I have one gMSA user created. I am trying to get the user sid-
ContextType contextType= ContextType.Domain;
PrincipalContext domainContext = new PrincipalContext(contextType, domain);
using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName))
{
if (foundUser != null)
{
identity = foundUser.Sid.Value;
result = true;
}
}
The gMSA user is under a domain such as contoso.ab.cd.com
I ran in to this issue as well. In my environment, I noticed that the gMSA accounts are not in the UserPrincipal at all. Rather, they are in ComputerPrincipal. Try the following:
ContextType contextType= ContextType.Domain;
PrincipalContext domainContext = new PrincipalContext(contextType, domain);
using (var foundUser = ComputerPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName))
{
if (foundUser != null)
{
identity = foundUser.Sid.Value;
result = true;
}
}
Related
I tried to change/reset password to user that has to change his password after first login using c#
My code:
var domain = WebConfigurationManager.AppSettings["ONLINE-AD"];
directoryEntry.Username = userName;
directoryEntry.Password = password;
var directorySearcher = new DirectorySearcher(directoryEntry);
SearchResult result = directorySearcher.FindOne();
if (result != null)
{
DirectoryEntry userEntry = result.GetDirectoryEntry();
if (userEntry != null)
{
userEntry.Invoke("SetPassword", model.Resetpassword);
userEntry.CommitChanges();
}
}
But when I tried to do FindOne() i got an error 773 (means that the user has to change password for first time)
here is the error :
How to access user using LDAP ?(I successed to do login with
proper user)
I created Admin user that can manage all users then I got all users using the admin and find the wanted user and set password to this user:
public string ResetPassword(LoginDTO model) {
try {
//get context by admin user
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, WebConfigurationManager.AppSettings["ONLINE-AD"], WebConfigurationManager.AppSettings["AdminName"], WebConfigurationManager.AppSettings["AdminPassword"]);
//find the wanted user
var user = UserPrincipal.FindByIdentity(ctx, model.UserName);
if (user != null) {
try {
user.ChangePassword(model.Password, model.NewPassword);
} catch {
return "-1";
}
}
} catch (Exception ex) {
return "-1";
}
return "1"
}
I want to find if the user belongs to an AD group. Can you advise how I can add that functionality using the following code?
I ask the user to enter their username and password (through a form), so not using the windows credentials. With the below code I am able to validate the user, by passing the username, and password. How can I build on the code to check if user exists in the AD Group. Is there another way to do this? Please advice
DirectoryEntry adsEntry = new DirectoryEntry("domain", userid, password);
DirectorySearcher adsSearcher = new DirectorySearcher(adsEntry);
try {
SearchResult adsSearchResult = adsSearcher.FindOne();
context.Session.Timeout = 2;
context.Session["ValidatedLoginID"] = userid;
user.Verified = true;
adsEntry.Close();
} catch ( Exception ex ) {
// Failed to authenticate. Most likely it is caused by unknown user
// id or bad strPassword.
user.error = ex.Message;
adsEntry.Close();
}
You can use the below code:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "DOMAINNAME");
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
if(user != null)
{
// check if user is member of that group
if (user.IsMemberOf(group))
{
// do something.....
}
}
Also look at: How to check if a user belongs to an AD group?
Here is how I solved this :
DirectoryEntry adsEntry = new DirectoryEntry("domain", userid, password);
DirectorySearcher adsSearcher = new DirectorySearcher(adsEntry);
adsSearcher.Filter = "(&(objectClass=user)(objectCategory=person)(sAMAccountName=" + userid + "))";
try
{
SearchResult adsSearchResult = adsSearcher.FindOne();
string propertyName = "memberOf";
ResultPropertyValueCollection rpvcResult = adsSearchResult.Properties[propertyName];
foreach (Object PropertyValue in rpvcResult)
{
if (PropertyValue.ToString() == "Group Name")
{
user.Verified = true;
user.FullName = GetFullName(userid);
adsEntry.Close();
} else
{
user.Verified = false;
user.error = "You do not belong to the Group so you cannot do this function";
}
}
} catch (Exception ex)
{
user.error = "Please check your username and password credentials";
adsEntry.Close();
}
I am finding user name from Active Directory by passing email id. It is working fine. But it takes 30-40 seconds to get the username. Is there any other better way to find the username from Active Directory by email address?
Please refer to my code:
using (PrincipalContext context = new PrincipalContext(ContextType.Domain, "domainname"))
{
UserPrincipal userPrincipal = new UserPrincipal(context);
PrincipalSearcher principalSearch = new PrincipalSearcher(userPrincipal);
foreach (UserPrincipal result in principalSearch.FindAll())
{
if (result != null && result.EmailAddress != null && result.EmailAddress.Equals(user.Email, StringComparison.OrdinalIgnoreCase))
{
user.FirstName = result.GivenName;
user.LastName = result.Surname;
}
}
}
You don't need to enumerate all users to to find one of them! Try this code:
using (PrincipalContext context = new PrincipalContext(ContextType.Domain, "domainname"))
{
UserPrincipal yourUser = UserPrincipal.FindByIdentity(context, EmailAddress);
if (yourUser != null)
{
user.FirstName = yourUser.GivenName;
user.LastName = yourUser.Surname;
}
}
If that shouldn't work, or if you need to search for several criteria at once, used the PrincipalSearcher with the QBE (query-by-example) approach - search the one user you need - don't cycle through all users!
// create your domain context
using (PrincipalContext context = new PrincipalContext(ContextType.Domain, "domainname"))
{
// define a "query-by-example" principal -
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.EmailAddress = yourEmailAddress;
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find all matches
foreach(var found in srch.FindAll())
{
// do whatever here - "found" is of type "Principal" - it could be user, group, computer.....
}
}
using System.DirectoryServices.AccountManagement;
// Lock user
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
UserPrincipal yourUser = UserPrincipal.FindByIdentity(context, logonName);
if (yourUser != null)
{
if(!yourUser.IsAccountLockedOut())
{
yourUser.Enabled = False;
yourUser.Save();
}
}
}
I need to let users bind there accounts to the Active Directory. This means that admin needs a GUI where he/she can write a Active Directory account like this : MyDomain\MyName and then get a validation if the users exists before save.
Im using this code to validate the name :
public static bool CheckActiveDirectoryAccount(string account)
{
string ADServer = null;
string ADDomain = null;
string ADUserName = null;
string ADUserPassword = null;
SetADSettings(out ADServer, out ADDomain, out ADUserName, out ADUserPassword);
using (PrincipalContext context = new PrincipalContext(ContextType.Domain, ADServer, ADUserName, ADUserPassword))
{
using (UserPrincipal user = UserPrincipal.FindByIdentity(context, account))
{
if(user != null)
return true;
else
return false;
}
}
}
The problem with this code is that there seems to be no way to check the user for a specific domain? Instead I have to input the server, if I try to input the domain instead there will be exception(Server not found).
How do I let the admin enter domain and username of a AD account and then check it against the AD?
I am able to pass the domain into the principalcontext without issue, I'm not passing in the server. I would expect this to work for you.
public static bool CheckActiveDirectoryAccount(string account, string domain)
{
using (var pc = new PrincipalContext(ContextType.Domain, domain))
{
// Find a user
UserPrincipal user = UserPrincipal.FindByIdentity(pc, account);
if (user == null)
return false;
return true;
}
}
I have noticed poor performance when passing in the NetBIOS domain name, though it does work. As a result I pass in the DNS domain name whenever possible.
I ended up with this :
public static string CheckActiveDirectoryAccount(string account)
{
UserPrincipal user;
PrincipalContext context;
List<string> userPrincipalNameList;
string ADServer = null;
string ADUserName = null;
string ADUserPassword = null;
string userAccount;
account = account.ToLower();
GetADSettings(out ADServer, out ADUserName, out ADUserPassword);
if (ADUserName.Length > 0)
context = new PrincipalContext(ContextType.Domain, ADServer, null, ADUserName, ADUserPassword);
else
context = new PrincipalContext(ContextType.Domain, ADServer);
using (context)
{
if((user = UserPrincipal.FindByIdentity(context, account)) == null)
{
if(account.Contains("\\"))
{
userPrincipalNameList = user.UserPrincipalName.Split('\\').ToList();
if (userPrincipalNameList.Count > 0)
user = UserPrincipal.FindByIdentity(context, userPrincipalNameList[0]);
}
}
if (user != null)
{
using (user)
{
userPrincipalNameList = user.UserPrincipalName.Split('#').ToList();
userAccount = userPrincipalNameList.First();
if (userPrincipalNameList.Count > 1)
userAccount = userPrincipalNameList.Last() + "\\" + userAccount;
if (user != null)
return userAccount.ToLower();
}
}
}
return string.Empty;
}
I am logged in under user User001 under domain DomainA and with password Pass001.
I use this code
//var principalContext = new PrincipalContext(
//ContextType.Domain,
//"DomainA",
//"User001",
//"Pass001");
var principalContext = new PrincipalContext(
ContextType.Domain,
domain,
userName,
password);
var userPrincipal = new UserPrincipal(principalContext);
And userPrincipal is always NULL.
How to fix it?
Somehow this code I found is working fine...
using (var context = new PrincipalContext(ContextType.Domain))
{
using (UserPrincipal principal = UserPrincipal.FindByIdentity(context, userName))
{
var uGroups = principal.GetGroups();
foreach (var group in uGroups)
{
Debug.WriteLine(group.DisplayName);
}
}
}