Win32 File API SetNamedSecurityInfo function

Download EaseFilter Monitor, Control and Encryption Filter Driver SDK Setup File
Download EaseFilter Monitor, Control and Encryption Filter Driver SDK Zip File

The SetNamedSecurityInfo function sets specified security information in the security descriptor of a specified object. The caller identifies the object by name.

Syntax

DWORD SetNamedSecurityInfoW(
  LPWSTR               pObjectName,
  SE_OBJECT_TYPE       ObjectType,
  SECURITY_INFORMATION SecurityInfo,
  PSID                 psidOwner,
  PSID                 psidGroup,
  PACL                 pDacl,
  PACL                 pSacl
);

Parameters

pObjectName

A pointer to a null-terminated string that specifies the name of the object for which to set security information. This can be the name of a local or remote file or directory on an NTFS file system, network share, registry key, semaphore, event, mutex, file mapping, or waitable timer.

For descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.

ObjectType

A value of the SE_OBJECT_TYPE enumeration that indicates the type of object named by the pObjectName parameter.

SecurityInfo

A set of bit flags that indicate the type of security information to set. This parameter can be a combination of the SECURITY_INFORMATION bit flags.

psidOwner

A pointer to a SID structure that identifies the owner of the object. If the caller does not have the SeRestorePrivilege constant (see Privilege Constants), this SID must be contained in the caller's token, and must have the SE_GROUP_OWNER permission enabled. The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. To set the owner, the caller must have WRITE_OWNER access to the object or have the SE_TAKE_OWNERSHIP_NAME privilege enabled. If you are not setting the owner SID, this parameter can be NULL.

psidGroup

A pointer to a SID that identifies the primary group of the object. The SecurityInfo parameter must include the GROUP_SECURITY_INFORMATION flag. If you are not setting the primary group SID, this parameter can be NULL.

pDacl

A pointer to the new DACL for the object. The SecurityInfo parameter must include the DACL_SECURITY_INFORMATION flag. The caller must have WRITE_DAC access to the object or be the owner of the object. If you are not setting the DACL, this parameter can be NULL.

pSacl

A pointer to the new SACL for the object. The SecurityInfo parameter must include any of the following flags: SACL_SECURITY_INFORMATION, LABEL_SECURITY_INFORMATION, ATTRIBUTE_SECURITY_INFORMATION, SCOPE_SECURITY_INFORMATION, or BACKUP_SECURITY_INFORMATION.

If setting SACL_SECURITY_INFORMATION or SCOPE_SECURITY_INFORMATION, the caller must have the SE_SECURITY_NAME privilege enabled. If you are not setting the SACL, this parameter can be NULL.

Return Value

If the function succeeds, the function returns ERROR_SUCCESS.

If the function fails, it returns a nonzero error code defined in WinError.h.

Remarks

If you are setting the discretionary access control list (DACL) or any elements in the system access control list (SACL) of an object, the system automatically propagates any inheritable access control entries (ACEs) to existing child objects, according to the rules of inheritance.

You can use the SetNamedSecurityInfo function with the following types of objects:

  • Local or remote files or directories on an NTFS
  • Local or remote printers
  • Local or remote Windows services
  • Network shares
  • Registry keys
  • Semaphores, events, mutexes, and waitable timers
  • File-mapping objects
  • Directory service objects
The SetNamedSecurityInfo function does not reorder access-allowed or access-denied ACEs based on the preferred order. When propagating inheritable ACEs to existing child objects, SetNamedSecurityInfo puts inherited ACEs in order after all of the noninherited ACEs in the DACLs of the child objects.

This function transfers information in plaintext. The information transferred by this function is signed unless signing has been turned off for the system, but no encryption is performed.

When you update access rights of a folder indicated by an UNC path, for example \Test\TestFolder, the original inherited ACE is removed and the full volume path is not included.

Examples

The following example adds an access control entry (ACE) to the discretionary access control list (DACL) of an object.

The AccessMode parameter determines the type of new ACE and how the new ACE is combined with any existing ACEs for the specified trustee. Use the GRANT_ACCESS, SET_ACCESS, DENY_ACCESS, or REVOKE_ACCESS flags in the AccessMode parameter. For information about these flags, see ACCESS_MODE.

Similar code can be used to work with a system access control list (SACL). Specify SACL_SECURITY_INFORMATION in the GetNamedSecurityInfo and SetNamedSecurityInfo functions to get and set the SACL for the object. Use the SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE, and REVOKE_ACCESS flags in the AccessMode parameter. For information about these flags, see ACCESS_MODE.

Use this code to add an object-specific ACE to the DACL of a directory service object. To specify the GUIDs in an object-specific ACE, set the TrusteeForm parameter to TRUSTEE_IS_OBJECTS_AND_NAME or TRUSTEE_IS_OBJECTS_AND_SID and set the pszTrusteeparameter to be a pointer to an OBJECTS_AND_NAME or OBJECTS_AND_SID structure.

This example uses the GetNamedSecurityInfo function to get the existing DACL. Then it fills an EXPLICIT_ACCESS structure with information about an ACE and uses the SetEntriesInAcl function to merge the new ACE with any existing ACEs in the DACL. Finally, the example calls the SetNamedSecurityInfo function to attach the new DACL to the security descriptor of the object.

#include <windows.h>  
#include <stdio.h>

DWORD AddAceToObjectsSecurityDescriptor (
    LPTSTR pszObjName,          // name of object
    SE_OBJECT_TYPE ObjectType,  // type of object
    LPTSTR pszTrustee,          // trustee for new ACE
    TRUSTEE_FORM TrusteeForm,   // format of trustee structure
    DWORD dwAccessRights,       // access mask for new ACE
    ACCESS_MODE AccessMode,     // type of ACE
    DWORD dwInheritance         // inheritance flags for new ACE
) 
{
    DWORD dwRes = 0;
    PACL pOldDACL = NULL, pNewDACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea;

    if (NULL == pszObjName) 
        return ERROR_INVALID_PARAMETER;

    // Get a pointer to the existing DACL.

    dwRes = GetNamedSecurityInfo(pszObjName, ObjectType, 
          DACL_SECURITY_INFORMATION,
          NULL, NULL, &pOldDACL, NULL, &pSD);
    if (ERROR_SUCCESS != dwRes) {
        printf( "GetNamedSecurityInfo Error %u\n", dwRes );
        goto Cleanup; 
    }  

    // Initialize an EXPLICIT_ACCESS structure for the new ACE. 

    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    ea.grfAccessPermissions = dwAccessRights;
    ea.grfAccessMode = AccessMode;
    ea.grfInheritance= dwInheritance;
    ea.Trustee.TrusteeForm = TrusteeForm;
    ea.Trustee.ptstrName = pszTrustee;

    // Create a new ACL that merges the new ACE
    // into the existing DACL.

    dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
    if (ERROR_SUCCESS != dwRes)  {
        printf( "SetEntriesInAcl Error %u\n", dwRes );
        goto Cleanup; 
    }  

    // Attach the new ACL as the object's DACL.

    dwRes = SetNamedSecurityInfo(pszObjName, ObjectType, 
          DACL_SECURITY_INFORMATION,
          NULL, NULL, pNewDACL, NULL);
    if (ERROR_SUCCESS != dwRes)  {
        printf( "SetNamedSecurityInfo Error %u\n", dwRes );
        goto Cleanup; 
    }  

    Cleanup:

        if(pSD != NULL) 
            LocalFree((HLOCAL) pSD); 
        if(pNewDACL != NULL) 
            LocalFree((HLOCAL) pNewDACL); 

        return dwRes;
}