I've been working lately on adding "self-healing" capabilities to a certain application.  The idea is to create a set of utility functions which will validate (and fix if needed) various environmental settings such as NTFS permissions, registry permissions, IIS metabase settings, etc.  None if this is rocket science but there still was some work involved in bringing it all together, so I'll list it here in case I (or you) ever need to do it in the future.

Note: For anything related to security in 1.1, the Windows32.Security library  (written by Renaud Paquay) is an indispensable resource.

Snippet #1:   Check for permissions on a registry key (using Windows32.Security)

public bool TestRegistryKeyPermissions(string keyName, string userName)

{

      // get a handle to the key

      IntPtr hKey;

      if (Microsoft.Win32.Security.Win32.RegOpenKey(Win32Consts.HKEY_LOCAL_MACHINE, keyName, out hKey) != Microsoft.Win32.Security.Win32.SUCCESS)

      {

            return false;

      }

      try

      {

            // get the security descriptor

            using (SecurityDescriptor sd = SecurityDescriptor.GetRegistryKeySecurity (hKey, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION))

            {

                  // check whether the specified user has an ACE in the ACL

                  Dacl acl = sd.Dacl;

                  return TestAcl(acl,userName);

            }    

      }    

      catch

      {

            return false;

      }

}

 

public static bool TestAcl(Dacl acl, string userName)

{

      for(int i=0; i<acl.AceCount;i++)

      {

            Ace ace= acl.GetAce(i);

            if (ace.Sid.AccountName == userName)

            {

                  return true;

            }

      }

      return false;

}

 

Snippet #2:   Set permissions on a registry key (using Windows32.Security)

 

public static void SetRegistryKeyPermissions(string keyName, string userName)

{

      // get a handle to the key

      IntPtr hKey;

      if (Microsoft.Win32.Security.Win32.RegOpenKey(Win32Consts.HKEY_LOCAL_MACHINE, keyName, out hKey) != Microsoft.Win32.Security.Win32.SUCCESS)

      {

            throw new Exception ("failed to access registry key " + keyName);

      }

 

      try

      {

            // get the security descriptor

            using (SecurityDescriptor sd = SecurityDescriptor.GetRegistryKeySecurity (hKey, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION))

            {

                  // give the service user standard read access.

                  Dacl acl = sd.Dacl;

                  Sid serviceUserSID = new Sid(userName);

                  acl.RemoveAces (serviceUserSID);

                 

                  AccessType aclAccessType =  AccessType.GENERIC_ALL ;

                  acl.AddAce (new AceAccessAllowed (serviceUserSID, aclAccessType , AceFlags.OBJECT_INHERIT_ACE | AceFlags.CONTAINER_INHERIT_ACE));

                       

                  // set the values

                  sd.SetDacl(acl);

                  sd.SetRegistryKeySecurity (hKey, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);

            }

      }

      finally

      {

            Microsoft.Win32.Security.Win32.RegCloseKey (hKey);

      }

}