/** * Handles any controls contained in the request. * * @throws DirectoryException If there is a problem with any of the request controls. */ private void handleRequestControls() throws DirectoryException { LocalBackendWorkflowElement.removeAllDisallowedControls(baseDN, this); List<Control> requestControls = getRequestControls(); if (requestControls != null && !requestControls.isEmpty()) { for (Control c : requestControls) { String oid = c.getOID(); if (OID_LDAP_ASSERTION.equals(oid)) { LDAPAssertionRequestControl assertControl = getRequestControl(LDAPAssertionRequestControl.DECODER); SearchFilter assertionFilter; try { assertionFilter = assertControl.getSearchFilter(); } catch (DirectoryException de) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, de); } throw new DirectoryException( de.getResultCode(), ERR_SEARCH_CANNOT_PROCESS_ASSERTION_FILTER.get(de.getMessageObject()), de); } Entry entry; try { entry = DirectoryServer.getEntry(baseDN); } catch (DirectoryException de) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, de); } throw new DirectoryException( de.getResultCode(), ERR_SEARCH_CANNOT_GET_ENTRY_FOR_ASSERTION.get(de.getMessageObject())); } if (entry == null) { throw new DirectoryException( ResultCode.NO_SUCH_OBJECT, ERR_SEARCH_NO_SUCH_ENTRY_FOR_ASSERTION.get()); } // Check if the current user has permission to make // this determination. if (!AccessControlConfigManager.getInstance() .getAccessControlHandler() .isAllowed(this, entry, assertionFilter)) { throw new DirectoryException( ResultCode.INSUFFICIENT_ACCESS_RIGHTS, ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid)); } try { if (!assertionFilter.matchesEntry(entry)) { throw new DirectoryException( ResultCode.ASSERTION_FAILED, ERR_SEARCH_ASSERTION_FAILED.get()); } } catch (DirectoryException de) { if (de.getResultCode() == ResultCode.ASSERTION_FAILED) { throw de; } if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, de); } throw new DirectoryException( de.getResultCode(), ERR_SEARCH_CANNOT_PROCESS_ASSERTION_FILTER.get(de.getMessageObject()), de); } } else if (OID_PROXIED_AUTH_V1.equals(oid)) { // Log usage of legacy proxy authz V1 control. addAdditionalLogItem( AdditionalLogItem.keyOnly(getClass(), "obsoleteProxiedAuthzV1Control")); // The requester must have the PROXIED_AUTH privilege in order to be // able to use this control. if (!clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this)) { throw new DirectoryException( ResultCode.AUTHORIZATION_DENIED, ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get()); } ProxiedAuthV1Control proxyControl = getRequestControl(ProxiedAuthV1Control.DECODER); Entry authorizationEntry = proxyControl.getAuthorizationEntry(); setAuthorizationEntry(authorizationEntry); setProxiedAuthorizationDN(getDN(authorizationEntry)); } else if (OID_PROXIED_AUTH_V2.equals(oid)) { // The requester must have the PROXIED_AUTH privilege in order to be // able to use this control. if (!clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this)) { throw new DirectoryException( ResultCode.AUTHORIZATION_DENIED, ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get()); } ProxiedAuthV2Control proxyControl = getRequestControl(ProxiedAuthV2Control.DECODER); Entry authorizationEntry = proxyControl.getAuthorizationEntry(); setAuthorizationEntry(authorizationEntry); setProxiedAuthorizationDN(getDN(authorizationEntry)); } else if (OID_PERSISTENT_SEARCH.equals(oid)) { final PersistentSearchControl ctrl = getRequestControl(PersistentSearchControl.DECODER); persistentSearch = new PersistentSearch( this, ctrl.getChangeTypes(), ctrl.getChangesOnly(), ctrl.getReturnECs()); } else if (OID_LDAP_SUBENTRIES.equals(oid)) { SubentriesControl subentriesControl = getRequestControl(SubentriesControl.DECODER); setReturnSubentriesOnly(subentriesControl.getVisibility()); } else if (OID_LDUP_SUBENTRIES.equals(oid)) { // Support for legacy draft-ietf-ldup-subentry. addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(), "obsoleteSubentryControl")); setReturnSubentriesOnly(true); } else if (OID_MATCHED_VALUES.equals(oid)) { MatchedValuesControl matchedValuesControl = getRequestControl(MatchedValuesControl.DECODER); setMatchedValuesControl(matchedValuesControl); } else if (OID_ACCOUNT_USABLE_CONTROL.equals(oid)) { setIncludeUsableControl(true); } else if (OID_REAL_ATTRS_ONLY.equals(oid)) { setRealAttributesOnly(true); } else if (OID_VIRTUAL_ATTRS_ONLY.equals(oid)) { setVirtualAttributesOnly(true); } else if (OID_GET_EFFECTIVE_RIGHTS.equals(oid) && DirectoryServer.isSupportedControl(OID_GET_EFFECTIVE_RIGHTS)) { // Do nothing here and let AciHandler deal with it. } // NYI -- Add support for additional controls. else if (c.isCritical() && !backendSupportsControl(oid)) { throw new DirectoryException( ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, ERR_SEARCH_UNSUPPORTED_CRITICAL_CONTROL.get(oid)); } } } }
/** Test PersistentSearchControl. */ @Test(dataProvider = "persistentSearchControl") public void checkPersistentSearchControlTest( boolean isCritical, boolean changesOnly, boolean returnECs) throws Exception { // Test constructor // CheclPersistentSearchControlTest(Set<PersistentSearchChangeType> // changeTypes, boolean changesOnly, boolean returnECs for (int i = 1; i <= 15; i++) { Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i); PersistentSearchControl psc = new PersistentSearchControl(returnTypes, changesOnly, returnECs); assertNotNull(psc); assertEquals(changesOnly, psc.getChangesOnly()); assertEquals(returnECs, psc.getReturnECs()); assertEquals(returnTypes.size(), psc.getChangeTypes().size()); assertEquals(OID_PERSISTENT_SEARCH, psc.getOID()); } // Test constructor // CString oid, boolean isCritical, // Set<PersistentSearchChangeType> changeTypes, // boolean changesOnly, boolean returnECs for (int i = 1; i <= 15; i++) { Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i); PersistentSearchControl psc = new PersistentSearchControl(isCritical, returnTypes, changesOnly, returnECs); assertNotNull(psc); assertEquals(isCritical, psc.isCritical()); assertEquals(OID_PERSISTENT_SEARCH, psc.getOID()); assertEquals(changesOnly, psc.getChangesOnly()); assertEquals(returnECs, psc.getReturnECs()); assertEquals(returnTypes.size(), psc.getChangeTypes().size()); } // Test encode/decode ByteStringBuilder bsb = new ByteStringBuilder(); ASN1Writer writer = ASN1.getWriter(bsb); for (int i = 1; i <= 15; i++) { bsb.clear(); Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i); PersistentSearchControl psc = new PersistentSearchControl(isCritical, returnTypes, changesOnly, returnECs); psc.write(writer); LDAPControl control = LDAPReader.readControl(ASN1.getReader(bsb)); psc = PersistentSearchControl.DECODER.decode(control.isCritical(), control.getValue()); assertNotNull(psc); assertEquals(isCritical, psc.isCritical()); assertEquals(OID_PERSISTENT_SEARCH, psc.getOID()); assertEquals(changesOnly, psc.getChangesOnly()); assertEquals(returnECs, psc.getReturnECs()); assertEquals(returnTypes.size(), psc.getChangeTypes().size()); // Check the toString String changeTypes = PersistentSearchChangeType.changeTypesToString(psc.getChangeTypes()); String toString = "PersistentSearchControl(changeTypes=\"" + changeTypes + "\",changesOnly=" + psc.getChangesOnly() + ",returnECs=" + psc.getReturnECs() + ")"; assertEquals(psc.toString(), toString); // check null value for the control try { control = new LDAPControl(OID_PERSISTENT_SEARCH, isCritical); psc = PersistentSearchControl.DECODER.decode(control.isCritical(), control.getValue()); fail(); } catch (DirectoryException expected) { assertEquals(expected.getMessage(), CANNOT_DECODE_PERSISTENT_SEARCH_CONTROL_NO_VALUE); } // check invalid value for the control try { control = new LDAPControl(OID_PERSISTENT_SEARCH, isCritical, ByteString.valueOf("invalid value")); psc = PersistentSearchControl.DECODER.decode(control.isCritical(), control.getValue()); fail(); } catch (DirectoryException expected) { assertThat(expected.getMessage()) .contains("Cannot decode the provided persistent search control"); } } }