Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#204] ADD LDAP Relax Rules Control #362

Merged
merged 4 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.forgerock.opendj.ldap.controls;

import org.forgerock.opendj.ldap.ByteString;

public class RelaxRulesControl implements Control{

public final static String OID="1.3.6.1.4.1.4203.666.5.12";

@Override
public String getOID() {
return OID;
}

@Override
public ByteString getValue() {
return null;
}

@Override
public boolean hasValue() {
return false;
}

@Override
public boolean isCritical() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
! CCPL HEADER END
!
! Copyright 2011 ForgeRock AS
! Portions copyright 2024 3A Systems,LLC.
!
-->
<appendix xml:id='appendix-controls'
Expand Down Expand Up @@ -445,5 +446,19 @@
Browsing of Search Results</link></para>
</listitem>
</varlistentry>

<varlistentry xml:id="virtual-list-view-response-control">
<term>The LDAP Relax Rules Control</term>
<listitem>
<indexterm>
<primary>LDAP controls</primary>
<secondary>Relax Rules Control</secondary>
</indexterm>
<para>Object Identifier: 1.3.6.1.4.1.4203.666.5.12</para>
<para>Internet-Draft: <link
xlink:href='https://tools.ietf.org/html/draft-zeilenga-ldap-relax-03'
>ddraft-zeilenga-ldap-relax-03 - The LDAP Relax Rules Control</link></para>
</listitem>
</varlistentry>
</variablelist>
</appendix>
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
! CCPL HEADER END
!
! Copyright 2011-2014 ForgeRock AS
! Portions copyright 2024 3A Systems,LLC.
!
-->
<book xml:id='admin-guide'
Expand All @@ -40,7 +41,14 @@
<year>2011-2014</year>
<holder>ForgeRock AS</holder>
</copyright>
<copyright>
<year>2024- </year>
<holder>Open Identity Platform Community</holder>
</copyright>
<authorgroup>
<author>
<personname><firstname>Valery </firstname><surname>Kharseko</surname></personname>
</author>
<author>
<personname><firstname>Mark </firstname><surname>Craig</surname></personname>
</author>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*
* Copyright 2006-2010 Sun Microsystems, Inc.
* Portions copyright 2014-2016 ForgeRock AS.
* Portions copyright 2022-2024 3A Systems,LLC.
*/
package com.forgerock.opendj.ldap.tools;

Expand Down Expand Up @@ -58,19 +59,7 @@
import org.forgerock.opendj.ldap.Filter;
import org.forgerock.opendj.ldap.LdapException;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.AssertionRequestControl;
import org.forgerock.opendj.ldap.controls.AuthorizationIdentityRequestControl;
import org.forgerock.opendj.ldap.controls.AuthorizationIdentityResponseControl;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.controls.GenericControl;
import org.forgerock.opendj.ldap.controls.GetEffectiveRightsRequestControl;
import org.forgerock.opendj.ldap.controls.PasswordExpiredResponseControl;
import org.forgerock.opendj.ldap.controls.PasswordExpiringResponseControl;
import org.forgerock.opendj.ldap.controls.PasswordPolicyErrorType;
import org.forgerock.opendj.ldap.controls.PasswordPolicyRequestControl;
import org.forgerock.opendj.ldap.controls.PasswordPolicyResponseControl;
import org.forgerock.opendj.ldap.controls.PasswordPolicyWarningType;
import org.forgerock.opendj.ldap.controls.SubtreeDeleteRequestControl;
import org.forgerock.opendj.ldap.controls.*;
import org.forgerock.opendj.ldap.requests.BindRequest;
import org.forgerock.opendj.ldap.requests.Request;
import org.forgerock.opendj.ldap.responses.BindResult;
Expand Down Expand Up @@ -379,6 +368,8 @@ private static String readControlID(final String controlOidStr) {
case "effectiverights":
case "geteffectiverights":
return GetEffectiveRightsRequestControl.OID;
case "relaxrules":
return RelaxRulesControl.OID;
case "noop":
case "no-op":
case "subentries":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*
* Copyright 2008-2010 Sun Microsystems, Inc.
* Portions Copyright 2011-2016 ForgeRock AS.
* Portions copyright 2024 3A Systems,LLC.
*/
package org.opends.server.workflowelement.localbackend;

Expand All @@ -37,6 +38,7 @@
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.RelaxRulesControl;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.ObjectClass;
import org.forgerock.opendj.ldap.schema.Syntax;
Expand Down Expand Up @@ -108,7 +110,8 @@ public class LocalBackendAddOperation
private Map<AttributeType, List<Attribute>> operationalAttributes;
/** The set of user attributes for the entry to add. */
private Map<AttributeType, List<Attribute>> userAttributes;

/** Indicates whether the request included the RelaxRules request control. */
private boolean RelaxRulesControlRequested=false;
/**
* Creates a new operation that may be used to add a new entry in a
* local backend of the Directory Server.
Expand All @@ -122,6 +125,10 @@ public LocalBackendAddOperation(AddOperation add)
LocalBackendWorkflowElement.attachLocalOperation (add, this);
}

@Override
public boolean isSynchronizationOperation() {
return super.isSynchronizationOperation()||RelaxRulesControlRequested;
}


/**
Expand Down Expand Up @@ -406,7 +413,7 @@ private void processAdd(ClientConnection clientConnection,
// sensitive information to the client.
try
{
if (!getAccessControlHandler().isAllowed(this))
if (!getAccessControlHandler().isAllowed(this) || (RelaxRulesControlRequested && !clientConnection.hasPrivilege(Privilege.BYPASS_ACL, this)))
{
setResultCodeAndMessageNoInfoDisclosure(entryDN,
ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
Expand Down Expand Up @@ -957,6 +964,10 @@ else if (OID_PASSWORD_POLICY_CONTROL.equals(oid))
// We don't need to do anything here because it's already handled
// in LocalBackendAddOperation.handlePasswordPolicy().
}
else if (RelaxRulesControl.OID.equals(oid))
{
RelaxRulesControlRequested = true;
}
else if (c.isCritical() && !backend.supportsControl(oid))
{
throw newDirectoryException(entryDN, ResultCode.UNAVAILABLE_CRITICAL_EXTENSION,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*
* Copyright 2008-2011 Sun Microsystems, Inc.
* Portions Copyright 2011-2016 ForgeRock AS.
* Portions copyright 2024 3A Systems,LLC.
*/
package org.opends.server.workflowelement.localbackend;

Expand All @@ -33,6 +34,7 @@
import org.forgerock.opendj.ldap.ModificationType;
import org.forgerock.opendj.ldap.RDN;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.RelaxRulesControl;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.forgerock.opendj.ldap.schema.ObjectClass;
Expand Down Expand Up @@ -123,6 +125,8 @@ public class LocalBackendModifyOperation
private boolean permissiveModify;
/** Indicates whether the request included the password policy request control. */
private boolean pwPolicyControlRequested;
/** Indicates whether the request included the RelaxRules request control. */
private boolean RelaxRulesControlRequested=false;
/** The post-read request control, if present. */
private LDAPPostReadRequestControl postReadRequest;
/** The pre-read request control, if present. */
Expand Down Expand Up @@ -163,6 +167,11 @@ public LocalBackendModifyOperation(ModifyOperation modify)
LocalBackendWorkflowElement.attachLocalOperation (modify, this);
}

@Override
public boolean isSynchronizationOperation() {
return super.isSynchronizationOperation()||RelaxRulesControlRequested;
}

/**
* Returns whether authentication for this user is managed locally
* or via Pass-Through Authentication.
Expand Down Expand Up @@ -527,7 +536,7 @@ private boolean operationIsAllowed()
{
try
{
if (!getAccessControlHandler().isAllowed(this))
if (!getAccessControlHandler().isAllowed(this) || (RelaxRulesControlRequested && !clientConnection.hasPrivilege(Privilege.BYPASS_ACL, this)))
{
setResultCodeAndMessageNoInfoDisclosure(modifiedEntry,
ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
Expand Down Expand Up @@ -684,6 +693,10 @@ else if (OID_PASSWORD_POLICY_CONTROL.equals(oid))
{
pwPolicyControlRequested = true;
}
else if (RelaxRulesControl.OID.equals(oid))
{
RelaxRulesControlRequested = true;
}
else if (c.isCritical() && !backend.supportsControl(oid))
{
throw newDirectoryException(currentEntry, ResultCode.UNAVAILABLE_CRITICAL_EXTENSION,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* information: "Portions Copyright [year] [name of copyright owner]".
*
* Copyright 2013-2016 ForgeRock AS.
* Portions copyright 2024 3A Systems,LLC.
*/
package org.forgerock.opendj.adapter.server3x;

Expand Down Expand Up @@ -39,12 +40,7 @@
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchResultReferenceIOException;
import org.forgerock.opendj.ldap.SearchScope;
import org.forgerock.opendj.ldap.controls.GenericControl;
import org.forgerock.opendj.ldap.controls.MatchedValuesRequestControl;
import org.forgerock.opendj.ldap.controls.PermissiveModifyRequestControl;
import org.forgerock.opendj.ldap.controls.PreReadRequestControl;
import org.forgerock.opendj.ldap.controls.PreReadResponseControl;
import org.forgerock.opendj.ldap.controls.SubentriesRequestControl;
import org.forgerock.opendj.ldap.controls.*;
import org.forgerock.opendj.ldap.requests.AddRequest;
import org.forgerock.opendj.ldap.requests.CompareRequest;
import org.forgerock.opendj.ldap.requests.DeleteRequest;
Expand Down Expand Up @@ -576,6 +572,25 @@ public void testAdapterModifyRequest() throws LdapException, DecodeException {
"modified@example.com");
}

@Test
public void testAdapterModifyRequestRelax() throws LdapException, DecodeException {
final ModifyRequest changeRequest =
Requests.newModifyRequest("uid=user.2, o=test")
.addControl(new RelaxRulesControl())
.addModification(ModificationType.REPLACE, "pwdChangedTime", "20211203224637.000Z");

final Connection connection = Adapters.newRootConnectionFactory().getConnection();
final Result result = connection.modify(changeRequest);
assertThat(result.getDiagnosticMessage()).isEmpty();
assertThat(result.getMatchedDN()).isEmpty();

//Verifies that entry has been correctly modified.
final SearchResultEntry srEntry =
connection.searchSingleEntry(Requests.newSearchRequest(
"uid=user.2, o=test", SearchScope.BASE_OBJECT, "(uid=user.2)").addAttribute("+"));
assertThat(srEntry.getAttribute("pwdChangedTime").firstValueAsString()).isEqualTo(
"20211203224637.000Z");
}
/**
* Tries to modify the existing entry with the same values but using the
* permissive modify control.
Expand Down Expand Up @@ -772,4 +787,6 @@ public void testLDAPConnectionAndAdapterComparison() throws LdapException, Searc
assertThat(entry.getControls().size()).isEqualTo(sdkEntry.getControls().size());
}
}


}
Loading