I read in this question that a common answer to the 0x error also covered in that aforesaid question is often to specify an account under which to search.
I realised that I'm already doing this - in fact, I'm trying to use active directory to authenticate a user to my application. Originally I thought the issue with my error related to how I was formulating my search parameter:
string domainAndUsername = domain + @"\" + username;
DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
Where _path
returned the URI. domainAndUsername
returned the following:
"domain.com\\usrname"
So I changed the instantiation to:
DirectoryEntry entry = new DirectoryEntry(_path, username, pwd);
returning "usr@domain.com" (I substituted "@domain.com" because my implementation will require the user to enter their email address and NT password).
That led me to consider the slight possibility that my test might be being performed under an account not privileged enough to perform directory searches - but I've already performed a search for the same data with another implementation - in the same project, no less.
So why does my implementation fall over with 0x80005000
whenever I try to use object obj = entry.NativeObject;
?
More importantly, why does this implementation fall over when my original one doesn't? For reference, this implementation is using the same format as demonstrated by Microsoft here, and my original (working) implementation is below:
public class dirSearch
{
public bool searchSuccessful;
public string errStr;
List<string> resList = new List<string>();
public void getEmpDetails(string filStr, string varStr)
{
string strServerDNS = "ldap.domain.com:389";
string strSearchBaseDN = "ou=People,o=domain.com";
string strLDAPPath = "LDAP://" + strServerDNS + "/" + strSearchBaseDN;
DirectoryEntry objDirEntry = new DirectoryEntry(strLDAPPath, null, null, AuthenticationTypes.Anonymous);
DirectorySearcher searcher = new DirectorySearcher(objDirEntry);
SearchResultCollection results;
searcher.Filter = "(uid=" + filStr + ")";
//make sure the order of the search is like so:
//UID
//empnum
//full name
searcher.PropertiesToLoad.Add(varStr);
try
{
results = searcher.FindAll();
foreach (SearchResult result in results)
{
string temStr = result.Properties[varStr][0].ToString();
resList.Add(temStr);
searchSuccessful = true;
}
}
catch (Exception e)
{
errStr = e.ToString();
searchSuccessful = false;
}
}
}
Further information:
I pulled the error code from the exception, which happened to be -2147463168. This corresponds to ADS_BAD_PATHNAME
. This is somewhat confusing, as LDAP://ldap.domain.com:389/ is correct. My theory is that I should be using a Distinguished Name, in which case I need to return to my original working method and pull the full name of the staff member, before then formulating the name with that information.
I noticed you're using anonymous authentication to login to your AD, I think you want to use username and password, then see if the user exists. Try the code below:
public bool IsAuthenticated(string username, string pwd)
{
string strLDAPServerAndPort = "ldap.domain.com:389";
string strLDAPContainer = "CN=Users,DC=domain,DC=com";
string strLDAPPath = "LDAP://" + strLDAPServerAndPort + "/" + strLDAPContainer;
DirectoryEntry objDirEntry = new DirectoryEntry(strLDAPPath, username, pwd);
try
{
//Bind to the native AdsObject to force authentication.
object obj = objDirEntry.NativeObject;
DirectorySearcher search = new DirectorySearcher(objDirEntry);
search.Filter = "(SAMAccountName=" + username + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
if (null == result)
{
return false;
}
}
catch (Exception ex)
{
throw new Exception("Error authenticating user. " + ex.Message);
}
return true;
}
User contributions licensed under CC BY-SA 3.0