How do I change phone number in Active Directory using C# - c#

I have this code where I can change the display name, password, etc. in the Active Directory
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, userName);
userPrincipal.DisplayName = "Some NAME";
userPrincipal.SetPassword("NEW_PASSWORD");
userPrincipal.Save();
I have looked at the properties of userPrincipal and I can not find the phone number property. My question is how do I change the phone number for the User in the code.
Thank You

Correction (Sorry for all the edits):
Here's what I do......
public static void SetUserInfo(string userName)
{
var dsDirectoryEntry = new DirectoryEntry("LDAP://xxxx/DC=xx,DC=xxx", "ADusername", "ADpassword");
var dsSearch = new DirectorySearcher(dsDirectoryEntry) { Filter = "(&(objectClass=user)(SAMAccountName=" + userName + "))" };
var dsResults = dsSearch.FindOne();
var myEntry = dsResults.GetDirectoryEntry();
//myEntry.Properties[property].Value = value;
myEntry.Properties["telephoneNumber"].Value = "222-222-2222";
myEntry.CommitChanges();
}

Related

How to authenticate users in C# LDAP

I am new to LDAP related coding and today I am asked to develop a code to check the users authentication against LDAP.
The tutorials I have found online are so simple but our company's Directory is so complicated that I don't know how to write a code for that. Here is the info of the LDAP . I have changed the company name to hide the name.
uri = ldaps://ABC.ad.XYZ.com:636
user_filter = memberOf=CN=TENXAIRFLOWPROD,OU=Security Groups,OU=Normal Users and Groups,OU=Account Management Services,OU=AD Master OU,DC=ABC,DC=ad,DC=XYZ,DC=com
user_name_attr = sAMAccountName
superuser_filter = memberOf=CN=TENXAIRFLOWPROD_ADM,OU=Security Groups,OU=Normal Users and Groups,OU=Account Management Services,OU=AD Master OU,DC=ABC,DC=ad,DC=XYZ,DC=com
bind_user = SCGLOBAL\twiki
bind_password_cmd = python /bns/tenx/airflow/ldap_password.py
basedn = DC=ABC,DC=ad,DC=XYZ,DC=com
search_scope = SUBTREE
Here is a code I have developed but it gives me error:
string username = "myUserName";
string domain = "ldaps://ABC.ad.XYZ.com:636";
string pwd = "myPasword";
try
{
DirectoryEntry entry = new DirectoryEntry(domain, username, pwd);
//Bind to the native AdsObject to force authentication.
object obj = entry.NativeObject;
lblError.Text=("Login Successful");
//search some info of this user if any
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + username + ")";
SearchResult result = search.FindOne();
}
catch (Exception ex)
{
lblError.Text=("Login failed: " + ex.ToString());
}
Could anybody help plz?
Comment: According to the admin , I have been assigned to the group in AD. But how can I make sure I can access it?
It seems like Active Directory. If so, you could just use PrincipalContext.
public bool ValidateCredentials(string domain, string username, string password)
{
using (var context = new PrincipalContext(ContextType.Domain, domain))
{
return context.ValidateCredentials(username, password);
}
}
public bool IsUserInAdGroup(string domain, string username, string adGroupName)
{
bool result = false;
using (var context = new PrincipalContext(ContextType.Domain, domain))
{
var user = UserPrincipal.FindByIdentity(context, username);
if (user != null)
{
var group = GroupPrincipal.FindByIdentity(context, adGroupName);
if (group != null && user.IsMemberOf(group))
result = true;
}
}
return result;
}
Please make sure to reference System.DirectoryServices.AccountManagement.

Retrieving User Name from Active Directory

I am trying to retrieve the User Name from Active Directory. I have found this piece of code to try however, it does not recognize the User portion of User.Identity.Name. I have looked to see if I need to add another reference or assembly however I have not seen anything. Is there a better way of getting the User Name from Active Directory?
static string GetUserName(){
string name = "";
using (var context = new PrincipalContext(ContextType.Domain))
{
var usr = UserPrincipal.FindByIdentity(context, User.Identity.Name);
if (usr != null)
name = usr.DisplayName;
}
}
You can use WindowsIdentity.GetCurrent
using System.Security.Principal;
static string GetUserName()
{
WindowsIdentity wi = WindowsIdentity.GetCurrent();
string[] parts = wi.Name.Split('\\');
if(parts.Length > 1) //If you are under a domain
return parts[1];
else
return wi.Name;
}
Usage:
string fullName = GetUserName();
Happy to help you!
How about:
public string GetUserName()
{
string name = "";
using (var context = new PrincipalContext(ContextType.Domain))
{
var usr = UserPrincipal.Current;
if (usr != null)
{
name = usr.DisplayName;
}
}
}

Add none UserPrincipal field to AD entry

I am trying to add a none UserPrincipal field to a small application, but I just cannot get it to work. I tried several ways to do this simple task, but I cannot get anything to work for me. I am trying to ADD a field called Company to be inserted into the Active Directory, but Company is not a field that can be inserted...
Any ideas? Please post a code example if you have one. I have this so far:
public bool CreateNewUser(string sUserName, string sPassword, string sGivenName, string sSurname, string email, string phone)
{
if (!IsUserExisting(sUserName))
{
string sOU = "OU=Users,OU=External,DC=external,DC=rootteck,DC=com";
PrincipalContext oPrincipalContext = GetPrincipalContext(sOU);
UserPrincipal oUserPrincipal = new UserPrincipal(oPrincipalContext, sUserName, sPassword, true /*Enabled or not*/);
//User Log on Name
oUserPrincipal.Name = sUserName;
oUserPrincipal.UserPrincipalName = sUserName + "#external.rootteck.com";
oUserPrincipal.GivenName = sGivenName;
oUserPrincipal.Surname = sSurname;
oUserPrincipal.EmailAddress = email;
oUserPrincipal.DisplayName = sGivenName + " " + sSurname;
if (phone != string.Empty) { oUserPrincipal.VoiceTelephoneNumber = phone; }
oUserPrincipal.PasswordNeverExpires = true;
oUserPrincipal.Save();
return true;
}
else
{
return false;
//return GetUser(sUserName);
}
}

Using C# to authenticate user against LDAP

I'm using DirectorySearcher to search for a user entry in LDAP server.
DirectoryEntry de = new DirectoryEntry();
de.Path = "LDAP://myserver/OU=People,O=mycompany";
de.AuthenticationType = AuthenticationTypes.None;
DirectorySearcher deSearch = new DirectorySearcher();
deSearch.SearchRoot = de;
deSearch.Filter = "(uid=" + model.UserName + ")";
SearchResult result = deSearch.FindOne();
I'm able to get th intended output in result variable.
However If I try to authenticate the same user by providing password in directory entry, I always get following error.
"The user name or password is incorrect."
DirectoryEntry entry = new DirectoryEntry("LDAP://myserver/OU=People,O=mycompany", username, password);
DirectorySearcher search = new DirectorySearcher(
entry,
"(uid=" + username + ")",
new string[] { "uid" }
);
search.SearchScope = System.DirectoryServices.SearchScope.Subtree;
SearchResult found = search.FindOne(); ->>>>>this is where I get wrong credential error.
The username and password are for the user I want to authenticate.
Can anyone tell me what I'm doing wrong here or how to debug this.
This username, password within this line:
DirectoryEntry("LDAP://myserver/OU=People,O=mycompany", username, password);
should be for an account that has permission for directory lookup. It could be a service account or testing purpose try with your own. This shouldn't be the user/pass of someone who you are trying to authenticate.
If you want to authenticate, you can use following steps using PrincipalContext:
using(var context = new PrincipalContext(ContextType.Domain, "mydomain", "mydomain\serviceAcct", "serviceAcctPass")) {
//Username and password for authentication.
return context.ValidateCredentials(username, password);
}
"serviceAcct" = an account within domain users that has permission for directory lookup.
"serviceAcctPass" = password for that service account.
As I said, for testing you can try with your own user/pass context.
Also, make sure supplied username has either "domain\username" or "username#domain" formatting.
Here we are getting the active directory user details and we can use DomainName and UserRole from web.config file
bool isAdmin = false;
RegisterInput model = new RegisterInput();
NewUserInput usr = new NewUserInput();
SearchResultCollection results;
string mobileNumber = string.Empty;
using (DirectoryEntry domainEntry = new DirectoryEntry("LDAP://" + AppSettings.DomainName))
{
using (DirectorySearcher searcher = new DirectorySearcher(domainEntry, "userPrincipalName=" + userName + "#" + AppSettings.DomainName) { Filter = string.Format("(&(objectClass=user)(samaccountname={0}))", userName) })
{
results = searcher.FindAll();
if (results.Count > 0)
{
usr.FirstName = results[0].GetDirectoryEntry().Properties["givenName"].Value.ToString();
usr.LastName = results[0].GetDirectoryEntry().Properties["sn"].Value?.ToString();
usr.EmailAddress = results[0].GetDirectoryEntry().Properties["mail"].Value?.ToString();
mobileNumber = results[0].GetDirectoryEntry().Properties["mobile"]?.Value?.ToString();
dynamic userRoleList = results[0].GetDirectoryEntry().Properties["memberOf"];
if (userRoleList != null)
{
foreach (var role in userRoleList)
{
string[] split = role.ToString().Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
bool result = split.Any(x => x.ToLowerInvariant() == AppSettings.UserRole.ToLowerInvariant());
if (result)
{
isAdmin = true;
break;
}
}
}
}
}
}
model.NewUser = usr;

Get parent OU of user in Active Directory using C#

I want to check, if a a user is in a specific parent OU.
How can I do that?
Check below code for a clear desciption of what I am looking for.
using System.DirectoryServices.AccountManagement;
public bool IsUserInOU(string samAccountName, string OUName){
using (var context = new PrincipalContext(ContextType.Domain))
{
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, samAccountName))
{
//Check if the user is in the OU specified in OUName
//Something like:
//return user.IsInOU(OUName);
}
}
}
public void TestIt_1(){
//The parent OU of this user is "AwesomeOU"
string samAccountName = "Joe";
string OUName = "AwesomeOU";
bool expected = true;
bool actual = IsUserInOU(samAccountName, OUName);
Assert.AreEqual(expected, actual);
}
public void TestIt_2(){
//The parent OU of this user is "WhateverOU"
string samAccountName = "Mike";
string OUName = "AwesomeOU";
bool expected = false;
bool actual = IsUserInOU(samAccountName, OUName);
Assert.AreEqual(expected, actual);
}
The Domain:
National OU
Awesome OU
Joe
Whatever OU
Mike
Solution 1 after empi's answer
With the information given by empi, I wrote the below method to extract the first OU in the DistinguishedName. Having done that, the rest is a breeze.
public static string GetOUForUser(string samAccountName)
{
using (var context = new PrincipalContext(ContextType.Domain))
{
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, samAccountName))
{
//System.Console.WriteLine(user.DistinguishedName);
int startIndex = user.DistinguishedName.IndexOf("OU=", 1) + 3; //+3 for length of "OU="
int endIndex = user.DistinguishedName.IndexOf(",", startIndex);
var group = user.DistinguishedName.Substring((startIndex), (endIndex - startIndex));
return group;
}
}
}
Solution 2 after JPBlanc's answer
public static string GetOUForUser(string samAccountName)
{
using (var context = new PrincipalContext(ContextType.Domain))
{
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, samAccountName))
{
using (DirectoryEntry deUser = user.GetUnderlyingObject() as DirectoryEntry)
{
using (DirectoryEntry deUserContainer = deUser.Parent)
{
return deUserContainer.Properties["Name"].Value.ToString();
}
}
}
}
}
Ok #Empi solution is working, but UserPrincipal is built on DirectoryEntry objects that provides a parent or container properties that just give you the object you are looking for, without using string way.
/* Retreiving a principal context
*/
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, "WM2008R2ENT:389", "dc=dom,dc=fr", "dom\\jpb", "MyPwd");
/* Retreive a user
*/
UserPrincipal user = UserPrincipal.FindByIdentity(domainContext, "user1");
/* Retreive the container
*/
DirectoryEntry deUser = user.GetUnderlyingObject() as DirectoryEntry;
DirectoryEntry deUserContainer = deUser.Parent;
Console.WriteLine (deUserContainer.Properties["distinguishedName"].Value);
This information is in UserPrincipal.DistinguishedName. You should check if DistinguishedName ends with "," + ou distinguished name (case insensitive). However, you must know the distingushed name of ou you're checking.
For example, if dn is: CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=COM, then it says that user is in OU=Sales,DC=Fabrikam,DC=COM ou.
This is how I would get the Distinguished Name for a specific AD user, hope it helps :-)
private static string GetDNOfUser(string user)
{
var ctx = new PrincipalContext(ContextType.Domain, Environmentals.Domain, Environmentals.OUPath);
//Creating object for search filter
UserPrincipal userPrin = new UserPrincipal(ctx)
{
//Only getting users with the same name as the input
Name = user
};
var searcher = new PrincipalSearcher
{
//Applying filter to query
QueryFilter = userPrin
};
//Finding the user
var results = searcher.FindOne();
searcher.Dispose();
//Return the distinguishedname
return results.DistinguishedName;
}

Categories