From 31ba1e793e3c61e2d9b29851a08e39a4fcaf4296 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Apr 27 2018 13:04:29 +0000 Subject: Ticket 49652 - DENY aci's are not handled properly Bug Description: There are really two issues here. One, when a resource is denied by a DENY aci the cached results for that resource are not proprely set, and on the same connection if the same operation repeated it will be allowed instead of denied because the cache result was not proprely updated. Two, if there are no ALLOW aci's on a resource, then we don't check the deny rules, and resources that are restricted are returned to the client. Fix Description: For issue one, when an entry is denied access reset all the attributes' cache results to DENIED as it's possible previously evaluated aci's granted access to some of these attributes which are still present in the acl result cache. For issue two, if there are no ALLOW aci's on a resource but there are DENY aci's, then set the aclpb state flags to process DENY aci's https://pagure.io/389-ds-base/issue/49652 Reviewed by: tbordaz & lkrispenz(Thanks!!) --- diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c index 12fb2c7..3b45311 100644 --- a/ldap/servers/plugins/acl/acl.c +++ b/ldap/servers/plugins/acl/acl.c @@ -1083,17 +1083,30 @@ acl_read_access_allowed_on_entry ( */ if ( aclpb->aclpb_state & ACLPB_FOUND_A_ENTRY_TEST_RULE){ /* Do I have access on the entry itself */ - if (acl_access_allowed (pb, e, NULL, - NULL, access) != LDAP_SUCCESS) { + if (acl_access_allowed (pb, e, NULL, NULL, access) != LDAP_SUCCESS) { /* How was I denied ? ** I could be denied on a DENY rule or because ** there is no allow rule. If it's a DENY from ** a DENY rule, then we don't have access to ** the entry ( nice trick to get in ) */ - if ( aclpb->aclpb_state & - ACLPB_EXECUTING_DENY_HANDLES) - return LDAP_INSUFFICIENT_ACCESS; + if (aclpb->aclpb_state & ACLPB_EXECUTING_DENY_HANDLES) { + aclEvalContext *c_ContextEval = &aclpb->aclpb_curr_entryEval_context; + AclAttrEval *c_attrEval = NULL; + /* + * The entire entry is blocked, but previously evaluated allow aci's might + * show some of the attributes as readable in the acl cache, so reset all + * the cached attributes' status to FAIL. + */ + for (size_t j = 0; j < c_ContextEval->acle_numof_attrs; j++) { + c_attrEval = &c_ContextEval->acle_attrEval[j]; + c_attrEval->attrEval_r_status &= ~ACL_ATTREVAL_SUCCESS; + c_attrEval->attrEval_r_status |= ACL_ATTREVAL_FAIL; + c_attrEval->attrEval_s_status &= ~ACL_ATTREVAL_SUCCESS; + c_attrEval->attrEval_s_status |= ACL_ATTREVAL_FAIL; + } + return LDAP_INSUFFICIENT_ACCESS; + } /* The other case is I don't have an ** explicit allow rule -- which is fine. @@ -2914,6 +2927,11 @@ acl__TestRights(Acl_PBlock *aclpb,int access, const char **right, const char ** result_reason->deciding_aci = NULL; result_reason->reason = ACL_REASON_NO_MATCHED_RESOURCE_ALLOWS; + /* If we have deny handles we should process them */ + if (aclpb->aclpb_num_deny_handles > 0) { + aclpb->aclpb_state &= ~ACLPB_EXECUTING_ALLOW_HANDLES; + aclpb->aclpb_state |= ACLPB_EXECUTING_DENY_HANDLES; + } TNF_PROBE_1_DEBUG(acl__TestRights_end,"ACL","", tnf_string,no_allows,"");