Allowing Access Using the Low-Level Functions
This topic shows how to use the low-level functions to work with ACLs and ACEs that allow access to an object. For similar examples that use the high-level security functions, see Allowing Access.
The first example shows the use of the low-level access-control functions to add a NULL DACL to a file's security descriptor. The low-level example allocates a security descriptor buffer and calls the InitializeSecurityDescriptor function to initialize it. Then it calls the SetSecurityDescriptorDacl function to attach a NULL DACL to the security descriptor. Finally, it calls the SetFileSecurity function to attach the security descriptor to a file. An equivalent high-level example could perform the same operation with a single call to the SetNamedSecurityInfo function.
Note You can write code that builds security descriptors from scratch, as in the example. However, when writing code that builds or manipulates security descriptors, your code should explore the default security descriptors that Windows NT places on objects. For example, an object may have a default DACL that contains ACEs inherited from its parent object. Rather than simply replacing the default DACL, your code should first examine the default DACL to determine whether you want to include its ACEs in the new DACL.
PSECURITY_DESCRIPTOR pSD;
/* Initialize a security descriptor. */
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH); /* defined in WINNT.H */
if (pSD == NULL) {
ErrorHandler("LocalAlloc");
goto Cleanup;
}
if (!InitializeSecurityDescriptor(pSD,
SECURITY_DESCRIPTOR_REVISION)) { /* defined in WINNT.H */
ErrorHandler("InitializeSecurityDescriptor");
goto Cleanup;
}
/* Add a NULL disc. ACL to the security descriptor. */
if (!SetSecurityDescriptorDacl(pSD,
TRUE, /* specifying a disc. ACL */
(PACL) NULL,
FALSE)) { /* not a default disc. ACL */
ErrorHandler("SetSecurityDescriptorDacl");
goto Cleanup;
}
/* Add the security descriptor to the file. */
if (!SetFileSecurity(lpszTestFile,
DACL_SECURITY_INFORMATION,
pSD)) {
ErrorHandler("SetFileSecurity");
goto Cleanup;
}
Cleanup:
if(pSD != NULL)
LocalFree((HLOCAL) pSD);
The following example shows the use of the low-level access-control functions to add a DACL with an access-allowed ACE to a file's security descriptor. The example allocates and initializes a security descriptor, allocates and initializes an ACL, and allocates and looks up a security identifier (SID) for a specified account. Then it adds an ACE to the ACL, adds the ACL as the DACL of the security descriptor, and finally, attaches the security descriptor to the file. Note that the high-level functions perform many of these steps for you.
PSECURITY_DESCRIPTOR pSD;
PACL pACLNew;
DWORD cbACL = 1024;
PSID pSID;
DWORD cbSID = 1024;
LPSTR lpszAccount = "UserABC";
LPSTR lpszDomain;
DWORD cchDomainName = 80;
PSID_NAME_USE psnuType;
/* Initialize a new security descriptor. */
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH); /* defined in WINNT.H */
if (pSD == NULL) {
ErrorHandler("LocalAlloc");
goto Cleanup;
}
if (!InitializeSecurityDescriptor(pSD,
SECURITY_DESCRIPTOR_REVISION)) {
ErrorHandler("InitializeSecurityDescriptor");
goto Cleanup;
}
/* Initialize a new ACL. */
pACLNew = (PACL) LocalAlloc(LPTR, cbACL);
if (pACLNew == NULL) {
ErrorHandler("LocalAlloc");
goto Cleanup;
}
if (!InitializeAcl(pACLNew, cbACL, ACL_REVISION2)) {
ErrorHandler("InitializeAcl");
goto Cleanup;
}
/* Retrieve the SID for UserABC. */
pSID = (PSID) LocalAlloc(LPTR, cbSID);
psnuType = (PSID_NAME_USE) LocalAlloc(LPTR, 1024);
lpszDomain = (LPSTR) LocalAlloc(LPTR, cchDomainName);
if (pSID == NULL || psnuType == NULL ||
lpszDomain == NULL) {
ErrorHandler("LocalAlloc");
goto Cleanup;
}
if (!LookupAccountName((LPSTR) NULL, /* local name */
lpszAccount,
pSID,
&cbSID,
lpszDomain,
&cchDomainName,
psnuType)) {
ErrorHandler("LookupAccountName");
goto Cleanup;
}
if (!IsValidSid(pSID))
TextOut(hdc, 10, yIncrement += 18,
"SID is not valid.", 17);
else
TextOut(hdc, 10, yIncrement += 18,
"SID is valid.", 13);
/* Allow read but not write access to the file. */
if (!AddAccessAllowedAce(pACLNew,
ACL_REVISION2,
GENERIC_READ,
pSID)) {
ErrorHandler("AddAccessAllowedAce");
goto Cleanup;
}
/* Add a new ACL to the security descriptor. */
if (!SetSecurityDescriptorDacl(pSD,
TRUE, /* fDaclPresent flag */
pACLNew,
FALSE)) { /* not a default disc. ACL */
ErrorHandler("SetSecurityDescriptorDacl");
goto Cleanup;
}
/* Apply the new security descriptor to the file. */
if (!SetFileSecurity("d:\\ntfs_sample_file",
DACL_SECURITY_INFORMATION,
pSD)) {
ErrorHandler("SetFileSecurity");
goto Cleanup;
}
TextOut(hdc, 10, yIncrement += 18,
"Successfully added access-allowed ACE to file's DACL.", 53);
Cleanup:
FreeSid(pSID);
if(pSD != NULL)
LocalFree((HLOCAL) pSD);
if(pACLNew != NULL)
LocalFree((HLOCAL) pACLNew);
if(psnuType != NULL)
LocalFree((HLOCAL) psnuType);
if(lpszDomain != NULL)
LocalFree((HLOCAL) lpszDomain);