Creating users in Active Directory is actually just like creating any other object in the directory. We simply create an instance of the class we want and set any required attributes on the object. However, to get a fully functional user object that is "enabled," has a password, and has other useful attributes takes a bit more work.
But first, the basics! Let's create a user object in an organizational unit called people that exists in the root of our domain (see Listing 10.1).
Listing 10.1. Creating an Active Directory or ADAM User
DirectoryEntry parent = new DirectoryEntry( "LDAP://OU=people,DC=mydomain,DC=com", null, null, AuthenticationTypes.Secure ); DirectoryEntry user = parent.Children.Add("CN=test.user", "user"); using (user) { //sAMAccountName is required for W2k AD, we would not use //this for ADAM, however. user.Properties["sAMAccountName"].Value = "test.user"; //userPrincipalName is not required, but recommended //for ADAM. AD also contains this, so we can use it. user.Properties["userPrincipalName"].Value = "test.user"; user.CommitChanges(); } |
As Listing 10.1 demonstrates, creating a user is pretty simple. We just need to know the distinguished name (DN) of the object that will serve as the user's parent container. This is typically an organizational unit, but it could be a container or a lot of different things in ADAM. We should also note that ADAM is slightly different from Active Directory in that sAMAccountName does not exist in ADAM, so there are actually no required attributes! Instead, we chose to populate userPrincipalName (which is a good idea in both Active Directory and ADAM). The userPrincipalName attribute is one of the accepted names used for binding to the directory.
If we remember from Chapter 3, we know that creating an object requires supplying a relative distinguished name (RDN) value. The prefix that we should use is defined in the schema by the rDNAttId attribute on the class. Active Directory and ADAM tend to use the CN RDN prefix for a number of object types; however, it is not uncommon for third-party LDAP directories from other vendors to use something different (e.g., UID). The RDN prefix (e.g., CN, OU, O, etc.) will differ slightly by object, but for user objects, we should generally choose the CN prefix. Essentially, we must always supply the name using the correct RDN attribute name for the class being created.
In Listing 10.1, we set the sAMAccountName attribute. This is not strictly required in the Windows 2003 version of Active Directory, but it is in the Windows 2000 version. Windows 2003 Active Directory will pick a random name for us, though, so it is probably a good idea to set one intentionally, especially since this is the user's login name in the Windows NT format (domainlogin).
While the code in Listing 10.1 will create a user object in Active Directory (and with slight modification, in ADAM) it will not be very useful. The user account will not have a password, it will contain very few attributes, and it will not even be enabled by default. While some of these attributes are simple strings that do not require anything particularly complicated to set, passwords and account properties are more complicated. The sections that follow detail how to deal with them and make user accounts behave like the user accounts we have come to expect.
Managing User Account Features |
Part I: Fundamentals
Introduction to LDAP and Active Directory
Introduction to .NET Directory Services Programming
Binding and CRUD Operations with DirectoryEntry
Searching with the DirectorySearcher
Advanced LDAP Searches
Reading and Writing LDAP Attributes
Active Directory and ADAM Schema
Security in Directory Services Programming
Introduction to the ActiveDirectory Namespace
Part II: Practical Applications
User Management
Group Management
Authentication
Part III: Appendixes
Appendix A. Three Approaches to COM Interop with ADSI
Appendix B. LDAP Tools for Programmers
Appendix C. Troubleshooting and Help
Index