如何通过用户名获取Active Directory用户的IADs
界面?
注意:原生代码
我正在尝试编写可以在Active Directory中获取用户的IADs
接口的函数。
到目前为止,我有以下“伪代码”:
public IADs GetUserObject(string samAccountName)
{
IADs ads;
//Get the current domain's distinguished name ("dc=stackoverflow,dc=com")
AdsGetObject("LDAP://rootDSE", IADs, ref ads);
String dn = ads.Get("defaultNamingContext"); //"dc=stackoverflow,dc=com"
String path;
//Attempt #1 to bind to a user by username
path = "LDAP://sSAMAccountName="+samAccountName+",dc=stackoverflow,dc=com"
AdsGetObject(path, IADs, ref ads); //invalid syntax
return ads;
}
我无法弄清楚的诀窍是如何通过他们的帐户名绑定到用户。以下变体不起作用:
LDAP://sSAMAccountName=ian,dc=stackoverflow,dc=com
LDAP://dc=stackoverflow,dc=com;(&(objectCategory=user)(sAMAccountName=ian))
<LDAP://dc=stackoverflow,dc=com>;(&(objectCategory=user)(sAMAccountName=ian))
修改:
工作的版本,但不回答我的问题,是:
LDAP://cn=Ian Boyd,ou=Avatar Users,dc=stackoverflow,dc=com
由于两个原因,它没有回答我的问题:
- 我不知道用户的
CN
(通用名称)(例如Ian Boyd),只知道他们的sAMAccountName
(例如ian)- 不适用于不在头像用户组织单位的用户;我不知道用户的OU
这来自我以前的笔记:
注意:
tl; dr:您如何编写效用函数:
public IADs GetUserObject(string samAccountName)
{
//TODO: ask stackoverflow
}
更新2:
注意:
IADs
的问题)更新3 :
当然可能需要我应用“过滤器”,除了我不知道在哪里。提到过滤器的唯一ActiveDs界面是IADSContainer
,但我不知道从哪里获取。
我随机尝试从根IADsContainer
接口获取IADs
接口,但“rootDSE”不支持IADsContainer
:
IADs ads = AdsGetObject("LDAP://rootDSE");
IADsContainer container = (IADsContainer)ads; //interface not supported exception
我可以
IADsContainer
的问题
IADsContainer
进行过滤
但是跟踪所有这些问题很困难。
答案 0 :(得分:2)
如果您知道sAMAccountName
的价值并且需要获得用户的IADs
,则首先在sAMAccountName
内找到 Active Directory中的用户获取用户的distinguishedName
属性。您已经知道如何通过IADs
获取distinguishedName
。
因此,您应该只关注MSDN中的the code。首先,您获得IDirectorySearch
defaultNamingContext
的AD容器的"LDAP://rootDSE"
界面。
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
,您可以使用仅LPOLESTR
组成的L"distinguishedName"
数组(请参阅代码示例中的pszNonVerboseList
并查看FindUsers
的代码如果bIsVerbose
为FALSE
)。
您应该获得第一个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=stackoverflow,dc=com")
AdsGetObject("LDAP://rootDSE", IADs, ref ads);
String dn = ads.Get("defaultNamingContext"); //"dc=stackoverflow,dc=com"
//Get the the object of the current domain (e.g. LDAP://dc=stackoverflow,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
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=stackoverflow,dc=com")
IADs ads = GetObject("LDAP://rootDSE");
String dn = ads.Get("defaultNamingContext"); //"dc=stackoverflow,dc=com"
//Get the the object of the current domain (e.g. LDAP://dc=stackoverflow,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;
}
答案 1 :(得分:0)
以下是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中找到更多信息。