1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
6 //
7 // Managed ACL wrapper for directories
8 
9 
10 using Microsoft.Win32.SafeHandles;
11 using Microsoft.Win32;
12 using System.Collections;
13 using System.Diagnostics;
14 using System.IO;
15 using System.Reflection;
16 using System.Runtime.InteropServices;
17 using System.Runtime.Versioning;
18 using System.Security.AccessControl;
19 using System.Security.Principal;
20 using System;
21 
22 namespace System.Security.AccessControl
23 {
24     public abstract class DirectoryObjectSecurity : ObjectSecurity
25     {
26         #region Private Members
27 
28         internal CommonSecurityDescriptor _securityDescriptor;
29 
30         #endregion
31 
32         #region Constructors
33 
DirectoryObjectSecurity()34         protected DirectoryObjectSecurity()
35             : base(true, true)
36         {
37             return;
38         }
39 
DirectoryObjectSecurity(CommonSecurityDescriptor securityDescriptor)40         protected DirectoryObjectSecurity(CommonSecurityDescriptor securityDescriptor)
41             : base(securityDescriptor)
42         {
43             if (securityDescriptor == null)
44             {
45                 throw new ArgumentNullException(nameof(securityDescriptor));
46             }
47 
48             _securityDescriptor = securityDescriptor;
49         }
50 
51         #endregion
52 
53         #region Private Methods
54 
55         // Ported from NDP\clr\src\BCL\System\Security\Principal\SID.cs since we can't access System.Security.Principal.IdentityReference's internals
IsValidTargetTypeStatic(Type targetType)56         private static bool IsValidTargetTypeStatic(Type targetType)
57         {
58             if (targetType == typeof(NTAccount))
59             {
60                 return true;
61             }
62             else if (targetType == typeof(SecurityIdentifier))
63             {
64                 return true;
65             }
66             else
67             {
68                 return false;
69             }
70         }
71 
GetRules(bool access, bool includeExplicit, bool includeInherited, System.Type targetType)72         private AuthorizationRuleCollection GetRules(bool access, bool includeExplicit, bool includeInherited, System.Type targetType)
73         {
74             ReadLock();
75 
76             try
77             {
78                 AuthorizationRuleCollection result = new AuthorizationRuleCollection();
79 
80                 if (!IsValidTargetTypeStatic(targetType))
81                 {
82                     throw new ArgumentException(SR.Arg_MustBeIdentityReferenceType, nameof(targetType));
83                 }
84 
85                 CommonAcl acl = null;
86 
87                 if (access)
88                 {
89                     if ((_securityDescriptor.ControlFlags & ControlFlags.DiscretionaryAclPresent) != 0)
90                     {
91                         acl = _securityDescriptor.DiscretionaryAcl;
92                     }
93                 }
94                 else // !access == audit
95                 {
96                     if ((_securityDescriptor.ControlFlags & ControlFlags.SystemAclPresent) != 0)
97                     {
98                         acl = _securityDescriptor.SystemAcl;
99                     }
100                 }
101 
102                 if (acl == null)
103                 {
104                     //
105                     // The required ACL was not present; return an empty collection.
106                     //
107                     return result;
108                 }
109 
110                 IdentityReferenceCollection irTarget = null;
111 
112                 if (targetType != typeof(SecurityIdentifier))
113                 {
114                     IdentityReferenceCollection irSource = new IdentityReferenceCollection(acl.Count);
115 
116                     for (int i = 0; i < acl.Count; i++)
117                     {
118                         //
119                         // Calling the indexer on a common ACL results in cloning,
120                         // (which would not be the case if we were to use the internal RawAcl property)
121                         // but also ensures that the resulting order of ACEs is proper
122                         // However, this is a big price to pay - cloning all the ACEs just so that
123                         // the canonical order could be ascertained just once.
124                         // A better way would be to have an internal method that would canonicalize the ACL
125                         // and call it once, then use the RawAcl.
126                         //
127                         QualifiedAce ace = acl[i] as QualifiedAce;
128 
129                         if (ace == null)
130                         {
131                             //
132                             // Only consider qualified ACEs
133                             //
134                             continue;
135                         }
136 
137                         if (ace.IsCallback == true)
138                         {
139                             //
140                             // Ignore callback ACEs
141                             //
142                             continue;
143                         }
144 
145                         if (access)
146                         {
147                             if (ace.AceQualifier != AceQualifier.AccessAllowed && ace.AceQualifier != AceQualifier.AccessDenied)
148                             {
149                                 continue;
150                             }
151                         }
152                         else
153                         {
154                             if (ace.AceQualifier != AceQualifier.SystemAudit)
155                             {
156                                 continue;
157                             }
158                         }
159 
160                         irSource.Add(ace.SecurityIdentifier);
161                     }
162 
163                     irTarget = irSource.Translate(targetType);
164                 }
165 
166                 for (int i = 0; i < acl.Count; i++)
167                 {
168                     //
169                     // Calling the indexer on a common ACL results in cloning,
170                     // (which would not be the case if we were to use the internal RawAcl property)
171                     // but also ensures that the resulting order of ACEs is proper
172                     // However, this is a big price to pay - cloning all the ACEs just so that
173                     // the canonical order could be ascertained just once.
174                     // A better way would be to have an internal method that would canonicalize the ACL
175                     // and call it once, then use the RawAcl.
176                     //
177                     QualifiedAce ace = acl[i] as CommonAce;
178 
179                     if (ace == null)
180                     {
181                         ace = acl[i] as ObjectAce;
182                         if (ace == null)
183                         {
184                             //
185                             // Only consider common or object ACEs
186                             //
187                             continue;
188                         }
189                     }
190 
191                     if (ace.IsCallback == true)
192                     {
193                         //
194                         // Ignore callback ACEs
195                         //
196                         continue;
197                     }
198 
199                     if (access)
200                     {
201                         if (ace.AceQualifier != AceQualifier.AccessAllowed && ace.AceQualifier != AceQualifier.AccessDenied)
202                         {
203                             continue;
204                         }
205                     }
206                     else
207                     {
208                         if (ace.AceQualifier != AceQualifier.SystemAudit)
209                         {
210                             continue;
211                         }
212                     }
213 
214                     if ((includeExplicit && ((ace.AceFlags & AceFlags.Inherited) == 0)) || (includeInherited && ((ace.AceFlags & AceFlags.Inherited) != 0)))
215                     {
216                         IdentityReference iref = (targetType == typeof(SecurityIdentifier)) ? ace.SecurityIdentifier : irTarget[i];
217 
218                         if (access)
219                         {
220                             AccessControlType type;
221 
222                             if (ace.AceQualifier == AceQualifier.AccessAllowed)
223                             {
224                                 type = AccessControlType.Allow;
225                             }
226                             else
227                             {
228                                 type = AccessControlType.Deny;
229                             }
230 
231                             if (ace is ObjectAce)
232                             {
233                                 ObjectAce objectAce = ace as ObjectAce;
234 
235                                 result.AddRule(AccessRuleFactory(iref, objectAce.AccessMask, objectAce.IsInherited, objectAce.InheritanceFlags, objectAce.PropagationFlags, type, objectAce.ObjectAceType, objectAce.InheritedObjectAceType));
236                             }
237                             else
238                             {
239                                 CommonAce commonAce = ace as CommonAce;
240 
241                                 if (commonAce == null)
242                                 {
243                                     continue;
244                                 }
245 
246                                 result.AddRule(AccessRuleFactory(iref, commonAce.AccessMask, commonAce.IsInherited, commonAce.InheritanceFlags, commonAce.PropagationFlags, type));
247                             }
248                         }
249                         else
250                         {
251                             if (ace is ObjectAce)
252                             {
253                                 ObjectAce objectAce = ace as ObjectAce;
254 
255                                 result.AddRule(AuditRuleFactory(iref, objectAce.AccessMask, objectAce.IsInherited, objectAce.InheritanceFlags, objectAce.PropagationFlags, objectAce.AuditFlags, objectAce.ObjectAceType, objectAce.InheritedObjectAceType));
256                             }
257                             else
258                             {
259                                 CommonAce commonAce = ace as CommonAce;
260 
261                                 if (commonAce == null)
262                                 {
263                                     continue;
264                                 }
265 
266                                 result.AddRule(AuditRuleFactory(iref, commonAce.AccessMask, commonAce.IsInherited, commonAce.InheritanceFlags, commonAce.PropagationFlags, commonAce.AuditFlags));
267                             }
268                         }
269                     }
270                 }
271 
272                 return result;
273             }
274             finally
275             {
276                 ReadUnlock();
277             }
278         }
279 
280         //
281         // Modifies the DACL
282         //
ModifyAccess(AccessControlModification modification, ObjectAccessRule rule, out bool modified)283         private bool ModifyAccess(AccessControlModification modification, ObjectAccessRule rule, out bool modified)
284         {
285             bool result = true;
286 
287             if (_securityDescriptor.DiscretionaryAcl == null)
288             {
289                 if (modification == AccessControlModification.Remove || modification == AccessControlModification.RemoveAll || modification == AccessControlModification.RemoveSpecific)
290                 {
291                     modified = false;
292                     return result;
293                 }
294 
295                 //_securityDescriptor.DiscretionaryAcl = new DiscretionaryAcl(IsContainer, IsDS, GenericAcl.AclRevisionDS, 1);
296                 //_securityDescriptor.AddControlFlags(ControlFlags.DiscretionaryAclPresent);
297                 _securityDescriptor.AddDiscretionaryAcl(GenericAcl.AclRevisionDS, 1);
298             }
299             else if ((modification == AccessControlModification.Add || modification == AccessControlModification.Set || modification == AccessControlModification.Reset) &&
300                         (rule.ObjectFlags != ObjectAceFlags.None))
301             {
302                 //
303                 // This will result in an object ace being added to the dacl, so the dacl revision must be AclRevisionDS
304                 //
305                 if (_securityDescriptor.DiscretionaryAcl.Revision < GenericAcl.AclRevisionDS)
306                 {
307                     //
308                     // we need to create a new dacl with the same aces as the existing one but the revision should be AclRevisionDS
309                     //
310                     byte[] binaryForm = new byte[_securityDescriptor.DiscretionaryAcl.BinaryLength];
311                     _securityDescriptor.DiscretionaryAcl.GetBinaryForm(binaryForm, 0);
312                     binaryForm[0] = GenericAcl.AclRevisionDS; // revision is the first byte of the binary form
313 
314                     _securityDescriptor.DiscretionaryAcl = new DiscretionaryAcl(IsContainer, IsDS, new RawAcl(binaryForm, 0));
315                 }
316             }
317 
318             SecurityIdentifier sid = rule.IdentityReference.Translate(typeof(SecurityIdentifier)) as SecurityIdentifier;
319 
320             if (rule.AccessControlType == AccessControlType.Allow)
321             {
322                 switch (modification)
323                 {
324                     case AccessControlModification.Add:
325                         //_securityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
326                         _securityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Allow, sid, rule);
327                         break;
328 
329                     case AccessControlModification.Set:
330                         //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
331                         _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule);
332                         break;
333 
334                     case AccessControlModification.Reset:
335                         _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty);
336                         //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
337                         _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule);
338                         break;
339 
340                     case AccessControlModification.Remove:
341                         //result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
342                         result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, rule);
343                         break;
344 
345                     case AccessControlModification.RemoveAll:
346                         result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty);
347                         if (result == false)
348                         {
349                             throw new InvalidOperationException(SR.InvalidOperation_RemoveFail);
350                         }
351 
352                         break;
353 
354                     case AccessControlModification.RemoveSpecific:
355                         //_securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
356                         _securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Allow, sid, rule);
357                         break;
358 
359                     default:
360                         throw new ArgumentOutOfRangeException(
361 nameof(modification),
362                             SR.ArgumentOutOfRange_Enum);
363                 }
364             }
365             else if (rule.AccessControlType == AccessControlType.Deny)
366             {
367                 switch (modification)
368                 {
369                     case AccessControlModification.Add:
370                         //_securityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
371                         _securityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Deny, sid, rule);
372                         break;
373 
374                     case AccessControlModification.Set:
375                         //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
376                         _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule);
377                         break;
378 
379                     case AccessControlModification.Reset:
380                         _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty);
381                         //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
382                         _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule);
383                         break;
384 
385                     case AccessControlModification.Remove:
386                         //result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
387                         result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, rule);
388                         break;
389 
390                     case AccessControlModification.RemoveAll:
391                         result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty);
392                         if (result == false)
393                         {
394                             throw new InvalidOperationException(SR.InvalidOperation_RemoveFail);
395                         }
396 
397                         break;
398 
399                     case AccessControlModification.RemoveSpecific:
400                         //_securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
401                         _securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Deny, sid, rule);
402                         break;
403 
404                     default:
405                         throw new ArgumentOutOfRangeException(
406 nameof(modification),
407                             SR.ArgumentOutOfRange_Enum);
408                 }
409             }
410             else
411             {
412                 throw new ArgumentException(SR.Format(SR.TypeUnrecognized_AccessControl, rule.AccessControlType));
413             }
414 
415             modified = result;
416             AccessRulesModified |= modified;
417             return result;
418         }
419 
420         //
421         // Modifies the SACL
422         //
ModifyAudit(AccessControlModification modification, ObjectAuditRule rule, out bool modified)423         private bool ModifyAudit(AccessControlModification modification, ObjectAuditRule rule, out bool modified)
424         {
425             bool result = true;
426 
427             if (_securityDescriptor.SystemAcl == null)
428             {
429                 if (modification == AccessControlModification.Remove || modification == AccessControlModification.RemoveAll || modification == AccessControlModification.RemoveSpecific)
430                 {
431                     modified = false;
432                     return result;
433                 }
434 
435                 //_securityDescriptor.SystemAcl = new SystemAcl(IsContainer, IsDS, GenericAcl.AclRevisionDS, 1);
436                 //_securityDescriptor.AddControlFlags(ControlFlags.SystemAclPresent);
437                 _securityDescriptor.AddSystemAcl(GenericAcl.AclRevisionDS, 1);
438             }
439             else if ((modification == AccessControlModification.Add || modification == AccessControlModification.Set || modification == AccessControlModification.Reset) &&
440                         (rule.ObjectFlags != ObjectAceFlags.None))
441             {
442                 //
443                 // This will result in an object ace being added to the sacl, so the sacl revision must be AclRevisionDS
444                 //
445                 if (_securityDescriptor.SystemAcl.Revision < GenericAcl.AclRevisionDS)
446                 {
447                     //
448                     // we need to create a new sacl with the same aces as the existing one but the revision should be AclRevisionDS
449                     //
450                     byte[] binaryForm = new byte[_securityDescriptor.SystemAcl.BinaryLength];
451                     _securityDescriptor.SystemAcl.GetBinaryForm(binaryForm, 0);
452                     binaryForm[0] = GenericAcl.AclRevisionDS; // revision is the first byte of the binary form
453 
454                     _securityDescriptor.SystemAcl = new SystemAcl(IsContainer, IsDS, new RawAcl(binaryForm, 0));
455                 }
456             }
457 
458             SecurityIdentifier sid = rule.IdentityReference.Translate(typeof(SecurityIdentifier)) as SecurityIdentifier;
459 
460             switch (modification)
461             {
462                 case AccessControlModification.Add:
463                     //_securityDescriptor.SystemAcl.AddAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
464                     _securityDescriptor.SystemAcl.AddAudit(sid, rule);
465                     break;
466 
467                 case AccessControlModification.Set:
468                     //_securityDescriptor.SystemAcl.SetAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
469                     _securityDescriptor.SystemAcl.SetAudit(sid, rule);
470                     break;
471 
472                 case AccessControlModification.Reset:
473                     _securityDescriptor.SystemAcl.RemoveAudit(AuditFlags.Failure | AuditFlags.Success, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty);
474                     //_securityDescriptor.SystemAcl.SetAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
475                     _securityDescriptor.SystemAcl.SetAudit(sid, rule);
476                     break;
477 
478                 case AccessControlModification.Remove:
479                     //result = _securityDescriptor.SystemAcl.RemoveAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
480                     result = _securityDescriptor.SystemAcl.RemoveAudit(sid, rule);
481                     break;
482 
483                 case AccessControlModification.RemoveAll:
484                     result = _securityDescriptor.SystemAcl.RemoveAudit(AuditFlags.Failure | AuditFlags.Success, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty);
485                     if (result == false)
486                     {
487                         throw new InvalidOperationException(SR.InvalidOperation_RemoveFail);
488                     }
489 
490                     break;
491 
492                 case AccessControlModification.RemoveSpecific:
493                     //_securityDescriptor.SystemAcl.RemoveAuditSpecific(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType);
494                     _securityDescriptor.SystemAcl.RemoveAuditSpecific(sid, rule);
495                     break;
496 
497                 default:
498                     throw new ArgumentOutOfRangeException(
499 nameof(modification),
500                         SR.ArgumentOutOfRange_Enum);
501             }
502 
503             modified = result;
504             AuditRulesModified |= modified;
505             return result;
506         }
507 
508         #endregion
509 
510         #region public Methods
511 
AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type, Guid objectType, Guid inheritedObjectType)512         public virtual AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type, Guid objectType, Guid inheritedObjectType)
513         {
514             throw NotImplemented.ByDesign;
515         }
516 
AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags, Guid objectType, Guid inheritedObjectType)517         public virtual AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags, Guid objectType, Guid inheritedObjectType)
518         {
519             throw NotImplemented.ByDesign;
520         }
521 
ModifyAccess(AccessControlModification modification, AccessRule rule, out bool modified)522         protected override bool ModifyAccess(AccessControlModification modification, AccessRule rule, out bool modified)
523         {
524             ////if(this.AccessRuleType.IsAssignableFrom(rule.GetType().GetTypeInfo()))
525             ////if (!TypeExtensions.IsAssignableFrom(this.AccessRuleType, rule.GetType()))
526             //{
527             //    throw new ArgumentException(
528             //        SR.AccessControl_InvalidAccessRuleType,
529             //        "rule");
530             //}
531             return ModifyAccess(modification, rule as ObjectAccessRule, out modified);
532         }
533 
ModifyAudit(AccessControlModification modification, AuditRule rule, out bool modified)534         protected override bool ModifyAudit(AccessControlModification modification, AuditRule rule, out bool modified)
535         {
536             //if (this.AccessRuleType.IsAssignableFrom(rule.GetType().GetTypeInfo()))
537             ////if (!TypeExtensions.IsAssignableFrom(this.AuditRuleType, rule.GetType()))
538             //{
539             //    throw new ArgumentException(
540             //        SR.AccessControl_InvalidAuditRuleType,
541             //        "rule");
542             //}
543             return ModifyAudit(modification, rule as ObjectAuditRule, out modified);
544         }
545         #endregion
546 
547         #region Public Methods
548 
AddAccessRule(ObjectAccessRule rule)549         protected void AddAccessRule(ObjectAccessRule rule)
550         {
551             if (rule == null)
552             {
553                 throw new ArgumentNullException(nameof(rule));
554             }
555 
556             WriteLock();
557 
558             try
559             {
560                 bool modified;
561                 ModifyAccess(AccessControlModification.Add, rule, out modified);
562             }
563             finally
564             {
565                 WriteUnlock();
566             }
567 
568             return;
569         }
570 
SetAccessRule(ObjectAccessRule rule)571         protected void SetAccessRule(ObjectAccessRule rule)
572         {
573             if (rule == null)
574             {
575                 throw new ArgumentNullException(nameof(rule));
576             }
577 
578             WriteLock();
579 
580             try
581             {
582                 bool modified;
583                 ModifyAccess(AccessControlModification.Set, rule, out modified);
584             }
585             finally
586             {
587                 WriteUnlock();
588             }
589         }
590 
ResetAccessRule(ObjectAccessRule rule)591         protected void ResetAccessRule(ObjectAccessRule rule)
592         {
593             if (rule == null)
594             {
595                 throw new ArgumentNullException(nameof(rule));
596             }
597 
598             WriteLock();
599 
600             try
601             {
602                 bool modified;
603                 ModifyAccess(AccessControlModification.Reset, rule, out modified);
604             }
605             finally
606             {
607                 WriteUnlock();
608             }
609         }
610 
RemoveAccessRule(ObjectAccessRule rule)611         protected bool RemoveAccessRule(ObjectAccessRule rule)
612         {
613             if (rule == null)
614             {
615                 throw new ArgumentNullException(nameof(rule));
616             }
617 
618             WriteLock();
619 
620             try
621             {
622                 if (_securityDescriptor == null)
623                 {
624                     return true;
625                 }
626 
627                 bool modified;
628                 return ModifyAccess(AccessControlModification.Remove, rule, out modified);
629             }
630             finally
631             {
632                 WriteUnlock();
633             }
634         }
635 
RemoveAccessRuleAll(ObjectAccessRule rule)636         protected void RemoveAccessRuleAll(ObjectAccessRule rule)
637         {
638             if (rule == null)
639             {
640                 throw new ArgumentNullException(nameof(rule));
641             }
642 
643             WriteLock();
644 
645             try
646             {
647                 if (_securityDescriptor == null)
648                 {
649                     return;
650                 }
651 
652                 bool modified;
653                 ModifyAccess(AccessControlModification.RemoveAll, rule, out modified);
654             }
655             finally
656             {
657                 WriteUnlock();
658             }
659         }
660 
RemoveAccessRuleSpecific(ObjectAccessRule rule)661         protected void RemoveAccessRuleSpecific(ObjectAccessRule rule)
662         {
663             if (rule == null)
664             {
665                 throw new ArgumentNullException(nameof(rule));
666             }
667 
668             if (_securityDescriptor == null)
669             {
670                 return;
671             }
672 
673             WriteLock();
674 
675             try
676             {
677                 bool modified;
678                 ModifyAccess(AccessControlModification.RemoveSpecific, rule, out modified);
679             }
680             finally
681             {
682                 WriteUnlock();
683             }
684         }
685 
AddAuditRule(ObjectAuditRule rule)686         protected void AddAuditRule(ObjectAuditRule rule)
687         {
688             if (rule == null)
689             {
690                 throw new ArgumentNullException(nameof(rule));
691             }
692 
693             WriteLock();
694 
695             try
696             {
697                 bool modified;
698                 ModifyAudit(AccessControlModification.Add, rule, out modified);
699             }
700             finally
701             {
702                 WriteUnlock();
703             }
704         }
705 
SetAuditRule(ObjectAuditRule rule)706         protected void SetAuditRule(ObjectAuditRule rule)
707         {
708             if (rule == null)
709             {
710                 throw new ArgumentNullException(nameof(rule));
711             }
712 
713             WriteLock();
714 
715             try
716             {
717                 bool modified;
718                 ModifyAudit(AccessControlModification.Set, rule, out modified);
719             }
720             finally
721             {
722                 WriteUnlock();
723             }
724         }
725 
RemoveAuditRule(ObjectAuditRule rule)726         protected bool RemoveAuditRule(ObjectAuditRule rule)
727         {
728             if (rule == null)
729             {
730                 throw new ArgumentNullException(nameof(rule));
731             }
732 
733             WriteLock();
734 
735             try
736             {
737                 bool modified;
738                 return ModifyAudit(AccessControlModification.Remove, rule, out modified);
739             }
740             finally
741             {
742                 WriteUnlock();
743             }
744         }
745 
RemoveAuditRuleAll(ObjectAuditRule rule)746         protected void RemoveAuditRuleAll(ObjectAuditRule rule)
747         {
748             if (rule == null)
749             {
750                 throw new ArgumentNullException(nameof(rule));
751             }
752 
753             WriteLock();
754 
755             try
756             {
757                 bool modified;
758                 ModifyAudit(AccessControlModification.RemoveAll, rule, out modified);
759             }
760             finally
761             {
762                 WriteUnlock();
763             }
764         }
765 
RemoveAuditRuleSpecific(ObjectAuditRule rule)766         protected void RemoveAuditRuleSpecific(ObjectAuditRule rule)
767         {
768             if (rule == null)
769             {
770                 throw new ArgumentNullException(nameof(rule));
771             }
772 
773             WriteLock();
774 
775             try
776             {
777                 bool modified;
778                 ModifyAudit(AccessControlModification.RemoveSpecific, rule, out modified);
779             }
780             finally
781             {
782                 WriteUnlock();
783             }
784         }
785 
GetAccessRules(bool includeExplicit, bool includeInherited, System.Type targetType)786         public AuthorizationRuleCollection GetAccessRules(bool includeExplicit, bool includeInherited, System.Type targetType)
787         {
788             return GetRules(true, includeExplicit, includeInherited, targetType);
789         }
790 
GetAuditRules(bool includeExplicit, bool includeInherited, System.Type targetType)791         public AuthorizationRuleCollection GetAuditRules(bool includeExplicit, bool includeInherited, System.Type targetType)
792         {
793             return GetRules(false, includeExplicit, includeInherited, targetType);
794         }
795 
796         #endregion
797     }
798 }
799