Creación de una DACL

La creación de una lista de control de acceso discrecional (DACL) adecuada es una parte necesaria e importante del desarrollo de aplicaciones. Dado que una DACL NULL permite todos los tipos de acceso a todos los usuarios, no use DACL NULL .

Warning

Una DACL NULL concede acceso total a todos los usuarios, incluidos usuarios que no son de confianza y atacantes remotos. Nunca use una DACL NULL en ningún objeto protegible. Si necesita permitir el acceso amplio, cree una DACL explícita que conceda los permisos mínimos necesarios. Una DACL vacía (una DACL con cero ACL) deniega todo el acceso; este es el valor predeterminado seguro si no está seguro de qué permisos conceder.

En el ejemplo siguiente se muestra cómo crear correctamente una DACL. El ejemplo contiene una función, CreateMyDACL, que usa el lenguaje de definición de descriptor de seguridad (SDDL) para definir el control de acceso concedido y denegado en una DACL. Para proporcionar acceso diferente a los objetos de la aplicación, modifique la función CreateMyDACL según sea necesario.

En el ejemplo:

  1. La función principal pasa la dirección de una estructura SECURITY_ATTRIBUTES a la función CreateMyDACL.

  2. La función CreateMyDACL usa cadenas SDDL para:

    • Denegar el acceso a los usuarios de inicio de sesión invitado y anónimo.
    • Permitir el acceso de lectura, escritura y ejecución a los usuarios autenticados.
    • Permitir el control total a los administradores.

    Para obtener más información sobre los formatos de cadena SDDL, vea Formato de cadena del descriptor de seguridad.

  3. La función CreateMyDACL llama a la función ConvertStringSecurityDescriptorToSecurityDescriptor para convertir las cadenas SDDL en un descriptor de seguridad. El descriptor de seguridad está señalado por el miembro lpSecurityDescriptor de la estructura SECURITY_ATTRIBUTES. CreateMyDACL envía el valor devuelto de ConvertStringSecurityDescriptorToSecurityDescriptor a la función principal.

  4. La función principal usa la estructura SECURITY_ATTRIBUTES actualizada para especificar la DACL para una nueva carpeta creada por la función CreateDirectory .

  5. Cuando la función principal termine de usar la estructura SECURITY_ATTRIBUTES , la función principal libera la memoria asignada para el miembro lpSecurityDescriptor llamando a la función LocalFree .

Note

Para compilar correctamente funciones SDDL como ConvertStringSecurityDescriptorToSecurityDescriptor, debe definir la constante _WIN32_WINNT como 0x0500 o superior. En el caso de las aplicaciones modernas, tenga como destino al menos Windows 10 (0x0A00).

#include <windows.h>
#include <sddl.h>
#include <stdio.h>

#pragma comment(lib, "advapi32.lib")

BOOL CreateMyDACL(SECURITY_ATTRIBUTES *);

void main()
{
     SECURITY_ATTRIBUTES  sa;
      
     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
     sa.bInheritHandle = FALSE;  

     // Call function to set the DACL. The DACL
     // is set in the SECURITY_ATTRIBUTES 
     // lpSecurityDescriptor member.
     if (!CreateMyDACL(&sa))
     {
         // Error encountered; generate message and exit.
         printf("Failed CreateMyDACL\n");
         exit(1);
     }

     // Use the updated SECURITY_ATTRIBUTES to specify
     // security attributes for securable objects.
     // This example uses security attributes during
     // creation of a new directory.
     if (0 == CreateDirectory(TEXT("C:\\MyFolder"), &sa))
     {
         // Error encountered; generate message and exit.
         printf("Failed CreateDirectory\n");
         exit(1);
     }

     // Free the memory allocated for the SECURITY_DESCRIPTOR.
     if (NULL != LocalFree(sa.lpSecurityDescriptor))
     {
         // Error encountered; generate message and exit.
         printf("Failed LocalFree\n");
         exit(1);
     }
}


// CreateMyDACL.
//    Create a security descriptor that contains the DACL 
//    you want.
//    This function uses SDDL to make Deny and Allow ACEs.
//
// Parameter:
//    SECURITY_ATTRIBUTES * pSA
//    Pointer to a SECURITY_ATTRIBUTES structure. It is your
//    responsibility to properly initialize the 
//    structure and to free the structure's 
//    lpSecurityDescriptor member when you have
//    finished using it. To free the structure's 
//    lpSecurityDescriptor member, call the 
//    LocalFree function.
// 
// Return value:
//    FALSE if the address to the structure is NULL. 
//    Otherwise, this function returns the value from the
//    ConvertStringSecurityDescriptorToSecurityDescriptor 
//    function.
BOOL CreateMyDACL(SECURITY_ATTRIBUTES * pSA)
{
     // Define the SDDL for the DACL. This example sets 
     // the following access:
     //     Built-in guests are denied all access.
     //     Anonymous logon is denied all access.
     //     Authenticated users are allowed 
     //     read/write/execute access.
     //     Administrators are allowed full control.
     // Modify these values as needed to generate the proper
     // DACL for your application. 
     TCHAR * szSD = TEXT("D:")       // Discretionary ACL
        TEXT("(D;OICI;GA;;;BG)")     // Deny access to 
                                     // built-in guests
        TEXT("(D;OICI;GA;;;AN)")     // Deny access to 
                                     // anonymous logon
        TEXT("(A;OICI;GRGWGX;;;AU)") // Allow 
                                     // read/write/execute 
                                     // to authenticated 
                                     // users
        TEXT("(A;OICI;GA;;;BA)");    // Allow full control 
                                     // to administrators

    if (NULL == pSA)
        return FALSE;

     return ConvertStringSecurityDescriptorToSecurityDescriptor(
                szSD,
                SDDL_REVISION_1,
                &(pSA->lpSecurityDescriptor),
                NULL);
}