HOWTO: Specify Access Control on Window NT Container Objects

ID: Q188760


The information in this article applies to:


SUMMARY

Programmatically specifying access control for Windows NT container objects is more complex that that of other Win32 objects. This is because access control on container objects allows you to specify access to the container and access for future objects created in the container.


MORE INFORMATION

A Windows NT securable object is a container if it can logically contain other securable objects. The following table demonstrates the relationship between a container object and the objects it might contain:


   Container Object         Objects Contained
   -----------------------------------------------

   Directory                Files/Directories

   Registry Key             Registry Keys/Values

   Windowstation            Desktop

   Printer                  Printer share 
Windows NT supports ACL Inheritance. This means that when a new object is created within a container object, the new object inherits permissions from the parent container object by default.

When you programmatically assign access control to container objects, you must explicitly set the inheritance attribute of each access control entry (ACE). Use the following flags to set the ACE inheritance properties:

For a complete description of these and the other possible AceFlags values see the Win32 SDK documentation for the ACE_HEADER structure.

There are two ways to assign inheritance flags to an access control entry on Windows NT 3.x and 4.0. These techniques assume that you are familiar with the Windows NT access control API. For additional information, please see Win32 SDK and the following article in the Microsoft Knowledge Base:
Q102102 HOWTO: Add an Access-Allowed ACE to a File
Once the ACE is in the DACL through AddAccessAllowed/DeniedAce(), set the AceFlags member of the new ACE. You do this by using the GetAce() API to retrieve a pointer to the new ACE. Use this pointer to set the AceFlags member of the ACE header structure as follows:

   {  // You can add this to step 14 of Q102102, which demonstrates adding
      // an Access Allowed ACE to a DACL.

      // Add the access-allowed ACE to the new DACL.
      if(!AddAccessAllowedAce(pNewACL,ACL_REVISION2,dwAcessMask, pSid))
      {
      // Handle AddAccessAllowedAce Error.
      }

      // Get pointer to ACE you just added, so you can change the AceFlags.
      if(!GetAce( pNewACL,
                  0, // You know it is the first ACE in the Acl.
                  &pTempAce ))
      {
      // Handle GetAce Error.
      }

      // Set AceFlags member.
      pTempAce->Header.AceFlags = bAceFlags;
   } 
This extra step is necessary because the AddAccessAllowedAce() API does not have a parameter to specify this attribute of a new ACE.

On the other hand, you can build the ACE yourself and set the AceFlags member of the ACE_Header Structure as follows:

   {
      DWORD bAceFlags = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; 
      ACCESS_ALLOWED_ACE *pAce = (ACCESS_ALLOWED_ACE *)
            malloc(sizeof(ACCESS_ALLOWED_ACE) + sidlen - sizeof(DWORD));

      // Fill in ACCESS_ALLOWED_ACE structure.
      pAce->Mask = dwAcessMask; 
      pAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; 
      pAce->Header.AceFlags = bAceFlags;
      pAce->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) 
                                            + sidlen - sizeof(DWORD);
      memcpy(&(pAce->Header.SidStart),pSid,GetLengthSid(pSid) );      
      if(!AddAce(pNewACL, ACL_REVISION, MAXDWORD, 
                                         pAce, pAce->Header.AceSize))
      {
      // Handle AddAce error.
      }
   } 

Additional query words: directory sid special security printer


Keywords          : kbKernBase kbSecurity 
Version           : winnt:
Platform          : winnt 
Issue type        : kbhowto 

Last Reviewed: February 6, 1999