CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-unboundid--unboundid-ldapsdk

Comprehensive Java LDAP SDK providing full LDAPv3 protocol support, connection pooling, schema handling, and persistence framework for LDAP directory operations.

Pending
Overview
Eval results
Files

controls-extensions.mddocs/

Controls and Extensions

Standard LDAP controls and extended operations for advanced directory functionality including paged results, server-side sorting, persistent search, and password management.

Capabilities

Standard LDAP Controls

Paged Results Controls

/**
 * Control for retrieving search results in pages
 */
public class PagedResultsRequestControl extends Control {
    public PagedResultsRequestControl(int pageSize);
    public PagedResultsRequestControl(int pageSize, ASN1OctetString cookie);
    
    public int getSize();
    public ASN1OctetString getCookie();
}

/**
 * Response control for paged results
 */
public class SimplePagedResultsControl extends Control {
    public int getSize();
    public ASN1OctetString getCookie();
    public boolean moreResultsToReturn();
    
    public static SimplePagedResultsControl get(LDAPResult result);
}

Server-Side Sort Controls

/**
 * Control for server-side sorting of search results
 */
public class ServerSideSortRequestControl extends Control {
    public ServerSideSortRequestControl(SortKey... sortKeys);
    public ServerSideSortRequestControl(List<SortKey> sortKeys);
    
    public List<SortKey> getSortKeys();
}

/**
 * Sort key specification
 */
public class SortKey implements Serializable {
    public SortKey(String attributeName);
    public SortKey(String attributeName, boolean reverseOrder);
    public SortKey(String attributeName, String matchingRuleID, boolean reverseOrder);
    
    public String getAttributeName();
    public String getMatchingRuleID();
    public boolean reverseOrder();
}

/**
 * Response control for server-side sort status
 */
public class ServerSideSortResponseControl extends Control {
    public ResultCode getResultCode();
    public String getAttributeName();
}

Authorization Controls

/**
 * Control for proxied authorization (version 1)
 */
public class ProxiedAuthorizationV1RequestControl extends Control {
    public ProxiedAuthorizationV1RequestControl(String proxyDN);
    
    public String getProxyDN();
}

/**
 * Control for proxied authorization (version 2)
 */
public class ProxiedAuthorizationV2RequestControl extends Control {
    public ProxiedAuthorizationV2RequestControl(String authorizationID);
    
    public String getAuthorizationID();
}

/**
 * Control for requesting authorization identity
 */
public class AuthorizationIdentityRequestControl extends Control {
    public AuthorizationIdentityRequestControl();
}

/**
 * Response control containing authorization identity
 */
public class AuthorizationIdentityResponseControl extends Control {
    public String getAuthorizationID();
}

Extended Operations

Password Management

/**
 * Extended operation for password modification
 */
public class PasswordModifyExtendedRequest extends ExtendedRequest {
    public PasswordModifyExtendedRequest();
    public PasswordModifyExtendedRequest(String userIdentity, String oldPassword, String newPassword);
    
    public String getUserIdentity();
    public String getOldPassword();
    public String getNewPassword();
}

/**
 * Result for password modify operation
 */
public class PasswordModifyExtendedResult extends ExtendedResult {
    public String getGeneratedPassword();
}

Identity Operations

/**
 * Extended operation to determine current identity
 */
public class WhoAmIExtendedRequest extends ExtendedRequest {
    public WhoAmIExtendedRequest();
}

/**
 * Result containing current authorization identity
 */
public class WhoAmIExtendedResult extends ExtendedResult {
    public String getAuthorizationID();
}

Transaction Support

/**
 * Extended operation to start a transaction
 */
public class StartTransactionExtendedRequest extends ExtendedRequest {
    public StartTransactionExtendedRequest();
}

/**
 * Result for start transaction operation
 */
public class StartTransactionExtendedResult extends ExtendedResult {
    public ASN1OctetString getTransactionID();
}

/**
 * Extended operation to end a transaction
 */
public class EndTransactionExtendedRequest extends ExtendedRequest {
    public EndTransactionExtendedRequest(ASN1OctetString transactionID, boolean commit);
    
    public ASN1OctetString getTransactionID();
    public boolean commit();
}

SSL/TLS Support

/**
 * Extended operation to start TLS encryption
 */
public class StartTLSExtendedRequest extends ExtendedRequest {
    public StartTLSExtendedRequest();
    public StartTLSExtendedRequest(SSLContext sslContext);
    public StartTLSExtendedRequest(SSLSocketFactory socketFactory);
}

Usage Examples

Paged Search Results

import com.unboundid.ldap.sdk.*;
import com.unboundid.ldap.sdk.controls.*;

LDAPConnection connection = new LDAPConnection("ldap.example.com", 389);

try {
    connection.bind("cn=admin,dc=example,dc=com", "password");
    
    SearchRequest searchRequest = new SearchRequest(
        "dc=example,dc=com",
        SearchScope.SUB,
        "(objectClass=inetOrgPerson)",
        "cn", "mail"
    );
    
    int pageSize = 10;
    ASN1OctetString cookie = null;
    
    do {
        searchRequest.setControls(new PagedResultsRequestControl(pageSize, cookie));
        SearchResult result = connection.search(searchRequest);
        
        System.out.println("Page with " + result.getEntryCount() + " entries:");
        for (SearchResultEntry entry : result.getSearchEntries()) {
            System.out.println("  " + entry.getAttributeValue("cn"));
        }
        
        SimplePagedResultsControl responseControl = 
            SimplePagedResultsControl.get(result);
        cookie = (responseControl != null) ? responseControl.getCookie() : null;
        
    } while ((cookie != null) && (cookie.getValueLength() > 0));
    
} finally {
    connection.close();
}

Server-Side Sorting

import com.unboundid.ldap.sdk.*;
import com.unboundid.ldap.sdk.controls.*;

LDAPConnection connection = new LDAPConnection("ldap.example.com", 389);

try {
    connection.bind("cn=admin,dc=example,dc=com", "password");
    
    SearchRequest searchRequest = new SearchRequest(
        "dc=example,dc=com",
        SearchScope.SUB,
        "(objectClass=inetOrgPerson)",
        "cn", "sn", "mail", "department"
    );
    
    // Sort by department, then by surname
    SortKey[] sortKeys = {
        new SortKey("department"),
        new SortKey("sn")
    };
    
    searchRequest.addControl(new ServerSideSortRequestControl(sortKeys));
    
    SearchResult result = connection.search(searchRequest);
    
    // Check if sorting was successful
    ServerSideSortResponseControl sortResponse = 
        result.getResponseControl(ServerSideSortResponseControl.class);
    
    if (sortResponse != null && sortResponse.getResultCode() == ResultCode.SUCCESS) {
        System.out.println("Results sorted successfully");
    }
    
    // Results are now sorted by department, then surname
    for (SearchResultEntry entry : result.getSearchEntries()) {
        System.out.println(entry.getAttributeValue("department") + 
            " - " + entry.getAttributeValue("sn") + 
            ", " + entry.getAttributeValue("cn"));
    }
    
} finally {
    connection.close();
}

Password Modification

import com.unboundid.ldap.sdk.*;
import com.unboundid.ldap.sdk.extensions.*;

LDAPConnection connection = new LDAPConnection("ldap.example.com", 389);

try {
    connection.bind("cn=admin,dc=example,dc=com", "password");
    
    // Change password for specific user
    PasswordModifyExtendedRequest passwordRequest = new PasswordModifyExtendedRequest(
        "cn=john.doe,ou=people,dc=example,dc=com",  // user identity
        "oldPassword",                              // old password
        "newSecurePassword123"                      // new password
    );
    
    PasswordModifyExtendedResult passwordResult = 
        (PasswordModifyExtendedResult) connection.processExtendedOperation(passwordRequest);
    
    if (passwordResult.getResultCode() == ResultCode.SUCCESS) {
        System.out.println("Password changed successfully");
    } else {
        System.err.println("Password change failed: " + passwordResult.getDiagnosticMessage());
    }
    
    // Generate new password (let server generate)
    PasswordModifyExtendedRequest generateRequest = new PasswordModifyExtendedRequest(
        "cn=jane.smith,ou=people,dc=example,dc=com",
        "currentPassword",
        null  // null = let server generate new password
    );
    
    PasswordModifyExtendedResult generateResult = 
        (PasswordModifyExtendedResult) connection.processExtendedOperation(generateRequest);
    
    if (generateResult.getResultCode() == ResultCode.SUCCESS) {
        System.out.println("Generated password: " + generateResult.getGeneratedPassword());
    }
    
} finally {
    connection.close();
}

Authorization Identity

import com.unboundid.ldap.sdk.*;
import com.unboundid.ldap.sdk.extensions.*;
import com.unboundid.ldap.sdk.controls.*;

LDAPConnection connection = new LDAPConnection("ldap.example.com", 389);

try {
    connection.bind("cn=admin,dc=example,dc=com", "password");
    
    // Determine current authorization identity
    WhoAmIExtendedRequest whoAmIRequest = new WhoAmIExtendedRequest();
    WhoAmIExtendedResult whoAmIResult = 
        (WhoAmIExtendedResult) connection.processExtendedOperation(whoAmIRequest);
    
    if (whoAmIResult.getResultCode() == ResultCode.SUCCESS) {
        System.out.println("Current identity: " + whoAmIResult.getAuthorizationID());
    }
    
    // Perform operation with proxied authorization
    SearchRequest searchRequest = new SearchRequest(
        "dc=example,dc=com",
        SearchScope.ONE,
        "(objectClass=*)",
        "1.1"  // no attributes, just check access
    );
    
    // Act as different user
    searchRequest.addControl(new ProxiedAuthorizationV2RequestControl(
        "dn:cn=readonly,ou=service,dc=example,dc=com"
    ));
    
    // Request authorization identity in response
    searchRequest.addControl(new AuthorizationIdentityRequestControl());
    
    SearchResult result = connection.search(searchRequest);
    
    // Check what identity was actually used
    AuthorizationIdentityResponseControl authzResponse = 
        result.getResponseControl(AuthorizationIdentityResponseControl.class);
    
    if (authzResponse != null) {
        System.out.println("Operation performed as: " + authzResponse.getAuthorizationID());
    }
    
} finally {
    connection.close();
}

Transaction Operations

import com.unboundid.ldap.sdk.*;
import com.unboundid.ldap.sdk.extensions.*;
import com.unboundid.ldap.sdk.controls.*;

LDAPConnection connection = new LDAPConnection("ldap.example.com", 389);

try {
    connection.bind("cn=admin,dc=example,dc=com", "password");
    
    // Start transaction
    StartTransactionExtendedRequest startTxnRequest = new StartTransactionExtendedRequest();
    StartTransactionExtendedResult startTxnResult = 
        (StartTransactionExtendedResult) connection.processExtendedOperation(startTxnRequest);
    
    if (startTxnResult.getResultCode() != ResultCode.SUCCESS) {
        throw new LDAPException(startTxnResult.getResultCode(), "Failed to start transaction");
    }
    
    ASN1OctetString transactionID = startTxnResult.getTransactionID();
    System.out.println("Transaction started");
    
    try {
        // Create transaction control
        TransactionSpecificationRequestControl txnControl = 
            new TransactionSpecificationRequestControl(transactionID);
        
        // Perform operations within transaction
        AddRequest addRequest1 = new AddRequest(
            "cn=user1,ou=people,dc=example,dc=com",
            new Attribute("objectClass", "inetOrgPerson"),
            new Attribute("cn", "user1"),
            new Attribute("sn", "User")
        );
        addRequest1.addControl(txnControl);
        
        AddRequest addRequest2 = new AddRequest(
            "cn=user2,ou=people,dc=example,dc=com",
            new Attribute("objectClass", "inetOrgPerson"),
            new Attribute("cn", "user2"),
            new Attribute("sn", "User")
        );
        addRequest2.addControl(txnControl);
        
        // Execute operations (won't be committed until transaction ends)
        connection.add(addRequest1);
        connection.add(addRequest2);
        
        System.out.println("Operations queued in transaction");
        
        // Commit transaction
        EndTransactionExtendedRequest commitRequest = 
            new EndTransactionExtendedRequest(transactionID, true);
        
        ExtendedResult commitResult = connection.processExtendedOperation(commitRequest);
        
        if (commitResult.getResultCode() == ResultCode.SUCCESS) {
            System.out.println("Transaction committed successfully");
        } else {
            System.err.println("Transaction commit failed: " + commitResult.getDiagnosticMessage());
        }
        
    } catch (LDAPException e) {
        // Rollback transaction on error
        System.err.println("Error in transaction: " + e.getMessage());
        
        EndTransactionExtendedRequest rollbackRequest = 
            new EndTransactionExtendedRequest(transactionID, false);
        
        connection.processExtendedOperation(rollbackRequest);
        System.out.println("Transaction rolled back");
    }
    
} finally {
    connection.close();
}

Start TLS

import com.unboundid.ldap.sdk.*;
import com.unboundid.ldap.sdk.extensions.*;
import com.unboundid.util.ssl.*;

// Start with plain connection
LDAPConnection connection = new LDAPConnection("ldap.example.com", 389);

try {
    // Create SSL context
    SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager());
    
    // Start TLS to upgrade connection to SSL
    StartTLSExtendedRequest startTLSRequest = 
        new StartTLSExtendedRequest(sslUtil.createSSLContext());
    
    ExtendedResult startTLSResult = connection.processExtendedOperation(startTLSRequest);
    
    if (startTLSResult.getResultCode() == ResultCode.SUCCESS) {
        System.out.println("TLS started successfully");
        System.out.println("Connection is now encrypted");
        
        // Now authenticate over the encrypted connection
        connection.bind("cn=admin,dc=example,dc=com", "password");
        
        // Perform operations over encrypted connection
        SearchResult result = connection.search("dc=example,dc=com", SearchScope.BASE, "(objectClass=*)");
        System.out.println("Secure search completed");
        
    } else {
        System.err.println("Start TLS failed: " + startTLSResult.getDiagnosticMessage());
    }
    
} catch (Exception e) {
    System.err.println("TLS operation failed: " + e.getMessage());
} finally {
    connection.close();
}

Install with Tessl CLI

npx tessl i tessl/maven-com-unboundid--unboundid-ldapsdk

docs

authentication.md

controls-extensions.md

core-operations.md

data-types.md

index.md

ldif.md

persistence.md

schema.md

search.md

tile.json