Share via


Enlace a un objeto mediante un SID

En Windows Server 2003, es posible enlazar a un objeto mediante el identificador de seguridad (SID) del objeto, así como un GUID. El SID de objeto se almacena en el atributo objectSID . El enlace a un SID no funciona en Windows 2000.

El proveedor LDAP para Servicios de dominio de Active Directory proporciona un método para enlazar a un objeto mediante el SID de objeto. El formato de cadena de enlace es:

LDAP://servername/<SID=XXXXX>

En este ejemplo, "servername" es el nombre del servidor de directorios y "XXXXX" es la representación de cadena del valor hexadecimal del SID. El valor "servername" es opcional. La cadena SID se especifica en un formulario en el que cada carácter de la cadena es la representación hexadecimal de cada byte del SID. Por ejemplo, si la matriz es:

0xAB 0x14 0xE2

la cadena de enlace de SID sería "<SID=AB14E2>". La función ADsEncodeBinaryData no se debe usar para convertir la matriz SID en una cadena porque precede a cada carácter de byte con una barra diagonal inversa, que no es un formato de cadena de enlace válido.

La cadena SID también puede tomar la forma "<SID=S-X-X-XX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-XXX>", donde la parte "S-X-X-XX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-XXXXXX-XXX" es la misma que la cadena devuelta por la función ConvertSidToStringSid .

Al enlazar mediante el SID de objeto, no se admiten algunos MÉTODOs y PROPIEDADES IADsContainer. Los siguientes IDENTIFICADORes no son compatibles con los objetos obtenidos mediante el enlace mediante el SID de objeto:

Los siguientes métodos IADsContainer no son compatibles con los objetos obtenidos mediante el enlace mediante el SID de objeto:

Para usar estos métodos y propiedades después de enlazar a un objeto mediante el SID de objeto, use el método IADs.Get para recuperar el nombre distintivo del objeto y, a continuación, use el nombre distintivo para enlazarlo de nuevo al objeto.

En el ejemplo de código siguiente se muestra cómo convertir un objectSid en una cadena enlazable.

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