Author: rmeggins
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv4939/ldapserver/ldap/servers/slapd
Modified Files:
dn.c slapi-plugin.h
Log Message:
Bug(s) fixed: 179137
Bug Description: recursion causes OOM with bad DN in dn2ancestor
Reviewed by: All (Thanks!)
Fix Description:
The fix looks scary, but I thought it would be best to get rid of
recursion entirely (ugh - recursion in a multi threaded server - this
isn't lisp . . .). Along with eliminating recursion, I created a new
function called slapi_dn_find_parent that just returns a pointer to the
beginning of the parent of the given dn, rather than returning a copy
(as in slapi_dn_parent), to eliminate malloc/free in cases where it is
unnecessary such as iterating through the parents in an DN. The new
function is basically just the guts of slapi_dn_parent with one twist,
specifically to address the bug in question - it skips through
consecutive runs of DN separator characters. We should probably have a
function like const char *slapi_dn_is_valid(const char *) that returns
NULL if the given DN is valid or returns a pointer to the first invalid
character if not. We could probably save a lot of time in processing
bad or malicious client requests.
Anyway, back to dn2ancestor. The given ancestordn must contain the
_unnormalized_ parent DN, since some clients get irritated when they get
back an DN in a different form than given. However, we need to have a
normalized DN to pass to dn2entry, and we cannot use a single Slapi_DN
that has both a dn and a ndn that are passed in byval (unless we add a
new API or skip the API altogether), so the variable ancestorndn holds
the normalized DN. Using the original pointer to the given sdn also
allows us to avoid malloc/free entirely.
Platforms tested: Fedora Core 4
Flag Day: no
Doc impact: no
QA impact: should be covered by regular nightly and manual testing
New Tests integrated into TET: We need a test case that calls moddn and
modify operations with really bad DNs, consisting of nothing but
thousands of ',', '+', and '=' chars.
Index: dn.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/dn.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- dn.c 8 Dec 2005 00:59:14 -0000 1.7
+++ dn.c 23 Feb 2006 20:47:59 -0000 1.8
@@ -593,8 +593,26 @@
return r;
}
-char*
-slapi_dn_parent( const char *dn )
+/*
+ * This function is used for speed. Instead of returning a newly allocated
+ * dn string that contains the parent, this function just returns a pointer
+ * to the address _within_ the given string where the parent dn of the
+ * given dn starts e.g. if you call this with "dc=example,dc=com", the
+ * function will return "dc=com" - that is, the char* returned will be the
+ * address of the 'd' after the ',' in "dc=example,dc=com".
This function
+ * also checks for bogus things like consecutive ocurrances of unquoted
+ * separators e.g. DNs like cn=foo,,,,,,,,,,,cn=bar,,,,,,,
+ * This function is useful for "interating" over a DN returning the ancestors
+ * of the given dn e.g.
+ *
+ * const char *dn = somedn;
+ * while (dn = slapi_dn_find_parent(dn)) {
+ * see if parent exists
+ * etc.
+ * }
+ */
+const char*
+slapi_dn_find_parent( const char *dn )
{
const char *s;
int inquote;
@@ -621,14 +639,34 @@
} else {
if ( *s == '"' )
inquote = 1;
- else if ( DNSEPARATOR( *s ) )
- return( slapi_ch_strdup( s + 1 ) );
+ else {
+ if ( DNSEPARATOR( *s ) ) {
+ while ( *s && DNSEPARATOR( *s ) ) {
+ ++s;
+ }
+ if (*s) {
+ return( s );
+ }
+ }
+ }
}
}
return( NULL );
}
+char*
+slapi_dn_parent( const char *dn )
+{
+ const char *s = slapi_dn_find_parent(dn);
+
+ if ( s == NULL || *s == '\0' ) {
+ return( NULL );
+ }
+
+ return( slapi_ch_strdup( s ) );
+}
+
/*
* slapi_dn_issuffix - tells whether suffix is a suffix of dn. both dn
* and suffix must be normalized.
Index: slapi-plugin.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slapi-plugin.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- slapi-plugin.h 19 Apr 2005 22:07:37 -0000 1.8
+++ slapi-plugin.h 23 Feb 2006 20:47:59 -0000 1.9
@@ -362,6 +362,7 @@
char *slapi_dn_ignore_case( char *dn );
char *slapi_dn_normalize_case( char *dn );
char *slapi_dn_beparent( Slapi_PBlock *pb, const char *dn );
+const char *slapi_dn_find_parent( const char *dn );
char *slapi_dn_parent( const char *dn );
int slapi_dn_issuffix( const char *dn, const char *suffix );
int slapi_dn_isparent( const char *parentdn, const char *childdn );