WMI - Enabling Privileges

Some operations that can be carried out through WMI may require the user to hold certain system privileges. For instance, the ability to reboot a computer is dependent on SeShutdownPrivilege or SeRemoteShutdownPrivilege, which must not only be granted to the user, but must also be enabled for the process that is attempting the reboot. The privileges can be granted using the local security policy editor.

Once the privileges are granted, they have to be explicitly enabled by the process attempting the privileged operation. Thus, in order to reboot a remote computer you may write code similar to the following:

ManagementClass mc = new ManagementClass(
@"\\BCK_OFFICE\root\CIMV2:Win32_OperatingSystem");
foreach(ManagementObject mo in mc.GetInstances()) {
mo.Scope.Options.Username = "username";
mo.Scope.Options.Password = "password";
mo.Scope.Options.EnablePrivileges = true;
mo.InvokeMethod("Reboot", new Object [] {0});
}

This code binds to the Win32_OperatingSystem WMI class, enumerates its instances, and invokes the Reboot method for each operating system. Of course in most cases, there would be a single instance of the Win32_OperatingSystem class and it is probably easier to just locate such an instance directly based on its key. Unfortunately, the key of this class is the name of the OS, which is often very long and easy to mistype, therefore, I chose to use the enumeration approach. The thing you should notice here is the line of code that sets the EnablePrivileges property of the ConnectionOptions object to true. Unlike the AdjustTokenPrivileges function, which allows you to enable and disable individual privileges, setting the EnablePrivileges property to true enables all privileges granted to a given user or group. In effect, assigning this property to true is equivalent to obtaining the set of privileges associated with the access token via the GetTokenInformation function; iterating through the returned array of token privileges to set the enabled attribute for each of them; and then invoking AdjustTokenPrivileges. Here again the designers of the System.Management namespace chose to trade flexibility for simplicity by disallowing access to individual user and group privileges.

Lastly, there is still the question of figuring out which WMI operations are privileged and exactly what privileges are required to perform such operations. Although it is always possible to get the answer by digging through the mess of WMI security documentation, there is an easier way. It turns out that all WMI methods that require certain privileges are marked as such using the Privileges qualifier. For instance, take a look at the partial MOF definition for the Win32_OperatingSystem class:

class Win32_OperatingSystem : CIM_OperatingSystem {
...
[Privileges{"SeShutdownPrivilege"}: ToSubClass]
uint32 Reboot();
[Privileges{"SeShutdownPrivilege"}: ToSubClass]
uint32 Shutdown();
[Privileges{"SeShutdownPrivilege"}: ToSubClass]
uint32 Win32Shutdown(sint32 Flags, sint32 Reserved = 0);
};

Here the Privileges qualifier is parameterized with the string value of the required privilege. In reality, the qualifier value is really an array of strings, so it is possible to account for methods that require multiple privileges to be enabled. Therefore, by examining the qualifiers associated with a given method, you can determine whether it is necessary to enable the privileges before attempting to execute the method. Note that it is not even necessary to check the qualifier value (since individual privileges cannot be controlled via the System.Management types anyway)—the mere presence of the Privileges qualifier is indicative of a privileged operation.

Source of Information : Dot NET System Management Services - Apress

0 comments


Subscribe to Developer Techno ?
Enter your email address:

Delivered by FeedBurner