Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
TransactedRegistrySecurity.cs457 linesDownload Raw Back to namespaces
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4//5// NOTE: A vast majority of this code was copied from BCL in6// ndp\clr\src\BCL\System\Security\AccessControl\RegistrySecurity.cs.7// Namespace: System.Security.AccessControl8//9/*============================================================10**11**12**13** Purpose: Managed ACL wrapper for registry keys.14**15**16===========================================================*/17 18using System;19using System.Security.Permissions;20using System.Security.Principal;21using System.Runtime.InteropServices;22using System.IO;23using System.Security.AccessControl;24using System.Diagnostics.CodeAnalysis;25 26namespace Microsoft.PowerShell.Commands.Internal27{28    /// <summary>29    /// <para>Represents a set of access rights allowed or denied for a user or group. This class cannot be inherited.</para>30    /// </summary>31    // Suppressed because these are needed to manipulate TransactedRegistryKey, which is written to the pipeline.32    [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")]33    public sealed class TransactedRegistryAccessRule : AccessRule34    {35        // Constructor for creating access rules for registry objects36 37        /// <summary>38        /// <para>Initializes a new instance of the RegistryAccessRule class, specifying the user or group the rule applies to,39        /// the access rights, and whether the specified access rights are allowed or denied.</para>40        /// </summary>41        /// <param name="identity">The user or group the rule applies to. Must be of type SecurityIdentifier or a type such as42        /// NTAccount that can be converted to type SecurityIdentifier.</param>43        /// <param name="registryRights">A bitwise combination of Microsoft.Win32.RegistryRights values indicating the rights allowed or denied.</param>44        /// <param name="type">One of the AccessControlType values indicating whether the rights are allowed or denied.</param>45        internal TransactedRegistryAccessRule(IdentityReference identity, RegistryRights registryRights, AccessControlType type)46            : this(identity, (int)registryRights, false, InheritanceFlags.None, PropagationFlags.None, type)47        {48        }49 50        /// <summary>51        /// <para>Initializes a new instance of the RegistryAccessRule class, specifying the user or group the rule applies to,52        /// the access rights, and whether the specified access rights are allowed or denied.</para>53        /// </summary>54        /// <param name="identity">The name of the user or group the rule applies to.</param>55        /// <param name="registryRights">A bitwise combination of Microsoft.Win32.RegistryRights values indicating the rights allowed or denied.</param>56        /// <param name="type">One of the AccessControlType values indicating whether the rights are allowed or denied.</param>57        internal TransactedRegistryAccessRule(string identity, RegistryRights registryRights, AccessControlType type)58            : this(new NTAccount(identity), (int)registryRights, false, InheritanceFlags.None, PropagationFlags.None, type)59        {60        }61 62        /// <summary>63        /// <para>Initializes a new instance of the RegistryAccessRule class, specifying the user or group the rule applies to,64        /// the access rights, and whether the specified access rights are allowed or denied.</para>65        /// </summary>66        /// <param name="identity">The user or group the rule applies to. Must be of type SecurityIdentifier or a type such as67        /// NTAccount that can be converted to type SecurityIdentifier.</param>68        /// <param name="registryRights">A bitwise combination of Microsoft.Win32.RegistryRights values indicating the rights allowed or denied.</param>69        /// <param name="inheritanceFlags">A bitwise combination of InheritanceFlags flags specifying how access rights are inherited from other objects.</param>70        /// <param name="propagationFlags">A bitwise combination of PropagationFlags flags specifying how access rights are propagated to other objects.</param>71        /// <param name="type">One of the AccessControlType values indicating whether the rights are allowed or denied.</param>72        public TransactedRegistryAccessRule(IdentityReference identity, RegistryRights registryRights, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)73            : this(identity, (int)registryRights, false, inheritanceFlags, propagationFlags, type)74        {75        }76 77        /// <summary>78        /// <para>Initializes a new instance of the RegistryAccessRule class, specifying the user or group the rule applies to,79        /// the access rights, and whether the specified access rights are allowed or denied.</para>80        /// </summary>81        /// <param name="identity">The name of the user or group the rule applies to.</param>82        /// <param name="registryRights">A bitwise combination of Microsoft.Win32.RegistryRights values indicating the rights allowed or denied.</param>83        /// <param name="inheritanceFlags">A bitwise combination of InheritanceFlags flags specifying how access rights are inherited from other objects.</param>84        /// <param name="propagationFlags">A bitwise combination of PropagationFlags flags specifying how access rights are propagated to other objects.</param>85        /// <param name="type">One of the AccessControlType values indicating whether the rights are allowed or denied.</param>86        internal TransactedRegistryAccessRule(string identity, RegistryRights registryRights, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)87            : this(new NTAccount(identity), (int)registryRights, false, inheritanceFlags, propagationFlags, type)88        {89        }90 91        //92        // Internal constructor to be called by public constructors93        // and the access rule factory methods of {File|Folder}Security94        //95        internal TransactedRegistryAccessRule(96            IdentityReference identity,97            int accessMask,98            bool isInherited,99            InheritanceFlags inheritanceFlags,100            PropagationFlags propagationFlags,101            AccessControlType type)102            : base(103                identity,104                accessMask,105                isInherited,106                inheritanceFlags,107                propagationFlags,108                type)109        {110        }111 112        /// <summary>113        /// <para>Gets the rights allowed or denied by the access rule.</para>114        /// </summary>115        public RegistryRights RegistryRights116        {117            get { return (RegistryRights)base.AccessMask; }118        }119    }120 121    /// <summary>122    /// <para>Represents a set of access rights to be audited for a user or group. This class cannot be inherited.</para>123    /// </summary>124    // Suppressed because these are needed to manipulate TransactedRegistryKey, which is written to the pipeline.125    [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")]126    public sealed class TransactedRegistryAuditRule : AuditRule127    {128        /// <summary>129        /// <para>Initializes a new instance of the RegistryAuditRule class, specifying the user or group to audit, the rights to130        /// audit, whether to take inheritance into account, and whether to audit success, failure, or both.</para>131        /// </summary>132        /// <param name="identity">The user or group the rule applies to. Must be of type SecurityIdentifier or a type such as133        /// NTAccount that can be converted to type SecurityIdentifier.</param>134        /// <param name="registryRights">A bitwise combination of RegistryRights values specifying the kinds of access to audit.</param>135        /// <param name="inheritanceFlags">A bitwise combination of InheritanceFlags values specifying whether the audit rule applies to subkeys of the current key.</param>136        /// <param name="propagationFlags">A bitwise combination of PropagationFlags values that affect the way an inherited audit rule is propagated to subkeys of the current key.</param>137        /// <param name="flags">A bitwise combination of AuditFlags values specifying whether to audit success, failure, or both.</param>138        internal TransactedRegistryAuditRule(IdentityReference identity, RegistryRights registryRights, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)139            : this(identity, (int)registryRights, false, inheritanceFlags, propagationFlags, flags)140        {141        }142 143        /// <summary>144        /// <para>Initializes a new instance of the RegistryAuditRule class, specifying the user or group to audit, the rights to145        /// audit, whether to take inheritance into account, and whether to audit success, failure, or both.</para>146        /// </summary>147        /// <param name="identity">The name of the user or group the rule applies to.</param>148        /// <param name="registryRights">A bitwise combination of RegistryRights values specifying the kinds of access to audit.</param>149        /// <param name="inheritanceFlags">A bitwise combination of InheritanceFlags values specifying whether the audit rule applies to subkeys of the current key.</param>150        /// <param name="propagationFlags">A bitwise combination of PropagationFlags values that affect the way an inherited audit rule is propagated to subkeys of the current key.</param>151        /// <param name="flags">A bitwise combination of AuditFlags values specifying whether to audit success, failure, or both.</param>152        internal TransactedRegistryAuditRule(string identity, RegistryRights registryRights, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)153            : this(new NTAccount(identity), (int)registryRights, false, inheritanceFlags, propagationFlags, flags)154        {155        }156 157        internal TransactedRegistryAuditRule(IdentityReference identity, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)158            : base(identity, accessMask, isInherited, inheritanceFlags, propagationFlags, flags)159        {160        }161 162        /// <summary>163        /// <para>Gets the access rights affected by the audit rule.</para>164        /// </summary>165        public RegistryRights RegistryRights166        {167            get { return (RegistryRights)base.AccessMask; }168        }169    }170 171    /// <summary>172    /// <para>Represents the Windows access control security for a registry key. This class cannot be inherited.173    /// This class is specifically to be used with TransactedRegistryKey.</para>174    /// </summary>175    // Suppressed because these are needed to manipulate TransactedRegistryKey, which is written to the pipeline.176    [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")]177    public sealed class TransactedRegistrySecurity : NativeObjectSecurity178    {179        private const string resBaseName = "RegistryProviderStrings";180 181        /// <summary>182        /// <para>Initializes a new instance of the TransactedRegistrySecurity class with default values.</para>183        /// </summary>184        public TransactedRegistrySecurity()185            : base(true, ResourceType.RegistryKey)186        {187        }188 189        /*190        // The name of registry key must start with a predefined string,191        // like CLASSES_ROOT, CURRENT_USER, MACHINE, and USERS.  See192        // MSDN's help for SetNamedSecurityInfo for details.193        internal TransactedRegistrySecurity(string name, AccessControlSections includeSections)194            : base(true, ResourceType.RegistryKey, HKeyNameToWindowsName(name), includeSections)195        {196            new RegistryPermission(RegistryPermissionAccess.NoAccess, AccessControlActions.View, name).Demand();197        }198        */199 200        // Suppressed because the passed name and hkey won't change.201        [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity")]202        internal TransactedRegistrySecurity(SafeRegistryHandle hKey, string name, AccessControlSections includeSections)203            : base(true, ResourceType.RegistryKey, hKey, includeSections, _HandleErrorCode, null)204        {205            new RegistryPermission(RegistryPermissionAccess.NoAccess, AccessControlActions.View, name).Demand();206        }207 208        private static Exception _HandleErrorCode(int errorCode, string name, SafeHandle handle, object context)209        {210            System.Exception exception = null;211 212            switch (errorCode)213            {214                case Win32Native.ERROR_FILE_NOT_FOUND:215                    exception = new IOException(RegistryProviderStrings.Arg_RegKeyNotFound);216                    break;217 218                case Win32Native.ERROR_INVALID_NAME:219                    exception = new ArgumentException(RegistryProviderStrings.Arg_RegInvalidKeyName);220                    break;221 222                case Win32Native.ERROR_INVALID_HANDLE:223                    exception = new ArgumentException(RegistryProviderStrings.AccessControl_InvalidHandle);224                    break;225 226                default:227                    break;228            }229 230            return exception;231        }232 233        /// <summary>234        /// <para>Creates a new access control rule for the specified user, with the specified access rights, access control, and flags.</para>235        /// </summary>236        /// <returns>A TransactedRegistryAccessRule object representing the specified rights for the specified user.</returns>237        /// <param name="identityReference">An IdentityReference that identifies the user or group the rule applies to.</param>238        /// <param name="accessMask">A bitwise combination of RegistryRights values specifying the access rights to allow or deny, cast to an integer.</param>239        /// <param name="isInherited">A Boolean value specifying whether the rule is inherited.</param>240        /// <param name="inheritanceFlags">A bitwise combination of InheritanceFlags values specifying how the rule is inherited by subkeys.</param>241        /// <param name="propagationFlags">A bitwise combination of PropagationFlags values that modify the way the rule is inherited by subkeys. Meaningless if the value of inheritanceFlags is InheritanceFlags.None.</param>242        /// <param name="type">One of the AccessControlType values specifying whether the rights are allowed or denied.</param>243        public override AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)244        {245            return new TransactedRegistryAccessRule(identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, type);246        }247 248        /// <summary>249        /// <para>Creates a new audit rule, specifying the user the rule applies to, the access rights to audit, the inheritance and propagation of the250        /// rule, and the outcome that triggers the rule.</para>251        /// </summary>252        /// <returns>A TransactedRegistryAuditRule object representing the specified audit rule for the specified user, with the specified flags.253        /// The return type of the method is the base class, AuditRule, but the return value can be cast safely to the derived class.</returns>254        /// <param name="identityReference">An IdentityReference that identifies the user or group the rule applies to.</param>255        /// <param name="accessMask">A bitwise combination of RegistryRights values specifying the access rights to audit, cast to an integer.</param>256        /// <param name="isInherited">A Boolean value specifying whether the rule is inherited.</param>257        /// <param name="inheritanceFlags">A bitwise combination of InheritanceFlags values specifying how the rule is inherited by subkeys.</param>258        /// <param name="propagationFlags">A bitwise combination of PropagationFlags values that modify the way the rule is inherited by subkeys. Meaningless if the value of inheritanceFlags is InheritanceFlags.None.</param>259        /// <param name="flags">A bitwise combination of AuditFlags values specifying whether to audit successful access, failed access, or both.</param>260        public override AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)261        {262            return new TransactedRegistryAuditRule(identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, flags);263        }264 265        internal AccessControlSections GetAccessControlSectionsFromChanges()266        {267            AccessControlSections persistRules = AccessControlSections.None;268            if (AccessRulesModified)269                persistRules = AccessControlSections.Access;270            if (AuditRulesModified)271                persistRules |= AccessControlSections.Audit;272            if (OwnerModified)273                persistRules |= AccessControlSections.Owner;274            if (GroupModified)275                persistRules |= AccessControlSections.Group;276            return persistRules;277        }278 279        // Suppressed because the passed keyName won't change.280        [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity")]281        internal void Persist(SafeRegistryHandle hKey, string keyName)282        {283            new RegistryPermission(RegistryPermissionAccess.NoAccess, AccessControlActions.Change, keyName).Demand();284 285            WriteLock();286 287            try288            {289                AccessControlSections persistRules = GetAccessControlSectionsFromChanges();290                if (persistRules == AccessControlSections.None)291                    return;  // Don't need to persist anything.292 293                base.Persist(hKey, persistRules);294                OwnerModified = GroupModified = AuditRulesModified = AccessRulesModified = false;295            }296            finally297            {298                WriteUnlock();299            }300        }301 302        /// <summary>303        /// <para>Searches for a matching access control with which the new rule can be merged. If none are found, adds the new rule.</para>304        /// </summary>305        /// <param name="rule">The access control rule to add.</param>306        // Suppressed because we want to ensure TransactedRegistry* objects.307        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]308        public void AddAccessRule(TransactedRegistryAccessRule rule)309        {310            base.AddAccessRule(rule);311        }312 313        /// <summary>314        /// <para>Removes all access control rules with the same user and AccessControlType (allow or deny) as the specified rule, and then adds the specified rule.</para>315        /// </summary>316        /// <param name="rule">The TransactedRegistryAccessRule to add. The user and AccessControlType of this rule determine the rules to remove before this rule is added.</param>317        // Suppressed because we want to ensure TransactedRegistry* objects.318        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]319        public void SetAccessRule(TransactedRegistryAccessRule rule)320        {321            base.SetAccessRule(rule);322        }323 324        /// <summary>325        /// <para>Removes all access control rules with the same user as the specified rule, regardless of AccessControlType, and then adds the specified rule.</para>326        /// </summary>327        /// <param name="rule">The TransactedRegistryAccessRule to add. The user specified by this rule determines the rules to remove before this rule is added.</param>328        // Suppressed because we want to ensure TransactedRegistry* objects.329        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]330        public void ResetAccessRule(TransactedRegistryAccessRule rule)331        {332            base.ResetAccessRule(rule);333        }334 335        /// <summary>336        /// <para>Searches for an access control rule with the same user and AccessControlType (allow or deny) as the specified access rule, and with compatible337        /// inheritance and propagation flags; if such a rule is found, the rights contained in the specified access rule are removed from it.</para>338        /// </summary>339        /// <param name="rule">A TransactedRegistryAccessRule that specifies the user and AccessControlType to search for, and a set of inheritance340        /// and propagation flags that a matching rule, if found, must be compatible with. Specifies the rights to remove from the compatible rule, if found.</param>341        // Suppressed because we want to ensure TransactedRegistry* objects.342        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]343        public bool RemoveAccessRule(TransactedRegistryAccessRule rule)344        {345            return base.RemoveAccessRule(rule);346        }347 348        /// <summary>349        /// <para>Searches for all access control rules with the same user and AccessControlType (allow or deny) as the specified rule and, if found, removes them.</para>350        /// </summary>351        /// <param name="rule">A TransactedRegistryAccessRule that specifies the user and AccessControlType to search for. Any rights, inheritance flags, or352        /// propagation flags specified by this rule are ignored.</param>353        // Suppressed because we want to ensure TransactedRegistry* objects.354        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]355        public void RemoveAccessRuleAll(TransactedRegistryAccessRule rule)356        {357            base.RemoveAccessRuleAll(rule);358        }359 360        /// <summary>361        /// <para>Searches for an access control rule that exactly matches the specified rule and, if found, removes it.</para>362        /// </summary>363        /// <param name="rule">The TransactedRegistryAccessRule to remove.</param>364        // Suppressed because we want to ensure TransactedRegistry* objects.365        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]366        public void RemoveAccessRuleSpecific(TransactedRegistryAccessRule rule)367        {368            base.RemoveAccessRuleSpecific(rule);369        }370 371        /// <summary>372        /// <para>Searches for an audit rule with which the new rule can be merged. If none are found, adds the new rule.</para>373        /// </summary>374        /// <param name="rule">The audit rule to add. The user specified by this rule determines the search.</param>375        // Suppressed because we want to ensure TransactedRegistry* objects.376        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]377        public void AddAuditRule(TransactedRegistryAuditRule rule)378        {379            base.AddAuditRule(rule);380        }381 382        /// <summary>383        /// <para>Removes all audit rules with the same user as the specified rule, regardless of the AuditFlags value, and then adds the specified rule.</para>384        /// </summary>385        /// <param name="rule">The TransactedRegistryAuditRule to add. The user specified by this rule determines the rules to remove before this rule is added.</param>386        // Suppressed because we want to ensure TransactedRegistry* objects.387        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]388        public void SetAuditRule(TransactedRegistryAuditRule rule)389        {390            base.SetAuditRule(rule);391        }392 393        /// <summary>394        /// <para>Searches for an audit control rule with the same user as the specified rule, and with compatible inheritance and propagation flags;395        /// if a compatible rule is found, the rights contained in the specified rule are removed from it.</para>396        /// </summary>397        /// <param name="rule">A TransactedRegistryAuditRule that specifies the user to search for, and a set of inheritance and propagation flags that398        /// a matching rule, if found, must be compatible with. Specifies the rights to remove from the compatible rule, if found.</param>399        // Suppressed because we want to ensure TransactedRegistry* objects.400        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]401        public bool RemoveAuditRule(TransactedRegistryAuditRule rule)402        {403            return base.RemoveAuditRule(rule);404        }405 406        /// <summary>407        /// <para>Searches for all audit rules with the same user as the specified rule and, if found, removes them.</para>408        /// </summary>409        /// <param name="rule">A TransactedRegistryAuditRule that specifies the user to search for. Any rights, inheritance410        /// flags, or propagation flags specified by this rule are ignored.</param>411        // Suppressed because we want to ensure TransactedRegistry* objects.412        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]413        public void RemoveAuditRuleAll(TransactedRegistryAuditRule rule)414        {415            base.RemoveAuditRuleAll(rule);416        }417 418        /// <summary>419        /// <para>Searches for an audit rule that exactly matches the specified rule and, if found, removes it.</para>420        /// </summary>421        /// <param name="rule">The TransactedRegistryAuditRule to be removed.</param>422        // Suppressed because we want to ensure TransactedRegistry* objects.423        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]424        public void RemoveAuditRuleSpecific(TransactedRegistryAuditRule rule)425        {426            base.RemoveAuditRuleSpecific(rule);427        }428 429        /// <summary>430        /// <para>Gets the enumeration type that the TransactedRegistrySecurity class uses to represent access rights.</para>431        /// </summary>432        /// <returns>A Type object representing the RegistryRights enumeration.</returns>433        public override Type AccessRightType434        {435            get { return typeof(RegistryRights); }436        }437 438        /// <summary>439        /// <para>Gets the type that the TransactedRegistrySecurity class uses to represent access rules.</para>440        /// </summary>441        /// <returns>A Type object representing the TransactedRegistryAccessRule class.</returns>442        public override Type AccessRuleType443        {444            get { return typeof(TransactedRegistryAccessRule); }445        }446 447        /// <summary>448        /// <para>Gets the type that the TransactedRegistrySecurity class uses to represent audit rules.</para>449        /// </summary>450        /// <returns>A Type object representing the TransactedRegistryAuditRule class.</returns>451        public override Type AuditRuleType452        {453            get { return typeof(TransactedRegistryAuditRule); }454        }455    }456}457