Partager via


Liaison à un objet à l’aide d’un SID

Dans Windows Server 2003, il est possible de lier à un objet à l’aide de l’identificateur de sécurité (SID) de l’objet ainsi que d’un GUID. Le SID de l’objet est stocké dans l’attribut objectSID . La liaison à un SID ne fonctionne pas sur Windows 2000.

Le fournisseur LDAP pour services de domaine Active Directory fournit une méthode à lier à un objet à l’aide du SID de l’objet. Le format de chaîne de liaison est le suivant :

LDAP://servername/<SID=XXXXX>

Dans cet exemple, « servername » est le nom du serveur d’annuaire et « XXXXX » est la représentation sous forme de chaîne de la valeur hexadécimale du SID. « servername » est facultatif. La chaîne SID est spécifiée sous une forme où chaque caractère de la chaîne est la représentation hexadécimale de chaque octet du SID. Par exemple, si le tableau est :

0xAB 0x14 0xE2

la chaîne de liaison SID serait «< SID=AB14E2> ». La fonction ADsEncodeBinaryData ne doit pas être utilisée pour convertir le tableau SID en chaîne, car elle précède chaque caractère d’octet d’une barre oblique inverse, qui n’est pas un format de chaîne de liaison valide.

La chaîne SID peut également prendre la forme «< SID=S-X-X-XX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-XXXXXXXX-XXX> », où la partie « S-X-X-XX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-XXX » est identique à la chaîne retournée par la fonction ConvertSidToStringSid .

Lors de la liaison à l’aide du SID d’objet, certaines méthodes et propriétés IADsContainer et IADsContainer ne sont pas prises en charge. Les propriétés IAD suivantes ne sont pas prises en charge par les objets obtenus par liaison à l’aide du SID d’objet :

Les méthodes IADsContainer suivantes ne sont pas prises en charge par les objets obtenus par liaison à l’aide du SID d’objet :

Pour utiliser ces méthodes et propriétés après la liaison à un objet à l’aide du SID de l’objet, utilisez la méthode IADs.Get pour récupérer le nom unique de l’objet, puis utilisez à nouveau le nom unique pour lier à l’objet.

L’exemple de code suivant montre comment convertir un objectSid en chaîne pouvant être liée.

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