获取给定 LDAP 服务器的全局目录
Get Global Catalog for a given LDAP server
先提问,再解释:如何获取任何给定 LDAP 服务器的 GC 服务器?
为了了解我的需求,让我解释一下:
我必须扩展 Henning Krause's ExchangeAddressListService(我不确定我是否 should/may 将 Henning 的所有代码都放到这个 post 中?)以获得有用的调试输出:
private DirectoryEntry GetDirectoryEntry(string path, string protocol)
{
var ldapPath = string.IsNullOrEmpty(path) ? string.Format("{0}:", protocol) : string.Format("{0}://{1}", protocol, path);
dbg.Add("Getting DirectoryEntry for path " + ldapPath);
return new DirectoryEntry(ldapPath);
}
public ActiveDirectoryConnection(Debug dbg)
{
this.dbg = dbg;
}
并允许选择特定域:
internal AddressList(string path, ActiveDirectoryConnection connection, string domain)
{
_Path = path;
_Connection = connection;
_Domain = domain;
}
...
private IEnumerable<AddressList> GetAddressLists(string containerName)
{
string exchangeRootPath;
using (var root = _Connection.GetLdapDirectoryEntry(_Domain+"/RootDSE"))
...
foreach (SearchResult addressBook in searchResultCollection)
{
yield return
new AddressList((string)addressBook.Properties["distinguishedName"][0], _Connection, _Domain);
}
...
}
现在我的域有问题,因为似乎某些域 SOMEDOMAIN
无法通过 GC://SOMEDOMAIN
访问全局目录。这是我使用的代码:
var domain = User.Identity.Name.Split('\')[0]; // SOMEDOMAIN\SomeUser -> Domain is SOMEDOMAIN
dbg.Add("User NETBIOS domain is "+domain);
AddressListService addressListService = new ExchangeAddressListService(connection,domain);
IEnumerable<AddressList> addressLists = addressListService.GetGlobalAddressLists();
AddressList addressList = addressLists.First()
try {
IEnumerable<SearchResult> searchResults = addressList.GetMembers("displayName", "distinguishedname", "mail")
} catch(Exception e) {
dbg.Add("Error in GetMembers: "+e.Message);
return new AjaxAnswer(dbg.Flush());
}
它产生错误日志:
User NETBIOS domain is SOMEDOMAIN
Getting DirectoryEntry for path LDAP://SOMEDOMAIN/RootDSE
Getting DirectoryEntry for path LDAP://CN=Microsoft Exchange, CN=Services, CN=Configuration,DC=somedomain,DC=net
Getting DirectoryEntry for path LDAP://CN=All Global Address Lists,CN=Address Lists Container, CN=MYMAIL,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=somedomain,DC=net
Getting DirectoryEntry for path LDAP://CN=Default Global Address List,CN=All Global Address Lists,CN=Address Lists Container,CN=MYMAIL,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=somedomain,DC=net
Getting DirectoryEntry for path GC://SOMEDOMAIN
Error in GetMembers: The server is not operational.
并不是所有的 DC 都是 GC。因此,如果 SOMEDOMAIN
不是 GC,GC://SOMEDOMAIN
可能会失败。
在我的项目中,我使用 DsGetDcName Win32 函数来发现 GC。
DsGetDcName函数详情:
http://msdn.microsoft.com/en-us/library/ms675983%28v=vs.85%29.aspx
请参阅下文了解如何调用呼叫:
http://www.pinvoke.net/default.aspx/netapi32.dsgetdcname
据我所知System.DirectoryServices.ActiveDirectory
还提供类来处理GC。
例如Forest.GlobalCatalogs
我已经使用了 DsGetDcName 函数,所以以前从未尝试过。
先提问,再解释:如何获取任何给定 LDAP 服务器的 GC 服务器?
为了了解我的需求,让我解释一下:
我必须扩展 Henning Krause's ExchangeAddressListService(我不确定我是否 should/may 将 Henning 的所有代码都放到这个 post 中?)以获得有用的调试输出:
private DirectoryEntry GetDirectoryEntry(string path, string protocol)
{
var ldapPath = string.IsNullOrEmpty(path) ? string.Format("{0}:", protocol) : string.Format("{0}://{1}", protocol, path);
dbg.Add("Getting DirectoryEntry for path " + ldapPath);
return new DirectoryEntry(ldapPath);
}
public ActiveDirectoryConnection(Debug dbg)
{
this.dbg = dbg;
}
并允许选择特定域:
internal AddressList(string path, ActiveDirectoryConnection connection, string domain)
{
_Path = path;
_Connection = connection;
_Domain = domain;
}
...
private IEnumerable<AddressList> GetAddressLists(string containerName)
{
string exchangeRootPath;
using (var root = _Connection.GetLdapDirectoryEntry(_Domain+"/RootDSE"))
...
foreach (SearchResult addressBook in searchResultCollection)
{
yield return
new AddressList((string)addressBook.Properties["distinguishedName"][0], _Connection, _Domain);
}
...
}
现在我的域有问题,因为似乎某些域 SOMEDOMAIN
无法通过 GC://SOMEDOMAIN
访问全局目录。这是我使用的代码:
var domain = User.Identity.Name.Split('\')[0]; // SOMEDOMAIN\SomeUser -> Domain is SOMEDOMAIN
dbg.Add("User NETBIOS domain is "+domain);
AddressListService addressListService = new ExchangeAddressListService(connection,domain);
IEnumerable<AddressList> addressLists = addressListService.GetGlobalAddressLists();
AddressList addressList = addressLists.First()
try {
IEnumerable<SearchResult> searchResults = addressList.GetMembers("displayName", "distinguishedname", "mail")
} catch(Exception e) {
dbg.Add("Error in GetMembers: "+e.Message);
return new AjaxAnswer(dbg.Flush());
}
它产生错误日志:
User NETBIOS domain is SOMEDOMAIN
Getting DirectoryEntry for path LDAP://SOMEDOMAIN/RootDSE
Getting DirectoryEntry for path LDAP://CN=Microsoft Exchange, CN=Services, CN=Configuration,DC=somedomain,DC=net
Getting DirectoryEntry for path LDAP://CN=All Global Address Lists,CN=Address Lists Container, CN=MYMAIL,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=somedomain,DC=net
Getting DirectoryEntry for path LDAP://CN=Default Global Address List,CN=All Global Address Lists,CN=Address Lists Container,CN=MYMAIL,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=somedomain,DC=net
Getting DirectoryEntry for path GC://SOMEDOMAIN
Error in GetMembers: The server is not operational.
并不是所有的 DC 都是 GC。因此,如果 SOMEDOMAIN
不是 GC,GC://SOMEDOMAIN
可能会失败。
在我的项目中,我使用 DsGetDcName Win32 函数来发现 GC。
DsGetDcName函数详情:
http://msdn.microsoft.com/en-us/library/ms675983%28v=vs.85%29.aspx
请参阅下文了解如何调用呼叫:
http://www.pinvoke.net/default.aspx/netapi32.dsgetdcname
据我所知System.DirectoryServices.ActiveDirectory
还提供类来处理GC。
例如Forest.GlobalCatalogs
我已经使用了 DsGetDcName 函数,所以以前从未尝试过。