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.
Then, add the source file and give it a suitable name.
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(LInitializeSecurityDescriptor() 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(LSetSecurityDescriptorDacl() 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(LFailed to create %s directory! Error %u\n, DirName, GetLastError());
// Just exit
exit(1);
}
else
wprintf(LCreateDirectory() - %s was created successfully!\n, DirName);
}
else
wprintf(LSetSecurityDescriptorDacl() failed, error %u\n, GetLastError());
}
else
wprintf(LInitializeSecurityDescriptor() 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(Lsa.lpSecurityDescriptor NOT NULL!\n);
wprintf(LLocalFree() failed, error %u\n, GetLastError());
exit(1);
}
else
wprintf(LLocalFree() - 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.
When we verify through the C:\MyNULLDACLDirectory’s property page, Everyone has Full Control permission! It is very dangerous if misused.