X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Facl.c;h=46159d21563a4ae45032583586c4270b58c2cbda;hb=804490a8b12a94a19e7c1a8710a7d8a2fb7d5477;hp=8e226d8861533eb4760203da5ea402d0f9629cf4;hpb=1658aa089320a3b07639c77fd4d1896e0c2a89ea;p=openldap diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index 8e226d8861..46159d2156 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -17,25 +17,33 @@ #include "sets.h" #include "lber_pvt.h" +#define ACL_BUF_SIZE 1024 /* use most appropriate size */ + /* * speed up compares */ static struct berval - aci_bv_entry = { sizeof("entry") - 1, "entry" }, - aci_bv_br_entry = { sizeof("[entry]") - 1, "[entry]" }, - aci_bv_br_all = { sizeof("[all]") - 1, "[all]" }, - aci_bv_access_id = { sizeof("access-id") - 1, "access-id" }, - aci_bv_anonymous = { sizeof("anonymous") - 1, "anonymous" }, - aci_bv_users = { sizeof("users") - 1, "users" }, - aci_bv_self = { sizeof("self") - 1, "self" }, - aci_bv_dnattr = { sizeof("dnattr") - 1, "dnattr" }, - aci_bv_group = { sizeof("group") - 1, "group" }, - aci_bv_role = { sizeof("role") - 1, "role" }, - aci_bv_set = { sizeof("set") - 1, "set" }, - aci_bv_set_ref = { sizeof("set-ref") - 1, "set-ref"}, - aci_bv_grant = { sizeof("grant") - 1, "grant" }, - aci_bv_deny = { sizeof("deny") - 1, "deny" }; + aci_bv_entry = BER_BVC("entry"), + aci_bv_br_entry = BER_BVC("[entry]"), + aci_bv_br_all = BER_BVC("[all]"), + aci_bv_access_id = BER_BVC("access-id"), + aci_bv_anonymous = BER_BVC("anonymous"), + aci_bv_users = BER_BVC("users"), + aci_bv_self = BER_BVC("self"), + aci_bv_dnattr = BER_BVC("dnattr"), + aci_bv_group = BER_BVC("group"), + aci_bv_role = BER_BVC("role"), + aci_bv_set = BER_BVC("set"), + aci_bv_set_ref = BER_BVC("set-ref"), + aci_bv_grant = BER_BVC("grant"), + aci_bv_deny = BER_BVC("deny"), + + aci_bv_group_class = BER_BVC(SLAPD_GROUP_CLASS), + aci_bv_group_attr = BER_BVC(SLAPD_GROUP_ATTR), + aci_bv_role_class = BER_BVC(SLAPD_ROLE_CLASS), + aci_bv_role_attr = BER_BVC(SLAPD_ROLE_ATTR); + static AccessControl * acl_get( AccessControl *ac, int *count, @@ -623,7 +631,7 @@ acl_mask( } } else if ( b->a_dn_style == ACL_STYLE_REGEX ) { - if ( ber_bvccmp( &b->a_dn_pat, '*' ) == 0 ) { + if ( !ber_bvccmp( &b->a_dn_pat, '*' ) ) { int ret = regex_matches( &b->a_dn_pat, op->o_ndn.bv_val, e->e_ndn, matches ); @@ -633,45 +641,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[ACL_BUF_SIZE]; + + 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; + } + } + + 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 ( strcmp( b->a_dn_pat.bv_val, op->o_ndn.bv_val + odnlen - patlen ) != 0 ) + if ( !got_match ) { continue; + } } } @@ -685,7 +731,7 @@ acl_mask( b->a_sockurl_pat.bv_val, 0, 0 ); #endif - if ( ber_bvccmp( &b->a_sockurl_pat, '*' ) != 0) { + if ( !ber_bvccmp( &b->a_sockurl_pat, '*' ) ) { if ( b->a_sockurl_style == ACL_STYLE_REGEX) { if (!regex_matches( &b->a_sockurl_pat, conn->c_listener_url.bv_val, e->e_ndn, matches ) ) @@ -708,7 +754,7 @@ acl_mask( Debug( LDAP_DEBUG_ACL, "<= check a_domain_pat: %s\n", b->a_domain_pat.bv_val, 0, 0 ); #endif - if ( ber_bvccmp( &b->a_domain_pat, '*' ) != 0) { + if ( !ber_bvccmp( &b->a_domain_pat, '*' ) ) { if ( b->a_domain_style == ACL_STYLE_REGEX) { if (!regex_matches( &b->a_domain_pat, conn->c_peer_domain.bv_val, e->e_ndn, matches ) ) @@ -716,8 +762,39 @@ acl_mask( continue; } } else { - if ( ber_bvstrcasecmp( &b->a_domain_pat, &conn->c_peer_domain ) != 0 ) + char buf[ACL_BUF_SIZE]; + + 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; + } } } } @@ -731,7 +808,7 @@ acl_mask( Debug( LDAP_DEBUG_ACL, "<= check a_peername_path: %s\n", b->a_peername_pat.bv_val, 0, 0 ); #endif - if ( ber_bvccmp( &b->a_peername_pat, '*' ) != 0) { + if ( !ber_bvccmp( &b->a_peername_pat, '*' ) ) { if ( b->a_peername_style == ACL_STYLE_REGEX) { if (!regex_matches( &b->a_peername_pat, conn->c_peer_name.bv_val, e->e_ndn, matches ) ) @@ -754,7 +831,7 @@ acl_mask( Debug( LDAP_DEBUG_ACL, "<= check a_sockname_path: %s\n", b->a_sockname_pat.bv_val, 0, 0 ); #endif - if ( ber_bvccmp( &b->a_sockname_pat, '*' ) != 0) { + if ( !ber_bvccmp( &b->a_sockname_pat, '*' ) ) { if ( b->a_sockname_style == ACL_STYLE_REGEX) { if (!regex_matches( &b->a_sockname_pat, conn->c_sock_name.bv_val, e->e_ndn, matches ) ) @@ -848,7 +925,7 @@ acl_mask( } if ( b->a_group_pat.bv_len ) { - char buf[1024]; + char buf[ACL_BUF_SIZE]; struct berval bv; struct berval ndn = { 0, NULL }; int rc; @@ -1257,21 +1334,6 @@ acl_check_modlist( return( 1 ); } -#if 0 /* not used any more */ -static char * -aci_bvstrdup( struct berval *bv ) -{ - char *s; - - s = (char *)ch_malloc(bv->bv_len + 1); - if (s != NULL) { - AC_MEMCPY(s, bv->bv_val, bv->bv_len); - s[bv->bv_len] = 0; - } - return(s); -} -#endif - static int aci_get_part( struct berval *list, @@ -1575,7 +1637,6 @@ aci_group_member ( regmatch_t *matches ) { - struct berval bv; struct berval subjdn; struct berval grpoc; struct berval grpat; @@ -1607,30 +1668,21 @@ aci_group_member ( grp_oc = oc_bvfind( &grpoc ); if (grp_oc != NULL && grp_ad != NULL ) { - struct berval ndn; - bv.bv_val = (char *)ch_malloc(1024); - bv.bv_len = 1024; + char buf[ACL_BUF_SIZE]; + struct berval bv, ndn; + bv.bv_len = sizeof( buf ); + bv.bv_val = (char *)&buf; string_expand(&bv, &subjdn, e->e_ndn, matches); if ( dnNormalize2(NULL, &bv, &ndn) == LDAP_SUCCESS ) { rc = (backend_group(be, conn, op, e, &ndn, &op->o_ndn, grp_oc, grp_ad) == 0); free( ndn.bv_val ); } - ch_free(bv.bv_val); } done: 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, @@ -1698,10 +1750,9 @@ aci_mask( rc = 0; free(ndn.bv_val); } - return(rc); - } + return (rc); - if (ber_bvstrcasecmp( &aci_bv_self, &bv ) == 0) { + } else if (ber_bvstrcasecmp( &aci_bv_self, &bv ) == 0) { if (dn_match(&op->o_ndn, &e->e_nname)) return(1); @@ -1734,11 +1785,11 @@ aci_mask( } else if (ber_bvstrcasecmp( &aci_bv_group, &bv ) == 0) { - if (aci_group_member(&sdn, &GroupClass, &GroupAttr, be, e, conn, op, matches)) + if (aci_group_member(&sdn, &aci_bv_group_class, &aci_bv_group_attr, be, e, conn, op, matches)) return(1); } else if (ber_bvstrcasecmp( &aci_bv_role, &bv ) == 0) { - if (aci_group_member(&sdn, &RoleClass, &RoleAttr, be, e, conn, op, matches)) + if (aci_group_member(&sdn, &aci_bv_role_class, &aci_bv_role_attr, be, e, conn, op, matches)) return(1); } else if (ber_bvstrcasecmp( &aci_bv_set, &bv ) == 0) { @@ -1776,16 +1827,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 +1866,9 @@ string_expand( *dp++ = match[i]; } *dp = '\0'; + + flag = 0; } - flag = 0; } else { if (*sp == '$') { flag = 1; @@ -1805,7 +1879,7 @@ string_expand( } } - if (flag) { + if ( flag ) { /* must have ended with a single $ */ *dp++ = '$'; size++;