Windows Access Control List (ACL) Example 18

 

 

 

 

 

The NULL DACL Program Example: Everyone get Full Control

 

The following program example demonstrates how to create a NULL DACL. Previously we can assign NULL DACL directly using CreateDirectory() as shown below:

CreateDirectory(pathname, NULL);

However it will fail because the new directory object will inherit the parent security descriptor. By default, the Everyone group also no longer includes anonymous users on a computer that is running Windows XP Service Pack 2 (SP2) and above or updated.

Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.

 

The NULL DACL Program Example: Everyone get Full Control: Creating new Visual C++ project

 

Then, add the source file and give it a suitable name.

 

The NULL DACL Program Example: Everyone get Full Control - Adding the C++ source code

 

Next, add the following source code.

 

#include <windows.h>

#include <stdio.h>

 

int wmain(int argc, WCHAR **argv)

{

      // The securable object to be created

      WCHAR DirName[] = L"\\\\?\\C:\\MyNULLDACLDirectory";

      // declare and initialize a security attributes structure

      SECURITY_ATTRIBUTES sa;

      // Same as SECURITY_ATTRIBUTES sa = {0};

      ZeroMemory(&sa, sizeof(sa));

      sa.nLength = sizeof(sa);

      // Object handle uninheritable

      sa.bInheritHandle = FALSE;

      BOOL bInitOk = FALSE;

      BOOL bSetOk = FALSE;   

     

      // declare a security descriptor

      SECURITY_DESCRIPTOR SD;

 

      // initializes a new security descriptor. The InitializeSecurityDescriptor()

      // function initializes a security descriptor to have no system access control list (SACL),

      // no discretionary access control list (DACL), no owner, no primary group,

      // and all control flags set to FALSE (NULL). Thus, except for its revision level, it is empty.

      bInitOk = InitializeSecurityDescriptor(&SD, SECURITY_DESCRIPTOR_REVISION);

     

      if(bInitOk)

      {

            wprintf(L"InitializeSecurityDescriptor() is OK\n");

            // sets information in a discretionary access control list (DACL).

            // If a DACL is already present in the security descriptor, the DACL is replaced.

            // give the security descriptor a Null Dacl

            // done using the  "TRUE, (PACL)NULL" here

            bSetOk = SetSecurityDescriptorDacl(&SD, TRUE,(PACL)NULL, FALSE);

           

            if (bSetOk)

            {

                  wprintf(L"SetSecurityDescriptorDacl() is OK\n");

                  // Make the security attributes point to the security descriptor

                  sa.lpSecurityDescriptor = &SD;

 

                  // Then create a directory with the NULL security descriptor

                  if(CreateDirectory(DirName, &sa) == 0)

                  {

                        // Error encountered; generate message and exit

                        wprintf(L"Failed to create %s directory! Error %u\n", DirName, GetLastError());

                        // Just exit

                        exit(1);

                  }

                  else

                        wprintf(L"CreateDirectory() - %s was created successfully!\n", DirName);

            }

            else

                  wprintf(L"SetSecurityDescriptorDacl() failed, error %u\n", GetLastError());

      }

      else

            wprintf(L"InitializeSecurityDescriptor() failed, error %u\n", GetLastError());

/*

      // Release the memory allocated for the SECURITY_DESCRIPTOR.

      if(LocalFree(sa.lpSecurityDescriptor) != NULL)

      {

            // Error encountered; generate message and exit

            wprintf(L"sa.lpSecurityDescriptor NOT NULL!\n");

            wprintf(L"LocalFree() failed, error %u\n", GetLastError());

            exit(1);

      }

      else

            wprintf(L"LocalFree() - buffer was freed...\n");

*/

 

            return 0;

}

 

/*

There is an important difference between an empty and a nonexistent DACL.

When a DACL is empty, it contains no access control entries (ACEs);

therefore, no access rights are explicitly granted. As a result, access

to the object is implicitly denied.

When an object has no DACL (when the pDacl parameter is NULL), no protection

is assigned to the object, and all access requests are granted. To help maintain

security, restrict access by using a DACL. There are three possible outcomes

in different configurations of the bDaclPresent flag and the pDacl parameter:

 

    * When the pDacl parameter points to a DACL and the bDaclPresent flag is TRUE,

        a DACL is specified and it must contain access-allowed ACEs to allow access to the object.

    * When the pDacl parameter does not point to a DACL and the bDaclPresent flag is TRUE,

        a NULL DACL is specified. All access is allowed. You should not use a NULL DACL with

        an object because any user can change the DACL and owner of the security descriptor.

        This will interfere with use of the object.

    * When the pDacl parameter does not point to a DACL and the bDaclPresent flag is FALSE,

        a DACL can be provided for the object through an inheritance or default mechanism.

*/

 

Build and run the project. The following screenshot is a sample output.

 

The NULL DACL Program Example: Everyone get Full Control - console output sample

 

When we verify through the C:\MyNULLDACLDirectory’s property page, Everyone has Full Control permission!  It is very dangerous if misused.

 

The NULL DACL Program Example: Everyone get Full Control - folder properties show that Everyone got Full Control

 

The NULL DACL Program Example: Everyone get Full Control - Advanced security setting doesn't show any permission entries

 

 

 

 

< Windows ACL Example 17 | Windows Access Control List (ACL) Main | Win32 Programming | Windows ACL Example 19 >