如何获取活动目录用户的 IADs 接口?
Posted
技术标签:
【中文标题】如何获取活动目录用户的 IADs 接口?【英文标题】:How to get the IADs interface of an active directory user? 【发布时间】:2011-12-21 14:56:08 【问题描述】:如何通过 用户名 获得 Active Directory 用户的IADs
界面?
注意:本机代码
我正在尝试编写可以在 Active Directory 中获取 用户 的IADs
接口的函数。
到目前为止,我有以下“伪代码”:
public IADs GetUserObject(string samAccountName)
IADs ads;
//Get the current domain's distinguished name ("dc=***,dc=com")
AdsGetObject("LDAP://rootDSE", IADs, ref ads);
String dn = ads.Get("defaultNamingContext"); //"dc=***,dc=com"
String path;
//Attempt #1 to bind to a user by username
path = "LDAP://sSAMAccountName="+samAccountName+",dc=***,dc=com"
AdsGetObject(path, IADs, ref ads); //invalid syntax
return ads;
我想不通的诀窍是如何通过用户的帐户名绑定到用户。以下变体不起作用:
LDAP://sSAMAccountName=ian,dc=***,dc=com
LDAP://dc=***,dc=com;(&(objectCategory=user)(sAMAccountName=ian))
<LDAP://dc=***,dc=com>;(&(objectCategory=user)(sAMAccountName=ian))
编辑:
确实有效但没有回答我的问题的版本是:
LDAP://cn=Ian Boyd,ou=Avatar Users,dc=***,dc=com
它没有回答我的问题有两个原因:
我不知道用户的CN
(通用名)(例如 Ian Boyd),只知道他们的sAMAccountName
(例如 ian) 不适用于不在头像用户单位部门的用户;而且我不知道用户的 OU这来自我之前的笔记:
注意:
我不知道域名的名称(不过没关系,我可以在运行时获取) 我不知道任何活动目录服务器的名称 我不知道用户所在的文件夹tl;dr:你会如何编写实用函数:
public IADs GetUserObject(string samAccountName)
//TODO: ask ***
更新 2:
注意:
我已经知道如何查询用户信息using .NET's DirectorySearcher 我已经知道如何查询有关用户 using the Active Directory Services OLEDB provider with ADO 的信息(使用 SQL 语法,但不是本机语法) 我现在正在寻找代码来查询有关用户 using Active Directory Services COM objects 的信息(因此是关于为用户获取IADs
的问题)
更新 3:
当然可能需要我应用“过滤器”,但我不知道在哪里。唯一提到 Filter 的 ActiveDs 界面是 IADSContainer
,但我不知道从哪里获得。
我随机尝试从根IADs
接口获取IADsContainer
接口,但是“rootDSE”不支持IADsContainer
:
IADs ads = AdsGetObject("LDAP://rootDSE");
IADsContainer container = (IADsContainer)ads; //interface not supported exception
我可以
请教如何获取AD根的IADsContainer
所以我可以问如何递归搜索活动目录
所以我可以询问如何使用IADsContainer
进行过滤
so i can figure out how to get the IADs object of a user
so i an figure out how to query AD for user properties
但是跟踪所有这些问题很困难。
【问题讨论】:
为什么不尝试使用轻量级目录访问协议 Microsoft API(如 RFC 1823 中所述) @JPBlanc 这将需要 另一个 *** 问题,“如何使用 RFC1823 的轻量级直接访问协议获得IADs
接口?”
【参考方案1】:
如果您知道sAMAccountName
的值并需要获取您需要的用户的IADs
,您首先需要在Active Directory 中通过sAMAccountName
找到用户并获取distinguishedName
的属性用户。您已经知道如何通过distinguishedName
获取IADs
。
因此,例如,您应该关注 MSDN 中的 the code。首先得到"LDAP://rootDSE"
的defaultNamingContext
的AD容器的IDirectorySearch
接口。
IADs domain;
ADsGetObject("LDAP://rootDSE", IADs, domain);
然后您使用IDirectorySearch::ExecuteSearch 使用过滤字符串应用搜索:
(&(objectClass=user)(objectCategory=person)(sAMAccountName=theName))
注意:搜索过滤器语法描述为here。
IDirectorySearch directorySearch = domain as IDirectorySearch;
ADS_SEARCH_HANDLE searchHandle;
directorySearch.ExecuteSearch(
"(&(objectClass=user)(objectCategory=person)(sAMAccountName=ian))",
attributeNames, numberOfAttributes,
out searchHandle);
您使用sAMAccountName
的已知值而不是theName
。
对于pAttributeNames
,您可以使用仅由L"distinguishedName"
组成的LPOLESTR
数组(请参阅代码示例中的pszNonVerboseList
,并在bIsVerbose
的情况下查看FindUsers
的代码为@987654345 @)。
你应该得到distinguishedName
属性的第一个(如果有的话)找到的项目。拥有distinguishedName
属性,您可以使用AdsGetObject
来获取用户的IADs
。
或者你可以获取用户的objectGUID
属性而不是distinguishedName
属性并使用binding by GUID语法,但是distinguishedName
的用法我个人觉得更清晰易懂。
public IADs GetUserObject(string samAccountName)
IADs ads;
//Get the current domain's distinguished name (e.g. "dc=***,dc=com")
AdsGetObject("LDAP://rootDSE", IADs, ref ads);
String dn = ads.Get("defaultNamingContext"); //"dc=***,dc=com"
//Get the the object of the current domain (e.g. LDAP://dc=***,dc=com)
AdsGetObject("LDAP://"+dn, IADs, ref ads);
//Now we're going to search for the "distinguishedName" of this user
//setup the search filter for the user we want
String filter = "(&(objectClass=user)(objectCategory=person)(sAMAccountName="+samAccountName+"))";
//specify that we only need to return one attribute, distinguishedNamem,
//otherwise it returns all attributes and is a waste of resources
String[] searchAttributes = "distinguishedName" ;
//run the search
IDirectorySearch ds = ads as IDirectorySearch;
ADS_SEARCH_HANDLE searchHandle;
ds.ExecuteSearch(filter, searchAttributes, 1, out searchHandle);
ds.GetFirstRow(searchHandle);
//Now get the details of the "distinguishedName" column
ADS_SEARCH_COLUMN column;
ds.GetColumn(searchHandle, "distinguishedName", ref column);
//Get the user's distinguishedName
String dn = column.pADsValues.DNString;
//Now that we have the user's distinguishedName, we can do what we really wanted:
AdsGetObject("LDAP://"+dn, IADs, ads);
return ads;
这意味着在概念上它可以分为两个步骤:
从用户的samAccountName
获取用户的distinguishedName
为 distinguishedName 获取 IADs
并拆分代码:
public IADs GetUserObject(string samAccountName)
String userDistinguishedName = GetUserDistinguishedName(samAccountName);
return GetObject("LDAP://"+userDistingishedName);
public String GetUserDistinguishedName(string samAccountName)
//Get the current domain's distinguished name (e.g. "dc=***,dc=com")
IADs ads = GetObject("LDAP://rootDSE");
String dn = ads.Get("defaultNamingContext"); //"dc=***,dc=com"
//Get the the object of the current domain (e.g. LDAP://dc=***,dc=com)
ads := GetObject("LDAP://"+dn);
//Now we're going to search for the "distinguishedName" of this user
//setup the search filter for the user we want
String filter = '(&(objectClass=user)(objectCategory=person)(sAMAccountName='+samAccountName+'))';
//specify that we only need to return one attribute, distinguishedNamem,
//otherwise it returns all attributes and is a waste of resources
String[] searchAttributes = "distinguishedName" ;
//run the search
IDirectorySearch ds = ads as IDirectorySearch;
ADS_SEARCH_HANDLE searchHandle;
ds.ExecuteSearch(filter, searchAttributes, 1, out searchHandle);
ds.GetFirstRow(searchHandle);
//Now get the details of the "distinguishedName" column
ADS_SEARCH_COLUMN column;
ds.GetColumn(searchHandle, "distinguishedName", ref column);
//Get the user's distinguishedName
return column.pADsValues.DNString;
【讨论】:
【参考方案2】:这是一个 C++ 示例
IADs *pObject;
HRESULT hr;
// Initialize COM.
CoInitialize(NULL);
hr = ADsGetObject(L"LDAP://CN=JPB,OU=MonOU,DC=societe,DC=fr",
IID_IADs,
(void**) &pObject);
if(SUCCEEDED(hr))
// Use the object.
// Release the object.
pObject->Release()
// Uninitialize COM.
CoUninitialize();
您可以在Binding to Active Directory Domain Services找到更多信息。
【讨论】:
当我用LDAP://cn=ian,dc=avatopia,dc=com
调用 AdsGetObject
时,我得到了 hresult $80072030
(“服务器上没有这样的对象”)。大概是因为ian
不是Common-Name (CN
),而是sAMAccountName
。 (即我只知道帐户名称)。以上是关于如何获取活动目录用户的 IADs 接口?的主要内容,如果未能解决你的问题,请参考以下文章