使用 SID 绑定到对象
在 Windows Server 2003 中,可使用对象安全标识符 (SID) 和 GUID 绑定到对象。 对象 SID 会存储在 objectSID 属性中。 绑定到 SID 在 Windows 2000 上不起作用。
Active Directory 域服务的 LDAP 提供程序提供了一种方法,以便使用对象 SID 绑定到对象。 绑定字符串的格式为:
LDAP://servername/<SID=XXXXX>
在此示例中,“servername”为目录服务器的名称,而“XXXXX”则是 SID 十六进制值的字符串表示形式。 “servername”为可选项。 SID 字符串会以字符串中的每个字符均为 SID 的每个字节的十六进制表示形式来指定。 例如,如果该数组为:
0xAB 0x14 0xE2
SID 绑定字符串则为“<SID=AB14E2>”。 ADsEncodeBinaryData 函数不应用于将 SID 数组转换为字符串,因为它前面有一个反斜线,而反斜线是无效的绑定字符串格式。
SID 字符串也可采用“<SID=S-X-X-XX-XXXXXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-XXXXXXXXX-XXXXXX”>的形式,其中“S-X-X-XXXXXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-XXX”部分与 ConvertSidToStringSid 函数返回的字符串相同。
使用对象 SID 进行绑定时,不支持某些 IADs 和 IADsContainer 方法与属性。 使用对象 SID 绑定来获取的对象不支持以下 IADs 属性:
使用对象 SID 绑定来获取的对象不支持以下 IADsContainer 方法:
若要在使用对象 SID 绑定到对象后使用这些方法和属性,请使用 IADs.Get 方法检索对象可分辨名称,然后使用该可分辨名称再次绑定到此对象。
以下代码示例演示如何将 objectSid 转换为可绑定字符串。
HRESULT VariantArrayToBytes(VARIANT Variant,
LPBYTE *ppBytes,
DWORD *pdwBytes);
/********
GetSIDBindStringFromVariant()
Converts a SID in VARIANT form, such as an objectSid value, and
converts it into a bindable string in the form:
LDAP://<SID=xxxxxxx...>
The returned string is allocated with AllocADsMem and must be
freed by the caller with FreeADsMem.
*********/
LPWSTR GetSIDBindStringFromVariant(VARIANT vSID)
{
LPWSTR pwszReturn = NULL;
if(VT_ARRAY & vSID.vt)
{
HRESULT hr;
LPBYTE pByte;
DWORD dwBytes = 0;
hr = VariantArrayToBytes(vSID, &pByte, &dwBytes);
if(S_OK == hr)
{
// Convert the BYTE array into a string of hex
// characters.
CComBSTR sbstrTemp = "LDAP://<SID=";
for(DWORD i = 0; i < dwBytes; i++)
{
WCHAR wszByte[3];
swprintf_s(wszByte, L"%02x", pByte[i]);
sbstrTemp += wszByte;
}
sbstrTemp += ">";
pwszReturn =
(LPWSTR)AllocADsMem((sbstrTemp.Length() + 1) *
sizeof(WCHAR));
if(pwszReturn)
{
wcscpy_s(pwszReturn, sbstrTemp.m_str);
}
FreeADsMem(pByte);
}
}
return pwszReturn;
}
/*********
VariantArrayToBytes()
This function converts a VARIANT array into an array of BYTES.
This function allocates the buffer using AllocADsMem. The
caller must free this memory with FreeADsMem when it is no
longer required.
**********/
HRESULT VariantArrayToBytes(VARIANT Variant,
LPBYTE *ppBytes,
DWORD *pdwBytes)
{
if(!(Variant.vt & VT_ARRAY) ||
!Variant.parray ||
!ppBytes ||
!pdwBytes)
{
return E_INVALIDARG;
}
*ppBytes = NULL;
*pdwBytes = 0;
HRESULT hr = E_FAIL;
SAFEARRAY *pArrayVal = NULL;
CHAR HUGEP *pArray = NULL;
// Retrieve the safe array.
pArrayVal = Variant.parray;
DWORD dwBytes = pArrayVal->rgsabound[0].cElements;
*ppBytes = (LPBYTE)AllocADsMem(dwBytes);
if(NULL == *ppBytes)
{
return E_OUTOFMEMORY;
}
hr = SafeArrayAccessData(pArrayVal, (void HUGEP * FAR *) &pArray);
if(SUCCEEDED(hr))
{
// Copy the bytes to the safe array.
CopyMemory(*ppBytes, pArray, dwBytes);
SafeArrayUnaccessData( pArrayVal );
*pdwBytes = dwBytes;
}
return hr;
}