【发布时间】:2011-05-14 01:03:37
【问题描述】:
我知道以前有人问过这种类型的问题,但其他方法现在让我失败了。
就目前而言,我们的 Windows 服务轮询 AD,给定一个 LDAP(即 LDAP://10.32.16.80)和该 AD 服务器中要搜索的用户组列表。 它检索那些给定组中的所有用户,并递归地搜索这些组以查找更多组。 然后将每个用户添加到另一个应用程序的已验证用户列表中。
这部分应用程序运行成功。但是,我们需要每个用户的友好域名(即他们登录 DOMAIN/用户名的一部分)
因此,如果有一个用户属于 TEST 域,名为 Steve:TEST/steve 是他的登录名。 我可以在 AD 中找到 steve,但我还需要将“TEST”与他的 AD 信息一起存储。
再一次,我可以通过使用目录搜索器和给定的 LDAP IP 找到“steve”,但是给定 LDAP IP,我怎样才能找到友好的域名?
当我尝试以下代码时,我在尝试访问“defaultNamingContext”时遇到错误:
System.Runtime.InteropServices.COMException (0x8007202A):身份验证机制未知。
代码如下:
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;
}
编辑
我添加了这个示例方法是为了尝试提出建议,但是当我在搜索器上点击“FindAll()”调用时出现异常:“未指定错误”。 传入的字符串是:"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;
【问题讨论】:
-
TEST域是否与当前域在同一个 Forest 下?如果是这样,您可以为该用户查询正确的域,因为该用户可能存在于您当前的域中,但不存在于另一个域中。 -
是的,TEST 域将与当前域位于同一林中。在这方面,我如何去查询给定用户的域?请记住,我的 AD 知识是有限的,因为我并不精通构建 LDAP 字符串等......
-
Get NT style domain\user given DN 的可能重复项 - 这提供了有关如何将用户的 DN 转换为其 NETBIOS 域名的信息,这正是您想要的。
-
然后我会在每个域中查询用户 Steve 并返回 Steve 拥有帐户的域中的
IList<string>。因此,您不能说绝对用户名是TEST\Steve,因为 Steve 可能有另一个用于不同域的同名用户帐户,比如PROD\Steve。 -
Steve Townsend,我尝试使用该链接作为解决方案,但在搜索器上调用“FindOne()”时出现未指定的错误。
标签: c# active-directory dns comexception