X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Faclparse.c;h=fddae6b13a5eec2f6a9fbe8fdb2e6db8a78150b0;hb=b94a77687075b0eb2d54d087b8b956d197c1023c;hp=1a77a9527f18438a79206745b29fafce957e216d;hpb=e0ca6e386e832b857e371ce96ff8270a1f4540c8;p=openldap diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c index 1a77a9527f..fddae6b13a 100644 --- a/servers/slapd/aclparse.c +++ b/servers/slapd/aclparse.c @@ -45,7 +45,11 @@ static char *style_strings[] = { "one", "subtree", "children", + "level", "attrof", + "anonymous", + "users", + "self", "ip", "path", NULL @@ -585,14 +589,39 @@ parse_acl( /* get */ for ( ; i < argc; i++ ) { - slap_style_t sty = ACL_STYLE_REGEX; - char *style_modifier = NULL; - int expand = 0; + slap_style_t sty = ACL_STYLE_REGEX; + char *style_modifier = NULL; + char *style_level = NULL; + int level = 0; + int expand = 0; + slap_dn_access *bdn = &b->a_dn; + int is_realdn = 0; split( argv[i], '=', &left, &right ); split( left, '.', &left, &style ); if ( style ) { - split( style, ',', &style, &style_modifier); + split( style, ',', &style, &style_modifier ); + + if ( strncasecmp( style, "level", STRLENOF( "level" ) ) == 0 ) { + split( style, '{', &style, &style_level ); + if ( style_level != NULL ) { + char *p = strchr( style_level, '}' ); + if ( p == NULL ) { + fprintf( stderr, + "%s: line %d: premature eol: " + "expecting closing '}' in \"level{n}\"\n", + fname, lineno ); + acl_usage(); + } else if ( p == style_level ) { + fprintf( stderr, + "%s: line %d: empty level " + "in \"level{n}\"\n", + fname, lineno ); + acl_usage(); + } + p[0] = '\0'; + } + } } if ( style == NULL || *style == '\0' || @@ -615,6 +644,21 @@ parse_acl( } else if ( strcasecmp( style, "children" ) == 0 ) { sty = ACL_STYLE_CHILDREN; + } else if ( strcasecmp( style, "level" ) == 0 ) + { + char *next; + + level = strtol( style_level, &next, 10 ); + if ( next[0] != '\0' ) { + fprintf( stderr, + "%s: line %d: unable to parse level " + "in \"level{n}\"\n", + fname, lineno ); + acl_usage(); + } + + sty = ACL_STYLE_LEVEL; + } else if ( strcasecmp( style, "regex" ) == 0 ) { sty = ACL_STYLE_REGEX; @@ -679,38 +723,48 @@ parse_acl( fname, lineno ); } - if ( strcasecmp( argv[i], "*" ) == 0 ) { + if ( strncasecmp( left, "real", STRLENOF( "real" ) ) == 0 ) { + is_realdn = 1; + bdn = &b->a_realdn; + left += STRLENOF( "real" ); + } + + if ( strcasecmp( left, "*" ) == 0 ) { + if ( is_realdn ) { + acl_usage(); + } + ber_str2bv( "*", STRLENOF( "*" ), 1, &bv ); sty = ACL_STYLE_REGEX; - } else if ( strcasecmp( argv[i], "anonymous" ) == 0 ) { + } else if ( strcasecmp( left, "anonymous" ) == 0 ) { ber_str2bv("anonymous", STRLENOF( "anonymous" ), 1, &bv); sty = ACL_STYLE_ANONYMOUS; - } else if ( strcasecmp( argv[i], "users" ) == 0 ) { + } else if ( strcasecmp( left, "users" ) == 0 ) { ber_str2bv("users", STRLENOF( "users" ), 1, &bv); sty = ACL_STYLE_USERS; - } else if ( strcasecmp( argv[i], "self" ) == 0 ) { + } else if ( strcasecmp( left, "self" ) == 0 ) { ber_str2bv("self", STRLENOF( "self" ), 1, &bv); sty = ACL_STYLE_SELF; } else if ( strcasecmp( left, "dn" ) == 0 ) { if ( sty == ACL_STYLE_REGEX ) { - b->a_dn_style = ACL_STYLE_REGEX; + bdn->a_style = ACL_STYLE_REGEX; if ( right == NULL ) { /* no '=' */ ber_str2bv("users", STRLENOF( "users" ), 1, &bv); - b->a_dn_style = ACL_STYLE_USERS; + bdn->a_style = ACL_STYLE_USERS; } else if (*right == '\0' ) { /* dn="" */ ber_str2bv("anonymous", STRLENOF( "anonymous" ), 1, &bv); - b->a_dn_style = ACL_STYLE_ANONYMOUS; + bdn->a_style = ACL_STYLE_ANONYMOUS; } else if ( strcmp( right, "*" ) == 0 ) { /* dn=* */ @@ -718,7 +772,7 @@ parse_acl( ber_str2bv("users", STRLENOF( "users" ), 1, &bv); - b->a_dn_style = ACL_STYLE_USERS; + bdn->a_style = ACL_STYLE_USERS; } else if ( strcmp( right, ".+" ) == 0 || strcmp( right, "^.+" ) == 0 @@ -730,7 +784,7 @@ parse_acl( ber_str2bv("users", STRLENOF( "users" ), 1, &bv); - b->a_dn_style = ACL_STYLE_USERS; + bdn->a_style = ACL_STYLE_USERS; } else if ( strcmp( right, ".*" ) == 0 || strcmp( right, "^.*" ) == 0 @@ -766,7 +820,7 @@ parse_acl( } if ( !BER_BVISNULL( &bv ) ) { - if ( !BER_BVISEMPTY( &b->a_dn_pat ) ) { + if ( !BER_BVISEMPTY( &bdn->a_pat ) ) { fprintf( stderr, "%s: line %d: dn pattern already specified.\n", fname, lineno ); @@ -780,7 +834,7 @@ parse_acl( expand == 0 ) { rc = dnNormalize(0, NULL, NULL, - &bv, &b->a_dn_pat, NULL); + &bv, &bdn->a_pat, NULL); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "%s: line %d: bad DN \"%s\" in by DN clause\n", @@ -790,10 +844,34 @@ parse_acl( free( bv.bv_val ); } else { - b->a_dn_pat = bv; + bdn->a_pat = bv; + } + bdn->a_style = sty; + bdn->a_expand = expand; + if ( sty == ACL_STYLE_SELF ) { + bdn->a_self_level = level; + + } else { + if ( level < 0 ) { + fprintf( stderr, + "%s: line %d: bad negative level \"%d\" " + "in by DN clause\n", + fname, lineno, level ); + acl_usage(); + } else if ( level == 1 ) { + fprintf( stderr, + "%s: line %d: \"onelevel\" should be used " + "instead of \"level{1}\" in by DN clause\n", + fname, lineno, 0 ); + } else if ( level == 0 && sty == ACL_STYLE_LEVEL ) { + fprintf( stderr, + "%s: line %d: \"base\" should be used " + "instead of \"level{0}\" in by DN clause\n", + fname, lineno, 0 ); + } + + bdn->a_level = level; } - b->a_dn_style = sty; - b->a_dn_expand = expand; continue; } @@ -806,14 +884,14 @@ parse_acl( acl_usage(); } - if( b->a_dn_at != NULL ) { + if( bdn->a_at != NULL ) { fprintf( stderr, "%s: line %d: dnattr already specified.\n", fname, lineno ); acl_usage(); } - rc = slap_str2ad( right, &b->a_dn_at, &text ); + rc = slap_str2ad( right, &bdn->a_at, &text ); if( rc != LDAP_SUCCESS ) { fprintf( stderr, @@ -823,20 +901,20 @@ parse_acl( } - if( !is_at_syntax( b->a_dn_at->ad_type, + if( !is_at_syntax( bdn->a_at->ad_type, SLAPD_DN_SYNTAX ) && - !is_at_syntax( b->a_dn_at->ad_type, + !is_at_syntax( bdn->a_at->ad_type, SLAPD_NAMEUID_SYNTAX )) { fprintf( stderr, "%s: line %d: dnattr \"%s\": " "inappropriate syntax: %s\n", fname, lineno, right, - b->a_dn_at->ad_type->sat_syntax_oid ); + bdn->a_at->ad_type->sat_syntax_oid ); acl_usage(); } - if( b->a_dn_at->ad_type->sat_equality == NULL ) { + if( bdn->a_at->ad_type->sat_equality == NULL ) { fprintf( stderr, "%s: line %d: dnattr \"%s\": " "inappropriate matching (no EQUALITY)\n", @@ -1584,9 +1662,13 @@ parse_acl( } /* get */ - if ( strncasecmp( left, "self", 4 ) == 0 ) { + if ( strncasecmp( left, "self", STRLENOF( "self" ) ) == 0 ) { b->a_dn_self = 1; - ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( &left[4] ) ); + ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( &left[ STRLENOF( "self" ) ] ) ); + + } else if ( strncasecmp( left, "realself", STRLENOF( "realself" ) ) == 0 ) { + b->a_realdn_self = 1; + ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( &left[ STRLENOF( "realself" ) ] ) ); } else { ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( left ) ); @@ -1905,13 +1987,18 @@ acl_usage( void ) " ::= [val[.]=] | , \n" " ::= | entry | children\n", " ::= [ * | anonymous | users | self | dn[.]= ]\n" + "\t[ realanonymous | realusers | realself | realdn[.]= ]\n" "\t[dnattr=]\n" + "\t[realdnattr=]\n" "\t[group[/[/]][.