X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Facl.c;h=a6f0a853d01b1284a67bdfa291d619aff5ce9df5;hb=e281e08e79829175aa9545dc2e3eb85e4e873717;hp=c4ac1d9acf2c981885d7a75d6e4c504054e026fc;hpb=a85603c10bf32294ade8dbae064cdc1d43329040;p=openldap diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index c4ac1d9acf..a6f0a853d0 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -37,10 +37,6 @@ #include "lber_pvt.h" #include "lutil.h" -#ifdef LDAP_SLAPI -#include "slapi/slapi.h" -#endif /* LDAPI_SLAPI */ - #define ACL_BUF_SIZE 1024 /* use most appropriate size */ /* @@ -88,7 +84,7 @@ typedef enum slap_aci_scope_t { SLAP_ACI_SCOPE_SUBTREE = ( SLAP_ACI_SCOPE_ENTRY | SLAP_ACI_SCOPE_CHILDREN ) } slap_aci_scope_t; -static AccessControl * acl_get( +static AccessControl * slap_acl_get( AccessControl *ac, int *count, Operation *op, Entry *e, AttributeDescription *desc, @@ -96,7 +92,7 @@ static AccessControl * acl_get( int nmatch, regmatch_t *matches, AccessControlState *state ); -static slap_control_t acl_mask( +static slap_control_t slap_acl_mask( AccessControl *ac, slap_mask_t *mask, Operation *op, Entry *e, AttributeDescription *desc, @@ -142,7 +138,7 @@ static int aci_match_set ( struct berval *subj, Operation *op, * the whole attribute is assumed (all values). * * This routine loops through all access controls and calls - * acl_mask() on each applicable access control. + * slap_acl_mask() on each applicable access control. * The loop exits when a definitive answer is reached or * or no more controls remain. * @@ -166,7 +162,7 @@ slap_access_always_allowed( AccessControlState *state, slap_mask_t *maskp ) { - assert( maskp ); + assert( maskp != NULL ); ACL_PRIV_SET( *maskp, ACL_ACCESS2PRIV( access ) ); @@ -207,16 +203,6 @@ slap_access_allowed( assert( attr != NULL ); -#ifdef LDAP_SLAPI - if ( op->o_pb != NULL ) { - ret = slapi_int_access_allowed( op, e, desc, val, access, state ); - if ( ret == 0 ) { - /* ACL plugin denied access */ - goto done; - } - } -#endif /* LDAP_SLAPI */ - /* grant database root access */ if ( be_isroot( op ) ) { Debug( LDAP_DEBUG_ACL, "<= root access granted\n", 0, 0, 0 ); @@ -281,7 +267,7 @@ slap_access_allowed( memset( matches, '\0', sizeof( matches ) ); } - while ( ( a = acl_get( a, &count, op, e, desc, val, + while ( ( a = slap_acl_get( a, &count, op, e, desc, val, MAXREMATCHES, matches, state ) ) != NULL ) { int i; @@ -303,19 +289,19 @@ slap_access_allowed( ( state->as_recorded & ACL_STATE_RECORDED_NV ) ) { Debug( LDAP_DEBUG_ACL, - "slap_access_allowed: result from state (%s)\n", + "=> slap_access_allowed: result from state (%s)\n", attr, 0, 0 ); ret = state->as_result; goto done; } else { Debug( LDAP_DEBUG_ACL, - "slap_access_allowed: no res from state (%s)\n", + "=> slap_access_allowed: no res from state (%s)\n", attr, 0, 0 ); } } vd_access: - control = acl_mask( a, &mask, op, + control = slap_acl_mask( a, &mask, op, e, desc, val, MAXREMATCHES, matches, count, state ); if ( control != ACL_BREAK ) { @@ -350,6 +336,39 @@ done: return ret; } +int +fe_access_allowed( + Operation *op, + Entry *e, + AttributeDescription *desc, + struct berval *val, + slap_access_t access, + AccessControlState *state, + slap_mask_t *maskp ) +{ + BackendDB *be_orig; + int rc; + + /* + * NOTE: control gets here if FIXME + * if an appropriate backend cannot be selected for the operation, + * we assume that the frontend should handle this + * FIXME: should select_backend() take care of this, + * and return frontendDB instead of NULL? maybe for some value + * of the flags? + */ + be_orig = op->o_bd; + + op->o_bd = select_backend( &op->o_req_ndn, 0, 0 ); + if ( op->o_bd == NULL ) { + op->o_bd = frontendDB; + } + rc = slap_access_allowed( op, e, desc, val, access, state, maskp ); + op->o_bd = be_orig; + + return rc; +} + int access_allowed_mask( Operation *op, @@ -373,7 +392,6 @@ access_allowed_mask( const char *attr; int st_same_attr = 0; static AccessControlState state_init = ACL_STATE_INIT; - BI_access_allowed *bi_access_allowed = NULL; assert( e != NULL ); assert( desc != NULL ); @@ -442,10 +460,22 @@ access_allowed_mask( assert( op->o_bd != NULL ); /* this is enforced in backend_add() */ - assert( op->o_bd->bd_info->bi_access_allowed ); + if ( op->o_bd->bd_info->bi_access_allowed ) { + /* delegate to backend */ + ret = op->o_bd->bd_info->bi_access_allowed( op, e, + desc, val, access, state, &mask ); + + } else { + BackendDB *be_orig = op->o_bd; + + /* use default (but pass through frontend + * for global ACL overlays) */ + op->o_bd = frontendDB; + ret = frontendDB->bd_info->bi_access_allowed( op, e, + desc, val, access, state, &mask ); + op->o_bd = be_orig; + } - /* delegate to backend */ - ret = op->o_bd->bd_info->bi_access_allowed( op, e, desc, val, access, state, &mask ); if ( !ret ) { if ( ACL_IS_INVALID( mask ) ) { Debug( LDAP_DEBUG_ACL, @@ -576,16 +606,6 @@ access_allowed_mask( } assert( be != NULL ); -#ifdef LDAP_SLAPI - if ( op->o_pb != NULL ) { - ret = slapi_int_access_allowed( op, e, desc, val, access, state ); - if ( ret == 0 ) { - /* ACL plugin denied access */ - goto done; - } - } -#endif /* LDAP_SLAPI */ - /* grant database root access */ if ( be_isroot( op ) ) { Debug( LDAP_DEBUG_ACL, "<= root access granted\n", 0, 0, 0 ); @@ -678,7 +698,7 @@ access_allowed_mask( memset( matches, '\0', sizeof(matches) ); } - while ( ( a = acl_get( a, &count, op, e, desc, val, + while ( ( a = slap_acl_get( a, &count, op, e, desc, val, MAXREMATCHES, matches, state ) ) != NULL ) { int i; @@ -712,7 +732,7 @@ access_allowed_mask( } vd_access: - control = acl_mask( a, &mask, op, + control = slap_acl_mask( a, &mask, op, e, desc, val, MAXREMATCHES, matches, count, state ); if ( control != ACL_BREAK ) { @@ -760,13 +780,13 @@ done: #endif /* SLAP_OVERLAY_ACCESS */ /* - * acl_get - return the acl applicable to entry e, attribute + * slap_acl_get - return the acl applicable to entry e, attribute * attr. the acl returned is suitable for use in subsequent calls to * acl_access_allowed(). */ static AccessControl * -acl_get( +slap_acl_get( AccessControl *a, int *count, Operation *op, @@ -876,7 +896,7 @@ acl_get( if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) { state->as_recorded |= ACL_STATE_RECORDED_VD; - state->as_vd_acl = prev; + state->as_vd_acl = a; state->as_vd_acl_count = *count; state->as_vd_access = a->acl_access; state->as_vd_access_count = 1; @@ -901,7 +921,7 @@ acl_get( 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, + /* desc->ad_type->sat_equality */ a->acl_attrval_mr, 0, val, &a->acl_attrval, &text ) != LDAP_SUCCESS || match ) continue; @@ -915,11 +935,11 @@ acl_get( if ( vdnlen < patlen ) continue; - if ( a->acl_dn_style == ACL_STYLE_BASE ) { + if ( a->acl_attrval_style == ACL_STYLE_BASE ) { if ( vdnlen > patlen ) continue; - } else if ( a->acl_dn_style == ACL_STYLE_ONE ) { + } else if ( a->acl_attrval_style == ACL_STYLE_ONE ) { int rdnlen = -1; if ( !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) ) @@ -929,11 +949,11 @@ acl_get( if ( rdnlen != vdnlen - patlen - 1 ) continue; - } else if ( a->acl_dn_style == ACL_STYLE_SUBTREE ) { + } else if ( a->acl_attrval_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 ) { + } else if ( a->acl_attrval_style == ACL_STYLE_CHILDREN ) { if ( vdnlen <= patlen ) continue; @@ -1348,7 +1368,7 @@ acl_mask_dnattr( /* - * acl_mask - modifies mask based upon the given acl and the + * slap_acl_mask - modifies mask based upon the given acl and the * requested access to entry e, attribute attr, value val. if val * is null, access to the whole attribute is assumed (all values). * @@ -1357,7 +1377,7 @@ acl_mask_dnattr( */ static slap_control_t -acl_mask( +slap_acl_mask( AccessControl *a, slap_mask_t *mask, Operation *op, @@ -1973,7 +1993,7 @@ acl_mask( continue; } - /* this could be improved by changing acl_mask so that it can deal with + /* this could be improved by changing slap_acl_mask so that it can deal with * by clauses that return grant/deny pairs. Right now, it does either * additive or subtractive rights, but not both at the same time. So, * we need to combine the grant/deny pair into a single rights mask in @@ -2126,7 +2146,7 @@ acl_mask( continue; } - /* this could be improved by changing acl_mask so that it can deal with + /* this could be improved by changing slap_acl_mask so that it can deal with * by clauses that return grant/deny pairs. Right now, it does either * additive or subtractive rights, but not both at the same time. So, * we need to combine the grant/deny pair into a single rights mask in @@ -2254,6 +2274,16 @@ acl_check_modlist( } for ( ; mlist != NULL; mlist = mlist->sml_next ) { + /* + * Internal mods are ignored by ACL_WRITE checking + */ + if ( mlist->sml_flags & SLAP_MOD_INTERNAL ) { + Debug( LDAP_DEBUG_ACL, "acl: internal mod %s:" + " modify access granted\n", + mlist->sml_desc->ad_cname.bv_val, 0, 0 ); + continue; + } + /* * no-user-modification operational attributes are ignored * by ACL_WRITE checking as any found here are not provided @@ -3158,7 +3188,7 @@ dynacl_aci_parse( const char *fname, int lineno, slap_style_t sty, const char *r if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) { fprintf( stderr, "%s: line %d: " "inappropriate style \"%s\" in \"aci\" by clause\n", - fname, lineno, sty ); + fname, lineno, style_strings[sty] ); return -1; } @@ -3193,7 +3223,7 @@ dynacl_aci_unparse( void *priv, struct berval *bv ) AttributeDescription *ad = ( AttributeDescription * )priv; char *ptr; - assert( ad ); + assert( ad != NULL ); bv->bv_val = ch_malloc( STRLENOF(" aci=") + ad->ad_cname.bv_len + 1 ); ptr = lutil_strcopy( bv->bv_val, " aci=" ); @@ -3425,8 +3455,8 @@ slap_dynacl_get( const char *name ) int acl_init( void ) { - int i, rc; #ifdef SLAP_DYNACL + int i, rc; slap_dynacl_t *known_dynacl[] = { #ifdef SLAPD_ACI_ENABLED &dynacl_aci,