Patch: aclparse.c bugs (ITS#1752) ================ Written by Hallvard B. Furuseth and placed into the public domain. This software is not subject to any license of the University of Oslo. ================ Bug fixes: - acl_regex_normalized_dn(pattern): * used pattern->bv_len even though it claimed not to, * would walk past the end of strings that ended (incorrectly) with a single '\'. - style=regex checked for "^.*$$" twice but not for "^.*$". - the code did not notice if dnNormalize2() failed, and would (at least in one case) treat a bad DN as '*'. Some cleanup: - changed regtest() to return void, since the return value was unused. - changed acl_regex_normalized_dn() to take a string input argument instead of a half-filled berval, it looks saner that way. Hallvard B. Furuseth , April 2002. diff -u2 -r servers/slapd/aclparse.c~ servers/slapd/aclparse.c --- servers/slapd/aclparse.c~ Thu Apr 4 11:15:40 2002 +++ servers/slapd/aclparse.c Sun Apr 14 10:37:54 2002 @@ -23,5 +23,5 @@ static void acl_usage(void) LDAP_GCCATTR((noreturn)); -static void acl_regex_normalized_dn(struct berval *pattern); +static void acl_regex_normalized_dn(const char *src, struct berval *pat); #ifdef LDAP_DEBUG @@ -30,5 +30,5 @@ #endif -static int +static void regtest(const char *fname, int lineno, char *pat) { int e; @@ -80,8 +80,6 @@ fname, lineno, pat, error ); acl_usage(); - return(0); } regfree(&re); - return(1); } @@ -167,5 +165,5 @@ || strcmp(right, ".*$") == 0 || strcmp(right, "^.*") == 0 - || strcmp(right, "^.*$$") == 0 + || strcmp(right, "^.*$") == 0 || strcmp(right, ".*$$") == 0 || strcmp(right, "^.*$$") == 0 ) @@ -175,6 +173,5 @@ } else { - a->acl_dn_pat.bv_val = right; - acl_regex_normalized_dn( &a->acl_dn_pat ); + acl_regex_normalized_dn( right, &a->acl_dn_pat ); } } else if ( strcasecmp( style, "base" ) == 0 ) { @@ -237,5 +234,11 @@ if ( a->acl_dn_style != ACL_STYLE_REGEX ) { struct berval bv; - dnNormalize2( NULL, &a->acl_dn_pat, &bv); + rc = dnNormalize2( NULL, &a->acl_dn_pat, &bv); + if ( rc != LDAP_SUCCESS ) { + fprintf( stderr, + "%s: line %d: bad DN \"%s\"\n", + fname, lineno, a->acl_dn_pat.bv_val ); + acl_usage(); + } free( a->acl_dn_pat.bv_val ); a->acl_dn_pat = bv; @@ -374,6 +377,5 @@ } else { - bv.bv_val = right; - acl_regex_normalized_dn( &bv ); + acl_regex_normalized_dn( right, &bv ); if ( !ber_bvccmp( &bv, '*' ) ) { regtest(fname, lineno, bv.bv_val); @@ -403,5 +405,11 @@ if ( sty != ACL_STYLE_REGEX && expand == 0 ) { - dnNormalize2(NULL, &bv, &b->a_dn_pat); + rc = dnNormalize2(NULL, &bv, &b->a_dn_pat); + if ( rc != LDAP_SUCCESS ) { + fprintf( stderr, + "%s: line %d: bad DN \"%s\"\n", + fname, lineno, bv.bv_val ); + acl_usage(); + } free(bv.bv_val); } else { @@ -491,6 +499,5 @@ b->a_group_style = sty; if (sty == ACL_STYLE_REGEX) { - bv.bv_val = right; - acl_regex_normalized_dn( &bv ); + acl_regex_normalized_dn( right, &bv ); if ( !ber_bvccmp( &bv, '*' ) ) { regtest(fname, lineno, bv.bv_val); @@ -499,5 +506,11 @@ } else { ber_str2bv( right, 0, 0, &bv ); - dnNormalize2( NULL, &bv, &b->a_group_pat ); + rc = dnNormalize2( NULL, &bv, &b->a_group_pat ); + if ( rc != LDAP_SUCCESS ) { + fprintf( stderr, + "%s: line %d: bad DN \"%s\"\n", + fname, lineno, right ); + acl_usage(); + } } @@ -626,6 +639,5 @@ b->a_peername_style = sty; if (sty == ACL_STYLE_REGEX) { - bv.bv_val = right; - acl_regex_normalized_dn( &bv ); + acl_regex_normalized_dn( right, &bv ); if ( !ber_bvccmp( &bv, '*' ) ) { regtest(fname, lineno, bv.bv_val); @@ -662,6 +674,5 @@ b->a_sockname_style = sty; if (sty == ACL_STYLE_REGEX) { - bv.bv_val = right; - acl_regex_normalized_dn( &bv ); + acl_regex_normalized_dn( right, &bv ); if ( !ber_bvccmp( &bv, '*' ) ) { regtest(fname, lineno, bv.bv_val); @@ -705,6 +716,5 @@ b->a_domain_expand = expand; if (sty == ACL_STYLE_REGEX) { - bv.bv_val = right; - acl_regex_normalized_dn( &bv ); + acl_regex_normalized_dn( right, &bv ); if ( !ber_bvccmp( &bv, '*' ) ) { regtest(fname, lineno, bv.bv_val); @@ -741,6 +751,5 @@ b->a_sockurl_style = sty; if (sty == ACL_STYLE_REGEX) { - bv.bv_val = right; - acl_regex_normalized_dn( &bv ); + acl_regex_normalized_dn( right, &bv ); if ( !ber_bvccmp( &bv, '*' ) ) { regtest(fname, lineno, bv.bv_val); @@ -1271,23 +1280,24 @@ /* + * Set pattern to a "normalized" DN from src. * At present it simply eats the (optional) space after * a RDN separator (,) * Eventually will evolve in a more complete normalization - * - * Note that the input berval only needs bv_val, it ignores - * the input bv_len and sets it on return. */ static void acl_regex_normalized_dn( + const char *src, struct berval *pattern ) { char *str, *p; + ber_len_t len; - str = ch_strdup( pattern->bv_val ); + str = ch_strdup( src ); + len = strlen( src ); for ( p = str; p && p[ 0 ]; p++ ) { /* escape */ - if ( p[ 0 ] == '\\' ) { + if ( p[ 0 ] == '\\' && p[ 1 ] ) { /* * if escaping a hex pair we should @@ -1310,5 +1320,5 @@ /* DO NOTHING */ ; } - AC_MEMCPY( p+1, q, pattern->bv_len-(q-str)+1); + AC_MEMCPY( p+1, q, len-(q-str)+1); } }