8.6. Updating Static Groups

Static groups enumerate user entries. Static groups can grow large. For an example, see the group entry at the end of big-group.ldif:

dn: cn=Static,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: groupofnames
cn: Static
member: uid=user.0,ou=People,dc=example,dc=com
member: uid=user.1,ou=People,dc=example,dc=com
member: uid=user.2,ou=People,dc=example,dc=com
...
member: uid=user.10000,ou=People,dc=example,dc=com

To update a static group, you either add members or remove members. For sample code, see UpdateGroup.java, one of the OpenDJ LDAP SDK examples.

The UpdateGroup example checks that the directory server supports the Permissive Modify control. With directory servers such as OpenDJ that support the LDAP Permissive Modify control, you can use the control to avoid having to determine whether a given member is already in the group before performing the operation. Instead you can simply request an add or a delete modification for the member.

Example 8.1. Updating a Group With Permissive Modify

final LDAPConnectionFactory factory = new LDAPConnectionFactory(host, port);
Connection connection = null;
try {
    connection = factory.getConnection();

    Collection<String> controls =
            RootDSE.readRootDSE(connection).getSupportedControls();

    final String user = "cn=Directory Manager";
    final char[] password = "password".toCharArray();
    connection.bind(user, password);

    if (controls.contains(PermissiveModifyRequestControl.OID)) {

        final ModifyRequest request = Requests.newModifyRequest(groupDN)
                .addControl(PermissiveModifyRequestControl.newControl(true))
                .addModification(modType, "member", memberDN);
        connection.modify(request);

    } else {

        /* ... */

    }

    String op = (modType == ModificationType.ADD) ? "added to" : "deleted from";
    System.out.println("The entry with DN " + memberDN + " has been "
            + op + " the group with DN " + groupDN + ".");

} catch (final ErrorResultException e) {
    System.err.println(e.getMessage());
    System.exit(e.getResult().getResultCode().intValue());
    return;
} finally {
    if (connection != null) {
        connection.close();
    }
}

If the directory server does not support the Permissive Modify control, then the example checks whether the member is present in the group by using an LDAP compare operation. If a member to be added does not yet belong to the group, the example requests an add modification. If a member to be deleted does belong to the group, the example requests a delete modification.

Example 8.2. Updating a Group With Compare & Modify

final LDAPConnectionFactory factory = new LDAPConnectionFactory(host, port);
Connection connection = null;
try {
    connection = factory.getConnection();

    Collection<String> controls =
            RootDSE.readRootDSE(connection).getSupportedControls();

    final String user = "cn=Directory Manager";
    final char[] password = "password".toCharArray();
    connection.bind(user, password);

    if (controls.contains(PermissiveModifyRequestControl.OID)) {

        /* ... */

    } else {

        System.out.println("Checking whether the entry with DN "
                + memberDN + " belongs to the group with DN " + groupDN
                + "...");
        final CompareRequest request =
                Requests.newCompareRequest(groupDN, "member", memberDN);
        CompareResult result = connection.compare(request);

        if (modType == ModificationType.ADD) {
            if (result.getResultCode() == ResultCode.COMPARE_FALSE) {
                System.out.println("Member does not yet belong to group."
                        + " Adding it...");
                final ModifyRequest addMember =
                        Requests.newModifyRequest(groupDN)
                            .addModification(modType, "member", memberDN);
                connection.modify(addMember);
            }
        }

        if (modType == ModificationType.DELETE) {
            if (result.getResultCode() == ResultCode.COMPARE_TRUE) {
                System.out.println("Member belongs to group."
                        + " Removing it...");
                final ModifyRequest delMember =
                        Requests.newModifyRequest(groupDN)
                            .addModification(modType, "member", memberDN);
                connection.modify(delMember);
            }
        }

    }

    String op = (modType == ModificationType.ADD) ? "added to" : "deleted from";
    System.out.println("The entry with DN " + memberDN + " has been "
            + op + " the group with DN " + groupDN + ".");

} catch (final ErrorResultException e) {
    System.err.println(e.getMessage());
    System.exit(e.getResult().getResultCode().intValue());
    return;
} finally {
    if (connection != null) {
        connection.close();
    }
}

You can change multiple member values with a single modification. The final argument of this form of the ModifyRequest.addModification() method takes a series of one or more values. So if you have multiple group members to add or delete, you can loop over your list to perform compare individual compare requests, then construct a single modify request to add or delete the group members. In other words, if you have three members to add, you can list the three member DNs as arguments of addModification.

String member1 = "uid=user1,ou=people,dc=example,dc=com";
String member2 = "uid=user1,ou=people,dc=example,dc=com";
String member3 = "uid=user1,ou=people,dc=example,dc=com";
final ModifyRequest addMember =
    Requests.newModifyRequest(groupDN)
        .addModification(modType, "member", member1, member2, member3);
connection.modify(addMember);

To try the example, download and import big-group.ldif into your directory server, and then run the sample. For example, if OpenDJ is set up to with directory manager as cn=Directory Manager, password password listening on localhost port 1389, and you run the example with arguments localhost 1389 cn=Static,ou=Groups,dc=example,dc=com uid=user.5150,ou=People,dc=example,dc=com del, the resulting output is The entry with DN uid=user.5150,ou=People,dc=example,dc=com has been deleted from the group with DN cn=Static,ou=Groups,dc=example,dc=com..