Click here to Skip to main content
15,887,214 members
Articles / Programming Languages / C#
Article

NT Security Classes for .NET

Rate me:
Please Sign up or sign in to vote.
4.78/5 (33 votes)
19 Feb 2004CPOL2 min read 378K   4K   75   103
A collection of .NET classes written in Managed C++ that faciliate the manipulation of NT security rights

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).

C#
// Get the current user and print their information
WindowsUser user = WindowsUser.CurrentUser;
Console.WriteLine("{0} ({1})", user.FullName, user.SidString);

// Get the current user from their token
WindowsUser duser = new WindowsUser(
  System.Security.Principal.WindowsIdentity.GetCurrent().Token);
Console.WriteLine(duser.FullName);

// Compare users
if (user == duser)
   Console.WriteLine("Same");
else
   Console.WriteLine("Different");

// Get a well-known user
user = WindowsUser.WellKnownIdentities.World;
Console.WriteLine(user.FullName);

// Get a user by name from a specific server (usually a domain controller)
WindowsUser kuser = new WindowsUser("user2", @"\\MYPDC");
Console.WriteLine(kuser.FullName);

// Get a user by name
user = new WindowsUser("DOMAIN\\user3");
Console.WriteLine(user.FullName);

// Get a user by SID
user = new WindowsUser("S-1-5-21-21782756-1035017279-1439700725-1111");
Console.WriteLine(user.FullName);

// Get security for C:\ directory
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.

C#
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));
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
United States United States
I have been a Windows software developer since 1991. Most of what I create fills the need for some aspect of bigger projects that I consult on.

Comments and Discussions

 
AnswerRe: registrykey securedobject? Pin
groovyponens6-Oct-02 23:29
groovyponens6-Oct-02 23:29 
GeneralACCESS_MASK Pin
Mazdak19-Sep-02 3:34
Mazdak19-Sep-02 3:34 
GeneralOwners! Pin
Mazdak19-Sep-02 2:18
Mazdak19-Sep-02 2:18 
GeneralInheritence of permssions Pin
Syborg7712-Sep-02 21:13
Syborg7712-Sep-02 21:13 
GeneralRe: Inheritence of permssions Pin
Pierrick17-Sep-02 5:43
Pierrick17-Sep-02 5:43 
GeneralRe: Inheritence of permssions Pin
Syborg7717-Sep-02 20:43
Syborg7717-Sep-02 20:43 
GeneralRe: Inheritence of permssions Pin
Pierrick17-Sep-02 23:00
Pierrick17-Sep-02 23:00 
GeneralRe: Inheritence of permssions Pin
Syborg7718-Sep-02 21:06
Syborg7718-Sep-02 21:06 
Ur problem seems to be extremely strange OMG | :OMG: firstly to change owner information in anyway requires SE_TAKEOWNERSHIP privilege on ur processes Access Token and mind u ownership can only be Taken and not set to any user according to Microsoft (if u read some previous threads ... in those converstions me and David have found otherwise..Smile | :) )....back to the problem ....secondly the fuction which does the actual work of manipulating any information owner,group , dacl or sacl is "SetNamedSecurityInfo" ill just try to explain what this function does so that u can play around with it......

DWORD SetNamedSecurityInfo(
LPTSTR pObjectName,
SE_OBJECT_TYPE ObjectType,
SECURITY_INFORMATION SecurityInfo,
PSID psidOwner,
PSID psidGroup,
PACL pDacl,
PACL pSacl
);
where

pObjectName corresponds to
Pointer to a null-terminated string that specifies the name of the object for which to set security information.
In our case is name of a file or directory on an NTFS file system.

ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object named by the pObjectName parameter.In our case
would be SE_FILE_OBJECT.

psidOwner
Pointer to a SID that identifies the object's owner.The SID must be one that can be assigned as the owner SID of a security descriptor.
The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. The caller must have WRITE_OWNER access to
the object or have the SE_TAKE_OWNERSHIP_NAME privilege enabled. This parameter can be NULL if you are not setting the owner SID.

psidGroup
Pointer to a SID that identifies the object's primary group. The SecurityInfo parameter must include the GROUP_SECURITY_INFORMATION flag.
This parameter can be NULL if you are not setting the primary group SID.

pDacl
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 object's owner. This parameter can be NULL if you are not setting the DACL.

pSacl
Pointer to the new SACL for the object. The SecurityInfo parameter must include the SACL_SECURITY_INFORMATION flag.
The caller must have the SE_SECURITY_NAME privilege enabled. This parameter can be NULL if you are not setting the SACL.

and last but not least

SecurityInfo
A set of SECURITY_INFORMATION bit flags that indicate the type of security information to set.
ie the owner info,or the group info, or dacl info or sacl info.
This parameter can be a combination of the following values.
OWNER_SECURITY_INFORMATION : if this flag is set,the sid contained in the psidOwner would be updated in the descriptor
else the value would be ignored.
GROUP_SECURITY_INFORMATION : if this flag is set,the sid contained in the psidGroup would be updated in the descriptor
else the value would be ignored.
DACL_SECURITY_INFORMATION : if this flag is set,the DACL information contained pDACL would be updated in the descriptor
else the value would be ignored.
SACL_SECURITY_INFORMATION : if this flag is set,the SACL information contained pSACL would be updated in the descriptor
else the value would be ignored.

PROTECTED_DACL_SECURITY_INFORMATION : Protects the DACL from inheriting ACEs.
This value is ignored unless DACL_SECURITY_INFORMATION is also used.ie the effective value would be
DACL_SECURITY_INFORMATION|PROTECTED_DACL_SECURITY_INFORMATION.

UNPROTECTED_DACL_SECURITY_INFORMATION : DACLs inherits from parent inheritable ACEs.This value is ignored unless
DACL_SECURITY_INFORMATION is also used.ie the effective value would be DACL_SECURITY_INFORMATION|UNPROTECTED_DACL_SECURITY_INFORMATION.

PROTECTED_SACL_SECURITY_INFORMATION : Protects the SACL from inheriting ACEs.
This value is ignored unless SACL_SECURITY_INFORMATION is also used.ie the effective value would be
SACL_SECURITY_INFORMATION|PROTECTED_SACL_SECURITY_INFORMATION.

UNPROTECTED_SACL_SECURITY_INFORMATION : SACLs inherits from parent inheritable ACEs.This value is ignored unless
SACL_SECURITY_INFORMATION is also used.ie the effective value would be DACL_SECURITY_INFORMATION|UNPROTECTED_DACL_SECURITY_INFORMATION.


N as far as ur question wether this is happening to me .. nops ... its not ... it should not ... if u read how the above funciton works
Any ways send me some more details on who the owner is before it is magically set to NULL have u modified the token information in any way for the library ??

hope whatever i have written helps ya ...


adios
GeneralRe: Inheritence of permssions Pin
Pierrick19-Sep-02 6:18
Pierrick19-Sep-02 6:18 
GeneralVC.NET Pin
Mazdak28-Aug-02 22:08
Mazdak28-Aug-02 22:08 
GeneralSystem.Xml.Serialization Pin
Rye21-Aug-02 4:37
Rye21-Aug-02 4:37 
GeneralRe: System.Xml.Serialization Pin
David Hall21-Aug-02 8:33
professionalDavid Hall21-Aug-02 8:33 
Generalproblems accessing the security object Pin
Syborg779-Aug-02 19:57
Syborg779-Aug-02 19:57 
GeneralRe: problems accessing the security object Pin
David Hall12-Aug-02 8:58
professionalDavid Hall12-Aug-02 8:58 
GeneralRe: problems accessing the security object Pin
Syborg7713-Aug-02 20:48
Syborg7713-Aug-02 20:48 
GeneralRe: problems accessing the security object Pin
David Hall14-Aug-02 4:22
professionalDavid Hall14-Aug-02 4:22 
GeneralRe: problems accessing the security object Pin
Syborg7717-Aug-02 1:39
Syborg7717-Aug-02 1:39 
GeneralRe: problems accessing the security object Pin
David Hall19-Aug-02 6:11
professionalDavid Hall19-Aug-02 6:11 
GeneralRe: problems accessing the security object Pin
Syborg7719-Aug-02 23:40
Syborg7719-Aug-02 23:40 
GeneralRe: problems accessing the security object Pin
David Hall20-Aug-02 8:47
professionalDavid Hall20-Aug-02 8:47 
GeneralRe: problems accessing the security object Pin
Syborg7722-Aug-02 22:54
Syborg7722-Aug-02 22:54 
GeneralVery interesting! Pin
serberwww29-Jul-02 21:20
serberwww29-Jul-02 21:20 
GeneralRe: Very interesting! Pin
David Hall30-Jul-02 4:39
professionalDavid Hall30-Jul-02 4:39 
GeneralRe: Very interesting! Pin
serberwww6-Aug-02 4:04
serberwww6-Aug-02 4:04 
GeneralRe: Very interesting! Pin
Yik Kheam30-Sep-02 14:46
sussYik Kheam30-Sep-02 14:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.