]> git.sur5r.net Git - openldap/commitdiff
ITS#3008 fix value-based ACLs
authorHoward Chu <hyc@openldap.org>
Wed, 10 Mar 2004 02:59:03 +0000 (02:59 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 10 Mar 2004 02:59:03 +0000 (02:59 +0000)
servers/slapd/acl.c
servers/slapd/result.c

index dccaeded050c2943d71a7225399c83657a73afdc..c4f4d2bdcce1da5b7deb7b490c94822851833741 100644 (file)
@@ -535,6 +535,89 @@ acl_get(
 #endif
                }
 
+               if ( a->acl_attrs && !ad_inlist( desc, a->acl_attrs ) ) {
+                       matches[0].rm_so = matches[0].rm_eo = -1;
+                       continue;
+               }
+
+               /* Is this ACL only for a specific value? */
+               if ( a->acl_attrval.bv_len ) {
+                       if ( val == NULL ) {
+                               continue;
+                       }
+                       if ( a->acl_attrval_style == ACL_STYLE_REGEX ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( ACL, DETAIL1, 
+                                       "acl_get: valpat %s\n",
+                                       a->acl_attrval.bv_val, 0, 0 );
+#else
+                               Debug( LDAP_DEBUG_ACL,
+                                       "acl_get: valpat %s\n",
+                                       a->acl_attrval.bv_val, 0, 0 );
+#endif
+                               if (regexec(&a->acl_attrval_re, val->bv_val, 0, NULL, 0))
+                                       continue;
+                       } else {
+                               int match = 0;
+                               const char *text;
+#ifdef NEW_LOGGING
+                               LDAP_LOG( ACL, DETAIL1, 
+                                       "acl_get: val %s\n",
+                                       a->acl_attrval.bv_val, 0, 0 );
+#else
+                               Debug( LDAP_DEBUG_ACL,
+                                       "acl_get: val %s\n",
+                                       a->acl_attrval.bv_val, 0, 0 );
+#endif
+       
+                               if ( a->acl_attrs[0].an_desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) {
+                                       if (value_match( &match, desc,
+                                               desc->ad_type->sat_equality, 0,
+                                               val, &a->acl_attrval, &text ) != LDAP_SUCCESS ||
+                                                       match )
+                                               continue;
+                                       
+                               } else {
+                                       int             patlen, vdnlen;
+       
+                                       patlen = a->acl_attrval.bv_len;
+                                       vdnlen = val->bv_len;
+       
+                                       if ( vdnlen < patlen )
+                                               continue;
+       
+                                       if ( a->acl_dn_style == ACL_STYLE_BASE ) {
+                                               if ( vdnlen > patlen )
+                                                       continue;
+       
+                                       } else if ( a->acl_dn_style == ACL_STYLE_ONE ) {
+                                               int rdnlen = -1;
+       
+                                               if ( !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) )
+                                                       continue;
+       
+                                               rdnlen = dn_rdnlen( NULL, val );
+                                               if ( rdnlen != vdnlen - patlen - 1 )
+                                                       continue;
+       
+                                       } else if ( a->acl_dn_style == ACL_STYLE_SUBTREE ) {
+                                               if ( vdnlen > patlen && !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) )
+                                                       continue;
+       
+                                       } else if ( a->acl_dn_style == ACL_STYLE_CHILDREN ) {
+                                               if ( vdnlen <= patlen )
+                                                       continue;
+       
+                                               if ( !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) )
+                                                       continue;
+                                       }
+       
+                                       if ( strcmp( a->acl_attrval.bv_val, val->bv_val + vdnlen - patlen ))
+                                               continue;
+                               }
+                       }
+               }
+
                if ( a->acl_filter != NULL ) {
                        ber_int_t rc = test_filter( NULL, e, a->acl_filter );
                        if ( rc != LDAP_COMPARE_TRUE ) {
@@ -544,25 +627,12 @@ acl_get(
 
 #ifdef NEW_LOGGING
                LDAP_LOG( ACL, DETAIL1, 
-                       "acl_get: [%d] check attr %s\n", *count, attr ,0 );
+                       "acl_get: [%d] attr %s\n", *count, attr ,0 );
 #else
-               Debug( LDAP_DEBUG_ACL, "=> acl_get: [%d] check attr %s\n",
+               Debug( LDAP_DEBUG_ACL, "=> acl_get: [%d] attr %s\n",
                       *count, attr, 0);
 #endif
-               if ( a->acl_attrs == NULL ||
-                       ad_inlist( desc, a->acl_attrs ) )
-               {
-#ifdef NEW_LOGGING
-                       LDAP_LOG( ACL, DETAIL1, 
-                               "acl_get:  [%d] acl %s attr: %s\n", *count, e->e_dn, attr );
-#else
-                       Debug( LDAP_DEBUG_ACL,
-                               "<= acl_get: [%d] acl %s attr: %s\n",
-                               *count, e->e_dn, attr );
-#endif
-                       return a;
-               }
-               matches[0].rm_so = matches[0].rm_eo = -1;
+               return a;
        }
 
 #ifdef NEW_LOGGING
@@ -646,106 +716,6 @@ acl_mask(
                accessmask2str( *mask, accessmaskbuf ) );
 #endif
 
-       /* Is this ACL only for a specific value? */
-       if ( a->acl_attrval.bv_len ) {
-               if ( state && !state->as_vd_acl ) {
-                       state->as_vd_acl = a;
-                       state->as_vd_access = a->acl_access;
-                       state->as_vd_access_count = 1;
-               }
-               if ( val == NULL ) {
-                       return ACL_BREAK;
-               }
-               if ( a->acl_attrval_style == ACL_STYLE_REGEX ) {
-#ifdef NEW_LOGGING
-                       LDAP_LOG( ACL, DETAIL1, 
-                               "acl_get: valpat %s\n",
-                               a->acl_attrval.bv_val, 0, 0 );
-#else
-                       Debug( LDAP_DEBUG_ACL,
-                               "acl_get: valpat %s\n",
-                               a->acl_attrval.bv_val, 0, 0 );
-#endif
-                       if (regexec(&a->acl_attrval_re, val->bv_val, 0, NULL, 0))
-                               return ACL_BREAK;
-               } else {
-                       int match = 0;
-                       const char *text;
-#ifdef NEW_LOGGING
-                       LDAP_LOG( ACL, DETAIL1, 
-                               "acl_get: val %s\n",
-                               a->acl_attrval.bv_val, 0, 0 );
-#else
-                       Debug( LDAP_DEBUG_ACL,
-                               "acl_get: val %s\n",
-                               a->acl_attrval.bv_val, 0, 0 );
-#endif
-
-                       if ( a->acl_attrs[0].an_desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) {
-                               if (value_match( &match, desc,
-                                       desc->ad_type->sat_equality, 0,
-                                       val, &a->acl_attrval, &text ) != LDAP_SUCCESS ||
-                                               match )
-                                       return ACL_BREAK;
-                               
-                       } else {
-                               int             patlen, vdnlen, rc, got_match = 0;
-                               struct berval   vdn = { 0, NULL };
-
-                               /* it is a DN */
-                               assert( a->acl_attrs[0].an_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName );
-
-                               rc = dnNormalize( 0, NULL, NULL, val, &vdn,
-                                               op->o_tmpmemctx );
-                               if ( rc != LDAP_SUCCESS ) {
-                                       /* error */
-                                       return ACL_BREAK;
-                               }
-
-                               patlen = a->acl_attrval.bv_len;
-                               vdnlen = vdn.bv_len;
-
-                               if ( vdnlen < patlen )
-                                       goto attrval_cleanup;
-
-                               if ( a->acl_dn_style == ACL_STYLE_BASE ) {
-                                       if ( vdnlen > patlen )
-                                               goto attrval_cleanup;
-
-                               } else if ( a->acl_dn_style == ACL_STYLE_ONE ) {
-                                       int rdnlen = -1;
-
-                                       if ( !DN_SEPARATOR( vdn.bv_val[vdnlen - patlen - 1] ) )
-                                               goto attrval_cleanup;
-
-                                       rdnlen = dn_rdnlen( NULL, &vdn );
-                                       if ( rdnlen != vdnlen - patlen - 1 )
-                                               goto attrval_cleanup;
-
-                               } else if ( a->acl_dn_style == ACL_STYLE_SUBTREE ) {
-                                       if ( vdnlen > patlen && !DN_SEPARATOR( vdn.bv_val[vdnlen - patlen - 1] ) )
-                                               goto attrval_cleanup;
-
-                               } else if ( a->acl_dn_style == ACL_STYLE_CHILDREN ) {
-                                       if ( vdnlen <= patlen )
-                                               goto attrval_cleanup;
-
-                                       if ( !DN_SEPARATOR( vdn.bv_val[vdnlen - patlen - 1] ) )
-                                               goto attrval_cleanup;
-                               }
-
-                               got_match = strcmp( a->acl_attrval.bv_val, vdn.bv_val + vdnlen - patlen );
-
-attrval_cleanup:;
-                               if ( vdn.bv_val )
-                                       free( vdn.bv_val );
-
-                               if ( !got_match )
-                                       return ACL_BREAK;
-                               
-                       }
-               }
-       }
 
        if( state && ( state->as_recorded & ACL_STATE_RECORDED_VD )
                && state->as_vd_acl == a )
index 63408450132681c643fbf811fafe7ce49614b7aa..2f97e13ab40cbafeef42b0daefbef6f165ae9732 100644 (file)
@@ -888,6 +888,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
        for ( a = rs->sr_entry->e_attrs, j = 0; a != NULL; a = a->a_next, j++ ) {
                AttributeDescription *desc = a->a_desc;
+               int finish = 0;
 
                if ( rs->sr_attrs == NULL ) {
                        /* all attrs request, skip operational attributes */
@@ -909,39 +910,42 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        }
                }
 
-               if ( ! access_allowed( op, rs->sr_entry, desc, NULL,
-                       ACL_READ, &acl_state ) )
-               {
+               if ( op->ors_attrsonly ) {
+                       if ( ! access_allowed( op, rs->sr_entry, desc, NULL,
+                               ACL_READ, &acl_state ) )
+                       {
 #ifdef NEW_LOGGING
-                       LDAP_LOG( ACL, INFO, 
-                               "send_search_entry: conn %lu  access to attribute %s not "
-                               "allowed\n", op->o_connid, desc->ad_cname.bv_val, 0 );
+                               LDAP_LOG( ACL, INFO, 
+                                       "send_search_entry: conn %lu  access to attribute %s not "
+                                       "allowed\n", op->o_connid, desc->ad_cname.bv_val, 0 );
 #else
-                       Debug( LDAP_DEBUG_ACL, "acl: "
-                               "access to attribute %s not allowed\n",
-                           desc->ad_cname.bv_val, 0, 0 );
+                               Debug( LDAP_DEBUG_ACL, "acl: "
+                                       "access to attribute %s not allowed\n",
+                                   desc->ad_cname.bv_val, 0, 0 );
 #endif
-                       continue;
-               }
+                               continue;
+                       }
 
-               if (( rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname )) == -1 ) {
+                       if (( rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname )) == -1 ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG( OPERATION, ERR, 
-                               "send_search_entry: conn %lu  ber_printf failed\n", 
-                               op->o_connid, 0, 0 );
+                               LDAP_LOG( OPERATION, ERR, 
+                                       "send_search_entry: conn %lu  ber_printf failed\n", 
+                                       op->o_connid, 0, 0 );
 #else
-                       Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
+                               Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
-                       if ( op->o_res_ber == NULL ) ber_free_buf( ber );
-                       send_ldap_error( op, rs, LDAP_OTHER, "encoding description error");
-                       goto error_return;
-               }
+                               if ( op->o_res_ber == NULL ) ber_free_buf( ber );
+                               send_ldap_error( op, rs, LDAP_OTHER, "encoding description error");
+                               goto error_return;
+                       }
+                       finish = 1;
 
-               if ( ! op->ors_attrsonly ) {
-                       for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
+               } else {
+                       int first = 1;
+                       for ( i = 0; a->a_nvals[i].bv_val != NULL; i++ ) {
                                if ( ! access_allowed( op, rs->sr_entry,
-                                       desc, &a->a_vals[i], ACL_READ, &acl_state ) )
+                                       desc, &a->a_nvals[i], ACL_READ, &acl_state ) )
                                {
 #ifdef NEW_LOGGING
                                        LDAP_LOG( ACL, INFO, 
@@ -962,6 +966,23 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                                        continue;
                                }
 
+                               if ( first ) {
+                                       first = 0;
+                                       finish = 1;
+                                       if (( rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname )) == -1 ) {
+#ifdef NEW_LOGGING
+                                               LDAP_LOG( OPERATION, ERR, 
+                                                       "send_search_entry: conn %lu  ber_printf failed\n", 
+                                                       op->o_connid, 0, 0 );
+#else
+                                               Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
+#endif
+
+                                               if ( op->o_res_ber == NULL ) ber_free_buf( ber );
+                                               send_ldap_error( op, rs, LDAP_OTHER, "encoding description error");
+                                               goto error_return;
+                                       }
+                               }
                                if (( rc = ber_printf( ber, "O", &a->a_vals[i] )) == -1 ) {
 #ifdef NEW_LOGGING
                                        LDAP_LOG( OPERATION, ERR, 
@@ -980,7 +1001,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        }
                }
 
-               if (( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) {
+               if ( finish && ( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG( OPERATION, ERR, 
                                "send_search_entry: conn %lu ber_printf failed\n",