Creating a Security Descriptor for a New Object

[This is preliminary documentation and subject to change.]

The following example creates a security descriptor for a new registry key. The example initializes an ACTRL_ACCESS_ENTRY structure with information about an access-allowed ACE for the key's DACL. The SetEntriesInAccessList function creates an ACTRL_ACCESS buffer containing the new ACE information. The example then calls the ConvertAccessToSecurityDescriptor function to create a security descriptor from the ACTRL_ACCESS buffer. Finally, the example assigns the security descriptor to a SECURITY_ATTRIBUTES structure which is then passed to the RegCreateKeyEx function.

Note  The security functions must use the provider-independent access rights, such as ACTRL_REG_LIST, and RegCreateKeyEx uses the Windows NT-specific access rights, such as KEY_READ.

ACTRL_ACCESS_ENTRY      AccessEntry;
PACTRL_ACCESS           pAccessList;
DWORD                   dwErr, dwDisposition;
PSECURITY_DESCRIPTOR    pSD;
SECURITY_ATTRIBUTES sa;
LONG lRes;
HKEY hk, hkSub;

// Initialize the access list entry.

ZeroMemory (&AccessEntry, sizeof(ACTRL_ACCESS_ENTRY) );
BuildTrusteeWithName(&(AccessEntry.Trustee), "george");
AccessEntry.Inheritance = NO_INHERITANCE;
AccessEntry.fAccessFlags = ACTRL_ACCESS_ALLOWED;

// Set provider-independent rights for registry objects.

AccessEntry.Access = ACTRL_REG_LINK | ACTRL_REG_CREATE_CHILD | 
         ACTRL_REG_LIST | ACTRL_REG_NOTIFY | 
         ACTRL_REG_QUERY | ACTRL_REG_SET;

// Build an access list from the access list entry.

dwErr = SetEntriesInAccessList(
     1,                  // Number of entries in array
     AccessEntry,        // array of entries
     SET_ACCESS,         // replace any existing items
     NULL,               // property name
     NULL,               // existing access list
     &pAccessList);      // receives new access list

// Initialize a security descriptor from the access list.

dwErr = ConvertAccessToSecurityDescriptor(
    pAccessList,    // pointer to the access-control information
    NULL,           // pointer to the audit-control information
    NULL,           // name of the object's owner 
    NULL,           // name of the object's primary group
    &pSD            // receives pointer to security descriptor
   );    

// Initialize a security attributes structure.

sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = TRUE;

// Use the security attributes to create a key.

lRes = RegCreateKeyEx(hk, "mykey", 0, "", 0, 
        KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition); 

// Free the returned buffers.

if (pAccessList) 
    LocalFree(pAccessList);
if (pSD) 
    LocalFree(pSD);