From: Pierangelo Masarati Date: Wed, 3 Apr 2002 15:42:19 +0000 (+0000) Subject: various acl improvements/cleanups/speedups (need to be documented, though) X-Git-Tag: OPENLDAP_REL_ENG_2_MP~259 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=440637dde797ffe8f8e71b4ce3c063fc6a7c3ee6;p=openldap various acl improvements/cleanups/speedups (need to be documented, though) --- diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index ace21f1f65..763a7e3f21 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -633,45 +633,83 @@ acl_mask( } } else { + struct berval pat; + int got_match = 0; + if ( e->e_dn == NULL ) continue; - patlen = b->a_dn_pat.bv_len; + if ( b->a_dn_expand ) { + struct berval bv; + char buf[1024]; + + bv.bv_len = sizeof( buf ) - 1; + bv.bv_val = buf; + + string_expand(&bv, &b->a_dn_pat, + e->e_ndn, matches); + if ( dnNormalize2(NULL, &bv, &pat) != LDAP_SUCCESS ) { + /* did not expand to a valid dn */ + continue; + } + } else { + pat = b->a_dn_pat; + } + + patlen = pat.bv_len; odnlen = op->o_ndn.bv_len; - if ( odnlen < patlen ) - continue; + if ( odnlen < patlen ) { + goto dn_match_cleanup; + + } if ( b->a_dn_style == ACL_STYLE_BASE ) { /* base dn -- entire object DN must match */ - if ( odnlen != patlen ) - continue; + if ( odnlen != patlen ) { + goto dn_match_cleanup; + } } else if ( b->a_dn_style == ACL_STYLE_ONE ) { int rdnlen = -1; - if ( odnlen <= patlen ) - continue; + if ( odnlen <= patlen ) { + goto dn_match_cleanup; + } - if ( !DN_SEPARATOR( op->o_ndn.bv_val[odnlen - patlen - 1] ) ) - continue; + if ( !DN_SEPARATOR( op->o_ndn.bv_val[odnlen - patlen - 1] ) ) { + goto dn_match_cleanup; + } rdnlen = dn_rdnlen( NULL, &op->o_ndn ); - if ( rdnlen != odnlen - patlen - 1 ) - continue; + if ( rdnlen != odnlen - patlen - 1 ) { + goto dn_match_cleanup; + } } else if ( b->a_dn_style == ACL_STYLE_SUBTREE ) { - if ( odnlen > patlen && !DN_SEPARATOR( op->o_ndn.bv_val[odnlen - patlen - 1] ) ) - continue; + if ( odnlen > patlen && !DN_SEPARATOR( op->o_ndn.bv_val[odnlen - patlen - 1] ) ) { + goto dn_match_cleanup; + } } else if ( b->a_dn_style == ACL_STYLE_CHILDREN ) { - if ( odnlen <= patlen ) - continue; - if ( !DN_SEPARATOR( op->o_ndn.bv_val[odnlen - patlen - 1] ) ) - continue; + if ( odnlen <= patlen ) { + goto dn_match_cleanup; + } + + if ( !DN_SEPARATOR( op->o_ndn.bv_val[odnlen - patlen - 1] ) ) { + goto dn_match_cleanup; + } } - if ( strcmp( b->a_dn_pat.bv_val, op->o_ndn.bv_val + odnlen - patlen ) != 0 ) + got_match = !strcmp( pat.bv_val, op->o_ndn.bv_val + odnlen - patlen ); + +dn_match_cleanup:; + if ( pat.bv_val != b->a_dn_pat.bv_val ) { + free( pat.bv_val ); + } + + if ( !got_match ) { continue; + } } } @@ -716,8 +754,39 @@ acl_mask( continue; } } else { - if ( ber_bvstrcasecmp( &b->a_domain_pat, &conn->c_peer_domain ) != 0 ) + char buf[1024]; + + struct berval cmp = conn->c_peer_domain; + struct berval pat = b->a_domain_pat; + + if ( b->a_domain_expand ) { + struct berval bv; + + bv.bv_len = sizeof(buf); + bv.bv_val = buf; + + string_expand(&bv, &b->a_domain_pat, e->e_ndn, matches); + pat = bv; + } + + if ( b->a_domain_style == ACL_STYLE_SUBTREE ) { + int offset = cmp.bv_len - pat.bv_len; + if ( offset < 0 ) { + continue; + } + + if ( offset == 1 || ( offset > 1 && cmp.bv_val[ offset - 1 ] != '.' ) ) { + continue; + } + + /* trim the domain */ + cmp.bv_val = &cmp.bv_val[ offset ]; + cmp.bv_len -= offset; + } + + if ( ber_bvstrcasecmp( &pat, &cmp ) != 0 ) { continue; + } } } } @@ -1776,16 +1845,38 @@ string_expand( for ( dp = bv->bv_val, sp = pat->bv_val; size < bv->bv_len && sp < pat->bv_val + pat->bv_len ; sp++) { /* did we previously see a $ */ - if (flag) { - if (*sp == '$') { + if ( flag ) { + if ( flag == 1 && *sp == '$' ) { *dp++ = '$'; size++; - } else if (*sp >= '0' && *sp <= '9' ) { + flag = 0; + + } else if ( flag == 1 && *sp == '{') { + flag = 2; + + } else if ( *sp >= '0' && *sp <= '9' ) { int n; int i; int l; n = *sp - '0'; + + if ( flag == 2 ) { + for ( sp++; *sp != '\0' && *sp != /* { */ '}'; sp++ ) { + if ( *sp >= '0' && *sp <= '9' ) { + n = 10*n + ( *sp - '0' ); + } + } + + if ( *sp != /* { */ '}' ) { + /* error */ + } + } + + if ( n >= MAXREMATCHES ) { + + } + *dp = '\0'; i = matches[n].rm_so; l = matches[n].rm_eo; @@ -1793,8 +1884,9 @@ string_expand( *dp++ = match[i]; } *dp = '\0'; + + flag = 0; } - flag = 0; } else { if (*sp == '$') { flag = 1; @@ -1805,7 +1897,7 @@ string_expand( } } - if (flag) { + if ( flag ) { /* must have ended with a single $ */ *dp++ = '$'; size++; diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c index e559029bf5..95397c2668 100644 --- a/servers/slapd/aclparse.c +++ b/servers/slapd/aclparse.c @@ -280,9 +280,14 @@ parse_acl( /* get */ for ( ; i < argc; i++ ) { slap_style_t sty = ACL_STYLE_REGEX; + char *style_modifier = NULL; + int expand = 0; split( argv[i], '=', &left, &right ); split( left, '.', &left, &style ); + if ( style ) { + split( style, ',', &style, &style_modifier); + } if ( style == NULL || *style == '\0' || strcasecmp( style, "regex" ) == 0 ) { @@ -304,6 +309,10 @@ parse_acl( acl_usage(); } + if ( style_modifier && strcasecmp( style_modifier, "expand" ) == 0 ) { + expand = 1; + } + if ( strcasecmp( argv[i], "*" ) == 0 ) { bv.bv_val = ch_strdup( "*" ); bv.bv_len = 1; @@ -392,13 +401,14 @@ parse_acl( acl_usage(); } - if ( sty != ACL_STYLE_REGEX ) { + if ( sty != ACL_STYLE_REGEX && expand == 0 ) { dnNormalize2(NULL, &bv, &b->a_dn_pat); free(bv.bv_val); } else { b->a_dn_pat = bv; } b->a_dn_style = sty; + b->a_dn_expand = expand; continue; } @@ -443,17 +453,17 @@ parse_acl( continue; } - if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) { - fprintf( stderr, - "%s: line %d: inappropriate style \"%s\" in by clause\n", - fname, lineno, style ); - acl_usage(); - } - if ( strncasecmp( left, "group", sizeof("group")-1 ) == 0 ) { char *name = NULL; char *value = NULL; + if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) { + fprintf( stderr, + "%s: line %d: inappropriate style \"%s\" in by clause\n", + fname, lineno, style ); + acl_usage(); + } + if ( right == NULL || right[ 0 ] == '\0' ) { fprintf( stderr, "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n", @@ -592,6 +602,13 @@ parse_acl( } if ( strcasecmp( left, "peername" ) == 0 ) { + if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) { + fprintf( stderr, + "%s: line %d: inappropriate style \"%s\" in by clause\n", + fname, lineno, style ); + acl_usage(); + } + if ( right == NULL || right[ 0 ] == '\0' ) { fprintf( stderr, "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n", @@ -621,6 +638,13 @@ parse_acl( } if ( strcasecmp( left, "sockname" ) == 0 ) { + if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) { + fprintf( stderr, + "%s: line %d: inappropriate style \"%s\" in by clause\n", + fname, lineno, style ); + acl_usage(); + } + if ( right == NULL || right[ 0 ] == '\0' ) { fprintf( stderr, "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n", @@ -650,6 +674,19 @@ parse_acl( } if ( strcasecmp( left, "domain" ) == 0 ) { + switch ( sty ) { + case ACL_STYLE_REGEX: + case ACL_STYLE_BASE: + case ACL_STYLE_SUBTREE: + break; + + default: + fprintf( stderr, + "%s: line %d: inappropriate style \"%s\" in by clause\n", + fname, lineno, style ); + acl_usage(); + } + if ( right == NULL || right[ 0 ] == '\0' ) { fprintf( stderr, "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n", @@ -665,6 +702,7 @@ parse_acl( } b->a_domain_style = sty; + b->a_domain_expand = expand; if (sty == ACL_STYLE_REGEX) { bv.bv_val = right; acl_regex_normalized_dn( &bv ); @@ -679,6 +717,13 @@ parse_acl( } if ( strcasecmp( left, "sockurl" ) == 0 ) { + if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) { + fprintf( stderr, + "%s: line %d: inappropriate style \"%s\" in by clause\n", + fname, lineno, style ); + acl_usage(); + } + if ( right == NULL || right[ 0 ] == '\0' ) { fprintf( stderr, "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n", @@ -708,6 +753,13 @@ parse_acl( } if ( strcasecmp( left, "set" ) == 0 ) { + if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) { + fprintf( stderr, + "%s: line %d: inappropriate style \"%s\" in by clause\n", + fname, lineno, style ); + acl_usage(); + } + if( b->a_set_pat.bv_len != 0 ) { fprintf( stderr, "%s: line %d: set attribute already specified.\n", @@ -730,6 +782,13 @@ parse_acl( #ifdef SLAPD_ACI_ENABLED if ( strcasecmp( left, "aci" ) == 0 ) { + if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) { + fprintf( stderr, + "%s: line %d: inappropriate style \"%s\" in by clause\n", + fname, lineno, style ); + acl_usage(); + } + if( b->a_aci_at != NULL ) { fprintf( stderr, "%s: line %d: aci attribute already specified.\n", @@ -766,6 +825,13 @@ parse_acl( #endif /* SLAPD_ACI_ENABLED */ if ( strcasecmp( left, "ssf" ) == 0 ) { + if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) { + fprintf( stderr, + "%s: line %d: inappropriate style \"%s\" in by clause\n", + fname, lineno, style ); + acl_usage(); + } + if( b->a_authz.sai_ssf ) { fprintf( stderr, "%s: line %d: ssf attribute already specified.\n", @@ -792,6 +858,13 @@ parse_acl( } if ( strcasecmp( left, "transport_ssf" ) == 0 ) { + if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) { + fprintf( stderr, + "%s: line %d: inappropriate style \"%s\" in by clause\n", + fname, lineno, style ); + acl_usage(); + } + if( b->a_authz.sai_transport_ssf ) { fprintf( stderr, "%s: line %d: transport_ssf attribute already specified.\n", @@ -818,6 +891,13 @@ parse_acl( } if ( strcasecmp( left, "tls_ssf" ) == 0 ) { + if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) { + fprintf( stderr, + "%s: line %d: inappropriate style \"%s\" in by clause\n", + fname, lineno, style ); + acl_usage(); + } + if( b->a_authz.sai_tls_ssf ) { fprintf( stderr, "%s: line %d: tls_ssf attribute already specified.\n", @@ -844,6 +924,13 @@ parse_acl( } if ( strcasecmp( left, "sasl_ssf" ) == 0 ) { + if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) { + fprintf( stderr, + "%s: line %d: inappropriate style \"%s\" in by clause\n", + fname, lineno, style ); + acl_usage(); + } + if( b->a_authz.sai_sasl_ssf ) { fprintf( stderr, "%s: line %d: sasl_ssf attribute already specified.\n", diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index dc88b57cc5..3ff6e17f10 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -69,7 +69,7 @@ LDAP_BEGIN_DECL */ #define SLAP_MOD_SOFTADD 0x1000 -#define MAXREMATCHES (10) +#define MAXREMATCHES (100) #define SLAP_MAX_WORKER_THREADS (32) @@ -911,6 +911,7 @@ typedef struct slap_access { slap_style_t a_dn_style; AttributeDescription *a_dn_at; int a_dn_self; + int a_dn_expand; slap_style_t a_peername_style; struct berval a_peername_pat; @@ -919,6 +920,8 @@ typedef struct slap_access { slap_style_t a_domain_style; struct berval a_domain_pat; + int a_domain_expand; + slap_style_t a_sockurl_style; struct berval a_sockurl_pat; slap_style_t a_set_style;