Using the RegGetKeySecurity() and RegSetKeySecurity() Functions


Using the RegGetKeySecurity() and RegSetKeySecurity() Functions

Another area where you need to use the Win32 API to control security is the registry. If you want to determine the current security state of the registry, then you need to use the RegGetKeySecurity() function. Likewise, you’ll use the RegSetKeySecurity() function to set the registry security. Listing 15.5 shows the first part of the process—determining the current security state. This listing only shows the essentials and lacks information such as the Win32 API calling syntax. (You can find the complete source code for this example in the \Chapter 15\C#\SecureRegistry and \Chapter 15\VB\SecureRegistry folders of the source code located on the Sybex Web site.)

Listing 15.5 Reading a Registry Entry

start example
private void btnRead_Click(object sender, System.EventArgs e) {    IntPtr         KeyHandle;  // Registry key handle.    Int32          Result;     // Result of a call.    IntPtr         SD;         // The security descriptor.    Int32          SDSize;     // Size of the security descriptor.    Int32          LastError;  // Last Win32 API error.    IntPtr         OwnerSID;   // SID of the owner account.    Boolean        IsDefault;  // Is this a defaulted account?    Int32          NameSize;   // Size of the account name.    Int32          DomainSize; // Size of the domain name.    StringBuilder  Name;       // Account name.    StringBuilder  Domain;     // Domain name.    SID_NAME_USE   Use;        // Account use.    // Open the registry key entry.    Result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,                          @"Software\LockedKey",                          0,                          REGSAM.KEY_ALL_ACCESS,                          out KeyHandle);    // Get the security information size.    SDSize = 0;    SD = new IntPtr(0);    Result = RegGetKeySecurity(KeyHandle,                      SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION,                      SD,                      out SDSize);    // Get the security information.    SD = Marshal.AllocHGlobal(SDSize);    Result = RegGetKeySecurity(KeyHandle,                      SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION,                      SD,                      out SDSize);    ... Lookup SID and Display Information ...    // Free the memory we allocated.    Marshal.FreeHGlobal(SD);    // Close the registry key.    RegCloseKey(KeyHandle); }
end example

You might find it hard to imagine, but unlike many other objects in the .NET Framework, the RegistryKey object doesn’t include any method for obtaining a handle. Unfortunately, many of the Win32 API calls require a handle, so you need to open the registry key using the RegOpenKeyEx() function. Translating this function into code that .NET can understand requires a few additional tricks. For example, you need two versions of the function. The first accepts an IntPtr as an input for use with handles you create using any of the registry functions that return a handle, while the second accepts a UInt32 value that corresponds to the standard registry handles such as HKEY_CLASSES_ROOT.

After the code opens the registry key for this example, it uses the RegGetKeySecurity() function to obtain a security descriptor for the registry key. This security descriptor works precisely the same as the security descriptor used with a file in Listing 15.4. In fact, once the code obtains the security descriptor, it uses the same display code as shown in Listing 15.4 with a few slight modifications. See the source code for additional information. As usual, the code frees the memory used for the security descriptor and closes the registry key handle.

Adding security to a registry entry is like any other Windows object. Listings 15.1 and 15.2 show how to work with the security descriptors that Windows requires. Once you create a security descriptor, you use the RegSetKeySecurity() function to add security to a specific registry key. Here’s the function declaration you need for this function.

  // This function sets registry security.   [DllImport(“AdvAPI32.DLL”, CharSet=CharSet.Auto, SetLastError=true )]   public static extern Int32 RegSetKeySecurity(      IntPtr hKey,      SECURITY_INFORMATION SecurityInformation,      IntPtr pSecurityDescriptor);

Notice that the function accepts three inputs. The first is the registry key handle. Listing 15.5 shows how to open a registry key and obtain a handle for it. The second is the SECURITY_INFORMATION enumerated value that defines the values contained in the security descriptor. Here’s a listing of the possible values.

// This enumeration tells what type of information we want to retrieve // or set in the registry. public enum SECURITY_INFORMATION : uint {    OWNER_SECURITY_INFORMATION                = 0x00000001,    GROUP_SECURITY_INFORMATION                = 0x00000002,    DACL_SECURITY_INFORMATION                 = 0x00000004,    SACL_SECURITY_INFORMATION                 = 0x00000008,    PROTECTED_DACL_SECURITY_INFORMATION       = 0x80000000,    PROTECTED_SACL_SECURITY_INFORMATION       = 0x40000000,    UNPROTECTED_DACL_SECURITY_INFORMATION     = 0x20000000,    UNPROTECTED_SACL_SECURITY_INFORMATION     = 0x10000000 };

Notice that you can set the owner, group, DACL, or SACL information individually or in combination. The final input value, pSecurityDescriptor, accepts the security descriptor. As mentioned earlier, you build the security descriptor using the same techniques as you use for a file or other Windows object.




.Net Development Security Solutions
.NET Development Security Solutions
ISBN: 0782142664
EAN: 2147483647
Year: 2003
Pages: 168

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net