/** {@inheritDoc} */ public ConfigChangeResult applyConfigurationAdd(RootDNUserCfg configuration) { configuration.addChangeListener(this); ResultCode resultCode = ResultCode.SUCCESS; boolean adminActionRequired = false; ArrayList<Message> messages = new ArrayList<Message>(); HashSet<DN> altBindDNs = new HashSet<DN>(); for (DN altBindDN : configuration.getAlternateBindDN()) { try { DirectoryServer.registerAlternateRootDN(configuration.dn(), altBindDN); altBindDNs.add(altBindDN); } catch (DirectoryException de) { // This shouldn't happen, since the set of DNs should have already been // validated. resultCode = DirectoryServer.getServerErrorResultCode(); messages.add(de.getMessageObject()); for (DN dn : altBindDNs) { DirectoryServer.deregisterAlternateRootBindDN(dn); } break; } } if (resultCode == ResultCode.SUCCESS) { DirectoryServer.registerRootDN(configuration.dn()); alternateBindDNs.put(configuration.dn(), altBindDNs); } return new ConfigChangeResult(resultCode, adminActionRequired, messages); }
/** * Tests whether the who am I? extended operation with an unauthenticated connection fails with * new setting of "ds-cfg-reject-unauthenticated-requests". * * @throws UnsupportedEncodingException If an unexpected problem occurs. * @throws IOException If an unexpected problem occurs. * @throws ClientException If an unexpected problem occurs. */ @Test public void testUnauthWAINewCfg() throws UnsupportedEncodingException, IOException, ClientException { try { DirectoryServer.setRejectUnauthenticatedRequests(true); Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort()); LDAPReader reader = new LDAPReader(s); LDAPWriter writer = new LDAPWriter(s); AtomicInteger nextMessageID = new AtomicInteger(1); LDAPAuthenticationHandler authHandler = new LDAPAuthenticationHandler(reader, writer, "localhost", nextMessageID); ByteString authzID = null; try { authzID = authHandler.requestAuthorizationIdentity(); } catch (LDAPException e) { assertNull(authzID); } finally { LDAPMessage unbindMessage = new LDAPMessage(nextMessageID.getAndIncrement(), new UnbindRequestProtocolOp()); writer.writeMessage(unbindMessage); s.close(); } } finally { DirectoryServer.setRejectUnauthenticatedRequests(false); } }
/** * Tests the use of the StartTLS extended operation to communicate with the server in conjunction * with no authentication and using blind trust. * * @throws Exception If an unexpected problem occurs. */ @Test public void testStartTLSNoAuthTrustAll() throws Exception { try { DirectoryServer.setRejectUnauthenticatedRequests(true); String[] argSearch = { "--noPropertiesFile", "-h", "127.0.0.1", "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), "-D", "cn=directory manager", "-w", "password", "-q", "-X", "-b", "", "-s", "base", "(objectClass=*)" }; assertEquals(LDAPSearch.mainSearch(argSearch, false, null, System.err), 0); } finally { DirectoryServer.setRejectUnauthenticatedRequests(false); } }
/** {@inheritDoc} */ public ConfigChangeResult applyConfigurationAdd(LogRotationPolicyCfg config) { // Default result code. ResultCode resultCode = ResultCode.SUCCESS; boolean adminActionRequired = false; ArrayList<Message> messages = new ArrayList<Message>(); try { RotationPolicy rotationPolicy = getRotationPolicy(config); DirectoryServer.registerRotationPolicy(config.dn(), rotationPolicy); } catch (ConfigException e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } messages.add(e.getMessageObject()); resultCode = DirectoryServer.getServerErrorResultCode(); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } messages.add( ERR_CONFIG_ROTATION_POLICY_CANNOT_CREATE_POLICY.get( String.valueOf(config.dn().toString()), stackTraceToSingleLineString(e))); resultCode = DirectoryServer.getServerErrorResultCode(); } return new ConfigChangeResult(resultCode, adminActionRequired, messages); }
@BeforeClass() public void setUp() throws Exception { TestCaseUtils.startServer(); TestCaseUtils.clearJEBackend(false, "userRoot", SUFFIX); InternalClientConnection connection = InternalClientConnection.getRootConnection(); // Add suffix entry. DN suffixDN = DN.decode(SUFFIX); if (DirectoryServer.getEntry(suffixDN) == null) { Entry suffixEntry = StaticUtils.createEntry(suffixDN); AddOperation addOperation = connection.processAdd( suffixEntry.getDN(), suffixEntry.getObjectClasses(), suffixEntry.getUserAttributes(), suffixEntry.getOperationalAttributes()); assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS); assertNotNull(DirectoryServer.getEntry(suffixEntry.getDN())); } // Add base entry. DN baseDN = DN.decode(BASE); if (DirectoryServer.getEntry(baseDN) == null) { Entry baseEntry = StaticUtils.createEntry(baseDN); AddOperation addOperation = connection.processAdd( baseEntry.getDN(), baseEntry.getObjectClasses(), baseEntry.getUserAttributes(), baseEntry.getOperationalAttributes()); assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS); assertNotNull(DirectoryServer.getEntry(baseEntry.getDN())); } // Add test entry. Entry testEntry = TestCaseUtils.makeEntry( "dn: uid=rogasawara," + BASE, "objectclass: top", "objectclass: person", "objectclass: organizationalPerson", "objectclass: inetOrgPerson", "uid: rogasawara", "userpassword: password", "mail: [email protected]", "givenname: Rodney", "sn: Ogasawara", "cn: Rodney Ogasawara", "title: Sales, Director"); AddOperation addOperation = connection.processAdd( testEntry.getDN(), testEntry.getObjectClasses(), testEntry.getUserAttributes(), testEntry.getOperationalAttributes()); assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS); assertNotNull(DirectoryServer.getEntry(testEntry.getDN())); }
/** {@inheritDoc} */ public ConfigChangeResult applyConfigurationChange(RootDNUserCfg configuration) { ResultCode resultCode = ResultCode.SUCCESS; boolean adminActionRequired = false; ArrayList<Message> messages = new ArrayList<Message>(); HashSet<DN> setDNs = new HashSet<DN>(); HashSet<DN> addDNs = new HashSet<DN>(); HashSet<DN> delDNs = new HashSet<DN>(alternateBindDNs.get(configuration.dn())); for (DN altBindDN : configuration.getAlternateBindDN()) { setDNs.add(altBindDN); if (!delDNs.remove(altBindDN)) { addDNs.add(altBindDN); } } for (DN dn : delDNs) { DirectoryServer.deregisterAlternateRootBindDN(dn); } HashSet<DN> addedDNs = new HashSet<DN>(addDNs.size()); for (DN dn : addDNs) { try { DirectoryServer.registerAlternateRootDN(configuration.dn(), dn); addedDNs.add(dn); } catch (DirectoryException de) { // This shouldn't happen, since the set of DNs should have already been // validated. resultCode = DirectoryServer.getServerErrorResultCode(); messages.add(de.getMessageObject()); for (DN addedDN : addedDNs) { DirectoryServer.deregisterAlternateRootBindDN(addedDN); } for (DN deletedDN : delDNs) { try { DirectoryServer.registerAlternateRootDN(configuration.dn(), deletedDN); } catch (Exception e) { // This should also never happen. alternateBindDNs.get(configuration.dn()).remove(deletedDN); } } } } if (resultCode == ResultCode.SUCCESS) { alternateBindDNs.put(configuration.dn(), setDNs); } return new ConfigChangeResult(resultCode, adminActionRequired, messages); }
/** * Tests whether the Who Am I? extended operation with an internal authenticated connection * succeeds with new setting of "ds-cfg-reject-unauthenticated-requests". * * @throws Exception If an unexpected problem occurs. */ @Test public void testAuthWAINewCfg() throws Exception { try { DirectoryServer.setRejectUnauthenticatedRequests(true); InternalClientConnection conn = InternalClientConnection.getRootConnection(); ExtendedOperation extOp = conn.processExtendedOperation(OID_WHO_AM_I_REQUEST, null); assertEquals(extOp.getResultCode(), ResultCode.SUCCESS); assertNotNull(extOp.getResponseValue()); } finally { DirectoryServer.setRejectUnauthenticatedRequests(false); } }
/** * Tests whether the Who Am I? extended operation with an internal authenticated connection * succeeds with default setting of "ds-cfg-reject-unauthenticated-requests". * * @throws Exception If an unexpected problem occurs. */ @Test() public void testAuthWAIDefCfg() throws Exception { DirectoryServer.setRejectUnauthenticatedRequests(false); Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort()); LDAPReader reader = new LDAPReader(s); LDAPWriter writer = new LDAPWriter(s); AtomicInteger nextMessageID = new AtomicInteger(1); LDAPAuthenticationHandler authHandler = new LDAPAuthenticationHandler(reader, writer, "localhost", nextMessageID); authHandler.doSimpleBind( 3, ByteString.valueOf("cn=Directory Manager"), ByteString.valueOf("password"), new ArrayList<Control>(), new ArrayList<Control>()); ByteString authzID = authHandler.requestAuthorizationIdentity(); assertNotNull(authzID); LDAPMessage unbindMessage = new LDAPMessage(nextMessageID.getAndIncrement(), new UnbindRequestProtocolOp()); writer.writeMessage(unbindMessage); s.close(); }
/** * Process this search operation against a local backend. * * @param wfe The local backend work-flow element. * @throws CanceledOperationException if this operation should be cancelled */ public void processLocalSearch(LocalBackendWorkflowElement wfe) throws CanceledOperationException { this.backend = wfe.getBackend(); this.clientConnection = getClientConnection(); // Check for a request to cancel this operation. checkIfCanceled(false); try { BooleanHolder executePostOpPlugins = new BooleanHolder(false); processSearch(executePostOpPlugins); // Check for a request to cancel this operation. checkIfCanceled(false); // Invoke the post-operation search plugins. if (executePostOpPlugins.value) { PluginResult.PostOperation postOpResult = DirectoryServer.getPluginConfigManager().invokePostOperationSearchPlugins(this); if (!postOpResult.continueProcessing()) { setResultCode(postOpResult.getResultCode()); appendErrorMessage(postOpResult.getErrorMessage()); setMatchedDN(postOpResult.getMatchedDN()); setReferralURLs(postOpResult.getReferralURLs()); } } } finally { LocalBackendWorkflowElement.filterNonDisclosableMatchedDN(this); } }
/** {@inheritDoc} */ public ConfigChangeResult applyConfigurationDelete(LogRotationPolicyCfg config) { // Default result code. ResultCode resultCode = ResultCode.SUCCESS; boolean adminActionRequired = false; ArrayList<Message> messages = new ArrayList<Message>(); RotationPolicy policy = DirectoryServer.getRotationPolicy(config.dn()); if (policy != null) { DirectoryServer.deregisterRotationPolicy(config.dn()); } else { // TODO: Add message and check for usage resultCode = DirectoryServer.getServerErrorResultCode(); } return new ConfigChangeResult(resultCode, adminActionRequired, messages); }
/** {@inheritDoc} */ public ConfigChangeResult applyConfigurationDelete(RootDNUserCfg configuration) { DirectoryServer.deregisterRootDN(configuration.dn()); configuration.removeChangeListener(this); ResultCode resultCode = ResultCode.SUCCESS; boolean adminActionRequired = false; ArrayList<Message> messages = new ArrayList<Message>(); HashSet<DN> altBindDNs = alternateBindDNs.remove(configuration.dn()); if (altBindDNs != null) { for (DN dn : altBindDNs) { DirectoryServer.deregisterAlternateRootBindDN(dn); } } return new ConfigChangeResult(resultCode, adminActionRequired, messages); }
/** * Tests whether an Unauthenticated BIND request will be allowed with the default configuration * settings for "ds-cfg-reject-unauthenticated-requests". */ @Test() public void testUnauthBindDefCfg() { DirectoryServer.setRejectUnauthenticatedRequests(false); InternalClientConnection conn = new InternalClientConnection(new AuthenticationInfo()); BindOperation bindOperation = conn.processSimpleBind(DN.nullDN(), null); assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS); }
/** * Tests whether authenticated and unauthenticated BIND requests will be allowed with the new * configuration settings for "ds-cfg-reject-unauthenticated-requests" . */ @Test public void testBindNewCfg() { try { DirectoryServer.setRejectUnauthenticatedRequests(true); InternalClientConnection conn = new InternalClientConnection(new AuthenticationInfo()); ByteString user = ByteString.valueOf("cn=Directory Manager"); ByteString password = ByteString.valueOf("password"); // Unauthenticated BIND request. BindOperation bindOperation = conn.processSimpleBind(DN.nullDN(), null); assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS); // Authenticated BIND request. bindOperation = conn.processSimpleBind(user, password); assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS); } finally { DirectoryServer.setRejectUnauthenticatedRequests(false); } }
/** * Tests the whether the unauthenticated ADD,MODIFY,COMPARE,MODRDN and DELETE requests fail with * the new configuration settings. * * @throws Exception If an unexpected problem occurs. */ @Test public void testOtherOpsUnauthNewCfg() throws Exception { try { DirectoryServer.setRejectUnauthenticatedRequests(true); assertFalse(performAddOperation(false) == 0); assertFalse(performModifyOperation(false) == 0); assertFalse(performCompareOperation(false) == 0); assertFalse(performModRdnOperation(false) == 0); assertFalse(performDeleteOperation(false) == 0); } finally { DirectoryServer.setRejectUnauthenticatedRequests(false); } }
/** * Ensures that password policy creation will fail when given an invalid configuration. * * @param e The entry containing an invalid password policy configuration. * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "invalidConfigs") public void testInvalidConfigurations(Entry e) throws Exception { InternalClientConnection connection = InternalClientConnection.getRootConnection(); AddOperation addOperation = connection.processAdd( e.getDN(), e.getObjectClasses(), e.getUserAttributes(), e.getOperationalAttributes()); assertTrue(addOperation.getResultCode() != ResultCode.SUCCESS); assertNull(DirectoryServer.getEntry(e.getDN())); }
/** * Tests whether an authenticated BIND request will be allowed with the default configuration * settings for "ds-cfg-reject-unauthenticated-requests" . */ @Test() public void testAuthBindDefCfg() { DirectoryServer.setRejectUnauthenticatedRequests(false); InternalClientConnection conn = new InternalClientConnection(new AuthenticationInfo()); ByteString user = ByteString.valueOf("cn=Directory Manager"); ByteString password = ByteString.valueOf("password"); BindOperation bindOperation = conn.processSimpleBind(user, password); assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS); }
/** * Validates a number of password policy state constraints for the user. This will be called * before the offered credentials are checked. * * @param userEntry The entry for the user that is authenticating. * @param saslHandler The SASL mechanism handler if this is a SASL bind, or {@code null} for a * simple bind. * @throws DirectoryException If a problem occurs that should cause the bind to fail. */ protected void checkUnverifiedPasswordPolicyState( Entry userEntry, SASLMechanismHandler<?> saslHandler) throws DirectoryException { PasswordPolicyState pwPolicyState = (PasswordPolicyState) authPolicyState; PasswordPolicy policy = pwPolicyState.getAuthenticationPolicy(); boolean isSASLBind = saslHandler != null; // If the password policy is configured to track authentication failures or // keep the last login time and the associated backend is disabled, then we // may need to reject the bind immediately. if ((policy.getStateUpdateFailurePolicy() == PasswordPolicyCfgDefn.StateUpdateFailurePolicy.PROACTIVE) && ((policy.getLockoutFailureCount() > 0) || ((policy.getLastLoginTimeAttribute() != null) && (policy.getLastLoginTimeFormat() != null))) && ((DirectoryServer.getWritabilityMode() == WritabilityMode.DISABLED) || (backend.getWritabilityMode() == WritabilityMode.DISABLED))) { // This policy isn't applicable to root users, so if it's a root // user then ignore it. if (!DirectoryServer.isRootDN(userEntry.getName())) { throw new DirectoryException( ResultCode.INVALID_CREDENTIALS, ERR_BIND_OPERATION_WRITABILITY_DISABLED.get(userEntry.getName())); } } // Check to see if the authentication must be done in a secure // manner. If so, then the client connection must be secure. if (policy.isRequireSecureAuthentication() && !clientConnection.isSecure()) { if (isSASLBind) { if (!saslHandler.isSecure(saslMechanism)) { throw new DirectoryException( ResultCode.INVALID_CREDENTIALS, ERR_BIND_OPERATION_INSECURE_SASL_BIND.get(saslMechanism, userEntry.getName())); } } else { throw new DirectoryException( ResultCode.INVALID_CREDENTIALS, ERR_BIND_OPERATION_INSECURE_SIMPLE_BIND.get()); } } }
/** * Tests whether both authenticated and unauthenticated SEARCH requests will be allowed with the * new configuration settings for "ds-cfg-reject-unauthenticated-requests" . */ @Test public void testSearchNewCfg() { try { DirectoryServer.setRejectUnauthenticatedRequests(true); String[] args = { "--noPropertiesFile", "-h", "127.0.0.1", "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), "-b", "", "-s", "base", "(objectClass=*)" }; assertFalse(LDAPSearch.mainSearch(args, false, null, null) == 0); String[] authArgs = { "--noPropertiesFile", "-h", "127.0.0.1", "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), "-D", "cn=Directory Manager", "-w", "password", "-b", "", "-s", "base", "(objectClass=*)" }; assertEquals(LDAPSearch.mainSearch(authArgs, false, null, System.err), 0); } finally { DirectoryServer.setRejectUnauthenticatedRequests(false); } }
/** * Performs the processing necessary for an anonymous simple bind. * * @return {@code true} if processing should continue for the operation, or {@code false} if not. * @throws DirectoryException If a problem occurs that should cause the bind operation to fail. */ protected boolean processAnonymousSimpleBind() throws DirectoryException { // If the server is in lockdown mode, then fail. if (DirectoryServer.lockdownMode()) { throw new DirectoryException( ResultCode.INVALID_CREDENTIALS, ERR_BIND_REJECTED_LOCKDOWN_MODE.get()); } // If there is a bind DN, then see whether that is acceptable. if (DirectoryServer.bindWithDNRequiresPassword() && bindDN != null && !bindDN.isRootDN()) { throw new DirectoryException( ResultCode.UNWILLING_TO_PERFORM, ERR_BIND_DN_BUT_NO_PASSWORD.get()); } // Invoke pre-operation plugins. if (!invokePreOpPlugins()) { return false; } setResultCode(ResultCode.SUCCESS); setAuthenticationInfo(new AuthenticationInfo()); return true; }
/** {@inheritDoc} */ public ConfigChangeResult applyConfigurationChange(LogRotationPolicyCfg configuration) { // Default result code. ResultCode resultCode = ResultCode.SUCCESS; boolean adminActionRequired = false; ArrayList<Message> messages = new ArrayList<Message>(); RotationPolicy policy = DirectoryServer.getRotationPolicy(configuration.dn()); String className = configuration.getJavaClass(); if (!className.equals(policy.getClass().getName())) { adminActionRequired = true; } return new ConfigChangeResult(resultCode, adminActionRequired, messages); }
/** * Tests the whether the authenticated ADD,MODIFY,COMPARE,MODRDN and DELETE requests succeed with * the default configuration settings. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testOtherOpsAuthDefCfg() throws Exception { DirectoryServer.setRejectUnauthenticatedRequests(false); assertEquals(performAddOperation(true), 0); assertEquals(performModifyOperation(true), 0); assertEquals(performCompareOperation(true), 0); assertEquals(performModRdnOperation(true), 0); assertEquals(performDeleteOperation(true), 0); }
/** * Initializes all of the root users currently defined in the Directory Server configuration, as * well as the set of privileges that root users will inherit by default. * * @throws ConfigException If a configuration problem causes the identity mapper initialization * process to fail. * @throws InitializationException If a problem occurs while initializing the identity mappers * that is not related to the server configuration. */ public void initializeRootDNs() throws ConfigException, InitializationException { // Get the root configuration object. ServerManagementContext managementContext = ServerManagementContext.getInstance(); RootCfg rootConfiguration = managementContext.getRootConfiguration(); // Get the root DN configuration object, use it to set the default root // privileges, and register a change listener for it. RootDNCfg rootDNCfg = rootConfiguration.getRootDN(); rootPrivilegeChangeListener.setDefaultRootPrivileges(rootDNCfg); rootDNCfg.addChangeListener(rootPrivilegeChangeListener); // Register as an add and delete listener for new root DN users. rootDNCfg.addRootDNUserAddListener(this); rootDNCfg.addRootDNUserDeleteListener(this); // Get the set of root users defined below "cn=Root DNs,cn=config". For // each one, register as a change listener, and get the set of alternate // bind DNs. for (String name : rootDNCfg.listRootDNUsers()) { RootDNUserCfg rootUserCfg = rootDNCfg.getRootDNUser(name); rootUserCfg.addChangeListener(this); DirectoryServer.registerRootDN(rootUserCfg.dn()); HashSet<DN> altBindDNs = new HashSet<DN>(); for (DN alternateBindDN : rootUserCfg.getAlternateBindDN()) { try { altBindDNs.add(alternateBindDN); DirectoryServer.registerAlternateRootDN(rootUserCfg.dn(), alternateBindDN); } catch (DirectoryException de) { throw new InitializationException(de.getMessageObject()); } } alternateBindDNs.put(rootUserCfg.dn(), altBindDNs); } }
/** * Initializes all the log rotation policies. * * @throws ConfigException If an unrecoverable problem arises in the process of performing the * initialization as a result of the server configuration. * @throws InitializationException If a problem occurs during initialization that is not related * to the server configuration. */ public void initializeLogRotationPolicyConfig() throws ConfigException, InitializationException { ServerManagementContext context = ServerManagementContext.getInstance(); RootCfg root = context.getRootConfiguration(); root.addLogRotationPolicyAddListener(this); root.addLogRotationPolicyDeleteListener(this); for (String name : root.listLogRotationPolicies()) { LogRotationPolicyCfg config = root.getLogRotationPolicy(name); RotationPolicy rotationPolicy = getRotationPolicy(config); DirectoryServer.registerRotationPolicy(config.dn(), rotationPolicy); } }
/** * Tests whether an unauthenticated SEARCH request will be allowed with the default configuration * settings for "ds-cfg-reject-unauthenticated-requests". */ @Test() public void testUnauthSearchDefCfg() { DirectoryServer.setRejectUnauthenticatedRequests(false); String[] args = { "--noPropertiesFile", "-h", "127.0.0.1", "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), "-b", "", "-s", "base", "(objectClass=*)" }; assertEquals(LDAPSearch.mainSearch(args, false, null, System.err), 0); }
/** {@inheritDoc} */ public boolean isConfigurationChangeAcceptable( RootDNUserCfg configuration, List<Message> unacceptableReasons) { boolean configAcceptable = true; // There must not be any new alternate bind DNs that are already in use by // other root users. for (DN altBindDN : configuration.getAlternateBindDN()) { DN existingRootDN = DirectoryServer.getActualRootBindDN(altBindDN); if ((existingRootDN != null) && (!existingRootDN.equals(configuration.dn()))) { Message message = ERR_CONFIG_ROOTDN_CONFLICTING_MAPPING.get( String.valueOf(altBindDN), String.valueOf(configuration.dn()), String.valueOf(existingRootDN)); unacceptableReasons.add(message); configAcceptable = false; } } return configAcceptable; }
/** {@inheritDoc} */ public boolean isConfigurationAddAcceptable( RootDNUserCfg configuration, List<Message> unacceptableReasons) { // The new root user must not have an alternate bind DN that is already // in use. boolean configAcceptable = true; for (DN altBindDN : configuration.getAlternateBindDN()) { DN existingRootDN = DirectoryServer.getActualRootBindDN(altBindDN); if (existingRootDN != null) { Message message = ERR_CONFIG_ROOTDN_CONFLICTING_MAPPING.get( String.valueOf(altBindDN), String.valueOf(configuration.dn()), String.valueOf(existingRootDN)); unacceptableReasons.add(message); configAcceptable = false; } } return configAcceptable; }
private Integer getIntegerUserAttribute( Entry userEntry, String attributeTypeName, Arg1<Object> nonUniqueAttributeMessage, Arg2<Object, Object> cannotProcessAttributeMessage) { AttributeType attrType = DirectoryServer.getAttributeTypeOrDefault(attributeTypeName); List<Attribute> attrList = userEntry.getAttribute(attrType); if (attrList != null && attrList.size() == 1) { Attribute a = attrList.get(0); if (a.size() == 1) { ByteString v = a.iterator().next(); try { return Integer.valueOf(v.toString()); } catch (Exception e) { logger.traceException(e); logger.error(cannotProcessAttributeMessage.get(v, userEntry.getName())); } } else if (a.size() > 1) { logger.error(nonUniqueAttributeMessage.get(userEntry.getName())); } } return null; }
/** * 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)); } } } }
private void processSearch(BooleanHolder executePostOpPlugins) throws CanceledOperationException { // Process the search base and filter to convert them from their raw forms // as provided by the client to the forms required for the rest of the // search processing. baseDN = getBaseDN(); filter = getFilter(); if (baseDN == null || filter == null) { return; } // Check to see if there are any controls in the request. If so, then // see if there is any special processing required. try { handleRequestControls(); } catch (DirectoryException de) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, de); } setResponseData(de); return; } // Check to see if the client has permission to perform the // search. // FIXME: for now assume that this will check all permission // pertinent to the operation. This includes proxy authorization // and any other controls specified. try { if (!AccessControlConfigManager.getInstance().getAccessControlHandler().isAllowed(this)) { setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS); appendErrorMessage(ERR_SEARCH_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS.get(String.valueOf(baseDN))); return; } } catch (DirectoryException e) { setResultCode(e.getResultCode()); appendErrorMessage(e.getMessageObject()); return; } // Check for a request to cancel this operation. checkIfCanceled(false); // Invoke the pre-operation search plugins. executePostOpPlugins.value = true; PluginResult.PreOperation preOpResult = DirectoryServer.getPluginConfigManager().invokePreOperationSearchPlugins(this); if (!preOpResult.continueProcessing()) { setResultCode(preOpResult.getResultCode()); appendErrorMessage(preOpResult.getErrorMessage()); setMatchedDN(preOpResult.getMatchedDN()); setReferralURLs(preOpResult.getReferralURLs()); return; } // Check for a request to cancel this operation. checkIfCanceled(false); // Get the backend that should hold the search base. If there is none, // then fail. if (backend == null) { setResultCode(ResultCode.NO_SUCH_OBJECT); appendErrorMessage(ERR_SEARCH_BASE_DOESNT_EXIST.get(String.valueOf(baseDN))); return; } // We'll set the result code to "success". If a problem occurs, then it // will be overwritten. setResultCode(ResultCode.SUCCESS); try { // If there's a persistent search, then register it with the server. boolean processSearchNow = true; if (persistentSearch != null) { // If we're only interested in changes, then we do not actually want // to process the search now. processSearchNow = !persistentSearch.isChangesOnly(); // The Core server maintains the count of concurrent persistent searches // so that all the backends (Remote and Local) are aware of it. Verify // with the core if we have already reached the threshold. if (!DirectoryServer.allowNewPersistentSearch()) { setResultCode(ResultCode.ADMIN_LIMIT_EXCEEDED); appendErrorMessage(ERR_MAX_PSEARCH_LIMIT_EXCEEDED.get()); return; } backend.registerPersistentSearch(persistentSearch); persistentSearch.enable(); } if (processSearchNow) { // Process the search in the backend and all its subordinates. backend.search(this); } } catch (DirectoryException de) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.VERBOSE, de); } setResponseData(de); if (persistentSearch != null) { persistentSearch.cancel(); setSendResponse(true); } return; } catch (CanceledOperationException coe) { if (persistentSearch != null) { persistentSearch.cancel(); setSendResponse(true); } throw coe; } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } setResultCode(DirectoryServer.getServerErrorResultCode()); appendErrorMessage(ERR_SEARCH_BACKEND_EXCEPTION.get(getExceptionMessage(e))); if (persistentSearch != null) { persistentSearch.cancel(); setSendResponse(true); } } }
/** * Ensures that password policy pwdPolicySubentry operational attribute reflects active password * policy for a given user entry. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testPasswordPolicySubentryAttribute() throws Exception { PasswordPolicy defaultPolicy = DirectoryServer.getDefaultPasswordPolicy(); assertNotNull(defaultPolicy); Entry testEntry = DirectoryServer.getEntry(DN.decode("uid=rogasawara," + BASE)); assertNotNull(testEntry); AttributeType attrType = DirectoryServer.getAttributeType("pwdpolicysubentry"); // Make sure that default policy is in effect // for the user entry. assertTrue(testEntry.hasAttribute(attrType)); assertTrue( testEntry.hasValue( attrType, null, AttributeValues.create(attrType, defaultPolicy.getDN().toString()))); // Add new subentry policy with the // scope to apply to the user entry. Entry policyEntry = TestCaseUtils.makeEntry( "dn: cn=Temp Policy," + SUFFIX, "objectClass: top", "objectClass: pwdPolicy", "objectClass: subentry", "cn: Temp Policy", "subtreeSpecification: { base \"ou=people\" }", "pwdLockoutDuration: 300", "pwdMaxFailure: 3", "pwdMustChange: true", "pwdAttribute: userPassword"); InternalClientConnection connection = InternalClientConnection.getRootConnection(); AddOperation addOperation = connection.processAdd( policyEntry.getDN(), policyEntry.getObjectClasses(), policyEntry.getUserAttributes(), policyEntry.getOperationalAttributes()); assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS); assertNotNull(DirectoryServer.getEntry(policyEntry.getDN())); // Make sure just added policy is in effect. testEntry = DirectoryServer.getEntry(DN.decode("uid=rogasawara," + BASE)); assertNotNull(testEntry); assertTrue(testEntry.hasAttribute(attrType)); assertTrue( testEntry.hasValue( attrType, null, AttributeValues.create(attrType, "cn=Temp Policy," + SUFFIX))); // Remove subentry policy and make sure // default policy is in effect again. TestCaseUtils.deleteEntry(policyEntry.getDN()); testEntry = DirectoryServer.getEntry(DN.decode("uid=rogasawara," + BASE)); assertNotNull(testEntry); assertTrue(testEntry.hasAttribute(attrType)); assertTrue( testEntry.hasValue( attrType, null, AttributeValues.create(attrType, defaultPolicy.getDN().toString()))); }