![]() |
Show Changes |
![]() |
Edit |
![]() |
|
![]() |
Recent Changes |
![]() |
Subscriptions |
![]() |
Lost and Found |
![]() |
Find References |
![]() |
Rename |
| Search |
History
| 6/9/2006 1:24:31 PM |
| -71.211.188.249 |
| 6/9/2006 1:24:18 PM |
| -71.211.188.249 |
| 6/8/2006 2:08:04 PM |
| -71.211.188.249 |
| 6/8/2006 2:07:26 PM |
| -71.211.188.249 |
![]() |
List all versions |
The local security authority (LSA) on each machine ultimately decides what privileges will be granted to a user when she logs in. The most direct way of affecting that decision is to open the local security policy of the machine and edit the privilege grants there. You can get to the local security policy either by running secpol.msc from an administrative command prompt (HowToDevelopCodeAsANonAdmin) or by looking on the Start menu for an administrative tool called "Local Security Policy." From there, drill down into "Local Policies" and select "User Rights Assignment." I show a picture of this editor in WhatIsAPrivilege Figure 21.1).
In a domain environment it's also possible to set privileges (and all other local security policy) at the domain, site, or organizational unit (OU) levels, and the local machine will download those updates at each reboot (or more frequently if you configure periodic refreshes). Check out WhatIsGroupPolicy for more details.
Because privilege assignments are always expanded at the local machine, you can grant them to individual users from any domain or any group known to that machine. This includes all four types of group (WhatIsAGroup). Privileges are very flexible this way. Note, though, that if you use group policy to set privileges for a large number of machines, you'll have to be careful about the types of group you use: Use only those that will have meaning on all the machines to which your group policy will apply! The group names you specify in group policy aren't checked for validity: They’re only stored as strings. It's not until the policy is actually deployed to individual machines that these names are used to look up real groups, converted into SIDs (WhatIsASID), and stored in the local policy of the machine.
Also note that, like groups, any changes you make to privilege assignments won't take effect for any given user until she establishes a fresh logon on the machine. I've seen many developers who, after granting themselves a privilege on their machine and then starting a new process, expect the privilege grant to take effect immediately. Don't forget the latency that's inherent in each security context (WhatIsSecurityContext)! If you start another process, you're just going to get a copy of the parent process's token, which won't have the new privilege in it. Log off and back on to get a fresh token.
On a few occasions I'll cheat by using the Secondary Logon Service (HowToRunAProgramAsAnotherUser). For example, Windows XP has the annoying restriction (I can't imagine that it's intentional; it's probably a bug) that prevents nonadministrators from changing their power-saving settings. This makes it a pain for me to run as a non-admin on my laptop. When I get on a plane, I usually want to change my power settings to "max battery," but because each user profile (WhatIsAUserProfile) has its own settings, I can't simply run powercfg.cpl from an administrative command prompt. I need to put myself in the local Administrators group temporarily and make the change in my own user profile. To avoid having to log off and log back on, I simply run the following batch file from my admin command prompt:
REM ******************************************** REM powercfg.cmd - temporarily elevate privilege REM and launch the power configuration editor REM ******************************************** net localgroup administrators keith /add runas /u:keith "cmd /c powercfg.cpl" net localgroup administrators keith /delete
This works because the secondary logon service always establishes a fresh logon before launching the new process.
You can also grant (and enumerate) privileges programmatically, via the Win32 LSA API, but note that, just as when running the local security policy tool interactively, you must be an administrator to read or write privilege settings in policy. Figure 23.1 shows a C# program that uses a helper class manages privileges in policy (you can download the entire sample library from the website for this book). The PrivilegePolicy class is written in Managed C++ and simplifies the programmatic use of privileges. Note that this code also uses the SecurityIdentifier class that's new in version 2.0 of the .NET Framework, which makes it easy to translate between SIDs and account names (WhatIsASID).
using System;
using System.Security.AccessControl;
using KBC.WindowsSecurityUtilities;
class Test {
static void Main() {
WindowsSecurityUtilities.Initialize();
string account = @"BUILTIN\Backup Operators";
PrintUsersWithShutdownPrivilege();
Console.WriteLine("Adding privilege...");
PrivilegePolicy.AddPrivilege(account,
Privileges.Shutdown);
PrintUsersWithShutdownPrivilege();
Console.WriteLine("Removing privilege...");
PrivilegePolicy.RemovePrivilege(account,
Privileges.Shutdown);
PrintUsersWithShutdownPrivilege();
WindowsSecurityUtilities.Terminate();
}
static void PrintUsersWithShutdownPrivilege() {
foreach (byte[] bsid in PrivilegePolicy.GetPrivilegeGrants(
Privileges.Shutdown)) {
SecurityIdentifier sid = new SecurityIdentifier(bsid, 0);
Console.WriteLine(sid.Translate(typeof(NTAccount)));
}
}
}
Figure 23.1 Enumerating, adding, and removing privileges programmatically
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