Obtaining Security/Audit Information






Obtaining Security/Audit Information

Problem

You need to obtain the security rights and/or audit information for a file or registry key.

Solution

When obtaining security/audit information for a file, use the static GetAccessControl method of the File class to obtain a System.Security.AccessControl.FileSecurity object. Use the FileSecurity object to access the security and audit information for the file. These steps are demonstrated in Figure.

Obtaining security audit information

public static void ViewFileRights()
{
    // Get security information from a file.
    string file = @"c:\FOO.TXT";

    FileSecurity fileSec = File.GetAccessControl(file);

    DisplayFileSecurityInfo(fileSec);
}

public static void DisplayFileSecurityInfo(FileSecurity fileSec)
{
    Console.WriteLine("GetSecurityDescriptorSddlForm: {0}",
        fileSec.GetSecurityDescriptorSddlForm(AccessControlSections.All));

    foreach (FileSystemAccessRule ace in
            fileSec.GetAccessRules(true, true, typeof(NTAccount)))
    {
        Console.WriteLine("\tIdentityReference.Value: {0}",
                          ace.IdentityReference.Value);
        Console.WriteLine("\tAccessControlType: {0}", ace.AccessControlType);
        Console.WriteLine("\tFileSystemRights: {0}", ace.FileSystemRights);
        Console.WriteLine("\tInheritanceFlags: {0}", ace.InheritanceFlags);
        Console.WriteLine("\tIsInherited: {0}", ace.IsInherited);
        Console.WriteLine("\tPropagationFlags: {0}", ace.PropagationFlags);

        Console.WriteLine("-----------------\r\n\r\n");
    }

    foreach (FileSystemAuditRule ace in
            fileSec.GetAuditRules(true, true, typeof(NTAccount)))
    {
        Console.WriteLine("\tIdentityReference.Value: {0}",
                          ace.IdentityReference.Value);
        Console.WriteLine("\tAuditFlags: {0}", ace.AuditFlags);
        Console.WriteLine("\tFileSystemRights: {0}", ace.FileSystemRights);
        Console.WriteLine("\tInheritanceFlags: {0}", ace.InheritanceFlags);
        Console.WriteLine("\tIsInherited: {0}", ace.IsInherited);
        Console.WriteLine("\tPropagationFlags: {0}", ace.PropagationFlags);

        Console.WriteLine("-----------------\r\n\r\n");
    }

    Console.WriteLine("GetGroup(typeof(NTAccount)).Value: {0}",
                      fileSec.GetGroup(typeof(NTAccount)).Value);
    Console.WriteLine("GetOwner(typeof(NTAccount)).Value: {0}",
                      fileSec.GetOwner(typeof(NTAccount)).Value);

    Console.WriteLine("---------------------------------------\r\n\r\n\r\n");
}

These methods produce the following output:

	GetSecurityDescriptorSddlForm: O:BAG:SYD:PAI(A;;FA;;;SY)(A;;FA;;;BA)
	    IdentityReference.Value: NT AUTHORITY\SYSTEM
	    AccessControlType: Allow
	    FileSystemRights: FullControl
	    InheritanceFlags: None
	    IsInherited: False
	    PropagationFlags: None
	-----------------

	    IdentityReference.Value: BUILTIN\Administrators
	    AccessControlType: Allow
	    FileSystemRights: FullControl
	    InheritanceFlags: None
	    IsInherited: False
	    PropagationFlags: None
	-----------------

	GetGroup(typeof(NTAccount)).Value: NT AUTHORITY\SYSTEM
	GetOwner(typeof(NTAccount)).Value: BUILTIN\Administrators

When obtaining security/audit information for a registry key, use the GetAccess-Control instance method of the Microsoft.Win32.RegistryKey class to obtain a System. Security.AccessControl.RegistrySecurity object. Use the RegistrySecurity object to access the security and audit information for the registry key. These steps are demonstrated in Figure.

Getting security or audit information for a registry key

public static void ViewRegKeyRights()
{
    // Get security information from a registry key.
    using (RegistryKey regKey =
        Registry.LocalMachine.OpenSubKey(@"SOFTWARE\MyCompany\MyApp"))
    {
        RegistrySecurity regSecurity = regKey.GetAccessControl();
        DisplayRegKeySecurityInfo(regSecurity);
    }
}

public static void DisplayRegKeySecurityInfo(RegistrySecurity regSec)
{
    Console.WriteLine("GetSecurityDescriptorSddlForm: {0}",
        regSec.GetSecurityDescriptorSddlForm(AccessControlSections.All));

    foreach (RegistryAccessRule ace in
            regSec.GetAccessRules(true, true, typeof(NTAccount)))
    {
        Console.WriteLine("\tIdentityReference.Value: {0}",
                          ace.IdentityReference.Value);
        Console.WriteLine("\tAccessControlType: {0}", ace.AccessControlType);
        Console.WriteLine("\tRegistryRights: {0}", ace.RegistryRights.ToString());
        Console.WriteLine("\tInheritanceFlags: {0}", ace.InheritanceFlags);
        Console.WriteLine("\tIsInherited: {0}", ace.IsInherited);
        Console.WriteLine("\tPropagationFlags: {0}", ace.PropagationFlags);

        Console.WriteLine("-----------------\r\n\r\n");
    }

    foreach (RegistryAuditRule ace in
            regSec.GetAuditRules(true, true, typeof(NTAccount)))
    {
        Console.WriteLine("\tIdentityReference.Value: {0}",
                          ace.IdentityReference.Value);
        Console.WriteLine("\tAuditFlags: {0}", ace.AuditFlags);
        Console.WriteLine("\tRegistryRights: {0}", ace.RegistryRights.ToString());
        Console.WriteLine("\tInheritanceFlags: {0}", ace.InheritanceFlags);
        Console.WriteLine("\tIsInherited: {0}", ace.IsInherited);
        Console.WriteLine("\tPropagationFlags: {0}", ace.PropagationFlags);

        Console.WriteLine("-----------------\r\n\r\n");
    }
    Console.WriteLine("GetGroup(typeof(NTAccount)).Value: {0}",
                      regSec.GetGroup(typeof(NTAccount)).Value);
    Console.WriteLine("GetOwner(typeof(NTAccount)).Value: {0}",
                      regSec.GetOwner(typeof(NTAccount)).Value);

    Console.WriteLine("---------------------------------------\r\n\r\n\r\n");
}

These methods produce the following output:

	GetSecurityDescriptorSddlForm: O:S-1-5-21-329068152-1383384898-682003330-1004G:S-1-
	5-21-329068152-1383384898-682003330-513D:
	AI(A;ID;KR;;;BU)(A;CIIOID;GR;;;BU)(A;ID;KA;;;BA)(A;CIIOID;GA;;;BA)(A;ID;KA;;;SY)(A;CI
	IOID;GA;;;SY)(A;ID;KA;;;S-1-5-21-329068152-1383384898-682003330-
	1004)(A;CIIOID;GA;;;CO)
	    IdentityReference.Value: BUILTIN\Users
	    AccessControlType: Allow
	    RegistryRights: ReadKey
	    InheritanceFlags: None
	    IsInherited: True
	    PropagationFlags: None
	-----------------

	    IdentityReference.Value: BUILTIN\Users
	    AccessControlType: Allow
	    RegistryRights: -2147483648
	    InheritanceFlags: ContainerInherit
	    IsInherited: True
	    PropagationFlags: InheritOnly
	-----------------

	    IdentityReference.Value: BUILTIN\Administrators
	    AccessControlType: Allow
	    RegistryRights: FullControl
	    InheritanceFlags: None
	    IsInherited: True
	    PropagationFlags: None
	-----------------

	    IdentityReference.Value: BUILTIN\Administrators
	    AccessControlType: Allow
	    RegistryRights: 268435456
	    InheritanceFlags: ContainerInherit
	    IsInherited: True
	    PropagationFlags: InheritOnly
	-----------------

	    IdentityReference.Value: NT AUTHORITY\SYSTEM
	    AccessControlType: Allow
	    RegistryRights: FullControl
	    InheritanceFlags: None
	    IsInherited: True
	    PropagationFlags: None
	-----------------

	    IdentityReference.Value: NT AUTHORITY\SYSTEM
	    AccessControlType: Allow
	    RegistryRights: 268435456
	    InheritanceFlags: ContainerInherit
	    IsInherited: True
	    PropagationFlags: InheritOnly
	-----------------

	    IdentityReference.Value: OPERATOR-C1EFE0\Admin
	    AccessControlType: Allow
	    RegistryRights: FullControl
	    InheritanceFlags: None
	    IsInherited: True
	    PropagationFlags: None
	-----------------

	    IdentityReference.Value: CREATOR OWNER
	    AccessControlType: Allow
	    RegistryRights: 268435456
	    InheritanceFlags: ContainerInherit
	    IsInherited: True
	    PropagationFlags: InheritOnly
	-----------------

	GetGroup(typeof(NTAccount)).Value: OPERATOR-C1EFE0\None
	GetOwner(typeof(NTAccount)).Value: OPERATOR-C1EFE0\Admin
	---------------------------------------

Discussion

The essential method that is used to obtain the security information for a file or registry key is the GetAccessControl method. When this method is called on the RegistryKey object, a RegistrySecurity object is returned. However, when this method is called on a File class, a FileSecurity object is returned. The RegistrySecurity and FileSecurity objects essentially represent a Discretionary Access Control List (DACL), which is what developers writing code in unmanaged languages such as C++ are used to working with.

The RegistrySecurity and FileSecurity objects each contains a list of security rules that has been applied to the system object that it represents. The RegistrySecurity object contains a list of RegistryAccessRule objects, and the FileSecurity object contains a list of FileSystemAccessRule objects. These rule objects are the equivalent of the Access Control Entries (ACE) that make up the list of security rules within a DACL.

System objects other than just the File class and RegistryKey object allow security privileges to be queried. Figure lists all the .NET Framework classes that return a security object type and what that type is. In addition, the rule-object type that is contained in the security object is also listed.

List of all *Security and *AccessRule objects and the types to which they apply

Class

Object returned by the GetAccessControl method

Rule-object type contained within the security object

Directory

DirectorySecurity

FileSystemAccessRule

DirectoryInfo

DirectorySecurity

FileSystemAccessRule

EventWaitHandle

EventWaitHandleSecurity

EventWaitHandleAccessRule

File

FileSecurity

FileSystemAccessRule

FileInfo

FileSecurity

FileSystemAccessRule

FileStream

FileSecurity

FileSystemAccessRule

Mutex

MutexSecurity

MutexAccessRule

RegistryKey

RegistrySecurity

RegistryAccessRule

Semaphore

SemaphoreSecurity

SemaphoreAccessRule


The abstraction of a system object's DACL through the *Security objects and the abstraction of a DACL's ACE through the *AccessRule objects allows easy access to the security privileges of that system object. In previous versions of the .NET Framework, these DACLs and their ACEs would have been accessible only in unmanaged code. With the latest .NET Framework, you now have access to view and program these objects.

See Also

See Recipe 17.14; see the "System.IO.File.GetAccessControl Method," "System. Security.AccessControl.FileSecurity Class," "Microsoft.Win32.RegistryKey.GetAccessControl Method," and "System.Security.AccessControl.RegistrySecurity Class" topics in the MSDN documentation.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows