Access Control

The DS evaluation setup profile leaves access more open, especially to sample Example.com data. This makes it easy to demonstrate and learn features before you fully understand access control. When deploying DS servers in production, grant only the necessary access.

Access Control Mechanisms

DS servers support two access control mechanisms, ACIs for directory servers, and global access control policies for proxy servers.

Characteristic Access Control Instructions (ACIs) Global Access Control Policies

Default for

Directory Servers.

Directory Proxy Servers.

Where

Operational aci attributes (replicated).

global-aci properties (not replicated).

global-access-control-policy entries (not replicated).

Default access

No access unless explicitly granted.(1)

No access unless explicitly granted.

Level of control

Very fine-grained control that can depend on the directory data.

Overall control that does not require access to directory data.

Interaction(2)

When configured, global policies have no effect.

When configured, ACIs have no effect.

Reference

(1) The bypass-acl privilege grants users access regardless of ACIs.

(2) In the rare event that you choose to change the type of server and the type of its access control handler, you must stop the server and make the change with the dsconfig --offline command.

Some operations require administrative privileges and access control. By combining access control and privileges, you effectively restrict the scope of the privileges. Privileges are described in Administrative Roles.

Directory Server ACIs

  • ACIs set scoped permissions which depend on what operation is requested, who requested the operation, and how the client connected to the server.

  • To let other users change ACIs, grant them the modify-acl privilege and permission to edit aci attributes.

    For examples, see Learn Access Control.

ACI Syntax

targets (version 3.0; acl "name"; permissions subjects;)
targets

The ACI applies to the target entries, attributes, controls, and extended operations.

To define multiple targets, put each target in parentheses, (). All targets must match for the ACI to apply (AND).

name

Human-readable description of what the ACI does.

permissions

Actions to allow, and which to deny.

Paired with subjects.

subjects

Clients the permissions apply to, and the conditions under which they apply.

Paired with permissions.

Separate multiple permissions-subjects pairs with semicolons, ;. At least one must match for the ACI to apply (OR).

ACI Targets

Most target expressions let you use either = (target must match), or != (target must not match):

(target [!]= "ldap:///DN")

The ACI scope is the entry with distinguished name DN, and subordinates.

Use an asterisk, \*, to replace attribute types, attribute values, and entire DN components. The following example targets uid=bjensen,ou=People,dc=example,dc=com and cn=My App,ou=Apps,dc=example,dc=com:

(target = "ldap:///*=*,*,dc=example,dc=com")

The DN must be in the subtree of the entry where the ACI is defined.

If you omit target, the ACI applies to its entry.

If you omit targetscope as well, the ACI applies to its entry and all subordinates.

(targetattr [!]= "attr-list")

The ACI targets the specified attributes.

In the attr-list, separate attribute names with ||.

This ACI affects its entry, or the entries specified by other targets in the ACI.

For best performance, explicitly list attributes. Use an asterisk, \*, to specify all user attributes. Use a plus sign, \+, to specify all operational attributes.

A negated attr-list of operational attributes matches only other operational attributes, never any user attributes, and vice-versa.

If you omit targetattr, by default this ACI does not affect attributes.

(targetfilter [!]= "ldap-filter")

This ACI is scoped to match the ldap-filter dynamically, as in an LDAP search. The ldap-filter can be any valid LDAP filter.

(targattrfilters = "expression")

Use this target specification when managing changes made to particular attributes.

The expression takes one of the following forms. Separate expressions with commas (,):

op=attr1:filter1[&& attr2:filter2 ...][,op=attr3:filter3[&& attr4:filter4 ...] ...]

The op can be either add for operations creating attributes, or del for operations removing them.

Replace attr with an attribute type. Replace filter with an LDAP filter that corresponds to the attr attribute type.

(targetscope = "base|onelevel|subtree|subordinate")
  • base refers to the entry with the ACI.

  • onelevel refers to immediate children.

  • subtree refers to the base entry and all children.

  • subordinate refers to all children only. If you omit targetscope, the default is subtree.

(targetcontrol [!]= "alias-or-OID")

The ACI targets the LDAP control with the specified alias or object identifier alias-or-OID. Separate multiple aliases or OIDs with ||.

DS servers support the following control aliases for ACIs:

  • AccountUsable, AccountUsability (1.3.6.1.4.1.42.2.27.9.5.8)

  • ActiveDirectoryChangeNotification, AdChangeNotification (1.2.840.113556.1.4.528)

  • Affinity (1.3.6.1.4.1.36733.2.1.5.2)

  • Assertion, LdapAssertion (1.3.6.1.1.12)

  • AuthorizationIdentity, AuthzId (2.16.840.1.113730.3.4.16)

  • Csn, ChangeNumber, ChangeSequenceNumber (1.3.6.1.4.1.42.2.27.9.5.9)

  • Ecl, EclCookie, ExternalChangelogCookie (1.3.6.1.4.1.26027.1.5.4)

  • EffectiveRights, GetEffectiveRights (1.3.6.1.4.1.42.2.27.9.5.2)

  • ManageDsaIt (2.16.840.1.113730.3.4.2)

  • MatchedValues (1.2.826.0.1.3344810.2.3)

  • NoOp (1.3.6.1.4.1.4203.1.10.2)

  • PasswordPolicy, PwdPolicy, PwpPolicy (1.3.6.1.4.1.42.2.27.8.5.1)

  • PasswordQualityAdvice (1.3.6.1.4.1.36733.2.1.5.5)

  • PermissiveModify (1.2.840.113556.1.4.1413)

  • PersistentSearch, PSearch (2.16.840.1.113730.3.4.3)

  • PostRead (1.3.6.1.1.13.2)

  • PreRead (1.3.6.1.1.13.1)

  • ProxiedAuthV1 (2.16.840.1.113730.3.4.12)

  • ProxiedAuthV2, ProxiedAuth (2.16.840.1.113730.3.4.18)

  • RealAttrsOnly, RealAttributesOnly (2.16.840.1.113730.3.4.17)

  • RelaxRules (1.3.6.1.4.1.4203.666.5.12)

  • ReplicationRepair (1.3.6.1.4.1.26027.1.5.2)

  • ServerSideSort, Sort (1.2.840.113556.1.4.473)

  • SimplePagedResults, PagedResults (1.2.840.113556.1.4.319)

  • SubEntries (1.3.6.1.4.1.4203.1.10.1)

  • SubtreeDelete, TreeDelete (1.2.840.113556.1.4.805)

  • TransactionId, TxnId (1.3.6.1.4.1.36733.2.1.5.1)

  • VirtualAttrsOnly, VirtualAttributesOnly (2.16.840.1.113730.3.4.19)

  • Vlv, VirtualListView (2.16.840.1.113730.3.4.9)

To use an LDAP control, the bind DN user must have allow(read) permissions. This target cannot be restricted to a specific subtree.

(extop [!]= "alias-or-OID")

This ACI targets the LDAP extended operation with the specified alias or object identifier alias-or-OID. Separate multiple aliases or OIDs with ||.

DS servers support the following extended operation aliases for ACIs:

  • Cancel (1.3.6.1.1.8)

  • GetConnectionId, ConnectionId (1.3.6.1.4.1.26027.1.6.2)

  • GetSymmetricKey, SymmetricKey (1.3.6.1.4.1.26027.1.6.3)

  • PasswordModify (1.3.6.1.4.1.4203.1.11.1)

  • PasswordPolicyState (1.3.6.1.4.1.26027.1.6.1)

  • StartTls (1.3.6.1.4.1.1466.20037)

  • WhoAmI (1.3.6.1.4.1.4203.1.11.3)

To use an LDAP extended operation, the bind DN user must have allow(read) permissions. This target cannot be restricted to a specific subtree.

ACI Permissions

ACI permission definitions take one of the following forms:

allow(action[, action ...])
deny(action[, action ...])

Avoid using deny.

Instead, explicitly allow access only as needed. What looks harmless and simple in tests and examples can grow complicated quickly with nested ACIs.

The action is one of the following:

add

Entry creation, as for an LDAP add operation.

all

All permissions, except export, import, proxy.

compare

Attribute value comparison, as for an LDAP compare operation.

delete

Entry deletion, as for an LDAP delete operation.

export

Entry export during a modify DN operation.

Despite the name, this action is unrelated to LDIF export operations.

import

Entry import during a modify DN operation.

Despite the name, this action is unrelated to LDIF import operations.

proxy

Access the ACI target using the rights of another user.

read

Read entries and attributes, or use an LDAP control or extended operation.

search

Search the ACI targets.

Combine with read to read the search results.

selfwrite

Add or delete own DN from a group.

write

Modify attributes on ACI target entries.

ACI Subjects

Subjects restrict whether the ACI applies depending on who connected, and when, where, and how they connected.

Most target expressions allow you to use either = (condition must match), or != (condition must not match):

authmethod [!]= "none|simple|ssl|sasl mech"
  • none: ignore the authentication method.

  • simple: simple authentication.

  • ssl: certificate-based authentication over LDAPS.

  • sasl mech: SASL authentication, where mech is the SASL mechanism, such as EXTERNAL, or GSSAPI.

dayofweek [!]= "day[, day…​]"

Valid days:

  • sun (Sunday)

  • mon (Monday)

  • tue (Tuesday)

  • wed (Wednesday)

  • thu (Thursday)

  • fri (Friday)

  • sat (Saturday)

dns [!]= "hostname"

Use an asterisk, *, to replace name components, as in dns = "*.example.com".

groupdn [!]= "ldap:///DN [|| ldap:///DN …​]"

The subjects are the members of the group with the specified DN.

ip [!]= "addresses"

Valid IP addresses:

  • Individual IPv4 or IPv6 addresses.

    Put IPv6 addresses in brackets, as in ldap://[address]/subnet-prefix, where /subnet-prefix is optional.

  • Addresses with asterisk (*) for a subnet or host number.

  • CIDR notation.

  • Forms such as 192.168.0.*+255.255.255.0 to specify subnet masks.

ssf = "strength"

The security strength factor (ssf) reflects the cipher key strength for a secure connection.

The ssf takes an integer in the range 0-1024:

  • ssf = 0: send plain text with no connection security.

  • ssf = 1: configure TLS without a cipher. The server verifies integrity using packet checksums, but all content is sent in cleartext.

  • ssf >= "256": require a cipher strength of at least 256 bits.

The ssf setting can help to neutralize STRIPTLS attacks. A TLS stripping attack is a man-in-the-middle attack. It takes advantage of the fact that the initial TLS handshake starts on an unencrypted connection. An attacker who has control of the network makes it appear during the handshake that TLS is not available. Client applications may then fall back to using the connection without TLS encryption. In this case, ACIs with ssf settings greater than 1 require encryption to grant access. Use an appropriately high ssf setting in your ACIs, such as ssf >= "256" to ensure secure encryption.

timeofday = "hhmm"

Express times, hhmm, as on a 24-hour clock.

For example, 1:15 PM is written 1315.

userattr [!]= "attr#value"

The userattr subject specifies an attribute that must match on the bind entry and the ACI target entry:

  • Use userattr [!]= "attr#value" when the bind entry and target entry have the same attribute. The attr is a user attribute. The value is the attribute value.

    The server does an internal search to get the attributes of the bind entry. Therefore, this ACI subject does not work with operational attributes.

  • Use userattr [!]= ldap-url#LDAPURL" when the target entry is identified by the LDAP URL, and the bind entry is in the subtree scope of the DN in the LDAP URL.

  • Use userattr [!]= "[parent[child-level].]attr#GROUPDN" when the bind DN is a member of the group identified by the attr of the target entry.

  • Use userattr [!]= "[parent[child-level].]attr#USERDN" when the bind DN is referenced by the attr of the target entry.

The optional inheritance specification, parent[child-level]., defines how many levels below the target entry inherit the ACI. The child-level is a number from 0 to 9, with 0 indicating the target entry only. Separate multiple child-level digits with commas (,).

userdn [!]= "ldap-url++[|| ldap-url++ …​]"

This subject matches either a valid LDAP URL, or a special LDAP URL-like keyword from the following list:

ldap:///all

Match authenticated users.

ldap:///anyone

Match anonymous and authenticated users.

ldap:///parent

Match when the bind DN is a parent of the ACI target.

ldap:///self

Match when the bind DN entry corresponds to ACI target.

ACI Evaluation

The rules the server follows are simple:

  1. To determine whether an operation is allowed or denied, DS servers look in the directory for the target of the operation. The server collects any ACI values from that entry, and then walks up the directory tree to the base DN, collecting all ACI values en route. It then collects global ACI values.

  2. The server separates the ACI values into two lists. One list contains all the ACI values that match the target and deny the required access. The other list contains all the ACI values that match the target and allow the required access.

  3. If the deny list contains any ACI values after this procedure, access is immediately denied.

  4. If the deny list is empty, the server processes the allow list. If the allow list contains any ACI values, access is allowed.

  5. If both lists are empty, access is denied.

Some operations require multiple permissions and involve multiple targets. Evaluation therefore takes place multiple times.

For example, a search operation requires the search permission for each attribute in the search filter. If applicable ACIs allow all search permissions, the server uses read permissions to decide which attributes and values to return.

ACI by Operation

Add

The ACI must allow the add permission to entries in the target. This implicitly lets users set attributes and values.

Use targattrfilters to explicitly deny access to any values if required.

For example, this ACI lets uid=bjensen,ou=People,dc=example,dc=com add an entry:

aci: (version 3.0;acl "Add entry"; allow (add)
 (userdn = "ldap:///uid=bjensen,ou=People,dc=example,dc=com");)
Bind

Because a bind establishes the user’s identity and derived authorizations, ACI is irrelevant for this operation and is not checked.

To prevent authentication, disable the account instead.

Compare

The ACI must allow the compare permission to the attribute in the target entry.

For example, this ACI lets uid=bjensen,ou=People,dc=example,dc=com compare values against the sn attribute:

aci: (targetattr = "sn")(version 3.0;acl "Compare surname"; allow (compare)
 (userdn = "ldap:///uid=bjensen,ou=People,dc=example,dc=com");)
Delete

The ACI must allow the delete permission to the target entry. This implicitly lets users delete attributes and values in the target.

Use targattrfilters to explicitly deny access to the values if required.

For example, this ACI lets uid=bjensen,ou=People,dc=example,dc=com delete an entry:

aci: (version 3.0;acl "Delete entry"; allow (delete)
 (userdn = "ldap:///uid=bjensen,ou=People,dc=example,dc=com");)
Modify

The ACI must allow the write permission to attributes in the target entries. This implicitly lets users modify all values of the target attribute.

Use targattrfilters to explicitly deny access to specific values if required.

For example, this ACI lets uid=bjensen,ou=People,dc=example,dc=com modify the description attribute in an entry:

aci: (targetattr = "description")(version 3.0; acl "Modify description";
 allow (write) (userdn = "ldap:///uid=bjensen,ou=People,dc=example,dc=com");)
ModifyDN

If the entry is being moved to a newSuperior, the export permission must be allowed on the target, and the import permission must be allowed on the newSuperior entry.

The ACI must allow write permission to the attributes in the old RDN and the new RDN. This implicitly lets users write all values of the old RDN and new RDN.

Use targattrfilters to explicitly deny access to values used if required.

For example, this ACI lets uid=bjensen,ou=People,dc=example,dc=com rename entries named with the uid attribute to new locations:

aci: (targetattr = "uid")(version 3.0;acl "Rename uid= entries";
 allow (write, import, export)
 (userdn = "ldap:///uid=bjensen,ou=People,dc=example,dc=com");)
Search

ACI is required to process the search filter, and to determine which attributes and values the server returns. The search permission allows particular attributes in the search filter. The read permission allows particular attributes to be returned.

If read permission is allowed to any attribute, the server automatically allows reads of the objectClass attribute.

For example, this ACI lets uid=bjensen,ou=People,dc=example,dc=com search for uid attributes, and read that attribute in matching entries:

aci: (targetattr = "uid")(version 3.0;acl "Search and read uid";
 allow (search, read) (userdn = "ldap:///uid=bjensen,ou=People,dc=example,dc=com");)
Use Control or Extended Operation

The ACI must allow the read permission to the targetcontrol or extop OIDs.

For example, this ACI lets uid=bjensen,ou=People,dc=example,dc=com use the Persistent Search request control with OID 2.16.840.1.113730.3.4.3:

aci: (targetcontrol = "PSearch")
 (version 3.0;acl "Request Persistent Search"; allow (read)
 (userdn = "ldap:///uid=bjensen,ou=People,dc=example,dc=com");)

Default Global ACIs

Modifying and removing global ACIs can have deleterious effects. Modifications to global ACIs fall into the following categories:

  • Modification or removal is permitted.

    You must test client applications when deleting the specified ACI.

  • Modification or removal may affect applications.

    You must test client applications when modifying or deleting the specified ACI.

  • Modification or removal may affect applications, but is not recommended.

    You must test client applications when modifying or deleting the specified ACI.

  • Do not modify or delete.

Name Description ACI Definition

Anonymous extended operation access

Anonymous and authenticated users can request the LDAP extended operations that are specified by OID or alias. Modification or removal may affect applications.

(extop="Cancel||GetSymmetricKey||PasswordModify||StartTls||WhoAmI") (version 3.0; acl "Anonymous extended operation access"; allow(read) userdn="ldap:///anyone";)

Anonymous extended operation access

Anonymous and authenticated users can request the LDAP extended operations that are specified by OID or alias. Modification or removal may affect applications.

(targetcontrol="Assertion||AuthorizationIdentity||MatchedValues||NoOp||PasswordPolicy||PasswordQualityAdvice||PermissiveModify||PostRead||PreRead||RealAttrsOnly||SimplePagedResults||TransactionId||VirtualAttrsOnly||Vlv") (version 3.0; acl "Anonymous extended operation access"; allow(read) userdn="ldap:///anyone";)

Authenticated users extended operation access

Authenticated users can request the LDAP extended operations that are specified by OID or alias. Modification or removal may affect applications.

(targetcontrol="ManageDsaIt||RelaxRules||ServerSideSort||SubEntries||SubtreeDelete") (version 3.0; acl "Authenticated users extended operation access"; allow(read) userdn="ldap:///all";)

Authenticated users extended operation access

Authenticated users can request the LDAP extended operations that are specified by OID or alias. Modification or removal may affect applications.

(extop="PasswordPolicyState") (version 3.0; acl "Authenticated users extended operation access"; allow(read) userdn="ldap:///all";)

User-Visible Monitor Attributes

Authenticated users can read monitoring information if they have the monitor read privilege. Modification or removal may affect applications.

(target="ldap:///cn=monitor")(targetattr="*||+") (version 3.0; acl "User-Visible Monitor Attributes"; allow (read,search,compare) userdn="ldap:///all";)

User-Visible Root DSE Operational Attributes

Anonymous and authenticated users can read attributes that describe what the server supports. Modification or removal may affect applications.

(target="ldap:///")(targetscope="base") (targetattr="objectClass||namingContexts||subSchemaSubEntry||supportedAuthPasswordSchemes||supportedControl||supportedExtension||supportedFeatures||supportedLDAPVersion||supportedSASLMechanisms||supportedTLSCiphers||supportedTLSProtocols||vendorName||vendorVersion||fullVendorVersion||alive||healthy")(version 3.0; acl "User-Visible Root DSE Operational Attributes"; allow (read,search,compare) userdn="ldap:///anyone";)

User-Visible Schema Operational Attributes

Authenticated users can read LDAP schema definitions. Modification or removal may affect applications.

(target="ldap:///cn=schema")(targetscope="base") (targetattr="objectClass||attributeTypes||dITContentRules||dITStructureRules ||ldapSyntaxes||matchingRules||matchingRuleUse||nameForms||objectClasses||etag||modifiersName||modifyTimestamp") (version 3.0; acl "User-Visible Schema Operational Attributes"; allow (read,search,compare) userdn="ldap:///all";)

Effective Rights

As the number of ACIs increases, it can be difficult to understand what rights a user actually has. The Get Effective Rights control (OID 1.3.6.1.4.1.42.2.27.9.5.2) lets you see the rights as evaluated by the server.

By default, only users who can bypass ACIs can use the Get Effective Rights control, and the related operational attributes, aclRights and aclRightsInfo. The following command grant access to My App:

$ dsconfig \
 set-access-control-handler-prop \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --add global-aci:\(targetcontrol=\"EffectiveRights\"\)\ \(version\ 3.0\;acl\ \"Allow\ My\ App\ to\ get\ effective\ rights\"\;\ allow\(read\)\ userdn=\"ldap:///cn=My\ App,ou=Apps,dc=example,dc=com\"\;\) \
 --add global-aci:\(targetattr=\"aclRights\|\|aclRightsInfo\"\)\(version\ 3.0\;\ acl\ \"Allow\ My\ App\ to\ read\ effective\ rights\ attributes\"\;\ allow\ \(read,search,compare\)\ userdn=\"ldap:///cn=My\ App,ou=Apps,dc=example,dc=com\"\;\) \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

In this example, Babs Jensen owns the LDAP group that includes people who are willing to carpool:

$ ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN "uid=bjensen,ou=people,dc=example,dc=com" \
 --bindPassword hifalutin \
 --baseDN "ou=Self Service,ou=Groups,dc=example,dc=com" \
 "(cn=Carpoolers)"

dn: cn=Carpoolers,ou=Self Service,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: groupOfNames
description: People who are willing to carpool
cn: Carpoolers
owner: uid=bjensen,ou=People,dc=example,dc=com
member: uid=bjensen,ou=People,dc=example,dc=com

When My App does the same search with the get effective rights control, and requests the aclRights attribute, it sees the rights it has on the entry:

$ ldapsearch \
 --control effectiverights \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN "cn=My App,ou=Apps,dc=example,dc=com" \
 --bindPassword password \
 --baseDN "ou=Self Service,ou=Groups,dc=example,dc=com" \
 "(cn=Carpoolers)" \
 aclRights

dn: cn=Carpoolers,ou=Self Service,ou=Groups,dc=example,dc=com
aclRights;entryLevel: add:1,delete:1,read:1,write:1,proxy:1

When My App requests the aclRightsInfo attribute, the server shows the ACIs that apply:

$ ldapsearch \
 --control effectiverights \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN "cn=My App,ou=Apps,dc=example,dc=com" \
 --bindPassword password \
 --baseDN "ou=Self Service,ou=Groups,dc=example,dc=com" \
 "(cn=Carpoolers)" \
 aclRights \
 aclRightsInfo

dn: cn=Carpoolers,ou=Self Service,ou=Groups,dc=example,dc=com
aclRights;entryLevel: add:1,delete:1,read:1,write:1,proxy:1
aclRightsInfo;logs;entryLevel;add: acl_summary(main): access allowed(add) on entry/attr(cn=Carpoolers,ou=Self Service,ou=Groups,dc=example,dc=com, NULL) to (cn=My App,ou=Apps,dc=example,dc=com) (not proxied) ( reason: evaluated allow , deciding_aci: Proxied authorization for apps)
aclRightsInfo;logs;entryLevel;delete: acl_summary(main): access allowed(delete) on entry/attr(cn=Carpoolers,ou=Self Service,ou=Groups,dc=example,dc=com, NULL) to (cn=My App,ou=Apps,dc=example,dc=com) (not proxied) ( reason: evaluated allow , deciding_aci: Proxied authorization for apps)
aclRightsInfo;logs;entryLevel;proxy: acl_summary(main): access allowed(proxy) on entry/attr(cn=Carpoolers,ou=Self Service,ou=Groups,dc=example,dc=com, NULL) to (cn=My App,ou=Apps,dc=example,dc=com) (not proxied) ( reason: evaluated allow , deciding_aci: Proxied authorization for apps)
aclRightsInfo;logs;entryLevel;read: acl_summary(main): access allowed(read) on entry/attr(cn=Carpoolers,ou=Self Service,ou=Groups,dc=example,dc=com, objectClass) to (cn=My App,ou=Apps,dc=example,dc=com) (not proxied) ( reason: evaluated allow , deciding_aci: Anonymous read and search access)
aclRightsInfo;logs;entryLevel;write: acl_summary(main): access allowed(write) on entry/attr(cn=Carpoolers,ou=Self Service,ou=Groups,dc=example,dc=com, NULL) to (cn=My App,ou=Apps,dc=example,dc=com) (not proxied) ( reason: evaluated allow , deciding_aci: Proxied authorization for apps)

To request effective rights for another user, use the --getEffectiveRightsAuthzid option. This option takes the authorization identity of the user as an argument. The following example shows My App checking Babs’s rights to the same entry:

$ ldapsearch \
 --getEffectiveRightsAuthzid "dn:uid=bjensen,ou=People,dc=example,dc=com" \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN "cn=My App,ou=Apps,dc=example,dc=com" \
 --bindPassword password \
 --baseDN "ou=Self Service,ou=groups,dc=example,dc=com" \
 "(cn=Carpoolers)" \
 aclRights

dn: cn=Carpoolers,ou=Self Service,ou=Groups,dc=example,dc=com
aclRights;entryLevel: add:0,delete:1,read:1,write:0,proxy:0

The following example checks anonymous user rights to the same entry. Notice that the authorization identity for an anonymous user is expressed as the empty DN:

$ ldapsearch \
 --getEffectiveRightsAuthzid "dn:" \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN "cn=My App,ou=Apps,dc=example,dc=com" \
 --bindPassword password \
 --baseDN "ou=Self Service,ou=groups,dc=example,dc=com" \
 "(cn=Carpoolers)" \
 aclRights

dn: cn=Carpoolers,ou=Self Service,ou=Groups,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0

To check access to a potentially nonexistent attribute, use the --getEffectiveRightsAttribute option. This option takes a comma-separated attribute list as an argument. The following example checks Andy Hall’s access to the member attribute for the Carpooler’s group entry:

$ ldapsearch \
 --getEffectiveRightsAuthzid "dn:uid=ahall,ou=People,dc=example,dc=com" \
 --getEffectiveRightsAttribute member \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN "cn=My App,ou=Apps,dc=example,dc=com" \
 --bindPassword password \
 --baseDN "ou=Self Service,ou=groups,dc=example,dc=com" \
 "cn=Carpoolers" \
 aclRights

dn: cn=Carpoolers,ou=Self Service,ou=Groups,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
aclRights;attributeLevel;member: search:1,read:1,compare:1,write:0,selfwrite-add:1,selfwrite-delete:1,proxy:0

Proxy Global Policies

By default, a policy matches all entries, all types of connection, and all users. You set the properties of the policy to restrict its scope of application.

Global access control policies can allow the following:

  • Requests for specified LDAP controls and extended operations.

  • Access to specific attributes, with support for wildcards, @objectclass notation, and exceptions to simplify settings.

  • Read access (for read, search, and compare operations).

  • Write access (for add, delete, modify, and modify DN operations).

  • Requiring authentication before other requests.

  • Requests targeting a particular scope, with wildcards to simplify settings.

  • Requests originating or not from specific client addresses or domains.

  • Requests using a specified protocol.

  • Requests using a specified port.

  • Requests using a minimum security strength factor.

  • Requests from a user whose DN does or does not match a DN pattern.

Default Global Policies

Access control rules are defined using individual access control policy entries. A user’s access is defined as the union of all access control rules that apply to that user. In other words, an individual access control rule can only grant additional access and can not remove rights granted by another rule. This approach results in an access control policy which is easier to understand and audit, since all rules can be understood in isolation.

Policy Settings

Anonymous extended operation and control access

authentication-required
  • false

allowed-extended-operation
  • Cancel

  • GetSymmetricKey

  • PasswordModify

  • StartTLS

  • WhoAmI

allowed-control
  • Assertion

  • MatchedValues

  • NoOp

  • PasswordQualityAdvice

  • PermissiveModify

  • PostRead

  • PreRead

  • RealAttrsOnly

  • SimplePagedResults

  • VirtualAttrsOnly

  • AuthorizationIdentity

  • PasswordPolicy

  • TransactionId

  • Vlv

Authenticated extended operation and control access

authentication-required
  • true

allowed-extended-operation
  • PasswordPolicyState

allowed-control
  • ManageDsaIt

  • SubEntries

  • RelaxRules

  • SubtreeDelete

  • ServerSideSort

Schema access

authentication-required
  • true

request-target-dn-equal-to
  • cn=schema

permission
  • read

allowed-attribute
  • objectClass

  • @subschema

  • etag

  • ldapSyntaxes

  • modifiersName

  • modifyTimestamp

Root DSE access

authentication-required
  • false

request-target-dn-equal-to
  • ""

permission
  • read

allowed-attribute
  • objectClass

  • namingContexts

  • subSchemaSubEntry

  • supportedAuthPasswordSchemes

  • supportedControl

  • supportedExtension

  • supportedFeatures

  • supportedLDAPVersion

  • supportedSASLMechanisms

  • supportedTLSCiphers

  • supportedTLSProtocols

  • vendorName

  • vendorVersion

  • fullVendorVersion

  • alive

  • healthy

Monitor access

authentication-required
  • true

request-target-dn-equal-to
  • cn=monitor

permission
  • read

allowed-attribute
  • *

  • +

Reject Unauthenticated Requests

The following example uses a single broad policy for authenticated access, and another narrow policy for anonymous extended operation access:

Show commands
$ dsconfig \
 create-global-access-control-policy \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --policy-name "Authenticated access all entries" \
 --set authentication-required:true \
 --set request-target-dn-not-equal-to:"**,cn=changelog" \
 --set permission:read \
 --set allowed-attribute:"*" \
 --set allowed-attribute:createTimestamp \
 --set allowed-attribute:creatorsName \
 --set allowed-attribute:entryDN \
 --set allowed-attribute:entryUUID \
 --set allowed-attribute:etag \
 --set allowed-attribute:governingStructureRule \
 --set allowed-attribute:hasSubordinates \
 --set allowed-attribute:isMemberOf \
 --set allowed-attribute:modifiersName \
 --set allowed-attribute:modifyTimestamp \
 --set allowed-attribute:numSubordinates \
 --set allowed-attribute:structuralObjectClass \
 --set allowed-attribute:subschemaSubentry \
 --set allowed-attribute-exception:authPassword \
 --set allowed-attribute-exception:userPassword \
 --set allowed-attribute-exception:debugSearchIndex \
 --set allowed-attribute-exception:@changeLogEntry \
 --set allowed-control:Assertion \
 --set allowed-control:AuthorizationIdentity \
 --set allowed-control:Csn \
 --set allowed-control:ManageDsaIt \
 --set allowed-control:MatchedValues \
 --set allowed-control:Noop \
 --set allowed-control:PasswordPolicy \
 --set allowed-control:PermissiveModify \
 --set allowed-control:PostRead \
 --set allowed-control:PreRead \
 --set allowed-control:ProxiedAuthV2 \
 --set allowed-control:RealAttributesOnly \
 --set allowed-control:ServerSideSort \
 --set allowed-control:SimplePagedResults \
 --set allowed-control:TransactionId \
 --set allowed-control:VirtualAttributesOnly \
 --set allowed-control:Vlv \
 --set allowed-extended-operation:GetSymmetricKey \
 --set allowed-extended-operation:PasswordModify \
 --set allowed-extended-operation:PasswordPolicyState \
 --set allowed-extended-operation:StartTls \
 --set allowed-extended-operation:WhoAmI \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

$ dsconfig \
 create-global-access-control-policy \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --policy-name "Anonymous extended operation access" \
 --set authentication-required:false \
 --set allowed-extended-operation:GetSymmetricKey \
 --set allowed-extended-operation:StartTls \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

Require Secure Connections

The following example creates a policy with a minimum security strength factor of 128. This effectively permits only secure connections for requests targeting data in dc=example,dc=com. The security strength factor defines the key strength for GSSAPI, SSL, and TLS:

$ dsconfig \
 create-global-access-control-policy \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --policy-name "Require secure connections for example.com data" \
 --set request-target-dn-equal-to:"**,dc=example,dc=com" \
 --set request-target-dn-equal-to:dc=example,dc=com \
 --set connection-minimum-ssf:128 \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

Anonymous Requests From Specific Network

The following example allows anonymous requests from clients in the example.com domain:

$ dsconfig \
 set-global-access-control-policy-prop \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --policy-name "Anonymous extended operation access" \
 --set connection-client-address-equal-to:.example.com \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

$ dsconfig \
 set-global-access-control-policy-prop \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --policy-name "Root DSE access" \
 --set connection-client-address-equal-to:.example.com \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

You can also use the connection-client-address-not-equal-to property to reject requests from a particular host, domain, address, or address mask.

For additional details, see Global Access Control Policy.