Fix OPENDJ-475: Incorrect behaviour/result code regarding non-critical controls
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011 ForgeRock AS. |
| | | * Portions copyright 2011-2012 ForgeRock AS. |
| | | */ |
| | | package org.opends.server.core; |
| | | import org.opends.messages.MessageBuilder; |
| | |
| | | try |
| | | { |
| | | if (!AccessControlConfigManager.getInstance() |
| | | .getAccessControlHandler().isAllowed( |
| | | this.getAuthorizationDN(), this, c)) |
| | | .getAccessControlHandler() |
| | | .isAllowed(getAuthorizationDN(), this, c)) |
| | | { |
| | | setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS); |
| | | // As per RFC 4511 4.1.11. |
| | | if (c.isCritical()) |
| | | { |
| | | setResultCode(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION); |
| | | appendErrorMessage(ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS |
| | | .get(c.getOID())); |
| | | return; |
| | | } |
| | | else |
| | | { |
| | | // We don't want to process this non-critical control, so |
| | | // remove it. |
| | | removeRequestControl(c); |
| | | continue; |
| | | } |
| | | } |
| | | } |
| | | catch (DirectoryException e) |
| | |
| | | { |
| | | Control c = requestControls.get(i); |
| | | String oid = c.getOID(); |
| | | if (! AccessControlConfigManager.getInstance(). |
| | | getAccessControlHandler().isAllowed(baseDN, this, c)) |
| | | |
| | | if (!AccessControlConfigManager.getInstance().getAccessControlHandler() |
| | | .isAllowed(baseDN, this, c)) |
| | | { |
| | | throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS, |
| | | // As per RFC 4511 4.1.11. |
| | | if (c.isCritical()) |
| | | { |
| | | throw new DirectoryException( |
| | | ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, |
| | | ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid)); |
| | | } |
| | | else |
| | | { |
| | | // We don't want to process this non-critical control, so remove it. |
| | | removeRequestControl(c); |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | if (oid.equals(OID_ECL_COOKIE_EXCHANGE_CONTROL)) |
| | | { |
| | |
| | | * |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011 ForgeRock AS |
| | | * Portions Copyright 2011-2012 ForgeRock AS |
| | | */ |
| | | package org.opends.server.workflowelement.localbackend; |
| | | |
| | |
| | | Control c = requestControls.get(i); |
| | | String oid = c.getOID(); |
| | | |
| | | if (!AccessControlConfigManager.getInstance(). |
| | | getAccessControlHandler().isAllowed(parentDN, this, c)) |
| | | if (!LocalBackendWorkflowElement.isControlAllowed(parentDN, this, c)) |
| | | { |
| | | throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS, |
| | | ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid)); |
| | | // Skip disallowed non-critical controls. |
| | | continue; |
| | | } |
| | | |
| | | if (oid.equals(OID_LDAP_ASSERTION)) |
| | |
| | | * |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011 ForgeRock AS. |
| | | * Portions copyright 2011-2012 ForgeRock AS. |
| | | */ |
| | | package org.opends.server.workflowelement.localbackend; |
| | | |
| | |
| | | Control c = requestControls.get(i); |
| | | String oid = c.getOID(); |
| | | |
| | | if (! AccessControlConfigManager.getInstance(). |
| | | getAccessControlHandler(). isAllowed(bindDN, this, c)) |
| | | if (!LocalBackendWorkflowElement.isControlAllowed(bindDN, this, c)) |
| | | { |
| | | throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS, |
| | | ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid)); |
| | | // Skip disallowed non-critical controls. |
| | | continue; |
| | | } |
| | | |
| | | if (oid.equals(OID_AUTHZID_REQUEST)) |
| | |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011 ForgeRock AS |
| | | * Portions Copyright 2011-2012 ForgeRock AS |
| | | */ |
| | | package org.opends.server.workflowelement.localbackend; |
| | | |
| | |
| | | Control c = requestControls.get(i); |
| | | String oid = c.getOID(); |
| | | |
| | | if (! AccessControlConfigManager.getInstance(). |
| | | getAccessControlHandler().isAllowed(entryDN, this, c)) |
| | | if (!LocalBackendWorkflowElement.isControlAllowed(entryDN, this, c)) |
| | | { |
| | | throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS, |
| | | ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid)); |
| | | // Skip disallowed non-critical controls. |
| | | continue; |
| | | } |
| | | |
| | | if (oid.equals(OID_LDAP_ASSERTION)) |
| | |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011 ForgeRock AS |
| | | * Portions Copyright 2011-2012 ForgeRock AS |
| | | */ |
| | | package org.opends.server.workflowelement.localbackend; |
| | | |
| | |
| | | Control c = requestControls.get(i); |
| | | String oid = c.getOID(); |
| | | |
| | | if (!AccessControlConfigManager.getInstance(). |
| | | getAccessControlHandler().isAllowed(entryDN, this, c)) |
| | | if (!LocalBackendWorkflowElement.isControlAllowed(entryDN, this, c)) |
| | | { |
| | | throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS, |
| | | ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid)); |
| | | // Skip disallowed non-critical controls. |
| | | continue; |
| | | } |
| | | |
| | | if (oid.equals(OID_LDAP_ASSERTION)) |
| | |
| | | Control c = requestControls.get(i); |
| | | String oid = c.getOID(); |
| | | |
| | | if (! AccessControlConfigManager.getInstance(). |
| | | getAccessControlHandler().isAllowed(entryDN, this, c)) |
| | | if (!LocalBackendWorkflowElement.isControlAllowed(entryDN, this, c)) |
| | | { |
| | | throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS, |
| | | ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid)); |
| | | // Skip disallowed non-critical controls. |
| | | continue; |
| | | } |
| | | |
| | | if (oid.equals(OID_LDAP_ASSERTION)) |
| | |
| | | Control c = requestControls.get(i); |
| | | String oid = c.getOID(); |
| | | |
| | | if (! AccessControlConfigManager.getInstance(). |
| | | getAccessControlHandler().isAllowed(entryDN, this, c)) |
| | | if (!LocalBackendWorkflowElement.isControlAllowed(entryDN, this, c)) |
| | | { |
| | | throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS, |
| | | ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid)); |
| | | // Skip disallowed non-critical controls. |
| | | continue; |
| | | } |
| | | |
| | | |
| | | if (oid.equals(OID_LDAP_ASSERTION)) |
| | | { |
| | | LDAPAssertionRequestControl assertControl = |
| | |
| | | * |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011 ForgeRock AS |
| | | * Portions copyright 2011-2012 ForgeRock AS |
| | | */ |
| | | package org.opends.server.workflowelement.localbackend; |
| | | |
| | |
| | | { |
| | | Control c = requestControls.get(i); |
| | | String oid = c.getOID(); |
| | | if (! AccessControlConfigManager.getInstance(). |
| | | getAccessControlHandler().isAllowed(baseDN, this, c)) |
| | | |
| | | if (!LocalBackendWorkflowElement.isControlAllowed(baseDN, this, c)) |
| | | { |
| | | throw new DirectoryException(ResultCode.INSUFFICIENT_ACCESS_RIGHTS, |
| | | ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid)); |
| | | // Skip disallowed non-critical controls. |
| | | continue; |
| | | } |
| | | |
| | | if (oid.equals(OID_LDAP_ASSERTION)) |
| | |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.workflowelement.LeafWorkflowElement; |
| | | |
| | | import static org.opends.messages.CoreMessages.*; |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * Determine whether or not the provided request control is permitted by the |
| | | * access control policy. If it is not allowed, then abort the operation if |
| | | * the control was critical, otherwise ignore it. |
| | | * |
| | | * @param targetDN |
| | | * The operation target DN. |
| | | * @param op |
| | | * The operation. |
| | | * @param control |
| | | * The request control. |
| | | * @return {@code true} if access is allowed, or {@code false} if access is |
| | | * not allowed, but the control is non-critical and should be ignored. |
| | | * @throws DirectoryException |
| | | * If access is not allowed and the control is critical. |
| | | */ |
| | | static boolean isControlAllowed(DN targetDN, Operation op, Control control) |
| | | throws DirectoryException |
| | | { |
| | | if (!AccessControlConfigManager.getInstance().getAccessControlHandler() |
| | | .isAllowed(targetDN, op, control)) |
| | | { |
| | | // As per RFC 4511 4.1.11. |
| | | if (control.isCritical()) |
| | | { |
| | | throw new DirectoryException(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, |
| | | ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(control.getOID())); |
| | | } |
| | | else |
| | | { |
| | | // We don't want the backend to process this non-critical control, so |
| | | // remove it. |
| | | op.removeRequestControl(control); |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds the post-read response control to the response if requested. |
| | | * |
| | | * @param operation |
| | |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | * Portions copyright 2012 ForgeRock AS. |
| | | */ |
| | | |
| | | |
| | |
| | | LDAPSearchParams(level3User, PWD, null, null, null, |
| | | superUser, filter, "aclRights mail description", true, |
| | | true, 0); |
| | | //This should fail since the both controls are not allowed for the |
| | | //ou=admins, o=test suffix. |
| | | //This should succeed since both controls are not allowed for the |
| | | //ou=admins, o=test suffix, but both are critical. |
| | | LDAPSearchParams(superUser, PWD, null, null, null, |
| | | superUser, filter, "aclRights mail description", true, |
| | | true, LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS); |
| | | true, 0); |
| | | deleteAttrFromEntry(peopleBase, "aci"); |
| | | } |
| | | |
| | |
| | | makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN, |
| | | controlAdmin, controlPeople); |
| | | LDIFAdminModify(globalControlAcis, DIR_MGR_DN, PWD); |
| | | //Fails because geteffectiverights control not allowed on |
| | | //ou=people, o=test |
| | | //Succeeds because geteffectiverights control is not allowed on |
| | | //ou=people, o=test, but it is non-critical. |
| | | LDAPSearchParams(level3User, PWD, null, |
| | | "dn: " + level1User, null, |
| | | level1User, filter, "aclRights mail description", |
| | | false, false, LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS); |
| | | false, false, 0); |
| | | //Ok because geteffectiverights control is allowed on |
| | | //ou=admin, o=test |
| | | LDAPSearchParams(level3User, PWD, null, |
| | |
| | | String addEntryLDIF=makeAddEntryLDIF(newPeopleDN, newEntry); |
| | | LDIFAdd(addEntryLDIF, superUser, PWD, controlStr, |
| | | LDAPResultCode.PROTOCOL_ERROR); |
| | | //Test add to ou=admin, o=test with assertion control, |
| | | //Test add to ou=admin, o=test with assertion control, and critical |
| | | //should get access denied since this control is not allowed. |
| | | String addEntryLDIF1=makeAddEntryLDIF(newAdminDN, newEntry); |
| | | LDIFAdd(addEntryLDIF1, superUser, PWD, controlStr, |
| | | LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS); |
| | | LDAPResultCode.UNAVAILABLE_CRITICAL_EXTENSION); |
| | | deleteAttrFromAdminEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI); |
| | | } |
| | | |
| | |
| | | LDAPSearchParams(superUser, PWD, null, |
| | | "dn: " + superUser, null, |
| | | base, filter, "aclRights mail description", false, false, |
| | | LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS); |
| | | 0 /* disallowed but non-critical */); |
| | | LDIFModify(aciRight, superUser, PWD, OID_LDAP_READENTRY_PREREAD, |
| | | LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS); |
| | | deleteAttrFromEntry (base, "aci"); |