I have been banging my head for quite a while with this and can't get it to work. I have a LDAP Query I do have working in AD Users and Computers but dont know how to do it programatically in C#.
Here are my LDAP Query that works fine in the AD Tool: (memberOf=CN=AccRght,OU=Groups,OU=P,OU=Server,DC=mydomain,DC=com)(objectCategory=user)(objectClass=user)(l=City)
I have used this code to get the user accounts to get members of CN=AccRght but I'm not succeeding on limiting users belonging to a specific city.
public StringCollection GetGroupMembers(string strDomain, string strGroup)
{
StringCollection groupMemebers = new StringCollection();
try
{
DirectoryEntry ent = new DirectoryEntry("LDAP://DC=" + strDomain + ",DC=com");
DirectorySearcher srch = new DirectorySearcher("(CN=" + strGroup + ")");
SearchResultCollection coll = srch.FindAll();
foreach (SearchResult rs in coll)
{
ResultPropertyCollection resultPropColl = rs.Properties;
foreach( Object memberColl in resultPropColl["member"])
{
DirectoryEntry gpMemberEntry = new DirectoryEntry("LDAP://" + memberColl);
System.DirectoryServices.PropertyCollection userProps = gpMemberEntry.Properties;
object obVal = userProps["sAMAccountName"].Value;
if (null != obVal)
{
groupMemebers.Add(obVal.ToString());
}
}
}
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
return groupMemebers;
}
Thanks for any help!
Well, basically all you need is to transfer that LDAP filter you're using in the tool into your DirectorySearcher - something like this:
public StringCollection GetGroupMembers(string strDomain, string strGroup)
{
StringCollection groupMemebers = new StringCollection();
try
{
DirectoryEntry ent = new DirectoryEntry("LDAP://DC=" + strDomain + ",DC=com");
DirectorySearcher srch = new DirectorySearcher();
// build the LDAP filter from your (CN=strGroup) part that you had
// in the constructor, plus that filter you used in the AD tool
// to "AND" those together, use the LDAP filter syntax:
// (&(condition1)(condition2))
srch.Filter = string.Format("(&(CN={0})(memberOf=CN=AccRght,OU=Groups,OU=P,OU=Server,DC=mydomain,DC=com)(objectCategory=user)(objectClass=user)(l=City))", strGroup);
SearchResultCollection coll = srch.FindAll();
foreach (SearchResult rs in coll)
{
ResultPropertyCollection resultPropColl = rs.Properties;
foreach( Object memberColl in resultPropColl["member"])
{
DirectoryEntry gpMemberEntry = new DirectoryEntry("LDAP://" + memberColl);
System.DirectoryServices.PropertyCollection userProps = gpMemberEntry.Properties;
object obVal = userProps["sAMAccountName"].Value;
if (null != obVal)
{
groupMemebers.Add(obVal.ToString());
}
}
}
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
return groupMemebers;
}
That should apply that filter to your search, e.g. you should now only get back users for that specific city.
Definitely check out this MSDN article Managing Directory Security Principals in the .NET Framework 3.5 - excellent intro to S.DS.AM ! :-)
If you are actually looking for a way to recursively enumerate group members, maybe you need to use the recursive version of memberof (which you can achieve by using the (memberof:1.2.840.113556.1.4.1941:=(cn=Group1,OU=groupsOU,DC=x))) syntax).
More info here: http://msdn.microsoft.com/en-us/library/aa746475(VS.85).aspx
Related
I am trying to get a list of employees of a manager given his DN.
Assuming logged in user is a manager,
1) Search for the manager in active directory using the sAMAccountName (i.e. Domain ID) and retrieve the distinguishedName
2) Search for all user objects in active directory with the "manager" attribute equal to the previously retrieved distinguishedName
However, my Directory Entry Collection is always empty. Here is what I have done, assuming user/manager's DN is given.
private static List<DirectoryEntry> GetUserDEByManagerDN(string sDN)
{
string adPath = ConfigurationManager.AppSettings["ADPath"].ToString();
DirectoryEntry de = new DirectoryEntry(adPath + "/" + sDN);
List<DirectoryEntry> lsUsers = new List<DirectoryEntry>();
using (DirectorySearcher Search = new DirectorySearcher())
{
Search.SearchRoot = de;
Search.Filter = "(&(manager=" + sDN + "))";
//Search.Filter = "(&(manager=" + sDN + ")(extensionAttribute14=INV))";
Search.SearchScope = SearchScope.Base; // Also tried SearchScope.Subtree
SearchResultCollection Results = Search.FindAll();
if (null != Results) // Results is not null but has zero length
{
foreach (SearchResult Result in Results)
{
DirectoryEntry deUser = Result.GetDirectoryEntry();
if (null != deUser)
lsUsers.Add(deUser);
}
}
}
return lsUsers;
}
I also tried escaping DN using:
string sEscapedDN = sDN.Replace('\\', '\x5C').Replace(')', '\x29').Replace('(', '\x28').Replace('*', '\x2A');
No Luck. Any help is appreciated.
Following itsme86's suggestion to set the container that has all of the users and Camilo Terevinto's specific suggestion to remove manager's DN from AD path, the issue was resolved. I also had to change the search scope from base to subtree.
Below is what worked for me:
private static List<DirectoryEntry> GetUserDEByManagerDN(string sManagerDN)
{
string adPath = ConfigurationManager.AppSettings["ADPath"].ToString();
/* This was one of the issues */
//DirectoryEntry de = new DirectoryEntry(adPath + "/" + sManagerDN);
DirectoryEntry de = new DirectoryEntry(adPath);
List<DirectoryEntry> lsUsers = new List<DirectoryEntry>();
using (DirectorySearcher Search = new DirectorySearcher())
{
Search.SearchRoot = de;
/* I had to include extension attribute 14 to get rid of some unusual "users", like Fax, special accounts, etc. You might not need it
//Search.Filter = "(manager=" + sDN + ")";
Search.Filter = "(&(manager=" + sDN + ")(extensionAttribute14=INV))";
//Search.SearchScope = SearchScope.Base;
Search.SearchScope = SearchScope.Subtree;
SearchResultCollection Results = Search.FindAll();
if (null != Results)
{
foreach (SearchResult Result in Results)
{
DirectoryEntry deUser = Result.GetDirectoryEntry();
if (null != deUser)
lsUsers.Add(deUser);
}
}
}
return lsUsers;
}
I have a problem in my SearchResult querying Active Directory. Here is what I try to do: I can search users from Active Directory and then show their name in a link form. This works. Then when you click on link it has to show all the information on the user. I uses lists to pass the query results, and when I search a name in Active Directory I have a full list of results, but when try to show the information of a specific user, my list is always null and I can't figure out why.
Here is my search result page with the links:
#{
var incLoop = 0;
var incArr = 0;
var list = (List<string>)ViewData["Names"];
var size = list.Count();
string[] objSID = new string[size];
foreach (var link in list)
{
if (incLoop % 2 == 0)
{
objSID[incArr] = link;
incArr++;
<p>#incArr</p>
}
else
{
#link
}
incLoop++;
}
}
When you click the link, it then does a research of AD using sAMAccountName parameter, here is the controller :
public ActionResult ShowUserInfo(string name)
{
ADManager adManager = new ADManager();
List<string> info = adManager.UserInformation(name);
if (info != null)
{
ViewData["UserInfo"] = info;
return View();
}
else
return View("SearchUser");
}
And finally here is my function that searches in AD from the ADManager class
public List<string> UserInformation(string SAMAccountName)
{
try
{
DirectoryEntry ldapConnection = createDirectoryEntry();
DirectorySearcher search = new DirectorySearcher(ldapConnection);
search.Filter = "(sAMAccountName="+ SAMAccountName + ")";
search.PropertiesToLoad.Add("displayName");
search.PropertiesToLoad.Add("userPrincipalName");
search.PropertiesToLoad.Add("description");
search.PropertiesToLoad.Add("accountExpires");
search.PropertiesToLoad.Add("memberOf");
search.PropertiesToLoad.Add("profilePath");
search.PropertiesToLoad.Add("objectSID");
search.PropertiesToLoad.Add("anr");
resultCollection = search.FindAll();
//result = search.FindOne();
foreach (SearchResult sr in resultCollection)
{
lastName.Add(sr.Properties["anr"][0].ToString());
lastName.Add(sr.Properties["displayName"][0].ToString());
lastName.Add(sr.Properties["userPrincipalName"][0].ToString());
lastName.Add(sr.Properties["description"][0].ToString());
lastName.Add(sr.Properties["accountExpires"][0].ToString());
lastName.Add(sr.Properties["memberOf"][0].ToString());
lastName.Add(sr.Properties["profilePath"][0].ToString());
lastName.Add(sr.Properties["objectSID"][0].ToString());
}
return lastName;
}
catch(Exception e)
{
Console.WriteLine("Exception caught:\n\n" + e.ToString());
}
return null;
}
}
createDirectoryEntry() allows to create the connection to AD, and ADManager class contains all the access functions to AD. Normally I should be able to use a simple SearchResult.FindOne() for this query since sAMAccountName is unique but it didn't work so I tried with collections (since this works for searching all users using anr parameter from AD).
EDIT: I forgot to say that I have an exception: System.ArgumentException in System.DirectoryServices.dll when I click on user links. So probably the problem comes from ADManager search query.
Thanks for your help, if unclear I can add precision.
I am trying to get detailed information about a user's group membership using directory services queries to the global catalog. I don't want to use GetAuthorizationGroups() because it's flaky.
There are 2 domains: DomainA and DomainB. The global catalog server is a domain controller for DomainB. Finally, there is a user (UserA) which is part of DomainA.
I find UserA in the global catalog and look at the tokenGroups property to get the SIDs of all groups to which UserA belongs.
To my great surprise, I find that DomainB\Domain Users is included in the list. Why is this being included, given that UserA is not part of DomainB?
Here is the code I'm running:
using (DirectoryEntry gc = new DirectoryEntry("GC:"))
{
string userPrincipalName = "UserA#DomainA.local";
DirectoryEntry searchRoot = null;
gc.AuthenticationType = System.DirectoryServices.AuthenticationTypes.Secure;
// There is only 1 child under "GC:".
foreach (DirectoryEntry de in gc.Children)
{
searchRoot = de;
break;
}
using (searchRoot)
{
SearchResult samResult;
using (var samSearcher = new DirectorySearcher())
{
// Find the user.
samSearcher.SearchRoot = searchRoot;
samSearcher.Filter = "(userPrincipalName=" + userPrincipalName + ")";
samSearcher.PropertiesToLoad.Add("distinguishedName");
samResult = samSearcher.FindOne();
}
List<byte[]> tokenGroups;
using (DirectoryEntry theUser = samResult.GetDirectoryEntry())
{
theUser.RefreshCache(new string[] { "tokenGroups" });
tokenGroups = theUser.Properties["tokenGroups"].Cast<byte[]>().ToList();
IdentityReferenceCollection irc = new IdentityReferenceCollection(tokenGroups.Count);
foreach (byte[] groupSidBytes in tokenGroups)
{
irc.Add(new SecurityIdentifier(groupSidBytes, 0));
}
List<string> groupNames =
irc.Translate(typeof(NTAccount), true)
.Cast<NTAccount>()
.Select(a => a.Value.ToString())
.ToList();
return groupNames;
}
}
}
I am admittedly very new to AD. I have a dropdown list that I have bound with a list of members within our organization. My end goal is to find their manager name, but I'm starting with baby steps.
I've done enough searching to get the right result. I'm having a problem getting the right data (verified by using breakpoints etc) out of the result
private void cmbUserList_SelectedIndexChanged(object sender, EventArgs e)
{
var userName = cmbUserList.SelectedValue.ToString();
DirectorySearcher search = new DirectorySearcher();
search.Filter = String.Format("(cn={0})", userName);
search.PropertiesToLoad.Add("givenName");
SearchResult result = search.FindOne();
if (result != null)
{
// For now I'm trying to just retrieve their name
lblManagerName.Text = result.GetDirectoryEntry().Name;
}
}
EDIT: I'm using .net version 4.0
Could someone point me towards retrieving the correct name, and then maybe even a link or resources to pull the manager name?
I think the problem with your code is you are using "(cn={0})", userName. You need to pass fully qualified name like
CN=Doe,John,OU=Users,OU=Headquarters,DC=company,DC=net
If you only have login ID, then the code below should work
DirectorySearcher directorySearcher = new DirectorySearcher("LDAP://RootDSE");
directorySearcher.Filter = "sAMAccountName=" + acctName;
directorySearcher.PropertiesToLoad.Add("manager");
SearchResult searchResult = directorySearcher.FindOne();
if (searchResult != null)
DirectoryEntry user = searchResult.GetDirectoryEntry();
Note that acctName is Windows login ID. If you want to play with AD and check out vearious properties and how they are stored, try dsquery and dsget command line tools. The command below will return a user record based on login id and will display contents of the manager field:
dsquery user domainroot -samid "loginid" | dsget user -samid -mgr
helper class and enum
public enum ActiveDirectoryObjectClass
{
Computer,
User,
Domain,
Group,
}
public static class ActiveDirectorySearcher
{
public static string GetCurrentDomainName()
{
string result;
using (Domain domain = Domain.GetCurrentDomain())
{
result = domain.Name;
}
return result;
}
public static IEnumerable<T> Select<T>(
ActiveDirectoryObjectClass activeDirectoryObjectClass,
Func<DirectoryEntry, ActiveDirectoryObjectClass, bool> condition,
Func<DirectoryEntry, T> selector
)
{
List<T> list = new List<T>();
using (Domain domain = Domain.GetCurrentDomain())
using (DirectoryEntry root = domain.GetDirectoryEntry())
{
string filter = string.Format("(objectClass={0})", activeDirectoryObjectClass);
using (DirectorySearcher searcher = new DirectorySearcher(filter))
{
searcher.SearchRoot = root;
searcher.SearchScope = SearchScope.Subtree;
using (SearchResultCollection result = searcher.FindAll())
{
foreach (SearchResult item in result)
{
using (DirectoryEntry entry = item.GetDirectoryEntry())
{
if (condition(entry, activeDirectoryObjectClass))
{
list.Add(selector(entry));
}
}
}
}
}
}
return list;
}
}
how to use
public IEnumerable<User> GetUsers()
{
return ActiveDirectorySearcher.Select(
ActiveDirectoryObjectClass.User,
(entry, adObjectClass) => string.Compare(entry.SchemaClassName, adObjectClass.ToString(), StringComparison.InvariantCultureIgnoreCase) == 0,
_ => new User
{
Name = _.Name.Substring(3),
Domain = ActiveDirectorySearcher.GetCurrentDomainName(),
});
}
Note: User in sample - custom class with properties Name, Domain, etc.
to find name and/or manager name:
if (sResult != null)
{
string userName = sResult.Properties["name"][0].ToString();
string managerDN = sResult.Properties["manager"][0].ToString();
DirectoryEntry man = new DirectoryEntry("LDAP://server_name/"+managerDN);
string managerName = man.Properties["name"][0].ToString();
}
server_name can be just domain component of FQDN i.e yourcompany.com, that way it will find catalog server on its own via DNS.
Edit:
I also recomend Active Directory Explorer from Sysinternals. It is great tool for exploring and understanding structure of AD
I know that this type of question has been asked before, but other methods are failing me right now.
As it stands our windows service polls AD, given an LDAP (i.e. LDAP://10.32.16.80) and a list of usergroups within that AD server to search for.
It retrieves all users within those given groups, recursively searching those groups for more groups as well.
Each user is then added to another applications authenticated users list.
This part of the application is running successfully. However, we're in need of each user's friendly domain name (i.e. the part of their login DOMAIN/username)
So if there is a user that is part of TEST domain, named Steve: TEST/steve is his login.
I'm able to find steve in the AD, however I also need "TEST" to be stored along with his AD information.
Again, I can find 'steve' fine by using a directory searcher and the LDAP IP I'm given, but given the LDAP IP, how can I find the friendly domain name?
When I try the following code I'm given an error when attempting to access the 'defaultNamingContext':
System.Runtime.InteropServices.COMException (0x8007202A): The authentication mechanism is unknown.
Here is the code:
private string SetCurrentDomain(string server)
{
string result = string.Empty;
try
{
logger.Debug("'SetCurrentDomain'; Instantiating rootDSE LDAP");
DirectoryEntry ldapRoot = new DirectoryEntry(server + "/rootDSE", username, password);
logger.Debug("'SetCurrentDomain'; Successfully instantiated rootDSE LDAP");
logger.Debug("Attempting to retrieve 'defaultNamingContext'...");
string domain = (string)ldapRoot.Properties["defaultNamingContext"][0]; //THIS IS WHERE I HIT THE COMEXCEPTION
logger.Debug("Retrieved 'defaultNamingContext': " + domain);
if (!domain.IsEmpty())
{
logger.Debug("'SetCurrentDomain'; Instantiating partitions/configuration LDAP entry");
DirectoryEntry parts = new DirectoryEntry(server + "/CN=Partitions,CN=Configuration," + domain, username, password);
logger.Debug("'SetCurrentDomain'; Successfully instantiated partitions/configuration LDAP entry");
foreach (DirectoryEntry part in parts.Children)
{
if (part.Properties["nCName"] != null && (string)part.Properties["nCName"][0] != null)
{
logger.Debug("'SetCurrentDomain'; Found property nCName");
if ((string)part.Properties["nCName"][0] == domain)
{
logger.Debug("'SetCurrentDomain'; nCName matched defaultnamingcontext");
result = (string)part.Properties["NetBIOSName"][0];
logger.Debug("'SetCurrentDomain'; Found NetBIOSName (friendly domain name): " + result);
break;
}
}
}
}
logger.Debug("finished setting current domain...");
}
catch (Exception ex)
{
logger.Error("error attempting to set domain:" + ex.ToString());
}
return result;
}
edit
I added this sample method in order to attempt a suggestion but am getting an exception: "Unspecified error" when I hit the "FindAll()" call on the searcher.
The string being passed in is: "CN=TEST USER,CN=Users,DC=tempe,DC=ktregression,DC=com"
private string GetUserDomain(string dn)
{
string domain = string.Empty;
string firstPart = dn.Substring(dn.IndexOf("DC="));
string secondPart = "CN=Partitions,CN=Configuration," + firstPart;
DirectoryEntry root = new DirectoryEntry(secondPart, textBox2.Text, textBox3.Text);
DirectorySearcher searcher = new DirectorySearcher(root);
searcher.SearchScope = SearchScope.Subtree;
searcher.ReferralChasing = ReferralChasingOption.All;
searcher.Filter = "(&(nCName=" + firstPart + ")(nETBIOSName=*))";
try
{
SearchResultCollection rs = searcher.FindAll();
if (rs != null)
{
domain = GetProperty(rs[0], "nETBIOSName");
}
}
catch (Exception ex)
{
}
return domain;
This article helped me much to understand how to work with the Active Directory.
Howto: (Almost) Everything In Active Directory via C#
From this point forward, if you require further assitance, please let me know with proper questions in comment, and I shall answer them for you to the best of my knowledge.
EDIT #1
You had better go with this example's filter instead. I have written some sample code to briefly show how to work with the System.DirectoryServices and System.DirectoryServices.ActiveDirectory namespaces. The System.DirectoryServices.ActiveDirectory namespace is used to retrieve information about the domains within your Forest.
private IEnumerable<DirectoryEntry> GetDomains() {
ICollection<string> domains = new List<string>();
// Querying the current Forest for the domains within.
foreach(Domain d in Forest.GetCurrentForest().Domains)
domains.Add(d.Name);
return domains;
}
private string GetDomainFullName(string friendlyName) {
DirectoryContext context = new DirectoryContext(DirectoryContextType.Domain, friendlyName);
Domain domain = Domain.GetDomain(context);
return domain.Name;
}
private IEnumerable<string> GetUserDomain(string userName) {
foreach(string d in GetDomains())
// From the domains obtained from the Forest, we search the domain subtree for the given userName.
using (DirectoryEntry domain = new DirectoryEntry(GetDomainFullName(d))) {
using (DirectorySearcher searcher = new DirectorySearcher()){
searcher.SearchRoot = domain;
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("sAMAccountName");
// The Filter is very important, so is its query string. The 'objectClass' parameter is mandatory.
// Once we specified the 'objectClass', we want to look for the user whose login
// login is userName.
searcher.Filter = string.Format("(&(objectClass=user)(sAMAccountName={0}))", userName);
try {
SearchResultCollection results = searcher.FindAll();
// If the user cannot be found, then let's check next domain.
if (results == null || results.Count = 0)
continue;
// Here, we yield return for we want all of the domain which this userName is authenticated.
yield return domain.Path;
} finally {
searcher.Dispose();
domain.Dispose();
}
}
}
Here, I didn't test this code and might have some minor issue to fix. This sample is provided as-is for the sake of helping you. I hope this will help.
EDIT #2
I found out another way out:
You have first to look whether you can find the user account within your domain;
If found, then get the domain NetBIOS Name; and
concatenate it to a backslash (****) and the found login.
The example below uses a NUnit TestCase which you can test for yourself and see if it does what you are required to.
[TestCase("LDAP://fully.qualified.domain.name", "TestUser1")]
public void GetNetBiosName(string ldapUrl, string login)
string netBiosName = null;
string foundLogin = null;
using (DirectoryEntry root = new DirectoryEntry(ldapUrl))
Using (DirectorySearcher searcher = new DirectorySearcher(root) {
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("sAMAccountName");
searcher.Filter = string.Format("(&(objectClass=user)(sAMAccountName={0}))", login);
SearchResult result = null;
try {
result = searcher.FindOne();
if (result == null)
if (string.Equals(login, result.GetDirectoryEntry().Properties("sAMAccountName").Value))
foundLogin = result.GetDirectoryEntry().Properties("sAMAccountName").Value
} finally {
searcher.Dispose();
root.Dispose();
if (result != null) result = null;
}
}
if (!string.IsNullOrEmpty(foundLogin))
using (DirectoryEntry root = new DirectoryEntry(ldapUrl.Insert(7, "CN=Partitions,CN=Configuration,DC=").Replace(".", ",DC="))
Using DirectorySearcher searcher = new DirectorySearcher(root)
searcher.Filter = "nETBIOSName=*";
searcher.PropertiesToLoad.Add("cn");
SearchResultCollection results = null;
try {
results = searcher.FindAll();
if (results != null && results.Count > 0 && results[0] != null) {
ResultPropertyValueCollection values = results[0].Properties("cn");
netBiosName = rpvc[0].ToString();
} finally {
searcher.Dispose();
root.Dispose();
if (results != null) {
results.Dispose();
results = null;
}
}
}
Assert.AreEqual("FULLY\TESTUSER1", string.Concat(netBiosName, "\", foundLogin).ToUpperInvariant())
}
The source from which I inspired myself is:
Find the NetBios Name of a domain in AD
Since I could not find any example code I would like to share my own solution. This will search the parents of the DirectoryEntry object until it hits the domainDNS class.
using System.DirectoryServices;
public static class Methods
{
public static T ldap_get_value<T>(PropertyValueCollection property)
{
object value = null;
foreach (object tmpValue in property) value = tmpValue;
return (T)value;
}
public static string ldap_get_domainname(DirectoryEntry entry)
{
if (entry == null || entry.Parent == null) return null;
using (DirectoryEntry parent = entry.Parent)
{
if (ldap_get_value<string>(parent.Properties["objectClass"]) == "domainDNS")
return ldap_get_value<string>(parent.Properties["dc"]);
else
return ldap_get_domainname(parent);
}
}
}
Use it like this:
string[] _properties = new string[] { "objectClass", "distinguishedName", "samAccountName", "userPrincipalName", "displayName", "mail", "title", "company", "thumbnailPhoto", "useraccountcontrol" };
string account = "my-user-name";
// OR even better:
// string account = "my-user-name#DOMAIN.local";
using (DirectoryEntry ldap = new DirectoryEntry())
{
using (DirectorySearcher searcher = new DirectorySearcher(ldap))
{
searcher.PropertiesToLoad.AddRange(_properties);
if (account.Contains('#')) searcher.Filter = "(userPrincipalName=" + account + ")";
else searcher.Filter = "(samAccountName=" + account + ")";
var user = searcher.FindOne().GetDirectoryEntry();
Console.WriteLine("Name: " + Methods.ldap_get_value<string>(user.Properties["displayName"]));
Console.WriteLine("Domain: " + Methods.ldap_get_domainname(user));
Console.WriteLine("Login: " + Methods.ldap_get_domainname(user) + "\\" + Methods.ldap_get_value<string>(user.Properties["samAccountName"]));
}
}
I haven't got a forest to test it on but in theory this should cut it.
You can retrieve the name of the domain that the current user is on using the Environment.UserDomainName Property.
string domainName;
domainName = System.Environment.UserDomainName;
Maybe not entirely correct but...
DirectoryEntry dirEntry = new DirectoryEntry();
DirectorySearcher dirSearcher = new DirectorySearcher(dirEntry);
dirSearcher.SearchScope = SearchScope.Subtree;
dirSearcher.Filter = string.Format("(&(objectClass=user)(|(cn={0})(sn={0}*)(givenName={0})(sAMAccountName={0}*)))", userName);
var searchResults = dirSearcher.FindAll();
foreach (SearchResult sr in searchResults)
{
var de = sr.GetDirectoryEntry();
string user = de.Properties["SAMAccountName"][0].ToString();
string domain = de.Path.ToString().Split(new [] { ",DC=" },StringSplitOptions.None)[1];
MessageBox.Show(domain + "/" + user);
}
Because the value of de.Path is
LDAP://CN=FullName,DC=domain,DC=local