35

I haven't worked with an LDAP before so I am a bit lost. I need to connect to an LDAP source find a specific attribute and change it. The input for the program is a CSV file with a list of users. The program is supposed to read the UID from the CSV file find the record in the LDAP and replace a certain attribute. I haven't a clue how to do this. Could any one point me in the right direction please?

Lucas
  • 3,376
  • 6
  • 31
  • 46
Graeme
  • 351
  • 1
  • 3
  • 3
  • 1
    Since you mention that you read UID from a CSV I get the feeling that you might not be connecting to an Active Directory LDAP repository, since normally the LDAP attribute you use is either cn, name, distinguishedname, objectguid, objectsid, userprincipalname or samaccountname and not UID. So please be a bit more specific on what you are connecting to and what you are changing. Also tell us what the "path" or LDAP search root is which you need to connect to is. – CosmosKey Jun 23 '11 at 16:41
  • 1
    Another resource if you're looking to use LDS. ftp://ftp.ca.com/pub/ldap/docs/ldapv3/eTrust_LDAP_Server_Administrator_Guide_30.pdf – AA11oAKas Nov 02 '12 at 14:27
  • 3
    The following article could be usefull: [Using .NET C# LDAP Library](http://www.novell.com/coolsolutions/feature/11204.html). – Akram Shahda Jun 23 '11 at 10:34

3 Answers3

27

@KenL Almost got me there. I also had to set the AuthenticationType of the DirectoryEntry to get it to work. Also, pay attention to how you are using wildcards (Kleene Stars).

DirectoryEntry rootEntry = new DirectoryEntry("LDAP://some.ldap.server.com");
rootEntry.AuthenticationType = AuthenticationTypes.None; //Or whatever it need be
DirectorySearcher searcher = new DirectorySearcher(rootEntry);
var queryFormat = "(&(objectClass=user)(objectCategory=person)(|(SAMAccountName=*{0}*)(cn=*{0}*)(gn=*{0}*)(sn=*{0}*)(email=*{0}*)))";
searcher.Filter = string.Format(queryFormat, searchString);
foreach(SearchResult result in searcher.FindAll()) 
{
    Console.WriteLine("account name: {0}", result.Properties["samaccountname"].Count > 0 ? result.Properties["samaccountname"][0] : string.Empty);
    Console.WriteLine("common name: {0}", result.Properties["cn"].Count > 0 ? result.Properties["cn"][0] : string.Empty);
}
rstackhouse
  • 2,238
  • 24
  • 28
  • Excellent stuff, this got me up and running really quickly. FYI: use alternative constructors for the DirectoryEntry class to bind if you can't search anonymously – sweetlilmre Jun 12 '14 at 06:12
  • 2
    Searchstring is not defined, but besides that your code was copy-paste :) – sonstabo Jan 03 '17 at 13:20
19

First Element of response, using ADSI (old fashion)

How to do Almost everything (with ADSI) on Active Directory with C#

Second Element of response, begining .NET 3.5 Microsoft introduce 'Principal' and 'AccountManagement'.

How to do Almost everything (with AccountManagement) on Active Directory with C#

Third Element of response, you can use low level (native LDAP) protocol with System.DirectoryServices.Protocols (S.DS.P).

Remark : If you are interested in how to interrogate active directory from native code, you may have a look to LDAP C-Binding API as discribed in RFC 1823 specifies, Microsoft support it, see MS Strategy for Lightweight Directory Access Protocol (LDAP). You'll find the using and reference manuals of the Microsoft API in Lightweight Directory Access Protocol.

John C
  • 3,052
  • 3
  • 34
  • 47
JPBlanc
  • 70,406
  • 17
  • 130
  • 175
13

code wise it is a lot simpler than you think. You need to create a connection to the directory, set up a searcher, then search by property name.

DirectoryEntry entry = new DirectoryEntry("LDAP://MyDomain.com");
DirectorySearcher dSearch = new DirectorySearcher(entry);
dSearch.Filter = "(&(objectCategory=person)(objectClass=user)(" + SType + "=" + Name + "))";

SType is the name type, and Name is the actual user name

KenL
  • 865
  • 5
  • 14
  • When unit testing is a concern, mocking DirectorySearcher is problematic. – Mario Tacke Aug 08 '14 at 15:49
  • @MarioTacke Should generally not mock a DS - mock at a higher abstraction, DS code itself (inside the the higher mocked typed) is tested via integrations. – user2864740 Aug 09 '18 at 18:40
  • 1
    but how would you retrieve result from dsearch. I am not able to figure that out that how to find if the user is found or not. – Priyanka Arora Jul 24 '20 at 13:08