![]() |
Show Changes |
![]() |
|
![]() |
Recent Changes |
![]() |
Subscriptions |
![]() |
Lost and Found |
![]() |
Find References |
![]() |
Rename |
| Search |
History
| 8/5/2006 3:51:32 PM |
| -71.212.190.55 |
![]() |
List all versions |
No book on Windows security programming would be complete without showing you how to programmatically read, write, or modify an ACL. But, frankly, before you run off and write lots of code to do this, consider whether it's really the right thing to do. Security policy is normally controlled by administrators, and programs usually can't make these decisions—even installation programs. Maybe what you really need is a graphical editor to allow an administrator to specify an ACL, and then you can simply persist that ACL somewhere until your program needs it. I like that idea a lot better than having people hardcode ACLs in their code!
To that end, I've uploaded some code to my Web site that I've been carrying around with me for a number of years. It uses the Win32 ACL UI interface (ISecurityInformation) to allow you to graphically construct any ACL you might need; then it spits out a stringified security descriptor (WhatIsASecurityDescriptor) that you can drop into a configuration file or even a registry key. It's called "EditSD," and you can download it here . It's a reasonable starting place for an interactive ACL editor for a server application installation program, but you'll need to tweak it to customize the permission names and values, and integrate it into your installer. The language used to stringify the security descriptor is called the Security Descriptor Description Language (SDDL), and with one function call you can rehydrate that string into a security descriptor that can be applied to any object secured with a DACL (see HowToPersistASecurityDescriptor for more details).
Even with that tool, however, someone will still need to programmatically construct an ACL from time to time. For example, if you're writing code to automatically deploy a piece of software on a machine, you might need to set ACLs on files, directories, services, and so on. Before version 2.0 of the .NET Framework, you pretty much had to write this type of code in C++ because the Win32 API was full of nasty pointer arithmetic, scary-looking casts, and so on. But version 2.0 introduces a new namespace (System.Security.AccessControl) that brings access control programming to the managed world (I still recommend you avoid constructing ACLs in code if you can).
The sample code in Figure 47.1 reads an ACL from a file, prints it out, and then grants ACME\Bob permission to delete the file. If you have ever done ACL programming in C++, you will seriously appreciate the simplicity of this code.
The corresponding sample in C++ would require an order of magnitude more time and code.
using System;
using System.IO;
using System.Security.Principal;
using System.Security.AccessControl;
class ModifyFileDacl {
const string path = @"c:\work\test.txt";
const string userName = @"ACME\Bob";
static void Main() {
FileSecurity sd = File.GetAccessControl(path);
PrintOwerAndDACL(sd);
Console.WriteLine("Granting DELETE to {0}", userName);
ModifyDACL(sd);
File.SetAccessControl(path, sd);
PrintOwerAndDACL(sd);
}
static void PrintOwerAndDACL(FileSecurity sd) {
Console.WriteLine("Owner: {0}", sd.GetOwner(typeof(NTAccount)));
// rule represents an ACE
foreach (FileSystemAccessRule rule in
sd.GetAccessRules(true, true, typeof(NTAccount))) {
PrintACE(rule);
}
}
static void PrintACE(FileSystemAccessRule rule) {
Console.WriteLine("{0} {1} to {2} ({3})",
AccessControlType.Allow == rule.AccessControlType ?
"grant" : "deny",
rule.FileSystemRights, // access permission mask
rule.IdentityReference,
rule.IsInherited ? "inherited" : "direct");
}
static void ModifyDACL(FileSecurity sd) {
FileSystemAccessRule ace = new FileSystemAccessRule(
new NTAccount(userName),
FileSystemRights.Delete,
AccessControlType.Allow);
sd.AddAccessRule(ace);
}
}
Figure 47.1 ACL programming in version 2.0 of the .NET Framework
The entire AccessControl namespace was redesigned from the ground up between the alpha (which is when I originally wrote this item) and beta 1 (which I’m looking at now as I make final edits). The beta 1 programming model (which I’ve shown above) is much cleaner than the alpha version, but doesn’t cover as broad a range of objects. My original sample showed how to change the DACL for a service, but that’s no longer possible in the beta. This doesn’t discourage me in the least, because the new design is so much easier to use, and it only took me about 15 minutes or so to extend the object model to support my original example: setting the DACL for a service. Keep your eyes on my Security Briefs column in MSDN Magazine, as I’ll surely be writing about this in the future as this namespace develops.
Keith's first book-in-a-wiki. If you would like to read the book online or order a physical copy to throw at annoying coworkers, surf to the HomePage. Please note that due to overwhelming wikispam, this particular wiki is no longer editable.
About FlexWiki.
Recent Topics