FR-721 OPENDJ-2071 improve aci checks for proxy auth controls
1 files added
24 files modified
| | |
| | | private Entry authorizationEntry; |
| | | |
| | | /** |
| | | * Used to save the current authorization entry when the authorization |
| | | * entry is switched during a proxy access check. |
| | | */ |
| | | private final Entry saveAuthorizationEntry; |
| | | |
| | | /** |
| | | * This entry is only used if proxied authorization is being used. It is |
| | | * the original authorization entry before the proxied authorization change. |
| | | */ |
| | | private Entry origAuthorizationEntry; |
| | | |
| | | /** |
| | | * True if proxied authorization is being used. |
| | | */ |
| | | private boolean proxiedAuthorization; |
| | |
| | | |
| | | //If the proxied authorization control was processed, then the operation |
| | | //will contain an attachment containing the original authorization entry. |
| | | this.origAuthorizationEntry = |
| | | (Entry) operation.getAttachment(ORIG_AUTH_ENTRY); |
| | | final Entry origAuthorizationEntry = (Entry) operation.getAttachment(ORIG_AUTH_ENTRY); |
| | | this.proxiedAuthorization = origAuthorizationEntry != null; |
| | | this.authorizationEntry=operation.getAuthorizationEntry(); |
| | | |
| | |
| | | |
| | | //Reference the current authorization entry, so it can be put back |
| | | //if an access proxy check was performed. |
| | | this.saveAuthorizationEntry=this.authorizationEntry; |
| | | this.rightsMask = rights; |
| | | } |
| | | |
| | |
| | | this.clientConnection=operation.getClientConnection(); |
| | | this.authInfo = authInfo; |
| | | this.authorizationEntry = authInfo.getAuthorizationEntry(); |
| | | this.saveAuthorizationEntry=this.authorizationEntry; |
| | | this.rightsMask = rights; |
| | | } |
| | | /** |
| | |
| | | return this.authzid.equals(this.authorizationEntry.getName()); |
| | | } |
| | | |
| | | /** |
| | | * If the specified value is true, then the original authorization entry, |
| | | * which is the entry before the switch performed by the proxied |
| | | * authorization control processing should be set to the current |
| | | * authorization entry. If the specified value is false then the proxied |
| | | * authorization entry is switched back using the saved copy. |
| | | * @param val The value used to select the authorization entry to use. |
| | | */ |
| | | public void useOrigAuthorizationEntry(boolean val) { |
| | | if(val) |
| | | authorizationEntry=origAuthorizationEntry; |
| | | else |
| | | authorizationEntry=saveAuthorizationEntry; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setDenyList(List<Aci> denys) { |
| | |
| | | } |
| | | } |
| | | |
| | | // 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. |
| | | List<Aci> candidates = aciList.getCandidateAcis(dn); |
| | | /* |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getProxiedAuthorizationDN() |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN) |
| | | { |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public final OperationType getOperationType() |
| | | { |
| | | // Note that no debugging will be done in this method because it is a likely |
| | |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2013-2014 ForgeRock AS |
| | | * Portions Copyright 2013-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.core; |
| | | |
| | |
| | | return getOperation().toString(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getProxiedAuthorizationDN() |
| | | { |
| | | return getOperation().getProxiedAuthorizationDN(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN) |
| | | { |
| | | getOperation().setProxiedAuthorizationDN(proxiedAuthorizationDN); |
| | | } |
| | | |
| | | } |
| | |
| | | * |
| | | * |
| | | * Copyright 2007-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2013-2014 ForgeRock AS |
| | | * Portions Copyright 2013-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.core; |
| | | |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getProxiedAuthorizationDN() |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN) |
| | | { |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public final AuthenticationType getAuthenticationType() |
| | | { |
| | | return authType; |
| | |
| | | } |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getProxiedAuthorizationDN() |
| | | { |
| | | return getOperation().getProxiedAuthorizationDN(); |
| | | } |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN) |
| | | { |
| | | getOperation().setProxiedAuthorizationDN(proxiedAuthorizationDN); |
| | | } |
| | | |
| | | } |
| | |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2013-2014 ForgeRock AS |
| | | * Portions Copyright 2013-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.core; |
| | | |
| | |
| | | return getOperation().toString(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getProxiedAuthorizationDN() |
| | | { |
| | | return getOperation().getProxiedAuthorizationDN(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN) |
| | | { |
| | | getOperation().setProxiedAuthorizationDN(proxiedAuthorizationDN); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getProxiedAuthorizationDN() |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN) |
| | | { |
| | | } |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public final ByteString getRequestValue() |
| | | { |
| | | return requestValue; |
| | |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2013-2014 ForgeRock AS |
| | | * Portions Copyright 2013-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.core; |
| | | |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getProxiedAuthorizationDN() { |
| | | return getOperation().getProxiedAuthorizationDN(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public ByteString getRawEntryDN() { |
| | | return getOperation().getRawEntryDN(); |
| | | } |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setProxiedAuthorizationDN(DN dn) |
| | | { |
| | | getOperation().setProxiedAuthorizationDN(dn); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getNewDN() |
| | | { |
| | | return getOperation().getNewDN(); |
| | |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011-2014 ForgeRock AS |
| | | * Portions Copyright 2011-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.core; |
| | | |
| | |
| | | return getOperation().toString(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getProxiedAuthorizationDN() |
| | | { |
| | | return getOperation().getProxiedAuthorizationDN(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN){ |
| | | getOperation().setProxiedAuthorizationDN(proxiedAuthorizationDN); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getProxiedAuthorizationDN() |
| | | { |
| | | return operation.getProxiedAuthorizationDN(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN) |
| | | { |
| | | operation.setProxiedAuthorizationDN(proxiedAuthorizationDN); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public CancelRequest getCancelRequest() |
| | | { |
| | | return operation.getCancelRequest(); |
| | |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011-2014 ForgeRock AS |
| | | * Portions Copyright 2011-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.core; |
| | | |
| | |
| | | return getOperation().sendSearchReference(reference); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getProxiedAuthorizationDN() |
| | | { |
| | | return getOperation().getProxiedAuthorizationDN(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN){ |
| | | getOperation().setProxiedAuthorizationDN(proxiedAuthorizationDN); |
| | | } |
| | | |
| | | } |
| | |
| | | // candidate for being called by the logging subsystem. |
| | | return OperationType.UNBIND; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DN getProxiedAuthorizationDN() |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN) |
| | | { |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public final List<Control> getResponseControls() |
| | |
| | | import org.forgerock.opendj.config.server.ConfigException; |
| | | import org.opends.server.controls.ProxiedAuthV1Control; |
| | | import org.opends.server.controls.ProxiedAuthV2Control; |
| | | import org.opends.server.core.AccessControlConfigManager; |
| | | import org.opends.server.core.ExtendedOperation; |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | import org.opends.server.types.*; |
| | | import org.forgerock.opendj.ldap.ResultCode; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import static org.opends.messages.ExtensionMessages.*; |
| | | import static org.opends.messages.ProtocolMessages.ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | /** |
| | |
| | | |
| | | authorizationEntry = proxyControlV1.getAuthorizationEntry(); |
| | | } |
| | | // Check the requester has the authz user in scope of their proxy aci. |
| | | if (! AccessControlConfigManager.getInstance().getAccessControlHandler() |
| | | .mayProxy(clientConnection.getAuthenticationInfo().getAuthenticationEntry(), |
| | | authorizationEntry, operation)) |
| | | { |
| | | final DN dn = authorizationEntry.getName(); |
| | | throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, |
| | | ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED.get(dn)); |
| | | } |
| | | operation.setAuthorizationEntry(authorizationEntry); |
| | | } |
| | | } |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011-2014 ForgeRock AS. |
| | | * Portions Copyright 2011-2015 ForgeRock AS. |
| | | */ |
| | | package org.opends.server.types; |
| | | |
| | |
| | | DN getAuthorizationDN(); |
| | | |
| | | /** |
| | | * Retrieves the proxied authorization DN for this operation if proxied |
| | | * authorization has been requested. |
| | | * |
| | | * @return The proxied authorization DN for this operation if proxied |
| | | * authorization has been requested, or {@code null} if proxied |
| | | * authorization has not been requested. |
| | | */ |
| | | DN getProxiedAuthorizationDN(); |
| | | |
| | | /** |
| | | * Set the proxied authorization DN for this operation if proxied |
| | | * authorization has been requested. |
| | | * |
| | | * @param proxiedAuthorizationDN |
| | | * The proxied authorization DN for this operation if proxied |
| | | * authorization has been requested, or {@code null} if proxied |
| | | * authorization has not been requested. |
| | | */ |
| | | void setProxiedAuthorizationDN(DN proxiedAuthorizationDN); |
| | | |
| | | /** |
| | | * Retrieves the set of attachments defined for this operation, as a |
| | | * mapping between the attachment name and the associated object. |
| | | * |
| | |
| | | import org.opends.server.controls.LDAPPostReadRequestControl; |
| | | import org.opends.server.controls.PasswordPolicyErrorType; |
| | | import org.opends.server.controls.PasswordPolicyResponseControl; |
| | | import org.opends.server.controls.ProxiedAuthV1Control; |
| | | import org.opends.server.controls.ProxiedAuthV2Control; |
| | | import org.opends.server.core.AccessControlConfigManager; |
| | | import org.opends.server.core.AddOperation; |
| | | import org.opends.server.core.AddOperationWrapper; |
| | |
| | | import org.opends.server.core.PluginConfigManager; |
| | | import org.opends.server.schema.AuthPasswordSyntax; |
| | | import org.opends.server.schema.UserPasswordSyntax; |
| | | import org.opends.server.types.AdditionalLogItem; |
| | | import org.opends.server.types.Attribute; |
| | | import org.opends.server.types.AttributeBuilder; |
| | | import org.opends.server.types.AttributeType; |
| | |
| | | postReadRequest = |
| | | getRequestControl(LDAPPostReadRequestControl.DECODER); |
| | | } |
| | | else if (OID_PROXIED_AUTH_V1.equals(oid)) |
| | | else if (LocalBackendWorkflowElement.processProxyAuthControls(this, 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 (!getClientConnection().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(getName(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 (! getClientConnection().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(getName(authorizationEntry)); |
| | | continue; |
| | | } |
| | | else if (OID_PASSWORD_POLICY_CONTROL.equals(oid)) |
| | | { |
| | |
| | | import org.opends.server.api.ClientConnection; |
| | | import org.opends.server.api.plugin.PluginResult; |
| | | import org.opends.server.controls.LDAPAssertionRequestControl; |
| | | import org.opends.server.controls.ProxiedAuthV1Control; |
| | | import org.opends.server.controls.ProxiedAuthV2Control; |
| | | import org.opends.server.core.*; |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | import org.opends.server.types.*; |
| | |
| | | ERR_COMPARE_CANNOT_PROCESS_ASSERTION_FILTER.get(entryDN, de.getMessageObject())); |
| | | } |
| | | } |
| | | else if (oid.equals(OID_PROXIED_AUTH_V1)) |
| | | else if (LocalBackendWorkflowElement.processProxyAuthControls(this, 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); |
| | | if (authorizationEntry == null) |
| | | { |
| | | setProxiedAuthorizationDN(DN.rootDN()); |
| | | } |
| | | else |
| | | { |
| | | setProxiedAuthorizationDN(authorizationEntry.getName()); |
| | | } |
| | | } |
| | | else if (oid.equals(OID_PROXIED_AUTH_V2)) |
| | | { |
| | | // 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); |
| | | if (authorizationEntry == null) |
| | | { |
| | | setProxiedAuthorizationDN(DN.rootDN()); |
| | | } |
| | | else |
| | | { |
| | | setProxiedAuthorizationDN(authorizationEntry.getName()); |
| | | } |
| | | continue; |
| | | } |
| | | |
| | | // NYI -- Add support for additional controls. |
| | |
| | | import org.opends.server.api.plugin.PluginResult; |
| | | import org.opends.server.controls.LDAPAssertionRequestControl; |
| | | import org.opends.server.controls.LDAPPreReadRequestControl; |
| | | import org.opends.server.controls.ProxiedAuthV1Control; |
| | | import org.opends.server.controls.ProxiedAuthV2Control; |
| | | import org.opends.server.core.AccessControlConfigManager; |
| | | import org.opends.server.core.DeleteOperation; |
| | | import org.opends.server.core.DeleteOperationWrapper; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.core.PersistentSearch; |
| | | import org.opends.server.core.PluginConfigManager; |
| | | import org.opends.server.types.AdditionalLogItem; |
| | | import org.opends.server.types.CanceledOperationException; |
| | | import org.opends.server.types.Control; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.Entry; |
| | | import org.opends.server.types.Privilege; |
| | | import org.opends.server.types.SearchFilter; |
| | | import org.opends.server.types.SynchronizationProviderResult; |
| | | import org.opends.server.types.LockManager.DNLock; |
| | |
| | | preReadRequest = |
| | | getRequestControl(LDAPPreReadRequestControl.DECODER); |
| | | } |
| | | else if (OID_PROXIED_AUTH_V1.equals(oid)) |
| | | else if (LocalBackendWorkflowElement.processProxyAuthControls(this, 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(getName(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(getName(authorizationEntry)); |
| | | continue; |
| | | } |
| | | // NYI -- Add support for additional controls. |
| | | else if (c.isCritical() |
| | |
| | | import org.opends.server.controls.LDAPAssertionRequestControl; |
| | | import org.opends.server.controls.LDAPPostReadRequestControl; |
| | | import org.opends.server.controls.LDAPPreReadRequestControl; |
| | | import org.opends.server.controls.ProxiedAuthV1Control; |
| | | import org.opends.server.controls.ProxiedAuthV2Control; |
| | | import org.opends.server.core.AccessControlConfigManager; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.core.ModifyDNOperation; |
| | | import org.opends.server.core.ModifyDNOperationWrapper; |
| | | import org.opends.server.core.PersistentSearch; |
| | | import org.opends.server.core.PluginConfigManager; |
| | | import org.opends.server.types.AdditionalLogItem; |
| | | import org.opends.server.types.Attribute; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.Attributes; |
| | |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.Entry; |
| | | import org.opends.server.types.Modification; |
| | | import org.opends.server.types.Privilege; |
| | | import org.opends.server.types.RDN; |
| | | import org.opends.server.types.SearchFilter; |
| | | import org.opends.server.types.SynchronizationProviderResult; |
| | |
| | | iter.set(postReadRequest); |
| | | } |
| | | } |
| | | else if (OID_PROXIED_AUTH_V1.equals(oid)) |
| | | else if (LocalBackendWorkflowElement.processProxyAuthControls(this, 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(getName(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(getName(authorizationEntry)); |
| | | continue; |
| | | } |
| | | else if (c.isCritical() |
| | | && (backend == null || !backend.supportsControl(oid))) |
| | |
| | | import org.opends.server.controls.LDAPPreReadRequestControl; |
| | | import org.opends.server.controls.PasswordPolicyErrorType; |
| | | import org.opends.server.controls.PasswordPolicyResponseControl; |
| | | import org.opends.server.controls.ProxiedAuthV1Control; |
| | | import org.opends.server.controls.ProxiedAuthV2Control; |
| | | import org.opends.server.core.AccessControlConfigManager; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.core.ModifyOperation; |
| | |
| | | import org.opends.server.types.AcceptRejectWarn; |
| | | import org.opends.server.types.AccountStatusNotification; |
| | | import org.opends.server.types.AccountStatusNotificationType; |
| | | import org.opends.server.types.AdditionalLogItem; |
| | | import org.opends.server.types.Attribute; |
| | | import org.opends.server.types.AttributeBuilder; |
| | | import org.opends.server.types.AttributeType; |
| | |
| | | iter.set(postReadRequest); |
| | | } |
| | | } |
| | | else if (OID_PROXIED_AUTH_V1.equals(oid)) |
| | | else if (LocalBackendWorkflowElement.processProxyAuthControls(this, 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(getName(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(getName(authorizationEntry)); |
| | | continue; |
| | | } |
| | | else if (OID_PASSWORD_POLICY_CONTROL.equals(oid)) |
| | | { |
| | |
| | | * |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011-2014 ForgeRock AS |
| | | * Portions Copyright 2011-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.workflowelement.localbackend; |
| | | |
| | |
| | | de.getMessageObject()), de); |
| | | } |
| | | } |
| | | else if (OID_PROXIED_AUTH_V1.equals(oid)) |
| | | else if (LocalBackendWorkflowElement.processProxyAuthControls(this, 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(getName(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(getName(authorizationEntry)); |
| | | continue; |
| | | } |
| | | else if (OID_PERSISTENT_SEARCH.equals(oid)) |
| | | { |
| | |
| | | import org.opends.server.controls.LDAPPostReadResponseControl; |
| | | import org.opends.server.controls.LDAPPreReadRequestControl; |
| | | import org.opends.server.controls.LDAPPreReadResponseControl; |
| | | import org.opends.server.controls.ProxiedAuthV1Control; |
| | | import org.opends.server.controls.ProxiedAuthV2Control; |
| | | import org.opends.server.core.*; |
| | | import org.opends.server.types.*; |
| | | |
| | | import static org.opends.messages.CoreMessages.*; |
| | | import static org.opends.messages.ProtocolMessages.ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | /** |
| | | * This class defines a local backend workflow element; e-g an entity that |
| | |
| | | for (Iterator<Control> iter = requestControls.iterator(); iter.hasNext();) |
| | | { |
| | | final Control control = iter.next(); |
| | | // The aci check for the proxy auth controls needs to check the authentication DN, |
| | | // not the operation target. |
| | | // TODO should we check the authentication DN for all controls? |
| | | final DN aciTarget; |
| | | if (OID_PROXIED_AUTH_V1.equals(control.getOID()) || OID_PROXIED_AUTH_V2.equals(control.getOID())) |
| | | { |
| | | aciTarget= op.getClientConnection().getAuthenticationInfo().getAuthenticationDN(); |
| | | } |
| | | else |
| | | { |
| | | aciTarget = targetDN; |
| | | } |
| | | |
| | | if (!getAccessControlHandler().isAllowed(targetDN, op, control)) |
| | | if (!getAccessControlHandler().isAllowed(aciTarget, op, control)) |
| | | { |
| | | // As per RFC 4511 4.1.11. |
| | | if (control.isCritical()) |
| | |
| | | } |
| | | |
| | | /** |
| | | * Check the requester has the PROXIED_AUTH privilege in order to be able to use a proxy auth control. |
| | | * |
| | | * @param operation The operation being checked |
| | | * @throws DirectoryException If insufficient privileges are detected |
| | | */ |
| | | static void checkPrivilegeForProxyAuthControl(Operation operation) throws DirectoryException |
| | | { |
| | | if (! operation.getClientConnection().hasPrivilege(Privilege.PROXIED_AUTH, operation)) |
| | | { |
| | | throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, |
| | | ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Check the requester has the authorization user in scope of proxy aci. |
| | | * |
| | | * @param operation The operation being checked |
| | | * @param authorizationEntry The entry being authorized as (e.g. from a proxy auth control) |
| | | * @throws DirectoryException If no proxy permission is allowed |
| | | */ |
| | | static void checkAciForProxyAuthControl(Operation operation, Entry authorizationEntry) throws DirectoryException |
| | | { |
| | | if (! AccessControlConfigManager.getInstance().getAccessControlHandler() |
| | | .mayProxy(operation.getClientConnection().getAuthenticationInfo().getAuthenticationEntry(), |
| | | authorizationEntry, operation)) |
| | | { |
| | | throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, |
| | | ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED.get(authorizationEntry.getName())); |
| | | } |
| | | } |
| | | /** |
| | | * Process the operation control with the given oid if it is a proxy auth control. |
| | | * |
| | | * Privilege and initial aci checks on the authenticating user are performed. The authenticating |
| | | * user must have the proxied-auth privilege, and the authz user must be in the scope of aci |
| | | * allowing the proxy right to the authenticating user. |
| | | * |
| | | * @param operation The operation containing the control(s) |
| | | * @param oid The OID of the detected proxy auth control |
| | | * @return <code>true</code> if the control has been processed, <code>false</code> if not |
| | | * @throws DirectoryException |
| | | */ |
| | | static boolean processProxyAuthControls(Operation operation, String oid) |
| | | throws DirectoryException |
| | | { |
| | | final Entry authorizationEntry; |
| | | |
| | | if (OID_PROXIED_AUTH_V1.equals(oid)) |
| | | { |
| | | final ProxiedAuthV1Control proxyControlV1 = operation.getRequestControl(ProxiedAuthV1Control.DECODER); |
| | | // Log usage of legacy proxy authz V1 control. |
| | | operation.addAdditionalLogItem(AdditionalLogItem.keyOnly(operation.getClass(), |
| | | "obsoleteProxiedAuthzV1Control")); |
| | | checkPrivilegeForProxyAuthControl(operation); |
| | | authorizationEntry = proxyControlV1.getAuthorizationEntry(); |
| | | } |
| | | else if (OID_PROXIED_AUTH_V2.equals(oid)) |
| | | { |
| | | final ProxiedAuthV2Control proxyControlV2 = operation.getRequestControl(ProxiedAuthV2Control.DECODER); |
| | | checkPrivilegeForProxyAuthControl(operation); |
| | | authorizationEntry = proxyControlV2.getAuthorizationEntry(); |
| | | } |
| | | else |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | checkAciForProxyAuthControl(operation, authorizationEntry); |
| | | operation.setAuthorizationEntry(authorizationEntry); |
| | | |
| | | if (authorizationEntry == null) |
| | | { |
| | | operation.setProxiedAuthorizationDN(DN.NULL_DN); |
| | | } |
| | | else |
| | | { |
| | | operation.setProxiedAuthorizationDN(authorizationEntry.getName()); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * Returns a new {@link DirectoryException} built from the provided |
| | | * resultCodes and messages. Depending on whether ACIs prevent information |
| | | * disclosure, the provided resultCode and message will be masked and |
| | |
| | | contain a valid IdentifiedChoiceValue at the current position: %s |
| | | INFO_NULL_KEY_PROVIDER_MANAGER_1524=The keystore %s seems to be missing, \ |
| | | this may render the secure port inoperative for '%s' |
| | | ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED_1525=Authorization as '%s' specified in \ |
| | | the proxied authorization control is not permitted |
| | |
| | | Assert.assertEquals(LDAPResultCode.SUCCESS, expectedRc, ""); |
| | | } |
| | | |
| | | void proxyModify(String ldif, String bindDn, String bindPassword, |
| | | String proxyUser, int expectedRc) |
| | | throws IOException |
| | | { |
| | | File tempFile = getTemporaryLdifFile(); |
| | | TestCaseUtils.writeFile(tempFile, ldif); |
| | | |
| | | ArrayList<String> argList=new ArrayList<>(); |
| | | argList.add("-h"); |
| | | argList.add("127.0.0.1"); |
| | | argList.add("-p"); |
| | | argList.add(String.valueOf(TestCaseUtils.getServerLdapPort())); |
| | | argList.add("-D"); |
| | | argList.add(bindDn); |
| | | argList.add("-w"); |
| | | argList.add(bindPassword); |
| | | if (proxyUser != null) { |
| | | argList.add("-Y"); |
| | | argList.add("dn:" + proxyUser); |
| | | } |
| | | argList.add("-f"); |
| | | argList.add(tempFile.getAbsolutePath()); |
| | | String[] args = new String[argList.size()]; |
| | | ldapModify(argList.toArray(args), expectedRc); |
| | | } |
| | | |
| | | private void ldapModify(String[] args, int expectedRc) |
| | | { |
| | | oStream.reset(); |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.authorization.dseecompat; |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.protocols.ldap.LDAPResultCode; |
| | | import org.opends.server.types.Entry; |
| | | import org.testng.Assert; |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.BeforeMethod; |
| | | import org.testng.annotations.Test; |
| | | |
| | | import java.util.List; |
| | | |
| | | import static org.opends.server.config.ConfigConstants.ATTR_AUTHZ_GLOBAL_ACI; |
| | | |
| | | /** |
| | | * This class tests ACI behavior with the proxy auth control. |
| | | */ |
| | | public class ProxyTestCase extends AciTestCase |
| | | { |
| | | static final String TEST_BASE = "o=test"; |
| | | static final String ALICE_DN = "uid=alice,ou=People," + TEST_BASE; |
| | | static final String BOB_DN = "uid=bob,ou=People," + TEST_BASE; |
| | | static final String CHARLIE_DN = "uid=charlie,ou=People," + TEST_BASE; |
| | | static final String PASSWORD = "password"; |
| | | |
| | | @BeforeClass |
| | | public void setupClass() throws Exception |
| | | { |
| | | deleteAttrFromAdminEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI); |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People," + TEST_BASE, |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "aci: (targetcontrol=\"2.16.840.1.113730.3.4.18\")" + |
| | | "(version 3.0; acl \"Allow proxy auth control\"; " + |
| | | "allow (read) userdn = \"ldap:///" + ALICE_DN + "\";)", |
| | | "aci: (target=\"ldap:///" + CHARLIE_DN + "\")(targetattr = \"telephoneNumber\")" + |
| | | "(version 3.0; acl \"Allow Bob to write Charlie\"; " + |
| | | "allow (write) userdn = \"ldap:///" + BOB_DN + "\";)", |
| | | "aci: (target=\"ldap:///ou=People," + TEST_BASE + "\")" + |
| | | "(version 3.0; acl \"Allow Alice to proxy People\"; " + |
| | | "allow (proxy) userdn = \"ldap:///" + ALICE_DN + "\";)", |
| | | "", |
| | | "dn: " + ALICE_DN, |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: alice", |
| | | "cn: Alice", |
| | | "sn: User", |
| | | "ds-privilege-name: proxied-auth", |
| | | "userPassword: " + PASSWORD, |
| | | "", |
| | | "dn: uid=bob,ou=People," + TEST_BASE, |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: bob", |
| | | "cn: Bob", |
| | | "sn: User", |
| | | "userPassword: " + PASSWORD, |
| | | "", |
| | | "dn: uid=charlie,ou=People," + TEST_BASE, |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: charlie", |
| | | "cn: Charlie", |
| | | "sn: User", |
| | | "userPassword: " + PASSWORD, |
| | | "", |
| | | "dn: ou=Groups," + TEST_BASE, |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Writable by Bob,ou=Groups," + TEST_BASE, |
| | | "objectClass: top", |
| | | "objectClass: groupOfEntries", |
| | | "cn: Writable by Bob", |
| | | "aci: (targetattr=\"description\")" + |
| | | "(version 3.0; acl \"Bob writes\"; " + |
| | | "allow(write) userdn=\"ldap:///" + BOB_DN + "\";)", |
| | | "", |
| | | "dn: cn=Visible to Bob,ou=Groups," + TEST_BASE, |
| | | "objectClass: top", |
| | | "objectClass: groupOfEntries", |
| | | "cn: Visible to Bob", |
| | | "description: Bob can read this group", |
| | | "aci: (targetattr=\"*||+\")" + |
| | | "(version 3.0; acl \"Bob visible\"; " + |
| | | "allow(read,search) userdn=\"ldap:///" + BOB_DN + "\";)", |
| | | "", |
| | | "dn: cn=Invisible to Bob,ou=Groups," + TEST_BASE, |
| | | "objectClass: top", |
| | | "objectClass: groupOfEntries", |
| | | "cn: Invisible to Bob", |
| | | "description: Bob cannot see this group", |
| | | "aci: (targetattr=\"*||+\")" + |
| | | "(version 3.0; acl \"Bob invisible\"; " + |
| | | "deny(read,search) userdn=\"ldap:///" + BOB_DN + "\";)", |
| | | ""); |
| | | } |
| | | |
| | | |
| | | @BeforeMethod |
| | | public void clearBackend() throws Exception |
| | | { |
| | | deleteAttrFromAdminEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI); |
| | | } |
| | | |
| | | /** |
| | | * Test Alice cannot proxy as Root. |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | @Test |
| | | public void testProxyAsRoot() throws Exception |
| | | { |
| | | proxyModify(TestCaseUtils.makeLdif( |
| | | "dn: " + CHARLIE_DN, |
| | | "changetype: modify", |
| | | "replace: telephoneNumber", |
| | | "telephoneNumber: 999"), |
| | | ALICE_DN, PASSWORD, |
| | | DIR_MGR_DN, |
| | | LDAPResultCode.AUTHORIZATION_DENIED); |
| | | } |
| | | |
| | | /** |
| | | * Test Alice (as Bob) modifies Charlie. |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | @Test |
| | | public void testSimpleProxy() throws Exception |
| | | { |
| | | proxyModify(TestCaseUtils.makeLdif( |
| | | "dn: " + CHARLIE_DN, |
| | | "changetype: modify", |
| | | "replace: telephoneNumber", |
| | | "telephoneNumber: 999"), |
| | | ALICE_DN, PASSWORD, |
| | | BOB_DN, |
| | | LDAPResultCode.SUCCESS); |
| | | } |
| | | |
| | | /** |
| | | * Test Alice (as Bob) modifies an entry outside of the proxy target scope. |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | @Test |
| | | public void testUpdateGroup() throws Exception |
| | | { |
| | | proxyModify(TestCaseUtils.makeLdif( |
| | | "dn: cn=Writable by Bob,ou=Groups," + TEST_BASE, |
| | | "changetype: modify", |
| | | "replace: description", |
| | | "description: written by Alice (Bob)"), |
| | | ALICE_DN, PASSWORD, |
| | | BOB_DN, |
| | | LDAPResultCode.SUCCESS); |
| | | } |
| | | |
| | | /** |
| | | * Test Alice (as Bob) can see entries that Bob can see. |
| | | * Only "cn=Visible to Bob,ou=Groups,..." should be returned. |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | @Test |
| | | public void testProxiedSearch() throws Exception |
| | | { |
| | | String results = LDAPSearchParams(ALICE_DN, PASSWORD, BOB_DN, null, null, |
| | | TEST_BASE, "(&)", null, |
| | | false, false, LDAPResultCode.SUCCESS); |
| | | List<Entry> entries = TestCaseUtils.entriesFromLdifString(results); |
| | | Assert.assertEquals(entries.size(), 1, "Wrong number of results"); |
| | | } |
| | | } |