Unlocking user Account - c#

I am trying to set properties to unlock User accounts in AD and I am using the following code; the problem is that de does not contain userAccountControl and the code fails.
I can get the value of userAccountControl by using DirectorySearcher but that does not help me in setting the property using de. Could anyone please help me? Thanks in advance
String m_Path = "LDAP://" + distinguishedName;
using (DirectoryEntry de = new DirectoryEntry(m_Path))
{
if (de.Contains("userAccountControl")
{
int m_Val = (int)de.Properties["userAccountControl"][0].Value;
de.Properties["userAccountControl"].Value = m_Val | 0x0001
de.CommitChanges;
}
}

I would think you need to check whether de.Properties contains a value of userAccountControl!
string ldapPath = "LDAP://" + distinguishedName;
using(DirectoryEntry de = new DirectoryEntry(ldapPath))
{
// check to see if we have "userAccountControl" in the **properties** of de
if(de.Properties.Contains("userAccountControl")
{
int m_Val = (int)de.Properties["userAccountControl"][0].Value ;
de.Properties["userAccountControl"].Value = m_Val | 0x0001;
de.CommitChanges();
}
}
Also, if you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find and manipulate users and/or groups in AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// unlock user
user.UnlockAccount();
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!

Related

Setting flags for users (Active Directory)

at the moment I am trying to write some code to help our support and having some problems. I am creating a user in the OU, setting all needed attributes and having trouble setting the flags.
string ADPath1 = "LDAP://127.0.0.1/OU=TEST,DC=abc,DC=def,DC=local";
string ADUser = "admin";
string ADPassword = "somepw";
DirectoryEntry de = new DirectoryEntry(ADPath1, ADUser, ADPassword, AuthenticationTypes.Secure);
I am connecting, and setting everything up
DirectoryEntries users = de.Children;
DirectoryEntry newuser = users.Add("CN=" + "Artemij Voskobojnikov", "user");
newuser.Properties["property"].Add("XXX");
Now I'd like to setup the userAccountControl-propery and am trying to do the following:
const int UF_PASSWD_CANT_CHANGE = 0x0040;
const int UF_DONT_EXPIRE_PASSWD = 0x10000;
int user_flags = UF_PASSWD_CANT_CHANGE + UF_DONT_EXPIRE_PASSWD;
newuser.Properties["userAccountControl"].Value = user_flags
I am getting an error, something like "Server cannot execute the operation". Is there any way to do this or do I have to use UserPrincipal?
Kind regards
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context and bind to the OU=Test container
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN", "OU=TEST"))
{
// create a new user
UserPrincipal user = new UserPrincipal(ctx);
// set first name, last name, display name, SAM Account Name and other properties easily
user.DisplayName = "Artemij Voskobojnikov";
user.GivenName = "Artemij";
user.Surname = "Voskobojnikov";
user.SamAccountName = "AVoskobojnikov";
// set some flags as appropriate for your use
user.UserCannotChangePassword = true;
user.PasswordNeverExpires = true;
// save user
user.Save();
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!

How to get and filter AD first & last name in ASP.NET

I am trying to search by AD username and display the First and Last Name to a table.
This is what I have so far:
DirectoryEntry myLDAPConnection = new DirectoryEntry("LDAP://company.com");
DirectorySearcher dSearch = new DirectorySearcher(myLDAPConnection);
I understand I need to do something with my dSearch object to filter what is returned, but I have no clue what to do beyond this.
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// do something here....
}
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
// if found....
if (group != null)
{
// iterate over members
foreach (Principal p in group.GetMembers())
{
Console.WriteLine("{0}: {1}", p.StructuralObjectClass, p.DisplayName);
// do whatever you need to do to those members
}
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!

Cannot access sn, givenName in LDAP

I am very new to C# and I'm using LDAP to 1) validate a user's login credentials and 2) obtain additional information about the user for my app. Our LDAP server doesn't allow some of the data I'm requesting to be given out anonymously, so I have to wait until I bind with the user's full credentials to pull the data. However, even then I have not been able to obtain simple fields like sn, and givenName. Using JXplorer I can see where these values are hidden during an anonymous connection, but with a full user/SSL/password combination I can see everytning in JXplorer. I just can't seem to do the same via my code.
If I loop through the properties after my first FindOne(), there are 9 properties found (none of which are the ones I'm looking for). If I loop through the properties after my second FindOne(), there are only 4 properties available. Neither results seems to be impacted by PropertiesToAdd.Add("...").
Any suggestions would be appreciated.
public string[] Authenticate(string user, string password)
{
string[] results = new string [2];
//Concatenate serverpath + username + container
//I.e. "LDAP://ldap.disney.com:636/CN=donaldDuck,ou=people,dc=la,dc=disney,dc=com"
DirectoryEntry de = new DirectoryEntry(_ldapserver + "cn=" + user + "," + _topContainer);
//User's password for initial verification
de.Password = password;
//initate anonymous bind
de.AuthenticationType = System.DirectoryServices.AuthenticationTypes.SecureSocketsLayer;
DirectorySearcher searcher = new DirectorySearcher(de);
searcher.SearchScope = System.DirectoryServices.SearchScope.Base;
//Search for first record
SearchResult result = searcher.FindOne();
//Check results
if (result == null) throw new Exception(ERR_NOT_FOUND);
de = result.GetDirectoryEntry();
//Return search results
//results[0] = (string)de.Properties["mail"].Value;
// results[1] = (string)de.Properties["givenName"].Value + " " + (string)de.Properties["sn"].Value;
// Distingushed Name of the found account
string DN = de.Path.Substring(de.Path.ToUpper().IndexOf("CN="));
// Close search connection
de.Close();
// now bind and verify the user's password,
de = new DirectoryEntry(_ldapserver + _topContainer);
de.Username = DN;
de.Password = password;
de.AuthenticationType = System.DirectoryServices.AuthenticationTypes.SecureSocketsLayer;
//Obtain additional information
searcher = new DirectorySearcher(de);
searcher.PropertiesToLoad.Add("sn");
searcher.PropertiesToLoad.Add("givenName");
SearchResult r = searcher.FindOne();
de = r.GetDirectoryEntry();
foreach (string property in de.Properties.PropertyNames)
{
Console.WriteLine("\t{0} : {1} ", property, de.Properties[property][0]);
}
//End obtain additional information
//Validate password
Object obj = de.NativeObject;
de.Close();
//if we made it here, we successfully authenticated
return results;
}
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// validate given user credentials
bool isValid = ctx.ValidateCredentials(user, password);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
string surname = user.Surname;
string givenName = user.GivenName;
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!

Domain Users group is not getting for an active directory user

We are using the following code to get the groups of an active directory user.
StringCollection groups = new StringCollection();
try
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domainName, userName, password))
{
//find user roles
UserPrincipal user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, loginUserName);
if (user != null)
{
DirectoryEntry de = (DirectoryEntry)user.GetUnderlyingObject();
object obGroups = de.Invoke("Groups");
foreach (object ob in (IEnumerable)obGroups)
{
DirectoryEntry obGpEntry = new DirectoryEntry(ob);
groups.Add(obGpEntry.Name);
}
}
}
}
catch (Exception e)
{
}
This is working almost as expected. But while we checking the users with Domain Users group, the method didn't return the group name. Some users are only with this Domain Users group and while we calling this method for such users its returning an empty group.
Any suggestions please..
It's a well-known and documented "omission" that the so called primary group is not returned from the Groups method in this code. There are some rather cryptic ways around this - or try this other approach:
if you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// the call to .GetAuthorizationGroups() will return **all** groups that
// user is a member of - including the primary group and all nested
// group memberships, too!
var result = user.GetAuthorizationGroups();
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
Update: if you insist on using the old legacy technology, check out this blog post by Ryan Dunn which explains in great detail how to get the primary group for an AD account in C#.

How to get username and SID for user by a domain name in ldap

I am trying to get the user information for a specific domain which will be the input of the program. On the basis of the domain name it should return the list of the users name/ or NT Id and SID of the user. I am new for the ldap programming can any one help me for get this list.
If you're on .NET 3.5 and up and talking about Active Directory, then you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// do something here....
var usersSid = user.Sid;
// not sure what you mean by "username" - the "DisplayName" ? The "SAMAccountName"??
var username = user.DisplayName;
var userSamAccountName = user.SamAccountName;
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
Update: if you need to loop through all the users of a domain - try this:
You can use a PrincipalSearcher and a "query-by-example" principal to do your searching:
// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// define a "query-by-example" principal - here, we search for a UserPrincipal
UserPrincipal qbeUser = new UserPrincipal(ctx);
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find all matches
foreach(var found in srch.FindAll())
{
UserPrincipal user = found as UserPrincipal;
if(user != null)
{
// do whatever here
var usersSid = user.Sid;
// not sure what you mean by "username" - the "DisplayName" ?
var username = user.DisplayName;
var userSamAccountName = user.SamAccountName;
}
}
Update #2: if you can't (or don't want to) use the S.DS.AM approach - which is the easiest, for Active Directory, by far - then you need to fall back to the System.DirectoryServices classes and methods:
// define the root of your search
DirectoryEntry root = new DirectoryEntry("LDAP://dc=YourCompany,dc=com");
// set up DirectorySearcher
DirectorySearcher srch = new DirectorySearcher(root);
srch.Filter = "(objectCategory=Person)";
srch.SearchScope = SearchScope.Subtree;
// define properties to load
srch.PropertiesToLoad.Add("objectSid");
srch.PropertiesToLoad.Add("displayName");
// search the directory
foreach(SearchResult result in srch.FindAll())
{
// grab the data - if present
if(result.Properties["objectSid"] != null && result.Properties["objectSid"].Count > 1)
{
var sid = result.Properties["objectSid"][0];
}
if(result.Properties["displayName"] != null && result.Properties["displayName"].Count > 0)
{
var userName = result.Properties["displayName"][0].ToString();
}
}

Categories