Udostępnij przez


Wiązanie z obiektem przy użyciu identyfikatora SID

W systemie Windows Server 2003 istnieje możliwość powiązania z obiektem przy użyciu identyfikatora zabezpieczeń obiektu (SID) oraz identyfikatora GUID. Identyfikator SID obiektu jest przechowywany w atrybucie objectSID. Powiązanie z identyfikatorem SID nie działa w systemie Windows 2000.

Dostawca LDAP dla usług Active Directory Domain Services udostępnia metodę powiązania z obiektem przy użyciu identyfikatora SID obiektu. Format ciągu powiązania to:

LDAP://servername/<SID=XXXXX>

W tym przykładzie "nazwa_serwera" jest nazwą serwera katalogów, a "XXXXX" jest reprezentacją ciągu wartości szesnastkowej identyfikatora SID. Wartość "servername" jest opcjonalna. Ciąg SID jest określony w postaci, w której każdy znak w ciągu jest reprezentacją szesnastkową każdego bajtu identyfikatora SID. Jeśli na przykład tablica to:

0xAB 0x14 0xE2

ciąg wiązania SID to "<SID=AB14E2>". Funkcja ADsEncodeBinaryData nie powinna być używana do konwertowania tablicy SID na ciąg, ponieważ poprzedza każdy znak bajtu ukośnikiem odwrotnym, który nie jest prawidłowym formatem ciągu powiązania.

Ciąg SID może również mieć postać "<SID=S-X-X-XX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-XXX>", gdzie część "S-X-X-XX-XXXXXXXXXX-XXXXXXXX-XXXXXXXXX-XXX" jest taka sama jak ciąg zwracany przez funkcję ConvertSidToStringSid.

Podczas tworzenia powiązania przy użyciu identyfikatora SID obiektu niektóre IADs oraz IADsContainer metody i właściwości nie są obsługiwane. Następujące właściwości IADs nie są obsługiwane przez obiekty uzyskane poprzez powiązanie z wykorzystaniem SID obiektu:

Następujące metody IADsContainer nie są obsługiwane przez obiekty uzyskane przez powiązanie przy użyciu identyfikatora SID obiektu:

Aby użyć tych metod i właściwości po powiązaniu z obiektem przy użyciu identyfikatora SID obiektu, użyj metody IADs.Get, aby pobrać nazwę wyróżniającą obiektu, a następnie użyć nazwy wyróżniającej, aby ponownie powiązać z obiektem.

Poniższy przykład kodu pokazuje, jak przekonwertować objectSid na powiązany ciąg.

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;
}