Freigeben über


Bindung an ein Objekt mithilfe einer SID

In Windows Server 2003 ist es möglich, eine Bindung an ein Objekt mithilfe der Objektsicherheits-ID (SID) und einer GUID zu erstellen. Die Objekt-SID wird im objectSID-Attribut gespeichert. Die Bindung an eine SID funktioniert unter Windows 2000 nicht.

Der LDAP-Anbieter für Active Directory Domain Services stellt eine Methode zum Binden an ein Objekt mithilfe der Objekt-SID bereit. Das Bindungszeichenfolgenformat lautet:

LDAP://servername/<SID=XXXXX>

In diesem Beispiel ist "servername" der Name des Verzeichnisservers und "XXXXX" die Zeichenfolgendarstellung des Hexadezimalwerts der SID. Der "Servername" ist optional. Die SID-Zeichenfolge wird in einem Formular angegeben, in dem jedes Zeichen in der Zeichenfolge die hexadezimale Darstellung jedes Byte der SID ist. Beispiel:

0xAB 0x14 0xE2

die SID-Bindungszeichenfolge wäre "<SID=AB14E2>". Die ADsEncodeBinaryData-Funktion sollte nicht verwendet werden, um das SID-Array in eine Zeichenfolge zu konvertieren, da sie jedem Bytezeichen einen umgekehrten Schrägstrich vorangestellt hat, was kein gültiges Bindzeichenfolgenformat ist.

Die SID-Zeichenfolge kann auch die Form "<SID=S-X-X-XX-XXXXXXXXXX-XXXXXXXX-XXXXXXX-XXXXXXX-XXX>" annehmen, wobei der Teil "S-X-X-XX-XXXXXXXXXXXX-XXXXXXXXX-XXX" mit der von der ConvertSidToStringSid-Funktion zurückgegebenen Zeichenfolge identisch ist.

Bei der Bindung mithilfe der Objekt-SID werden einige IADs und IADsContainer-Methoden und -Eigenschaften nicht unterstützt. Die folgenden IADs-Eigenschaften werden nicht von Objekten unterstützt, die durch Bindung mithilfe der Objekt-SID abgerufen werden:

Die folgenden IADsContainer-Methoden werden nicht von Objekten unterstützt, die durch Bindung mithilfe der Objekt-SID abgerufen werden:

Um diese Methoden und Eigenschaften nach der Bindung an ein Objekt mithilfe der Objekt-SID zu verwenden, verwenden Sie die IADs.Get-Methode , um den distinguished Name des Objekts abzurufen, und verwenden Sie dann den distinguished Name, um erneut an das Objekt zu binden.

Das folgende Codebeispiel zeigt, wie ein objectSid in eine bindbare Zeichenfolge konvertiert wird.

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