[Fedora-directory-commits] ldapserver/ldap/servers/slapd/back-ldbm ldbm_search.c, 1.12, 1.13
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv26906/slapd/back-ldbm
Modified Files:
ldbm_search.c
Log Message:
Resoves: #448831
Summary: attacker can tie up CPU in regex code
Description: when substring search is requested, sets the time limit based upon
the nsslapd-timelimit value. Pass the timelimit (time_up) to the regular
expression function. When the time is up, it returns the "Timelimit exceeded"
error. Note: timelimit is applied non-Directory Manager users.
Index: ldbm_search.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/ldbm_search.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- ldbm_search.c 12 Oct 2007 18:03:42 -0000 1.12
+++ ldbm_search.c 30 Jun 2008 17:28:16 -0000 1.13
@@ -1296,6 +1296,10 @@
"Failed the filter test", 0, NULL );
rc = SLAPI_FAIL_GENERAL;
goto bail;
+ } else if (LDAP_TIMELIMIT_EXCEEDED == filter_test) {
+ slapi_send_ldap_result( pb, LDAP_TIMELIMIT_EXCEEDED, NULL, NULL, nentries, urls );
+ rc = SLAPI_FAIL_GENERAL;
+ goto bail;
}
}
}
14 years, 11 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd entry.c, 1.15, 1.16 filterentry.c, 1.7, 1.8 getfilelist.c, 1.7, 1.8 plugin_syntax.c, 1.5, 1.6 proto-slap.h, 1.34, 1.35 regex.c, 1.6, 1.7 sasl_map.c, 1.8, 1.9 slapi-private.h, 1.24, 1.25 vattr.c, 1.8, 1.9
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv26906/slapd
Modified Files:
entry.c filterentry.c getfilelist.c plugin_syntax.c
proto-slap.h regex.c sasl_map.c slapi-private.h vattr.c
Log Message:
Resoves: #448831
Summary: attacker can tie up CPU in regex code
Description: when substring search is requested, sets the time limit based upon
the nsslapd-timelimit value. Pass the timelimit (time_up) to the regular
expression function. When the time is up, it returns the "Timelimit exceeded"
error. Note: timelimit is applied non-Directory Manager users.
Index: entry.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/entry.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- entry.c 4 Jun 2008 22:22:55 -0000 1.15
+++ entry.c 30 Jun 2008 17:28:16 -0000 1.16
@@ -1843,7 +1843,7 @@
f->f_choice,
&f->f_ava );
} else if ( filter_type == FILTER_TYPE_SUBSTRING) {
- *rc = plugin_call_syntax_filter_sub( tmp_attr,
+ *rc = plugin_call_syntax_filter_sub( NULL, tmp_attr,
&f->f_sub);
} else if ( filter_type == FILTER_TYPE_PRES ) {
/* type is there, that's all we need to know. */
Index: filterentry.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/filterentry.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- filterentry.c 18 Apr 2008 20:20:22 -0000 1.7
+++ filterentry.c 30 Jun 2008 17:28:16 -0000 1.8
@@ -693,7 +693,7 @@
rc = -1;
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
if ( slapi_attr_type_cmp( f->f_sub_type, a->a_type, SLAPI_TYPE_CMP_SUBTYPE ) == 0 ) {
- rc = plugin_call_syntax_filter_sub( a, &f->f_sub );
+ rc = plugin_call_syntax_filter_sub( pb, a, &f->f_sub );
if ( rc == 0 ) {
break;
}
@@ -726,8 +726,8 @@
rc = -1;
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
if ( slapi_attr_type_cmp( f->f_sub_type, a->a_type, SLAPI_TYPE_CMP_SUBTYPE ) == 0 ) {
- rc = plugin_call_syntax_filter_sub( a, &f->f_sub );
- if ( rc == 0 ) {
+ rc = plugin_call_syntax_filter_sub( pb, a, &f->f_sub );
+ if ( rc == 0 || rc == LDAP_TIMELIMIT_EXCEEDED ) {
break;
}
}
Index: getfilelist.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/getfilelist.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- getfilelist.c 10 Nov 2006 23:45:40 -0000 1.7
+++ getfilelist.c 30 Jun 2008 17:28:16 -0000 1.8
@@ -130,7 +130,7 @@
slapd_re_lock();
s = slapd_re_comp((char *)pattern);
if (!s)
- match = slapd_re_exec((char *)filename);
+ match = slapd_re_exec((char *)filename, -1 /* no timelimit */);
slapd_re_unlock();
return match;
Index: plugin_syntax.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/plugin_syntax.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- plugin_syntax.c 10 Nov 2006 23:45:40 -0000 1.5
+++ plugin_syntax.c 30 Jun 2008 17:28:16 -0000 1.6
@@ -211,15 +211,17 @@
int
plugin_call_syntax_filter_sub(
+ Slapi_PBlock *pb,
Slapi_Attr *a,
struct subfilt *fsub
)
{
- return(plugin_call_syntax_filter_sub_sv(a,fsub));
+ return(plugin_call_syntax_filter_sub_sv(pb,a,fsub));
}
int
plugin_call_syntax_filter_sub_sv(
+ Slapi_PBlock *pb,
Slapi_Attr *a,
struct subfilt *fsub
)
@@ -240,6 +242,13 @@
{
Slapi_Value **va= valueset_get_valuearray(&a->a_present_values);
pblock_init( &pipb );
+ if (pb)
+ {
+ Operation *op = NULL;
+ /* to pass SLAPI_SEARCH_TIMELIMIT & SLAPI_OPINITATED_TIME */
+ slapi_pblock_get( pb, SLAPI_OPERATION, &op );
+ slapi_pblock_set( &pipb, SLAPI_OPERATION, op );
+ }
slapi_pblock_set( &pipb, SLAPI_PLUGIN, (void *) a->a_plugin );
rc = a->a_plugin->plg_syntax_filter_sub( &pipb,
fsub->sf_initial, fsub->sf_any, fsub->sf_final, va);
Index: proto-slap.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/proto-slap.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- proto-slap.h 10 Jun 2008 18:50:07 -0000 1.34
+++ proto-slap.h 30 Jun 2008 17:28:16 -0000 1.35
@@ -745,8 +745,8 @@
struct slapdplugin *slapi_get_global_syntax_plugins();
int plugin_call_syntax_filter_ava( const Slapi_Attr *a, int ftype, struct ava *ava );
int plugin_call_syntax_filter_ava_sv( const Slapi_Attr *a, int ftype, struct ava *ava, Slapi_Value **retVal, int useDeletedValues );
-int plugin_call_syntax_filter_sub( Slapi_Attr *a, struct subfilt *fsub );
-int plugin_call_syntax_filter_sub_sv( Slapi_Attr *a, struct subfilt *fsub );
+int plugin_call_syntax_filter_sub( Slapi_PBlock *pb, Slapi_Attr *a, struct subfilt *fsub );
+int plugin_call_syntax_filter_sub_sv( Slapi_PBlock *pb, Slapi_Attr *a, struct subfilt *fsub );
int plugin_call_syntax_get_compare_fn(void *vpi, value_compare_fn_type *compare_fn);
struct slapdplugin *plugin_syntax_find( const char *nameoroid );
void plugin_syntax_enumerate( SyntaxEnumFunc sef, void *arg );
Index: regex.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/regex.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- regex.c 29 Apr 2008 00:38:36 -0000 1.6
+++ regex.c 30 Jun 2008 17:28:16 -0000 1.7
@@ -66,6 +66,14 @@
* Modification history:
*
* $Log$
+ * Revision 1.7 2008/06/30 17:28:16 nhosoi
+ * Resoves: #448831
+ * Summary: attacker can tie up CPU in regex code
+ * Description: when substring search is requested, sets the time limit based upon
+ * the nsslapd-timelimit value. Pass the timelimit (time_up) to the regular
+ * expression function. When the time is up, it returns the "Timelimit exceeded"
+ * error. Note: timelimit is applied non-Directory Manager users.
+ *
* Revision 1.6 2008/04/29 00:38:36 nhosoi
* Resolves: #182621 (#443955)
* Summary: Allow larger regex buffer to enable long substring filters
@@ -695,7 +703,7 @@
static UCHAR *bopat[MAXTAG];
static UCHAR *eopat[MAXTAG];
#ifdef NEEDPROTOS
-static UCHAR *pmatch( UCHAR *lp, UCHAR *ap );
+static UCHAR *pmatch( UCHAR *lp, UCHAR *ap, time_t time_up, int *err );
#else /* NEEDPROTOS */
static UCHAR *pmatch();
#endif /* NEEDPROTOS */
@@ -720,14 +728,18 @@
* to the beginning and the end of the matched fragment,
* respectively.
*
+ * return values: 0 -- did not match
+ * 1 -- matched
+ * othersise -- ldap error (TIMELIMIT_EXCEEDED only)
*/
int
-slapd_re_exec( char *lp )
+slapd_re_exec( char *lp, time_t time_up )
{
register UCHAR c;
register UCHAR *ep = 0;
register UCHAR *ap = nfa;
+ int ldaperror = 0;
bol = (UCHAR*)lp;
@@ -745,7 +757,7 @@
switch(*ap) {
case BOL: /* anchored: match from BOL only */
- ep = pmatch((UCHAR*)lp,ap);
+ ep = pmatch((UCHAR*)lp,ap,time_up,&ldaperror);
break;
case CHR: /* ordinary char: locate it fast */
c = *(ap+1);
@@ -755,7 +767,7 @@
return 0;
default: /* regular matching all the way. */
do {
- if ((ep = pmatch((UCHAR*)lp,ap)))
+ if ((ep = pmatch((UCHAR*)lp,ap,time_up,&ldaperror)))
break;
lp++;
} while (*lp);
@@ -764,6 +776,8 @@
case END: /* munged automaton. fail always */
return 0;
}
+ if (ldaperror)
+ return ldaperror;
if (!ep)
return 0;
@@ -844,13 +858,19 @@
#define CCLSKIP 18 /* [CLO] CCL 16bytes END ... */
static UCHAR *
-pmatch( UCHAR *lp, UCHAR *ap)
+pmatch( UCHAR *lp, UCHAR *ap, time_t time_up, int *err )
{
register int op, c, n;
register UCHAR *e; /* extra pointer for CLO */
register UCHAR *bp; /* beginning of subpat.. */
register UCHAR *ep; /* ending of subpat.. */
UCHAR *are; /* to save the line ptr. */
+ time_t curtime = current_time();
+
+ if ( time_up != -1 && curtime > time_up ) {
+ *err = LDAP_TIMELIMIT_EXCEEDED;
+ return 0;
+ }
while ((op = *ap++) != END)
switch(op) {
@@ -927,7 +947,7 @@
ap += n;
while (lp >= are) {
- if ((e = pmatch(lp, ap)) != NULL)
+ if ((e = pmatch(lp, ap, time_up, err)) != NULL)
return e;
--lp;
}
Index: sasl_map.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/sasl_map.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- sasl_map.c 10 Nov 2006 23:45:40 -0000 1.8
+++ sasl_map.c 30 Jun 2008 17:28:16 -0000 1.9
@@ -434,9 +434,10 @@
recomp_result = slapd_re_comp(dp->regular_expression);
if (recomp_result) {
LDAPDebug( LDAP_DEBUG_ANY, "sasl_map_check : re_comp failed for expression (%s)\n", dp->regular_expression, 0, 0 );
+ } else {
+ matched = slapd_re_exec(sasl_user_and_realm, -1 /* no timelimit */);
+ LDAPDebug( LDAP_DEBUG_TRACE, "regex: %s, id: %s, %s\n", dp->regular_expression, sasl_user_and_realm, matched ? "matched" : "didn't match" );
}
- matched = slapd_re_exec(sasl_user_and_realm);
- LDAPDebug( LDAP_DEBUG_TRACE, "regex: %s, id: %s, %s\n", dp->regular_expression, sasl_user_and_realm, matched ? "matched" : "didn't match" );
if (matched) {
if (matched == 1) {
/* Allocate buffers for the returned strings */
Index: slapi-private.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slapi-private.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- slapi-private.h 27 Jun 2008 19:28:21 -0000 1.24
+++ slapi-private.h 30 Jun 2008 17:28:16 -0000 1.25
@@ -1185,7 +1185,7 @@
void bervalarray_add_berval_fast(struct berval ***vals, const struct berval *addval, int nvals, int *maxvals);
-int slapd_re_exec( char *lp );
+int slapd_re_exec( char *lp, time_t time_up );
char *slapd_re_comp( char *pat );
int slapd_re_subs( char *src, char* dst );
void slapd_re_lock( void );
Index: vattr.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/vattr.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- vattr.c 1 Nov 2007 20:24:07 -0000 1.8
+++ vattr.c 30 Jun 2008 17:28:16 -0000 1.9
@@ -540,7 +540,7 @@
rc = plugin_call_syntax_filter_ava( a,
f->f_choice, &f->f_ava );
} else if ( filter_type == FILTER_TYPE_SUBSTRING) {
- rc = plugin_call_syntax_filter_sub( a,
+ rc = plugin_call_syntax_filter_sub( pb, a,
&f->f_sub);
}
@@ -611,7 +611,7 @@
} else if ( filter_type == FILTER_TYPE_SUBSTRING ) {
- rc = test_substring_filter( NULL, e, f, 0 /* no access check */,
+ rc = test_substring_filter( pb, e, f, 0 /* no access check */,
0 /* do test filter */, &acl_test_done);
} else if ( filter_type == FILTER_TYPE_PRES ) {
14 years, 11 months
[Fedora-directory-commits] ldapserver/ldap/servers/plugins/syntaxes string.c, 1.10, 1.11
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/syntaxes
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv26906/plugins/syntaxes
Modified Files:
string.c
Log Message:
Resoves: #448831
Summary: attacker can tie up CPU in regex code
Description: when substring search is requested, sets the time limit based upon
the nsslapd-timelimit value. Pass the timelimit (time_up) to the regular
expression function. When the time is up, it returns the "Timelimit exceeded"
error. Note: timelimit is applied non-Directory Manager users.
Index: string.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/syntaxes/string.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- string.c 29 Apr 2008 00:38:36 -0000 1.10
+++ string.c 30 Jun 2008 17:28:16 -0000 1.11
@@ -195,9 +195,20 @@
char pat[BUFSIZ];
char buf[BUFSIZ];
char ebuf[BUFSIZ];
+ time_t curtime = 0;
+ time_t time_up = 0;
+ time_t optime = 0; /* time op was initiated */
+ int timelimit = 0; /* search timelimit */
LDAPDebug( LDAP_DEBUG_FILTER, "=> string_filter_sub\n",
0, 0, 0 );
+ slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &timelimit );
+ slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime );
+ /*
+ * (timelimit==-1) means no time limit
+ */
+ time_up = ( timelimit==-1 ? -1 : optime + timelimit);
+
/*
* construct a regular expression corresponding to the
* filter and let regex do the work for each value
@@ -259,18 +270,21 @@
p = (bigpat) ? bigpat : pat;
slapd_re_lock();
if ( (tmpbuf = slapd_re_comp( p )) != 0 ) {
- LDAPDebug( LDAP_DEBUG_ANY, "re_comp (%s) failed (%s)\n",
- pat, p, 0 );
- slapd_re_unlock();
- if( bigpat != NULL ) {
- slapi_ch_free((void**)&bigpat );
- }
- return( LDAP_OPERATIONS_ERROR );
+ LDAPDebug( LDAP_DEBUG_ANY, "re_comp (%s) failed (%s): %s\n",
+ pat, p, tmpbuf );
+ rc = LDAP_OPERATIONS_ERROR;
+ goto bailout;
} else {
LDAPDebug( LDAP_DEBUG_TRACE, "re_comp (%s)\n",
escape_string( p, ebuf ), 0, 0 );
}
+ curtime = current_time();
+ if ( time_up != -1 && curtime > time_up ) {
+ rc = LDAP_TIMELIMIT_EXCEEDED;
+ goto bailout;
+ }
+
/*
* test the regex against each value
*/
@@ -296,22 +310,22 @@
}
value_normalize( realval, syntax, 1 /* trim leading blanks */ );
- tmprc = slapd_re_exec( realval );
+ tmprc = slapd_re_exec( realval, time_up );
LDAPDebug( LDAP_DEBUG_TRACE, "re_exec (%s) %i\n",
escape_string( realval, ebuf ), tmprc, 0 );
- if ( tmprc != 0 ) {
+ if ( tmprc == 1 ) {
rc = 0;
break;
+ } else if ( tmprc != 0 ) {
+ rc = tmprc;
+ break;
}
}
+bailout:
slapd_re_unlock();
- if ( tmpbuf != NULL ) {
- slapi_ch_free((void**)&tmpbuf );
- }
- if( bigpat != NULL ) {
- slapi_ch_free((void**)&bigpat );
- }
+ slapi_ch_free((void**)&tmpbuf ); /* NULL is fine */
+ slapi_ch_free((void**)&bigpat ); /* NULL is fine */
LDAPDebug( LDAP_DEBUG_FILTER, "<= string_filter_sub %d\n",
rc, 0, 0 );
14 years, 11 months
[Fedora-directory-commits] ldapserver/ldap/servers/plugins/acl acl.c, 1.10, 1.11
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/acl
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv26906/plugins/acl
Modified Files:
acl.c
Log Message:
Resoves: #448831
Summary: attacker can tie up CPU in regex code
Description: when substring search is requested, sets the time limit based upon
the nsslapd-timelimit value. Pass the timelimit (time_up) to the regular
expression function. When the time is up, it returns the "Timelimit exceeded"
error. Note: timelimit is applied non-Directory Manager users.
Index: acl.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/acl/acl.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- acl.c 18 Oct 2007 00:08:27 -0000 1.10
+++ acl.c 30 Jun 2008 17:28:16 -0000 1.11
@@ -3253,7 +3253,7 @@
** matching, it seems that step() is leaking 1036 bytes/search
** I couldn't figure out why it's leaking.
*/
- rc = slapd_re_exec( realval );
+ rc = slapd_re_exec( realval, -1 /* no timelimit */ );
slapd_re_unlock();
14 years, 11 months
[Fedora-directory-commits] ldapserver/ldap/servers/plugins/schema_reload schema_reload.c, 1.1, 1.2
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/schema_reload
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv6584/ldap/servers/plugins/schema_reload
Modified Files:
schema_reload.c
Log Message:
Resolves: #437525
Summary: GER: allow GER for non-existing entries
Description:
[slapd/charray.c]
new: charray_merge_nodup -- merge 2 string arrays skipping the duplicates
modified: charray_remove -- introduced "freeit" flag. If true, the removed
string is freed. (The API is used only in chainingdb. The change is applied
to the plugin.)
[slapd/opshared.c]
modified: check OP_FLAG_GET_EFFECTIVE_RIGHTS in the iterate to support
"@<objectclass>". It's needed to do at the location since we have to call acl
plugin even
when no entries are returned from the search. If no entries are returned and
"@<objectclass>" is found in the attribute list, acl effective rights code
generates the corresponding template entry.
[slapd/pblock.c]
place to store gerattrs is added (SLAPI_SEARCH_GERATTRS), where gerattrs is an
array of strings which store "...@<objectclass>".
[slapd/result.c]
moved OP_FLAG_GET_EFFECTIVE_RIGHTS checking to iterate (opshared.c)
[slapd/schema.c]
new: slapi_schema_list_objectclass_attributes -- return the required and/or
allowed attributes belonging to the given objectclass. This is used to support
"*" and "+" in the get effective rights.
new: slapi_schema_get_superior_name -- return the superior objectclass name of
the given objectclass.
[slapd/search.c]
if "<attr>@<objectclass>" is found in the attribute list, cut the <attr> part
out and added to the attrs array (pblock SLAPI_SEARCH_ATTRS) and store the
original
string to the gerattrs (pblock SLAPI_SEARCH_GERATTRS).
[plugin/acl/acleffectiverights.c]
modified: _ger_g_permission_granted -- if the requester and the subject user
are
identical, give "g" permission
modified: _ger_parse_control -- replaced strcpy with memmove since strcpy does
not guarantee the result of the overlap copy.
modified: _ger_get_attrs_rights -- support "*" (all attributes belonging to the
object) and "+" (operational attributes). If repeated attributes are found in
the given attribute list, they are reduced to one.
new: _ger_generate_template_entry -- generate a template entry if
"@<objectclass>" is passed.
[pluginc/cb/*]
adjusted to the updated charray_remove.
Please see also this wiki page for the overview and test cases.
http://directory.fedoraproject.org/wiki/Get_Effective_Rights_for_non-pres...
Index: schema_reload.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/schema_reload/schema_reload.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- schema_reload.c 4 Jun 2008 22:22:57 -0000 1.1
+++ schema_reload.c 27 Jun 2008 19:28:22 -0000 1.2
@@ -214,10 +214,10 @@
{
PRThread *thread = NULL;
const char *cn;
+ const char *schemadir = NULL;
int rv = SLAPI_DSE_CALLBACK_OK;
Slapi_PBlock *mypb = NULL;
Slapi_Task *task = NULL;
- char *schemadir = NULL;
*returncode = LDAP_SUCCESS;
if ((cn = fetch_attr(e, "cn", NULL)) == NULL) {
14 years, 11 months
[Fedora-directory-commits] ldapserver/ldap/servers/plugins/acl acleffectiverights.c, 1.7, 1.8
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/acl
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv6584/ldap/servers/plugins/acl
Modified Files:
acleffectiverights.c
Log Message:
Resolves: #437525
Summary: GER: allow GER for non-existing entries
Description:
[slapd/charray.c]
new: charray_merge_nodup -- merge 2 string arrays skipping the duplicates
modified: charray_remove -- introduced "freeit" flag. If true, the removed
string is freed. (The API is used only in chainingdb. The change is applied
to the plugin.)
[slapd/opshared.c]
modified: check OP_FLAG_GET_EFFECTIVE_RIGHTS in the iterate to support
"@<objectclass>". It's needed to do at the location since we have to call acl
plugin even
when no entries are returned from the search. If no entries are returned and
"@<objectclass>" is found in the attribute list, acl effective rights code
generates the corresponding template entry.
[slapd/pblock.c]
place to store gerattrs is added (SLAPI_SEARCH_GERATTRS), where gerattrs is an
array of strings which store "...@<objectclass>".
[slapd/result.c]
moved OP_FLAG_GET_EFFECTIVE_RIGHTS checking to iterate (opshared.c)
[slapd/schema.c]
new: slapi_schema_list_objectclass_attributes -- return the required and/or
allowed attributes belonging to the given objectclass. This is used to support
"*" and "+" in the get effective rights.
new: slapi_schema_get_superior_name -- return the superior objectclass name of
the given objectclass.
[slapd/search.c]
if "<attr>@<objectclass>" is found in the attribute list, cut the <attr> part
out and added to the attrs array (pblock SLAPI_SEARCH_ATTRS) and store the
original
string to the gerattrs (pblock SLAPI_SEARCH_GERATTRS).
[plugin/acl/acleffectiverights.c]
modified: _ger_g_permission_granted -- if the requester and the subject user
are
identical, give "g" permission
modified: _ger_parse_control -- replaced strcpy with memmove since strcpy does
not guarantee the result of the overlap copy.
modified: _ger_get_attrs_rights -- support "*" (all attributes belonging to the
object) and "+" (operational attributes). If repeated attributes are found in
the given attribute list, they are reduced to one.
new: _ger_generate_template_entry -- generate a template entry if
"@<objectclass>" is passed.
[pluginc/cb/*]
adjusted to the updated charray_remove.
Please see also this wiki page for the overview and test cases.
http://directory.fedoraproject.org/wiki/Get_Effective_Rights_for_non-pres...
Index: acleffectiverights.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/acl/acleffectiverights.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- acleffectiverights.c 18 Oct 2007 00:08:27 -0000 1.7
+++ acleffectiverights.c 27 Jun 2008 19:28:22 -0000 1.8
@@ -46,7 +46,13 @@
/* news2 is optional, provided as a convenience */
/* capacity is the capacity of the gerstr, size is the current length */
static void
-_append_gerstr(char **gerstr, size_t *capacity, size_t *size, const char *news, const char *news2)
+_append_gerstr(
+ char **gerstr,
+ size_t *capacity,
+ size_t *size,
+ const char *news,
+ const char *news2
+ )
{
size_t len;
size_t increment = 128;
@@ -90,7 +96,12 @@
}
static int
-_ger_g_permission_granted ( Slapi_PBlock *pb, Slapi_Entry *e, char **errbuf )
+_ger_g_permission_granted (
+ Slapi_PBlock *pb,
+ Slapi_Entry *e,
+ const char *subjectdn,
+ char **errbuf
+ )
{
char *proxydn = NULL;
Slapi_DN *requestor_sdn, *entry_sdn;
@@ -151,6 +162,14 @@
goto bailout;
}
+ /* if the requestor and the subject user are identical, let's grant it */
+ if ( strcasecmp ( slapi_sdn_get_ndn(requestor_sdn), subjectdn ) == 0)
+ {
+ /* Requestor should see his own permission rights on any entry */
+ rc = LDAP_SUCCESS;
+ goto bailout;
+ }
+
aclutil_str_appened ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
slapi_log_error (SLAPI_LOG_ACL, plugin_name,
"_ger_g_permission_granted: %s\n", *errbuf);
@@ -166,11 +185,17 @@
}
static int
-_ger_parse_control ( Slapi_PBlock *pb, char **subjectndn, int *iscritical, char **errbuf )
+_ger_parse_control (
+ Slapi_PBlock *pb,
+ char **subjectndn,
+ int *iscritical,
+ char **errbuf
+ )
{
LDAPControl **requestcontrols;
struct berval *subjectber;
BerElement *ber;
+ int subjectndnlen = 0;
if (NULL == subjectndn)
{
@@ -231,7 +256,8 @@
* (see section 9 of RFC 2829) only. It also only supports the "dnAuthzId"
* flavor, which looks like "dn:<DN>" where null <DN> is for anonymous.
*/
- if ( NULL == *subjectndn || strlen (*subjectndn) < 3 ||
+ subjectndnlen = strlen(*subjectndn);
+ if ( NULL == *subjectndn || subjectndnlen < 3 ||
strncasecmp ( "dn:", *subjectndn, 3 ) != 0 )
{
aclutil_str_appened ( errbuf, "get-effective-rights: subject is not dnAuthzId" );
@@ -239,7 +265,8 @@
return LDAP_INVALID_SYNTAX;
}
- strcpy ( *subjectndn, *subjectndn + 3 );
+ /* memmove is safe for overlapping copy */
+ memmove ( *subjectndn, *subjectndn + 3, subjectndnlen - 2);/* 1 for '\0' */
slapi_dn_normalize ( *subjectndn );
return LDAP_SUCCESS;
}
@@ -533,6 +560,27 @@
return attrrights;
}
+#define GER_GET_ATTR_RIGHTS(attrs) \
+ for (thisattr = (attrs); thisattr && *thisattr; thisattr++) \
+ { \
+ _ger_get_attr_rights (gerpb, e, subjectndn, *thisattr, \
+ gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf); \
+ isfirstattr = 0; \
+ } \
+
+#define GER_GET_ATTR_RIGHTA_EXT(c, inattrs, exattrs); \
+ for ( i = 0; attrs[i]; i++ ) \
+ { \
+ if ((c) != *attrs[i] && charray_inlist((inattrs), attrs[i]) && \
+ !charray_inlist((exattrs), attrs[i])) \
+ { \
+ _ger_get_attr_rights ( gerpb, e, subjectndn, attrs[i], \
+ gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf ); \
+ isfirstattr = 0; \
+ } \
+ }
+
+
void
_ger_get_attrs_rights (
Slapi_PBlock *gerpb,
@@ -552,12 +600,76 @@
if (attrs && *attrs)
{
- int i;
- for ( i = 0; attrs[i]; i++ )
+ int i = 0;
+ char **allattrs = NULL;
+ char **opattrs = NULL;
+ char **myattrs = NULL;
+ char **thisattr = NULL;
+ int hasstar = charray_inlist(attrs, "*");
+ int hasplus = charray_inlist(attrs, "+");
+ Slapi_Attr *objclasses = NULL;
+ Slapi_ValueSet *objclassvals = NULL;
+
+ /* get all attrs available for the entry */
+ slapi_entry_attr_find(e, "objectclass", &objclasses);
+ if (NULL != objclasses) {
+ Slapi_Value *v;
+ slapi_attr_get_valueset(objclasses, &objclassvals);
+ i = slapi_valueset_first_value(objclassvals, &v);
+ if (-1 != i) {
+ allattrs = slapi_schema_list_objectclass_attributes(
+ (const char *)v->bv.bv_val,
+ SLAPI_OC_FLAG_REQUIRED|SLAPI_OC_FLAG_ALLOWED);
+ /* add "aci" to the allattrs to adjust to do_search */
+ charray_add(&allattrs, slapi_attr_syntax_normalize("aci"));
+ while (-1 != i)
+ {
+ i = slapi_valueset_next_value(objclassvals, i, &v);
+ if (-1 != i)
+ {
+ myattrs = slapi_schema_list_objectclass_attributes(
+ (const char *)v->bv.bv_val,
+ SLAPI_OC_FLAG_REQUIRED|SLAPI_OC_FLAG_ALLOWED);
+ charray_merge_nodup(&allattrs, myattrs, 1/*copy_strs*/);
+ charray_free(myattrs);
+ }
+ }
+ }
+ }
+
+ /* get operational attrs */
+ opattrs = slapi_schema_list_attribute_names(SLAPI_ATTR_FLAG_OPATTR);
+
+ if (hasstar && hasplus)
+ {
+ GER_GET_ATTR_RIGHTS(allattrs);
+ GER_GET_ATTR_RIGHTS(opattrs);
+ }
+ else if (hasstar)
{
- _ger_get_attr_rights ( gerpb, e, subjectndn, attrs[i], gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf );
- isfirstattr = 0;
+ GER_GET_ATTR_RIGHTS(allattrs);
+ GER_GET_ATTR_RIGHTA_EXT('*', opattrs, allattrs);
}
+ else if (hasplus)
+ {
+ GER_GET_ATTR_RIGHTS(opattrs);
+ GER_GET_ATTR_RIGHTA_EXT('+', allattrs, opattrs);
+ }
+ else
+ {
+ for ( i = 0; attrs[i]; i++ )
+ {
+ if (charray_inlist(allattrs, attrs[i]) ||
+ charray_inlist(opattrs, attrs[i]))
+ {
+ _ger_get_attr_rights ( gerpb, e, subjectndn, attrs[i],
+ gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf );
+ isfirstattr = 0;
+ }
+ }
+ }
+ charray_free(allattrs);
+ charray_free(opattrs);
}
else
{
@@ -569,7 +681,8 @@
if ( ! slapi_attr_flag_is_set (attr, SLAPI_ATTR_FLAG_OPATTR) )
{
slapi_attr_get_type ( attr, &type );
- _ger_get_attr_rights ( gerpb, e, subjectndn, type, gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf );
+ _ger_get_attr_rights ( gerpb, e, subjectndn, type, gerstr,
+ gerstrsize, gerstrcap, isfirstattr, errbuf );
isfirstattr = 0;
}
prevattr = attr;
@@ -648,6 +761,131 @@
}
int
+_ger_generate_template_entry (
+ Slapi_PBlock *pb
+ )
+{
+ Slapi_Entry *e = NULL;
+ char **gerattrs = NULL;
+ char **attrs = NULL;
+ char *templateentry = NULL;
+ char *object = NULL;
+ char *superior = NULL;
+ char *p = NULL;
+ int siz = 0;
+ int len = 0;
+ int i = 0;
+ int notfirst = 0;
+ int rc = LDAP_SUCCESS;
+
+ slapi_pblock_get( pb, SLAPI_SEARCH_GERATTRS, &gerattrs );
+ if (NULL == gerattrs)
+ {
+ slapi_log_error (SLAPI_LOG_FATAL, plugin_name,
+ "Objectclass info is expected "
+ "in the attr list, e.g., \"*@person\"\n");
+ rc = LDAP_SUCCESS;
+ goto bailout;
+ }
+ for (i = 0; gerattrs && gerattrs[i]; i++)
+ {
+ object = strchr(gerattrs[i], '@');
+ if (NULL != object && '\0' != *(++object))
+ {
+ break;
+ }
+ }
+ if (NULL == object)
+ {
+ rc = LDAP_SUCCESS; /* no objectclass info; ok to return */
+ goto bailout;
+ }
+ attrs = slapi_schema_list_objectclass_attributes(
+ (const char *)object, SLAPI_OC_FLAG_REQUIRED);
+ if (NULL == attrs)
+ {
+ rc = LDAP_SUCCESS; /* bogus objectclass info; ok to return */
+ goto bailout;
+ }
+ for (i = 0; attrs[i]; i++)
+ {
+ if (0 == strcasecmp(attrs[i], "objectclass"))
+ {
+ /* <*attrp>: <object>\n\0 */
+ siz += strlen(attrs[i]) + 4 + strlen(object);
+ }
+ else
+ {
+ /* <*attrp>: dummy\n\0 */
+ siz += strlen(attrs[i]) + 4 + 5;
+ }
+ }
+ siz += 32 + strlen(object); /* dn: cn=<template_name>\n\0 */
+ templateentry = (char *)slapi_ch_malloc(siz);
+ PR_snprintf(templateentry, siz,
+ "dn: cn=template_%s_objectclass\n", object);
+ for (--i; i >= 0; i--)
+ {
+ len = strlen(templateentry);
+ p = templateentry + len;
+ if (0 == strcasecmp(attrs[i], "objectclass"))
+ {
+ PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
+ }
+ else
+ {
+ PR_snprintf(p, siz - len, "%s: dummy\n", attrs[i]);
+ }
+ }
+ charray_free(attrs);
+
+ while ((superior = slapi_schema_get_superior_name(object)) &&
+ (0 != strcasecmp(superior, "top")))
+ {
+ if (notfirst)
+ {
+ slapi_ch_free_string(&object);
+ }
+ notfirst = 1;
+ object = superior;
+ attrs = slapi_schema_list_objectclass_attributes(
+ (const char *)superior, SLAPI_OC_FLAG_REQUIRED);
+ for (i = 0; attrs && attrs[i]; i++)
+ {
+ if (0 == strcasecmp(attrs[i], "objectclass"))
+ {
+ /* <*attrp>: <object>\n\0 */
+ siz += strlen(attrs[i]) + 4 + strlen(object);
+ }
+ }
+ templateentry = (char *)slapi_ch_realloc(templateentry, siz);
+ for (--i; i >= 0; i--)
+ {
+ len = strlen(templateentry);
+ p = templateentry + len;
+ if (0 == strcasecmp(attrs[i], "objectclass"))
+ {
+ PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
+ }
+ }
+ charray_free(attrs);
+ }
+ slapi_ch_free_string(&superior);
+ siz += 18; /* objectclass: top\n\0 */
+ len = strlen(templateentry);
+ templateentry = (char *)slapi_ch_realloc(templateentry, siz);
+ p = templateentry + len;
+ PR_snprintf(p, siz - len, "objectclass: top\n");
+
+ e = slapi_str2entry(templateentry, SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF);
+ /* set the template entry to send the result to clients */
+ slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, e);
+bailout:
+ slapi_ch_free_string(&templateentry);
+ return rc;
+}
+
+int
acl_get_effective_rights (
Slapi_PBlock *pb,
Slapi_Entry *e, /* target entry */
@@ -664,10 +902,20 @@
size_t gerstrsize = 0;
size_t gerstrcap = 0;
int iscritical = 1;
- int rc;
+ int rc = LDAP_SUCCESS;
*errbuf = '\0';
+ if (NULL == e) /* create a template entry from SLAPI_SEARCH_GERATTRS */
+ {
+ rc = _ger_generate_template_entry ( pb );
+ slapi_pblock_get ( pb, SLAPI_SEARCH_RESULT_ENTRY, &e );
+ if ( rc != LDAP_SUCCESS || NULL == e )
+ {
+ goto bailout;
+ }
+ }
+
/*
* Get the subject
*/
@@ -681,7 +929,7 @@
* The requestor should have g permission on the entry
* to get the effective rights.
*/
- rc = _ger_g_permission_granted (pb, e, errbuf);
+ rc = _ger_g_permission_granted (pb, e, subjectndn, errbuf);
if ( rc != LDAP_SUCCESS )
{
goto bailout;
@@ -718,7 +966,7 @@
slapi_log_error (SLAPI_LOG_ACLSUMMARY, plugin_name,
"###### Effective Rights on Entry (%s) for Subject (%s) ######\n",
- slapi_entry_get_ndn (e), subjectndn);
+ e?slapi_entry_get_ndn(e):"null", subjectndn?subjectndn:"null");
slapi_log_error (SLAPI_LOG_ACLSUMMARY, plugin_name, "%s\n", gerstr);
/* Restore pb */
14 years, 11 months
[Fedora-directory-commits] ldapserver/ldap/servers/plugins/chainingdb cb_config.c, 1.6, 1.7 cb_controls.c, 1.8, 1.9 cb_instance.c, 1.8, 1.9
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/chainingdb
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv6584/ldap/servers/plugins/chainingdb
Modified Files:
cb_config.c cb_controls.c cb_instance.c
Log Message:
Resolves: #437525
Summary: GER: allow GER for non-existing entries
Description:
[slapd/charray.c]
new: charray_merge_nodup -- merge 2 string arrays skipping the duplicates
modified: charray_remove -- introduced "freeit" flag. If true, the removed
string is freed. (The API is used only in chainingdb. The change is applied
to the plugin.)
[slapd/opshared.c]
modified: check OP_FLAG_GET_EFFECTIVE_RIGHTS in the iterate to support
"@<objectclass>". It's needed to do at the location since we have to call acl
plugin even
when no entries are returned from the search. If no entries are returned and
"@<objectclass>" is found in the attribute list, acl effective rights code
generates the corresponding template entry.
[slapd/pblock.c]
place to store gerattrs is added (SLAPI_SEARCH_GERATTRS), where gerattrs is an
array of strings which store "...@<objectclass>".
[slapd/result.c]
moved OP_FLAG_GET_EFFECTIVE_RIGHTS checking to iterate (opshared.c)
[slapd/schema.c]
new: slapi_schema_list_objectclass_attributes -- return the required and/or
allowed attributes belonging to the given objectclass. This is used to support
"*" and "+" in the get effective rights.
new: slapi_schema_get_superior_name -- return the superior objectclass name of
the given objectclass.
[slapd/search.c]
if "<attr>@<objectclass>" is found in the attribute list, cut the <attr> part
out and added to the attrs array (pblock SLAPI_SEARCH_ATTRS) and store the
original
string to the gerattrs (pblock SLAPI_SEARCH_GERATTRS).
[plugin/acl/acleffectiverights.c]
modified: _ger_g_permission_granted -- if the requester and the subject user
are
identical, give "g" permission
modified: _ger_parse_control -- replaced strcpy with memmove since strcpy does
not guarantee the result of the overlap copy.
modified: _ger_get_attrs_rights -- support "*" (all attributes belonging to the
object) and "+" (operational attributes). If repeated attributes are found in
the given attribute list, they are reduced to one.
new: _ger_generate_template_entry -- generate a template entry if
"@<objectclass>" is passed.
[pluginc/cb/*]
adjusted to the updated charray_remove.
Please see also this wiki page for the overview and test cases.
http://directory.fedoraproject.org/wiki/Get_Effective_Rights_for_non-pres...
Index: cb_config.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/chainingdb/cb_config.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- cb_config.c 10 Nov 2006 23:44:50 -0000 1.6
+++ cb_config.c 27 Jun 2008 19:28:22 -0000 1.7
@@ -477,7 +477,8 @@
} else
if ( (mods[i]->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE) {
charray_remove(cb->config.chaining_components,
- slapi_dn_normalize(slapi_ch_strdup(config_attr_value)));
+ slapi_dn_normalize(slapi_ch_strdup(config_attr_value)),
+ 0 /* freeit */);
}
}
if (NULL == mods[i]->mod_bvalues) {
@@ -513,7 +514,8 @@
if ( (mods[i]->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE) {
charray_remove(cb->config.chainable_components,
slapi_dn_normalize(slapi_ch_strdup(config_attr_value)
-));
+),
+ 0 /* freeit */);
}
}
if (NULL == mods[i]->mod_bvalues) {
Index: cb_controls.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/chainingdb/cb_controls.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- cb_controls.c 10 Nov 2006 23:44:50 -0000 1.8
+++ cb_controls.c 27 Jun 2008 19:28:22 -0000 1.9
@@ -91,7 +91,7 @@
return;
}
if ( controlops == 0 ) {
- charray_remove(cb->config.forward_ctrls,controloid);
+ charray_remove(cb->config.forward_ctrls,controloid,0/* free it */);
}
PR_RWLock_Unlock(cb->config.rwl_config_lock);
}
Index: cb_instance.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/chainingdb/cb_instance.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- cb_instance.c 18 Oct 2007 00:08:28 -0000 1.8
+++ cb_instance.c 27 Jun 2008 19:28:22 -0000 1.9
@@ -392,7 +392,8 @@
} else
if ( (mods[i]->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE) {
charray_remove(inst->illegal_attributes,
- slapi_ch_strdup(config_attr_value));
+ slapi_ch_strdup(config_attr_value),
+ 0 /* freeit */);
}
}
if (NULL == mods[i]->mod_bvalues) {
@@ -426,7 +427,8 @@
} else
if ( (mods[i]->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE) {
charray_remove(inst->chaining_components,
- slapi_dn_normalize(slapi_ch_strdup(config_attr_value)));
+ slapi_dn_normalize(slapi_ch_strdup(config_attr_value)),
+ 0 /* freeit */);
}
}
if (NULL == mods[i]->mod_bvalues) {
14 years, 11 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd charray.c, 1.6, 1.7 opshared.c, 1.11, 1.12 pblock.c, 1.13, 1.14 result.c, 1.12, 1.13 schema.c, 1.14, 1.15 search.c, 1.8, 1.9 slapi-plugin.h, 1.22, 1.23 slapi-private.h, 1.23, 1.24
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv6584/ldap/servers/slapd
Modified Files:
charray.c opshared.c pblock.c result.c schema.c search.c
slapi-plugin.h slapi-private.h
Log Message:
Resolves: #437525
Summary: GER: allow GER for non-existing entries
Description:
[slapd/charray.c]
new: charray_merge_nodup -- merge 2 string arrays skipping the duplicates
modified: charray_remove -- introduced "freeit" flag. If true, the removed
string is freed. (The API is used only in chainingdb. The change is applied
to the plugin.)
[slapd/opshared.c]
modified: check OP_FLAG_GET_EFFECTIVE_RIGHTS in the iterate to support
"@<objectclass>". It's needed to do at the location since we have to call acl
plugin even
when no entries are returned from the search. If no entries are returned and
"@<objectclass>" is found in the attribute list, acl effective rights code
generates the corresponding template entry.
[slapd/pblock.c]
place to store gerattrs is added (SLAPI_SEARCH_GERATTRS), where gerattrs is an
array of strings which store "...@<objectclass>".
[slapd/result.c]
moved OP_FLAG_GET_EFFECTIVE_RIGHTS checking to iterate (opshared.c)
[slapd/schema.c]
new: slapi_schema_list_objectclass_attributes -- return the required and/or
allowed attributes belonging to the given objectclass. This is used to support
"*" and "+" in the get effective rights.
new: slapi_schema_get_superior_name -- return the superior objectclass name of
the given objectclass.
[slapd/search.c]
if "<attr>@<objectclass>" is found in the attribute list, cut the <attr> part
out and added to the attrs array (pblock SLAPI_SEARCH_ATTRS) and store the
original
string to the gerattrs (pblock SLAPI_SEARCH_GERATTRS).
[plugin/acl/acleffectiverights.c]
modified: _ger_g_permission_granted -- if the requester and the subject user
are
identical, give "g" permission
modified: _ger_parse_control -- replaced strcpy with memmove since strcpy does
not guarantee the result of the overlap copy.
modified: _ger_get_attrs_rights -- support "*" (all attributes belonging to the
object) and "+" (operational attributes). If repeated attributes are found in
the given attribute list, they are reduced to one.
new: _ger_generate_template_entry -- generate a template entry if
"@<objectclass>" is passed.
[pluginc/cb/*]
adjusted to the updated charray_remove.
Please see also this wiki page for the overview and test cases.
http://directory.fedoraproject.org/wiki/Get_Effective_Rights_for_non-pres...
Index: charray.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/charray.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- charray.c 10 Nov 2006 23:45:40 -0000 1.6
+++ charray.c 27 Jun 2008 19:28:21 -0000 1.7
@@ -118,6 +118,48 @@
(*a)[n + nn] = NULL;
}
+/*
+ * charray_merge_nodup:
+ * merge a string array (second arg) into the first string array
+ * unless the each string is in the first string array.
+ */
+void
+charray_merge_nodup(
+ char ***a,
+ char **s,
+ int copy_strs
+)
+{
+ int i, j, n, nn;
+ char **dupa;
+
+ if ( (s == NULL) || (s[0] == NULL) )
+ return;
+
+ for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
+ ; /* NULL */
+ }
+ for ( nn = 0; s[nn] != NULL; nn++ ) {
+ ; /* NULL */
+ }
+
+ dupa = (char **)slapi_ch_calloc(1, (n+nn+1) * sizeof(char *));
+ memcpy(dupa, *a, sizeof(char *) * n);
+ slapi_ch_free((void **)a);
+
+ for ( i = 0, j = 0; i < nn; i++ ) {
+ if (!charray_inlist(dupa, s[i])) { /* skip if s[i] is already in *a */
+ if ( copy_strs ) {
+ dupa[n+j] = slapi_ch_strdup( s[i] );
+ } else {
+ dupa[n+j] = s[i];
+ }
+ j++;
+ }
+ }
+ *a = dupa;
+}
+
/* Routines which don't pound on malloc. Don't interchange the arrays with the
* regular calls---they can end up freeing non-heap memory, which is wrong */
@@ -337,13 +379,15 @@
* Remove the char string from the array of char strings.
* Performs a case *insensitive* comparison!
* Just shunts the strings down to cover the deleted string.
- * Doesn't free up the unused memory.
+ * freeit: none zero -> free the found string
+ * : zero -> Doesn't free up the unused memory.
* Returns 1 if the entry found and removed, 0 if not.
*/
int
charray_remove(
char **a,
- const char *s
+ const char *s,
+ int freeit
)
{
int i;
@@ -353,6 +397,10 @@
if ( !found && strcasecmp (a[i],s) == 0 )
{
found= 1;
+ if (freeit)
+ {
+ slapi_ch_free_string(&a[i]);
+ }
}
if (found)
{
Index: opshared.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/opshared.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- opshared.c 18 Oct 2007 00:08:34 -0000 1.11
+++ opshared.c 27 Jun 2008 19:28:21 -0000 1.12
@@ -953,67 +953,188 @@
int rc;
int attrsonly;
int done = 0;
- Slapi_Entry *e;
+ Slapi_Entry *e = NULL;
char **attrs = NULL;
slapi_pblock_get(pb, SLAPI_SEARCH_ATTRS, &attrs);
slapi_pblock_get(pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly);
- *pnentries = 0;
+ *pnentries = 0;
while (!done)
- {
- rc = be->be_next_search_entry(pb);
- if (rc < 0)
- {
- /*
- * Some exceptional condition occurred. Results have been sent, so we're finished.
- */
- if (rc == SLAPI_FAIL_DISKFULL)
- {
- operation_out_of_disk_space();
- }
- return -1;
- }
- else
- {
- slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e);
- if (e == NULL)
- {
- /* no more entries */
- done = 1;
- continue;
- }
- }
-
- if (process_entry(pb, e, send_result))
- {
- /* shouldn't send this entry */
- continue;
- }
-
- /*
- * It's a regular entry, or it's a referral and
- * managedsait control is on. In either case, send
- * the entry.
- */
- switch (send_ldap_search_entry(pb, e, NULL, attrs, attrsonly))
- {
- case 0: /* entry sent ok */
- (*pnentries)++;
- slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries);
- break;
- case 1: /* entry not sent */
- break;
- case -1: /* connection closed */
- /*
- * mark the operation as abandoned so the backend
- * next entry function gets called again and has
- * a chance to clean things up.
- */
- pb->pb_op->o_status = SLAPI_OP_STATUS_ABANDONED;
- break;
- }
+ {
+ Slapi_Entry *gerentry = NULL;
+ Slapi_Operation *operation;
+
+ rc = be->be_next_search_entry(pb);
+ if (rc < 0)
+ {
+ /*
+ * Some exceptional condition occurred. Results have been sent, so we're finished.
+ */
+ if (rc == SLAPI_FAIL_DISKFULL)
+ {
+ operation_out_of_disk_space();
+ }
+ return -1;
+ }
+
+ slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e);
+
+ /* Check for possible get_effective_rights control */
+ slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
+ if ( operation->o_flags & OP_FLAG_GET_EFFECTIVE_RIGHTS )
+ {
+ char *errbuf = NULL;
+ char **gerattrs = NULL;
+ char **gerattrsdup = NULL;
+ char **gap = NULL;
+ char *gapnext = NULL;
+
+ slapi_pblock_get( pb, SLAPI_SEARCH_GERATTRS, &gerattrs );
+
+ gerattrsdup = cool_charray_dup(gerattrs);
+ gap = gerattrsdup;
+ do
+ {
+ gapnext = NULL;
+ if (gap)
+ {
+ if (*gap && *(gap+1))
+ {
+ gapnext = *(gap+1);
+ *(gap+1) = NULL;
+ }
+ slapi_pblock_set( pb, SLAPI_SEARCH_GERATTRS, gap );
+ rc = plugin_call_acl_plugin (pb, e, attrs, NULL,
+ SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS,
+ &errbuf);
+ if (NULL != gapnext)
+ {
+ *(gap+1) = gapnext;
+ }
+ }
+ else if (NULL != e)
+ {
+ rc = plugin_call_acl_plugin (pb, e, attrs, NULL,
+ SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS,
+ &errbuf);
+ }
+ if (NULL == e) {
+ /* get the template entry, if any */
+ slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e);
+ if (NULL == e) {
+ /* everything is ok - don't send the result */
+ return 1;
+ }
+ gerentry = e;
+ }
+ if ( rc != LDAP_SUCCESS ) {
+ /* Send error result and
+ abort op if the control is critical */
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "Failed to get effective rights for entry (%s), rc=%d\n",
+ slapi_entry_get_dn_const(e), rc, 0 );
+ send_ldap_result( pb, rc, NULL, errbuf, 0, NULL );
+ slapi_ch_free ( (void**)&errbuf );
+ if (gerentry)
+ {
+ slapi_pblock_set(pb,
+ SLAPI_SEARCH_RESULT_ENTRY, NULL);
+ slapi_entry_free(gerentry);
+ gerentry = e = NULL;
+ }
+ return( -1 );
+ }
+ slapi_ch_free ( (void**)&errbuf );
+ if (process_entry(pb, e, send_result))
+ {
+ /* shouldn't send this entry */
+ if (gerentry)
+ {
+ slapi_pblock_set(pb,
+ SLAPI_SEARCH_RESULT_ENTRY, NULL);
+ slapi_entry_free(gerentry);
+ gerentry = e = NULL;
+ }
+ continue;
+ }
+
+ /*
+ * It's a regular entry, or it's a referral and
+ * managedsait control is on. In either case, send
+ * the entry.
+ */
+ switch (send_ldap_search_entry(pb, e,
+ NULL, attrs, attrsonly))
+ {
+ case 0: /* entry sent ok */
+ (*pnentries)++;
+ slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries);
+ break;
+ case 1: /* entry not sent */
+ break;
+ case -1: /* connection closed */
+ /*
+ * mark the operation as abandoned so the backend
+ * next entry function gets called again and has
+ * a chance to clean things up.
+ */
+ pb->pb_op->o_status = SLAPI_OP_STATUS_ABANDONED;
+ break;
+ }
+ if (gerentry)
+ {
+ slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, NULL);
+ slapi_entry_free(gerentry);
+ gerentry = e = NULL;
+ }
+ }
+ while (gap && ++gap && *gap);
+ slapi_pblock_set( pb, SLAPI_SEARCH_GERATTRS, gerattrs );
+ cool_charray_free(gerattrsdup);
+ if (NULL == e)
+ {
+ /* no more entries */
+ done = 1;
+ }
+ }
+ else if (e)
+ {
+ if (process_entry(pb, e, send_result))
+ {
+ /* shouldn't send this entry */
+ continue;
+ }
+
+ /*
+ * It's a regular entry, or it's a referral and
+ * managedsait control is on. In either case, send
+ * the entry.
+ */
+ switch (send_ldap_search_entry(pb, e, NULL, attrs, attrsonly))
+ {
+ case 0: /* entry sent ok */
+ (*pnentries)++;
+ slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries);
+ break;
+ case 1: /* entry not sent */
+ break;
+ case -1: /* connection closed */
+ /*
+ * mark the operation as abandoned so the backend
+ * next entry function gets called again and has
+ * a chance to clean things up.
+ */
+ pb->pb_op->o_status = SLAPI_OP_STATUS_ABANDONED;
+ break;
+ }
+ }
+ else
+ {
+ /* no more entries */
+ done = 1;
+ }
}
return 1;
Index: pblock.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/pblock.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- pblock.c 4 Jun 2008 22:22:55 -0000 1.13
+++ pblock.c 27 Jun 2008 19:28:21 -0000 1.14
@@ -1231,6 +1231,12 @@
(*(char ***)value) = pblock->pb_op->o_params.p.p_search.search_attrs;
}
break;
+ case SLAPI_SEARCH_GERATTRS:
+ if(pblock->pb_op!=NULL)
+ {
+ (*(char ***)value) = pblock->pb_op->o_params.p.p_search.search_gerattrs;
+ }
+ break;
case SLAPI_SEARCH_ATTRSONLY:
if(pblock->pb_op!=NULL)
{
@@ -2509,6 +2515,12 @@
pblock->pb_op->o_params.p.p_search.search_attrs = (char **) value;
}
break;
+ case SLAPI_SEARCH_GERATTRS:
+ if(pblock->pb_op!=NULL)
+ {
+ pblock->pb_op->o_params.p.p_search.search_gerattrs = (char **) value;
+ }
+ break;
case SLAPI_SEARCH_ATTRSONLY:
if(pblock->pb_op!=NULL)
{
Index: result.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/result.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- result.c 18 Oct 2007 00:08:34 -0000 1.12
+++ result.c 27 Jun 2008 19:28:21 -0000 1.13
@@ -1203,14 +1203,15 @@
int *dontsendattr= NULL;
Slapi_Operation *operation;
int real_attrs_only = 0;
- LDAPControl **ctrlp = 0;
+ LDAPControl **ctrlp = 0;
+ Slapi_Entry *gerentry = NULL;
slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
LDAPDebug( LDAP_DEBUG_TRACE, "=> send_ldap_search_entry (%s)\n",
- slapi_entry_get_dn_const(e), 0, 0 );
+ e?slapi_entry_get_dn_const(e):"null", 0, 0 );
- if ( conn == NULL ) {
+ if ( conn == NULL && e ) {
if ( op->o_search_entry_handler != NULL ) {
if (( rc = (*op->o_search_entry_handler)(
pb->pb_backend, conn, op, e )) == 0 ) {
@@ -1224,7 +1225,7 @@
}
#if !defined(DISABLE_ACL_CHECK)
- if ( plugin_call_acl_plugin (pb, e, attrs, NULL,
+ if ( e && plugin_call_acl_plugin (pb, e, attrs, NULL,
SLAPI_ACL_READ, ACLPLUGIN_ACCESS_READ_ON_ENTRY, NULL ) != LDAP_SUCCESS ) {
LDAPDebug( LDAP_DEBUG_ACL, "acl: access to entry not allowed\n",
0, 0, 0 );
@@ -1232,21 +1233,8 @@
}
#endif
- /* Check for possible get_effective_rights control */
- if ( operation->o_flags & OP_FLAG_GET_EFFECTIVE_RIGHTS ) {
- char *errbuf = NULL;
- rc = plugin_call_acl_plugin (pb, e, attrs, NULL, SLAPI_ACL_ALL,
- ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS, &errbuf);
- if ( rc != LDAP_SUCCESS ) {
- LDAPDebug( LDAP_DEBUG_ANY,
- "Failed to get effective rights for entry (%s), rc=%d\n",
- slapi_entry_get_dn_const(e), rc, 0 );
- /* Send error result and abort op if the control is critical */
- send_ldap_result( pb, rc, NULL, errbuf, 0, NULL );
- slapi_ch_free ( (void**)&errbuf );
- return( -1 );
- }
- slapi_ch_free ( (void**)&errbuf );
+ if (NULL == e) {
+ return 1; /* everything is ok - don't send the result */
}
if ( (ber = der_alloc()) == NULL ) {
@@ -1454,6 +1442,10 @@
}
}
+ if (gerentry)
+ {
+ slapi_entry_free(gerentry);
+ }
LDAPDebug( LDAP_DEBUG_TRACE, "<= send_ldap_search_entry\n", 0, 0, 0 );
exit:
return( rc );
Index: schema.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/schema.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- schema.c 10 Jun 2008 18:50:07 -0000 1.14
+++ schema.c 27 Jun 2008 19:28:21 -0000 1.15
@@ -641,41 +641,41 @@
oc_check_required( Slapi_PBlock *pb, Slapi_Entry *e, struct objclass *oc )
{
int i;
- int rc = 0; /* success, by default */
+ int rc = 0; /* success, by default */
Slapi_Attr *a;
if (oc == NULL || oc->oc_required == NULL || oc->oc_required[0] == NULL) {
- return 0; /* success, as none required */
+ return 0; /* success, as none required */
}
/* for each required attribute */
for ( i = 0; oc->oc_required[i] != NULL; i++ ) {
/* see if it's in the entry */
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
- if ( slapi_attr_type_cmp( oc->oc_required[i], a->a_type,
- SLAPI_TYPE_CMP_SUBTYPE ) == 0 ) {
- break;
- }
- }
-
- /* not there => schema violation */
- if ( a == NULL ) {
- char errtext[ BUFSIZ ];
- char ebuf[ BUFSIZ ];
- LDAPDebug( LDAP_DEBUG_ANY,
- "Entry \"%s\" missing attribute \"%s\" required"
- " by object class \"%s\"\n",
- escape_string( slapi_entry_get_dn_const(e), ebuf ),
- oc->oc_required[i], oc->oc_name);
- if (pb) {
- PR_snprintf( errtext, sizeof( errtext ),
- "missing attribute \"%s\" required"
- " by object class \"%s\"\n",
- oc->oc_required[i], oc->oc_name );
- slapi_pblock_set( pb, SLAPI_PB_RESULT_TEXT, errtext );
- }
- rc = 1; /* failure */
- }
+ if ( slapi_attr_type_cmp( oc->oc_required[i], a->a_type,
+ SLAPI_TYPE_CMP_SUBTYPE ) == 0 ) {
+ break;
+ }
+ }
+
+ /* not there => schema violation */
+ if ( a == NULL ) {
+ char errtext[ BUFSIZ ];
+ char ebuf[ BUFSIZ ];
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "Entry \"%s\" missing attribute \"%s\" required"
+ " by object class \"%s\"\n",
+ escape_string( slapi_entry_get_dn_const(e), ebuf ),
+ oc->oc_required[i], oc->oc_name);
+ if (pb) {
+ PR_snprintf( errtext, sizeof( errtext ),
+ "missing attribute \"%s\" required"
+ " by object class \"%s\"\n",
+ oc->oc_required[i], oc->oc_name );
+ slapi_pblock_set( pb, SLAPI_PB_RESULT_TEXT, errtext );
+ }
+ rc = 1; /* failure */
+ }
}
return rc;
@@ -1392,8 +1392,8 @@
}
/* Return the list of attributes names matching attribute flags */
-
-char ** slapi_schema_list_attribute_names(unsigned long flag)
+char **
+slapi_schema_list_attribute_names(unsigned long flag)
{
struct listargs aew;
memset(&aew,0,sizeof(struct listargs));
@@ -4966,3 +4966,69 @@
return LDAP_LOCAL_ERROR;
}
}
+
+/*
+ * slapi_schema_list_objectclass_attributes:
+ * Return the list of attributes belonging to the objectclass
+ *
+ * The caller is responsible to free the returned list with charray_free.
+ * flags: one of them or both:
+ * SLAPI_OC_FLAG_REQUIRED
+ * SLAPI_OC_FLAG_ALLOWED
+ */
+char **
+slapi_schema_list_objectclass_attributes(const char *ocname_or_oid,
+ PRUint32 flags)
+{
+ struct objclass *oc = NULL;
+ char **attrs = NULL;
+ PRUint32 mask = SLAPI_OC_FLAG_REQUIRED | SLAPI_OC_FLAG_ALLOWED;
+
+ if (!flags) {
+ return attrs;
+ }
+
+ oc_lock_read();
+ oc = oc_find_nolock(ocname_or_oid);
+ if (oc) {
+ switch (flags & mask) {
+ case SLAPI_OC_FLAG_REQUIRED:
+ attrs = charray_dup(oc->oc_required);
+ break;
+ case SLAPI_OC_FLAG_ALLOWED:
+ attrs = charray_dup(oc->oc_allowed);
+ break;
+ case SLAPI_OC_FLAG_REQUIRED|SLAPI_OC_FLAG_ALLOWED:
+ attrs = charray_dup(oc->oc_required);
+ charray_merge(&attrs, oc->oc_allowed, 1/*copy_strs*/);
+ break;
+ default:
+ slapi_log_error( SLAPI_LOG_FATAL, "list objectclass attributes",
+ "flag 0x%x not supported\n", flags );
+ break;
+ }
+ }
+ oc_unlock();
+ return attrs;
+}
+
+/*
+ * slapi_schema_get_superior_name:
+ * Return the name of the superior objectclass
+ *
+ * The caller is responsible to free the returned name
+ */
+char *
+slapi_schema_get_superior_name(const char *ocname_or_oid)
+{
+ struct objclass *oc = NULL;
+ char *superior = NULL;
+
+ oc_lock_read();
+ oc = oc_find_nolock(ocname_or_oid);
+ if (oc) {
+ superior = slapi_ch_strdup(oc->oc_superior);
+ }
+ oc_unlock();
+ return superior;
+}
Index: search.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/search.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- search.c 18 Oct 2007 00:08:34 -0000 1.8
+++ search.c 27 Jun 2008 19:28:21 -0000 1.9
@@ -65,92 +65,93 @@
do_search( Slapi_PBlock *pb )
{
Slapi_Operation *operation;
- BerElement *ber;
- int i, err, attrsonly;
- ber_int_t scope, deref, sizelimit, timelimit;
- char *base = NULL, *fstr = NULL;
- struct slapi_filter *filter = NULL;
- char **attrs = NULL;
- int psearch = 0;
- struct berval *psbvp;
- ber_int_t changetypes;
+ BerElement *ber;
+ int i, err, attrsonly;
+ ber_int_t scope, deref, sizelimit, timelimit;
+ char *base = NULL, *fstr = NULL;
+ struct slapi_filter *filter = NULL;
+ char **attrs = NULL;
+ char **gerattrs = NULL;
+ int psearch = 0;
+ struct berval *psbvp;
+ ber_int_t changetypes;
int send_entchg_controls;
int changesonly = 0;
int rc = -1;
char *original_base = 0;
char *new_base = 0;
- LDAPDebug( LDAP_DEBUG_TRACE, "do_search\n", 0, 0, 0 );
+ LDAPDebug( LDAP_DEBUG_TRACE, "do_search\n", 0, 0, 0 );
slapi_pblock_get( pb, SLAPI_OPERATION, &operation);
- ber = operation->o_ber;
+ ber = operation->o_ber;
- /* count the search request */
- snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsSearchOps);
+ /* count the search request */
+ snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsSearchOps);
- /*
- * Parse the search request. It looks like this:
- *
- * SearchRequest := [APPLICATION 3] SEQUENCE {
- * baseObject DistinguishedName,
- * scope ENUMERATED {
- * baseObject (0),
- * singleLevel (1),
- * wholeSubtree (2)
- * },
- * derefAliases ENUMERATED {
- * neverDerefaliases (0),
- * derefInSearching (1),
- * derefFindingBaseObj (2),
- * alwaysDerefAliases (3)
- * },
- * sizelimit INTEGER (0 .. 65535),
- * timelimit INTEGER (0 .. 65535),
- * attrsOnly BOOLEAN,
- * filter Filter,
- * attributes SEQUENCE OF AttributeType
- * }
- */
-
- /* baseObject, scope, derefAliases, sizelimit, timelimit, attrsOnly */
- if ( ber_scanf( ber, "{aiiiib", &base, &scope, &deref, &sizelimit, &timelimit, &attrsonly ) == LBER_ERROR ){
- slapi_ch_free((void**)&base );
- log_search_access (pb, "???", -1, "???", "decoding error");
- send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL );
- return;
- }
-
- /*
- * ignore negative time and size limits since they make no sense
- */
- if ( timelimit < 0 ) {
+ /*
+ * Parse the search request. It looks like this:
+ *
+ * SearchRequest := [APPLICATION 3] SEQUENCE {
+ * baseObject DistinguishedName,
+ * scope ENUMERATED {
+ * baseObject (0),
+ * singleLevel (1),
+ * wholeSubtree (2)
+ * },
+ * derefAliases ENUMERATED {
+ * neverDerefaliases (0),
+ * derefInSearching (1),
+ * derefFindingBaseObj (2),
+ * alwaysDerefAliases (3)
+ * },
+ * sizelimit INTEGER (0 .. 65535),
+ * timelimit INTEGER (0 .. 65535),
+ * attrsOnly BOOLEAN,
+ * filter Filter,
+ * attributes SEQUENCE OF AttributeType
+ * }
+ */
+
+ /* baseObject, scope, derefAliases, sizelimit, timelimit, attrsOnly */
+ if ( ber_scanf( ber, "{aiiiib", &base, &scope, &deref, &sizelimit, &timelimit, &attrsonly ) == LBER_ERROR ){
+ slapi_ch_free((void**)&base );
+ log_search_access (pb, "???", -1, "???", "decoding error");
+ send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL );
+ return;
+ }
+
+ /*
+ * ignore negative time and size limits since they make no sense
+ */
+ if ( timelimit < 0 ) {
timelimit = 0;
- }
- if ( sizelimit < 0 ) {
+ }
+ if ( sizelimit < 0 ) {
sizelimit = 0;
- }
+ }
- if ( scope != LDAP_SCOPE_BASE && scope != LDAP_SCOPE_ONELEVEL
+ if ( scope != LDAP_SCOPE_BASE && scope != LDAP_SCOPE_ONELEVEL
&& scope != LDAP_SCOPE_SUBTREE ) {
log_search_access (pb, base, scope, "???", "Unknown search scope");
- send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
+ send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"Unknown search scope", 0, NULL );
- goto free_and_return;
- }
- /* check and record the scope for snmp */
- if ( scope == LDAP_SCOPE_ONELEVEL) {
+ goto free_and_return;
+ }
+ /* check and record the scope for snmp */
+ if ( scope == LDAP_SCOPE_ONELEVEL) {
/* count the one level search request */
snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsOneLevelSearchOps);
- } else if (scope == LDAP_SCOPE_SUBTREE) {
+ } else if (scope == LDAP_SCOPE_SUBTREE) {
/* count the subtree search request */
snmp_increment_counter(g_get_global_snmp_vars()->ops_tbl.dsWholeSubtreeSearchOps);
- }
+ }
- /* filter - returns a "normalized" version */
- filter = NULL;
- fstr = NULL;
- if ( (err = get_filter( pb->pb_conn, ber, scope, &filter, &fstr )) != 0 ) {
+ /* filter - returns a "normalized" version */
+ filter = NULL;
+ fstr = NULL;
+ if ( (err = get_filter( pb->pb_conn, ber, scope, &filter, &fstr )) != 0 ) {
char *errtxt;
if ( LDAP_UNWILLING_TO_PERFORM == err ) {
@@ -159,18 +160,18 @@
errtxt = "Bad search filter";
}
log_search_access( pb, base, scope, "???", errtxt );
- send_ldap_result( pb, err, NULL, errtxt, 0, NULL );
- goto free_and_return;
- }
-
- /* attributes */
- attrs = NULL;
- if ( ber_scanf( ber, "{v}}", &attrs ) == LBER_ERROR ) {
+ send_ldap_result( pb, err, NULL, errtxt, 0, NULL );
+ goto free_and_return;
+ }
+
+ /* attributes */
+ attrs = NULL;
+ if ( ber_scanf( ber, "{v}}", &attrs ) == LBER_ERROR ) {
log_search_access (pb, base, scope, fstr, "decoding error");
- send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
+ send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
NULL );
- goto free_and_return;
- }
+ goto free_and_return;
+ }
/*
* This search is performed against the legacy consumer, so ask explicitly
@@ -186,56 +187,128 @@
charray_add(&attrs, slapi_attr_syntax_normalize("aci"));
charray_add(&attrs, slapi_attr_syntax_normalize(LDAP_ALL_USER_ATTRS));
}
- else
+ }
+
+ if ( attrs != NULL ) {
+ int gerattrsiz = 1;
+ int gerattridx = 0;
+ int aciin = 0;
+ /*
+ * . store gerattrs if any
+ * . add "aci" once if "*" is given
+ */
+ for ( i = 0; attrs[i] != NULL; i++ )
{
- for ( i = 0; attrs[i] != NULL; i++ )
+ char *p = NULL;
+ /* check if @<objectclass> is included */
+ p = strchr(attrs[i], '@');
+ if ( p && '\0' != *(p+1) ) /* don't store "*@", e.g. */
{
- if ( strcasecmp(attrs[i], LDAP_ALL_USER_ATTRS) == 0 )
+ int j = 0;
+ if (gerattridx + 1 >= gerattrsiz)
{
- charray_add(&attrs, slapi_attr_syntax_normalize("aci"));
- break;
+ char **tmpgerattrs;
+ gerattrsiz *= 2;
+ tmpgerattrs =
+ (char **)slapi_ch_calloc(1, gerattrsiz*sizeof(char *));
+ if (NULL != gerattrs)
+ {
+ memcpy(tmpgerattrs, gerattrs, gerattrsiz*sizeof(char *));
+ slapi_ch_free((void **)&gerattrs);
+ }
+ gerattrs = tmpgerattrs;
}
+ for ( j = 0; gerattrs; j++ )
+ {
+ char *attri = NULL;
+ if ( NULL == gerattrs[j] )
+ {
+ if (0 == j)
+ {
+ /* first time */
+ gerattrs[gerattridx++] = attrs[i];
+ /* get rid of "@<objectclass>" part from the attr
+ list, which is needed only in gerattr list */
+ *p = '\0';
+ attri = slapi_ch_strdup(attrs[i]);
+ attrs[i] = attri;
+ *p = '@';
+ }
+ else
+ {
+ break; /* done */
+ }
+ }
+ else if ( 0 == strcasecmp( attrs[i], gerattrs[j] ))
+ {
+ /* skip if attrs[i] is already in gerattrs */
+ continue;
+ }
+ else
+ {
+ char *q = strchr(gerattrs[j], '@'); /* q never be 0 */
+ if ( 0 != strcasecmp( p+1, q+1 ))
+ {
+ /* you don't want to display the same template
+ entry multiple times */
+ gerattrs[gerattridx++] = attrs[i];
+ }
+ /* get rid of "@<objectclass>" part from the attr
+ list, which is needed only in gerattr list */
+ *p = '\0';
+ attri = slapi_ch_strdup(attrs[i]);
+ attrs[i] = attri;
+ *p = '@';
+ }
+ }
+ }
+ else if ( !aciin && strcasecmp(attrs[i], LDAP_ALL_USER_ATTRS) == 0 )
+ {
+ charray_add(&attrs, slapi_attr_syntax_normalize("aci"));
+ aciin = 1;
}
}
+ if (NULL != gerattrs)
+ {
+ gerattrs[gerattridx] = NULL;
+ }
+
+ operation->o_searchattrs = cool_charray_dup( attrs );
+ for ( i = 0; attrs[i] != NULL; i++ ) {
+ char *type;
+
+ type = slapi_attr_syntax_normalize(attrs[i]);
+ slapi_ch_free( (void**)&(attrs[i]) );
+ attrs[i] = type;
+ }
+ }
+ if ( slapd_ldap_debug & LDAP_DEBUG_ARGS ) {
+ char abuf[ 1024 ], *astr;
+
+ if ( NULL == attrs ) {
+ astr = "ALL";
+ } else {
+ strarray2str( attrs, abuf, sizeof( abuf ), 1 /* include quotes */);
+ astr = abuf;
+ }
+ slapi_log_error( SLAPI_LOG_ARGS, NULL, "SRCH base=\"%s\" "
+ "scope=%d deref=%d "
+ "sizelimit=%d timelimit=%d attrsonly=%d filter=\"%s\" "
+ "attrs=%s\n", base, scope, deref, sizelimit, timelimit,
+ attrsonly, fstr, astr );
}
- if ( attrs != NULL ) {
- operation->o_searchattrs = cool_charray_dup( attrs );
- for ( i = 0; attrs[i] != NULL; i++ ) {
- char *type;
-
- type = slapi_attr_syntax_normalize(attrs[i]);
- slapi_ch_free( (void**)&(attrs[i]) );
- attrs[i] = type;
- }
- }
- if ( slapd_ldap_debug & LDAP_DEBUG_ARGS ) {
- char abuf[ 1024 ], *astr;
-
- if ( NULL == attrs ) {
- astr = "ALL";
- } else {
- strarray2str( attrs, abuf, sizeof( abuf ), 1 /* include quotes */);
- astr = abuf;
- }
- slapi_log_error( SLAPI_LOG_ARGS, NULL, "SRCH base=\"%s\" "
- "scope=%d deref=%d "
- "sizelimit=%d timelimit=%d attrsonly=%d filter=\"%s\" "
- "attrs=%s\n", base, scope, deref, sizelimit, timelimit,
- attrsonly, fstr, astr );
- }
-
- /*
- * in LDAPv3 there can be optional control extensions on
- * the end of an LDAPMessage. we need to read them in and
- * pass them to the backend. get_ldapmessage_controls()
- * reads the controls and sets any we know about in the pb.
- */
- if ( (err = get_ldapmessage_controls( pb, ber, NULL )) != 0 ) {
+ /*
+ * in LDAPv3 there can be optional control extensions on
+ * the end of an LDAPMessage. we need to read them in and
+ * pass them to the backend. get_ldapmessage_controls()
+ * reads the controls and sets any we know about in the pb.
+ */
+ if ( (err = get_ldapmessage_controls( pb, ber, NULL )) != 0 ) {
log_search_access (pb, base, scope, fstr, "failed to decode LDAP controls");
- send_ldap_result( pb, err, NULL, NULL, 0, NULL );
- goto free_and_return;
- }
+ send_ldap_result( pb, err, NULL, NULL, 0, NULL );
+ goto free_and_return;
+ }
/* we support persistent search for regular operations only */
if ( slapi_control_present( operation->o_params.request_controls,
@@ -254,15 +327,16 @@
}
}
- slapi_pblock_set( pb, SLAPI_SEARCH_TARGET, base );
+ slapi_pblock_set( pb, SLAPI_SEARCH_TARGET, base );
slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET_DN, slapi_ch_strdup(base) );
- slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, &scope );
- slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, &deref );
- slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, filter );
- slapi_pblock_set( pb, SLAPI_SEARCH_STRFILTER, fstr );
- slapi_pblock_set( pb, SLAPI_SEARCH_ATTRS, attrs );
- slapi_pblock_set( pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
- slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &operation->o_isroot );
+ slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, &scope );
+ slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, &deref );
+ slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, filter );
+ slapi_pblock_set( pb, SLAPI_SEARCH_STRFILTER, fstr );
+ slapi_pblock_set( pb, SLAPI_SEARCH_ATTRS, attrs );
+ slapi_pblock_set( pb, SLAPI_SEARCH_GERATTRS, gerattrs );
+ slapi_pblock_set( pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
+ slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &operation->o_isroot );
slapi_pblock_set( pb, SLAPI_SEARCH_SIZELIMIT, &sizelimit );
slapi_pblock_set( pb, SLAPI_SEARCH_TIMELIMIT, &timelimit );
@@ -277,23 +351,22 @@
slapi_pblock_get(pb, SLAPI_SEARCH_TARGET, &new_base);
slapi_pblock_get (pb, SLAPI_PLUGIN_OPRETURN, &rc);
- slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, &filter );
+ slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, &filter );
- if ( psearch && rc == 0 ) {
+ if ( psearch && rc == 0 ) {
ps_add( pb, changetypes, send_entchg_controls );
- }
+ }
free_and_return:;
- if ( !psearch || rc < 0 ) {
+ if ( !psearch || rc < 0 ) {
if(original_base != new_base) {
slapi_ch_free_string(&new_base);
}
- slapi_ch_free_string(&base);
- slapi_ch_free_string(&fstr);
- slapi_filter_free( filter, 1 );
- if ( attrs != NULL ) {
- charray_free( attrs );
- }
+ slapi_ch_free_string(&base);
+ slapi_ch_free_string(&fstr);
+ slapi_filter_free( filter, 1 );
+ charray_free( attrs ); /* passing NULL is fine */
+ charray_free( gerattrs ); /* passing NULL is fine */
/*
* Fix for defect 526719 / 553356 : Persistent search op failed.
* Marking it as non-persistent so that operation resources get freed
@@ -304,7 +377,7 @@
/* we strdup'd this above - need to free */
slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &base);
slapi_ch_free_string(&base);
- }
+ }
}
static void log_search_access (Slapi_PBlock *pb, const char *base, int scope, const char *fstr, const char *msg)
Index: slapi-plugin.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slapi-plugin.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- slapi-plugin.h 4 Jun 2008 22:22:55 -0000 1.22
+++ slapi-plugin.h 27 Jun 2008 19:28:21 -0000 1.23
@@ -72,6 +72,9 @@
#define SLAPI_OP_FLAG_NEVER_CHAIN 0x00800 /* Do not chain the operation */
#define SLAPI_OP_FLAG_NO_ACCESS_CHECK 0x10000 /* Do not check for access control - bypass them */
+#define SLAPI_OC_FLAG_REQUIRED 0x0001
+#define SLAPI_OC_FLAG_ALLOWED 0x0002
+
/*
* access control levels
*/
@@ -1703,6 +1706,7 @@
#define SLAPI_SEARCH_FILTER 114
#define SLAPI_SEARCH_STRFILTER 115
#define SLAPI_SEARCH_ATTRS 116
+#define SLAPI_SEARCH_GERATTRS 1160
#define SLAPI_SEARCH_ATTRSONLY 117
#define SLAPI_SEARCH_IS_AND 118
Index: slapi-private.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slapi-private.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- slapi-private.h 10 Jun 2008 18:50:07 -0000 1.23
+++ slapi-private.h 27 Jun 2008 19:28:21 -0000 1.24
@@ -574,6 +574,7 @@
char **search_attrs;
int search_attrsonly;
int search_is_and;
+ char **search_gerattrs;
} p_search;
struct abandon_parameters
@@ -726,6 +727,11 @@
/* return the list of attr defined in the schema matching the attr flags */
char ** slapi_schema_list_attribute_names(unsigned long flag);
+/* return the list of attributes belonging to the objectclass */
+char ** slapi_schema_list_objectclass_attributes(const char *ocname_or_oid,
+ PRUint32 flags);
+char * slapi_schema_get_superior_name(const char *ocname_or_oid);
+
CSN *dup_global_schema_csn();
/* misc function for the chaining backend */
@@ -787,13 +793,14 @@
*/
void charray_add( char ***a, char *s );
void charray_merge( char ***a, char **s, int copy_strs );
+void charray_merge_nodup( char ***a, char **s, int copy_strs );
void charray_free( char **array );
int charray_inlist( char **a, char *s );
int charray_utf8_inlist( char **a, char *s );
char ** charray_dup( char **a );
char ** str2charray( char *str, char *brkstr );
char ** str2charray_ext( char *str, char *brkstr, int allow_dups );
-int charray_remove(char **a,const char *s);
+int charray_remove(char **a, const char *s, int freeit);
char ** cool_charray_dup( char **a );
void cool_charray_free( char **array );
void charray_subtract( char **a, char **b, char ***c );
@@ -1124,10 +1131,6 @@
const char* escape_string (const char* str, char buf[BUFSIZ]);
const char* escape_string_with_punctuation(const char* str, char buf[BUFSIZ]);
const char* escape_filter_value(const char* str, int len, char buf[BUFSIZ]);
-void charray_add( char ***a, char *s );
-void charray_free(char **array);
-int charray_remove(char **a,const char *s);
-int charray_inlist( char **a, char *s );
char *slapi_berval_get_string_copy(const struct berval *bval);
14 years, 11 months
[Fedora-directory-commits] dsgw/pbconfig display-orgperson.html.in, 1.2, 1.3
by Doctor Conrad
Author: rmeggins
Update of /cvs/dirsec/dsgw/pbconfig
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv31194/dsgw/pbconfig
Modified Files:
display-orgperson.html.in
Log Message:
Resolves: bug 171353
Bug Description: Unable to download a certificate from Gateway/Phonebook
Reviewed by: trivial
Fix Description: Have to support both "userCertificate;binary" and "userCertificate"
Platforms tested: HP-UX
Flag Day: no
Doc impact: no
Index: display-orgperson.html.in
===================================================================
RCS file: /cvs/dirsec/dsgw/pbconfig/display-orgperson.html.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- display-orgperson.html.in 6 Mar 2008 22:00:40 -0000 1.2
+++ display-orgperson.html.in 27 Jun 2008 18:49:18 -0000 1.3
@@ -164,6 +164,14 @@
onMouseOver="top.status='Retrieve this person\'s security certificate.'; return true"><img src="@cgiuri@/lang?<!-- GCONTEXT -->&file=tiny_cert.gif" border="0" height="20" width="20" alt="Click to retrieve this
person's security certificate." align="top"><span style="text-decoration:none;color:black"> Get Certificate</span></a>
<!-- ENDIF -->
+<!-- DS_ATTRIBUTE "attr=userCertificate" "type=hidden" "options=typeonly" -->
+<!-- IF "AttributeHasValues" "userCertificate" -->
+
+<a href=
+<!-- DS_ATTRIBUTE "attr=userCertificate" "options=link" "mimetype=application/x-x509-email-cert" -->
+onMouseOver="top.status='Retrieve this person\'s security certificate.'; return true"><img src="@cgiuri@/lang?<!-- GCONTEXT -->&file=tiny_cert.gif" border="0" height="20" width="20" alt="Click to retrieve this
+person's security certificate." align="top"><span style="text-decoration:none;color:black"> Get Certificate</span></a>
+<!-- ENDIF -->
</td>
</tr>
14 years, 11 months
[Fedora-directory-commits] dsgw/config/de display-ntperson.html.in, 1.2, 1.3 display-orgperson.html.in, 1.2, 1.3
by Doctor Conrad
Author: rmeggins
Update of /cvs/dirsec/dsgw/config/de
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv31194/dsgw/config/de
Modified Files:
display-ntperson.html.in display-orgperson.html.in
Log Message:
Resolves: bug 171353
Bug Description: Unable to download a certificate from Gateway/Phonebook
Reviewed by: trivial
Fix Description: Have to support both "userCertificate;binary" and "userCertificate"
Platforms tested: HP-UX
Flag Day: no
Doc impact: no
Index: display-ntperson.html.in
===================================================================
RCS file: /cvs/dirsec/dsgw/config/de/display-ntperson.html.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- display-ntperson.html.in 6 Mar 2008 22:00:11 -0000 1.2
+++ display-ntperson.html.in 27 Jun 2008 18:49:17 -0000 1.3
@@ -106,6 +106,13 @@
>Download Certificate</A>
<!-- ENDIF -->
+<!-- DS_ATTRIBUTE "attr=userCertificate" "type=hidden" "options=typeonly" -->
+<!-- IF "AttributeHasValues" "userCertificate" -->
+<A HREF=
+<!-- DS_ATTRIBUTE "attr=userCertificate" "options=link" "mimetype=application/x-x509-ca-cert" -->
+>Download Certificate</A>
+<!-- ENDIF -->
+
<!-- DS_ATTRIBUTE "attr=audio" "type=hidden" "options=typeonly" -->
<!-- IF "AttributeHasValues" "audio" -->
Index: display-orgperson.html.in
===================================================================
RCS file: /cvs/dirsec/dsgw/config/de/display-orgperson.html.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- display-orgperson.html.in 6 Mar 2008 22:00:11 -0000 1.2
+++ display-orgperson.html.in 27 Jun 2008 18:49:17 -0000 1.3
@@ -107,6 +107,13 @@
>Zertifikat laden</A>
<!-- ENDIF -->
+<!-- DS_ATTRIBUTE "attr=userCertificate" "type=hidden" "options=typeonly" -->
+<!-- IF "AttributeHasValues" "userCertificate" -->
+<A HREF=
+<!-- DS_ATTRIBUTE "attr=userCertificate" "options=link" "mimetype=application/x-x509-ca-cert" -->
+>Zertifikat laden</A>
+<!-- ENDIF -->
+
<!-- DS_ATTRIBUTE "attr=audio" "type=hidden" "options=typeonly" -->
<!-- IF "AttributeHasValues" "audio" -->
14 years, 11 months