Security and access control


Red Hat Directory Server 13

Improving Directory Server security, configuring access control settings

Red Hat Customer Content Services

Abstract

Learn how you can encrypt the connection between a client and the Directory Server, configure user permissions by using access control instructions (ACIs), how to group users and set up authentication-related configuration.

Providing feedback on Red Hat Directory Server

We appreciate your input on our documentation and products. Please let us know how we could make it better. To do so:

  • For submitting feedback on the Red Hat Directory Server documentation through Jira (account required):

    1. Go to the Red Hat Issue Tracker.
    2. Enter a descriptive title in the Summary field.
    3. Enter your suggestion for improvement in the Description field. Include links to the relevant parts of the documentation.
    4. Click Create at the bottom of the dialogue.
  • For submitting feedback on the Red Hat Directory Server product through Jira (account required):

    1. Go to the Red Hat Issue Tracker.
    2. On the Create Issue page, click Next.
    3. Fill in the Summary field.
    4. Select the component in the Component field.
    5. Fill in the Description field including:

      1. The version number of the selected component.
      2. Steps to reproduce the problem or your suggestion for improvement.
    6. Click Create.

Chapter 1. Securing Red Hat Directory Server

Improve the security of your LDAP service with Red Hat Directory Server. For example, you can encrypt the connection between a client and the Directory Server and store encrypted attributes in the Directory Server database. You can also encrypt the replication changelog, configure authentication, and perform other security tasks.

By default, Red Hat Directory Server provides the LDAP service without encryption. To improve the security, you can configure TLS in Directory Server to enable your clients or other hosts in a replication environment to use encrypted connections. They can then use the STARTTLS command on port 389 or the LDAPS protocol on port 636 for secure connections.

You can use TLS with simple authentication using a bind Distinguished Name (DN) and password, or using certificate-based authentication.

Directory Server’s cryptographic services are provided by Mozilla network security services (NSS), a library of TLS and base cryptographic functions. NSS includes a software-based cryptographic token which is Federal Information Processing Standard (FIPS) 140-2 certified.

To connect to Directory Server with an encrypted connection, you can use the following protocols and framework:

LDAPS
When you use the LDAPS protocol, the connection starts using encryption and either succeeds or fails. However, no unencrypted data is ever sent over the network. For this reason, prefer LDAPS instead of using STARTTLS over unencrypted LDAP.
STARTTLS over LDAP

Clients establish an unencrypted connection over the LDAP protocol and then send the STARTTLS command. If the command succeeds, all further communication is encrypted.

Warning

If the STARTTLS command fails and the client does not cancel the connection, all further data, including authentication information, is sent unencrypted over the network.

SASL
The Simple Authentication and Security Layer (SASL) framework enables you to authenticate a user using external authentication methods, such as Kerberos.

Directory Server stores certificate signing requests (CSR), private keys, and certificates in a network security services (NSS) database. When you install a new instance, the installer automatically creates the NSS database and protects it with a random password. The installer stores this password in the following files:

  • /etc/dirsrv/slapd-<instance_name>/pwdfile.txt: The dsconf tls command uses this file to access the NSS database.
  • /etc/dirsrv/slapd-<instance_name>/pin.txt: This file contains the token and password to automatically unlock the NSS database when Directory Server starts.

    • If you want Directory Server to prompt for the NSS database password each time you start the instance, remove this file.
    • If you want the instance to start automatically without prompting for the password, keep this file and update it when you change the NSS database password.

If the /etc/dirsrv/slapd-<instance_name>/pin.txt file does not exist, you start Directory Server with encryption enabled and set a password on the NSS database, the the behavior is as follows:

  • If the systemctl or dsctl utilities start the ns-slapd Directory Server process, the systemd service prompts for the password and automatically passes the input to the systemd-tty-ask-password-agent utility:

    # dsctl <instance_name> start
    Enter PIN for Internal (Software) Token: (press TAB for no echo)
    Copy to Clipboard Toggle word wrap
  • In rare cases, when the ns-slapd Directory Server process is not started by the systemctl or dsctl utilities, and the process is detached from the terminal, ns-slapd sends a message to all terminals using the wall command:

    Broadcast message from root@server (Fri 2021-01-01 06:00:00 CET):
    
    Password entry required for 'Enter PIN for Internal (Software) Token:' (PID 1234).
    Please enter password with the systemd-tty-ask-password-agent tool!
    Copy to Clipboard Toggle word wrap

    To enter the password:

    # systemd-tty-ask-password-agent
    Enter PIN for Internal (Software) Token:
    Copy to Clipboard Toggle word wrap

To use TLS encryption or certificate-based authentication, you must manage the certificates in a network security services (NSS) database. When you created the instance, the dscreate utility automatically created this database in the /etc/dirsrv/slapd-<instance_name>/ directory and protected it with a strong password.

Procedure

  1. Create a private key and a certificate signing request (CSR). Skip this step if you want to create them using an external utility.

    • If your host is reachable only by one name, enter:

      # dsctl <instance_name> tls generate-server-cert-csr -s "CN=server.example.com,O=example_organization"
      Copy to Clipboard Toggle word wrap
    • If your host is reachable by multiple names:

      # dsctl <instance_name> tls generate-server-cert-csr -s "CN=server.example.com,O=example_organization" server.example.com server.example.net
      Copy to Clipboard Toggle word wrap

      If you specify the host names as the last parameter, the command adds the Subject Alternative Name (SAN) extension with the DNS:server.example.com, DNS:server.example.net entries to the CSR.

    The string specified in the -s subject parameter must be a valid subject name according to RFC 1485. The CN field in the subject is required, and you must set it to one of the fully-qualified domain names (FQDN) of the server. The command stores the CSR in the /etc/dirsrv/slapd-<instance_name>/Server-Cert.csr file.

  2. Submit the CSR to the certificate authority (CA) to get a certificate issued. For further details, see your CA’s documentation.
  3. Import the server certificate issued by the CA to the NSS database:

    • If you created the private key using the dsctl tls generate-server-cert-csr command, enter:

      # dsconf <instance_name> security certificate add --file /root/instance_name.crt --name "server-cert" --primary-cert
      Copy to Clipboard Toggle word wrap

      Remember the name of the certificate you set in the --name _certificate_nickname parameter. You require it in a later step.

    • If you created the private key using an external utility, import the server certificate and the private key:

      # dsctl <instance_name> tls import-server-key-cert /root/server.crt /root/server.key
      Copy to Clipboard Toggle word wrap

      Note that the command requires you to specify the path to the server certificate first and then the path to the private key. This method always sets the nickname of the certificate to Server-Cert.

  4. Import the CA certificate to the NSS database:

    # dsconf <instance_name> security ca-certificate add --file /root/ca.crt --name "Example CA"
    Copy to Clipboard Toggle word wrap
  5. Set the trust flags of the CA certificate:

    # dsconf <instance_name> security ca-certificate set-trust-flags "Example CA" --flags "CT,,"
    Copy to Clipboard Toggle word wrap

    This configures Directory Server to trust the CA for TLS encryption and certificate-based authentication.

  6. Enable TLS and set the LDAPS port:

    # dsconf <instance_name> config replace nsslapd-securePort=636 nsslapd-security=on
    Copy to Clipboard Toggle word wrap
  7. Open the LDAPS port in the firewalld service:

    # firewall-cmd --permanent --add-port=636/tcp
    # firewall-cmd --reload
    Copy to Clipboard Toggle word wrap
  8. Enable the RSA cipher family, set the NSS database security device, and the server certificate name:

    # dsconf <instance_name> security rsa set --tls-allow-rsa-certificates on --nss-token "internal (software)" --nss-cert-name Server-Cert
    Copy to Clipboard Toggle word wrap

    By default, the name of the security device in the NSS database is internal (software).

  9. Optional: Disable the plain text LDAP port:

    # dsconf <instance_name> security disable_plain_port
    Copy to Clipboard Toggle word wrap
  10. Restart the instance

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap

Verification

  • Establish a connection to Directory Server using the LDAPS protocol. For example, run a query:

    # ldapsearch -H ldaps://server.example.com:636 -D "cn=Directory Manager" -W -b "dc=example,dc=com" -x -s base
    Copy to Clipboard Toggle word wrap

    If the command fails, with an ldap_sasl_bind(SIMPLE): Can’t contact LDAP server (-1) error, re-run the command with debug level 1:

    # ldapsearch -H ldaps://server.example.com:636 -D "cn=Directory Manager" -W -b "dc=example,dc=com" -x -s base -d 1
    Copy to Clipboard Toggle word wrap

You can configure TLS encryption using the web console.

Prerequisites

  • You are logged in to the instance in the web console.

Procedure

  1. Navigate to ServerSecurityCertificate ManagementCertificate Signing Request, and click Create Certificate Signing Request.
  2. Set a name for certificate signing request (CSR), common name (CN), and organization (O):

    If your host is reachable by multiple names, set the alternative names in the Subject Alternative Names filed.

  3. Click Create Certificate Signing Request.
  4. View the CSR text and copy it:

    1. Click Node options icon for the CSR you want to view and select View CSR.
    2. Copy the CSR content.
  5. Submit the CSR file to the certificate authority (CA) to get a certificate issued. For further details, see your CA’s documentation.
  6. When you get the certificate from your CA, navigate to ServerSecurityCertificate ManagementTLS Certificates, and click Add Server Certificate.
  7. Set a unique nickname for the server certificate, upload the issued certificate, and click Add Certificate.

    Remember the certificate nickname, because a later step requires it.

  8. Navigate to ServerSecurityCertificate ManagementTrusted Certificate Authorities, and click Add CA Certificate.
  9. Set a unique nickname for the CA certificate, upload the CA certificate file, and click Add Certificate.
  10. Optional: If you did not enable TLS encryption during the Directory Server instance installation, enable it:

    1. Navigate to ServerSecurity Settings, and enable the security switch.
    2. On the pop-up window, click Enable Security.
    3. Click Save Configuration on the Security Setting page.
  11. Configure the Server Certificate Name on the Security Configuration page:

    1. Navigate to ServerSecuritySecurity Configuration.
    2. Select the server certificate nickname in the Server Certificate Name drop-down list, and click Save Configuration.
    3. Optional: If you do not see the certificate nickname in the drop-down list, refresh the Security Settings page and perform the previous step again.
  12. Optional: If you want to use an LDAPS port other than 636, navigate to the ServerServer Settings, set the LDAPS port, and click Save.
  13. Open the LDAPS port in the firewalld service:

    # firewall-cmd --permanent --add-port=636/tcp
    # firewall-cmd --reload
    Copy to Clipboard Toggle word wrap
  14. Optional: Navigate to ServerSecuritySecurity Configuration, check Require Secure Connections checkbox, and click Save Configuration.

    Directory Server disables the plain text LDAP port.

  15. Click Actions in the top right corner, and select Restart Instance.

By default, if encryption is enabled and the certificate has expired, Directory Server logs a warning and the service starts. To change this behavior, set the nsslapd-validate-cert parameter. You can set it to the following values:

  • warn: Directory Server starts and logs a warning about the expired certificate into the /var/log/dirsrv/slapd-<instance_name>/error log file. This is the default setting.
  • on: Directory Server validates the certificate. If the certificate has expired, the instance fails to start.
  • off: Directory Server does not validate the certificate expiration date. The instance starts and no warning will be logged.

Prerequisites

  • You configured TLS encryption.

Procedure

  • Use the following command to change the nsslapd-validate-cert parameter:

    # dsconf <instance_name> config replace nsslapd-validate-cert=<value>
    Copy to Clipboard Toggle word wrap

1.1.6. Changing the password of the NSS database

You can change the password of the network security services (NSS) database. For example, change it when the password becomes known to unauthorized persons.

Prerequisites

  • You know the current NSS database password.

    If you use a password file to automatically unlock the database when Directory Server starts, the password is stored non-encrypted in plain text in the /etc/dirsrv/slapd-<instance_name>/pin.txt file.

Procedure

  1. Use the following command to change the NSS database password:

    # certutil -d /etc/dirsrv/slapd-<instance_name>/ -W
    
    Enter Password or Pin for "NSS Certificate DB":
    Enter a password which will be used to encrypt your keys.
    The password should be at least 8 characters long,
    and should contain at least one non-alphabetic character.
    
    Enter new password:
    Re-enter password:
    Password changed successfully.
    Copy to Clipboard Toggle word wrap
  2. If you use a password file to start Directory Server automatically without prompting for the NSS database password, replace the old password with the new one in the /etc/dirsrv/slapd-<instance_name>/pin.txt:

    • If you use the NSS software cryptography module, which is the default:

      Internal (Software) Token:password
      Copy to Clipboard Toggle word wrap
    • If you use a Hardware Security Module (HSM):

      name_of_the_token:password
      Copy to Clipboard Toggle word wrap

Verification

  • Perform an operation on the NSS database that requires entering the password. For example, list the private keys of your instance:

    # certutil -d /etc/dirsrv/slapd-<instance_name>/ -K
    certutil: Checking token "NSS Certificate DB" in slot "NSS User Private Key and Certificate Services"
    Enter Password or Pin for "NSS Certificate DB":
    < 0> rsa      72cb03f87381abfbb6b9e78234e2e4502ad1bfc0   NSS Certificate DB:Server-Cert
    Copy to Clipboard Toggle word wrap

    If the command displays the expected output after you entered the new password, changing the password was successful.

When you create a new instance, the installer automatically creates the /etc/dirsrv/slapd-instance_name/pin.txt file to enable Directory Server to start without prompting for the network security services (NSS) password. However, if you remove this file, you can recreate it.

Warning

The password is stored in plain text. Do not use a password file if the server is running in an unsecured environment.

Prerequisites

  • You know the NSS database password.

Procedure

  1. Create the /etc/dirsrv/slapd-<instance_name>/pin.txt file with the following content:

    • If you use the NSS software cryptography module, which is the default:

      Internal (Software) Token:password
      Copy to Clipboard Toggle word wrap
    • If you use a Hardware Security Module (HSM):

      name_of_the_token:password
      Copy to Clipboard Toggle word wrap
  2. Set the file permissions:

    # chown dirsrv:root /etc/dirsrv/slapd-<instance_name>/pin.txt
    # chmod 400 /etc/dirsrv/slapd-<instance_name>/pin.txt
    Copy to Clipboard Toggle word wrap

Verification

  • Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap

    If the system does not prompt for the NSS database password, Directory Server uses the password file.

When you enable TLS encryption in Directory Server, you configure the instance to use a certificate issued by a CA. If a client now establishes a connection to the server using the LDAPS protocol or the STARTTLS command over LDAP, Directory Server uses this certificate to encrypt the connection. Client utilities use the CA certificate to verify if the server’s certificate is valid. By default, these utilities cancel the connection if they do not trust the certificate of the server.

Example 1.1. Possible connection errors if client utilities do not use the CA certificate

  • dsconf

    # dsconf -D "cn=Directory Manager" ldaps://server.example.com:636 config get
    Error: {'desc': "Can't contact LDAP server", 'info': 'error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed (self signed certificate in certificate chain)'}
    Copy to Clipboard Toggle word wrap
  • ldapsearch

    # ldapsearch -H ldaps://server.example.com:636 -D "cn=Directory Manager" -W -b "dc=example,dc=com" -x
    Enter LDAP Password:
    ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
    Copy to Clipboard Toggle word wrap

To enable client utilities on Red Hat Enterprise Linux to verify the certificate Directory Server uses, add the CA certificate to the trust store of the operating system.

Prerequisites

  • You know the password of the network security services (NSS) database.

    If you still use the password that was generated during the installation of the Directory Server instance, you find this password in plain text in the /etc/dirsrv/slapd-<instance_name>/pwdfile.txt file.

Procedure

  1. If you do not have a local copy of the CA certificate used by Directory Server:

    1. List the certificates in the server’s network security services (NSS) database:

      # certutil -d /etc/dirsrv/slapd-<instance_name>/ -L
      
      Certificate Nickname                       Trust Attributes
                                                 SSL,S/MIME,JAR/XPI
      
      Example CA                                 C,,
      Server-Cert                                u,u,u
      Copy to Clipboard Toggle word wrap
    2. Use the nickname of the CA certificate in the NSS database to export the CA certificate:

      # certutil -d /etc/dirsrv/slapd-<instance_name>/ -L -n "Example CA" -a > /tmp/ds-ca.crt
      Copy to Clipboard Toggle word wrap
  2. Copy the CA certificate to the /etc/pki/ca-trust/source/anchors/ directory:

    # cp /tmp/ds-ca.crt /etc/pki/ca-trust/source/anchors/
    Copy to Clipboard Toggle word wrap
  3. Rebuild the CA trust database:

    # update-ca-trust
    Copy to Clipboard Toggle word wrap

Verification

  • Establish a connection to Directory Server using the LDAPS protocol. For example, run a query:

    # ldapsearch -H ldaps://server.example.com:636 -D "cn=Directory Manager" -W -b "dc=example,dc=com" -x -s base
    Copy to Clipboard Toggle word wrap

In Red Hat Enterprise Linux 9, all system-wide crypto policy profiles define TLS 1.2 as the minimum. Therefore, this TLS version is also the minimum in Directory Server. However, if you only have clients which support a newer TLS version, you can set a higher protocol version as minimum to increase the security.

You can set both the minimum and maximum TLS protocol using the command line.

Warning

Do not set a maximum TLS protocol. If you do so, your clients might have to use a weaker TLS protocol than their default standard. If you do not set a maximum TLS version, Directory Server always uses the strongest version that is supported.

Prerequisites

  • You enabled TLS encryption in Directory Server.

Procedure

  1. Optional: Display the TLS protocols that are currently enabled in Directory Server:

    # dsconf <instance_name> security get | egrep -i "sslVersionMin|sslVersionMax"
    sslversionmin: TLS1.2
    sslversionmax: TLS1.3
    Copy to Clipboard Toggle word wrap
  2. Set the minimum TLS protocol. For example, to set it to TLS 1.3, enter:

    # dsconf <instance_name> security set --tls-protocol-min="TLS1.3"
    Copy to Clipboard Toggle word wrap

    Note that you cannot set the parameter to a value lower than TLS 1.2, which is the minimum of all RHEL system-wide crypto policy profiles.

  3. Not recommended: Set the highest supported TLS protocol:

    # dsconf <instance_name> security set --tls-protocol-max="TLS1.3"
    Copy to Clipboard Toggle word wrap

    If you set --tls-protocol-max to a value lower than in --tls-protocol-min, then Directory Server sets the maximum protocol to the same value as the minimum.

    To always use the strongest supported encryption protocol as the maximum supported TLS version, do not set --tls-protocol-max.

  4. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap

Verification

  1. Display the supported TLS protocols:

    # dsconf <instance_name> security get | egrep -i "sslVersionMin|sslVersionMax"
    sslversionmin: TLS1.3
    sslversionmax: TLS1.3
    Copy to Clipboard Toggle word wrap
  2. Use the openssl utility to establish a secure client connection using a specific TLS protocol:

    # echo | openssl s_client -connect server.example.com:636 -tls1_3
    ...
    New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
    ...
    Copy to Clipboard Toggle word wrap

You can set both the minimum and maximum TLS protocol using the web console

Warning

Do not set a maximum TLS protocol. If you do so, your clients might have to use a weaker TLS protocol than their default standard. If you do not set a maximum TLS version, Directory Server always uses the strongest version that is supported.

Prerequisites

  • You enabled TLS encryption in Directory Server.
  • You are logged in to the Directory Server instance in the web console.

Procedure

  1. Navigate to ServerSecurity.
  2. Set the minimum TLS protocol in the Minimum TLS Version field.
  3. Not recommended: Set the highest supported TLS protocol in the Maximum TLS Version field.
  4. Click Save Settings.
  5. Click Actions in the top right corner, and select Restart Instance.

Verification

  • Use the openssl utility to establish a secure client connection using a specific TLS protocol:

    # echo | openssl s_client -connect server.example.com:636 -tls1_3
    ...
    New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
    ...
    Copy to Clipboard Toggle word wrap

To prevent sending unencrypted passwords over the network, you can configure Directory Server to require users to use LDAPS or STARTTLS encryption when connecting to the server.

By default, Directory Server allows authentication using a bind DN and a password over unencrypted connections, which is a security risk. Suppose you cannot use an alternative secure mechanism, such as certificate-based authentication or SASL. In that case, you can configure Directory Server to require an encrypted connection when authenticating to the server using TLS or STARTTLS.

Note

Requiring a secure connection for bind operations only applies to authenticated binds. Bind operations without a password, such as anonymous and unauthenticated binds, can proceed over standard connections.

Prerequisites

  • You configured existing server-to-server connections, such as replication agreements, to use secure binds.

Procedure

  1. Set the nsslapd-require-secure-binds configuration parameter to on:

    # dsconf <instance_name> config replace nsslapd-require-secure-binds=on
    Copy to Clipboard Toggle word wrap
  2. Optional: If you want to use LDAPS, disable the plain text LDAP port:

    # dsconf <instance_name> security disable_plain_port
    
    Disabling plaintext ldap port - you must have ldaps configured:
    Type 'Yes I am sure' to continue: Yes I am sure
    Copy to Clipboard Toggle word wrap
  3. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap
Important

When you enable this feature, it is required for all connections. For example, this includes replication agreements, synchronization, and database chaining.

By default, Directory Server allows authentication using a bind DN and a password over unencrypted connections, which is a security risk. Suppose you cannot use an alternative secure mechanism, such as certificate-based authentication or SASL. In that case, you can configure Directory Server to require an encrypted connection when authenticating to the server using TLS or STARTTLS.

Note

Requiring a secure connection for bind operations only applies to authenticated binds. Bind operations without a password, such as anonymous and unauthenticated binds, can proceed over standard connections.

Prerequisites

  • You configured existing server-to-server connections, such as replication agreements, to use secure binds.
  • You are logged in to the instance in the web console.

Procedure

  1. Navigate to ServerSecuritySecurity Configuration, select the Require Secure Connections option, and click Save Configuration.
  2. Optional: If you want to use LDAPS, navigate to ServerServer SettingsGeneral Settings, and set LDAP Port to 0 to disable the plain text LDAP port. Click Save.
  3. Click Actions in the top right corner, and select Restart Instance.
Important

When you enable this feature, it is required for all connections. For example, this includes replication agreements, synchronization, and database chaining.

To establish an encrypted connection, both Directory Server and the client need at least one common cipher. For example, if a legacy application requires a cipher that is not enabled by default in Directory Server, you can enable it.

Instead of listing individual ciphers in the configuration, you can use one of the following keywords in the nsSSL3Ciphers parameter:

  • default: Refers to the default ciphers enabled in the network security services (NSS). To display the list, enter:

    # /usr/lib64/nss/unsupported-tools/listsuites | grep -B1 --no-group-separator "Enabled"
    Copy to Clipboard Toggle word wrap

    The default keyword is the default value of the nsSSL3Ciphers parameter.

  • all: Refers to all supported ciphers in Directory Server. To display the list, enter:

    # dsconf <instance_name> security ciphers list --supported
    Copy to Clipboard Toggle word wrap

    Use the all keyword when you want to enable only specific ciphers. For example, setting nsSSL3Ciphers to -all,+TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 configures Directory Server to disable all ciphers and enable only TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384.

1.4.2. Weak ciphers

By default, Directory Server rejects weak ciphers and you must configure Directory Server to support them.

Ciphers are considered weak, if:

  • They are exportable.

    Exportable ciphers are labeled EXPORT in the cipher name. For example, in TLS_RSA_EXPORT_WITH_RC4_40_MD5.

  • They are symmetrical and weaker than the 3DES algorithm.

    Symmetrical ciphers use the same cryptographic keys for both encryption and decryption.

  • The key length is shorter than 128 bits.

To update the list of supported ciphers in Directory Server, update the nsSSL3Ciphers parameter.

Prerequisites

  • You enabled TLS encryption in Directory Server.

Procedure

  1. Display the list of enabled ciphers:

    # dsconf <instance_name> security ciphers list --enabled
    Copy to Clipboard Toggle word wrap
  2. If you need to enable weak ciphers, enter:

    # dsconf <instance_name> security set --allow-insecure-ciphers on
    Copy to Clipboard Toggle word wrap
  3. Update the nsSSL3Ciphers parameter. For example, to enable only the TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 and TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ciphers, enter:

    # dsconf <instance_name> security ciphers set -- "-all,+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,+TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
    Copy to Clipboard Toggle word wrap

    Use -- to avoid that the shell interprets the - character in -all as an option to the command. Do not use a \ character to escape -all because it can create an error and this results in a different cipher selection.

  4. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap

Verification

  • Display the list of enabled ciphers:

    # dsconf <instance_name> security ciphers list
    default
    +TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
    +TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    Copy to Clipboard Toggle word wrap

You can configure the cipher settings in the Cipher Preferences menu of the Directory Server web console.

Prerequisites

  • You enabled TLS encryption in Directory Server.
  • You are logged in to the instance in the web console.

Procedure

  1. If you need to enable weak ciphers:

    1. Navigate to ServerSecuritySecurity Configuration.
    2. Select Allow Weak Ciphers.
    3. Click Save Settings.
  2. Navigate to ServerSecurityCipher Preferences.
  3. Update the cipher settings. For example, to enable only the TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 and TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ciphers:

    1. Select No Ciphers in the Cipher Suite field.
    2. Enter TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 in the Allow Specific Ciphers field.
  4. Click Save Settings.
  5. Click ActionsRestart Instance.

Verification

  • Navigate to ServerSecurityCipher Preferences. The Enabled Ciphers list displays the ciphers that are enabled.

1.5. Changing the CA trust flags

The certificate authority (CA) trust flags define for which scenarios Directory Server trusts a CA certificate. For example, you set the flags to trust the certificate for TLS connections to the server and for certificate-based authentication.

You can set the following trust flags on a certificate authority (CA) certificate:

  • C: Trusted CA
  • T: Trusted CA client authentication
  • c: Valid CA
  • P: Trusted peer
  • p: Valid peer
  • u: Private key

You specify the trust flags comma-separated in three categories: TLS, email, object signing

For example, to trust the CA for TLS encryption and certificate-based authentication, set the trust flags to CT,,.

Prerequisites

  • You imported a CA certificate to the network security services (NSS) database.

Procedure

  1. Use the following command to change the trust flags of a CA certificate:

    # dsconf <instance_name> security ca-certificate set-trust-flags "Example CA" --flags "trust_flags"
    Copy to Clipboard Toggle word wrap

Verification

  • Display all certificates in the NSS database:

    # certutil -d /etc/dirsrv/slapd-<instance_name>/ -L
    
    Certificate Nickname                                         Trust Attributes
                                                                 SSL,S/MIME,JAR/XPI
    
    Example CA                                                   CT,,
    Copy to Clipboard Toggle word wrap

You can use the web console to change the CA trust flags.

Prerequisites

  • You imported a CA certificate to the network security services (NSS) database.

Procedure

  1. Navigate to ServerSecurityCertificate ManagementTrusted Certificate Authorities.
  2. Click the Options menu (⋮) next to the CA certificate, and select Edit Trust Flags.
  3. Select the trust flags.

  4. Click Save Flags

Verification

  1. Navigate to ServerSecurityCertificate ManagementTrusted Certificate Authorities.
  2. Click > next to the CA certificate to display the trust flags.

1.6. Renewing a TLS certificate

TLS certificates have an expiration date and time. To continuously provide secure connections, renew the server certificate in Directory Server before it expires.

TLS certificates have an expiration date and time. To continuously provide secure connections, renew the server certificate in Directory Server before it expires.

Follow this procedure before the TLS server certificate expires to renew it.

Prerequisites

  • Attribute encryption is not configured.
  • The TLS certificate will expire in the near future.

Procedure

  1. Create a private key and a certificate signing request (CSR). Skip this step if you want to create them using an external utility.

    • If your host is reachable only by one name, enter:

      # dsctl <instance_name> tls generate-server-cert-csr -s "CN=server.example.com,O=example_organization"
      Copy to Clipboard Toggle word wrap
    • If your host is reachable by multiple names:

      # dsctl <instance_name> tls generate-server-cert-csr -s "CN=server.example.com,O=example_organization" server.example.com server.example.net
      Copy to Clipboard Toggle word wrap

      If you specify the host names as the last parameter, the command adds the Subject Alternative Name (SAN) extension with the DNS:server.example.com, DNS:server.example.net entries to the CSR.

    The string specified in the -s subject parameter must be a valid subject name according to RFC 1485. The CN field in the subject is required, and you must set it to one of the fully-qualified domain names (FQDN) of the server. The command stores the CSR in the /etc/dirsrv/slapd-<instance_name>/Server-Cert.csr file.

  2. Submit the CSR to the certificate authority (CA) to get a certificate issued. For further details, see your CA’s documentation.
  3. Store both the CA certificate and the server certificate in the /root/ directory.
  4. Import the server certificate issued by the CA to the NSS database, using one of the following options:

    • If you created the private key using the dsctl tls generate-server-cert-csr command, enter:

      # dsconf -D "cn=Directory Manager" ldap://server.example.com security certificate add --file /root/instance_name.crt --name "server-cert" --primary-cert
      Copy to Clipboard Toggle word wrap

      Remember the name of the certificate you set in the --name _certificate_nickname parameter. You require it in a later step.

    • If you created the private key using an external utility, import the server certificate and the private key:

      # dsctl <instance_name> tls import-server-key-cert /root/server.crt /root/server.key
      Copy to Clipboard Toggle word wrap

      Note that the command requires you to specify the path to the server certificate first and then the path to the private key. This method always sets the nickname of the certificate to Server-Cert.

  5. Import the CA certificate to the NSS database:

    # dsconf -D "cn=Directory Manager" ldap://server.example.com security ca-certificate add --file /root/ca.crt --name "Example CA"
    Copy to Clipboard Toggle word wrap
  6. Set the trust flags of the CA certificate:

    # dsconf -D "cn=Directory Manager" ldap://server.example.com security ca-certificate set-trust-flags "Example CA" --flags "CT,,"
    Copy to Clipboard Toggle word wrap

    This configures Directory Server to trust the CA for TLS encryption and certificate-based authentication.

  7. Stop the instance:

    # dsctl <instance_name> stop
    Copy to Clipboard Toggle word wrap
  8. Edit the /etc/dirsrv/slapd-<instance_name>/dse.ldif file, and remove the following entries including their attributes:

    • cn=AES,cn=encrypted attribute keys,cn=database_name,cn=ldbm database,cn=plugins,cn=config
    • cn=3DES,cn=encrypted attribute keys,cn=database_name,cn=ldbm database,cn=plugins,cn=config
    Important

    Remove the entries for all databases. If any entry that contains the nsSymmetricKey attribute is left in the /etc/dirsrv/slapd-<instance_name>/dse.ldif file, Directory Server will fail to start.

  9. Start the instance:

    # dsctl <instance_name> start
    Copy to Clipboard Toggle word wrap

1.7. Configuring certificate-based authentication

Directory Server supports certificate-based authentication of LDAP clients and server-to-server connections, such as in replication topologies.

Depending on the configuration, clients can or must authenticate using a certificate. After verifying the certificate, based on the attributes in the subject field of the certificate, the server searches for the user in the directory. If the search return exactly one user entry, Directory Server uses this user for all further operations. Optionally, you can configure that the certificate used for authentication must match the Distinguished Encoding Rules (DER)-formatted certificate stored in the userCertificate attribute of the user entry.

Benefits of using certificate-based authentication:

  • Improved efficiency: Authenticating with the certificate database password and then using that certificate for all subsequent bind or authentication operations is more efficient than repeatedly providing a bind distinguished name (DN) and password.
  • Improved security: The use of certificate-based authentication is more secure than non-certificate bind operations because certificate-based authentication uses public-key cryptography. Attackers cannot intercept bind credentials across the network. If the certificate or device is lost, it is useless without the PIN, so it is immune to third-party interference such as phishing attacks.

1.7.1. Setting up certificate-based authentication

Prerequisites

  • You enabled TLS encryption in Directory Server.
  • You set the CT flags for the certificate authority (CA) certificate in the network security services (NSS) database.

Procedure

  1. Create a /etc/dirsrv/slapd-<instance_name>/certmap.conf file to map information from the certificate to Directory Server users:

    certmap default         default
    default:DNComps         dc
    default:FilterComps     mail,cn
    default:VerifyCert      on
    
    certmap example         cn=Example CA
    example:DNComps
    Copy to Clipboard Toggle word wrap

    With this configuration, for certificates issued by cn=Example CA, Directory Server does not generate a base DN from the subject of the certificate because the DNComps parameter is set empty for this issuer. Additionally, the settings for the FilterComps and VerifyCert are inherited from the default entry.

    Certificates that have a different issuer DN than cn=Example CA will use the settings from the default entry and generate the base DN based on the cn attributes in the subject of the certificate. This enables Directory Server to start the search under a specific DN, without searching the whole directory.

    For all certificates, Directory Server generates the search filter using the mail and the cn attribute from the certificate’s subject. However, if the mail attribute does not exist in the subject, Directory Server will automatically use the value of the certificate’s e attribute in the subject.

  2. Enable certificate-based authentication. For example, to configure certificate-based authentication as optional, enter:

    # dsconf <instance_name> security set --tls-client-auth="allowed"
    Copy to Clipboard Toggle word wrap

    Use the --tls-client-auth=required option to configure certificate-based authentication as mandatory.

  3. Optional: If you configured certificate-based authentication as required, enable the nsslapd-require-secure-binds parameter:

    # dsconf <instance_name> config replace nsslapd-require-secure-binds=on
    Copy to Clipboard Toggle word wrap

    This setting ensures that users cannot bypass the certificate-based authentication by using an unencrypted connection.

  4. Optional: If Directory Server should use the identity from the certificate instead of the credentials in the bind request, configure Directory Server to use the EXTERNAL simple authentication and security layer (SASL) mechanism:

    # dsconf <instance_name> config replace nsslapd-force-sasl-external=on
    Copy to Clipboard Toggle word wrap

    With this setting, Directory Server ignores any other bind method than the identity in the certificate.

  5. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap

Next steps:

  • If you have configured Directory Server so that the authenticating certificate must match the one stored in the userCertificate attribute of the user, add the certificates to the user entries.

    For details, see Section 1.7.2, “Adding a certificate to a user”

1.7.2. Adding a certificate to a user

When you set up certificate-based authentication, you can configure the server so that the certificate used to authenticate must match the one stored in the userCertificate binary attribute of the user. If you enabled this feature, you must add the certificate of the affected users to their directory entry.

Prerequisites

  • You enabled certificate-based authentication in Directory Server.
  • You have a client certificate issued by a certificate authority (CA) that is trusted by the server.
  • The client certificate is in distinguished encoding rules (DER)-formatted.
  • The client certificate meets the requirements set in /etc/dirsrv/slapd-<instance_name>/certmap.conf on the server.

Procedure

  1. If the certificate is not in DER format, convert it. For example, to convert a certificate from privacy enhanced mail (PEM) to DER, enter:

    # openssl x509 -in /home/user_name/certificate.pem -out /home/user_name/certificate.der -outform DER
    Copy to Clipboard Toggle word wrap
  2. Add the certificate to the user’s userCertificate attribute:

    # ldapmodify -D "cn=Directory Manager" -W -H ldaps://server.example.com -x
    
    dn: uid=user_name,ou=People,dc=example,dc=com
    changetype: modify
    add: userCertificate
    userCertificate:< file:///home/user_name/example.der
    Copy to Clipboard Toggle word wrap

Verification

  1. Authenticate as the user using certificate-based authentication:

    1. Set the following environment variables to the corresponding paths to the CA certificate, the user key, and the user certificate:

      LDAPTLS_CACERT=/home/user_name/CA.crt
      LDAPTLS_KEY=/home/user_name/user.key
      LDAPTLS_CERT=/home/user_name/user.der
      Copy to Clipboard Toggle word wrap

      Alternatively, set the TLS_CACERT, TLS_KEY, and TLS_CERT parameters in the ~/.ldaprc file of the current user.

    2. Connect to the server:

      # ldapwhoami -H ldaps://server.example.com -Y EXTERNAL
      dn: uid=example,ou=people,dc=example,dc=com
      Copy to Clipboard Toggle word wrap

For more details, see Configuring multi-supplier replication with certificate-based authentication in the Configuring and managing replication documentation.

1.9. Encrypting the replication changelog

For details, how to encrypt the replication changelog, see Encrypting the replication changelog in the Configuring amd managing replication documentation.

1.12. Enabling the FIPS mode

Directory Server fully supports the Federal Information Processing Standard (FIPS) 140-2. When you run Directory Server run in FIPS mode, security-related settings change. For example, SSL is automatically disabled and only TLS 1.2 and 1.3 encryption is used.

To use Directory Server in Federal Information Processing Standard (FIPS) mode, enable the mode in RHEL and Directory Server.

Prerequisites

  • You enabled the FIPS mode in RHEL.

Procedure

  1. Enable the FIPS mode for the network security services (NSS) database:

    # modutil -dbdir /etc/dirsrv/slapd-<instance_name>/ -fips true
    Copy to Clipboard Toggle word wrap
  2. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap

Verification

  • Verify that FIPS mode is enabled for the NSS database:

    # modutil -dbdir /etc/dirsrv/slapd-<instance_name>/ -chkfips true
    FIPS mode enabled.
    Copy to Clipboard Toggle word wrap

    The command returns FIPS mode enabled, if the module is in FIPS mode.

Having an unconstrained administrative user makes sense from a maintenance perspective. The Directory Manager requires a high level of access in order to perform maintenance tasks and to respond to incidents.

However, because of the power of the Directory Manager user, a certain level of access control can be advisable to prevent damages from attacks being performed as the administrative user.

Directory Server applies regular access control instructions only to the directory tree. The privileges of the Directory Manager account are hard-coded, and you cannot use this account in bind rules. To limit access to the Directory Manager account, use the RootDN Access Control plug-in.

This plug-in’s features are different from standard access control instructions (ACI). For example, certain information, such as the target (the Directory Manager entry) and the allowed permissions (all of them) is implied. The purpose of the RootDN Access Control plug-in is to provide a level of security by limiting who can log in as Directory Manager based on their location or time, not to restrict what this user can do.

For this reason, the settings of the plug-in only support:

  • Time-based access controls, to allow or deny access on certain days and specific time ranges
  • IP address rules, to allow or deny access from defined IP addresses, subnets, and domains
  • Host access rules, to allow or deny access from specific hosts, domains, and subdomains

There is only one access control rule you can set for the Directory Manager. It is in the plug-in entry, and it applies to the entire directory.

Same as in regular ACIs, deny rules have a higher priority than allow rules.

Important

Ensure that the Directory Manager account has an appropriate level of access. This administrative user might need to perform maintenance operations in off-hours or to respond to failures. In this case, setting a too restrictive time or day rule can prevent the Directory Manager user from adequately manage the directory.

By default, the RootDN Access Control plug-in is disabled. To limit permissions of the Directory Manager account, enable and configure the plug-in.

Procedure

  1. Enable the RootDN Access Control plug-in:

    # dsconf <instance_name> plugin root-dn enable
    Copy to Clipboard Toggle word wrap
  2. Set the bind rules. For example, to allow the Directory Manager account to only log in between 6am and 9pm from the host with IP address 192.0.2.1, enter:

    # dsconf <instance_name> plugin root-dn set --open-time=0600 --close-time=2100 --allow-ip="192.0.2.1"
    Copy to Clipboard Toggle word wrap

    For the full list of parameters you can set and their descriptions, enter:

    # dsconf <instance_name> plugin root-dn set --help
    Copy to Clipboard Toggle word wrap
  3. Restart the instance:

    # *dsctl <instance_name> restart`
    Copy to Clipboard Toggle word wrap

Verification

  • Perform a query as cn=Directory Manager from a host that is not allowed or outside of the allowed time range:

    [user@192.0.2.2]$ ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -x -b "dc=example,dc=com"
    Enter LDAP Password:
    ldap_bind: Server is unwilling to perform (53)
    	additional info: RootDN access control violation
    Copy to Clipboard Toggle word wrap

    If Directory Server denies access, the plug-in works as expected.

By default, the RootDN Access Control plug-in is disabled. To limit permissions of the Directory Manager account, enable and configure the plug-in.

Prerequisites

  • You are logged in to the instance in the web console.

Procedure

  1. Navigate to PluginsRootDN Access Control.
  2. Enable the plug-in.
  3. Fill the fields according to your requirements.

  4. Click Save.
  5. Click Actions in the top right corner, and select Restart Instance.

Verification

  • Perform a query as cn=Directory Manager from a host that is not allowed or outside of the allowed time range:

    [user@192.0.2.2]$ ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -x -b "dc=example,dc=com"
    Enter LDAP Password:
    ldap_bind: Server is unwilling to perform (53)
            additional info: RootDN access control violation
    Copy to Clipboard Toggle word wrap

    If Directory Server denies access, the plug-in works as expected.

1.14. Managing attribute encryption

Chapter 2. Managing access control

Learn how to define which user can perform specific actions on suffixes and entries in Red Hat Directory Server. These tasks are controlled by access control instructions (ACI). Learn about the different ACI types, ACI use cases, bind rules, and methods for checking access rights on entries.

2.1. Managing access control instructions

When Directory Server receives a request, it uses the authentication information provided by the user in the bind operation and the access control instructions (ACI) defined in the directory to allow or deny access to the requested entry or attribute. The server can allow or deny permissions for actions, such as read, write, search, and compare. The permission level granted to a user depends on the authentication information provided.

Access control in Directory Server enables you to set precise rules on when the ACIs are applicable:

  • For the entire directory, a subtree, or specific entries
  • For a specific user, all users belonging to a specific group or role, or all users in the directory
  • For a specific location, such as an IP address, an IP range, or a DNS name.

    Note that load balancers can affect location-specific rules.

Important

Complex ACIs are difficult to read and understand. Instead of one complex ACI, you can write multiple simple rules to achieve the same effect. However, a higher number of ACIs also increases the costs of ACI processing.

2.1.1. ACI placement

Directory Server stores access control instruction (ACI) in the multi-valued aci operational attribute in directory entries. To set an ACI, add the aci attribute to the corresponding directory entry. Directory Server applies the ACIs:

  • Only to the entry that contains the ACI, if it does not have any child entries. For example, if a client requires access to the uid=user_name,ou=People,dc=example,dc=com object, and an ACI is only set on dc=example,dc=com and not on any child entries, only this ACI is applied.

    Note

    ACIs with add permissions also apply to child entries created in future.

  • To the entry that contains the ACI and to all entries below it, if it has child entries. As a direct consequence, when the server evaluates access permissions to any given entry, it verifies the ACIs for every entry between the one requested and the directory suffix, as well as the ACIs on the entry itself.

    For example, ACIs are set on the dc=example,dc=com and the ou=People,dc=example,dc=com entry: If a client wants to access the uid=user_name,ou=People,dc=example,dc=com object, which has no ACI set, Directory Server first validates the ACI on the ou=People,dc=example,dc=com entry. If this ACI grants access, evaluation stops and grants access. If not, Directory Server verifies the ACI on ou=People,dc=example,dc=com. If this ACI successfully authorizes the client, it can access the object.

Note

ACIs set in the rootDSE entry apply only to this entry.

An ACI created on an entry can be set not to apply directly to that entry but rather to some or all of the entries in the subtree below. The advantage of this approach is that general ACIs can be placed higher in the directory tree to have effect on entries located lower in the tree. For example, an ACI that targets entries that include the inetOrgPerson object class can be created at the level of an organizationalUnit entry or a locality entry.

Note

Minimize the number of ACIs in the directory tree by placing general rules at high level branch points. To limit the scope of more specific rules, place them to leaf entries as closely as possible.

2.1.2. The structure of an ACI

The aci attribute uses the following syntax:

(target_rule) (version 3.0; acl "ACL_name"; permission_rule bind_rules;)
Copy to Clipboard Toggle word wrap
  • target_rule specifies the entry, attributes, or set of entries and attributes for which to control access.
  • version 3.0 is a required string which identifies the access control instructions (ACI) version.
  • acl "ACL name" sets a name or string that describes the ACI.
  • permission_rule sets what rights, such as read or write, are allowed or denied.
  • bind_rules specifies which rules must match during the bind to allow or deny access.

The permission and the bind rule pair are called an access control rule.

To efficiently set multiple access controls for a given target, you can set multiple access control rules for each target:

(target_rule)(version 3.0; acl "ACL_name"; permission_rule bind_rules; permission_rule bind_rules; ... ;)
Copy to Clipboard Toggle word wrap

2.1.3. ACI evaluation

To evaluate the access rights to a particular entry, the server creates a list of the access control instructions (ACI) present on the entry itself and on the parent entries back up to the top level entry stored in Directory Server. ACIs are evaluated across all databases for a particular instance but not across different instances.

Directory Server evaluates this list of ACIs based on the semantics of the ACIs, not on their placement in the directory tree. This means that ACIs that are close to the root of the directory tree do not take precedence over ACIs that are closer to the leaves of the directory tree.

In Directory Server, the deny permission in ACIs take precedence over the allow permission. For example, if you deny write permission at the directory’s root level, none of the users can write to the directory, regardless if an other ACI grants this permission. To grant a specific user write permissions to the directory, you have to add an exception to the original denying rule to allow the user to write in that directory.

Note

For improved ACIs, use fine-grained allow rules instead of deny rules.

2.1.4. Limitations of ACIs

When you set access control instructions (ACI), the following restrictions apply:

  • If your directory database is distributed over multiple servers, the following restrictions apply to the keywords you can use in ACIs:

    • ACIs depending on group entries using the groupdn keyword must be located on the same server as the group entry.

      If the group is dynamic, all members of the group must have an entry on the server. Member entries of static groups can be located on the remote server.

    • ACIs depending on role definitions using the roledn keyword, must be located on the same server as the role definition entry. Every entry that is intended to have the role must also be located on the same server.

    However, you can match values stored in the target entry with values stored in the entry of the bind user by, for example, using the userattr keyword. In this case, access is evaluated normally even if the bind user does not have an entry on the server that stores the ACI.

  • You cannot use virtual attributes, such as Class of Service (CoS) attributes, in the following ACI keywords:

    • targetfilter
    • targattrfilters
    • userattr
  • Access control rules are evaluated only on the local server. For example, if you specify the host name of a server in LDAP URLs in ACI keywords, the URL will be ignored.

Access control instructions (ACI) are stored in aci attributes of entries. Therefore, if an entry containing ACIs is part of a replicated database, the ACIs are replicated.

ACIs are always evaluated on the server that resolves the incoming LDAP requests. When a consumer server receives an update request, it returns a referral to the supplier server before evaluating whether the request can be serviced on the supplier.

You can use the ldapsearch utility to search, and the ldapmodify utility to add, delete, and update Access Control Instructions (ACI).

Displaying ACIs:

For example, to display the ACIs set on dc=example,dc=com and sub-entries, enter:

# ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -x -b "dc=example,dc=com" -s sub '(aci=&#42;)' aci
Copy to Clipboard Toggle word wrap

Adding an ACI

For example, to add an ACI to the ou=People,dc=example,dc=com entry, enter:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr="userPassword") (version 3.0; acl
  "Allow users updating their password";
  allow (write) userdn= "ldap:///self";)
Copy to Clipboard Toggle word wrap

Deleting an ACI

To delete an ACI:

  • If only one aci attribute is set on the entry or you want to remove all ACIs from the entry:

    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: ou=People,dc=example,dc=com
    changetype: delete
    delete: aci
    Copy to Clipboard Toggle word wrap
  • If multiple ACIs exist on the entry and you want to delete a specific ACI, specify the exact ACI:

    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: ou=People,dc=example,dc=com
    changetype: modify
    delete: aci
    aci: (targetattr="userPassword") (version 3.0; acl "Allow users
      updating their password"; allow (write) userdn= "ldap:///self";)
    Copy to Clipboard Toggle word wrap

Updating an ACI

To update an ACI:

  • Delete the existing ACI.
  • Add a new ACI with the updated settings.

2.1.7. Defining ACI targets

Target rules in an access control instruction (ACI) define to which entries Directory Server applies the ACI. If you do not set a target, the ACI applies to the entry containing the aci attribute and to entries below.

In an ACI, the following highlighted part is the target rule:

(target_rule)(version 3.0; acl "ACL_name"; permission_rule bind_rules;)
Copy to Clipboard Toggle word wrap

For complex ACIs, Directory Server supports multiple target rules with different keywords in an ACI:

(target_rule_1)(target_rule_2)(...)(version 3.0; acl "ACL_name"; permission_rule bind_rules;)
Copy to Clipboard Toggle word wrap

If you specify multiple target rules, the order is not relevant. Note that you can use each of the following keywords only once in an ACI:

  • target
  • targetattr
  • targetattrfilters
  • targetfilter
  • target_from
  • target_to
2.1.7.1. The syntax of target rules

The general syntax of a target rule is:

(keyword comparison_operator "expression")
Copy to Clipboard Toggle word wrap
  • keyword: Sets the type of the target.
  • comparison_operator: Valid values are = and != and indicate whether or not the target is the object specified in the expression.

    Warning

    For security reasons, Red Hat recommends not using the != operator, because it allows the specified operation on all other entries or attributes. For example:

    (targetattr != "userPassword");(version 3.0; acl "example"); allow (write) ... );
    Copy to Clipboard Toggle word wrap

    The previous example allows users to set, update, or delete any attribute except the userPassword attribute under the Distinguished Name (DN) you set the ACI. However, also this enables users, for example, to add an additional aci attribute that allows write access to this attribute as well.

  • expression: Sets the target and must be surrounded by quotation marks. The expression itself depends on the keyword you use.
2.1.7.2. Targeting a directory entry

To control access based on a Distinguished Name (DN) and the entries below it, use the target keyword in the access control instruction (ACI). A target rule which uses the target keyword takes a DN as expression:

(target comparison_operator "ldap:///distinguished_name")
Copy to Clipboard Toggle word wrap
Note

You must set the ACI with the target keyword on the DN you are targeting or a higher-level DN of it. For example, if you target ou=People,dc=example,dc=com, you must either set the ACI on ou=People,dc=example,dc=com or dc=example,dc=com.

Example 2.1. Using the target keyword

To enable users that are stored in the ou=People,dc=example,dc=com entry to search and display all attributes in their own entry:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (target = "ldap:///ou=People,dc=example,dc=com") (version 3.0;
 acl "Allow users to read and search attributes of own entry"; allow (search, read)
 (userdn = "ldap:///self");)
Copy to Clipboard Toggle word wrap

Using wildcards with the target keyword

You can use the * wildcard character target multiple entries.

The following target rule example matches all entries in ou=People,dc=example,dc=com whose uid attribute is set to a value that starts with the letter a:

(target = "ldap:///uid=a*,ou=People,dc=example,dc=com")
Copy to Clipboard Toggle word wrap

Depending on the position of the wildcard, the rule not only applies to attribute values, but also to the full DN. Therefore, you can use the wildcard as a substitute for portions of the DN.

Example 2.2. Targeting a directory entries using wildcards

The following rule targets all entries in the dc=example,dc=com tree with a matching uid attribute and not only entries which are stored in the dc=example,dc=com entry itself:

(target = "ldap:///uid=user_name*,dc=example,dc=com")
Copy to Clipboard Toggle word wrap

The previous target rule matches multiple entries, such as:

  • uid=user_name,dc=example,dc=com
  • uid=user_name,ou=People,dc=example,dc=com
  • uid=user_name2,dc=example,dc=com
Important

Directory Serverdoes not support wildcards in the suffix part of a DN. For example, if your directory’s suffix is dc=example,dc=com, you cannot use a target with a wildcard in this suffix, such as (target = "ldap:///dc=*.com").

2.1.7.3. Targeting attributes

To limit access in an access control instruction (ACI) to certain attributes, use the targetattr keyword. For example, this keyword defines:

  • In a read operation, what attributes will be returned to a client
  • In a search operation, what attributes will be searched
  • In a write operation, what attributes can be written to an object
  • In an add operation, what attributes can be added when creating a new object

In certain situations, you can use the targetattr keyword to secure ACIs by combining other target keywords with targetattr. See Advanced usage of target rules.

Important

In read and search operations, the default targets no attribute. An ACI without a targetattr keyword is only useful for ACIs with rights affecting a complete entry, such as add or delete.

To separate multiple attributes in a target rule that uses the targetattr keyword, use ||:

(targetattr comparison_operator "attribute_1 || attribute_2 || ...")
Copy to Clipboard Toggle word wrap

The attributes set in the expression must be defined in the schema.

The attributes specified in the expression apply to the entry on which you create the ACI and to all entries below it if not restricted by further target rules.

Example 2.3. Using the targetattr keyword

To enable users stored in dc=example,dc=com and all subentries to update the userPassword attribute in their own entry, enter:

# ldapmodify -D "cn=Directory Manager" -W -H ldap::server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "userPassword") (version 3.0;
 acl "Allow users updating own userPassword";
 allow (write) (userdn = "ldap:///self");)
Copy to Clipboard Toggle word wrap

Using wildcards with the targetattr keyword

Using the * wildcard character, you can, for example, target all attributes:

(targetattr = "*")
Copy to Clipboard Toggle word wrap
Warning

For security reasons, do not use wildcards with the targetattr, because it allows access to all attributes, including operational attributes. For example, if users can add or modify all attributes, users might create additional ACIs and increase their own permissions.

To target a group of entries that match a certain criteria, use the targetfilter keyword with an LDAP filter:

(targetfilter comparison_operator "LDAP_filter")
Copy to Clipboard Toggle word wrap

The filter expression is a standard LDAP search filter.

Example 2.4. Using the targetfilter keyword

To grant permissions to members of the cn=Human Resources,dc=example,dc.com group to modify all entries having the department attribute set to Engineering or Sales:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targetfilter = "(|(department=Engineering)(department=Sales)")
 (version 3.0; acl "Allow HR updating engineering and sales entries";
 allow (write) (groupdn = "ldap:///cn=Human Resources,dc=example,dc.com");)
Copy to Clipboard Toggle word wrap

The targetfilter keyword targets whole entries. If you combine it with the targetattr keyword, the access control instruction (ACI) applies only to a subset of attributes of the targeted entries. See Targeting certain attributes of entries matching a filter.

Note

Using LDAP filters is useful when targeting entries and attributes that are spread across the directory. However, the results are sometimes unpredictable because filters do not directly name the object for which you are managing access. The set of entries targeted by a filtered ACI is likely to change as attributes are added or deleted. Therefore, if you use LDAP filters in ACIs, verify that they target the correct entries and attributes by using the same filter, for example, in an ldapsearch operation.

Using wildcards with the targetfilter keyword

The targetfilter keyword supports wildcards similarly to standard LDAP filters. For example, to target all uid attributes whose value starts with adm, use:

(targetfilter = "(uid=adm*) ...)
Copy to Clipboard Toggle word wrap

You can use access control to target specific values of attributes. This means that you can grant or deny permissions on an attribute if that attribute’s value meets the criteria that is defined in the access control instruction (ACI). An ACI that grants or denies access based on an attribute’s value is called a value-based ACI. This applies only to ADD and DEL operations. You cannot limit search rights by specific values.

To create a value-based ACI, use the targattrfilters keyword with the following syntax:

  • For one operation with one attribute and filter combination:

    (targattrfilters="operation=attribute:filter")
    Copy to Clipboard Toggle word wrap
  • For one operation with multiple attribute and filter combinations:

    (targattrfilters="operation=attribute_1:filter_1 && attribute_2:filter_2 ... && attribute_m:filter_m")
    Copy to Clipboard Toggle word wrap
  • For two operations, each with multiple attribute and filter combinations:

    (targattrfilters="operation_1=attribute_1_1:filter_1_1 && attribute_1_2:filter_1_2 ... && attribute_1_m:filter_1_m , operation_2=attribute_2_1:filter_2_1 && attribute_2_2:filter_2_2 ... & attribute_2_n:filter_2_n ")
    Copy to Clipboard Toggle word wrap

In the previous syntax examples, you can set the operations either to add or del. The attribute:filter combination sets the filter and the attribute the filter is applied to.

The following describes how filter must match:

  • When creating an entry and a filter applies to an attribute in the new entry, then each instance of that attribute must match the filter.
  • When deleting an entry and a filter applies to an attribute in the entry, then each instance of that attribute must also match the filter.
  • When modifying an entry and the operation adds an attribute, then the add filter that applies to that attribute must match.
  • If the operation deletes an attribute, then the del filter that applies to that attribute must match. If the individual values of an attribute already present in the entry are replaced, then both the add and del filters must match.

Example 2.5. Using the targattrfilters keyword

To create an ACI that enables users to add any role to their own entry, except the Admin role, and to add the telephone attribute, as long as the value begins with the 123 prefix, enter:

# ldapmodify -D "cn=Directory Manager" -W -H ldap::server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targattrfilters="add=nsroledn:(!(nsroledn=cn=Admin)) &&
 telephoneNumber:(telephoneNumber=123*)") (version 3.0;
 acl "Allow adding roles and telephone";
 allow (add) (userdn = "ldap:///self");)
Copy to Clipboard Toggle word wrap
2.1.7.6. Targeting source and destination DNs

In certain situations, administrators want to allow users to move directory entries. Using the target_from and target_to keywords in an access control instruction (ACI), you can specify the source and destination of the operation, however, without enabling the user:

  • To move entries from a different source as set in the ACI.
  • To move entries to a different destination as set in the ACI.
  • To delete existing entries from the source Distinguished Name (DN).
  • To add new entries to the destination DN.

Example 2.6. Using the target_from and target_to keywords

To enable the uid=user,dc=example,dc=com account to move user accounts from the cn=staging,dc=example,dc=com entry to cn=people,dc=example,dc=com, enter:

# ldapmodify -D "cn=Directory Manager" -W -H ldap:server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (target_from="ldap:///uid=*,cn=staging,dc=example,dc=com")
 (target_to="ldap:///cn=People,dc=example,dc=com")
 (version 3.0; acl "MODDN from"; allow (moddn))
 userdn="ldap:///uid=user,dc=example,dc=com";)
Copy to Clipboard Toggle word wrap

ACIs apply only to the subtree where they are defined. In the previous example, the ACI is applied only to the dc=example,dc=com subtree.

If the target_from or target_to keyword is not set, the ACI matches any source or destination.

2.1.8. Advanced usage of target rules

By combining multiple keywords, you can create complex target rules. This section provides examples of the advanced usage of target rules.

In certain situations, administrators want to delegate permissions to other accounts or groups. By combining target keywords, you can create secure access control instructions (ACI) that solve this request.

Example 2.7. Delegating permissions to create and maintain groups

To enable the uid=user,ou=People,dc=example,dc=com" account to create and update groups in the ou=groups,dc=example,dc=com entry:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (target = "ldap:///cn=*,ou=Groups,dc=example,dc=com")
 (targattrfilters="add=objectclass:(|(objectclas=top)(objectclass=groupOfUniqueNames)))
 (targetattr="cn || uniqueMember || objectClass")
 (version 3.0; acl "example"; allow (read, search, write, add)
 (userdn = "ldap:///uid=test,ou=People,dc=example,dc=com");)
Copy to Clipboard Toggle word wrap

For security reasons, the previous example adds certain limitations. The uid=test,ou=People,dc=example,dc=com user:

  • Can create objects that must contain the top and groupOfUniqueNames object classes.
  • Cannot add additional object classes, such as account. For example, this prevents if you use Directory Server accounts for local authentication, to create new users with an invalid user ID, such as 0 for the root user.

The targetfilter rule ensures that the ACI entry applies only to entries with the groupofuniquenames object class and the targetattrfilter rule ensures that no other object class can be added.

2.1.8.2. Targeting both an entry and attributes

The target controls access based on a distinguished name (DN). However, if you use it in combination with a wildcard and the targetattr keyword, you can target both entries and attributes.

Example 2.8. Targeting both an entry and attributes

To enable the uid=user,ou=People,dc=example,dc.com user to read and search members of groups in all organizational units in the dc=example,dc=com subtree:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (target="ldap:///cn=*,dc=example,dc=com")(targetattr="member" || "cn") (version 3.0;
 acl "Allow uid=user to search and read members of groups";
 allow (read, search) (userdn = "ldap:///uid=user,ou=People,dc=example,dc.com");)
Copy to Clipboard Toggle word wrap

If you combine the targetattr and targetfilter keywords in two target rules, you can target certain attributes in entries that match a filter.

Example 2.9. Targeting certain attributes of entries matching a filter

To allow members of the cn=Engineering Admins,dc=example,dc=com group to modify the jpegPhoto and manager attributes of all entries having the department attribute set to Engineering, enter:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "jpegPhoto || manager")
 (targetfilter = "(department=Engineering)") (version 3.0;
 acl "Allow engineering admins updating jpegPhoto and manager of department members";
 allow (write) (groupdn = "ldap:///cn=Engineering Admins,dc=example,dc.com");)
Copy to Clipboard Toggle word wrap
2.1.8.4. Targeting a single directory entry

To target a single directory entry, combine the targetattr and targetfilter keywords.

Example 2.10. Targeting a single directory entry

To enable the uid=user,ou=People,dc=example,dc=com user to read and search the ou and cn attributes in the ou=Engineering,dc=example,dc=com entry:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=Engineering,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "ou || cn")
 (targetfilter = "(ou=Engineering)") (version 3.0;
 acl "Allow uid=user to search and read engineering attributes";
 allow (read, search) (userdn = "ldap:///uid=user,ou=People,dc=example,dc.com");)
Copy to Clipboard Toggle word wrap

To enable the previous example to target only the ou=Engineering,dc=example,dc=com entry, sub-entries in ou=Engineering,dc=example,dc=com must not have the ou attribute set to Engineering.

Important

These kinds of ACIs can fail if the structure of your directory changes.

Alternatively, you can create a bind rule that matches the user input in the bind request with an attribute value that is stored in the targeted entry. See Defining access based on value matching.

2.1.9. Defining ACI permissions

Permission rules define the rights that are associated with the access control instruction (ACI) and whether access is allowed or denied.

In an ACI, the following highlighted part is the permission rule:

(target_rule) (version 3.0; acl "ACL_name"; permission_rule bind_rules;)
Copy to Clipboard Toggle word wrap
2.1.9.1. The syntax of permission rules

The general syntax of a permission rule is:

permission (rights)
Copy to Clipboard Toggle word wrap
  • permission: Sets if the access control instruction (ACI) allows or denies permission.
  • rights: Sets the rights which the ACI allows or denies. See User rights in permission rules.

Example 2.11. Defining permissions

To enable users stored in the ou=People,dc=example,dc=com entry to search and display all attributes in their own entry:

# *ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x`

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (target = "ldap:///ou=People,dc=example,dc=com") (version 3.0;
 acl "Allow users to read and search attributes of own entry"; allow (search, read)
 (userdn = "ldap:///self");)
Copy to Clipboard Toggle word wrap
2.1.9.2. User rights in permission rules

The rights in a permission rule define what operations are granted or denied. In an ACI, you can set one or multiple of the following rights:

Expand
Table 2.1. User rights
RightDescription

read

Sets whether users can read directory data. This permission applies only to search operations in LDAP.

write

Sets whether users can modify an entry by adding, modifying, or deleting attributes. This permission applies to the modify and modrdn operations in LDAP.

add

Sets whether users can create an entry. This permission applies only to the add operation in LDAP.

delete

Sets whether users can delete an entry. This permission applies only to the delete operation in LDAP.

search

Sets whether users can search for directory data. To view data returned as part of a search result, assign search and read rights. This permission applies only to search operations in LDAP.

compare

Sets whether the users can compare data they supply with data stored in the directory. With compare rights, the directory returns a success or failure message in response to an inquiry, but the user cannot see the value of the entry or attribute. This permission applies only to the compare operation in LDAP.

selfwrite

Sets whether users can add or delete their own distinguished name (DN) from a group. This right is used only for group management.

proxy

Sets whether the specified DN can access the target with the rights of another entry. The proxy right is granted within the scope of the ACL, and the user or group who as the right granted can run commands as any Directory Server user. You cannot restrict the proxy rights to certain users. For security reasons, set ACIs that use the proxy right at the most targeted level of the directory.

all

Sets all of the rights, except proxy.

2.1.9.3. Rights required for LDAP operations
This section describes the rights you must grant to users depending on the type of LDAP operation you want to authorize them to perform.
Copy to Clipboard Toggle word wrap
  • Adding an entry:

    • Grant add permission on the entry that you want to add.
    • Grant write permission on the value of each attribute in the entry. This right is granted by default but can be restricted using the targattrfilters keyword.
  • Deleting an entry:

    • Grant delete permission on the entry that you want to delete.
    • Grant write permission on the value of each attribute in the entry. This right is granted by default but can be restricted using the targattrfilters keyword.
  • Modifying an attribute in an entry:

    • Grant write permission on the attribute type.
    • Grant write permission on the value of each attribute type. This right is granted by default but can be restricted using the targattrfilters keyword.
  • Modifying the RDN of an entry:

    • Grant write permission on the entry.
    • Grant write permission on the attribute type that is used in the new RDN.
    • Grant write permission on the attribute type that is used in the old RDN, if you want to grant the right to delete the old RDN.
    • Grant write permission on the value of attribute type that is used in the new RDN. This right is granted by default but can be restricted using the targattrfilters keyword.
  • Comparing the value of an attribute:

    • Grant compare permission on the attribute type.
  • Searching for entries:

    • Grant search permission on each attribute type used in the search filter.
    • Grant read permission on attribute types used in the entry.

2.1.10. Defining ACI bind rules

The bind rules in an access control instruction (ACI) define the required bind parameters that must meet so that Directory Server applies the ACI. For example, you can set bind rules based on:

  • DNs
  • Group memberships or assigned roles
  • Locations from which an entry must bind
  • Types of authentication that must be in use during the bind
  • Times or days on which the bind occurs

In an ACI, the following highlighted part is the bind rule:

(target_rule) (version 3.0; acl "ACL_name"; permission_rule bind_rules;)
Copy to Clipboard Toggle word wrap
2.1.10.1. The syntax of bind rules

The general syntax of a bind rule is:

keyword comparison_operator "expression"
Copy to Clipboard Toggle word wrap
  • keyword: Sets the type of the bind operation.
  • comparison_operator: Valid values are = and != and indicate whether or not the target is the object specified in the expression. If a keyword supports additional comparison operators, it is mentioned in the corresponding section.
  • expression: Sets the expression and must be surrounded by quotation marks. The expression itself depends on the keyword you use.
2.1.10.2. Defining user-based access

The userdn keyword enables you to grant or deny access based on one or multiple DNs and uses the following syntax:

userdn comparison_operator "ldap:///distinguished_name || ldap:///distinguished_name || ..."
Copy to Clipboard Toggle word wrap

Set the DN in the expression to:

Note

Do not specify a host name or port number within the LDAP URL. The URL always applies to the local server.

2.1.10.2.1. Using a DN with the userdn keyword

Set the userdn keyword to a distinguished name (DN) to apply the ACI only to the matching entry. To match multiple entries, use the * wildcard in the DN.

Using the userdn keyword with a DN must match the following syntax:

userdn comparison_operator ldap:///distinguished_name
Copy to Clipboard Toggle word wrap

Example 2.12. Using a DN with the userdn keyword

To enable the uid=admin,ou=People,dc=example,dc=com user to read the manager attribute of all other users in the ou=People,dc=example,dc=com entry:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr="manager") (version 3.0; acl "Allow uid=admin reading manager attribute";
 allow (search, read) userdn = "ldap:///uid=admin,ou=People,dc=example,dc=com";)
Copy to Clipboard Toggle word wrap

If you want to dynamically allow or deny permissions to users, use the userdn keyword with an LDAP filter:

userdn comparison_operator "ldap:///distinguished_name??scope?(filter)"
Copy to Clipboard Toggle word wrap
Note

The LDAP filter supports the * wildcard.

Example 2.13. Using the userdn keyword with an LDAP filter

To enable users who have the department attribute set to Human Resources to update the homePostalAddress attribute of users in the ou=People,dc=example,dc=com entry:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr="homePostalAddress") (version 3.0;
 acl "Allow HR setting homePostalAddress"; allow (write)
 userdn = "ldap:///ou=People,dc=example,dc=com??sub?(department=Human Resources)";)
Copy to Clipboard Toggle word wrap
2.1.10.2.3. Granting anonymous access

In certain situations, administrators want to configure anonymous access to data in the directory. Anonymous access means that it is possible to bind to the directory by providing:

  • No bind DN and password
  • A valid bind DN and password

To configure anonymous access, use the ldap:///anyone expression with the userdn keyword in a bind rule:

userdn comparison_operator "ldap:///anyone"
Copy to Clipboard Toggle word wrap

Example 2.14. Granting anonymous access

To enable anyone without authentication to read and search the sn, givenName, and telephoneNumber attributes in the ou=People,dc=example,dc=com entry:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com` -x dn: ou=People,dc=example,dc=com__
changetype: modify
add: aci
aci: (targetattr="sn" || targetattr="givenName" || targetattr = "telephoneNumber")
 (version 3.0; acl "Anonymous read, search for names and phone numbers";
 allow (read, search) userdn = "ldap:///anyone")
Copy to Clipboard Toggle word wrap
2.1.10.2.4. Granting access to authenticated users

In certain situations, administrators want to grant permission to any user who is able to successfully bind to Directory Server, except anonymous binds. To configure this feature, use the ldap:///all expression with the userdn keyword in a bind rule:

userdn comparison_operator "ldap:///all"
Copy to Clipboard Toggle word wrap

Example 2.15. Granting access to authenticated users

To enable authenticated users to add and remove themselves as a member to or from the ou=example,ou=groups,dc=example,dc=com group:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=example,ou=Groups,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr="member") (version 3.0;
 acl "Allow users to add/remove themselves from example group";
 allow (selfwrite) userdn = "ldap:///all")
Copy to Clipboard Toggle word wrap

To set ACI which allow or deny access to users to their own entry, use the ldap:///self expression with the userdn keyword in a bind rule:

userdn comparison_operator "ldap:///self"
Copy to Clipboard Toggle word wrap

Example 2.16. Enabling users to access their own entries

To enable users in the ou=People,dc=example,dc=com entry to update their own userPassword attribute:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr="userPassword") (version 3.0;
 acl "Allow users updating their password";
 allow (write) userdn = "ldap:///self")
Copy to Clipboard Toggle word wrap

To specify that users are granted or denied access to an entry only if their bind DN is the parent of the targeted entry, use the self:///parent expression with the userdn keyword in a bind rule:

userdn comparison_operator "ldap:///parent"
Copy to Clipboard Toggle word wrap

Example 2.17. Setting access for child entries of a user

To enable the cn=user,ou=People,dc=example,dc=com user to update the manager attribute of its own sub-entries, such as cn=example,cn=user,ou=People,dc=example,dc=com:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: cn=user,ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr="manager") (version 3.0;
 acl "Allow cn=user to update manager attributes";
 allow (write) userdn = "ldap:///parent")
Copy to Clipboard Toggle word wrap
2.1.10.3. Defining group-based access

Group-based access control instructions (ACI) enable you to manage access by adding or removing users to or from a group. To configure an ACI that is based on a group membership, use the groupdn keyword. If the user is a member of one or multiple of the specified groups, the ACI matches.

When using the groupdn keyword, Directory Server verifies the group membership based on the following attributes:

  • member
  • uniqueMember
  • memberURL
  • memberCertificateDescription

Bind rules with the groupdn keyword use the following syntax:

groupdn comparison_operator "ldap:///distinguished_name || ldap:///distinguished_name || ..."
Copy to Clipboard Toggle word wrap

Set the distinguished name (DN) in the expression to:

If you set multiple DNs in one bind rule, Directory Server applies the ACI if the authenticated user is a member of one of these groups. To set the user as a member of multiple groups, use multiple groupdn keywords and combine them using the Boolean and operator. For details, see Combining Bind Rules Using Boolean Operators.

Note

Do not specify a host name or port number within the LDAP URL. The URL always applies to the local server.

2.1.10.3.1. Using a DN with the groupdn keyword

To apply an ACI to members of a group, set the groupdn keyword to the group’s DN.

The groupdn keyword set to a DN uses the following syntax:

groupdn comparison_operator ldap:///distinguished_name
Copy to Clipboard Toggle word wrap

Example 2.18. Using a DN with the groupdn Keyword

To enable members of the cn=example,ou=Groups,dc=example,dc=com group to search and read the manager attribute of entries in ou=People,dc=example,dc=com:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr="manager") (version 3.0;
 acl "Allow example group to read manager attribute";
 allow (search, read) groupdn = "ldap:///cn=example,ou=Groups,dc=example,dc=com";)
Copy to Clipboard Toggle word wrap

Using an LDAP filter with the groupdn keyword, you can define that the authenticated user must be a member of at least one of the groups that the filter search returns, to match the ACI.

The groupdn keyword with an LDAP filter uses the following syntax:

groupdn comparison_operator "ldap:///distinguished_name??scope?(filter)"
Copy to Clipboard Toggle word wrap
Note

The LDAP filter supports the * wildcard.

Example 2.19. Using the groupdn keyword with an LDAP filter

To enable members of groups in dc=example,dc=com and subtrees, which have the manager attribute set to example, update the homePostalAddress of entries in ou=People,dc=example,dc=com:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr="homePostalAddress") (version 3.0;
 acl "Allow manager=example setting homePostalAddress"; allow (write)
 userdn = "ldap:///dc=example,dc=com??sub?(manager=example)";)
Copy to Clipboard Toggle word wrap
2.1.10.4. Defining access based on value matching

Use the userattr keyword in a bind rule to specify which attribute must match between the entry used to bind to the directory and the targeted entry.

The userattr keyword uses the following syntax:

userattr comparison_operator "attribute_name#bind_type_or_attribute_value
Copy to Clipboard Toggle word wrap

For further details, see:

Important

By default, Directory Server evaluates access rights on the entry they are created. However, to prevent user objects on the same level, Directory Server does not grant add permissions to the entry where you set the access control instructions (ACI), when using the userattr keyword. To configure this behavior, use the userattr keyword in conjunction with the parent keyword and grant the permission additionally on level 0.

For details about inheritance, see Defining access based on value matching.

2.1.10.4.1. Using the USERDN bind type

To apply an ACI when the binding user distinguished name (DN) matches the DN stored in an attribute, use the USERDN bind type.

The userattr keyword with the USERDN bind type requires the following syntax:

userattr comparison_operator "attribute_name#USERDN"
Copy to Clipboard Toggle word wrap

Example 2.20. Using the USERDN bind type

To grant a manager all permissions to the telephoneNumber attribute of its own associates:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "telephoneNumber")
 (version 3.0; acl "Manager: telephoneNumber";
 allow (all) userattr = "manager#USERDN";)
Copy to Clipboard Toggle word wrap

The previous ACI is evaluated to be true if the DN of the user who performs the operation on an entry in ou=People,dc=example,dc=com, matches the DN stored in the manager attribute of this entry.

2.1.10.4.2. Using the GROUPDN bind type

To apply an ACI when the binding user DN is a member of a group set in an attribute, use the GROUPDN bind type.

The userattr keyword with the GROUPDN bind type requires the following syntax:

userattr comparison_operator "attribute_name#GROUPDN"
Copy to Clipboard Toggle word wrap

Example 2.21. Using the GROUPDN bind type

To grant users the permission to delete a group entry which they own under the ou=Social Committee,ou=Groups,dc=example,dc=com entry:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=Social Committee,ou=Groups,dc=example,dc=com
changetype: modify
add: aci
aci: (target="ou=Social Committee,ou=Groups,dc=example,dc=com)
 (targattrfilters="del=objectClass:(objectClass=groupOfNames)")
 (version 3.0; acl "Delete Group";
 allow (delete) userattr = "owner#GROUPDN";)
Copy to Clipboard Toggle word wrap

The previous ACI is evaluated to be true if the DN of the user who performs the operation is a member of the group specified in the owner attribute.

The specified group can be a dynamic group, and the DN of the group can be under any suffix in the database. However, the evaluation of this type of ACI by the server is very resource-intensive.

If you are using static groups that are under the same suffix as the targeted entry, use the following expression for better performance:

userattr comparison_operator "ldap:///distinguished_name?attribute_name#GROUPDN"
Copy to Clipboard Toggle word wrap
2.1.10.4.3. Using the ROLEDN bind type

To apply an ACI when the binding user belongs to a role specified in an attribute, use the ROLEDN bind type.

The userattr keyword with the ROLEDN bind type requires the following syntax:

userattr comparison_operator "attribute_name#ROLEDN"
Copy to Clipboard Toggle word wrap

Example 2.22. Using the ROLEDN bind type

To enable users with the cn=Administrators,dc=example,dc=com role to search and read the manager attribute of entries in ou=People,dc=example,dc=com:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (version 3.0; acl "Allow example role owners to read manager attribute";
 allow (search, read) userattr = manager#ROLEDN;)
Copy to Clipboard Toggle word wrap

The specified role can be under any suffix in the database. If you are also using filtered roles, the evaluation of this type of ACI uses a lot of resources on the server.

If you are using a static role definition and the role entry is under the same suffix as the targeted entry, use the following expression for better performance:

2.1.10.4.4. Using the SELFDN bind type

The SELFDN bind type enables you to grant permissions, when the bound user’s DN is set in a single-value attribute of the entry.

The userattr keyword with the SELFDN bind type requires the following syntax:

userattr comparison_operator "attribute_name#SELFDN"
Copy to Clipboard Toggle word wrap

Example 2.23. Using the SELFDN bind type

To enable a user to add ipatokenuniqueid=*,cn=otp,dc=example,dc=com entries that have the bind user’s DN set in the ipatokenOwner attribute:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=otp,dc=example,dc=com
changetype: modify
add: aci
aci: (target = "ldap:///ipatokenuniqueid=*,cn=otp,dc=example,dc=com")
 (targetfilter = "(objectClass=ipaToken)")(version 3.0;
 acl "token-add-delete"; allow (add) userattr = "ipatokenOwner#SELFDN";)
Copy to Clipboard Toggle word wrap
2.1.10.4.5. Using the LDAPURL bind type

To apply an ACL when the bind DN matches the filter specified in an attribute of the targeted entry, use the LDAPURL bind type.

The userattr keyword with the LDAPURL bind type requires the following syntax:

userattr comparison_operator "attribute_name#LDAPURL"
Copy to Clipboard Toggle word wrap

Example 2.24. Using the LDAPURL bind type

To grant read and search permissions to user objects which contain the aciurl attribute set to ldap:///ou=People,dc=example,dc=com??one?(uid=user*):

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x
dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "*")
 (version 3.0; acl "Allow read,search "; allow (read,search)
 (userattr = "aciurl#LDAPURL);)
Copy to Clipboard Toggle word wrap

When you use the userattr keyword to associate the entry used to bind with the target entry, the ACI applies only to the target specified and not to the entries below it. In certain situations, administrators want to extend the application of the ACI several levels below the targeted entry. This is possible by using the parent keyword and specifying the number of levels below the target that should inherit the ACI.

When using the userattr keyword with the parent keyword, the syntax is as follows:

userattr comparison_operator "parent[inheritance_level].attribute_name#bind_type_or_attribute_value
Copy to Clipboard Toggle word wrap
  • inheritance_level: Comma-separated list that indicates how many levels below the target inherit the ACI. You can include five levels (0, 1, 2, 3, 4) below the targeted entry. Zero (0) indicates the targeted entry.
  • attribute_name: The attribute targeted by the userattr or groupattr keyword.
  • bind_type_or_attribute_value: Sets the attribute value or a bind type, such as USERDN.

For example:

userattr = "parent[0,1].manager#USERDN"
Copy to Clipboard Toggle word wrap

This bind rule is evaluated to be true if the bind DN matches the manager attribute of the targeted entry. The permissions granted when the bind rule is evaluated to be true apply to the target entry and to all entries immediately below it.

Example 2.25. Using the userattr keyword with inheritance

To enable a user to read and search the cn=Profiles,dc=example,dc=com entry where the user’s DN is set in the owner attribute, as well as the first level of child entries which includes cn=mail,cn=Profiles,dc=example,dc=com and cn=news,cn=Profiles,dc=example,dc=com:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com` -x

dn: cn=Profiles,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr="*") (version 3.0; acl "Profile access",
 allow (read,search) userattr="parent[0,1].owner#USERDN" ;)
Copy to Clipboard Toggle word wrap

The ip keyword in a bind rule enables you to grant or deny access from a specific IP address or a range of IP addresses.

Bind rules with the ip keyword use the following syntax:

ip comparison_operator "IP_address_or_range"
Copy to Clipboard Toggle word wrap

Example 2.26. Using IPv4 address ranges in bind rules

To deny access from the 192.0.2.0/24 network to the dc=example,dc=com entry:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "*") (version 3.0;acl "Deny 192.0.2.0/24"; deny (all)
 (userdn = "ldap:///anyone") and (ip != "192.0.2.");)
Copy to Clipboard Toggle word wrap

Example 2.27. Using IPv6 address ranges in bind rules

To deny access from the 2001:db8::/64 network to the dc=example,dc=com entry:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "*") (version 3.0;acl "Deny 2001:db8::/64"; deny (all)
 (userdn = "ldap:///anyone") and (ip != "2001:db8::");)
Copy to Clipboard Toggle word wrap

The dns keyword in a bind rule enables you to grant or deny access from a specific host or domain.

Warning

If Directory Server cannot resolve a connecting IP address to its fully qualified domain name (FQDN) using DNS, the server does not apply access control instructions (ACI) with the dns bind rule for this client.

If client IP addresses are not resolvable using DNS, use the ip keyword and IP addresses instead. See Defining access from specific IP addresses or ranges.

Bind rules with the dns keyword use the following syntax:

dns comparison_operator "host_name_or_domain_name"
Copy to Clipboard Toggle word wrap

Example 2.28. Defining access from a specific host

To deny access from the client.example.com host to the dc=example,dc=com entry:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "*") (version 3.0;acl "Deny client.example.com"; deny (all)
 (userdn = "ldap:///anyone") and (dns != "client.example.com");)
Copy to Clipboard Toggle word wrap

Example 2.29. Defining access from a specific domain

To deny access from all hosts within the example.com domain to the dc=example,dc=com entry:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "") (version 3.0;acl "Deny example.com"; deny (all) (userdn = "ldap:///anyone") and (dns != ".example.com");)
Copy to Clipboard Toggle word wrap

The security of a connection is determined by its security strength factor (SSF), which sets the minimum key strength required to process operations. Using the ssf keyword in a bind rule, you can set that a connection must use a certain level of security. This enables you to force operations, for example password changes, to be performed over an encrypted connection.

The value for the SSF for any operation is the higher of the values between a TLS connection and a SASL bind. This means that if a server is configured to run over TLS and a replication agreement is configured for SASL/GSSAPI, the SSF for the operation is whichever available encryption type is more secure.

Bind rules with the ssf keyword use the following syntax:

ssf comparison_operator key_strength
Copy to Clipboard Toggle word wrap

You can use the following comparison operators:

  • = (equal to)
  • ! (not equal to)
  • < (less than)
  • > (greater than)
  • (less than or equal to)
  • >= (greater than or equal to)

If the key_strength parameter is set to 0, no secure operation is required for the LDAP operation.

Example 2.30. Requiring a certain level of security in connections

To configure that users in the dc=example,dc=com entry can only update their userPassword attribute when the SSF is 128 or higher:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "userPassword") (version 3.0;
 acl "Allow users updating own userPassword";
 allow (write) (userdn = "ldap:///self") and (ssf >= "128");)
Copy to Clipboard Toggle word wrap

The dayofweek keyword in a bind rule enables you to grant or deny access based on the day of the week.

Note

Directory Server uses the time on the server to evaluate the access control instruction (ACI); not the time on the client.

Bind rules with the dayofweek keyword use the following syntax:

dayofweek comparison_operator "comma-separated_list_of_days"
Copy to Clipboard Toggle word wrap

Example 2.31. Granting access on specific days of the week

To deny access for the uid=user,ou=People,dc=example,dc=com user entry to bind to the server on Saturdays and Sundays:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (version 3.0; acl "Deny access on Saturdays and Sundays";
 deny (all)
 (userdn = "ldap:///uid=user,ou=People,dc=example,dc=com") and
 (dayofweek = "Sun,Sat");)
Copy to Clipboard Toggle word wrap

The timeofday keyword in a bind rule enables you to grant or deny access based on the time of day.

Note

Directory Server uses the time on the server to evaluate the access control instructions (ACI); not the time on the client.

Bind rules with the timeofday keyword use the following syntax:

timeofday comparison_operator "time"
Copy to Clipboard Toggle word wrap

You can use the following comparison operators:

  • = (equal to)
  • ! (not equal to)
  • < (less than)
  • > (greater than)
  • (less than or equal to)
  • >= (greater than or equal to)
Important

The timeofday keyword requires that you specify the time in 24-hour format.

Example 2.32. Defining access at a specific time of a day

To deny access for the uid=user,ou=People,dc=example,dc=com user entry to bind to the server between 6pm and 0am:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
 aci: (version 3.0; acl "Deny access between 6pm and 0am";
 deny (all)
 (userdn = "ldap:///uid=user,ou=People,dc=example,dc=com") and
 (timeofday >= "1800" and timeofday < "2400");)
Copy to Clipboard Toggle word wrap

The authmethod keyword in a bind rule sets what authentication method a client must use when connecting to the server, to apply the access control instruction (ACI).

Bind rules with the authmethod keyword use the following syntax:

authmethod comparison_operator "authentication_method"
Copy to Clipboard Toggle word wrap

You can set the following authentication methods:

  • none: Authentication is not required and represents anonymous access. This is the default.
  • simple: The client must provide a user name and password to bind to the directory.
  • SSL: The client must bind to the directory using a TLS certificate either in a database, smart card, or other device.
  • SASL: The client must bind to the directory over a Simple Authentication and Security Layer (SASL) connection. When you use this authentication method in a bind rule, additionally specify the SASL mechanism, such as EXTERNAL.

Example 2.33. Enabling access only for connections using the EXTERNAL SASL authentication method

To deny access to the server if the connection does not use a certificate-based authentication method or SASL:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com` -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (version 3.0; acl "Deny all access without certificate"; deny (all)
 (authmethod = "none" or authmethod = "simple");)
Copy to Clipboard Toggle word wrap
2.1.10.11. Defining access based on roles

The roledn keyword in a bind rule enables you to grant or deny access to users having one or multiple role sets.

Note

Red Hat recommends using groups instead of roles.

Bind rules with the roledn keyword use the following syntax:

roledn comparison_operator "ldap:///distinguished_name || ldap:///distinguished_name || ..."
Copy to Clipboard Toggle word wrap

If a distinguished name (DN) contains a comma, escape the comma with a backslash.

Example 2.34. Defining access based on roles

To enable users that have the cn=Human Resources,ou=People,dc=example,dc=com role set in the nsRole attribute to search and read the manager attribute of entries in ou=People,dc=example,dc=com:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr="manager") (version 3.0;
 acl "Allow manager role to update manager attribute";
 allow (search, read) roledn = "ldap:///cn=Human Resources,ou=People,dc=example,dc=com";)
Copy to Clipboard Toggle word wrap

When creating complex bind rules, the AND, OR, and NOT Boolean operators enable you to combine multiple keywords.

Bind rules combined with Boolean operators have the following syntax:

bind_rule_1 boolean_operator bind_rule_2...
Copy to Clipboard Toggle word wrap

Example 2.35. Combining bind rules using Boolean operators

To configure that users which are member of both the cn=Administrators,ou=Groups,dc=example,com and cn=Operators,ou=Groups,dc=example,com] group can `read, search, add, update, and delete entries in ou=People,dc=example,dc=com:

# ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x

dn: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (target="ldap:///ou=People,dc=example,dc=com") (version 3.0;
 acl "Allow members of administrators and operators group to manage users";
 allow (read, search, add, write, delete)
 groupdn = "ldap:///cn=Administrators,ou=Groups,dc=example,com" AND
 groupdn = "ldap:///cn=Operators,ou=Groups,dc=example,com";)
Copy to Clipboard Toggle word wrap

How Directory Server evaluates boolean operators

Directory Server evaluates Boolean operators by using the following rules:

  • All expressions from left to right.

    In the following example, bind_rule_1 is evaluated first:

    (bind_rule_1) OR (bind_rule_2)
    Copy to Clipboard Toggle word wrap
  • From innermost to outermost parenthetical expressions first.

    In the following example, bind_rule_2 is evaluated first and bind_rule_3 second:

    (bind_rule_1) OR ((bind_rule_2) AND (bind_rule_3))
    Copy to Clipboard Toggle word wrap
  • NOT before AND or OR operators.

    In the following example, bind_rule_2 is evaluated first:

    (bind_rule_1) AND NOT (bind_rule_2)
    Copy to Clipboard Toggle word wrap

    The AND and OR operators have no order of precedence.

This set of instructions provides you with the basics of managing the access control instructions (ACIs) by using the LDAP browser wizard in the web console.

You can create and add an access control instruction (ACI) for a Red Hat Directory Server (RHDS) entry by using the LDAP Browser in the web console.

Prerequisites

  • Access to the web console.
  • A parent entry exists in the Red Hat Directory Server.

Procedure

  1. Log in to the web console and click Red Hat Directory Server.
  2. After the web console loads the Red Hat Directory Server interface, click LDAP browser.
  3. Select an LDAP entry and click the Options menu (⋮).
  4. From the drop-down menu, select ACIs.
  5. To create an ACI by using the LDAP browser wizard, you have two options:

    1. Click Add ACI Wizard to create the ACI using the wizard. Continue with the next step.
    2. Click Add ACI Manually, specify the instruction in the text field, and click Save ACI.
  6. Follow the steps in the wizard and click the Next button after you complete each step.
  7. To create the ACI, review the data that the wizard generated, and click Add ACI.
  8. To close the wizard window, click the Finish button.

Verification

  • Verify the new ACI appears in the Manage ACIs window.

You can edit an access control instruction (ACI) for a Red Hat Directory Server entry by using the LDAP Browser Manage ACIs window in the web console.

Prerequisites

  • Access to the web console.
  • A parent entry exists in the Red Hat Directory Server.

Procedure

  1. Log in to the web console and click Red Hat Directory Server.
  2. After the web console loads the Red Hat Directory Server interface, click LDAP browser.
  3. Select an LDAP entry and click the Options menu (⋮).
  4. From the drop-down menu select ACIs.
  5. Click the Options menu and select Edit ACI.
  6. Modify the instruction in the text field and click Save ACI.

Verification

  • In the Manage ACIs window expand the ACI you modified and observe your changes.

You can remove an access control instruction (ACI) for a Red Hat Directory Server entry by using the LDAP Browser in the web console.

Prerequisites

  • Access to the web console.
  • A parent entry exists in the Directory Server.

Procedure

  1. Log in to the web console and click Red Hat Directory Server.
  2. After the web console loads the Red Hat Directory Server interface, click LDAP Browser.
  3. Select an LDAP entry and click the Options menu (⋮).
  4. From the drop-down menu select ACIs to open the Manage ACIs window.
  5. Click the Node options icon for the ACI you are removing and select Remove ACI.
  6. Select the Yes, I’m sure checkbox and click the Delete ACI button.

Verification

  • On the Manage ACIs window, verify the ACI you removed no longer appears on the list of ACIs.

2.3. Using macro access control instructions

Macro access control instructions (ACIs) provides you with the possibility to automate the tailored access to an LDAP entry distinguished name (DN) or to its part and reduce the number of ACIs.

2.3.1. Macro access control instruction example

The picture below shows a directory tree with suffixes dc=hostedCompany1,dc=example,dc=com and dc=hostedCompany2,dc=example,dc=com with the repetitive pattern of subdomains. Each subdomain has the same structure of ou=groups, ou=people entries. The directory tree uses macro access control instructions (ACIs) to reduce the total number of ACIs.

The ACIs that apply in the directory tree also have a repeating pattern. For example, the following ACI is located on the dc=hostedCompany1,dc=example,dc=com node and grants read and search rights to the DomainAdmins group to any entry in that tree:

aci: (targetattr="*")(targetfilter=(objectClass=nsManagedDomain))
     (version 3.0; acl "Domain access"; allow (read,search)
     groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=hostedCompany1,dc=example,dc=com";)
Copy to Clipboard Toggle word wrap

Figure 2.1. Directory tree for macro ACI example

The ACIs below show the different part of DN in the groupdn keyword:

  • The dc=hostedCompany1,dc=example,dc=com node contains the following ACI:
aci: (targetattr="*")(targetfilter=(objectClass=nsManagedDomain))
    (version 3.0; acl "Domain access"; allow (read,search)
    groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=hostedCompany1,dc=example,dc=com";)
Copy to Clipboard Toggle word wrap
  • The dc=subdomain1,dc=hostedCompany1,dc=example,dc=com node contains the following ACI:
aci: (targetattr="*")(targetfilter=(objectClass=nsManagedDomain))
     (version 3.0; acl "Domain access"; allow (read,search)
     groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=subdomain1,dc=hostedCompany1,dc=example,dc=com";)
Copy to Clipboard Toggle word wrap
  • The dc=hostedCompany2,dc=example,dc=com node contains the following ACI:
aci: (targetattr="*")(targetfilter=(objectClass=nsManagedDomain))
     (version 3.0; acl "Domain access"; allow (read,search)
     groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=hostedCompany2,dc=example,dc=com";)
Copy to Clipboard Toggle word wrap
  • The dc=subdomain1,dc=hostedCompany2,dc=example,dc=com node contains the following ACI:
aci: (targetattr="*")(targetfilter=(objectClass=nsManagedDomain))
     (version 3.0; acl "Domain access"; allow (read,search)
     groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=subdomain1,dc=hostedCompany2,dc=example,dc=com";)
Copy to Clipboard Toggle word wrap

Use the macro to replace multiple ACIs for repetitive patterns. For example, to reduce the ACIs above to one, use the following macro:

aci: (target="ldap:///ou=Groups,($dn),dc=example,dc=com")
     (targetattr="*")(targetfilter=(objectClass=nsManagedDomain))
     (version 3.0; acl "Domain access"; allow (read,search)
     groupdn="ldap:///cn=DomainAdmins,ou=Groups,[$dn],dc=example,dc=com";)
Copy to Clipboard Toggle word wrap

2.3.2. Macro access control instruction syntax

Macro access control instructions (ACIs) include the following types of expressions to replace a DN or a part of a DN:

  • ($dn),
  • [$dn],
  • ($attr.attrName), where attrName represents an attribute which is the part of the target entry.

The ACI keywords provide bind credentials which are the subject of the ACI. The subject determines where the ACI applies.

Expand
Table 2.2. Macros for ACI keywords
MacroACI keywordsDescription

($dn)

target, targetfilter, userdn, roledn, groupdn, userattr

Matching and direct substitution in the subject. It will match to target or to targetfilter and substitute the matched value into userdn, groupdn, or userattr.

[$dn]

targetfilter, userdn, roledn, groupdn, userattr

Substitution of multiple RDNs that work in subtrees of the subject.

($attr.attrName)

userdn, roledn, groupdn, userattr

Substitution of the attributeName attribute value from the target entry into the subject.

Note, if you use any macro, you must define the target that contains the ($dn) macro. You can combine ($dn) and ($attr.attrName) macros.

2.3.3. The [$dn] macro example

The [$dn] macro examines the DN of the targeted source multiple times. This macro drops the leftmost RDN component each iteration until it finds a match.

For example, you have an LDAP request with the target at the cn=all,ou=groups,dc=subdomain1,dc=hostedCompany1,dc=example,dc=com subtree and the following ACI:

aci: (target="ldap:///ou=groups,($dn),dc=example,dc=com")
     (targetattr = "*") (version 3.0; acl "Domain access"; allow (read,search)
     groupdn="ldap:///cn=domainAdmins,ou=groups,[$dn],dc=example,dc=com";)
Copy to Clipboard Toggle word wrap

The macro expands as follows:

  1. The ($dn) in the target matches dc=subdomain1,dc=hostedCompany1.
  2. The replacement for the [$dn] in the subject is dc=subdomain1,dc=hostedCompany1.

    The result is groupdn="ldap:///cn=domainAdmins,ou=Groups,dc=subdomain1,dc=hostedCompany1,dc=example,dc=com". If the bind DN is a member of that group, the matching process stops, and the ACI is evaluated. If the result does not match, the process continues and drops the leftmost part.

  3. The [$dn] in the subject is dc=hostedCompany1.

    The result is groupdn="ldap:///cn=domainAdmins,ou=Groups,dc=hostedCompany1,dc=example,dc=com". If the bind DN is not a member of that group, the ACI is not evaluated. If it is a member, the ACI is evaluated.

The [$dn] macro grants access to domain-level administrators to all the subdomains in the directory tree. It is useful for expressing a hierarchical relationship between domains. For example, consider the following ACI:

aci: (target="ldap:///ou=*, ($dn),dc=example,dc=com")
     (targetattr="*")(targetfilter=(objectClass=nsManagedDomain))
     (version 3.0; acl "Domain access"; allow (read,search)
     groupdn="ldap:///cn=domainAdmins,ou=groups,[$dn],dc=example,dc=com";)
Copy to Clipboard Toggle word wrap

This ACI grants access to the members of the cn=domainAdmins,ou=groups,dc=hostedCompany1,dc=example,dc=com to all of the subdomains under dc=hostedCompany1. An administrator that is a member of that group can access a subtree like ou=people,dc=subdomain1.1,dc=subdomain1. But members of cn=domainAdmins,ou=groups,dc=subdomain1.1 do not have an access to the ou=people,dc=hostedCompany1 and ou=people,dc=subdomain1,dc=hostedCompany1 nodes.

2.3.4. The ($dn) macro example

The ($dn) macro compares the substitution value to the entry from the LDAP request. For example, the LDAP request targets the entry:

cn=all,ou=groups,dc=subdomain1,dc=hostedCompany1,dc=example,dc=com
Copy to Clipboard Toggle word wrap

The ACI defines the following target:

(target="ldap:///ou=groups,($dn),dc=example,dc=com")
Copy to Clipboard Toggle word wrap

The ($dn) macro matches with dc=subdomain1,dc=hostedCompany1 in this example.

The substring that matches the target expands the subject when the subject of the ACI uses the ($dn) macro:

aci: (target="ldap:///ou=*,($dn),dc=example,dc=com")
     (targetattr = "*") (version 3.0; acl "Domain access"; allow (read,search)
     groupdn="ldap:///cn=domainAdmins,ou=groups,($dn),dc=example,dc=com";)
Copy to Clipboard Toggle word wrap

The ACI expands as follow:

aci: (target="ldap:///ou=groups,dc=subdomain1,dc=hostedCompany1,
     dc=example,dc=com") (targetattr = "*") (version 3.0; acl "Domain
     access"; allow (read,search) groupdn="ldap:///cn=domainAdmins,ou=groups,
     dc=subdomain1,dc=hostedCompany1,dc=example,dc=com";)
Copy to Clipboard Toggle word wrap

After the macro is expanded, Red Hat Directory Server evaluates the ACI following the normal process to determine if access is granted.

2.3.5. The ($attr.attrName) macro example

You always use the ($attr.attrName) macro as a part of a DN. For example, define the following roledn:

roledn = "ldap:///cn=DomainAdmins,($attr.ou),dc=HostedCompany1,dc=example,dc=com"
Copy to Clipboard Toggle word wrap

Assuming, that the server receives an LDAP operation that targets at the following entry:

dn: cn=Jane Doe,ou=People,dc=HostedCompany1,dc=example,dc=com
cn: Jane Doe
sn: Doe
ou: Engineering...
Copy to Clipboard Toggle word wrap

To evaluate the roledn part of the ACI, the server looks at the ou attribute in the targeted entry and uses the value of this attribute to expand the macro. The roledn expands as follows:

roledn = "ldap:///cn=DomainAdmins,ou=Engineering,dc=HostedCompany1,dc=example,dc=com"
Copy to Clipboard Toggle word wrap

Red Hat Directory Server evaluates the ACI according to the normal ACI evaluation algorithm.

If the attribute has multiple values, RHDS uses each value to expand the macro and uses the value that has a first successful match of the expanded macro. For example:

dn: cn=Jane Doe,ou=People,dc=HostedCompany1,dc=example,dc=com
cn: Jane Doe
sn: Doe
ou: Engineering
ou: People...
Copy to Clipboard Toggle word wrap

When the Red Hat Directory Server evaluates the ACI, it performs a logical OR on the following expanded expressions:

roledn = "ldap:///cn=DomainAdmins,ou=Engineering,dc=HostedCompany1,dc=example,dc=com"

roledn = "ldap:///cn=DomainAdmins,ou=People,dc=HostedCompany1,dc=example,dc=com"
Copy to Clipboard Toggle word wrap

A password-based account lockout policy prevents attackers from repeatedly trying to guess a user’s password. You can configure the account lockout policy to lock a user account after a specified number of failed attempts to bind.

If a password-based account lockout policy is configured, Directory Server maintains the lockout information in the following attributes of the user entries:

  • passwordRetryCount: Stores the number of failed bind attempts. Directory Server resets the value if the user successfully binds to the directory later than the time in retryCountResetTime. This attribute is present after a user fails to bind for the first time.
  • retryCountResetTime: Stores the time after which the passwordRetryCount attribute is reset. This attribute is present after a user fails to bind for the first time.
  • accountUnlockTime: Stores the time after which the user account is unlocked. This attribute is present after the account was locked for the first time.

Administrators can configure one of the following behaviors when Directory Server locks accounts on failed login attempts:

  • The server locks accounts if the limit has been exceeded. For example, if the limit is set to 3 attempts, the lockout happens after the fourth failed attempt (n+1). This also means that, if the fourth attempt succeeds, Directory Server does not lock the account.

    By default, Directory Server uses this legacy password policy that is often expected by traditional LDAP clients.

  • The server locks accounts if the limit has been reached. For example, if the limit is set to 3 attempts, the server locks the account after the third failed attempt (n).

    Modern LDAP clients often expect this behavior.

This procedure describes how to disable the legacy password policy. After changing the policy, Directory Server blocks login attempts for a user that reached the configured limit.

Prerequisites

  • You configured an account lockout policy.

Procedure

  • To disable the legacy password policy and lock accounts if the limit has been reached, enter:

    # dsconf <instance_name> config replace passwordLegacyPolicy=off
    Copy to Clipboard Toggle word wrap

Verification

  1. Display the value of the passwordmaxfailure setting:

    # dsconf <instance_name> pwpolicy get passwordmaxfailure
    passwordmaxfailure: 2
    Copy to Clipboard Toggle word wrap
  2. Attempt to bind using an invalid password one more time than the value set in passwordmaxfailure:

    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w <invalid-password> -b "dc=example,dc=com" -x
    ldap_bind: Invalid credentials (49)
    
    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w <invalid-password> -b "dc=example,dc=com" -x
    ldap_bind: Invalid credentials (49)
    
    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w <invalid-password> -b "dc=example,dc=com" -x
    ldap_bind: Constraint violation (19)
    	additional info: Exceed password retry limit. Please try later.
    Copy to Clipboard Toggle word wrap

    With legacy passwords disabled, Directory Server locked the account after the second attempt, and further tries are blocked with an ldap_bind: Constraint violation (19) error.

To block login recurring bind attempts with invalid passwords, configure a password-based account lockout policy.

Important

The behavior whether Directory Server locks accounts when reaching or exceeding the configured maximum attempts depends on the legacy password policy setting.

Procedure

  1. Optional: Identify whether the legacy password policy is enabled or disabled:

    # dsconf <instance_name> config get passwordLegacyPolicy
    passwordLegacyPolicy: on
    Copy to Clipboard Toggle word wrap
  2. Enable the password lockout policy and set the maximum number of failures to 2:

    # dsconf <instance_name> pwpolicy set --pwdlockout on --pwdmaxfailures=2
    Successfully updated global password policy
    Copy to Clipboard Toggle word wrap

    With the legacy password policy enabled, Directory Server will lock accounts after the third failed attempt to bind (value of the --pwdmaxfailures parameter + 1).

    The dsconf pwpolicy set command supports the following parameters:

    • --pwdlockout: Enables or disables the account lockout feature. Default: off.
    • --pwdmaxfailures: Sets the maximum number of allowed failed bind attempts before Directory Server locks the account. Default: 3.

      Note that this lockout happens one attempt later if the legacy password policy setting is enabled. Default: 3.

    • --pwdresetfailcount: Sets the time in seconds before Directory Server resets the passwordRetryCount attribute in the user’s entry. Default: 600 seconds (10 minutes).
    • --pwdlockoutduration: Sets the time of accounts being locked in seconds. This parameter is ignored if you set the --pwdunlock parameter to off. Default: 3600 seconds (1 hour).
    • --pwdunlock: Enables or disables whether locked accounts should be unlocked after a certain amount of time or stay disabled until an administrator manually unlocks them. Default: on.

Verification

  • Attempt to bind using an invalid password two more times than the value you set in the --pwdmaxfailures parameter:

    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w <invalid-password> -b "dc=example,dc=com" -x
    ldap_bind: Invalid credentials (49)
    
    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w <invalid-password> -b "dc=example,dc=com" -x
    ldap_bind: Invalid credentials (49)
    
    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w <invalid-password> -b "dc=example,dc=com" -x
    ldap_bind: Invalid credentials (49)
    
    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w <invalid-password> -b "dc=example,dc=com" -x
    ldap_bind: Constraint violation (19)
            additional info: Exceed password retry limit. Please try later.
    Copy to Clipboard Toggle word wrap

    With legacy passwords enabled, Directory Server locked the account after the limit has exceeded, and further tries are blocked with an ldap_bind: Constraint violation (19) error.

To block login recurring bind attempts with invalid passwords, configure a password-based account lockout policy.

Important

The behavior whether Directory Server locks accounts when reaching or exceeding the configured maximum attempts depends on the legacy password policy setting.

Prerequisites

  • You are logged in to the instance in the web console.

Procedure

  1. Optional: Identify whether the legacy password policy is enabled or disabled:

    # dsconf <instance_name> config get passwordLegacyPolicy
    passwordLegacyPolicy: on
    Copy to Clipboard Toggle word wrap

    This setting is not available in the web console.

  2. Navigate to DatabasePassword PoliciesGlobal PolicyAccount Lockout.
  3. Select Enable Account Lockout.
  4. Configure the lockout settings:

    • Number of Failed Logins That Locks out Account: Sets the maximum number of allowed failed bind attempts before Directory Server locks the account.
    • Time Until Failure Count Resets: Sets the time in seconds before Directory Server resets the passwordRetryCount attribute in the user’s entry.
    • Time Until Account Unlocked: Sets the time of accounts beging locked in seconds. This parameter is ignored if you disable Do Not Lockout Account Forever.
    • Do Not Lockout Account Forever: Enables or disables whether locked accounts should be unlocked after a certain amount of time or stay disabled until an administrator manually unlocks them.
  5. Click Save.

Verification

  • Attempt to bind using an invalid password two more times than the value you set in Number of Failed Logins That Locks out Account:

    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w <invalid-password> -b "dc=example,dc=com" -x
    ldap_bind: Invalid credentials (49)
    
    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w <invalid-password> -b "dc=example,dc=com" -x
    ldap_bind: Invalid credentials (49)
    
    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w <invalid-password> -b "dc=example,dc=com" -x
    ldap_bind: Invalid credentials (49)
    
    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w <invalid-password> -b "dc=example,dc=com" -x
    ldap_bind: Constraint violation (19)
            additional info: Exceed password retry limit. Please try later.
    Copy to Clipboard Toggle word wrap

    With legacy passwords enabled, Directory Server locked the account after the limit has exceeded, and further tries are blocked with an ldap_bind: Constraint violation (19) error.

You can use the Account Policy plug-in to configure different time-based lockout policies, such as:

Follow this procedure to configure a time-based lockout policy that inactivates users under the dc=example,dc=com entry who do not log in for more than 21 days.

This the account inactivity feature to ensure, for example if an employee left the company and the administrator forgets to delete the account, that Directory Server inactivates the account after a certain amount of time.

Procedure

  1. Enable the Account Policy plug-in:

    # dsconf <instance_name> plugin account-policy enable
    Copy to Clipboard Toggle word wrap
  2. Configure the plug-in configuration entry:

    # dsconf <instance_name> plugin account-policy config-entry set "cn=config,cn=Account Policy Plugin,cn=plugins,cn=config" --always-record-login yes --state-attr lastLoginTime --alt-state-attr 1.1 --spec-attr acctPolicySubentry --limit-attr accountInactivityLimit
    Copy to Clipboard Toggle word wrap

    This command uses the following options:

    • --always-record-login yes: Enables logging of the login time. This is required to use Class of Service (CoS) or roles with account policies, even if it does not have the acctPolicySubentry attribute set.
    • --state-attr lastLoginTime: Configures that the Account Policy plug-in stores the last login time in the lastLoginTime attribute of users.
    • --alt-state-attr 1.1: Disables using an alternative attribute to check if the primary one does not exist. By default, Directory Server uses the createTimestamp attribute as alternative. However, this causes that Directory Server logs out existing users automatically if their account do not have the lastLoginTime attribute set and createTimestamp is older than the configured inactivity period. Disabling the alternative attribute causes that Directory Server automatically adds the lastLoginTime attribute to user entries when they log in the next time.
    • --spec-attr acctPolicySubentry: Configures Directory Server to apply the policy to entries that have the acctPolicySubentry attribute set. You configure this attribute in the CoS entry.
    • --limit-attr accountInactivityLimit: Configures that the accountInactivityLimit attribute in the account inactivation policy entry stores the inactivity time.
  3. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap
  4. Create the account inactivation policy entry:

    # ldapadd -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: cn=Account Inactivation Policy,dc=example,dc=com
    objectClass: top
    objectClass: ldapsubentry
    objectClass: extensibleObject
    objectClass: accountpolicy
    accountInactivityLimit: 1814400
    cn: Account Inactivation Policy
    Copy to Clipboard Toggle word wrap

    The value in the accountInactivityLimit attribute configures that Directory Server inactivates accounts 1814400 seconds (21 days) after the last log in.

  5. Create the CoS template entry:

    # ldapadd -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: cn=TemplateCoS,dc=example,dc=com
    objectClass: top
    objectClass: ldapsubentry
    objectClass: extensibleObject
    objectClass: cosTemplate
    acctPolicySubentry: cn=Account Inactivation Policy,dc=example,dc=com
    Copy to Clipboard Toggle word wrap

    This template entry references the account inactivation policy.

  6. Create the CoS definition entry:

    # ldapadd -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: cn=DefinitionCoS,dc=example,dc=com
    objectClass: top
    objectClass: ldapsubentry
    objectclass: cosSuperDefinition
    objectclass: cosPointerDefinition
    cosTemplateDn: cn=TemplateCoS,dc=example,dc=com
    cosAttribute: acctPolicySubentry default operational-default
    Copy to Clipboard Toggle word wrap

    This definition entry references the CoS template entry and causes that the acctPolicySubentry attribute appears in each user entry with a value set to cn=Account Inactivation Policy,dc=example,dc=com.

Verification

  1. Set the lastLoginTime attribute of a user to a value that is older than the inactivity time you configured:

    # ldapmodify -H ldap://server.example.com -x -D "cn=Directory Manager" -W
    
    dn: uid=example,ou=People,dc=example,dc=com
    changetype: modify
    replace: lastLoginTime
    lastLoginTime: 20210101000000Z
    Copy to Clipboard Toggle word wrap
  2. Try to connect to the directory as a this user:

    # ldapsearch -H ldap://server.example.com -x -D "uid=example,ou=People,dc=example,dc=com" -W -b "dc=example,dc=com"
    ldap_bind: Constraint violation (19)
    	additional info: Account inactivity limit exceeded. Contact system administrator to reset.
    Copy to Clipboard Toggle word wrap

    If Directory Server denies access and returns this error, account inactivity works.

Follow this procedure to configure that accounts in the dc=example,dc=com entry expire 60 days after the administrator created them.

Use the account expiration feature, for example, to ensure that accounts for external workers are locked a certain amount of time after they have been created.

Procedure

  1. Enable the Account Policy plug-in:

    # dsconf <instance_name> plugin account-policy enable
    Copy to Clipboard Toggle word wrap
  2. Configure the plug-in configuration entry:

    # dsconf <instance_name> plugin account-policy config-entry set "cn=config,cn=Account Policy Plugin,cn=plugins,cn=config" --always-record-login yes --state-attr createTimestamp --alt-state-attr 1.1 --spec-attr acctPolicySubentry --limit-attr accountInactivityLimit
    Copy to Clipboard Toggle word wrap

    This command uses the following options:

    • --always-record-login yes: Enables logging of the login time. This is required to use Class of Service (CoS) or roles with account policies, even if it does not have the acctPolicySubentry attribute set.
    • --state-attr createTimestamp: Configures that the Account Policy plug-in uses the value of the createTimestamp attribute to calculate whether an account is expired.
    • --alt-state-attr 1.1: Disables using an alternative attribute to check if the primary one does not exist.
    • --spec-attr acctPolicySubentry: Configures Directory Server to apply the policy to entries that have the acctPolicySubentry attribute set. You configure this attribute in the CoS entry.
    • --limit-attr accountInactivityLimit: Configures that the accountInactivityLimit attribute in the account expiration policy entry stores the maximum age.
  3. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap
  4. Create the account expiration policy entry:

    # ldapadd -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: cn=Account Expiration Policy,dc=example,dc=com
    objectClass: top
    objectClass: ldapsubentry
    objectClass: extensibleObject
    objectClass: accountpolicy
    accountInactivityLimit: 5184000
    cn: Account Expiration Policy
    Copy to Clipboard Toggle word wrap

    The value in the accountInactivityLimit attribute configures that accounts expire 5184000 seconds (60 days) after they have been created.

  5. Create the CoS template entry:

    # ldapadd -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: cn=TemplateCoS,dc=example,dc=com
    objectClass: top
    objectClass: ldapsubentry
    objectClass: extensibleObject
    objectClass: cosTemplate
    acctPolicySubentry: cn=Account Expiration Policy,dc=example,dc=com
    Copy to Clipboard Toggle word wrap

    This template entry references the account expiration policy.

  6. Create the CoS definition entry:

    # ldapadd -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: cn=DefinitionCoS,dc=example,dc=com
    objectClass: top
    objectClass: ldapsubentry
    objectclass: cosSuperDefinition
    objectclass: cosPointerDefinition
    cosTemplateDn: cn=TemplateCoS,dc=example,dc=com
    cosAttribute: acctPolicySubentry default operational-default
    Copy to Clipboard Toggle word wrap

    This definition entry references the CoS template entry and causes that the acctPolicySubentry attribute appears in each user entry with a value set to cn=Account Expiration Policy,dc=example,dc=com.

Verification

  • Try to connect to the directory as a user stored in the dc=example,dc=com entry whose createTimestamp attribute is set to a value more than 60 days ago:

    # ldapsearch -H ldap://server.example.com -x -D "uid=example,dc=example,dc=com" -W -b "dc=example,dc=com"
    ldap_bind: Constraint violation (19)
    	additional info: Account inactivity limit exceeded. Contact system administrator to reset.
    Copy to Clipboard Toggle word wrap

    If Directory Server denies access and returns this error, account expiration works.

Follow this procedure to configure a time-based lockout policy that inactivates users under the dc=example,dc=com entry who do not change their password for more than 28 days.

Prerequisites

  • Users must have the passwordExpirationTime attribute set in their entry.

Procedure

  1. Enable the password expiration feature:

    # dsconf <instance_name> config replace passwordExp=on
    Copy to Clipboard Toggle word wrap
  2. Enable the Account Policy plug-in:

    # dsconf <instance_name> plugin account-policy enable
    Copy to Clipboard Toggle word wrap
  3. Configure the plug-in configuration entry:

    # dsconf <instance_name> plugin account-policy config-entry set "cn=config,cn=Account Policy Plugin,cn=plugins,cn=config" --always-record-login yes --always-record-login-attr lastLoginTime --state-attr non_existent_attribute --alt-state-attr passwordExpirationTime --spec-attr acctPolicySubentry --limit-attr accountInactivityLimit
    Copy to Clipboard Toggle word wrap

    This command uses the following options:

    • --always-record-login yes: Enables logging of the login time. This is required to use Class of Service (CoS) or roles with account policies, even if it does not have the acctPolicySubentry attribute set.
    • --always-record-login-attr lastLoginTime: Configures that the Account Policy plug-in stores the last login time in the lastLoginTime attribute of users.
    • --state-attr non_existent_attribute: Sets the primary time attribute used to evaluate an account policy to a non-existent dummy attribute name.
    • --alt-state-attr `passwordExpirationTime: Configures the plug-in to use the passwordExpirationTime attribute as the alternative attribute to check.
    • --spec-attr acctPolicySubentry: Configures Directory Server to apply the policy to entries that have the acctPolicySubentry attribute set. You configure this attribute in the CoS entry.
    • --limit-attr accountInactivityLimit: Configures that the accountInactivityLimit attribute in the account policy entry stores the time when accounts are inactivated after their last password change.
  4. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap
  5. Create the account inactivation policy entry:

    # ldapadd -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: cn=Account Inactivation Policy,dc=example,dc=com
    objectClass: top
    objectClass: ldapsubentry
    objectClass: extensibleObject
    objectClass: accountpolicy
    accountInactivityLimit: 2419200
    cn: Account Inactivation Policy
    Copy to Clipboard Toggle word wrap

    The value in the accountInactivityLimit attribute configures that Directory Server inactivates accounts 2419200 seconds (28 days) after the password was changed.

  6. Create the CoS template entry:

    # ldapadd -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: cn=TemplateCoS,dc=example,dc=com
    objectClass: top
    objectClass: ldapsubentry
    objectClass: extensibleObject
    objectClass: cosTemplate
    acctPolicySubentry: cn=Account Inactivation Policy,dc=example,dc=com
    Copy to Clipboard Toggle word wrap

    This template entry references the account inactivation policy.

  7. Create the CoS definition entry:

    # ldapadd -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: cn=DefinitionCoS,dc=example,dc=com
    objectClass: top
    objectClass: ldapsubentry
    objectclass: cosSuperDefinition
    objectclass: cosPointerDefinition
    cosTemplateDn: cn=TemplateCoS,dc=example,dc=com
    cosAttribute: acctPolicySubentry default operational-default
    Copy to Clipboard Toggle word wrap

    This definition entry references the CoS template entry and causes that the acctPolicySubentry attribute appears in each user entry with a value set to cn=Account Inactivation Policy,dc=example,dc=com.

Verification

  1. Set the passwordExpirationTime attribute of a user to a value that is older than the inactivity time you configured:

    # ldapmodify -H ldap://server.example.com -x -D "cn=Directory Manager" -W
    
    dn: uid=example,ou=People,dc=example,dc=com
    changetype: modify
    replace: passwordExpirationTime
    passwordExpirationTime: 20210101000000Z
    Copy to Clipboard Toggle word wrap
  2. Try to connect to the directory as a this user:

    # ldapsearch -H ldap://server.example.com -x -D "uid=example,ou=People,dc=example,dc=com" -W -b "dc=example,dc=com"
    ldap_bind: Constraint violation (19)
    	additional info: Account inactivity limit exceeded. Contact system administrator to reset.
    Copy to Clipboard Toggle word wrap

    If Directory Server denies access and returns this error, account inactivity works.

You can apply both account inactivity and password expiration when a user authenticates by using the checkAllStateAttrs setting. By default, when checkAllStateAttrs is not present in the plug-in configuration entry, or when you set this parameter to no, the plug-in checks for the state attribute lastLoginTime. If the attribute is not present in the entry, the plug-in checks the alternate state attribute.

You can set the main state attribute to a non-existent attribute and set the alternate state attribute to passwordExpirationtime when you want the plug-in to handle expiration based on the passwordExpirationtime attribute. When you enable this parameter it check’s the main state attribute and if the account is fine it then check’s the alternate state attribute.

This differs from the password policy’s password expiration, in that the account policy plug-in completely disables the account if the passwordExpirationtime exceeds the inactivity limit. While with the password policy expiration the user can still log in and change their password. The account policy plug-in completely blocks the user from doing anything and an administrator must reset the account.

Procedure

  1. Create the plug-in configuration entry and enable the setting:

    # dsconf <instance_name> plugin account-policy config-entry set "cn=config,cn=Account Policy Plugin,cn=plugins,cn=config" --always-record-login yes --state-attr lastLoginTime --alt-state-attr 1.1 --spec-attr acctPolicySubentry --limit-attr accountInactivityLimit --check-all-state-attrs yes
    Copy to Clipboard Toggle word wrap
  2. Restart the server to load the new plug-in configuration:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap
    Warning

    The checkAllStateAttrs setting is designed to only work when the alternate state attribute is set to passwordExpiratontime. Setting it to createTimestamp can cause undesired results and entries might get locked out.

You can re-enable accounts using the dsconf account unlock command or by manually updating the lastLoginTime attribute of the inactivated user.

Prerequisites

  • An inactivated user account.

Procedure

  • Reactivate the account using one of the following methods:

    • Using the dsconf account unlock command:

      # dsidm <instance_name> -b "dc=example,dc=com" account unlock "uid=example,ou=People,dc=example,dc=com"
      Copy to Clipboard Toggle word wrap
    • By setting the lastLoginTime attribute of the user to a recent time stamp:

      # ldapmodify -H ldap://server.example.com -x -D "cn=Directory Manager" -W
      
      dn: uid=example,ou=People,dc=example,dc=com
      changetype: modify
      replace: lastLoginTime
      lastLoginTime: 20210901000000Z
      Copy to Clipboard Toggle word wrap

Verification

  • Authenticate as the user that you have reactivated. For example, perform a search:

    # ldapsearch -H ldap://server.example.com -x -D "uid=example,ou=People,dc=example,dc=com" -W -b "dc=example,dc=com" -s base
    Copy to Clipboard Toggle word wrap

    If the user can successfully authenticate, the account was reactivated.

You can use the Account Policy plug-in to track user login times without setting an expiration time or inactivity period. In this case, the plug-in adds the lastLoginTime attribute to user entries.

Follow this procedure to record the last login time of users in the lastLoginTime attribute of user entries.

Procedure

  1. Enable the Account Policy plug-in:

    # dsconf <instance_name> plugin account-policy enable
    Copy to Clipboard Toggle word wrap
  2. Create the plug-in configuration entry to record login times:

    # dsconf <instance_name> plugin account-policy config-entry set "cn=config,cn=Account Policy Plugin,cn=plugins,cn=config" --always-record-login yes --state-attr lastLoginTime
    Copy to Clipboard Toggle word wrap

    This command uses the following options:

    • --always-record-login yes: Enables logging of the log in time.
    • --state-attr lastLoginTime: Configures that the Account Policy plug-in stores the last log in time in the lastLoginTime attribute of users.
  3. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap

Verification

  1. Log in to Directory Server as a user. For example, run a search:

    # ldapsearch -H ldap://server.example.com -x -D "uid=example,ou=People,dc=example,dc=com" -W -b "dc=example,dc=com"
    Copy to Clipboard Toggle word wrap
  2. Display the lastLoginTime attribute of the user you used in the previous step:

    # ldapsearch -H ldap://server.example.com -x -D "cn=Directory Manager" -W -b "uid=example,ou=people,dc=example,dc=com" lastLoginTime
    ...
    dn: uid=example,ou=People,dc=example,dc=com
    lastLoginTime: 20210913091435Z
    Copy to Clipboard Toggle word wrap

    If the lastLoginTime attribute exists and Directory Server updated its value, recording of the last login time works.

Chapter 3. User management and authentication

Learn how to manage user access permissions, resource limits, user groups, and user roles. You can configure a password and account lockout policy, deny access for a group of users, and limit system resources depending on their bind distinguished name (bind DN).

3.1. Using groups in Directory Server

You can add users to groups in Directory Server. Groups are one of the mechanisms to group directory entries, that simplifies management of the user accounts.

When you use a group, Directory Server stores the distinguished name (DN) of the users who are members of this group in a membership attribute of the group entry. This special attribute is defined by the object class you choose when creating a group entry. For details about the group types, see Group types in Directory Server.

Groups are faster than roles. However, for a group to have benefits of a role, you need to enable the MemberOf plug-in. By default, the MemberOf plug-in automatically adds the memberOf attribute to a user entry if this user is a member of the group. As a result, the information about the membership is stored in both the group and user entries. For details about the MemberOf plug-in, see Listing group membership in user entries.

3.1.1. Group types in Directory Server

In Directory Server, you can add members to a static or dynamic group. For more details about definition of each group type, see About groups in Directory Server. A group object class defines a membership attribute, and to add a member to the group, you need to add a value to this membership attribute of the group entry.

The following table lists group object classes and corresponding membership attributes.

Expand
Group typeObject classMembership attribute

Static

groupOfNames

member

groupOfUniqueNames

uniqueMember

Dynamic

groupOfURLs

memberURL

groupOfCertificates

memberCertificate

Object classes that you can use when you create a group:

  • groupOfNames is a simple group. You can add any entry to this group. The member attribute determines the group membership. The member attribute values are distinguished names (DN) of user entries that are members of the group.
  • groupOfUniqueNames lists user DNs as members, however the DNs must be unique. This group prevents self-referential group memberships. The uniqueMember attribute determines the group membership.
  • groupOfURLs uses a list of LDAP URLs to filter and create its membership list. Any dynamic group requires this object class and you can use it in conjunction with groupOfNames and groupOfUniqueNames. The memberURL attribute determines the group membership.
  • groupOfCertificates uses an LDAP filter to search for certificate names to identify group members. Use the groupOfCertificates object class for group-based access control, because you can give special access permissions to this group. The memberCertificateDescription attribute determines the group membership.
Important

If you use an object class of a static group together with one of the dynamic object classes, the group becomes dynamic.

The MemberOf plug-in does not support dynamic groups. Therefore, the plug-in does not add the memberOf attribute to the user entry if the user entry matches the filter of a dynamic group.

3.1.2. Creating a static group

You can create a static group by using the command line or the web console.

Use the dsidm utility to create a static group with the groupOfNames object class. Use the ldapmodify utility to create a static group with the groupOfUniqueNames object class.

The following example creates two static groups in the ou=groups,dc=example,dc=com entry.

Prerequisites

  • The ou=groups,dc=example,dc=com parent entry exists.

Procedure

  • To create cn=simple_group group with the groupOfNames object class, run:

    # dsidm <instance_name> -b "dc=example,dc=com" group create --cn "simple_group"
    Successfully created simple_group
    Copy to Clipboard Toggle word wrap

    Note that the dsidm group create command creates groups only in the ou=group sub-entry. If you want to create a group in another entry, use ldapmodify utility.

  • To create cn=unique_members_group group with the groupOfUniqueNames object class, run:

    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    dn: cn=unique_members_group,ou=groups,dc=example,dc=com
    changetype: add
    objectClass: top
    objectClass: groupOfUniqueNames
    cn: unique_members_group
    description: A static group with unique members
    
    adding new entry "cn=unique_members_group,ou=groups,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap

Verification

  • Use dsidm group list command to list groups with the the groupOfNames object class:

    # dsidm --basedn "dc=example,dc=com" <instance_name> group list
    simple_group
    Copy to Clipboard Toggle word wrap
  • Use dsidm uniquegroup list command to list groups with the unique members:

    # dsidm --basedn "dc=example,dc=com" <instance_name> uniquegroup list
    unique_members_group
    Copy to Clipboard Toggle word wrap

You can use the web console to create a static group. The following example creates a static_group in the ou=groups,dc=example,dc=com parent entry.

Prerequisites

Procedure

  1. Navigate to LDAP Browser menu.
  2. Using the Tree or Table view, expand the parent entry ou=groups,dc=example,dc=com under which you want to create the group.
  3. Click the Options menu (⋮) and select New to open the wizard window.
  4. Select the Create a group and click Next.
  5. Select the Basic Group for the groupe type and click Next.
  6. Add the group name, group description, and select the membership attribute for the group:

    • member for the group with the groupOfNames object class.
    • uniquemember for the group with the groupOfUniqueNames object class.
  7. Click Next.
  8. Optional: Add members to the group and click Next.
  9. Verify the group information, click Create, and Finish.

Verification

  • Expand the newly created group entry in the suffix tree.

3.1.3. Adding members to static groups

You can add a member to a group by using the command line of the web console.

To add a member to a static group use the ldapmodify utility.

Prerequisites

  • The group entry exists.
  • The users entry exist.

Procedure

  • To add a member to a static group with the groupOfNames object class, add the user distinguished name (DN) as the value to the member attribute of the group entry:

    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    dn: cn=simple_group,ou=groups,dc=example,dc=com
    changetype: modify
    add: member
    member: uid=jsmith,ou=people,dc=example,dc=com
    
    modifying entry "cn=simple_group,ou=groups,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap

    The command adds the uid=jsmith user to the cn=simple_group group.

  • To add a member to a static group with the groupOfUniqueNames object class, add the user distinguished name (DN) as the value to the uniqueMember attribute of the group entry:

    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    dn: cn=unique_members_group,ou=groups,dc=example,dc=com
    changetype: modify
    add: uniqueMember
    uniqueMember: uid=ajonson,ou=people,dc=example,dc=com
    
    modifying entry "cn=unique_members_group,ou=groups,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap

    The command adds the uid=ajonson user to the cn=unique_members_group group.

Verification

  • List the members of the group:

    # ldapsearch -xLL -D "cn=Directory Manager" -W -b dc=example,dc=com "(cn=simple_group)"
    
    dn: cn=simple_group,ou=Groups,dc=example,dc=com
    objectClass: top
    objectClass: groupOfNames
    objectClass: nsMemberOf
    cn: simple_group
    member: uid=jsmith,ou=people,dc=example,dc=com
    member: uid=mtomson,ou=people,dc=example,dc=com
    Copy to Clipboard Toggle word wrap

You can add a member to a static group in the web console by using LDAP Browser.

Prerequisites

Procedure

  1. Navigate to LDAP Browser menu.
  2. Using the Tree or Table view, expand the group entry to which you want to add the member. For example. you want to add a member to cn=unique_members_group,ou=groups,dc=example,dc=com.
  3. Click the Options menu (⋮) and select Edit to open the wizard window. The window displays the current members list.
  4. Select Find New Members tab.
  5. Type the part of the uid or cn attribute value of the member in the search bar and press Enter. The Available Members field displays the user distinguished names (DN) that you can add to the group.
  6. Select the member DN and move it to the Chosen Members field by click on the arrow (>).
  7. Click Add Member button.

Verification

  • Expand the cn=unique_members_group,ou=groups,dc=example,dc=com group entry and find the added user in the entry details.

Directory Server supports creating dynamic groups by using only the command line. Use the ldapmodify utility to create a dynamic group with the groupOfURLs and groupOfCertificates object classes.

The following example creates two dynamic groups in the ou=groups,dc=example,dc=com entry.

Prerequisites

  • The ou=groups,dc=example,dc=com parent entry exists.

Procedure

  • To create cn=example_dynamic_group group with the groupOfURLs object class, run:

    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    dn: cn=example_dynamic_group,ou=groups,dc=example,dc=com
    changetype: add
    objectClass: top
    objectClass: groupOfURLs
    cn: example_dynamic_group
    description: Example dynamic group for user entries
    memberURL: ldap:///dc=example,dc=com??sub?(&(objectclass=person)(cn=*sen))
    
    adding new entry "cn=example_dynamic_group,ou=groups,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap

    The command creates a dynamic group that filters members with the person object class and the sen substring in the right part of the common name (cn) value.

  • To create cn=example_certificates_group group with the groupOfCertificates object class, run:

    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    dn: cn=example_certificates_group,ou=groups,dc=example,dc=com
    changetype: add
    objectClass: top
    objectClass: groupOfCertificates
    cn: example_certificates_group
    description: Example dynamic group for certificate entries
    memberCertificateDescription: {ou=people, l=USA, dc=example, dc=com}
    
    adding new entry "cn=example_certificates_group,ou=groups,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap

    The command creates a dynamic group that filters members whose certificate subject DNs contain ou=people,l=USA,dc=example,dc=com.

Verification

  • Search for the newly created group with the groupOfURLs object class:

    # ldapsearch -xLLL -D "cn=Directory Manager" -W -H ldap://server.example.com -b "dc=example,dc=com" "objectClass=groupOfURLs" 1.1 
    
    dn: cn=example_dynamic_group,ou=groups,dc=example,dc=com
    Copy to Clipboard Toggle word wrap
  • Search for the newly created group with the groupOfCertificates object class:

    # ldapsearch -xLLL -D "cn=Directory Manager" -W -H ldap://server.example.com -b "dc=example,dc=com" "objectClass=groupOfCertificates" 1.1 
    
    dn: cn=example_certificates_group,ou=groups,dc=example,dc=com
    Copy to Clipboard Toggle word wrap

3.1.5. Listing group membership in user entries

A group defines entries that belong to this group by using the membership attribute. It is easy to look at the group and find its members. For example, a static group with the groupOfNames object class stores distinguished names (DNs) of its members as values of the member attribute. However, you cannot quickly find out what groups a single user belongs to. With groups, a user entry does not contain anything that indicates the user memberships, unlike with roles.

To solve this problem, you can use the MemberOf plug-in. The MemberOf plug-in analyzes the membership attribute in a group entry and automatically writes the memberOf attribute in the user entry that points to the group. By default, the plug-in checks the member attribute in the groups, however, you can use several attributes to support different group types.

When you add or delete a member of a group, the plug-in updates the memberOf attributes in the user entries. With the MemberOf plug-in, you can do a simple search against a specific user entry to find all groups that the user is a member of. The MemberOf Plug-in shows direct and indirect memberships for all groups.

Important

The MemberOf plug-in manages membership attributes only for static groups.

When using the MemberOf plug-in, consider the following:

  • The MemberOf plug-in in a replication topology

    In a replication topology, you can manage the MemberOf plug-in in two ways:

    • Enable the MemberOf plug-in on all supplier and consumer servers in the topology. In this case, you must exclude the memberOf attribute of user entries from replication in all replication agreements.

      For details about about excluding attributes, see Managing attributes within fractional replication.

    • Enable the MemberOf plug-in only on all supplier servers in the topology. To do this:

      • You must disable replication of the memberOf attribute to all write-enabled suppliers in the replication agreement.

        For details about excluding attributes, see Managing attributes within fractional replication.

      • You must enable replication of the memberOf attribute to all consumer replicas in their replication agreement.
      • You must disable the MemberOf plug-in on consumer replicas.
  • The MemberOf plug-in with distributed databases

    As described in Configuring directory databases, you can store sub-trees of your directory in separate databases. By default, the MemberOf plug-in only updates user entries that are stored within the same database as the group. To update users across all databases, you must set the memberOfAllBackends parameter to on. For more details about setting the memberOfAllBackends parameter, see Configuring the MemberOf plug-in on each server using the web console.

By default, the MemberOf plug-in adds the nsMemberOf object class to user entries to provide the memberOf attribute. The nsMemberOf object class is sufficient for the plug-in to work correctly.

Alternatively, you can create user entries that contain the inetUser,inetAdmin, inetOrgPerson object class. These object classes support the memberOf attribute.

To configure nested groups, the group must use the extensibleObject object class.

Note

If directory entries do not contain an object class that supports required attributes operations fail with the following error:

LDAP: error code 65 - Object Class Violation
Copy to Clipboard Toggle word wrap
3.1.5.3. The MemberOf plug-in syntax

When configuring the MemberOf plug-in, you set the main two attributes:

  • memberOfGroupAttr. Defines which membership attribute to poll from the group entry. The memberOfGroupAttr attribute is multi-valued. Therefore, the plug-in can manage multiple types of groups. By default, the plug-in polls the member attribute.
  • memberOfAttr. Defines which membership attribute to create and manage in the member’s user entry. By default, the plug-in adds the memberOf attribute to the user entry.

In addition, the plug-in syntax provides the plug-in path, function to identify the MemberOf plug-in, the plug-in state, and other configuration parameters.

The following example shows the default MemberOf plug-in entry configuration:

dn: cn=MemberOf Plugin,cn=plugins,cn=config
cn: MemberOf Plugin
memberofallbackends: off
memberofattr: memberOf
memberofentryscope: dc=example,dc=com
memberofgroupattr: member
memberofskipnested: off
nsslapd-plugin-depends-on-type: database
nsslapd-pluginDescription: memberof plugin
nsslapd-pluginEnabled: off
nsslapd-pluginId: memberof
nsslapd-pluginInitfunc: memberof_postop_init
nsslapd-pluginPath: libmemberof-plugin
nsslapd-pluginType: betxnpostoperation
nsslapd-pluginVendor: 389 Project
nsslapd-pluginVersion: 2.4.5
objectClass: top
objectClass: nsSlapdPlugin
objectClass: extensibleObject
Copy to Clipboard Toggle word wrap

For details about the parameters in the example and other parameters you can set, see MemberOf plug-in section in the "Configuration and schema reference" documentation.

3.1.5.4. Enabling the MemberOf plug-in

You can enable the MemberOf plug-in by using the command line or the web console.

Use the dsconf utility to enable the MemberOf plug-in.

Procedure

  1. Enable the plug-in:

    # dsconf <instance_name> plugin memberof enable
    Copy to Clipboard Toggle word wrap
  2. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap

Verification

  • View the plug-in configuration details:

    # dsconf <instance_name> plugin memberof show
    
    dn: cn=MemberOf Plugin,cn=plugins,cn=config
    ...
    nsslapd-pluginEnabled: on
    ...
    Copy to Clipboard Toggle word wrap

You can use the web console to enable the MemberOf plug-in.

Prerequisites

Procedure

  1. Navigate to the Plugins menu.
  2. Select the MemberOf plug-in in the list of plug-ins.
  3. Change the status to ON to enable the plug-in.
  4. Restart the instance. For instructions for restarting the instance, see Starting and stopping a Directory Server instance by using the web console.

If you do not want to replicate the configuration of the MemberOf plug-in, configure the plug-in manually on each server by using the command line or the web console.

By default, the MemberOf plug-in reads the member membership attribute from the group entries and adds the memberOf attribute to the user entries. However, you can configure the plug-in to read other membership attribute from the group, add another attribute to the user entry, skip nested groups, work on all databases and other settings.

For example, you want the MemberOf plug-in to do the following:

  • Read uniqueMember attribute from group entries to identify membership.
  • Skip nested groups.
  • Search for user entries in all databases.

Prerequisites

Procedure

  1. Optionally: Display the MemberOf plug-in configuration to see which membership attribute the plug-in currently reads from groups entries:

    # dsconf <instance_name> plugin memberof show
    
    ...
    memberofgroupattr: member
    ...
    Copy to Clipboard Toggle word wrap

    The plug-in currently reads the member attribute from the group entry to retrieve members.

  2. Set the uniqueMember attribute as the value to the memberOfGroupAttr parameter in the plug-in configuration:

    # dsconf <instance_name> plugin memberof set --groupattr uniqueMember
    Copy to Clipboard Toggle word wrap

    The memberOfGroupAttr parameter is multi-valued and you can set several values by passing them all to the --groupattr parameter. For example:

    # dsconf <instance_name> plugin memberof set --groupattr member uniqueMember
    Copy to Clipboard Toggle word wrap
  3. In an environment that uses distributed databases, configure the plug-in to search user entries in all databases instead of only the local database:

    # dsconf <instance_name> plugin memberof set --allbackends on
    Copy to Clipboard Toggle word wrap

    The command sets the memberOfAllBackends parameter.

  4. Configure the plug-in to skip nested groups:

    # dsconf <instance_name> plugin memberof set --skipnested on
    Copy to Clipboard Toggle word wrap

    The command sets the memberOfSkipNested parameter.

  5. Optional: By default, the plug-in adds nsMemberOf object class to user entries if the user entries do not have the object class that allows the memberOf attribute. To configure the plug-in to add the inetUser object class to the user entries instead of nsMemberOf, run:

    # dsconf <instance_name> plugin memberof set --autoaddoc inetUser
    Copy to Clipboard Toggle word wrap

    The command sets the memberOfAutoAddOC parameter.

  6. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap

Verification

  • View the MemberOf plug-in configuration:

    # dsconf <instance_name> plugin memberof show
    dn: cn=MemberOf Plugin,cn=plugins,cn=config
    cn: MemberOf Plugin
    memberofallbackends: on
    memberofattr: memberOf
    memberofautoaddoc: inetuser
    memberofentryscope: dc=example,dc=com
    memberofgroupattr: uniqueMember
    memberofskipnested: on
    ...
    nsslapd-pluginEnabled: on
    ...
    Copy to Clipboard Toggle word wrap

By default, the MemberOf plug-in reads the member membership attribute from the group entries and adds the memberOf attribute to the user entries. However, you can configure the plug-in to read other membership attribute from the group, skip nested groups, work on all databases and other settings by using the web console.

For example, you want the MemberOf plug-in to do the following:

  • Read member and uniqueMember attributes from group entries to identify membership.
  • Set the scope of the plug-in to dc=example,dc=com.
  • Skip nested groups.
  • Search for user entries in all databases.

Prerequisites

Procedure

  1. Navigate to LDAP Browser menu.
  2. Select the MemberOf plug-in from the plug-ins list.
  3. Add the uniqueMember attribute to the Group Attribute field.
  4. Set the scope of the plug-in to dc=example,dc=com:

    1. Enter dc=example,dc=com to the Subtree Scope field.
    2. Click Create "dc=example,dc=com" in the drop-down list.

      security configuring the memberof 1

  5. Optional: Set a subtree to exclude. For example, you do not want the plug-in to work on the ou=private,dc=example,dc=com subtree:

    1. Enter ou=private,dc=example,dc=com to the Exclude Subtree field.
    2. Click Create "ou=private,dc=example,dc=com" in the drop-down list.
  6. Check All Backends to configure the plug-in to search user entries in all databases instead of only the local database.
  7. Check Skip Nested to configure the plug-in to skip nested groups.
  8. Click Save Config.

By default, each server stores its own configuration of the MemberOf plug-in. With the shared configuration of the plug-in, you can use the same settings without configuring the plug-in manually on each server. Directory Server stores the shared configuration outside of the cn=config suffix and replicates it.

For example, you want to store the plug-in shared configuration in the cn=shared_MemberOf_config,dc=example,dc=com entry.

Important

After enabling the shared configuration, the plug-in ignores all parameters set in the cn=MemberOf Plugin,cn=plugins,cn=config plug-in entry and only uses settings from the shared configuration entry.

Prerequisites

Procedure

  1. Enable the shared configuration entry on a server:

    # dsconf <instance_name> plugin memberof config-entry add "cn=shared_MemberOf_config,dc=example,dc=com" --attr memberOf --groupattr member
    
    Successfully created the cn=shared_MemberOf_config,dc=example,dc=com
    MemberOf attribute nsslapd-pluginConfigArea (config-entry) was set in the main plugin config
    Copy to Clipboard Toggle word wrap

    The command sets nsslapd-pluginConfigArea attribute value to cn=shared_MemberOf_config,dc=example,dc=com.

  2. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap
  3. Enable the shared configuration on other servers in the replication topology that should use the shared configuration:

    1. Set the distinguished name (DN) of the configuration entry that stores the shared configuration:

      # dsconf -D "cn=Directory Manager" ldap://server2.example.com plugin memberof set --config-entry cn=shared_MemberOf_config,dc=example,dc=com
      Copy to Clipboard Toggle word wrap
    2. Restart the instance:

      # dsctl <instance_name> restart
      Copy to Clipboard Toggle word wrap

Verification

  1. Check that the MemberOf plug-in uses the shared configuration:

    # dsconf <instance_name> plugin memberof show
    
    dn: cn=MemberOf Plugin,cn=plugins,cn=config
    cn: MemberOf Plugin
    ...
    nsslapd-pluginConfigArea: cn=shared_MemberOf_config,dc=example,dc=com
    ...
    Copy to Clipboard Toggle word wrap
  2. Optional: Check the shared configuration settings:

    # dsconf <instance_name> memberof config-entry show "cn=shared_MemberOf_config,dc=example,dc=com"
    
    dn: cn=shared_MemberOf_config,dc=example,dc=com
    cn: shared_MemberOf_config
    memberofattr: memberOf
    memberofgroupattr: member
    objectClass: top
    objectClass: extensibleObject
    Copy to Clipboard Toggle word wrap
3.1.5.7. Setting the scope of the MemberOf plug-in

If you configured several backends or multiple-nested suffixes, you can use the memberOfEntryScope and memberOfEntryScopeExcludeSubtree parameters to set what suffixes the MemberOf plug-in works on.

If you add a user to a group, the MemberOf plug-in only adds the memberOf attribute to the group if both the user and the group are in the plug-in’s scope.

For example, the following procedure configures the MemberOf plug-in to work on all entries in dc=example,dc=com, but to exclude entries in ou=private,dc=example,dc=com.

Prerequisites

Procedure

  1. Set the scope value for the MemberOf plug-in to dc=example,dc=com:

    # dsconf <instance_name> plugin memberof set --scope "dc=example,dc=com"
    Copy to Clipboard Toggle word wrap
  2. Exclude entries in ou=private,dc=example,dc=com:

    # dsconf <instance_name> plugin memberof set --exclude "ou=private,dc=example,com"
    Copy to Clipboard Toggle word wrap

    If you moved a user entry out of the scope by using the --scope DN parameter:

    • The MemberOf plug-in updates the membership attribute, such as member, in the group entry to remove the user DN value.
    • The MemberOf plug-in updates the memberOf attribute in the user entry to remove the group DN value.

      Note

      The value set in the --exclude parameter has a higher priority than values set in --scope. If the scopes set in both parameters overlap, the MemberOf plug-in only works on the non-overlapping directory entries.

For details about setting the scope for the MemberOf plug-in, see Configuring the MemberOf plug-in on each server using the web console.

The MemberOf plug-in automatically manages memberOf attributes in group member entries based on the configuration in the group entry. However, you need to run the fixup task in the following situations to avoid inconsistency between the memberOf configuration that the server plug-in manages and the actual memberships defined in user entries:

  • You added group members to a group before you enabled the MemberOf plug-in.
  • You manually edited the memberOf attribute in a user entry.
  • You imported or replicated new user entries to the server that already have the memberOf attribute.

Note that you can run the fixup tasks only locally. In a replication environment, Directory Server updates the memberOf attribute for entries on other servers after Directory Server replicates the updated entries.

Prerequisites

Procedure

  • For example, to update the memberOf values in dc=example,dc=com entry and subentries, run:

    # dsconf <instance_name> plugin memberof fixup "dc=example,dc=com"
    Attempting to add task entry...
    Successfully added task entry
    Copy to Clipboard Toggle word wrap

    By default, the fixup task updates memberOf values in all entries that contain the inetUser, inetAdmin, or nsMemberOf object class.

    If you want the fixup task to also work on entries that contain other object classes, use -f filter option:

    # dsconf <instance_name> plugin memberof fixup -f "(|(objectclass=inetuser)(objectclass=inetadmin)(objectclass=nsmemberof)(objectclass=nsmemberof)(objectclass=inetOrgPerson))" "dc=example,dc=com"
    Copy to Clipboard Toggle word wrap

    This fixup task updates memberOf values in all entries that contain the inetUser, inetAdmin, nsMemberOf, or inetOrgPerson object class.

3.2. Using roles in Directory Server

You can group Directory Server entries by using roles. Roles behave as both a static and a dynamic group. Roles are easier to use than groups because they are more flexible in their implementation. For example, an application can get the list of roles to which an entry belongs by querying the entry itself rather than selecting a group and browsing the members list of several groups.

You can manage roles by using the command line or the web console.

3.2.1. Roles in Directory Server

A role behaves as both a static and a dynamic group, similarly to a hybrid group:

  • With a group, Directory Server adds entries to the group entry as members.
  • With a role, Directory Server adds the role attribute to the entry and then uses this attribute to automatically identify members in the role entry.

Role members are entries that possess the role. You can specify members of the role explicitly or dynamically depending on the role type. Directory Server supports the following types of roles:

  • Managed roles

    Managed roles have an explicit list of members. You can use managed roles to perform the same tasks that you perform with static groups.

  • Filtered roles

    You can filter the role members by using filtered roles, similarly to filtering with dynamic groups. Directory Server assigns entries to a filtered role depending on whether the entry possesses a specific attribute defined in the role.

  • Nested roles

    Nested roles can contain managed and filtered roles.

When you create a role, determine if users can add or remove themselves from the role. For more details, see Section 3.2.2, “Using roles securely in Directory Server”.

Note

Evaluating roles is more resource-intensive for the Directory Server than evaluating groups because the server does the work for the client application. With roles, the client application can check role membership by searching for the nsRole attribute. The nsRole attribute is a computed attribute that identifies which roles an entry belongs to. Directory Server does not store the nsRole attribute. From the client application point of view, the method for checking membership is uniform and is performed on the server side.

For considerations for using roles in Directory Server, see Deciding between groups and roles in the Planning and designing Directory Server documentation.

3.2.2. Using roles securely in Directory Server

When creating a new role, consider if users can easily add or remove themselves from a role. For example, you can allow users of the Mountain Biking interest group role to add or remove themselves easily. However, you must not allow users who are assigned the Marketing role to add or remove themselves from the role.

One potential security risk is inactivating user accounts by inactivating roles. Inactive roles have special access control instructions (ACIs) defined for their suffix. If an administrator allows users to add and remove themselves from roles freely, these users can remove themselves from an inactive role to unlock their accounts.

For example, a user is assigned a managed role. When Directory Server locks this managed role by using account inactivation, the user can not bind to the server because Directory Server computes the nsAccountLock attribute as true for that user. However, if the user was already bound to Directory Server and now is locked through the managed role, the user can remove the nsRoleDN attribute from his entry and unlock himself if no restricting ACIs are specified.

To prevent users from removing the nsRoleDN attribute, use the following ACIs depending on the type of role:

  • Managed roles. For entries that are members of a managed role, use the following ACI:

    aci: (targetattr="nsRoleDN")
    (targattrfilters= add=nsRoleDN:(!(nsRoleDN=cn=AdministratorRole,dc=example,dc=com)), del=nsRoleDN:(!(nsRoleDN=cn=nsManagedDisabledRole,dc=example,dc=com)))
    (version3.0;acl "allow mod of nsRoleDN by self but not to critical values"; allow(write) userdn=ldap:///self;)
    Copy to Clipboard Toggle word wrap
  • Filtered roles. Protect attributes that are part of the filter (nsRoleFilter). Do not allow a user to add, delete, or modify the attribute that the filtered role uses. If Directory Server computes the value of the filter attribute, then you must protect all attributes that can modify this filter attribute value.
  • Nested roles. A nested role can contain filtered and managed roles. Thus, you must restrict modify operations in ACIs for each attribute of the roles that the nested role contains.

You can view, create, and delete roles by using the command line.

Managed roles are roles that have an explicit enumerated list of members. You can use the ldapmodify utility to create a managed role. The following example creates a managed role for a marketing team.

Prerequisites

  • The ou=people,dc=example,dc=com parent entry exists in Directory Server.
  • The cn=Bob Jones,ou=people,dc=example,dc=com user entry exists in Directory Server.

Procedure

  1. Create the cn=Marketing managed role entry by using the ldapmodify command with the -a option:

    # ldapmodify -a -D "cn=Directory Manager" -W -H ldap://server.example.com -x << EOF
    dn: cn=Marketing,ou=people,dc=example,dc=com
    objectclass: top
    objectclass: LDAPsubentry
    objectclass: nsRoleDefinition
    objectclass: nsSimpleRoleDefinition
    objectclass: nsManagedRoleDefinition
    cn: Marketing
    description: managed role for the marketing team
    EOF
    Copy to Clipboard Toggle word wrap

    The managed role entry must contain the following object classes:

    • LDAPsubentry
    • nsRoleDefinition
    • nsSimpleRoleDefinition
    • nsManagedRoleDefinition
  2. Assign the cn=Marketing,ou=people,dc=example,dc=com managed role to the cn=Bob Jones,ou=people,dc=example,dc=com user entry by adding the nsRoleDN attribute to this user entry:

    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x << EOF
    dn: cn=Bob Jones,ou=people,dc=example,dc=com
    changetype: modify
    add: nsRoleDN
    nsRoleDN: cn=Marketing,ou=people,dc=example,dc=com
    EOF
    
    modifying entry "cn=Bob Jones,ou=people,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap
  3. Optional: Configure the equality index for the nsRoleDN attribute in the userRoot database to avoid unindexed searches:

    # dsconf <instance_name> backend index add --index-type eq --attr nsroleDN --reindex userRoot
    Copy to Clipboard Toggle word wrap

Verification

  • List user entries that now belong to the cn=Marketing,ou=people,dc=example,dc=com managed role:

    # ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -x -b "dc=example,dc=com" "(nsRole=cn=Marketing,ou=people,dc=example,dc=com)" dn 
    
    dn: cn=Bob Jones,ou=people,dc=example,dc=com
    
    dn: cn=Tom Devis,ou=people,dc=example,dc=com
    Copy to Clipboard Toggle word wrap

Directory Server assigns entries to a filtered role if the entries have a specific attribute defined in the role. The role definition specifies the nsRoleFilter LDAP filter. Entries that match the filter are members of the role.

You can use ldapmodify utility to create a filtered role. The following example creates a filtered role for sales department managers.

Prerequisites

  • The ou=people,dc=example,dc=com parent entry exists in Directory Server.

Procedure

  1. Create the cn=SalesManagerFilter filtered role entry by using the ldapmodify command with the -a option:

    # ldapmodify -a -D "cn=Directory Manager" -W -H ldap://server.example.com -x << EOF
    dn: cn=SalesManagerFilter,ou=people,dc=example,dc=com
    changetype: add
    objectclass: top
    objectclass: LDAPsubentry
    objectclass: nsRoleDefinition
    objectclass: nsComplexRoleDefinition
    objectclass: nsFilteredRoleDefinition
    cn: SalesManagerFilter
    nsRoleFilter: o=sales managers
    Description: filtered role for sales managers
    EOF
    Copy to Clipboard Toggle word wrap

    The cn=SalesManagerFilter filtered role entry has the o=sales managers filter for the role. All user entries that have the o attribute with the value of sales managers are members of the filtered role.

    Example of the user entry that is now a member of the filtered role:

    dn: cn=Pat Smith,ou=people,dc=example,dc=com
    objectclass: person
    cn: Pat
    sn: Smith
    userPassword: password
    o: sales managers
    Copy to Clipboard Toggle word wrap

    The filtered role entry must have the following object classes:

    • LDAPsubentry
    • nsRoleDefinition
    • nsComplexRoleDefinition
    • nsFilteredRoleDefinition
  2. Optional: Configure the equality index for the attribute that you use in the nsRoleFilter role filter to avoid unindexed searches. In the given example, the role uses o=sales managers as the filter. Therefore, index the o attribute to improve the search performance:

    # dsconf <instance_name> backend index add --index-type eq --attr o --reindex userRoot
    Copy to Clipboard Toggle word wrap

Verification

  • List user entries that now belong to the cn=SalesManagerFilter,ou=people,dc=example,dc=com filtered role:

    # ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -x -b "dc=example,dc=com" "(nsRole=cn=SalesManagerFilter,ou=people,dc=example,dc=com)" dn 
    
    dn: cn=Jess Mor,ou=people,dc=example,dc=com
    
    dn: cn=Pat Smith,ou=people,dc=example,dc=com
    Copy to Clipboard Toggle word wrap

Nested roles can contain managed and filtered roles. A nested role entry requires the nsRoleDN attribute to identify the roles to nest.

You can use ldapmodify utility to create a nested role. The following example creates a nested role that contains the managed and the filtered roles you created in Creating a managed role in Directory Server and Creating a filtered role in Directory Server.

Prerequisites

  • The ou=people,dc=example,dc=com parent entry exists in Directory Server.

Procedure

  1. Create the cn=MarketingSales nested role entry that contains the cn=SalesManagerFilter filtered role and the cn=Marketing managed role by using the ldapmodify command with the -a option:

    # ldapmodify -a -D "cn=Directory Manager" -W -H ldap://server.example.com -x << EOF
    dn: cn=MarketingSales,ou=people,dc=example,dc=com
    objectclass: top
    objectclass: LDAPsubentry
    objectclass: nsRoleDefinition
    objectclass: nsComplexRoleDefinition
    objectclass: nsNestedRoleDefinition
    cn: MarketingSales
    nsRoleDN: cn=SalesManagerFilter,ou=people,dc=example,dc=com
    nsRoleDN: cn=Marketing,ou=people,dc=example,dc=com
    EOF
    Copy to Clipboard Toggle word wrap

    Optionally, the role can have the description attribute.

    The nested role entry must have the following object classes:

    • LDAPsubentry
    • nsRoleDefinition
    • nsComplexRoleDefinition
    • nsNestedRoleDefinition

Verification

  • List user entries that now belong to the cn=MarketingSales nested role:

    # ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -x -b "dc=example,dc=com" "(nsRole=cn=MarketingSales,ou=people,dc=example,dc=com)" dn 
    
    dn: cn=Bob Jones,ou=people,dc=example,dc=com
    dn: cn=Pat Smith,ou=people,dc=example,dc=com
    dn: cn=Jess Mor,ou=people,dc=example,dc=com
    dn: cn=Tom Devis,ou=people,dc=example,dc=com
    Copy to Clipboard Toggle word wrap
3.2.3.4. Viewing roles for an entry

To view roles for an entry, use the ldapsearch command with explicitly specified nsRole virtual attribute.

Prerequisites

  • Roles entry exists.
  • You assigned roles to the uid=user_name user entry.

Procedure

  • Search for the uid=user_name entry with specified nsRole virtual attribute:

    # ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -b "dc=example,dc=com" -s sub -x "(uid=user_name)" nsRole
    
    dn: uid=user_name,ou=people,dc=example,dc=com
    ...
    nsRole: cn=Role for Managers,dc=example,dc=com
    nsRole: cn=Role for Accounting,dc=example,dc=com
    Copy to Clipboard Toggle word wrap

    The command retrieves all roles which the uid=user_name user is a member of.

3.2.3.5. Deleting roles in Directory Server

To delete a role in Directory Server, you can use ldapmodify command.

The following is an example of deleting the cn=Marketing managed role from Directory Server.

Procedure

  • To delete the cn=Marketing managed role entry, enter:

    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x << EOF
    dn: cn=Marketing,ou=People,dc=example,dc=com
    changetype: delete
    EOF
    
    deleting entry "cn=Marketing,ou=People,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap
    Note

    When you delete a role, Directory Server deletes only the role entry and does not delete the nsRoleDN attribute for each role member. To delete the nsRoleDN attribute for each role member, enable the Referential Integrity plug-in and configure this plug-in to manage the nsRoleDN attribute.

    For more information about the Referential Integrity plug-in, see Using Referential Integrity to maintain relationships between entries.

You can view, create, and delete roles by using LDAP browser in the web console.

3.2.4.1. Creating a role in the LDAP Browser

You can create a role for a Red Hat Directory Server entry by using the LDAP Browser wizard in the web console.

Prerequisites

  • Access to the web console.
  • A parent entry exists in Directory Server.

Procedure

  1. Log in to the web console and click Red Hat Directory Server.
  2. After the web console loads the Red Hat Directory Server interface, open the LDAP Browser.
  3. Select an LDAP entry and open the Options menu (⋮).
  4. From the drop-down menu select New and click Create a new role.
  5. Follow the steps in the wizard and click the Next button after you complete each step.
  6. To create the role, review the role settings in the Create Role step and click the Create button. You can click the Back button to modify the role settings or click the Cancel button to cancel the role creation.
  7. To close the wizard window, click the Finish button.

Verification

  • Expand the LDAP entry and verify the new role appears among the entry parameters.
3.2.4.2. Deleting a role in the LDAP browser

You can delete the role from the Red Hat Directory Server entry by using the LDAP Browser in the web console.

Prerequisites

  • Access to the web console.
  • A parent entry exists in Directory Server.

Procedure

  1. Log in to the web console and click Red Hat Directory Server.
  2. After the web console loads the Red Hat Directory Server interface, click LDAP browser.
  3. Expand the LDAP entry select the role which you want to delete.
  4. Open the Options menu (⋮) and select Delete.
  5. Verify the data about the role you want to delete and click the Next button until you reach the Deletion step.
  6. Toggle the switch to the Yes, I’m sure position and click the Delete button.
  7. To close the wizard window, click the Finish button.

Verification

  • Expand the LDAP entry and verify the role is no longer a part of the entry parameters.
3.2.4.3. Modifying a role in the LDAP browser

You can modify the role parameters for a Red Hat Directory Server entry by using the LDAP Browser in the web console.

Prerequisites

  • Access to the web console.
  • A parent entry exists in Directory Server.

Procedure

  1. Log in to the web console and click Red Hat Directory Server.
  2. After the web console loads the Red Hat Directory Server interface, click LDAP Browser.
  3. Expand the LDAP entry and select the role you are modifying.
  4. Click the Options menu (⋮) and select Edit to modify the parameters of the role or Rename to rename the role.
  5. In the wizard window modify the necessary parameters and click Next after each step until you observe the LDIF Statements step.
  6. Check the updated parameters and click Modify Entry or Change Entry Name.
  7. To close the wizard window, click the Finish button.

Verification

  • Expand the LDAP entry and verify the updated parameters are listed for the role.

3.3. Changing the Directory Manager password

The Directory Manager is the privileged database administrator, comparable to the root user in a Linux operating system. The Directory Manager entry and the corresponding password are set during the instance installation. As an administrator, you can change the Directory Manager password to use a different one.

You can set a new password for the Directory Manager using the dsconf command line utility or manually by setting the nsslapd-rootpw parameter.

Important

Set the password using an encrypted connection only. Using an unencrypted connection can expose the password to the network. If your server does not support encrypted connections, use the web console to update the Directory Manager password.

Procedure

  • Set the Directory Manager password using one of the following options:

    • To encrypt the password automatically:

      # dsconf <instance_name> config replace nsslapd-rootpw=password
      Copy to Clipboard Toggle word wrap

      Directory Server automatically encrypts the plain text value that you set in the nsslapd-rootpw parameter.

      Warning

      Do not use curly braces {} in the password. Directory Server stores the password in the {password-storage-scheme}hashed_password format. The server interprets characters in curly braces as the password storage scheme. If the string is an invalid storage scheme or if the password is not correctly hashed, the Directory Manager cannot connect to the server.

    • To encrypt the password manually:

      1. Generate a new password hash. For example:

        # pwdhash -D /etc/dirsrv/slapd-<instance_name> password
        {PBKDF2_SHA256}AAAgAMwPYIhEkQozTagoX6RGG5E7d6/6oOJ8TVty...
        Copy to Clipboard Toggle word wrap

        The password is encrypted using the password storage scheme set in the nsslapd-rootpwstoragescheme attribute of the Directory Server instance configuration.

      2. Using a STARTTLS connection, set the nsslapd-rootpw attribute to the value displayed in the previous step:

        # dsconf <instance_name> config replace nsslapd-rootpw="{PBKDF2_SHA256}AAAgAMwPYIhEkQozTagoX6RGG5E7d6/6oOJ8TVty..."
        Copy to Clipboard Toggle word wrap

You can set a new password for the Directory Manager using the web console.

Prerequisites

  • You are logged in to the instance in the web console.

Procedure

  1. Open the ServerServer SettingsDirectory Manager menu.
  2. Enter the new password into the Directory Manager Password and Confirm Password fields.
  3. Optional: Set a different password storage scheme.
  4. Click Save.

3.4. Resetting the Directory Manager password

The Directory Manager is the privileged database administrator, comparable to the root user in a Linux operating system. The Directory Manager password is set during the instance installation. If you lose the password, you can reset it to regain privileged access to the directory.

If you have the root access to the Directory Server instance, you can reset the password of the Directory Manager.

Procedure

  1. Generate a new password hash. For example:

    # pwdhash -D /etc/dirsrv/slapd-<instance_name> <new_password>
    {PBKDF2_SHA256}AAAgABU0bKhyjY53NcxY33ueoPjOUWtl4iyYN5uW...
    Copy to Clipboard Toggle word wrap

    Because you specified the path to the Directory Server instance configuration, the pwdhash generator automatically uses the password storage scheme set in the nsslapd-rootpwstoragescheme attribute to encrypt the new password.

  2. Stop the Directory Server instance:

    # dsctl <instance_name> stop
    Copy to Clipboard Toggle word wrap
  3. Edit the /etc/dirsrv/slapd-<instance_name>/dse.ldif file and set the nsslapd-rootpw attribute to the value displayed in the first step:

    nsslapd-rootpw: {PBKDF2_SHA256}AAAgABU0bKhyjY53NcxY33ueoPjOUWtl4iyYN5uW...
    Copy to Clipboard Toggle word wrap
  4. Start the Directory Server instance:

    # dsctl <instance_name> start
    Copy to Clipboard Toggle word wrap

3.5. Configuring password policies

A password policy minimizes the risks associated with using passwords by enforcing a certain level of security. For example, you can define a password policy to ensure that:

  • Users must change their passwords according to a schedule
  • Users must provide non-trivial passwords
  • The password syntax must meet certain complexity requirements

3.5.1. How password policies work

Directory Server supports fine-grained password policies, which work in an inverted pyramid, from general to specific. A global password policy is superseded by a subtree-level password policy, which is superseded by a user-level password policy.

You can define:

  • Global password policy, applied to the entire directory
  • Local password policy

    • Subtree-level policy, applied to a particular subtree
    • User-level policy, applied to a particular user

Password policies are not additive: only one password policy applies to an entry. For example, when you configure a particular attribute in the global or subtree-level password policy, but not in the user-level password policy, this attribute does not apply to the user. In this case, when the user attempts to log in, only the user-level policy is active.

Warning

When using a password administrator account or the Directory Manager (root DN) to set a password, you bypass the password policies. Do not use these accounts for regular user password management. Use them only to perform password administration tasks that require bypassing the password policies, such as adding a prehashed password, or purposefully overriding current password constraints for setting temporary passwords after a reset.

The complete password policy that applies to a user account consists of the following elements:

  • The type or level of password policy checks. This information indicates whether the server should check for and enforce a global password policy or local password policies.
  • Password add and modify information. The password information includes password syntax and password history details.
  • Bind information. The bind information includes the number of grace logins permitted, password aging attributes, and tracking bind failures.
Note

After establishing a password policy, you can protect user passwords from potential threats by configuring an account lockout policy. Account lockout protects against attempts to break into the directory by repeatedly guessing a user’s password.

By default, global password policy settings are disabled. You can configure the global password policy using the dsconf command line utility.

Procedure

  1. Display the current settings:

    # dsconf <instance_name> pwpolicy get
    Global Password Policy: cn=config
    ------------------------------------
    passwordstoragescheme: PBKDF2_SHA256
    passwordChange: on
    passwordMustChange: off
    passwordHistory: off
    passwordInHistory: 6
    ...
    Copy to Clipboard Toggle word wrap
  2. Adjust the password policy settings. For a full list of available settings, enter:

    # dsconf <instance_name> pwpolicy set --help
    Copy to Clipboard Toggle word wrap

    For example, to enable password syntax checking and set the minimum length of passwords to 12 characters, enter:

    # dsconf <instance_name> pwpolicy set --pwdchecksyntax on --pwdmintokenlen 12
    Copy to Clipboard Toggle word wrap
  3. Enable the the account lockout feature for the password policy:

    # dsconf <instance_name> pwpolicy set --pwdlockout on
    Copy to Clipboard Toggle word wrap

Next steps

By default, global password policy settings are disabled. You can configure the global password policy using the web console.

Prerequisites

  • You are logged in to the instance in the web console.

Procedure

  1. Open the DatabasePassword PoliciesGlobal Policy menu.
  2. Set the global password policy settings. You can set parameters in the following categories:

    • General settings, such as the password storage scheme
    • Password expiration settings, such as the time when a password expires
    • Account lockout settings, such as after how many failed login attempts an account should be locked
    • Password syntax settings, such as the minimum password length

      To display a tool tip and the corresponding attribute name in the cn=config entry for a parameter, hover the mouse cursor over the setting.

  3. Click Save.

Next steps

3.5.4. Local password policy entries

When you use the dsconf localpwp addsubtree or dsconf localpwp adduser commands, Directory Server automatically creates an entry to store the local password policy attributes.

For a subtree, the following entries are added:

Expand
Table 3.1. Local password policy entries for a subtree
Entry nameDescriptionContents

nsPwPolicyContainer

A container entry at the subtree level

Various password policy-related entries for the subtree and all its children

nsPwPolicyEntry

The actual password policy specification entry

All the password policy attributes that are specific to the subtree

nsPwTemplateEntry

The CoS Template Entry

The pwdpolicysubentry value pointing to the nsPwPolicyEntry entry

<CoS definition entry DN>

The CoS definition entry at the subtree level

CoS definition entry

Example 3.1. The nsPwPolicyContainer entry for a subtree ou=people,dc=example,dc=com

dn: cn=nsPwPolicyContainer,ou=people,dc=example,dc=com
objectClass: top
objectClass: nsContainer
cn: nsPwPolicyContainer
Copy to Clipboard Toggle word wrap

Example 3.2. The nsPwPolicyEntry entry for a subtree ou=people,dc=example,dc=com

dn: cn="cn=nsPwPolicyEntry,ou=people,dc=example,dc=com",
 cn=nsPwPolicyContainer,ou=people,dc=example,dc=com
objectclass: top
objectclass: extensibleObject
objectclass: ldapsubentry
objectclass: passwordpolicy
Copy to Clipboard Toggle word wrap

Example 3.3. The nsPwTemplateEntry entry for a subtree ou=people,dc=example,dc=com

dn: cn="cn=nsPwTemplateEntry,ou=people,dc=example,dc=com",
 cn=nsPwPolicyContainer,ou=people,dc=example,dc=com
objectclass: top
objectclass: extensibleObject
objectclass: costemplate
objectclass: ldapsubentry
cosPriority: 1
pwdpolicysubentry: cn="cn=nsPwPolicyEntry,ou=people,dc=example,dc=com",
     cn=nsPwPolicyContainer,ou=people,dc=example,dc=com
Copy to Clipboard Toggle word wrap

Example 3.4. The CoS specification entry for a subtree ou=people,dc=example,dc=com

dn: cn=newpwdpolicy_cos,ou=people,dc=example,dc=com
objectclass: top
objectclass: LDAPsubentry
objectclass: cosSuperDefinition
objectclass: cosPointerDefinition
cosTemplateDn: cn=cn=nsPwTemplateEntry\,ou=people\,dc=example,dc=com,
 cn=nsPwPolicyContainer,ou=people,dc=example,dc=com
cosAttribute: pwdpolicysubentry default operational
Copy to Clipboard Toggle word wrap

For a user, the following entries are added:

Expand
Table 3.2. Local password policy entries for a user
Entry nameDescriptionContents

nsPwPolicyContainer

A container entry at the parent level

Various password policy-related entries for the user and all its children

nsPwPolicyEntry

The actual password policy specification entry

All the password policy attributes that are specific to the user

Example 3.5. The nsPwPolicyContainer entry for a user uid=user_name,ou=people,dc=example,dc=com

dn: cn=nsPwPolicyContainer,ou=people,dc=example,dc=com
objectClass: top
objectClass: nsContainer
cn: nsPwPolicyContainer
Copy to Clipboard Toggle word wrap

Example 3.6. The nsPwPolicyEntry entry for a user uid=user_name,ou=people,dc=example,dc=com

dn: cn="cn=nsPwPolicyEntry,uid=user_name,ou=people,dc=example,dc=com",
 cn=nsPwPolicyContainer,ou=people,dc=example,dc=com
objectclass: top
objectclass: extensibleObject
objectclass: ldapsubentry
objectclass: passwordpolicy
Copy to Clipboard Toggle word wrap

In contrast to a global password policy, which defines settings for the entire directory, a local password policy is a policy for a specific user or subtree. Currently, you can only set up a local password policy using the command line.

Prerequisites

  • User or subtree entries that you want to create the policy for already exist in the directory.

Procedure

  1. Verify if a local password policy already exists for the subtree or user entry. For example:

    # dsconf <instance_name> localpwp get "ou=People,dc=example,dc=com"
    Enter password for cn=Directory Manager on ldap://server.example.com:
    Error: No password policy was found for this entry
    Copy to Clipboard Toggle word wrap

    If no local policy exists, create one:

    • To create a subtree password policy:

      # dsconf <instance_name> localpwp addsubtree "ou=People,dc=example,dc=com"
      Copy to Clipboard Toggle word wrap
    • To create a user password policy:

      # dsconf <instance_name> localpwp adduser "uid=user_name,ou=People,dc=example,dc=com"
      Copy to Clipboard Toggle word wrap
  2. Set local policy attributes. For a full list of available settings, enter:

    # dsconf <instance_name> localpwp set --help
    Copy to Clipboard Toggle word wrap

    For example, to enable password expiration and set the maximum password age to 14 days (1209600 seconds):

    • On a subtree password policy:

      # dsconf <instance_name> localpwp set --pwdexpire on --pwdmaxage 1209600 "ou=People,dc=example,dc=com"
      Copy to Clipboard Toggle word wrap
    • On a user password policy:

      # dsconf <instance_name> localpwp set --pwdexpire on --pwdmaxage 1209600 "uid=user_name,ou=People,dc=example,dc=com"
      Copy to Clipboard Toggle word wrap

When you create a new local policy, the nsslapd-pwpolicy-local parameter in the cn=config entry is automatically set to on. If the local password policy should not be enabled, you can disable it manually using the command line.

Procedure

  • Disable all local policies or remove a particular local policy:

    • To disable all local password policies:

      # dsconf <instance_name> pwpolicy set --pwdlocal off
      Copy to Clipboard Toggle word wrap
    • To remove a single existing subtree password policy:

      # dsconf <instance_name> localpwp remove "ou=People,dc=example,dc=com"
      Copy to Clipboard Toggle word wrap
    • To remove a single existing user password policy:

      # dsconf <instance_name> localpwp remove "uid=user_name,ou=People,dc=example,dc=com"
      Copy to Clipboard Toggle word wrap

3.5.7. Tracking password change time

Password change operation is a typical modify operation on an entry, and Directory Server records the update time to the lastModified operational attribute. However, to make it easier to update passwords in Active Directory synchronization or to connect with other LDAP clients, you can record the time of the last password change separately.

Configure the passwordTrackUpdateTime parameter within a global or local password policy to record the time of the last password change to the pwdUpdateTime operation attribute of the user entry.

Prerequisites

  • You have root permissions.

Procedure

  1. Set the passwordTrackUpdateTime parameter to on:

    • For the global policy, run:

      # dsconf <instance_name> pwpolicy set --pwdtrack on
      Copy to Clipboard Toggle word wrap
    • For the subtree or user-level policy, run:

      # dsconf <instance_name> localpwp set "ou=people,dc=example,dc=com" --pwdtrack on
      Copy to Clipboard Toggle word wrap

Verification

  • Display the current settings of the policy:

    • For the global policy, run:

      # dsconf <instance_name> pwpolicy get
      
      Global Password Policy: cn=config
      ------------------------------------
      nsslapd-pwpolicy-local: on
      passwordstoragescheme: PBKDF2-SHA512
      ...
      passwordtrackupdatetime: on
      ...
      Copy to Clipboard Toggle word wrap
    • For the subtree or user-level policy, run:

      # dsconf <instance_name> localpwp get "ou=people,dc=example,dc=com"
      
      Local Subtree Policy Policy for "ou=people,dc=example,dc=com": cn=cn\3DnsPwPolicyEntry_subtree\2Cou\3Dpeople\2Cdc\3Dexample\2Cdc\3Dcom,cn=nsPwPolicyContainer,ou=people,dc=example,dc=com
      ------------------------------------
      ...
      passwordtrackupdatetime: on
      Copy to Clipboard Toggle word wrap

3.6. Configuring temporary password rules

Directory Server password policies support setting temporary passwords on user accounts. If you assign a temporary password to a user, Directory Server rejects any other operation than a password change until the user changes its password.

The following are the features of temporary passwords:

  • Only the cn=Directory Manager account can assign temporary passwords.
  • Directory Server allows authentication attempts only for a fixed number of times to avoid that an attacker probes the password.
  • Directory Server allows authentication attempts after a specified delay to configure that the temporary passwords are not usable directly after you set them.
  • Directory Server allows authentication attempts only for a specified time so that the temporary password expires if a user does not use or reset it.
  • If the authentication was successful, Directory Server requires that the user resets the password before the server performs any other operation.

By default, temporary password rules are disabled. You can configure them in global or local password policies.

To enable the temporary password feature for the whole Directory Server instance:

  1. Enable that users must change their password if an administrator resets it.
  2. Configure the feature in the global password policy.

If an administrator updates the userPassword attribute of a user and sets the passwordMustChange attribute to on, Directory Server applies the temporary password rules.

Procedure

  1. Configure that a user must change its password after an administrator resets it:

    # dsconf <instance_name> pwpolicy set --pwdmustchange on
    Copy to Clipboard Toggle word wrap
  2. Configure the temporary password rules settings in a global password policy:

    # dsconf <instance_name> pwpolicy set --pwptprmaxuse 5 --pwptprdelayexpireat 3600 --pwptprdelayvalidfrom 60
    Copy to Clipboard Toggle word wrap

    In this example:

    • The --pwptprmaxuse option sets the maximum number of attempts a user can use the temporary password to 5.
    • The --pwptprdelayexpireat option sets the time before the temporary password expires to 3600 seconds (1 hour).
    • The --pwptprdelayvalidfrom option configures that the time set in --pwptprdelayexpireat starts 60 seconds after an administrator reset the password of a user.

Verification

  • Display the attributes that store the temporary password rules:

    # dsconf <instance_name> pwpolicy get | grep -i TPR
    passwordTPRMaxUse: 5
    passwordTPRDelayExpireAt: 3600
    passwordTPRDelayValidFrom: 60
    Copy to Clipboard Toggle word wrap

To enable the temporary password feature for a specific user or sub-tree, enable that users must change their password if an administrator resets it, and configure the feature in a local password policy.

If an administrator updates the userPassword attribute of a user and sets the passwordMustChange attribute to on, Directory Server applies the temporary password rules if the user:

  • Has the local password policy enabled
  • Is stored in a sub-tree that has the local password policy enabled

Procedure

  1. Configure that a user must change its password after an administrator resets it:

    # dsconf <instance_name> pwpolicy set --pwdmustchange on
    Copy to Clipboard Toggle word wrap
  2. Configure the temporary password rules settings:

    • For an existing sub-tree:

      # dsconf <instance_name> localpwp addsubtree --pwptprmaxuse 5 --pwptprdelayexpireat 3600 --pwptprdelayvalidfrom 60 ou=People,dc=example,dc=com
      Copy to Clipboard Toggle word wrap
    • For an existing user:

      # dsconf <instance_name> localpwp adduser --pwptprmaxuse 5 --pwptprdelayexpireat 3600 --pwptprdelayvalidfrom 60 uid=example,ou=People,dc=example,dc=com
      Copy to Clipboard Toggle word wrap

    In these examples:

    • The --pwptprmaxuse option sets the maximum number of attempts a user can use the temporary password to 5.
    • The --pwptprdelayexpireat option sets the time before the temporary password expires to 3600 seconds (1 hour).
    • The --pwptprdelayvalidfrom option configures that the time set in --pwptprdelayexpireat starts 60 seconds after an administrator reset the password of a user.

Verification

  • Display the local password policy of the distinguished name (DN):

    # dsconf <instance_name> localpwp get <DN> | grep -i TPR
    passwordTPRMaxUse: 5
    passwordTPRDelayExpireAt: 3600
    passwordTPRDelayValidFrom: 60
    Copy to Clipboard Toggle word wrap

3.7. Assigning password administrator permissions

The Directory Manager can assign the password administrator role to a user or a group of users. Because password administrators need access control instructions (ACIs) with the appropriate permissions, Red Hat recommends that you configure a group to allow a single ACI set to manage all password administrators.

Using the password administrator role is beneficial in the following scenarios:

  • setting up an atribute that forces the user to change their password at the time of the next login
  • changing a user’s password to a different storage scheme defined in the password policy
Important

A password administrator can perform any user password operations. When using a password administrator account or the Directory Manager (root DN) to set a password, password policies are bypassed and not verified. Do not use these accounts for regular user password management. Red Hat recommends performing ordinary password updates under an existing role in the database with permissions to update only the userPassword attribute.

Note

You can add a new passwordAdminSkipInfoUpdate: on/off setting under the cn=config entry to provide a fine grained control over password updates performed by password administrators. When you enable this setting, passwords updates do not update certain attributes, for example, passwordHistory, passwordExpirationTime, passwordRetryCount, pwdReset, and passwordExpWarned.

In a global policy, you can assign the password administrator role to a user or a group of users. Red Hat recommends that you configure a group to allow a single access control instruction (ACI) set to manage all password administrators.

Prerequisites

  • You have created a group named password_admins that includes all of the users to whom you want to assign the password administrator role.

Procedure

  1. Create the ACI that defines the permissions for a password administrator role:

    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x << EOF
    dn: ou=people,dc=example,dc=com
    changetype: modify
    add: aci
    aci: (targetattr="userPassword || nsAccountLock || userCertificate || nsSshPublicKey")(targetfilter="(objectClass=nsAccount)")(version 3.0; acl "Enable user password reset"; allow (write, read)(groupdn="ldap:///cn=password_admins,ou=groups,dc=example,dc=com");)
    EOF
    Copy to Clipboard Toggle word wrap
  2. Assign the password administrator role to the group:

    # dsconf <instance_name> pwpolicy set --pwdadmin "cn=password_admins,ou=groups,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap

In a local policy, you can assign the password administrator role to a user or a group of users. Red Hat recommends that you configure a group to allow a single access control instruction (ACI) set to manage all password administrators.

Prerequisites

  • You have created a group named password_admins that includes all of the users to whom you want to assign the password administrator role.

Procedure

  1. Create the ACI that defines the permissions for a password administrator role:

    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x << EOF
    dn: ou=people,dc=example,dc=com
    changetype: modify
    add: aci
    aci: (targetattr="userPassword || nsAccountLock || userCertificate || nsSshPublicKey")(targetfilter="(objectClass=nsAccount)")(version 3.0; acl "Enable user password reset"; allow (write, read)(groupdn="ldap:///cn=password_admins,ou=groups,dc=example,dc=com");)
    EOF
    Copy to Clipboard Toggle word wrap
  2. Assign the password administrator role to the group:

    # dsconf <instance_name> localpwp set ou=people,dc=example,dc=com --pwdadmin "cn=password_admins,ou=groups,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap

3.8. Disabling anonymous binds

If a user attempts to connect to Directory Server without supplying any credentials, this operation is called anonymous bind. Anonymous binds simplify searches and read operations, such as finding a phone number in the directory by not requiring users to authenticate first. However, anonymous binds can also be a security risk, because users without an account are able to access the data.

Warning

By default, anonymous binds are enabled in Directory Server for search and read operations. This allows unauthorized access to user entries as well as configuration entries, such as the root directory server entry (DSE).

To increase the security, you can disable anonymous binds.

Procedure

  • Set the nsslapd-allow-anonymous-access configuration parameter to off:

    # dsconf <instance_name> config replace nsslapd-allow-anonymous-access=off
    Copy to Clipboard Toggle word wrap

Verification

  • Run a search without specifying a user account:

    # ldapsearch -H ldap://server.example.com -b "dc=example,dc=com" -x
    ldap_bind: Inappropriate authentication (48)
    	additional info: Anonymous access is not allowed
    Copy to Clipboard Toggle word wrap

To increase the security, you can disable anonymous binds.

Prerequisites

  • You are logged in to the instance in the web console.

Procedure

  1. Navigate to ServerServer SettingsAdvanced Settings.
  2. Set the Allow Anonymous Access parameter to off.
  3. Click Save.

Verification

  • Run a search without specifying a user account:

    # ldapsearch -H ldap://server.example.com -b "dc=example,dc=com" -x
    ldap_bind: Inappropriate authentication (48)
            additional info: Anonymous access is not allowed
    Copy to Clipboard Toggle word wrap

3.9. Manually inactivating users and roles

In Directory Server, you can temporarily inactivate a single user account or a set of accounts. Once an account is inactivated, a user cannot bind to the directory. The authentication operation fails.

You can manually inactivate users and roles using the command line or the operational attribute.

Roles behave as both a static and a dynamic group. With a group, entries are added to a group entry as members. With a role, the role attribute is added to an entry and then that attribute is used to identify members in the role entry automatically.

Users and roles are inactivated executing the same procedures. However, when a role is inactivated, the members of the role are inactivated, not the role entry itself.

To inactivate users and roles, execute the following commands in the command line:

  • For inactivation of a user account:

    # dsidm <instance_name> -b "dc=example,dc=com" account lock "uid=user_name,ou=People,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap
  • For inactivation of a role:

    # dsidm <instance_name> -b "dc=example,dc=com" role lock "cn=Marketing,ou=People,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap

To activate users and roles, execute the following commands in the command line:

  • For activation of a user account:

    # dsidm <instance_name> -b "dc=example,dc=com" account unlock "uid=user_name,ou=People,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap
  • For activation of a role:

    # dsidm <instance_name> -b "dc=example,dc=com" role unlock "cn=Marketing,ou=People,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap

Optionally, instead of using the commands, you can add the operational attribute nsAccountLock to the entry. When an entry contains the nsAccountLock attribute with a value of true, the server rejects the bind.

You can display the status of an account or a role in Directory Server using the corresponding commands in the command line.

Commands for displaying the status

  • Display the status of an account:

    # dsidm -D "cn=Directory Manager" ldap://server.example.com -b "dc=example,dc=com" account entry-status "uid=user_name,ou=People,dc=example,dc=com"
    Entry DN: uid=user_name,ou=People,dc=example,dc=com
    Entry Creation Date: 20210813085535Z (2021-08-13 08:55:35)
    Entry Modification Date: 20210813085535Z (2021-08-13 08:55:35)
    Entry State: activated
    Copy to Clipboard Toggle word wrap

    Optional: The -V option displays additional details.

    Example 3.7. Detailed output for an active account

    # dsidm <instance_name> -b "dc=example,dc=com" account entry-status "uid=user_name,ou=People,dc=example,dc=com" -V
    Entry DN: uid=user_name,ou=People,dc=example,dc=com
    Entry Creation Date: 20210824160645Z (2021-08-24 16:06:45)
    Entry Modification Date: 20210824160645Z (2021-08-24 16:06:45)
    Entry Last Login Date: 20210824160645Z (2021-08-24 16:06:45)
    Entry Time Until Inactive: 2 seconds (2021-08-24 16:07:45)
    Entry State: activated
    Copy to Clipboard Toggle word wrap

    Example 3.8. Detailed output for an inactive account

    # dsidm <instance_name> -b "dc=example,dc=com" account entry-status "uid=user_name,ou=People,dc=example,dc=com" -V
    Entry DN: uid=user_name,ou=People,dc=example,dc=com
    Entry Creation Date: 20210824160645Z (2021-08-24 16:06:45)
    Entry Modification Date: 20210824160645Z (2021-08-24 16:06:45)
    Entry Last Login Date: 20210824160645Z (2021-08-24 16:06:45)
    Entry Time Since Inactive: 3 seconds (2021-08-24 16:07:45)
    Entry State: inactivity limit exceeded
    Copy to Clipboard Toggle word wrap
  • Display the status of a role:

    # dsidm <instance_name> -b "dc=example,dc=com" role entry-status "cn=Marketing,ou=People,dc=example,dc=com"
    Entry DN: cn=Marketing,ou=people,dc=example,dc=com
    Entry State: activated
    Copy to Clipboard Toggle word wrap
  • Display the status of a sub-tree:

    # dsidm <instance_name> -b "dc=example,dc=com" account subtree-status "ou=People,dc=example,dc=com" -f "(uid=*)" -V -o "2021-08-25T14:30:30"
    Copy to Clipboard Toggle word wrap

    To filter the results of the search in a sub-tree, you can use:

    • The -f option to set the search filter
    • The -s option to set the search scope
    • The -i option to return only inactive accounts
    • The -o option to return only accounts which will be inactive before the specified date YYYY-MM-DDTHH:MM:SS

Directory Server stores account lockout attributes locally. In an environment with multiple servers, configure replication for these attributes to prevent attackers from attempting to log in to one server until the account lockout count is reached and then continue on other servers.

Directory Server enforces password and account lockout policies as follows:

  • Password policies are enforced on the data supplier
  • Account lockout policies are enforced on all servers in a replication topology

Directory Server replicates the following password policy attributes:

  • passwordMinAge
  • passwordMaxAge
  • passwordExp
  • passwordWarning

However, by default, Directory Server does not replicate the general account lockout attributes:

  • passwordRetryCount
  • retryCountResetTime
  • accountUnlockTime

To prevent attackers from attempting to log in to one server until the account lockout count is reached and then continue on other servers, replicate these account lockout attributes.

If you use an account lockout policy or password policy that updates the passwordRetryCount, retryCountResetTime, or accountUnlockTime attributes, configure Directory Server to replicate these attributes so that their values are the same across all servers.

Perform this procedure on all suppliers in the replication topology.

Prerequisites

  • You configured an account lockout policy or a password policy that updates one or more of the mentioned attributes.
  • You use Directory Server in a replication environment.

Procedure

  1. Enable replication of password policy attributes:

    # dsconf <instance_name> pwpolicy set --pwdisglobal="on"
    Copy to Clipboard Toggle word wrap
  2. If you use fractional replication, display the list of attributes that are excluded from replication:

    # dsconf <instance_name> repl-agmt get --suffix "dc=example,dc=com" example-agreement | grep "nsDS5ReplicatedAttributeList"dsconf <instance_name> repl-agmt get --suffix "dc=example,dc=com" example-agreement | grep "nsDS5ReplicatedAttributeList"dsconf <instance_name> repl-agmt get --suffix "dc=example,dc=com" example-agreement | grep "nsDS5ReplicatedAttributeList"dsconf <instance_name> repl-agmt get --suffix "dc=example,dc=com" example-agreement | grep "nsDS5ReplicatedAttributeList"dsconf <instance_name> repl-agmt get --suffix "dc=example,dc=com" example-agreement | grep "nsDS5ReplicatedAttributeList"dsconf <instance_name> repl-agmt get --suffix "dc=example,dc=com" example-agreement | grep "nsDS5ReplicatedAttributeList"dsconf <instance_name> repl-agmt get --suffix "dc=example,dc=com" example-agreement | grep "nsDS5ReplicatedAttributeList"
    Copy to Clipboard Toggle word wrap

    Using the default settings, no output is shown, and Directory Server replicates the account lockout attributes. However, if the command returns a list of excluded attributes, such as in the following example, verify the attribute list:

    nsDS5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE accountUnlockTime passwordRetryCount retryCountResetTime example1 example2
    Copy to Clipboard Toggle word wrap

    In this example, the accountUnlockTime, passwordRetryCount, and retryCountResetTime lockout policy attributes are excluded from replication, along with two other attributes.

  3. If the output of the previous command lists any of the account lockout attributes, update the fractional replication settings to only include attributes other than the lockout policy attributes:

    # dsconf <instance_name> repl-agmt set --suffix "dc=example,dc=com" --frac-list "example1 example2" example-agreement
    Copy to Clipboard Toggle word wrap

Verification

  1. Attempt to perform a search as a user using an invalid password:

    # ldapsearch -H ldap://server.example.com -D "uid=example,ou=People,dc=example,dc=com" -w "<invalid-password>" -b "dc=example,dc=com" -x
    ldap_bind: Invalid credentials (49)
    Copy to Clipboard Toggle word wrap
  2. Display the passwordRetryCount attribute of the user:

    # ldapsearch -H ldap://server.example.com -D "cn=Directory Manager" -W -b "uid=example,ou=People,dc=example,dc=com" -x passwordRetryCount
    ...
    dn: uid=example,ou=People,dc=example,dc=com
    passwordRetryCount: 1
    Copy to Clipboard Toggle word wrap
  3. Run the previous command on a different server in the replication topology. If the value of the passwordRetryCount attribute is the same, Directory Server replicated the attribute.

Referential Integrity is a database mechanism that ensures that Directory Server maintains relationship between related entries. You can use this feature to ensure that an update to one entry in the directory is correctly reflected in other entries that reference the updated entry.

For example, if you remove a user from the directory and the Referential Integrity plug-in is enabled, the server also removes the user from any group in which the user is a member. If the plug-in is not enabled, the user remains a member of the group until an administrator manually removes it.

Referential Integrity is an important feature if you integrate Directory Server with other products that rely on Directory Server for user and group management.

When you enable the Referential Integrity plug-in, it performs integrity updates on the member, uniqueMember, owner, and seeAlso attributes, by default, immediately after an operation.

For example, if an administrator deletes, updates, renames, or moves a group or user within the directory, Directory Server logs the operation in the Referential Integrity log file. Directory Server then uses the distinguished name (DN) from this log file and searches entries matching the attribute specified in the plug-in’s configuration, and then updates the matching entries. For example, after deleting the cn=demo,dc=example,dc=com entry the plug-in searches for entries with the member attribute set to cn=demo,dc=example,dc=com and removes these member attributes. Afterwards, the plug-in does the same for the uniqueMember, owner, and seeAlso attributes.

By default, Directory Server does searches and updates in the same transaction as the original operation. Because search and update operations can take a lot of time, it is possible to delay them after the completion of the original operation. You can use the --update-delay option of the dsconf plugin referential-integrity set command to separate the original operations from integrity updates.

To avoid poor performance of modify and delete operations, index the attributes you specify in the Referential Integrity plug-in configuration.

You can use the command line to configure the Referential Integrity plug-in.

Perform this procedure on every supplier in a replication topology.

Procedure

  1. Enable the Referential Integrity plug-in:

    # dsconf <instance_name> plugin referential-integrity enable
    Copy to Clipboard Toggle word wrap
  2. Set the subtree in which the plug-in searches for delete or rename operations of user entries:

    # dsconf <instance_name> plugin referential-integrity set --entry-scope "ou=People,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap
  3. Optional: Exclude a subtree under the entry scope:

    # dsconf <instance_name> plugin referential-integrity set --exclude-entry-scope "ou=Special Users,ou=People,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap

    This command configures the plug-in to ignore delete or rename operations performed in the ou=Special Users,ou=People,dc=example,dc=com subtree.

  4. Configure the subtree in which the plug-in updates group entries:

    # dsconf <instance_name> plugin referential-integrity set --container-scope "ou=Groups,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap
  5. By default, the plug-in performs integrity updates on the member, uniqueMember, owner, and seeAlso attributes. To specify other attributes, enter:

    # dsconf <instance_name> plugin referential-integrity set --membership-attr attribute_1 attribute_2
    Copy to Clipboard Toggle word wrap

    Note that this command overrides the list of attributes in the plug-in’s configuration. If you want to add an attribute, pass the current list of attributes and the additional one to the --membership-attr option.

  6. Optional: By default, Directory Server performs referential integrity checks immediately. If you want to set a delay, enter:

    # dsconf <instance_name> plugin referential-integrity set --update-delay=5
    Copy to Clipboard Toggle word wrap

    This command delays the referential integrity checks by 5 seconds. Note that, if you enabled the Referential Integrity on multiple suppliers, setting a delay can cause replication loops and directory inconsistencies. To avoid such problems, enable the plug-in only on one supplier in the topology.

  7. Restart the instance:

    # dsctl <instance_name> restart
    Copy to Clipboard Toggle word wrap

Verification

  1. Display the Referential Integrity plug-in configuration:

    # dsconf <instance_name> plugin referential-integrity show
    ...
    nsslapd-plugincontainerscope: ou=Groups,dc=example,dc=com
    nsslapd-pluginentryscope: ou=People,dc=example,dc=com
    ...
    referint-membership-attr: member
    referint-membership-attr: uniquemember
    referint-membership-attr: owner
    referint-membership-attr: seeAlso
    referint-update-delay: 0
    ...
    Copy to Clipboard Toggle word wrap
  2. List the members of a group by displaying the member attributes of the groups:

    # ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -b "cn=demoGroup,ou=Groups,dc=example,dc=com" member
    ...
    member: uid=demoUser,ou=People,dc=example,dc=com
    Copy to Clipboard Toggle word wrap
  3. Delete the uid=demoUser,ou=People,dc=example,dc=com user:

    # dsidm <instance_name> -b "dc=example,dc=com" user delete "uid=demoUser,ou=People,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap
  4. Display the members of the group again:

    # ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -b "cn=demoGroup,ou=People,dc=example,dc=com" member
    Copy to Clipboard Toggle word wrap

    If uid=demoUser,ou=People,dc=example,dc=com is no longer listed as a member of the group, the Referential Integrity plug-in works.

You can use the Directory Server web console to configure the Referential Integrity plug-in.

Perform this procedure on every supplier in a replication topology.

Prerequisites

  • You are logged in to the instance in the web console.

Procedure

  1. Navigate to PluginsReferential Integrity.
  2. Enable the plug-in.
  3. Click ActionsRestart Instance.
  4. Navigate again to PluginsReferential Integrity.
  5. By default, the plug-in performs integrity updates on the member, uniqueMember, owner, and seeAlso attributes. To specify other attributes, update the list in the Membership Attribute field.
  6. Set the Entry Scope field to the DN of the subtree in which the plug-in should search for delete or rename operations of user entries.
  7. Optional: To exclude a subtree under the entry scope, enter the DN of the subtree in the Exclude Entry Scope field.
  8. Set the Container Scope field to the DN of the subtree in which the plug-in should update group entries.
  9. Optional: Update the path to the Referential Integrity log file. Directory Server uses this file to track changes in the directory. Note that the dirsrv user must have write permissions to this location.
  10. Optional: By default, Directory Server performs referential integrity checks immediately. If you want to set a delay, set it in the Update Delay field.

    Note that, if you enabled the Referential Integrity on multiple suppliers, setting a delay can cause replication loops and directory inconsistencies. To avoid such problems, enable the plug-in only on one supplier in the topology.

  11. Click Save Config.

Verification

  1. List the members of a group by displaying the member attributes of the groups:

    # ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -b "cn=demoGroup,ou=Groups,dc=example,dc=com" member
    ...
    member: uid=demoUser,ou=People,dc=example,dc=com
    Copy to Clipboard Toggle word wrap
  2. Delete the uid=demoUser,ou=People,dc=example,dc=com user:

    # dsidm <instance_name> -b "dc=example,dc=com" user delete "uid=demoUser,ou=People,dc=example,dc=com"
    Copy to Clipboard Toggle word wrap
  3. Display the members of the group again:

    # ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -b "cn=demoGroup,ou=People,dc=example,dc=com" member
    Copy to Clipboard Toggle word wrap

    If uid=demoUser,ou=People,dc=example,dc=com is no longer listed as a member of the group, the Referential Integrity plug-in works.

Legal Notice

Copyright © 2025 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.
Back to top
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Theme

© 2025 Red Hat