From: Howard Chu Date: Wed, 26 Dec 2001 04:17:49 +0000 (+0000) Subject: More struct berval changes, dnNormalize migration... X-Git-Tag: LDBM_PRE_GIANT_RWLOCK~517 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=b96645af7d2bfc29ec48e8ca24d1206224373b04;p=openldap More struct berval changes, dnNormalize migration... --- diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index 321522d3ea..79ca468e5d 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -48,10 +48,17 @@ static int aci_mask( static int regex_matches( char *pat, char *str, char *buf, regmatch_t *matches); static void string_expand( - char *newbuf, int bufsiz, char *pattern, + struct berval *newbuf, char *pattern, char *match, regmatch_t *matches); -char **aci_set_gather (void *cookie, char *name, char *attr); +typedef struct AciSetCookie { + Backend *be; + Entry *e; + Connection *conn; + Operation *op; +} AciSetCookie; + +char **aci_set_gather (void *cookie, char *name, struct berval *attr); static int aci_match_set ( struct berval *subj, Backend *be, Entry *e, Connection *conn, Operation *op, int setref ); @@ -745,8 +752,11 @@ acl_mask( } } - if ( b->a_group_pat != NULL && op->o_ndn.bv_len != 0 ) { + if ( b->a_group_pat.bv_len && op->o_ndn.bv_len ) { char buf[1024]; + struct berval bv = {1024, buf }; + struct berval *ndn = NULL; + int rc; /* b->a_group is an unexpanded entry name, expanded it should be an * entry with objectclass group* and we test to see if odn is one of @@ -754,18 +764,21 @@ acl_mask( */ /* see if asker is listed in dnattr */ if ( b->a_group_style == ACL_STYLE_REGEX ) { - string_expand(buf, sizeof(buf), b->a_group_pat, e->e_ndn, matches); - if ( dn_normalize(buf) == NULL ) { + string_expand(&bv, b->a_group_pat.bv_val, e->e_ndn, matches); + if ( dnNormalize(NULL, &bv, &ndn) != LDAP_SUCCESS ) { /* did not expand to a valid dn */ continue; } + bv = *ndn; } else { - strncpy( buf, b->a_group_pat, sizeof(buf) - 1 ); - buf[sizeof(buf) - 1] = 0; + bv = b->a_group_pat; } - if (backend_group(be, conn, op, e, buf, &op->o_ndn, - b->a_group_oc, b->a_group_at) != 0) + rc = backend_group(be, conn, op, e, &bv, &op->o_ndn, + b->a_group_oc, b->a_group_at); + if ( ndn ) + ber_bvfree( ndn ); + if ( rc != 0 ) { continue; } @@ -1117,6 +1130,15 @@ acl_check_modlist( return( 1 ); } +static void +aci_bvdup( struct berval *dest, struct berval *src ) +{ + dest->bv_val = ch_malloc( src->bv_len + 1); + AC_MEMCPY( dest->bv_val, src->bv_val, src->bv_len ); + dest->bv_val[src->bv_len] = 0; + dest->bv_len = src->bv_len; +} + static char * aci_bvstrdup( struct berval *bv ) { @@ -1190,17 +1212,12 @@ aci_get_part( } char ** -aci_set_gather (void *cookie, char *name, char *attr) +aci_set_gather (void *cookie, char *name, struct berval *attr) { - struct { - Backend *be; - Entry *e; - Connection *conn; - Operation *op; - } *cp = (void *)cookie; + AciSetCookie *cp = cookie; struct berval **bvals = NULL; char **vals = NULL; - char *ndn; + struct berval bv, *ndn = NULL; int i; /* this routine needs to return the bervals instead of @@ -1208,27 +1225,27 @@ aci_set_gather (void *cookie, char *name, char *attr) * also return the syntax or some "comparison cookie". */ - if ((ndn = ch_strdup(name)) != NULL) { - if (dn_normalize(ndn) != NULL) { - const char *text; - AttributeDescription *desc = NULL; - if (slap_str2ad(attr, &desc, &text) == LDAP_SUCCESS) { - backend_attribute(cp->be, NULL, NULL, - cp->e, ndn, desc, &bvals); - if (bvals != NULL) { - for (i = 0; bvals[i] != NULL; i++) { } - vals = ch_calloc(i + 1, sizeof(char *)); - if (vals != NULL) { - while (--i >= 0) { - vals[i] = bvals[i]->bv_val; - bvals[i]->bv_val = NULL; - } + bv.bv_val = name; + bv.bv_len = strlen( name ); + if (dnNormalize(NULL, &bv, &ndn) == LDAP_SUCCESS) { + const char *text; + AttributeDescription *desc = NULL; + if (slap_bv2ad(attr, &desc, &text) == LDAP_SUCCESS) { + backend_attribute(cp->be, NULL, NULL, + cp->e, ndn, desc, &bvals); + if (bvals != NULL) { + for (i = 0; bvals[i] != NULL; i++) { } + vals = ch_calloc(i + 1, sizeof(char *)); + if (vals != NULL) { + while (--i >= 0) { + vals[i] = bvals[i]->bv_val; + bvals[i]->bv_val = NULL; } - ber_bvecfree(bvals); } + ber_bvecfree(bvals); } } - ch_free(ndn); + ber_bvfree(ndn); } return(vals); } @@ -1245,53 +1262,42 @@ aci_match_set ( { char *set = NULL; int rc = 0; - struct { - Backend *be; - Entry *e; - Connection *conn; - Operation *op; - } cookie; + AciSetCookie cookie; if (setref == 0) { set = aci_bvstrdup(subj); } else { - struct berval bv; - char *subjdn; - char *setat; + struct berval subjdn, *ndn = NULL; + struct berval setat; struct berval **bvals; const char *text; AttributeDescription *desc = NULL; /* format of string is "entry/setAttrName" */ - if (aci_get_part(subj, 0, '/', &bv) < 0) { + if (aci_get_part(subj, 0, '/', &subjdn) < 0) { return(0); } - subjdn = aci_bvstrdup(&bv); - if ( subjdn == NULL ) { - return(0); + if ( aci_get_part(subj, 1, '/', &setat) < 0 ) { + setat.bv_val = SLAPD_ACI_SET_ATTR; + setat.bv_len = sizeof(SLAPD_ACI_SET_ATTR)-1; } - - if ( aci_get_part(subj, 1, '/', &bv) < 0 ) { - setat = ch_strdup( SLAPD_ACI_SET_ATTR ); - } else { - setat = aci_bvstrdup(&bv); - } - if ( setat != NULL ) { - if ( dn_normalize(subjdn) != NULL - && slap_str2ad(setat, &desc, &text) == LDAP_SUCCESS ) + if ( setat.bv_val != NULL ) { + if ( dnNormalize(NULL, &subjdn, &ndn) == LDAP_SUCCESS + && slap_bv2ad(&setat, &desc, &text) == LDAP_SUCCESS ) { backend_attribute(be, NULL, NULL, e, - subjdn, desc, &bvals); + &subjdn, desc, &bvals); if ( bvals != NULL ) { if ( bvals[0] != NULL ) set = ch_strdup(bvals[0]->bv_val); ber_bvecfree(bvals); } } - ch_free(setat); + if (ndn) + ber_bvfree(ndn); } - ch_free(subjdn); + ch_free(subjdn.bv_val); } if (set != NULL) { @@ -1463,8 +1469,8 @@ aci_list_get_rights( static int aci_group_member ( struct berval *subj, - const char *defgrpoc, - const char *defgrpat, + struct berval *defgrpoc, + struct berval *defgrpat, Backend *be, Entry *e, Connection *conn, @@ -1473,9 +1479,9 @@ aci_group_member ( ) { struct berval bv; - char *subjdn, *grpdn = NULL; - char *grpoc; - char *grpat; + char *subjdn; + struct berval grpoc; + struct berval grpat; ObjectClass *grp_oc = NULL; AttributeDescription *grp_ad = NULL; const char *text; @@ -1491,43 +1497,49 @@ aci_group_member ( return(0); } - if (aci_get_part(subj, 1, '/', &bv) < 0) { - grpoc = ch_strdup( defgrpoc ); - } else { - grpoc = aci_bvstrdup(&bv); + if (aci_get_part(subj, 1, '/', &grpoc) < 0) { + grpoc = *defgrpoc; } - if (aci_get_part(subj, 2, '/', &bv) < 0) { - grpat = ch_strdup( defgrpat ); - } else { - grpat = aci_bvstrdup(&bv); + if (aci_get_part(subj, 2, '/', &grpat) < 0) { + grpat = *defgrpat; } - rc = slap_str2ad( grpat, &grp_ad, &text ); + rc = slap_bv2ad( &grpat, &grp_ad, &text ); if( rc != LDAP_SUCCESS ) { rc = 0; goto done; } rc = 0; - grp_oc = oc_find( grpoc ); - grpdn = (char *)ch_malloc(1024); + grp_oc = oc_bvfind( &grpoc ); - if (grp_oc != NULL && grp_ad != NULL && grpdn != NULL) { - string_expand(grpdn, 1024, subjdn, e->e_ndn, matches); - if ( dn_normalize(grpdn) != NULL ) { - rc = (backend_group(be, conn, op, e, grpdn, &op->o_ndn, grp_oc, grp_ad) == 0); + if (grp_oc != NULL && grp_ad != NULL ) { + struct berval *ndn = NULL; + bv.bv_val = (char *)ch_malloc(1024); + bv.bv_len = 1024; + string_expand(&bv, subjdn, e->e_ndn, matches); + if ( dnNormalize(NULL, &bv, &ndn) == LDAP_SUCCESS ) { + rc = (backend_group(be, conn, op, e, &bv, &op->o_ndn, grp_oc, grp_ad) == 0); + ber_bvfree( ndn ); } + ch_free(bv.bv_val); } done: - ch_free(grpdn); - ch_free(grpat); - ch_free(grpoc); ch_free(subjdn); return(rc); } +static struct berval GroupClass = { + sizeof(SLAPD_GROUP_CLASS)-1, SLAPD_GROUP_CLASS }; +static struct berval GroupAttr = { + sizeof(SLAPD_GROUP_ATTR)-1, SLAPD_GROUP_ATTR }; +static struct berval RoleClass = { + sizeof(SLAPD_ROLE_CLASS)-1, SLAPD_ROLE_CLASS }; +static struct berval RoleAttr = { + sizeof(SLAPD_ROLE_ATTR)-1, SLAPD_ROLE_ATTR }; + static int aci_mask( Backend *be, @@ -1543,7 +1555,6 @@ aci_mask( ) { struct berval bv, perms, sdn; - char *subjdn; int rc; char *attr = desc->ad_cname.bv_val; @@ -1589,14 +1600,13 @@ aci_mask( return(0); if (aci_strbvcmp( "access-id", &bv ) == 0) { - subjdn = aci_bvstrdup(&sdn); - if (subjdn == NULL) - return(0); + struct berval *ndn = NULL; rc = 1; - if ( dn_normalize(subjdn) != NULL ) - if (strcasecmp(op->o_ndn.bv_val, subjdn) != 0) + if ( dnNormalize(NULL, &sdn, &ndn) == LDAP_SUCCESS ) { + if (strcasecmp(op->o_ndn.bv_val, ndn->bv_val) != 0) rc = 0; - ch_free(subjdn); + ber_bvfree(ndn); + } return(rc); } @@ -1635,11 +1645,11 @@ aci_mask( } else if (aci_strbvcmp( "group", &bv ) == 0) { - if (aci_group_member(&sdn, SLAPD_GROUP_CLASS, SLAPD_GROUP_ATTR, be, e, conn, op, matches)) + if (aci_group_member(&sdn, &GroupClass, &GroupAttr, be, e, conn, op, matches)) return(1); } else if (aci_strbvcmp( "role", &bv ) == 0) { - if (aci_group_member(&sdn, SLAPD_ROLE_CLASS, SLAPD_ROLE_ATTR, be, e, conn, op, matches)) + if (aci_group_member(&sdn, &RoleClass, &RoleAttr, be, e, conn, op, matches)) return(1); } else if (aci_strbvcmp( "set", &bv ) == 0) { @@ -1659,8 +1669,7 @@ aci_mask( static void string_expand( - char *newbuf, - int bufsiz, + struct berval *bv, char *pat, char *match, regmatch_t *matches) @@ -1671,11 +1680,11 @@ string_expand( int flag; size = 0; - newbuf[0] = '\0'; - bufsiz--; /* leave space for lone $ */ + bv->bv_val[0] = '\0'; + bv->bv_len--; /* leave space for lone $ */ flag = 0; - for ( dp = newbuf, sp = pat; size < bufsiz && *sp ; sp++) { + for ( dp = bv->bv_val, sp = pat; size < bv->bv_len && *sp ; sp++) { /* did we previously see a $ */ if (flag) { if (*sp == '$') { @@ -1690,7 +1699,7 @@ string_expand( *dp = '\0'; i = matches[n].rm_so; l = matches[n].rm_eo; - for ( ; size < 512 && i < l; size++, i++ ) { + for ( ; size < bv->bv_len && i < l; size++, i++ ) { *dp++ = match[i]; size++; } @@ -1714,15 +1723,16 @@ string_expand( } *dp = '\0'; + bv->bv_len = size; #ifdef NEW_LOGGING LDAP_LOG(( "aci", LDAP_LEVEL_DETAIL1, "string_expand: pattern = %s\n", pat )); LDAP_LOG(( "aci", LDAP_LEVEL_DETAIL1, - "string_expand: expanded = %s\n", newbuf )); + "string_expand: expanded = %s\n", bv->bv_val )); #else Debug( LDAP_DEBUG_TRACE, "=> string_expand: pattern: %s\n", pat, 0, 0 ); - Debug( LDAP_DEBUG_TRACE, "=> string_expand: expanded: %s\n", newbuf, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, "=> string_expand: expanded: %s\n", bv->bv_val, 0, 0 ); #endif } @@ -1736,11 +1746,12 @@ regex_matches( { regex_t re; char newbuf[512]; + struct berval bv = {sizeof(newbuf), newbuf}; int rc; if(str == NULL) str = ""; - string_expand(newbuf, sizeof(newbuf), pat, buf, matches); + string_expand(&bv, pat, buf, matches); if (( rc = regcomp(&re, newbuf, REG_EXTENDED|REG_ICASE))) { char error[512]; regerror(rc, &re, error, sizeof(error)); diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c index f54bb8a933..0fc89c294c 100644 --- a/servers/slapd/aclparse.c +++ b/servers/slapd/aclparse.c @@ -21,7 +21,7 @@ static void split(char *line, int splitchar, char **left, char **right); static void access_append(Access **l, Access *a); static void acl_usage(void) LDAP_GCCATTR((noreturn)); -static char *acl_regex_normalized_dn(const char *pattern); +static void acl_regex_normalized_dn(struct berval *pattern); #ifdef LDAP_DEBUG static void print_acl(Backend *be, AccessControl *a); @@ -95,6 +95,7 @@ parse_acl( { int i; char *left, *right, *style; + struct berval bv; AccessControl *a; Access *b; int rc; @@ -166,8 +167,8 @@ parse_acl( a->acl_dn_pat.bv_len = 1; } else { - a->acl_dn_pat.bv_val = acl_regex_normalized_dn( right ); - a->acl_dn_pat.bv_len = strlen( a->acl_dn_pat.bv_val ); + a->acl_dn_pat.bv_val = right; + acl_regex_normalized_dn( &a->acl_dn_pat ); } } else if ( strcasecmp( style, "base" ) == 0 ) { a->acl_dn_style = ACL_STYLE_BASE; @@ -277,7 +278,6 @@ parse_acl( /* get */ for ( ; i < argc; i++ ) { - char *pat; slap_style_t sty = ACL_STYLE_REGEX; split( argv[i], '=', &left, &right ); @@ -304,32 +304,39 @@ parse_acl( } if ( strcasecmp( argv[i], "*" ) == 0 ) { - pat = ch_strdup( "*" ); + bv.bv_val = ch_strdup( "*" ); + bv.bv_len = 1; } else if ( strcasecmp( argv[i], "anonymous" ) == 0 ) { - pat = ch_strdup( "anonymous" ); + bv.bv_val = ch_strdup( "anonymous" ); + bv.bv_len = sizeof("anonymous")-1; } else if ( strcasecmp( argv[i], "self" ) == 0 ) { - pat = ch_strdup( "self" ); + bv.bv_val = ch_strdup( "self" ); + bv.bv_len = sizeof("self")-1; } else if ( strcasecmp( argv[i], "users" ) == 0 ) { - pat = ch_strdup( "users" ); + bv.bv_val = ch_strdup( "users" ); + bv.bv_len = sizeof("users")-1; } else if ( strcasecmp( left, "dn" ) == 0 ) { if ( sty == ACL_STYLE_REGEX ) { b->a_dn_style = ACL_STYLE_REGEX; if( right == NULL ) { /* no '=' */ - pat = ch_strdup( "users" ); + bv.bv_val = ch_strdup( "users" ); + bv.bv_len = sizeof("users")-1; } else if (*right == '\0' ) { /* dn="" */ - pat = ch_strdup( "anonymous" ); + bv.bv_val = ch_strdup( "anonymous" ); + bv.bv_len = sizeof("anonymous")-1; } else if ( strcmp( right, "*" ) == 0 ) { /* dn=* */ /* any or users? users for now */ - pat = ch_strdup( "users" ); + bv.bv_val = ch_strdup( "users" ); + bv.bv_len = sizeof("users")-1; } else if ( strcmp( right, ".+" ) == 0 || strcmp( right, "^.+" ) == 0 @@ -338,7 +345,8 @@ parse_acl( || strcmp( right, ".+$$" ) == 0 || strcmp( right, "^.+$$" ) == 0 ) { - pat = ch_strdup( "users" ); + bv.bv_val = ch_strdup( "users" ); + bv.bv_len = sizeof("users")-1; } else if ( strcmp( right, ".*" ) == 0 || strcmp( right, "^.*" ) == 0 @@ -347,11 +355,13 @@ parse_acl( || strcmp( right, ".*$$" ) == 0 || strcmp( right, "^.*$$" ) == 0 ) { - pat = ch_strdup( "*" ); + bv.bv_val = ch_strdup( "*" ); + bv.bv_len = 1; } else { - pat = acl_regex_normalized_dn( right ); - regtest(fname, lineno, pat); + bv.bv_val = right; + acl_regex_normalized_dn( &bv ); + regtest(fname, lineno, bv.bv_val); } } else if ( right == NULL || *right == '\0' ) { fprintf( stderr, @@ -360,14 +370,15 @@ parse_acl( acl_usage(); } else { - pat = ch_strdup( right ); + bv.bv_val = ch_strdup( right ); + bv.bv_len = strlen( right ); } } else { - pat = NULL; + bv.bv_val = NULL; } - if( pat != NULL ) { + if( bv.bv_val != NULL ) { if( b->a_dn_pat.bv_len != 0 ) { fprintf( stderr, "%s: line %d: dn pattern already specified.\n", @@ -375,11 +386,16 @@ parse_acl( acl_usage(); } - b->a_dn_pat.bv_val = pat; - b->a_dn_pat.bv_len = strlen( pat ); + if ( sty != ACL_STYLE_REGEX ) { + struct berval *ndn = NULL; + dnNormalize(NULL, &bv, &ndn); + b->a_dn_pat = *ndn; + free(ndn); + free(bv.bv_val); + } else { + b->a_dn_pat = bv; + } b->a_dn_style = sty; - if ( sty != ACL_STYLE_REGEX ) - dn_normalize(pat); continue; } @@ -442,7 +458,7 @@ parse_acl( acl_usage(); } - if( b->a_group_pat != NULL ) { + if( b->a_group_pat.bv_len ) { fprintf( stderr, "%s: line %d: group pattern already specified.\n", fname, lineno ); @@ -461,12 +477,17 @@ parse_acl( b->a_group_style = sty; if (sty == ACL_STYLE_REGEX) { - char *tmp = acl_regex_normalized_dn( right ); - regtest(fname, lineno, tmp); - b->a_group_pat = tmp; + bv.bv_val = right; + acl_regex_normalized_dn( &bv ); + regtest(fname, lineno, bv.bv_val); + b->a_group_pat = bv; } else { - b->a_group_pat = ch_strdup( right ); - dn_normalize(b->a_group_pat); + struct berval *ndn = NULL; + bv.bv_val = right; + bv.bv_len = strlen( right ); + dnNormalize( NULL, &bv, &ndn ); + b->a_group_pat = *ndn; + free(ndn); } if (value && *value) { @@ -588,9 +609,10 @@ parse_acl( b->a_peername_style = sty; if (sty == ACL_STYLE_REGEX) { - char *tmp = acl_regex_normalized_dn( right ); - regtest(fname, lineno, tmp); - b->a_peername_pat = tmp; + bv.bv_val = right; + acl_regex_normalized_dn( &bv ); + regtest(fname, lineno, bv.bv_val); + b->a_peername_pat = bv.bv_val; } else { b->a_peername_pat = ch_strdup( right ); } @@ -614,9 +636,10 @@ parse_acl( b->a_sockname_style = sty; if (sty == ACL_STYLE_REGEX) { - char *tmp = acl_regex_normalized_dn( right ); - regtest(fname, lineno, tmp); - b->a_sockname_pat = tmp; + bv.bv_val = right; + acl_regex_normalized_dn( &bv ); + regtest(fname, lineno, bv.bv_val); + b->a_sockname_pat = bv.bv_val; } else { b->a_sockname_pat = ch_strdup( right ); } @@ -640,9 +663,10 @@ parse_acl( b->a_domain_style = sty; if (sty == ACL_STYLE_REGEX) { - char *tmp = acl_regex_normalized_dn( right ); - regtest(fname, lineno, tmp); - b->a_domain_pat = tmp; + bv.bv_val = right; + acl_regex_normalized_dn( &bv ); + regtest(fname, lineno, bv.bv_val); + b->a_domain_pat = bv.bv_val; } else { b->a_domain_pat = ch_strdup( right ); } @@ -666,9 +690,10 @@ parse_acl( b->a_sockurl_style = sty; if (sty == ACL_STYLE_REGEX) { - char *tmp = acl_regex_normalized_dn( right ); - regtest(fname, lineno, tmp); - b->a_sockurl_pat = tmp; + bv.bv_val = right; + acl_regex_normalized_dn( &bv ); + regtest(fname, lineno, bv.bv_val); + b->a_sockurl_pat = bv.bv_val; } else { b->a_sockurl_pat = ch_strdup( right ); } @@ -1158,21 +1183,20 @@ acl_usage( void ) * 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 char * +static void acl_regex_normalized_dn( - const char *pattern + struct berval *pattern ) { char *str, *p; - str = ch_strdup( pattern ); - - if ( str == NULL ) { - return( NULL ); - } + str = ch_strdup( pattern->bv_val ); - for ( p = str; p[ 0 ]; p++ ) { + for ( p = str; p && p[ 0 ]; p++ ) { /* escape */ if ( p[ 0 ] == '\\' ) { p++; @@ -1189,8 +1213,10 @@ acl_regex_normalized_dn( } } } + pattern->bv_val = str; + pattern->bv_len = p-str; - return( str ); + return; } static void @@ -1240,8 +1266,8 @@ access_free( Access *a ) free ( a->a_sockurl_pat ); if ( a->a_set_pat.bv_len ) free ( a->a_set_pat.bv_val ); - if ( a->a_group_pat ) - free ( a->a_group_pat ); + if ( a->a_group_pat.bv_len ) + free ( a->a_group_pat.bv_val ); free( a ); } @@ -1366,8 +1392,8 @@ print_access( Access *b ) fprintf( stderr, " dnattr=%s", b->a_dn_at->ad_cname.bv_val ); } - if ( b->a_group_pat != NULL ) { - fprintf( stderr, " group=%s", b->a_group_pat ); + if ( b->a_group_pat.bv_len ) { + fprintf( stderr, " group=%s", b->a_group_pat.bv_val ); if ( b->a_group_oc ) { fprintf( stderr, " objectClass: %s", diff --git a/servers/slapd/ad.c b/servers/slapd/ad.c index 730ab94763..7a39fb8f83 100644 --- a/servers/slapd/ad.c +++ b/servers/slapd/ad.c @@ -100,22 +100,17 @@ int slap_bv2ad( } /* find valid base attribute type; parse in place */ + desc.ad_cname = *bv; name = bv->bv_val; options = strchr(name, ';'); - if (options != NULL) *options = '\0'; - desc.ad_type = at_find( name ); - if (options != NULL) *options = ';'; + if (options != NULL) + desc.ad_cname.bv_len = options - name; + desc.ad_type = at_bvfind( &desc.ad_cname ); if( desc.ad_type == NULL ) { *text = "attribute type undefined"; return rtn; } - if (options != NULL) { - desc.ad_cname.bv_len = options - name; - } else { - desc.ad_cname.bv_len = bv->bv_len; - } - desc.ad_flags = SLAP_DESC_NONE; desc.ad_lang.bv_len = 0; desc.ad_lang.bv_val = NULL; diff --git a/servers/slapd/at.c b/servers/slapd/at.c index 63f5f629c4..977cb1a618 100644 --- a/servers/slapd/at.c +++ b/servers/slapd/at.c @@ -69,6 +69,19 @@ attr_index_name_cmp( return (strcasecmp( type, air->air_name )); } +/* Uses strncasecmp to allow the input type to be non-terminated */ +static int +attr_index_bvname_cmp( + struct berval *type, + struct aindexrec *air +) +{ + int rc = strncasecmp( type->bv_val, air->air_name, type->bv_len ); + if (rc) + return rc; + return air->air_name[type->bv_len] ? -1 : 0; +} + AttributeType * at_find( const char *name @@ -82,6 +95,19 @@ at_find( return air != NULL ? air->air_at : NULL; } +AttributeType * +at_bvfind( + struct berval *name +) +{ + struct aindexrec *air; + + air = (struct aindexrec *) avl_find( attr_index, name, + (AVL_CMP) attr_index_bvname_cmp ); + + return air != NULL ? air->air_at : NULL; +} + int at_append_to_list( AttributeType *sat, diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index 12951245cd..9ca34811b6 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -986,28 +986,25 @@ backend_group( Connection *conn, Operation *op, Entry *target, - const char *gr_ndn, + struct berval *gr_ndn, struct berval *op_ndn, ObjectClass *group_oc, AttributeDescription *group_at ) { GroupAssertion *g; - struct berval gr; int i; - gr.bv_val = (char *) gr_ndn; - gr.bv_len = strlen(gr_ndn); - ldap_pvt_thread_mutex_lock( &op->o_abandonmutex ); i = op->o_abandon; ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex ); if (i) return SLAPD_ABANDON; - if( strcmp( target->e_ndn, gr_ndn ) != 0 ) { + if( target->e_nname.bv_len != gr_ndn->bv_len || + strcmp( target->e_nname.bv_val, gr_ndn->bv_val ) != 0 ) { /* we won't attempt to send it to a different backend */ - be = select_backend( &gr, 0, + be = select_backend( gr_ndn, 0, (be->be_glueflags & SLAP_GLUE_INSTANCE)); if (be == NULL) { @@ -1018,9 +1015,9 @@ backend_group( ldap_pvt_thread_mutex_lock( &conn->c_mutex ); for (g = conn->c_groups; g; g=g->next) { if (g->be != be || g->oc != group_oc || g->at != group_at || - g->len != gr.bv_len) + g->len != gr_ndn->bv_len) continue; - if (strcmp( g->ndn, gr_ndn ) == 0) + if (strcmp( g->ndn, gr_ndn->bv_val ) == 0) break; } ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); @@ -1029,17 +1026,17 @@ backend_group( if( be->be_group ) { int res = be->be_group( be, conn, op, - target, gr_ndn, op_ndn->bv_val, + target, gr_ndn->bv_val, op_ndn->bv_val, group_oc, group_at ); if (op->o_tag != LDAP_REQ_BIND) { - g = ch_malloc(sizeof(GroupAssertion) + gr.bv_len); + g = ch_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len); g->be = be; g->oc = group_oc; g->at = group_at; g->res = res; - g->len = gr.bv_len; - strcpy(g->ndn, gr_ndn); + g->len = gr_ndn->bv_len; + strcpy(g->ndn, gr_ndn->bv_val); ldap_pvt_thread_mutex_lock( &conn->c_mutex ); g->next = conn->c_groups; conn->c_groups = g; @@ -1058,21 +1055,17 @@ backend_attribute( Connection *conn, Operation *op, Entry *target, - const char *entry_ndn, + struct berval *edn, AttributeDescription *entry_at, struct berval ***vals ) { - struct berval edn; - edn.bv_val = (char *) entry_ndn; - edn.bv_len = strlen( entry_ndn ); - - if( target == NULL || - strcmp( target->e_ndn, entry_ndn ) != 0 ) + if( target == NULL || target->e_nname.bv_len != edn->bv_len || + strcmp( target->e_ndn, edn->bv_val ) != 0 ) { /* we won't attempt to send it to a different backend */ - be = select_backend( &edn, 0, + be = select_backend( edn, 0, (be->be_glueflags & SLAP_GLUE_INSTANCE)); if (be == NULL) { @@ -1081,7 +1074,7 @@ backend_attribute( } if( be->be_attribute ) { - return be->be_attribute( be, conn, op, target, entry_ndn, + return be->be_attribute( be, conn, op, target, edn->bv_val, entry_at, vals ); } diff --git a/servers/slapd/oc.c b/servers/slapd/oc.c index 064b553d4b..aac10ef95d 100644 --- a/servers/slapd/oc.c +++ b/servers/slapd/oc.c @@ -115,6 +115,21 @@ oc_index_cmp( return strcasecmp( oir1->oir_name, oir2->oir_name ); } +static int +oc_index_bvname_cmp( + struct berval *name, + struct oindexrec *oir ) +{ + int rc; + + assert( oir->oir_name ); + assert( oir->oir_oc ); + + rc = strncasecmp( name->bv_val, oir->oir_name, name->bv_len ); + if (rc) return rc; + return oir->oir_name[name->bv_len] ? -1 : 0; +} + static int oc_index_name_cmp( char *name, @@ -144,6 +159,24 @@ oc_find( const char *ocname ) return( NULL ); } +ObjectClass * +oc_bvfind( struct berval *ocname ) +{ + struct oindexrec *oir; + + oir = (struct oindexrec *) avl_find( oc_index, ocname, + (AVL_CMP) oc_index_bvname_cmp ); + + if ( oir != NULL ) { + assert( oir->oir_name ); + assert( oir->oir_oc ); + + return( oir->oir_oc ); + } + + return( NULL ); +} + static int oc_create_required( ObjectClass *soc, diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index e6822de750..4387d2c174 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -93,6 +93,8 @@ LDAP_SLAPD_F (void) at_config LDAP_P(( int argc, char **argv )); LDAP_SLAPD_F (AttributeType *) at_find LDAP_P(( const char *name )); +LDAP_SLAPD_F (AttributeType *) at_bvfind LDAP_P(( + struct berval *name )); LDAP_SLAPD_F (int) at_find_in_list LDAP_P(( AttributeType *sat, AttributeType **list )); LDAP_SLAPD_F (int) at_append_to_list LDAP_P(( @@ -203,7 +205,7 @@ LDAP_SLAPD_F (int) backend_group LDAP_P((BackendDB *be, Connection *conn, Operation *op, Entry *target, - const char *gr_ndn, + struct berval *gr_ndn, struct berval *op_ndn, ObjectClass *group_oc, AttributeDescription *group_at @@ -213,7 +215,7 @@ LDAP_SLAPD_F (int) backend_attribute LDAP_P((BackendDB *be, Connection *conn, Operation *op, Entry *target, - const char *entry_ndn, + struct berval *entry_ndn, AttributeDescription *entry_at, struct berval ***vals )); @@ -695,6 +697,8 @@ LDAP_SLAPD_F (void) schema_destroy LDAP_P(( void )); LDAP_SLAPD_F (ObjectClass *) oc_find LDAP_P(( const char *ocname)); +LDAP_SLAPD_F (ObjectClass *) oc_bvfind LDAP_P(( + struct berval *ocname)); LDAP_SLAPD_F (int) oc_add LDAP_P(( LDAPObjectClass *oc, diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index 57b204ee73..e65436aaf2 100644 --- a/servers/slapd/saslauthz.c +++ b/servers/slapd/saslauthz.c @@ -541,6 +541,7 @@ slap_sasl_check_authz(char *searchDN, char *assertDN, char *attr, char *authc) int i, rc; struct berval **vals=NULL; AttributeDescription *ad=NULL; + struct berval bv; #ifdef NEW_LOGGING @@ -557,7 +558,9 @@ slap_sasl_check_authz(char *searchDN, char *assertDN, char *attr, char *authc) if( rc != LDAP_SUCCESS ) goto COMPLETE; - rc = backend_attribute( NULL, NULL, NULL, NULL, searchDN+3, ad, &vals ); + bv.bv_val = searchDN+3; + bv.bv_len = strlen(bv.bv_val); + rc = backend_attribute( NULL, NULL, NULL, NULL, &bv, ad, &vals ); if( rc != LDAP_SUCCESS ) goto COMPLETE; diff --git a/servers/slapd/sets.c b/servers/slapd/sets.c index 768edbd317..25e07c8551 100644 --- a/servers/slapd/sets.c +++ b/servers/slapd/sets.c @@ -125,6 +125,7 @@ set_chase (SET_GATHER gatherer, { char **vals, **nset; char attrstr[32]; + struct berval bv = {attrlen, attrstr}; int i; if (set == NULL) @@ -146,7 +147,7 @@ set_chase (SET_GATHER gatherer, return(NULL); } for (i = 0; set[i]; i++) { - vals = (gatherer)(cookie, set[i], attrstr); + vals = (gatherer)(cookie, set[i], &bv); if (vals != NULL) nset = set_join(nset, '|', vals); } @@ -154,7 +155,7 @@ set_chase (SET_GATHER gatherer, if (closure) { for (i = 0; nset[i]; i++) { - vals = (gatherer)(cookie, nset[i], attrstr); + vals = (gatherer)(cookie, nset[i], &bv); if (vals != NULL) { nset = set_join(nset, '|', vals); if (nset == NULL) diff --git a/servers/slapd/sets.h b/servers/slapd/sets.h index 1c7b8fe55e..709500bc80 100644 --- a/servers/slapd/sets.h +++ b/servers/slapd/sets.h @@ -9,7 +9,7 @@ * also return the syntax or some "comparison cookie" * that is used by set_filter. */ -typedef char **(*SET_GATHER) (void *cookie, char *name, char *attr); +typedef char **(*SET_GATHER) (void *cookie, char *name, struct berval *attr); LDAP_SLAPD_F (long) set_size (char **set); LDAP_SLAPD_F (void) set_dispose (char **set); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 02b7d6f5a0..6d02e839e1 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -809,7 +809,7 @@ typedef struct slap_access { /* ACL Groups */ slap_style_t a_group_style; - char *a_group_pat; + struct berval a_group_pat; ObjectClass *a_group_oc; AttributeDescription *a_group_at;