예제 #1
0
        /// <summary>
        /// Check and if required, fix permissions on HKEY_CLASSES_ROOT
        /// </summary>
        /// <param name="FixPermissions">True to fix missing permissions, false just to check and report permission state</param>
        protected static void CheckHKCRPermissions(bool FixPermissions)
        {
            try
            {
                LogMessage("CheckHKCRPermissions", "Starting HKCR permission check, FixPermissions: " + FixPermissions.ToString());

                bool         FoundCreatorOwnerGenericAccess   = false;
                bool         FoundSystemGenericAccess         = false;
                bool         FoundSystemSpecificAccess        = false;
                bool         FoundAdministratorGenericAccess  = false;
                bool         FoundAdministratorSpecificAccess = false;
                bool         FoundUserGenericAccess           = false;
                bool         FoundUserSpecificAccess          = false;
                AccessRights Rights;

                RegistrySecurity HKCRAccessControl = Registry.ClassesRoot.GetAccessControl();

                //Iterate over the rule set and list them for Built in users
                foreach (RegistryAccessRule RegRule in HKCRAccessControl.GetAccessRules(true, true, typeof(NTAccount)))
                {
                    Rights = (AccessRights)RegRule.RegistryRights;

                    LogMessage("CheckHKCRPermissions", "Found rule: " + RegRule.AccessControlType.ToString() + " " + RegRule.IdentityReference.ToString() + " " + Rights.ToString() + " / " + (RegRule.IsInherited ? "Inherited" : "NotInherited") + " / " + RegRule.InheritanceFlags.ToString() + " / " + RegRule.PropagationFlags.ToString());

                    // Allow CREATOR OWNER GenericAll / NotInherited / ContainerInherit / InheritOnly
                    if ((RegRule.IdentityReference.ToString().Equals(GetLocalAccountName(CreatorOwnerSID), StringComparison.OrdinalIgnoreCase)) &
                        Rights == AccessRights.GenericAll &
                        RegRule.InheritanceFlags == InheritanceFlags.ContainerInherit &
                        RegRule.PropagationFlags == PropagationFlags.InheritOnly)
                    {
                        FoundCreatorOwnerGenericAccess = true;
                    }

                    // Allow NT AUTHORITY\SYSTEM GenericAll / NotInherited / ContainerInherit / InheritOnly
                    if ((RegRule.IdentityReference.ToString().Equals(GetLocalAccountName(NTAuthoritySystemSID), StringComparison.OrdinalIgnoreCase)) &
                        Rights == AccessRights.GenericAll &
                        RegRule.InheritanceFlags == InheritanceFlags.ContainerInherit &
                        RegRule.PropagationFlags == PropagationFlags.InheritOnly)
                    {
                        FoundSystemGenericAccess = true;
                    }

                    // Allow NT AUTHORITY\SYSTEM Query, SetKey, CreateSubKey, EnumSubkey, Notify, CreateLink, StandardDelete, StandardReadControl, StandardWriteDAC, StandardWriteOwner / NotInherited / None / None
                    if ((RegRule.IdentityReference.ToString().Equals(GetLocalAccountName(NTAuthoritySystemSID), StringComparison.OrdinalIgnoreCase)) &
                        Rights == FullRights &
                        RegRule.InheritanceFlags == InheritanceFlags.None &
                        RegRule.PropagationFlags == PropagationFlags.None)
                    {
                        FoundSystemSpecificAccess = true;
                    }

                    // Allow BUILTIN\Administrators GenericAll / NotInherited / ContainerInherit / InheritOnly
                    if ((RegRule.IdentityReference.ToString().Equals(GetLocalAccountName(BuiltInAdministratorsSID), StringComparison.OrdinalIgnoreCase)) &
                        Rights == AccessRights.GenericAll &
                        RegRule.InheritanceFlags == InheritanceFlags.ContainerInherit &
                        RegRule.PropagationFlags == PropagationFlags.InheritOnly)
                    {
                        FoundAdministratorGenericAccess = true;
                    }

                    // Allow BUILTIN\Administrators Query, SetKey, CreateSubKey, EnumSubkey, Notify, CreateLink, StandardDelete, StandardReadControl, StandardWriteDAC, StandardWriteOwner / NotInherited / None / None
                    if ((RegRule.IdentityReference.ToString().Equals(GetLocalAccountName(BuiltInAdministratorsSID), StringComparison.OrdinalIgnoreCase)) &
                        Rights == FullRights &
                        RegRule.InheritanceFlags == InheritanceFlags.None &
                        RegRule.PropagationFlags == PropagationFlags.None)
                    {
                        FoundAdministratorSpecificAccess = true;
                    }

                    // Allow BUILTIN\Users GenericRead / NotInherited / ContainerInherit / InheritOnly
                    if ((RegRule.IdentityReference.ToString().Equals(GetLocalAccountName(BuiltInUsersSID), StringComparison.OrdinalIgnoreCase)) &
                        Rights == AccessRights.GenericRead &
                        RegRule.InheritanceFlags == InheritanceFlags.ContainerInherit &
                        RegRule.PropagationFlags == PropagationFlags.InheritOnly)
                    {
                        FoundUserGenericAccess = true;
                    }

                    // Allow BUILTIN\Users Query, EnumSubkey, Notify, StandardReadControl / NotInherited / None / None
                    if ((RegRule.IdentityReference.ToString().Equals(GetLocalAccountName(BuiltInUsersSID), StringComparison.OrdinalIgnoreCase)) &
                        Rights == ReadRights &
                        RegRule.InheritanceFlags == InheritanceFlags.None &
                        RegRule.PropagationFlags == PropagationFlags.None)
                    {
                        FoundUserSpecificAccess = true;
                    }
                }
                LogMessage("CheckHKCRPermissions", " ");

                if (FoundCreatorOwnerGenericAccess)
                {
                    LogMessage("CheckHKCRPermissions", "OK - HKCR\\ does have CreatorOwnerGenericAccess");
                }
                else
                {
                    LogError("CheckHKCRPermissions", "HKCR\\ does not have CreatorOwnerGenericAccess!");
                }

                if (FoundSystemGenericAccess)
                {
                    LogMessage("CheckHKCRPermissions", "OK - HKCR\\ does have SystemGenericAccess");
                }
                else
                {
                    LogError("CheckHKCRPermissions", "HKCR\\ does not have SystemGenericAccess!");
                }
                if (FoundSystemSpecificAccess)
                {
                    LogMessage("CheckHKCRPermissions", "OK - HKCR\\ does have SystemSpecificAccess");
                }
                else
                {
                    LogError("CheckHKCRPermissions", "HKCR\\ does not have SystemSpecificAccess!");
                }

                if (FoundAdministratorGenericAccess)
                {
                    LogMessage("CheckHKCRPermissions", "OK - HKCR\\ does have AdministratorGenericAccess");
                }
                else
                {
                    LogError("CheckHKCRPermissions", "HKCR\\ does not have AdministratorGenericAccess!");
                }
                if (FoundAdministratorSpecificAccess)
                {
                    LogMessage("CheckHKCRPermissions", "OK - HKCR\\ does have AdministratorSpecificAccess");
                }
                else
                {
                    LogError("CheckHKCRPermissions", "HKCR\\ does not have AdministratorSpecificAccess!");
                }

                if (FoundUserGenericAccess)
                {
                    LogMessage("CheckHKCRPermissions", "OK - HKCR\\ does have UserGenericAccess");
                }
                else
                {
                    LogError("CheckHKCRPermissions", "HKCR\\ does not have UserGenericAccess!");
                }
                if (FoundUserSpecificAccess)
                {
                    LogMessage("CheckHKCRPermissions", "OK - HKCR\\ does have UserSpecificAccess");
                }
                else
                {
                    LogError("CheckHKCRPermissions", "HKCR\\ does not have UserSpecificAccess!");
                }

                LogMessage("CheckHKCRPermissions", " ");

                if (FixPermissions)
                {
                    Stopwatch swLocal = null;

                    try
                    {
                        swLocal = Stopwatch.StartNew();
                        LogMessage("SetRegistryACL", "Fixing registry permissions");

                        //Set a security ACL on the ASCOM Profile key giving the Users group Full Control of the key
                        LogMessage("SetRegistryACL", "Creating security identifiers");
                        SecurityIdentifier DomainSid = new SecurityIdentifier("S-1-0-0"); //Create a starting point domain SID

                        //Create security identifiers for the various accounts to be passed to the new access rule
                        SecurityIdentifier BuiltinUsersIdentifier   = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, DomainSid);
                        SecurityIdentifier AdministratorsIdentifier = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, DomainSid);
                        SecurityIdentifier CreatorOwnerIdentifier   = new SecurityIdentifier(WellKnownSidType.CreatorOwnerSid, DomainSid);
                        SecurityIdentifier SystemIdentifier         = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, DomainSid);

                        LogMessage("SetRegistryACL", "Creating new ACL rules"); // Create the new access permission rules
                        RegistryAccessRule CreatorOwnerGenericAccessRule = new RegistryAccessRule(CreatorOwnerIdentifier,
                                                                                                  (RegistryRights)AccessRights.GenericAll,
                                                                                                  InheritanceFlags.ContainerInherit,
                                                                                                  PropagationFlags.InheritOnly,
                                                                                                  AccessControlType.Allow);

                        RegistryAccessRule SystemGenericAccessRule = new RegistryAccessRule(SystemIdentifier,
                                                                                            (RegistryRights)AccessRights.GenericAll,
                                                                                            InheritanceFlags.ContainerInherit,
                                                                                            PropagationFlags.InheritOnly,
                                                                                            AccessControlType.Allow);

                        RegistryAccessRule SystemFullAccessRule = new RegistryAccessRule(SystemIdentifier,
                                                                                         (RegistryRights)FullRights,
                                                                                         InheritanceFlags.None,
                                                                                         PropagationFlags.None,
                                                                                         AccessControlType.Allow);

                        RegistryAccessRule AdministratorsGenericAccessRule = new RegistryAccessRule(AdministratorsIdentifier,
                                                                                                    (RegistryRights)AccessRights.GenericAll,
                                                                                                    InheritanceFlags.ContainerInherit,
                                                                                                    PropagationFlags.InheritOnly,
                                                                                                    AccessControlType.Allow);

                        RegistryAccessRule AdministratorsFullAccessRule = new RegistryAccessRule(AdministratorsIdentifier,
                                                                                                 (RegistryRights)FullRights,
                                                                                                 InheritanceFlags.None,
                                                                                                 PropagationFlags.None,
                                                                                                 AccessControlType.Allow);

                        RegistryAccessRule BuiltinUsersGenericAccessRule = new RegistryAccessRule(BuiltinUsersIdentifier,
                                                                                                  unchecked ((RegistryRights)AccessRights.GenericRead),
                                                                                                  InheritanceFlags.ContainerInherit,
                                                                                                  PropagationFlags.InheritOnly,
                                                                                                  AccessControlType.Allow);

                        RegistryAccessRule BuiltinUsersReadAccessRule = new RegistryAccessRule(BuiltinUsersIdentifier,
                                                                                               (RegistryRights)ReadRights,
                                                                                               InheritanceFlags.None,
                                                                                               PropagationFlags.None,
                                                                                               AccessControlType.Allow);

                        LogMessage("SetRegistryACL", "Retrieving current ACL rule");
                        LogMessage("SetRegistryACL", " ");
                        RegistrySecurity KeySec = Registry.ClassesRoot.GetAccessControl(); // Get existing ACL rules on the key

                        //Iterate over the rule set and list them
                        foreach (RegistryAccessRule RegRule in KeySec.GetAccessRules(true, true, typeof(NTAccount)))
                        {
                            LogMessage("SetRegistryACL Before", RegRule.AccessControlType.ToString() + " " +
                                       RegRule.IdentityReference.ToString() + " " +
                                       ((AccessRights)RegRule.RegistryRights).ToString() + " " +
                                       RegRule.IsInherited.ToString() + " " +
                                       RegRule.InheritanceFlags.ToString() + " " +
                                       RegRule.PropagationFlags.ToString());
                        }

                        LogMessage("SetRegistryACL", "Adding new ACL rules");
                        LogMessage("SetRegistryACL", " ");

                        // Remove old rules
                        KeySec.PurgeAccessRules(CreatorOwnerIdentifier);
                        KeySec.PurgeAccessRules(AdministratorsIdentifier);
                        KeySec.PurgeAccessRules(BuiltinUsersIdentifier);
                        KeySec.PurgeAccessRules(SystemIdentifier);

                        //Add the new rules to the existing rules
                        KeySec.AddAccessRule(CreatorOwnerGenericAccessRule);
                        KeySec.AddAccessRule(SystemGenericAccessRule);
                        KeySec.AddAccessRule(SystemFullAccessRule);
                        KeySec.AddAccessRule(AdministratorsGenericAccessRule);
                        KeySec.AddAccessRule(AdministratorsFullAccessRule);
                        KeySec.AddAccessRule(BuiltinUsersGenericAccessRule);
                        KeySec.AddAccessRule(BuiltinUsersReadAccessRule);

                        //Iterate over the new rule set and list them
                        foreach (RegistryAccessRule RegRule in KeySec.GetAccessRules(true, true, typeof(NTAccount)))
                        {
                            LogMessage("SetRegistryACL After", RegRule.AccessControlType.ToString() + " " +
                                       RegRule.IdentityReference.ToString() + " " +
                                       ((AccessRights)RegRule.RegistryRights).ToString() + " " +
                                       RegRule.IsInherited.ToString() + " " +
                                       RegRule.InheritanceFlags.ToString() + " " +
                                       RegRule.PropagationFlags.ToString());
                        }

                        LogMessage("SetRegistryACL", "Setting new ACL rule");
                        Registry.ClassesRoot.SetAccessControl(KeySec); //Apply the new rules to the Profile key

                        LogMessage("SetRegistryACL", "Retrieving new rule set from key");

                        // Retrieve the new rule set and list them
                        foreach (RegistryAccessRule RegRule in Registry.ClassesRoot.GetAccessControl().GetAccessRules(true, true, typeof(NTAccount)))
                        {
                            LogMessage("SetRegistryACL New", RegRule.AccessControlType.ToString() + " " +
                                       RegRule.IdentityReference.ToString() + " " +
                                       ((AccessRights)RegRule.RegistryRights).ToString() + " " +
                                       RegRule.IsInherited.ToString() + " " +
                                       RegRule.InheritanceFlags.ToString() + " " +
                                       RegRule.PropagationFlags.ToString());
                        }

                        swLocal.Stop();
                        LogMessage("SetRegistryACL", "ElapsedTime " + swLocal.ElapsedMilliseconds + " milliseconds");
                        swLocal = null;
                    }
                    catch (Exception ex)
                    {
                        LogMessage("SetRegistryACLException", ex.ToString());
                    }
                }
            }
            catch (NullReferenceException ex)
            {
                SetReturnCode(5);
                LogError("CheckHKCRPermissions", "HKCR\\ does not exist. " + ex.ToString()); // Should never happen!
            }
            catch (SecurityException ex)
            {
                SetReturnCode(5);
                LogError("CheckHKCRPermissions", "Security exception when accessing HKCR\\ " + ex.ToString()); // Should never happen!
            }
            catch (Exception ex)
            {
                SetReturnCode(5);
                LogError("CheckHKCRPermissions", "Unexpected exception: " + ex.ToString());
            }
        }