Introduction
This class library allows access to the Win32 security calls in a .NET friendly way. It encapsulates the concepts of a user, a securable object (like a file, named pipe, directory, etc.), and permissions. This library was written in Managed C++ to simplify the amount of work needed to link to existing Win32
libraries. However, since it exposes all of its functionality via .NET, it can be used from any .NET compliant language, including C# and Visual Basic. The project was written and compiled with Visual Studio 2002.
NOTE: There is a library written by some Microsoft guys on GotDotNet that does much of the same thing and more. It can be found at http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=e6098575-dda0-48b8-9abf-e0705af065d9.
This article outlines the primary objects in the library and their use in manipulating security objects.
Documentation
WindowsUser class
This class represents a single Windows identity (SID). It can be created by
specifying either a username ("DOMAIN\user" format) or the string representation
of a SID ("S-1-5-xxxx-xxx..."). You can also get the identity of the current
user using the static property CurrentUser
.
There are a number of predefined identities that exist as static members of a
child class called WellKnownIdentities
. Once you have an identity,
you can get the following properties:
AccountName
: string name of the account
Domain
: string name of the account's domain
FullName
: string in the form of "Domain\AccountName"
SidString
: string representation of the SID
SecuredObject class
This class represents an object which can have a security descriptor. It can
be created by specifying the name of the resource along with its type or by
passing a handle (as an IntPtr
) to the resource.
Once you have the object, you can update the permissions, audit information,
owner and group.
PermissionsList
This class encapsulates actions on the ACL. It allows granting, revoking,
changing, and denying access levels to different users. Derived from
AccessList
, which is a collection class for AccessEntry
.
AuditingList
This class encapsulates actions on the auditing list of an object. It allows
getting and setting audit success and failure rights. Derived from
AccessList
, which is a collection class for AccessEntry
.
AccessEntry
This class encapsulates the Access Control Entry or ACE. You can set the
user (trustee) and the associated rights and inheritance.
Example
This code shows the library in action. It assumes you have aliased the Microsoft.Win32.Security namespace (using in C#, Imports in VB).
WindowsUser user = WindowsUser.CurrentUser;
Console.WriteLine("{0} ({1})", user.FullName, user.SidString);
WindowsUser duser = new WindowsUser(
System.Security.Principal.WindowsIdentity.GetCurrent().Token);
Console.WriteLine(duser.FullName);
if (user == duser)
Console.WriteLine("Same");
else
Console.WriteLine("Different");
user = WindowsUser.WellKnownIdentities.World;
Console.WriteLine(user.FullName);
WindowsUser kuser = new WindowsUser("user2", @"\\MYPDC");
Console.WriteLine(kuser.FullName);
user = new WindowsUser("DOMAIN\\user3");
Console.WriteLine(user.FullName);
user = new WindowsUser("S-1-5-21-21782756-1035017279-1439700725-1111");
Console.WriteLine(user.FullName);
SecuredObject sec = new SecuredObject("C:\\", SecuredObjectType.FileObject);
DumpObject(sec);
// Set some various permissions on the directory
sec.Permissions.SetAccess(kuser, AccessRights.FileRead,
AceInheritanceFlags.ContainerInherit|AceInheritanceFlags.ObjectInherit);
sec.Permissions.GrantAccess(kuser, AccessRights.FileExecute,
AceInheritanceFlags.ContainerInherit|AceInheritanceFlags.ObjectInherit);
sec.Permissions.DenyAccess(kuser, AccessRights.FileWriteUnsync,
AceInheritanceFlags.ContainerInherit|AceInheritanceFlags.ObjectInherit);
WindowsUser owner = sec.Owner;
sec.Owner = duser;
sec.Auditing.SetAuditFailure(duser, AccessRights.FileReadUnsync,
AceInheritanceFlags.ContainerInherit|AceInheritanceFlags.ObjectInherit);
DumpObject(sec);
// Revoke some access
sec.Permissions.RevokeAccess(kuser);
sec.Owner = owner;
DumpObject(sec) ;
// Reset the security on the directory
sec.Permissions.Clear();
sec.Permissions.InheritFromParent = true;
DumpObject(sec);
// Write the DACL using the Microsoft style
Console.WriteLine(sec.ToString());
The following function shows how to enumerate the permissions on a security
object.
static void DumpObject(SecuredObject sec)
{
Console.WriteLine("Security description:");
Console.WriteLine("=====================");
Console.WriteLine("Owner: {0}\nGroup: {1}",
sec.Owner.FullName, sec.Group.FullName);
Console.WriteLine("Permissions:");
foreach (AccessEntry ace in sec.Permissions)
Console.WriteLine(String.Format(" {0} : {1} : {2}",
ace.Trustee.FullName,
ace.Inheritance, ace.Rights));
Console.WriteLine("Auditing:");
foreach (AccessEntry ace in sec.Auditing)
Console.WriteLine(String.Format(" {0} : {1} : {2}",
ace.Trustee.FullName,
ace.Inheritance, ace.Rights));
}