Compartir a través de


Identificador de seguridad

Windows usa el identificador de seguridad como valor definitivo para distinguir las entidades de seguridad entre sí. Por ejemplo, se asigna un identificador de seguridad único a cada nueva cuenta creada para usuarios individuales del sistema. En el caso de un sistema de archivos, solo se usa este SID.

En la ilustración siguiente se muestra la estructura del identificador de seguridad.

diagrama que ilustra la estructura del identificador de seguridad.

Además de los SID únicos, el sistema Windows define un conjunto de identificadores conocidos. Por ejemplo, el administrador local es un SID conocido. Windows proporciona un mecanismo en kernel para convertir entre SID y nombres de usuario dentro del entorno del kernel. Estas llamadas de función están disponibles en el controlador ksecdd, que implementa estas funciones mediante servicios auxiliares en modo de usuario. En consecuencia, su uso dentro de los sistemas de archivos debe cumplir las reglas habituales para la comunicación con los servicios en modo de usuario. Estas llamadas no se pueden usar durante la E/S del archivo de paginación.

Las funciones incluyen lo siguiente:

  • SecMakeSPN: crea una cadena de nombre del proveedor de servicios que se puede usar al comunicarse con proveedores de servicios de seguridad específicos.

  • SecMakeSPNEx: una versión aumentada de SecMakeSPN. Esta función está disponible en Microsoft Windows XP y versiones posteriores de Windows.

  • SecMakeSPNEx2: una versión aumentada de SecMakeSPNEx. Esta función está disponible en Windows Vista, Windows Server 2008 y versiones posteriores de Windows.

  • SecLookupAccountSid, dado un SID, esta rutina devolverá un nombre de cuenta. Esta función está disponible en Windows XP y versiones posteriores.

  • SecLookupAccountName, dado un nombre de cuenta, esta rutina recuperará el SID. Esta función está disponible en Windows XP y versiones posteriores.

  • SecLookupWellKnownSid, dado un tipo de SID conocido, esta rutina devolverá el SID correcto. Esta función está disponible en Windows Server 2003 y versiones posteriores.

Además, cualquier controlador de kernel puede crear un SID mediante las siguientes rutinas de biblioteca en tiempo de ejecución estándar:

  • RtlInitializeSid: inicializa un búfer para un nuevo SID.

  • RtlLengthSid: determina el tamaño del SID almacenado en el búfer especificado.

  • RtlValidSid: determina si el búfer de SID especificado es un búfer con formato válido.

Tenga en cuenta que RtlLengthSid y RtlValidSid asumen que el encabezado fijo de 8 bytes para un SID está presente. Por lo tanto, un controlador debe comprobar esta longitud mínima para un encabezado SID antes de llamar a estas funciones.

Aunque hay otras funciones RTL, estas son las funciones principales necesarias al construir un SID.

En el ejemplo de código siguiente se muestra cómo crear un SID para la entidad "sistema local":

{
    //
    // temporary stack-based storage for an SID
    //
    UCHAR sidBuffer[128];
    PISID localSid = (PISID) sidBuffer;
    SID_IDENTIFIER_AUTHORITY localSidAuthority = 
        SECURITY_NT_AUTHORITY;

    //
    // build the local system SID
    //
    RtlZeroMemory(sidBuffer, sizeof(sidBuffer));
 
    localSid->Revision = SID_REVISION;
    localSid->SubAuthorityCount = 1;
    localSid->IdentifierAuthority = localSidAuthority;
    localSid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
 
    //
    // make sure it is valid
    //
    if (!RtlValidSid(localSid)) {
        DbgPrint("no dice - SID is invalid\n");
        return(1);
    }
}

Tenga en cuenta que esto también podría haberse realizado con la función más sencilla SecLookupWellKnownSid introducida en Windows Server 2003.

En el ejemplo de código siguiente se muestra cómo crear un SID mediante la función SecLookupWellKnownSid para la entidad "sistema local":

{
    UCHAR sidBuffer[128];
    PISID localSid = (PISID) sidBuffer;
    SIZE_T sidSize;
    status = SecLookupWellKnownSid(WinLocalSid,
                                   &localSid,
                                   sizeof(sidBuffer),
                                   &sidSize);

    if (!NT_SUCCESS(status)) {
      //
      // error handling
      //
    }
  }

Cualquiera de estos enfoques es válido, aunque se prefiere el último código. Tenga en cuenta que estos ejemplos de código usan búferes locales para almacenar el SID. Estos búferes no se pueden usar fuera del contexto de llamada actual. Si es necesario que el búfer de SID sea persistente, se debe asignar el búfer desde la memoria del grupo.