使用 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-X-XX-XXXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXX>”格式,其中 “S-X-X-XXXXXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX”部分與 ConvertSidToStringSid 函式傳回的字元串相同。<
使用物件 SID 進行系結時,不支援某些 IAD 和 IADsContainer 方法和屬性。 使用物件 SID 系結取得的物件不支援下列 IAD 屬性:
使用物件 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;
}