### Install ldap4net Package Source: https://github.com/flamencist/ldap4net/blob/master/README.md Instructions for installing the ldap4net NuGet package using the .NET CLI or Package Manager Console. ```powershell Install-Package LdapForNet ``` ```bash dotnet add package LdapForNet ``` -------------------------------- ### Start TLS Encryption Source: https://context7.com/flamencist/ldap4net/llms.txt Upgrades an existing plain LDAP connection to use TLS encryption. This is useful for establishing a connection on a standard LDAP port (389) and then securing it. The example shows how to start TLS and then perform a simple bind. ```csharp using LdapForNet; using (var cn = new LdapConnection()) { cn.Connect("dc.example.com", 389); // Upgrade connection to TLS cn.StartTransportLayerSecurity(trustAll: false); // For self-signed certificates during development // cn.StartTransportLayerSecurity(trustAll: true); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "password"); // Connection is now encrypted } ``` -------------------------------- ### Configure LDAP Connection Options in C# Source: https://context7.com/flamencist/ldap4net/llms.txt Demonstrates how to get and set LDAP connection options like protocol version, referral handling, and hostnames using LdapForNet. This involves creating an LdapConnection, connecting to a server, retrieving options with GetOption, and setting options with SetOption. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); // Get current LDAP protocol version var version = cn.GetOption(LdapOption.LDAP_OPT_PROTOCOL_VERSION); Console.WriteLine($"Protocol version: {version}"); // Get server hostname var host = cn.GetOption(LdapOption.LDAP_OPT_HOST_NAME); Console.WriteLine($"Host: {host}"); // Disable referral following (useful for paged searches) cn.SetOption(LdapOption.LDAP_OPT_REFERRALS, IntPtr.Zero); // Set protocol version var newVersion = (int)LdapVersion.LDAP_VERSION3; cn.SetOption(LdapOption.LDAP_OPT_PROTOCOL_VERSION, newVersion); cn.Bind(); } ``` -------------------------------- ### Create OpenLDAP Library Symlinks on Linux Source: https://github.com/flamencist/ldap4net/blob/master/linux.md These commands create the necessary symbolic links for libldap.so.2 and liblber.so.2 if they are missing. Replace the placeholders with the actual version numbers of your installed OpenLDAP libraries. ```shell root@linux ~ % ln -s /usr/lib/libldap-2.X.so.2.Y.Z /usr/lib/libldap.so.2 root@linux ~ % ln -s /usr/lib/liblber-2.X.so.2.Y.Z /usr/lib/liblber.so.2 ``` -------------------------------- ### Receive Directory Notifications with C# Source: https://context7.com/flamencist/ldap4net/llms.txt This C# code demonstrates how to receive real-time notifications when directory entries change. It utilizes the DirectoryNotificationControl and requires an active LDAP connection. The example cancels the operation after the first notification for demonstration purposes. ```csharp using LdapForNet; using static LdapForNet.Native.Native; var cts = new CancellationTokenSource(); using (var cn = new LdapConnection()) { cn.Connect("dc.example.com", 389); await cn.BindAsync(); var results = new List(); var searchRequest = new SearchRequest( "CN=WatchedUser,CN=Users,dc=example,dc=com", "(objectClass=*)", LdapSearchScope.LDAP_SCOPE_BASE, "mail", "telephoneNumber" ) { OnPartialResult = searchResponse => { results.AddRange(searchResponse.Entries); Console.WriteLine($"Received notification: {searchResponse.Entries.Count} changes"); cts.Cancel(); // Cancel after first notification for demo } }; searchRequest.Controls.Add(new DirectoryNotificationControl()); try { var response = (SearchResponse)await cn.SendRequestAsync(searchRequest, cts.Token); } catch (OperationCanceledException) { Console.WriteLine("Notification monitoring stopped"); } } ``` -------------------------------- ### Handle Binary LDAP Attributes in C# Source: https://context7.com/flamencist/ldap4net/llms.txt Shows how to read and handle binary attribute values like objectSid, objectGUID, and jpegPhoto using LdapForNet. This involves performing a search request and then extracting binary data as byte arrays or using helper methods to get string representations of GUIDs and SIDs. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("dc.example.com", 389); cn.Bind(); var response = (SearchResponse)cn.SendRequest( new SearchRequest( "cn=user,dc=example,dc=com", "(objectClass=*)", LdapSearchScope.LDAP_SCOPE_BASE, "objectSid", "objectGUID", "jpegPhoto" ) ); var entry = response.Entries.First().ToLdapEntry(); // Get objectSid as byte array if (entry.DirectoryAttributes.Contains("objectSid")) { var sidBytes = entry.DirectoryAttributes["objectSid"].GetValue(); Console.WriteLine($"SID bytes length: {sidBytes.Length}"); } // Using DirectoryEntry helper methods var dirEntry = response.Entries.First(); // Get SID as string var sidString = dirEntry.GetObjectSid(); Console.WriteLine($"SID: {sidString}"); // Get GUID var guid = dirEntry.GetObjectGuid(); Console.WriteLine($"GUID: {guid}"); // Get modification timestamp var whenChanged = dirEntry.GetWhenChanged(); Console.WriteLine($"Last modified: {whenChanged}"); } ``` -------------------------------- ### Bind Anonymously Source: https://context7.com/flamencist/ldap4net/llms.txt Connects to an LDAP server without providing any credentials. The level of access granted is determined by the server's configuration for anonymous users. This example demonstrates connecting and performing a basic search. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthType.Anonymous, new LdapCredential()); // Access is limited to what the server allows for anonymous users var entries = cn.Search("dc=example,dc=com", "(objectClass=*)", scope: LdapSearchScope.LDAP_SCOPE_BASE); } ``` -------------------------------- ### Get LDAP Options Source: https://github.com/flamencist/ldap4net/blob/master/README.md Retrieves various options from an active LDAP connection, such as the protocol version, host name, and referral settings. Requires a connection. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); var ldapVersion = cn.GetOption(LdapOption.LDAP_OPT_PROTOCOL_VERSION); var host = cn.GetOption(LdapOption.LDAP_OPT_HOST_NAME); var refferals = cn.GetOption(LdapOption.LDAP_OPT_REFERRALS); cn.Bind(); } ``` -------------------------------- ### Add Entry with Binary Values (C#) Source: https://context7.com/flamencist/ldap4net/llms.txt Creates a new LDAP entry and includes binary attribute values, such as images or certificates. This example demonstrates adding a 'jpegPhoto' attribute by reading a file into a byte array. It requires a connection to an LDAP server and appropriate bind credentials. ```csharp using LdapForNet; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "adminpassword"); // Create entry with binary photo var photoAttribute = new DirectoryAttribute { Name = "jpegPhoto" }; photoAttribute.Add(File.ReadAllBytes("photo.jpg")); var response = (AddResponse)cn.SendRequest(new AddRequest( "cn=userphoto,ou=users,dc=example,dc=com", new DirectoryAttribute { Name = "objectClass" }.AddValues(new[] { "inetOrgPerson" }), new DirectoryAttribute { Name = "cn" }.AddValues(new[] { "userphoto" }), new DirectoryAttribute { Name = "sn" }.AddValues(new[] { "Photo" }), photoAttribute )); Console.WriteLine($"Entry added: {response.ResultCode}"); } ``` -------------------------------- ### Reset Password in Active Directory Source: https://github.com/flamencist/ldap4net/blob/master/README.md Provides a C# example for resetting a user's password in Microsoft Active Directory. This operation requires an LDAPS connection and modifies the 'unicodePwd' attribute with the new password encoded as UTF-16. ```csharp using (var cn = new LdapConnection()) { // need use ssl/tls for reset password cn.Connect("dc.example.com", 636, LdapSchema.LDAPS); cn.Bind(); var attribute = new DirectoryModificationAttribute() { Name = "unicodePwd", LdapModOperation = Native.LdapModOperation.LDAP_MOD_REPLACE }; string password = "\"strongPassword\""; byte[] encodedBytes = System.Text.Encoding.Unicode.GetBytes(password); attribute.Add(encodedBytes); var response = (ModifyResponse)cn.SendRequest(new ModifyRequest("CN=yourUser,CN=Users,dc=dc,dc=local", attribute)); } ``` -------------------------------- ### Modify Entry with Binary Values (C#) Source: https://context7.com/flamencist/ldap4net/llms.txt Modifies binary attribute values in an existing LDAP entry. This example shows how to replace the 'jpegPhoto' attribute with new image data read from a file. It requires an established LDAP connection, bind credentials, and the DN of the entry to be modified. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "adminpassword"); var imageAttribute = new DirectoryModificationAttribute { LdapModOperation = LdapModOperation.LDAP_MOD_REPLACE, Name = "jpegPhoto" }; imageAttribute.Add(File.ReadAllBytes("newphoto.jpg")); var response = (ModifyResponse)cn.SendRequest( new ModifyRequest("cn=testuser,ou=users,dc=example,dc=com", imageAttribute)); Console.WriteLine($"Photo updated: {response.ResultCode}"); } ``` -------------------------------- ### Get Root DSE Information with C# Source: https://context7.com/flamencist/ldap4net/llms.txt This C# code retrieves the Root DSE (Directory Server Agent Service Entry) from an LDAP server. It connects, binds, and then fetches server information such as supported LDAP versions, naming contexts, and supported SASL mechanisms. This requires a valid LDAP server address and credentials. ```csharp using LdapForNet; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "password"); var rootDse = cn.GetRootDse(); if (rootDse != null) { Console.WriteLine("Server Information:"); // Get supported LDAP versions if (rootDse.DirectoryAttributes.Contains("supportedLDAPVersion")) { var versions = rootDse.DirectoryAttributes["supportedLDAPVersion"].GetValues(); Console.WriteLine($" LDAP Versions: {string.Join(", ", versions)}"); } // Get naming contexts if (rootDse.DirectoryAttributes.Contains("namingContexts")) { var contexts = rootDse.DirectoryAttributes["namingContexts"].GetValues(); Console.WriteLine(" Naming Contexts:"); foreach (var ctx in contexts) { Console.WriteLine($" {ctx}"); } } // Get supported SASL mechanisms if (rootDse.DirectoryAttributes.Contains("supportedSASLMechanisms")) { var mechanisms = rootDse.DirectoryAttributes["supportedSASLMechanisms"].GetValues(); Console.WriteLine($" SASL Mechanisms: {string.Join(", ", mechanisms)}"); } } } ``` -------------------------------- ### Bind with Client Certificate (SASL EXTERNAL) Source: https://context7.com/flamencist/ldap4net/llms.txt Authenticates using an X.509 client certificate via the SASL EXTERNAL mechanism. This is often used for service accounts or automated systems. Examples include general client certificate authentication and specific integration with Active Directory. ```csharp using LdapForNet; using System.Security.Cryptography.X509Certificates; using static LdapForNet.Native.Native; // Client certificate authentication using (var cn = new LdapConnection()) { cn.Connect("dc.example.com", 636, LdapSchema.LDAPS); var cert = new X509Certificate2("client.pfx", "certpassword", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); cn.SetClientCertificate(cert); cn.Bind(LdapAuthType.External, new LdapCredential()); // Perform operations... } // Client certificate with Active Directory using (var cn = new LdapConnection()) { cn.Connect("dc.example.com", 636, LdapSchema.LDAPS); var cert = new X509Certificate2("client.pfx", "certpassword", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); cn.SetClientCertificate(cert); cn.Bind(LdapAuthType.ExternalAd, new LdapCredential()); } ``` -------------------------------- ### Search Directory Entries Source: https://context7.com/flamencist/ldap4net/llms.txt Searches the LDAP directory for entries that match a specified filter. This functionality supports various search scopes (base, one-level, subtree) and allows for selecting specific attributes to retrieve. Examples include a default subtree search, searches with specific scopes, and retrieving only certain attributes. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "password"); // Search all objects in subtree (default scope) var entries = cn.Search("dc=example,dc=com", "(objectClass=*)"); foreach (var entry in entries) { Console.WriteLine($"DN: {entry.Dn}"); foreach (var attr in entry.DirectoryAttributes) { var values = attr.GetValues(); Console.WriteLine($" {attr.Name}: {string.Join(", ", values)}"); } } } // Search with specific scope using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "password"); // One-level search (immediate children only) var entries = cn.Search("ou=users,dc=example,dc=com", "(objectClass=person)", scope: LdapSearchScope.LDAP_SCOPE_ONELEVEL); // Base search (single object) var baseEntry = cn.Search("cn=admin,dc=example,dc=com", "(objectClass=*)", scope: LdapSearchScope.LDAP_SCOPE_BASE); } // Search with specific attributes using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "password"); // Only retrieve cn and mail attributes var entries = cn.Search("dc=example,dc=com", "(objectClass=person)", new[] { "cn", "mail" }); foreach (var entry in entries) { var cn_value = entry.DirectoryAttributes["cn"].GetValue(); Console.WriteLine($"CN: {cn_value}"); } } ``` -------------------------------- ### Modify Entry Attributes (C#) Source: https://context7.com/flamencist/ldap4net/llms.txt Modifies existing LDAP entry attributes using add, replace, or delete operations. This example demonstrates how to update an entry's 'givenName', add a 'telephoneNumber', and delete a 'description' attribute. It requires a connection, bind, and the DN of the entry to modify. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "adminpassword"); // Modify multiple attributes cn.Modify(new LdapModifyEntry { Dn = "cn=testuser,ou=users,dc=example,dc=com", Attributes = new List { // Replace existing value new LdapModifyAttribute { LdapModOperation = LdapModOperation.LDAP_MOD_REPLACE, Type = "givenName", Values = new List { "UpdatedName" } }, // Add new attribute value new LdapModifyAttribute { LdapModOperation = LdapModOperation.LDAP_MOD_ADD, Type = "telephoneNumber", Values = new List { "+1-555-1234" } }, // Delete specific attribute value new LdapModifyAttribute { LdapModOperation = LdapModOperation.LDAP_MOD_DELETE, Type = "description", Values = new List { "old description" } } } }); Console.WriteLine("Entry modified successfully"); } ``` -------------------------------- ### Sample Usage: Kerberos Authentication in C# Source: https://github.com/flamencist/ldap4net/blob/master/README.md Demonstrates how to establish a connection, perform Kerberos authentication, and execute a search operation using the ldap4net library. This snippet requires the LdapConnection class and assumes a valid Kerberos credential cache is available. ```csharp using (var cn = new LdapConnection()) { // connect cn.Connect(); // bind using kerberos credential cache file cn.Bind(); // call ldap op var entries = cn.Search("<>", "(objectClass=*)"); } ``` -------------------------------- ### Add New LDAP Entry Source: https://context7.com/flamencist/ldap4net/llms.txt Demonstrates how to create a new entry in an LDAP directory. It shows how to define the entry's Distinguished Name (DN) and its attributes using both the `SearchResultAttributeCollection` and a dictionary-based approach. ```csharp using LdapForNet; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "adminpassword"); // Add a new user entry cn.Add(new LdapEntry { Dn = "cn=newuser,ou=users,dc=example,dc=com", DirectoryAttributes = new SearchResultAttributeCollection { new DirectoryAttribute { Name = "objectClass" }.AddValues(new[] { "inetOrgPerson", "top" }), new DirectoryAttribute { Name = "cn" }.AddValues(new[] { "newuser" }), new DirectoryAttribute { Name = "sn" }.AddValues(new[] { "User" }), new DirectoryAttribute { Name = "givenName" }.AddValues(new[] { "New" }), new DirectoryAttribute { Name = "mail" }.AddValues(new[] { "newuser@example.com" }) } }); Console.WriteLine("User added successfully"); } // Using the older Dictionary-based API using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "adminpassword"); cn.Add(new LdapEntry { Dn = "cn=testuser,ou=users,dc=example,dc=com", Attributes = new Dictionary> { { "objectClass", new List { "inetOrgPerson" } }, { "cn", new List { "testuser" } }, { "sn", new List { "User" } }, { "givenName", new List { "Test" } } } }); } ``` -------------------------------- ### Delete LDAP Entry Source: https://github.com/flamencist/ldap4net/blob/master/README.md Provides a C# example for deleting an LDAP entry. This operation requires an active LdapConnection and the distinguished name (DN) of the entry to be deleted. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); cn.Bind(); cn.Delete("cn=test,dc=example,dc=com"); } ``` -------------------------------- ### Virtual List View (VLV) Search with C# Source: https://context7.com/flamencist/ldap4net/llms.txt Enables retrieving a subset of sorted results, ideal for implementing scrollable lists. Requires a sorted search and uses VLV controls to manage pagination. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(); var allResults = new List(); var pageSize = 10; var searchRequest = new SearchRequest( "dc=example,dc=com", "(objectClass=person)", LdapSearchScope.LDAP_SCOPE_SUBTREE ); // VLV requires sorting searchRequest.Controls.Add(new SortRequestControl("cn", false)); // Get entries starting at position 1 var vlvControl = new VlvRequestControl(0, pageSize - 1, 1); searchRequest.Controls.Add(vlvControl); while (true) { var response = (SearchResponse)cn.SendRequest(searchRequest); allResults.AddRange(response.Entries); var vlvResponse = response.Controls .OfType() .Single(); vlvControl.Offset += pageSize; if (vlvControl.Offset > vlvResponse.ContentCount) { break; } } Console.WriteLine($"Retrieved {allResults.Count} entries using VLV"); } ``` -------------------------------- ### Get RootDSE Information in C# Source: https://github.com/flamencist/ldap4net/blob/master/README.md Retrieves RootDSE (Directory Service Agent) information from the LDAP server. RootDSE provides information about the server itself. Requires an active and bound LdapConnection. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); cn.Bind(); var rootDse = connection.GetRootDse(); } ``` -------------------------------- ### Directory Synchronization (DirSync) with C# Source: https://context7.com/flamencist/ldap4net/llms.txt Implements Active Directory's DirSync control to track directory changes. Requires DS-Replication-Get-Changes extended right. Handles initial and incremental synchronization using a cookie. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("dc.example.com", 389); cn.Bind(); var searchRequest = new SearchRequest( "dc=example,dc=com", "(objectClass=*)", LdapSearchScope.LDAP_SCOPE_SUBTREE ); var dirSyncControl = new DirSyncRequestControl { Cookie = new byte[0], Option = DirectorySynchronizationOptions.IncrementalValues, AttributeCount = int.MaxValue }; searchRequest.Controls.Add(dirSyncControl); // Initial sync - get all entries var response = (SearchResponse)cn.SendRequest(searchRequest); Console.WriteLine($"Initial sync: {response.Entries.Count} entries"); // Get cookie for incremental sync var responseControl = response.Controls .OfType() .FirstOrDefault(); if (responseControl != null) { // Store cookie for next sync byte[] syncCookie = responseControl.Cookie; // Later: get changes since last sync dirSyncControl.Cookie = syncCookie; response = (SearchResponse)cn.SendRequest(searchRequest); Console.WriteLine($"Changes since last sync: {response.Entries.Count}"); } } ``` -------------------------------- ### Get User Authorization ID with WhoAmI in C# Source: https://github.com/flamencist/ldap4net/blob/master/README.md Obtains the authorization ID of the current user using the 'WhoAmI' extended operation. This is useful for identifying the authenticated user. Requires an active and bound LdapConnection. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); cn.Bind(); var authzId = connection.WhoAmI().Result; } ``` -------------------------------- ### Perform Asynchronous LDAP Search with Cancellation Source: https://context7.com/flamencist/ldap4net/llms.txt Demonstrates how to perform asynchronous LDAP searches and how to cancel them using a CancellationTokenSource. This is useful for maintaining application responsiveness during long-running search operations. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); await cn.BindAsync(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "password"); // Async search var entries = await cn.SearchAsync("dc=example,dc=com", "(objectClass=person)"); Console.WriteLine($"Found {entries.Count} entries"); } // Async search with cancellation using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); await cn.BindAsync(); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); try { var entries = await cn.SearchAsync("dc=example,dc=com", "(objectClass=*)", cancellationToken: cts.Token); } catch (OperationCanceledException) { Console.WriteLine("Search was cancelled"); } } ``` -------------------------------- ### Get Group Members using AsqRequestControl in C# Source: https://github.com/flamencist/ldap4net/blob/master/README.md Retrieves all members of a specified group (e.g., 'Domain Admins') using the AsqRequestControl. This control is used to request specific attributes from search results. Requires an active LdapConnection. ```csharp using (var connection = new LdapConnection()) { connection.Connect(); connection.BindAsync().Wait(); var directoryRequest = new SearchRequest("CN=Domain Admins,CN=Users,dc=example,dc=com", "(objectClass=user)", LdapSearchScope.LDAP_SCOPE_BASE); directoryRequest.Controls.Add(new AsqRequestControl("member")); var response = (SearchResponse)connection.SendRequest(directoryRequest); } ``` -------------------------------- ### Add Source: https://github.com/flamencist/ldap4net/blob/master/README.md Adds a new entry to the LDAP directory. ```APIDOC ## Add ### Description This operation adds a new entry to the LDAP directory with specified attributes. ### Method `Add` ### Endpoint N/A (Client-side operation) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **entry** (LdapEntry) - The LDAP entry object to add: - **Dn** (string) - The Distinguished Name for the new entry. - **Attributes** (Dictionary>) - A dictionary of attributes for the new entry, where keys are attribute names and values are lists of attribute values. ### Request Example ```csharp using (var cn = new LdapConnection()) { cn.Connect(); cn.Bind(); cn.Add(new LdapEntry { Dn = "cn=test,dc=example,dc=com", Attributes = new Dictionary> { {"sn", new List {"Winston"}}, {"objectclass", new List {"inetOrgPerson"}}, {"givenName", new List {"your_name"}}, {"description", new List {"your_description"}} } }); } ``` ### Response #### Success Response (200) Successful addition operation does not return specific data, but the entry is created in the directory. #### Response Example N/A ``` -------------------------------- ### Get Single Notification from LDAP Server using DirectoryNotificationControl in C# Source: https://github.com/flamencist/ldap4net/blob/master/README.md Fetches a single notification from an LDAP server using the DirectoryNotificationControl. This is useful for monitoring specific directory changes. It utilizes a CancellationTokenSource for asynchronous operations and collects results in a list. ```csharp var cts = new CancellationTokenSource(); using (var connection = new LdapConnection()) { var results = new List(); connection.Connect(); connection.BindAsync().Wait(); var directoryRequest = new SearchRequest("CN=Administrator,CN=Users,dc=example,dc=com", "(objectClass=*)", LdapSearchScope.LDAP_SCOPE_BASE, "mail") { OnPartialResult = searchResponse => { results.AddRange(searchResponse.Entries); cts.Cancel(); } }; var directoryNotificationControl = new DirectoryNotificationControl(); directoryRequest.Controls.Add(directoryNotificationControl); var response = (SearchResponse) connection.SendRequestAsync(directoryRequest,cts.Token).Result; } ``` -------------------------------- ### Verify OpenLDAP Library Symlinks on Linux Source: https://github.com/flamencist/ldap4net/blob/master/linux.md This command demonstrates how to check for the existence and target of the libldap.so.2 and liblber.so.2 symlinks in the /usr/lib directory. It shows the typical output when these links are correctly configured. ```shell root@linux ~ % ls -l /usr/lib/libldap.so.2 lrwxrwxrwx 1 root root 10 Jul 18 2021 /usr/lib/libldap.so.2 -> libldap.so root@linux ~ % ls -l /usr/lib/libldap.so lrwxrwxrwx 1 root root 21 Jul 18 2021 /usr/lib/libldap.so -> libldap-2.4.so.2.11.7 root@linux ~ % ls -l /usr/lib/liblber.so.2 lrwxrwxrwx 1 root root 10 Jul 18 2021 /usr/lib/liblber.so.2 -> liblber.so root@linux ~ % ls -l /usr/lib/liblber.so lrwxrwxrwx 1 root root 21 Jul 18 2021 /usr/lib/liblber.so -> liblber-2.4.so.2.11.7 ``` -------------------------------- ### Connect to LDAP Server using Default Settings Source: https://github.com/flamencist/ldap4net/blob/master/README.md Establishes a connection to an LDAP server using the default port (389) and deriving the domain controller host from the computer's hostname. This method is suitable for environments where the computer's hostname can be resolved to the domain controller. ```csharp using (var cn = new LdapConnection()) { // connect use Domain Controller host from computer hostname and default port 389 // Computer hostname - mycomp.example.com => DC host - example.com cn.Connect(); .... } ``` -------------------------------- ### Bind SASL Proxy with Negotiate Authentication (Windows) Source: https://github.com/flamencist/ldap4net/blob/master/README.md Demonstrates binding to an LDAP server using SASL Negotiate authentication on Windows systems, providing username and password. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); cn.Bind(LdapAuthType.Negotiate, new LdapCredential { UserName = "username", Password = "clearTextPassword" }); ... ``` -------------------------------- ### Add Entry Asynchronously (C#) Source: https://context7.com/flamencist/ldap4net/llms.txt Asynchronously adds a new LDAP entry to the directory. This method is suitable for non-blocking operations, improving application responsiveness. It requires establishing an LDAP connection and binding with credentials before initiating the asynchronous add operation. ```csharp using LdapForNet; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); await cn.BindAsync(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "adminpassword"); await cn.AddAsync(new LdapEntry { Dn = "cn=asyncuser,ou=users,dc=example,dc=com", DirectoryAttributes = new SearchResultAttributeCollection { new DirectoryAttribute { Name = "objectClass" }.AddValues(new[] { "inetOrgPerson" }), new DirectoryAttribute { Name = "cn" }.AddValues(new[] { "asyncuser" }), new DirectoryAttribute { Name = "sn" }.AddValues(new[] { "User" }) } }); Console.WriteLine("User added asynchronously"); } ``` -------------------------------- ### Bind SASL Proxy Source: https://github.com/flamencist/ldap4net/blob/master/README.md Demonstrates how to bind using SASL authorization proxy on both UNIX and Windows systems with different authentication types. ```APIDOC ## Bind SASL Proxy ### Description This section details how to perform SASL bind operations, which are used for secure authentication and authorization in LDAP. Examples are provided for both UNIX and Windows environments, showcasing different SASL mechanisms like Digest and GSSAPI. ### Method `Bind` ### Endpoint N/A (This is a client-side operation) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **LdapAuthType** (enum) - The SASL authentication type (e.g., `Digest`, `GssApi`, `Negotiate`). - **LdapCredential** (object) - Contains credentials for the bind operation: - **UserName** (string) - Optional. The username for authentication. - **Password** (string) - Optional. The password for authentication. - **AuthorizationId** (string) - Optional. The authorization ID to use for the bind (e.g., `dn:cn=admin,dc=example,dc=com` or `u:admin`). ### Request Example ```csharp using (var cn = new LdapConnection()) { cn.Connect(); // Example for Digest authentication on UNIX cn.Bind(LdapAuthType.Digest, new LdapCredential { UserName = "username", Password = "clearTextPassword", AuthorizationId = "dn:cn=admin,dc=example,dc=com" }); // Example for GSSAPI authentication on UNIX cn.Bind(LdapAuthType.GssApi, new LdapCredential { AuthorizationId = "u:admin" }); // Example for Negotiate authentication on Windows cn.Bind(LdapAuthType.Negotiate, new LdapCredential { UserName = "username", Password = "clearTextPassword" }); // ... rest of the operations } ``` ### Response #### Success Response (200) Successful bind operation does not return specific data, but the connection is established and authenticated. #### Response Example N/A ``` -------------------------------- ### Connect to LDAP Server with Hostname and Port Source: https://github.com/flamencist/ldap4net/blob/master/README.md Establishes a connection to a specified LDAP server using its hostname and a custom port. This provides flexibility in targeting specific LDAP servers and ports. ```csharp using (var cn = new LdapConnection()) { // connect use hostname and port cn.Connect("dc.example.com",636); .... } ``` -------------------------------- ### Connect to LDAP Server using LdapForNet Source: https://context7.com/flamencist/ldap4net/llms.txt Establishes a connection to an LDAP directory server using LdapForNet. Supports standard LDAP, LDAPS, Unix sockets, and custom timeouts. The connection must be established before binding. ```csharp using LdapForNet; using static LdapForNet.Native.Native; // Basic connection with hostname and port using (var cn = new LdapConnection()) { cn.Connect("dc.example.com", 389); // Connection established, ready to bind } // Connection with SSL/TLS (LDAPS) using (var cn = new LdapConnection()) { cn.Connect("dc.example.com", 636, LdapSchema.LDAPS); cn.TrustAllCertificates(); // For self-signed certificates // Continue with bind... } // Connection with URI using (var cn = new LdapConnection()) { cn.Connect(new Uri("ldaps://dc.example.com:636")); // Continue with bind... } // Connection with specific LDAP version using (var cn = new LdapConnection()) { cn.Connect(new Uri("ldap://dc.example.com:389"), LdapVersion.LDAP_VERSION3); // Continue with bind... } // Connection via Unix socket (Linux/macOS) using (var cn = new LdapConnection()) { cn.ConnectI("/var/run/ldapi"); // Continue with bind... } // Set connection timeout using (var cn = new LdapConnection()) { cn.Timeout = new TimeSpan(0, 1, 0); // 1 minute timeout cn.Connect("dc.example.com", 389); // Continue with bind... } ``` -------------------------------- ### Send Custom LDAP Requests with C# (Sync and Async) Source: https://context7.com/flamencist/ldap4net/llms.txt This C# code illustrates the use of the generic SendRequest method in ldap4net for performing custom LDAP operations, including synchronous delete and compare requests, and an asynchronous search request with cancellation. It requires an established LDAP connection and appropriate credentials. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "password"); // Delete using SendRequest var deleteResponse = cn.SendRequest(new DeleteRequest("cn=oldentry,dc=example,dc=com")); Console.WriteLine($"Delete result: {deleteResponse.ResultCode}"); // Compare request var compareResponse = cn.SendRequest( new CompareRequest("cn=user,dc=example,dc=com", "mail", "user@example.com")); Console.WriteLine($"Compare result: {compareResponse.ResultCode}"); // ResultCode.CompareTrue or ResultCode.CompareFalse } // Async version with cancellation using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); await cn.BindAsync(); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); var response = await cn.SendRequestAsync( new SearchRequest("dc=example,dc=com", "(cn=*)", LdapSearchScope.LDAP_SCOPE_SUBTREE), cts.Token ); } ``` -------------------------------- ### Connect to LDAP Server with Specific LDAP Version Source: https://github.com/flamencist/ldap4net/blob/master/README.md Establishes a connection to an LDAP server using a URI and explicitly specifies the LDAP version to use (e.g., LDAP_VERSION2). This is useful for compatibility with older LDAP servers. ```csharp using (var cn = new LdapConnection()) { // connect with ldap version 2 cn.Connect(new Uri("ldaps://dc.example.com:636"), LdapForNet.Native.Native.LdapVersion.LDAP_VERSION2); .... } ``` -------------------------------- ### Search LDAP Entries Asynchronously Source: https://github.com/flamencist/ldap4net/blob/master/README.md Demonstrates performing an asynchronous search for all objects in the LDAP catalog with the default subtree scope. Requires a connection and bind operation. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); cn.Bind(); //search all objects in catalog (default search scope = LdapSearchScope.LDAP_SCOPE_SUBTREE) var entries = cn.SearchAsync("dc=example,dc=com","(objectClass=*)").Result; } ``` -------------------------------- ### Bind SASL Proxy with Digest Authentication (UNIX) Source: https://github.com/flamencist/ldap4net/blob/master/README.md Demonstrates binding to an LDAP server using SASL Digest authentication on UNIX systems. It shows how to provide the username, password, and authorization ID in DN format. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); cn.Bind(LdapAuthType.Digest, new LdapCredential { UserName = "username", Password = "clearTextPassword", AuthorizationId = "dn:cn=admin,dc=example,dc=com" }); ... ``` -------------------------------- ### BindAsync using Kerberos Credentials Source: https://github.com/flamencist/ldap4net/blob/master/README.md Performs an asynchronous LDAP bind operation using Kerberos credentials. The `Wait()` method is called to block until the asynchronous operation completes. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); // bind using kerberos credential cache file cn.BindAsync().Wait(); ... } ``` -------------------------------- ### Sorted Search Results with C# Source: https://context7.com/flamencist/ldap4net/llms.txt Retrieves LDAP search results sorted by specified attributes. Supports ascending and descending order, and multiple sort keys for complex sorting. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(LdapAuthMechanism.SIMPLE, "cn=admin,dc=example,dc=com", "adminpassword"); var searchRequest = new SearchRequest( "dc=example,dc=com", "(objectClass=person)", LdapSearchScope.LDAP_SCOPE_SUBTREE ); // Sort by CN in ascending order searchRequest.Controls.Add(new SortRequestControl("cn", false)); var response = (SearchResponse)cn.SendRequest(searchRequest); foreach (var entry in response.Entries) { Console.WriteLine(entry.Dn); } } // Sort descending with multiple sort keys using (var cn = new LdapConnection()) { cn.Connect("ldap.example.com", 389); cn.Bind(); var searchRequest = new SearchRequest( "dc=example,dc=com", "(objectClass=person)", LdapSearchScope.LDAP_SCOPE_SUBTREE ); // Sort by sn ascending, then by givenName descending searchRequest.Controls.Add(new SortRequestControl( new SortKey("sn", null, false), new SortKey("givenName", null, true) )); var response = (SearchResponse)cn.SendRequest(searchRequest); } ``` -------------------------------- ### Set LDAP Options Source: https://github.com/flamencist/ldap4net/blob/master/README.md Sets specific options for an LDAP connection, such as the protocol version. Requires a connection. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); var ldapVersion = (int)LdapVersion.LDAP_VERSION3; cn.SetOption(LdapOption.LDAP_OPT_PROTOCOL_VERSION, ref ldapVersion); cn.Bind(); } ``` -------------------------------- ### Connect to LDAP Server using URI Source: https://github.com/flamencist/ldap4net/blob/master/README.md Connects to an LDAP server by providing a Uniform Resource Identifier (URI). This method supports specifying the schema (e.g., ldaps) and port directly within the URI. ```csharp using (var cn = new LdapConnection()) { // connect with URI cn.Connect(new Uri("ldaps://dc.example.com:636")); .... } ``` -------------------------------- ### GetOption Source: https://github.com/flamencist/ldap4net/blob/master/README.md Retrieves the current value of a specific LDAP connection option. ```APIDOC ## GetOption ### Description This method allows you to retrieve the current settings of various LDAP connection options. ### Method `GetOption` ### Endpoint N/A (Client-side operation) ### Parameters - **option** (LdapOption) - The LDAP option to retrieve the value for. ### Request Example ```csharp using (var cn = new LdapConnection()) { cn.Connect(); var ldapVersion = cn.GetOption(LdapOption.LDAP_OPT_PROTOCOL_VERSION); var host = cn.GetOption(LdapOption.LDAP_OPT_HOST_NAME); var refferals = cn.GetOption(LdapOption.LDAP_OPT_REFERRALS); cn.Bind(); // Bind is often required before some options are meaningful } ``` ### Response #### Success Response (200) - **T** - The value of the requested LDAP option, cast to the specified type `T`. #### Response Example ```json { "ldapVersion": 3, "host": "ldap.example.com", "refferals": "0x00000000" } ``` ``` -------------------------------- ### Search LDAP Entries with Binary Attributes Source: https://github.com/flamencist/ldap4net/blob/master/README.md Demonstrates searching for LDAP entries and retrieving attributes that may contain binary values, such as objectSid. Requires a connection and bind operation. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); cn.Bind(); var response = (SearchResponse) connection.SendRequest(new SearchRequest("cn=admin,dc=example,dc=com", "(&(objectclass=top)(cn=admin))", LdapSearchScope.LDAP_SCOPE_SUBTREE)); var directoryAttribute = response.Entries.First().Attributes["objectSid"]; var objectSid = directoryAttribute.GetValues().First(); } ``` -------------------------------- ### Add Binary Values to LDAP Entry Source: https://github.com/flamencist/ldap4net/blob/master/README.md Demonstrates how to add binary attribute values, such as images, to an LDAP entry using C#. It requires an active LdapConnection and a DirectoryAttribute object. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); cn.Bind(); var image = new DirectoryAttribute { Name = "jpegPhoto" }; image.Add(new byte[]{1,2,3,4}); directoryEntry.Attributes.Add(image); var response = (AddResponse)connection.SendRequest(new AddRequest("cn=test,dc=example,dc=com", image)); } ``` -------------------------------- ### Bind SASL Proxy with GSSAPI Authentication (UNIX) Source: https://github.com/flamencist/ldap4net/blob/master/README.md Demonstrates binding to an LDAP server using SASL GSSAPI authentication on UNIX systems, specifying the authorization ID as a user ID. ```csharp using (var cn = new LdapConnection()) { cn.Connect(); cn.Bind(LdapAuthType.GssApi, new LdapCredential { AuthorizationId = "u:admin" }); ... ``` -------------------------------- ### Bind to LDAP Server with Simple Authentication using LdapForNet Source: https://context7.com/flamencist/ldap4net/llms.txt Authenticates to the LDAP server using simple username and password authentication with LdapForNet. This is a common method for directory server connections. ```csharp using LdapForNet; using static LdapForNet.Native.Native; using (var cn = new LdapConnection()) { cn.Connect("ldap.forumsys.com", 389); // Bind using mechanism string cn.Bind(LdapAuthMechanism.SIMPLE, "cn=read-only-admin,dc=example,dc=com", "password"); // Now ready to perform LDAP operations var entries = cn.Search("dc=example,dc=com", "(objectClass=*)"); foreach (var entry in entries) { Console.WriteLine($"DN: {entry.Dn}"); } } // Alternative: Bind using LdapAuthType and LdapCredential using (var cn = new LdapConnection()) { cn.Connect("ldap.forumsys.com", 389); cn.Bind(LdapAuthType.Simple, new LdapCredential { UserName = "cn=read-only-admin,dc=example,dc=com", Password = "password" }); // Perform operations... } ``` -------------------------------- ### Connect with SSL and Trust All Certificates Source: https://github.com/flamencist/ldap4net/blob/master/README.md Establishes an SSL connection to an LDAP server on a specified port and schema (LDAPS). The `TrustAllCertificates` method is used to bypass certificate validation, which is suitable for development environments with self-signed certificates. ```csharp using (var cn = new LdapConnection()) { cn.Connect("dc.example.com", 636, LdapSchema.LDAPS); cn.TrustAllCertificates(); .... } ```