/** {@inheritDoc} */ @Override public void filterEntry( Operation operation, SearchResultEntry unfilteredEntry, SearchResultEntry filteredEntry) { AciLDAPOperationContainer operationContainer = new AciLDAPOperationContainer(operation, (ACI_READ), unfilteredEntry); // Proxy access check has already been done for this entry in the // maySend method, set the seen flag to true to bypass any proxy // check. operationContainer.setSeenEntry(true); boolean skipCheck = skipAccessCheck(operation); if (!skipCheck) { filterEntry(operationContainer, filteredEntry); } if (operationContainer.hasGetEffectiveRightsControl()) { AciEffectiveRights.addRightsToEntry( this, ((SearchOperation) operation).getAttributes(), operationContainer, filteredEntry, skipCheck); } }
/** * Check access using the specified container. This container will have all of the information to * gather applicable ACIs and perform evaluation on them. * * @param container An ACI operation container which has all of the information needed to check * access. * @return True if access is allowed. */ boolean accessAllowed(AciContainer container) { DN dn = container.getResourceEntry().getDN(); // For ACI_WRITE_ADD and ACI_WRITE_DELETE set the ACI_WRITE // right. if (container.hasRights(ACI_WRITE_ADD) || container.hasRights(ACI_WRITE_DELETE)) { container.setRights(container.getRights() | ACI_WRITE); } // Check if the ACI_SELF right needs to be set (selfwrite right). // Only done if the right is ACI_WRITE, an attribute value is set // and that attribute value is a DN. if ((container.getCurrentAttributeValue() != null) && (container.hasRights(ACI_WRITE)) && (isAttributeDN(container.getCurrentAttributeType()))) { String DNString = null; try { DNString = container.getCurrentAttributeValue().getValue().toString(); DN tmpDN = DN.decode(DNString); // Have a valid DN, compare to clientDN to see if the ACI_SELF // right should be set. if (tmpDN.equals(container.getClientDN())) { container.setRights(container.getRights() | ACI_SELF); } } catch (DirectoryException ex) { // Log a message and keep going. Message message = WARN_ACI_NOT_VALID_DN.get(DNString); logError(message); } } // Check proxy authorization only if the entry has not already been // processed (working on a new entry). If working on a new entry, // then only do a proxy check if the right is not set to ACI_PROXY // and the proxied authorization control has been decoded. if (!container.hasSeenEntry()) { if (container.isProxiedAuthorization() && !container.hasRights(ACI_PROXY) && !container.hasRights(ACI_SKIP_PROXY_CHECK)) { int currentRights = container.getRights(); // Save the current rights so they can be put back if on // success. container.setRights(ACI_PROXY); // Switch to the original authorization entry, not the proxied // one. container.useOrigAuthorizationEntry(true); if (!accessAllowed(container)) { return false; } // Access is ok, put the original rights back. container.setRights(currentRights); // Put the proxied authorization entry back to the current // authorization entry. container.useOrigAuthorizationEntry(false); } // Set the seen flag so proxy processing is not performed for this // entry again. container.setSeenEntry(true); } /* * First get all allowed candidate ACIs. */ LinkedList<Aci> candidates = aciList.getCandidateAcis(dn); /* * Create an applicable list of ACIs by target matching each * candidate ACI against the container's target match view. */ createApplicableList(candidates, container); /* * Evaluate the applicable list. */ boolean ret = testApplicableLists(container); // Build summary string if doing geteffectiverights eval. if (container.isGetEffectiveRightsEval()) { AciEffectiveRights.createSummary(container, ret, "main"); } return ret; }
/** {@inheritDoc} */ @Override() public void finalizeAccessControlHandler() { aciListenerMgr.finalizeListenerManager(); AciEffectiveRights.finalizeOnShutdown(); DirectoryServer.deregisterSupportedControl(OID_GET_EFFECTIVE_RIGHTS); }
/** * Performs the test of the deny and allow access lists using the provided evaluation context. The * deny list is checked first. * * @param evalCtx The evaluation context to use. * @return True if access is allowed. */ private boolean testApplicableLists(AciEvalContext evalCtx) { EnumEvalResult res; evalCtx.setEvalReason(EnumEvalReason.NO_REASON); LinkedList<Aci> denys = evalCtx.getDenyList(); LinkedList<Aci> allows = evalCtx.getAllowList(); // If allows list is empty and not doing geteffectiverights return // false. evalCtx.setDenyEval(true); if (allows.isEmpty() && !(evalCtx.isGetEffectiveRightsEval() && !evalCtx.hasRights(ACI_SELF) && evalCtx.isTargAttrFilterMatchAciEmpty())) { evalCtx.setEvalReason(EnumEvalReason.NO_ALLOW_ACIS); evalCtx.setDecidingAci(null); return false; } for (Aci denyAci : denys) { res = Aci.evaluate(evalCtx, denyAci); // Failure could be returned if a system limit is hit or // search fails if (res.equals(EnumEvalResult.FAIL)) { evalCtx.setEvalReason(EnumEvalReason.EVALUATED_DENY_ACI); evalCtx.setDecidingAci(denyAci); return false; } else if (res.equals(EnumEvalResult.TRUE)) { if (evalCtx.isGetEffectiveRightsEval() && !evalCtx.hasRights(ACI_SELF) && !evalCtx.isTargAttrFilterMatchAciEmpty()) { // Iterate to next only if deny ACI contains a targattrfilters // keyword. if (AciEffectiveRights.setTargAttrAci(evalCtx, denyAci, true)) { continue; } evalCtx.setEvalReason(EnumEvalReason.EVALUATED_DENY_ACI); evalCtx.setDecidingAci(denyAci); return false; } else { evalCtx.setEvalReason(EnumEvalReason.EVALUATED_DENY_ACI); evalCtx.setDecidingAci(denyAci); return false; } } } // Now check the allows -- flip the deny flag to false first. evalCtx.setDenyEval(false); for (Aci allowAci : allows) { res = Aci.evaluate(evalCtx, allowAci); if (res.equals(EnumEvalResult.TRUE)) { if (evalCtx.isGetEffectiveRightsEval() && !evalCtx.hasRights(ACI_SELF) && !evalCtx.isTargAttrFilterMatchAciEmpty()) { // Iterate to next only if deny ACI contains a targattrfilters // keyword. if (AciEffectiveRights.setTargAttrAci(evalCtx, allowAci, false)) { continue; } evalCtx.setEvalReason(EnumEvalReason.EVALUATED_ALLOW_ACI); evalCtx.setDecidingAci(allowAci); return true; } else { evalCtx.setEvalReason(EnumEvalReason.EVALUATED_ALLOW_ACI); evalCtx.setDecidingAci(allowAci); return true; } } } // Nothing matched fall through. evalCtx.setEvalReason(EnumEvalReason.NO_MATCHED_ALLOWS_ACIS); evalCtx.setDecidingAci(null); return false; }