mscorlib(4.0.0.0) API with additions
CommonAcl.cs
2 
4 {
6  public abstract class CommonAcl : GenericAcl
7  {
8  [Flags]
9  private enum AF
10  {
11  CI = 0x8,
12  OI = 0x4,
13  IO = 0x2,
14  NP = 0x1,
15  Invalid = 0x1
16  }
17 
18  [Flags]
19  private enum PM
20  {
21  F = 0x10,
22  CF = 0x8,
23  CO = 0x4,
24  GF = 0x2,
25  GO = 0x1,
26  Invalid = 0x1
27  }
28 
29  private enum ComparisonResult
30  {
31  LessThan,
32  EqualTo,
33  GreaterThan
34  }
35 
36  private static PM[] AFtoPM;
37 
38  private static AF[] PMtoAF;
39 
40  private RawAcl _acl;
41 
42  private bool _isDirty;
43 
44  private readonly bool _isCanonical;
45 
46  private readonly bool _isContainer;
47 
48  private readonly bool _isDS;
49 
50  internal RawAcl RawAcl => _acl;
51 
54  public sealed override byte Revision => _acl.Revision;
55 
58  public sealed override int Count
59  {
60  get
61  {
62  CanonicalizeIfNecessary();
63  return _acl.Count;
64  }
65  }
66 
69  public sealed override int BinaryLength
70  {
71  get
72  {
73  CanonicalizeIfNecessary();
74  return _acl.BinaryLength;
75  }
76  }
77 
81  public bool IsCanonical => _isCanonical;
82 
86  public bool IsContainer => _isContainer;
87 
91  public bool IsDS => _isDS;
92 
96  public sealed override GenericAce this[int index]
97  {
98  get
99  {
100  CanonicalizeIfNecessary();
101  return _acl[index].Copy();
102  }
103  set
104  {
105  throw new NotSupportedException(Environment.GetResourceString("NotSupported_SetMethod"));
106  }
107  }
108 
109  static CommonAcl()
110  {
111  AFtoPM = new PM[16];
112  for (int i = 0; i < AFtoPM.Length; i++)
113  {
114  AFtoPM[i] = PM.GO;
115  }
116  AFtoPM[0] = PM.F;
117  AFtoPM[4] = (PM.F | PM.CO | PM.GO);
118  AFtoPM[5] = (PM.F | PM.CO);
119  AFtoPM[6] = (PM.CO | PM.GO);
120  AFtoPM[7] = PM.CO;
121  AFtoPM[8] = (PM.F | PM.CF | PM.GF);
122  AFtoPM[9] = (PM.F | PM.CF);
123  AFtoPM[10] = (PM.CF | PM.GF);
124  AFtoPM[11] = PM.CF;
125  AFtoPM[12] = (PM.F | PM.CF | PM.CO | PM.GF | PM.GO);
126  AFtoPM[13] = (PM.F | PM.CF | PM.CO);
127  AFtoPM[14] = (PM.CF | PM.CO | PM.GF | PM.GO);
128  AFtoPM[15] = (PM.CF | PM.CO);
129  PMtoAF = new AF[32];
130  for (int j = 0; j < PMtoAF.Length; j++)
131  {
132  PMtoAF[j] = AF.NP;
133  }
134  PMtoAF[16] = (AF)0;
135  PMtoAF[21] = AF.OI;
136  PMtoAF[20] = (AF.OI | AF.NP);
137  PMtoAF[5] = (AF.OI | AF.IO);
138  PMtoAF[4] = (AF.OI | AF.IO | AF.NP);
139  PMtoAF[26] = AF.CI;
140  PMtoAF[24] = (AF.CI | AF.NP);
141  PMtoAF[10] = (AF.CI | AF.IO);
142  PMtoAF[8] = (AF.CI | AF.IO | AF.NP);
143  PMtoAF[31] = (AF.CI | AF.OI);
144  PMtoAF[28] = (AF.CI | AF.OI | AF.NP);
145  PMtoAF[15] = (AF.CI | AF.OI | AF.IO);
146  PMtoAF[12] = (AF.CI | AF.OI | AF.IO | AF.NP);
147  }
148 
149  private static AF AFFromAceFlags(AceFlags aceFlags, bool isDS)
150  {
151  AF aF = (AF)0;
152  if ((aceFlags & AceFlags.ContainerInherit) != 0)
153  {
154  aF |= AF.CI;
155  }
156  if (!isDS && (aceFlags & AceFlags.ObjectInherit) != 0)
157  {
158  aF |= AF.OI;
159  }
160  if ((aceFlags & AceFlags.InheritOnly) != 0)
161  {
162  aF |= AF.IO;
163  }
164  if ((aceFlags & AceFlags.NoPropagateInherit) != 0)
165  {
166  aF |= AF.NP;
167  }
168  return aF;
169  }
170 
171  private static AceFlags AceFlagsFromAF(AF af, bool isDS)
172  {
173  AceFlags aceFlags = AceFlags.None;
174  if ((af & AF.CI) != 0)
175  {
176  aceFlags |= AceFlags.ContainerInherit;
177  }
178  if (!isDS && (af & AF.OI) != 0)
179  {
180  aceFlags |= AceFlags.ObjectInherit;
181  }
182  if ((af & AF.IO) != 0)
183  {
184  aceFlags |= AceFlags.InheritOnly;
185  }
186  if ((af & AF.NP) != 0)
187  {
188  aceFlags |= AceFlags.NoPropagateInherit;
189  }
190  return aceFlags;
191  }
192 
193  private static bool MergeInheritanceBits(AceFlags left, AceFlags right, bool isDS, out AceFlags result)
194  {
195  result = AceFlags.None;
196  AF aF = AFFromAceFlags(left, isDS);
197  AF aF2 = AFFromAceFlags(right, isDS);
198  PM pM = AFtoPM[(int)aF];
199  PM pM2 = AFtoPM[(int)aF2];
200  if (pM == PM.GO || pM2 == PM.GO)
201  {
202  return false;
203  }
204  PM pM3 = pM | pM2;
205  AF aF3 = PMtoAF[(int)pM3];
206  if (aF3 == AF.NP)
207  {
208  return false;
209  }
210  result = AceFlagsFromAF(aF3, isDS);
211  return true;
212  }
213 
214  private static bool RemoveInheritanceBits(AceFlags existing, AceFlags remove, bool isDS, out AceFlags result, out bool total)
215  {
216  result = AceFlags.None;
217  total = false;
218  AF aF = AFFromAceFlags(existing, isDS);
219  AF aF2 = AFFromAceFlags(remove, isDS);
220  PM pM = AFtoPM[(int)aF];
221  PM pM2 = AFtoPM[(int)aF2];
222  if (pM == PM.GO || pM2 == PM.GO)
223  {
224  return false;
225  }
226  PM pM3 = pM & ~pM2;
227  if (pM3 == (PM)0)
228  {
229  total = true;
230  return true;
231  }
232  AF aF3 = PMtoAF[(int)pM3];
233  if (aF3 == AF.NP)
234  {
235  return false;
236  }
237  result = AceFlagsFromAF(aF3, isDS);
238  return true;
239  }
240 
241  private void CanonicalizeIfNecessary()
242  {
243  if (_isDirty)
244  {
245  Canonicalize(compact: false, this is DiscretionaryAcl);
246  _isDirty = false;
247  }
248  }
249 
250  private static int DaclAcePriority(GenericAce ace)
251  {
252  AceType aceType = ace.AceType;
253  if ((ace.AceFlags & AceFlags.Inherited) != 0)
254  {
255  return 131070 + ace._indexInAcl;
256  }
257  switch (aceType)
258  {
259  case AceType.AccessDenied:
260  case AceType.AccessDeniedCallback:
261  return 0;
262  case AceType.AccessDeniedObject:
263  case AceType.AccessDeniedCallbackObject:
264  return 1;
265  case AceType.AccessAllowed:
266  case AceType.AccessAllowedCallback:
267  return 2;
268  case AceType.AccessAllowedObject:
269  case AceType.AccessAllowedCallbackObject:
270  return 3;
271  default:
272  return 65535 + ace._indexInAcl;
273  }
274  }
275 
276  private static int SaclAcePriority(GenericAce ace)
277  {
278  AceType aceType = ace.AceType;
279  if ((ace.AceFlags & AceFlags.Inherited) != 0)
280  {
281  return 131070 + ace._indexInAcl;
282  }
283  switch (aceType)
284  {
285  case AceType.SystemAudit:
286  case AceType.SystemAlarm:
287  case AceType.SystemAuditCallback:
288  case AceType.SystemAlarmCallback:
289  return 0;
290  case AceType.SystemAuditObject:
291  case AceType.SystemAlarmObject:
292  case AceType.SystemAuditCallbackObject:
293  case AceType.SystemAlarmCallbackObject:
294  return 1;
295  default:
296  return 65535 + ace._indexInAcl;
297  }
298  }
299 
300  private static ComparisonResult CompareAces(GenericAce ace1, GenericAce ace2, bool isDacl)
301  {
302  int num = isDacl ? DaclAcePriority(ace1) : SaclAcePriority(ace1);
303  int num2 = isDacl ? DaclAcePriority(ace2) : SaclAcePriority(ace2);
304  if (num < num2)
305  {
306  return ComparisonResult.LessThan;
307  }
308  if (num > num2)
309  {
310  return ComparisonResult.GreaterThan;
311  }
312  KnownAce knownAce = ace1 as KnownAce;
313  KnownAce knownAce2 = ace2 as KnownAce;
314  if (knownAce != null && knownAce2 != null)
315  {
316  int num3 = knownAce.SecurityIdentifier.CompareTo(knownAce2.SecurityIdentifier);
317  if (num3 < 0)
318  {
319  return ComparisonResult.LessThan;
320  }
321  if (num3 > 0)
322  {
323  return ComparisonResult.GreaterThan;
324  }
325  }
326  return ComparisonResult.EqualTo;
327  }
328 
329  private void QuickSort(int left, int right, bool isDacl)
330  {
331  if (left >= right)
332  {
333  return;
334  }
335  int num = left;
336  int num2 = right;
337  GenericAce genericAce = _acl[left];
338  int num3 = left;
339  while (left < right)
340  {
341  while (CompareAces(_acl[right], genericAce, isDacl) != 0 && left < right)
342  {
343  right--;
344  }
345  if (left != right)
346  {
347  _acl[left] = _acl[right];
348  left++;
349  }
350  while (ComparisonResult.GreaterThan != CompareAces(_acl[left], genericAce, isDacl) && left < right)
351  {
352  left++;
353  }
354  if (left != right)
355  {
356  _acl[right] = _acl[left];
357  right--;
358  }
359  }
360  _acl[left] = genericAce;
361  num3 = left;
362  left = num;
363  right = num2;
364  if (left < num3)
365  {
366  QuickSort(left, num3 - 1, isDacl);
367  }
368  if (right > num3)
369  {
370  QuickSort(num3 + 1, right, isDacl);
371  }
372  }
373 
374  private bool InspectAce(ref GenericAce ace, bool isDacl)
375  {
376  KnownAce knownAce = ace as KnownAce;
377  if (knownAce != null && knownAce.AccessMask == 0)
378  {
379  return false;
380  }
381  if (!IsContainer)
382  {
383  if ((ace.AceFlags & AceFlags.InheritOnly) != 0)
384  {
385  return false;
386  }
387  if ((ace.AceFlags & AceFlags.InheritanceFlags) != 0)
388  {
389  ace.AceFlags &= ~(AceFlags.ObjectInherit | AceFlags.ContainerInherit | AceFlags.NoPropagateInherit | AceFlags.InheritOnly);
390  }
391  }
392  else
393  {
394  if ((ace.AceFlags & AceFlags.InheritOnly) != 0 && (ace.AceFlags & AceFlags.ContainerInherit) == AceFlags.None && (ace.AceFlags & AceFlags.ObjectInherit) == AceFlags.None)
395  {
396  return false;
397  }
398  if ((ace.AceFlags & AceFlags.NoPropagateInherit) != 0 && (ace.AceFlags & AceFlags.ContainerInherit) == AceFlags.None && (ace.AceFlags & AceFlags.ObjectInherit) == AceFlags.None)
399  {
400  ace.AceFlags &= ~AceFlags.NoPropagateInherit;
401  }
402  }
403  QualifiedAce qualifiedAce = knownAce as QualifiedAce;
404  if (isDacl)
405  {
406  ace.AceFlags &= ~(AceFlags.SuccessfulAccess | AceFlags.FailedAccess);
407  if (qualifiedAce != null && qualifiedAce.AceQualifier != 0 && qualifiedAce.AceQualifier != AceQualifier.AccessDenied)
408  {
409  return false;
410  }
411  }
412  else
413  {
414  if ((ace.AceFlags & AceFlags.AuditFlags) == AceFlags.None)
415  {
416  return false;
417  }
418  if (qualifiedAce != null && qualifiedAce.AceQualifier != AceQualifier.SystemAudit)
419  {
420  return false;
421  }
422  }
423  return true;
424  }
425 
426  private void RemoveMeaninglessAcesAndFlags(bool isDacl)
427  {
428  for (int num = _acl.Count - 1; num >= 0; num--)
429  {
430  GenericAce ace = _acl[num];
431  if (!InspectAce(ref ace, isDacl))
432  {
433  _acl.RemoveAce(num);
434  }
435  }
436  }
437 
438  private void Canonicalize(bool compact, bool isDacl)
439  {
440  for (ushort num = 0; num < _acl.Count; num = (ushort)(num + 1))
441  {
442  _acl[num]._indexInAcl = num;
443  }
444  QuickSort(0, _acl.Count - 1, isDacl);
445  if (!compact)
446  {
447  return;
448  }
449  for (int i = 0; i < Count - 1; i++)
450  {
451  QualifiedAce ace = _acl[i] as QualifiedAce;
452  if (!(ace == null))
453  {
454  QualifiedAce qualifiedAce = _acl[i + 1] as QualifiedAce;
455  if (!(qualifiedAce == null) && MergeAces(ref ace, qualifiedAce))
456  {
457  _acl.RemoveAce(i + 1);
458  }
459  }
460  }
461  }
462 
463  private void GetObjectTypesForSplit(ObjectAce originalAce, int accessMask, AceFlags aceFlags, out ObjectAceFlags objectFlags, out Guid objectType, out Guid inheritedObjectType)
464  {
465  objectFlags = ObjectAceFlags.None;
466  objectType = Guid.Empty;
467  inheritedObjectType = Guid.Empty;
468  if ((accessMask & ObjectAce.AccessMaskWithObjectType) != 0)
469  {
470  objectType = originalAce.ObjectAceType;
471  objectFlags |= (originalAce.ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent);
472  }
473  if ((aceFlags & AceFlags.ContainerInherit) != 0)
474  {
475  inheritedObjectType = originalAce.InheritedObjectAceType;
476  objectFlags |= (originalAce.ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent);
477  }
478  }
479 
480  private bool ObjectTypesMatch(QualifiedAce ace, QualifiedAce newAce)
481  {
482  Guid guid = (ace is ObjectAce) ? ((ObjectAce)ace).ObjectAceType : Guid.Empty;
483  Guid g = (newAce is ObjectAce) ? ((ObjectAce)newAce).ObjectAceType : Guid.Empty;
484  return guid.Equals(g);
485  }
486 
487  private bool InheritedObjectTypesMatch(QualifiedAce ace, QualifiedAce newAce)
488  {
489  Guid guid = (ace is ObjectAce) ? ((ObjectAce)ace).InheritedObjectAceType : Guid.Empty;
490  Guid g = (newAce is ObjectAce) ? ((ObjectAce)newAce).InheritedObjectAceType : Guid.Empty;
491  return guid.Equals(g);
492  }
493 
494  private bool AccessMasksAreMergeable(QualifiedAce ace, QualifiedAce newAce)
495  {
496  if (ObjectTypesMatch(ace, newAce))
497  {
498  return true;
499  }
500  ObjectAceFlags objectAceFlags = (ace is ObjectAce) ? ((ObjectAce)ace).ObjectAceFlags : ObjectAceFlags.None;
501  if ((ace.AccessMask & newAce.AccessMask & ObjectAce.AccessMaskWithObjectType) == (newAce.AccessMask & ObjectAce.AccessMaskWithObjectType) && (objectAceFlags & ObjectAceFlags.ObjectAceTypePresent) == ObjectAceFlags.None)
502  {
503  return true;
504  }
505  return false;
506  }
507 
508  private bool AceFlagsAreMergeable(QualifiedAce ace, QualifiedAce newAce)
509  {
510  if (InheritedObjectTypesMatch(ace, newAce))
511  {
512  return true;
513  }
514  ObjectAceFlags objectAceFlags = (ace is ObjectAce) ? ((ObjectAce)ace).ObjectAceFlags : ObjectAceFlags.None;
515  if ((objectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent) == ObjectAceFlags.None)
516  {
517  return true;
518  }
519  return false;
520  }
521 
522  private bool GetAccessMaskForRemoval(QualifiedAce ace, ObjectAceFlags objectFlags, Guid objectType, ref int accessMask)
523  {
524  if ((ace.AccessMask & accessMask & ObjectAce.AccessMaskWithObjectType) != 0)
525  {
526  if (ace is ObjectAce)
527  {
528  bool flag = true;
529  ObjectAce objectAce = ace as ObjectAce;
530  if ((objectFlags & ObjectAceFlags.ObjectAceTypePresent) != 0 && (objectAce.ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent) == ObjectAceFlags.None)
531  {
532  return false;
533  }
534  if ((objectFlags & ObjectAceFlags.ObjectAceTypePresent) != 0 && !objectAce.ObjectTypesMatch(objectFlags, objectType))
535  {
536  accessMask &= ~ObjectAce.AccessMaskWithObjectType;
537  }
538  }
539  else if ((objectFlags & ObjectAceFlags.ObjectAceTypePresent) != 0)
540  {
541  return false;
542  }
543  }
544  return true;
545  }
546 
547  private bool GetInheritanceFlagsForRemoval(QualifiedAce ace, ObjectAceFlags objectFlags, Guid inheritedObjectType, ref AceFlags aceFlags)
548  {
549  if ((ace.AceFlags & AceFlags.ContainerInherit) != 0 && (aceFlags & AceFlags.ContainerInherit) != 0)
550  {
551  if (ace is ObjectAce)
552  {
553  bool flag = true;
554  ObjectAce objectAce = ace as ObjectAce;
555  if ((objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent) != 0 && (objectAce.ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent) == ObjectAceFlags.None)
556  {
557  return false;
558  }
559  if ((objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent) != 0 && !objectAce.InheritedObjectTypesMatch(objectFlags, inheritedObjectType))
560  {
561  aceFlags &= ~(AceFlags.ObjectInherit | AceFlags.ContainerInherit | AceFlags.NoPropagateInherit | AceFlags.InheritOnly);
562  }
563  }
564  else if ((objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent) != 0)
565  {
566  return false;
567  }
568  }
569  return true;
570  }
571 
572  private static bool AceOpaquesMatch(QualifiedAce ace, QualifiedAce newAce)
573  {
574  byte[] opaque = ace.GetOpaque();
575  byte[] opaque2 = newAce.GetOpaque();
576  if (opaque == null || opaque2 == null)
577  {
578  return opaque == opaque2;
579  }
580  if (opaque.Length != opaque2.Length)
581  {
582  return false;
583  }
584  for (int i = 0; i < opaque.Length; i++)
585  {
586  if (opaque[i] != opaque2[i])
587  {
588  return false;
589  }
590  }
591  return true;
592  }
593 
594  private static bool AcesAreMergeable(QualifiedAce ace, QualifiedAce newAce)
595  {
596  if (ace.AceType != newAce.AceType)
597  {
598  return false;
599  }
600  if ((ace.AceFlags & AceFlags.Inherited) != 0)
601  {
602  return false;
603  }
604  if ((newAce.AceFlags & AceFlags.Inherited) != 0)
605  {
606  return false;
607  }
608  if (ace.AceQualifier != newAce.AceQualifier)
609  {
610  return false;
611  }
612  if (ace.SecurityIdentifier != newAce.SecurityIdentifier)
613  {
614  return false;
615  }
616  if (!AceOpaquesMatch(ace, newAce))
617  {
618  return false;
619  }
620  return true;
621  }
622 
623  private bool MergeAces(ref QualifiedAce ace, QualifiedAce newAce)
624  {
625  if (!AcesAreMergeable(ace, newAce))
626  {
627  return false;
628  }
629  if (ace.AceFlags == newAce.AceFlags)
630  {
631  if (!(ace is ObjectAce) && !(newAce is ObjectAce))
632  {
633  ace.AccessMask |= newAce.AccessMask;
634  return true;
635  }
636  if (InheritedObjectTypesMatch(ace, newAce) && AccessMasksAreMergeable(ace, newAce))
637  {
638  ace.AccessMask |= newAce.AccessMask;
639  return true;
640  }
641  }
642  if ((ace.AceFlags & AceFlags.InheritanceFlags) == (newAce.AceFlags & AceFlags.InheritanceFlags) && ace.AccessMask == newAce.AccessMask)
643  {
644  if (!(ace is ObjectAce) && !(newAce is ObjectAce))
645  {
646  QualifiedAce obj = ace;
647  obj.AceFlags |= (newAce.AceFlags & AceFlags.AuditFlags);
648  return true;
649  }
650  if (InheritedObjectTypesMatch(ace, newAce) && ObjectTypesMatch(ace, newAce))
651  {
652  QualifiedAce obj2 = ace;
653  obj2.AceFlags |= (newAce.AceFlags & AceFlags.AuditFlags);
654  return true;
655  }
656  }
657  if ((ace.AceFlags & AceFlags.AuditFlags) == (newAce.AceFlags & AceFlags.AuditFlags) && ace.AccessMask == newAce.AccessMask)
658  {
659  AceFlags result;
660  if (ace is ObjectAce || newAce is ObjectAce)
661  {
662  if (ObjectTypesMatch(ace, newAce) && AceFlagsAreMergeable(ace, newAce) && MergeInheritanceBits(ace.AceFlags, newAce.AceFlags, IsDS, out result))
663  {
664  ace.AceFlags = (result | (ace.AceFlags & AceFlags.AuditFlags));
665  return true;
666  }
667  }
668  else if (MergeInheritanceBits(ace.AceFlags, newAce.AceFlags, IsDS, out result))
669  {
670  ace.AceFlags = (result | (ace.AceFlags & AceFlags.AuditFlags));
671  return true;
672  }
673  }
674  return false;
675  }
676 
677  private bool CanonicalCheck(bool isDacl)
678  {
679  if (isDacl)
680  {
681  int num = 0;
682  for (int i = 0; i < _acl.Count; i++)
683  {
684  int num2 = 3;
685  GenericAce genericAce = _acl[i];
686  if ((genericAce.AceFlags & AceFlags.Inherited) != 0)
687  {
688  num2 = 2;
689  }
690  else
691  {
692  QualifiedAce qualifiedAce = genericAce as QualifiedAce;
693  if (qualifiedAce == null)
694  {
695  return false;
696  }
697  if (qualifiedAce.AceQualifier == AceQualifier.AccessAllowed)
698  {
699  num2 = 1;
700  }
701  else
702  {
703  if (qualifiedAce.AceQualifier != AceQualifier.AccessDenied)
704  {
705  return false;
706  }
707  num2 = 0;
708  }
709  }
710  if (num2 != 3)
711  {
712  if (num2 > num)
713  {
714  num = num2;
715  }
716  else if (num2 < num)
717  {
718  return false;
719  }
720  }
721  }
722  }
723  else
724  {
725  int num3 = 0;
726  for (int j = 0; j < _acl.Count; j++)
727  {
728  int num4 = 2;
729  GenericAce genericAce2 = _acl[j];
730  if (genericAce2 == null)
731  {
732  continue;
733  }
734  if ((genericAce2.AceFlags & AceFlags.Inherited) != 0)
735  {
736  num4 = 1;
737  }
738  else
739  {
740  QualifiedAce qualifiedAce2 = genericAce2 as QualifiedAce;
741  if (qualifiedAce2 == null)
742  {
743  return false;
744  }
745  if (qualifiedAce2.AceQualifier != AceQualifier.SystemAudit && qualifiedAce2.AceQualifier != AceQualifier.SystemAlarm)
746  {
747  return false;
748  }
749  num4 = 0;
750  }
751  if (num4 > num3)
752  {
753  num3 = num4;
754  }
755  else if (num4 < num3)
756  {
757  return false;
758  }
759  }
760  }
761  return true;
762  }
763 
764  private void ThrowIfNotCanonical()
765  {
766  if (!_isCanonical)
767  {
768  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ModificationOfNonCanonicalAcl"));
769  }
770  }
771 
772  internal CommonAcl(bool isContainer, bool isDS, byte revision, int capacity)
773  {
774  _isContainer = isContainer;
775  _isDS = isDS;
776  _acl = new RawAcl(revision, capacity);
777  _isCanonical = true;
778  }
779 
780  internal CommonAcl(bool isContainer, bool isDS, RawAcl rawAcl, bool trusted, bool isDacl)
781  {
782  if (rawAcl == null)
783  {
784  throw new ArgumentNullException("rawAcl");
785  }
786  _isContainer = isContainer;
787  _isDS = isDS;
788  if (trusted)
789  {
790  _acl = rawAcl;
791  RemoveMeaninglessAcesAndFlags(isDacl);
792  }
793  else
794  {
795  _acl = new RawAcl(rawAcl.Revision, rawAcl.Count);
796  for (int i = 0; i < rawAcl.Count; i++)
797  {
798  GenericAce ace = rawAcl[i].Copy();
799  if (InspectAce(ref ace, isDacl))
800  {
801  _acl.InsertAce(_acl.Count, ace);
802  }
803  }
804  }
805  if (CanonicalCheck(isDacl))
806  {
807  Canonicalize(compact: true, isDacl);
808  _isCanonical = true;
809  }
810  else
811  {
812  _isCanonical = false;
813  }
814  }
815 
816  internal void CheckAccessType(AccessControlType accessType)
817  {
818  if (accessType != 0 && accessType != AccessControlType.Deny)
819  {
820  throw new ArgumentOutOfRangeException("accessType", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
821  }
822  }
823 
824  internal void CheckFlags(InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
825  {
826  if (IsContainer)
827  {
828  if (inheritanceFlags == InheritanceFlags.None && propagationFlags != 0)
829  {
830  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidAnyFlag"), "propagationFlags");
831  }
832  return;
833  }
834  if (inheritanceFlags != 0)
835  {
836  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidAnyFlag"), "inheritanceFlags");
837  }
838  if (propagationFlags != 0)
839  {
840  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidAnyFlag"), "propagationFlags");
841  }
842  }
843 
844  internal void AddQualifiedAce(SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType)
845  {
846  if (sid == null)
847  {
848  throw new ArgumentNullException("sid");
849  }
850  ThrowIfNotCanonical();
851  bool flag = false;
852  if (qualifier == AceQualifier.SystemAudit && (flags & AceFlags.AuditFlags) == AceFlags.None)
853  {
854  throw new ArgumentException(Environment.GetResourceString("Arg_EnumAtLeastOneFlag"), "flags");
855  }
856  if (accessMask == 0)
857  {
858  throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), "accessMask");
859  }
860  GenericAce ace = (IsDS && objectFlags != 0) ? ((QualifiedAce)new ObjectAce(flags, qualifier, accessMask, sid, objectFlags, objectType, inheritedObjectType, isCallback: false, null)) : ((QualifiedAce)new CommonAce(flags, qualifier, accessMask, sid, isCallback: false, null));
861  if (!InspectAce(ref ace, this is DiscretionaryAcl))
862  {
863  return;
864  }
865  for (int i = 0; i < Count; i++)
866  {
867  QualifiedAce ace2 = _acl[i] as QualifiedAce;
868  if (!(ace2 == null) && MergeAces(ref ace2, ace as QualifiedAce))
869  {
870  flag = true;
871  break;
872  }
873  }
874  if (!flag)
875  {
876  _acl.InsertAce(_acl.Count, ace);
877  _isDirty = true;
878  }
879  OnAclModificationTried();
880  }
881 
882  internal void SetQualifiedAce(SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType)
883  {
884  if (sid == null)
885  {
886  throw new ArgumentNullException("sid");
887  }
888  if (qualifier == AceQualifier.SystemAudit && (flags & AceFlags.AuditFlags) == AceFlags.None)
889  {
890  throw new ArgumentException(Environment.GetResourceString("Arg_EnumAtLeastOneFlag"), "flags");
891  }
892  if (accessMask == 0)
893  {
894  throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), "accessMask");
895  }
896  ThrowIfNotCanonical();
897  GenericAce ace = (IsDS && objectFlags != 0) ? ((QualifiedAce)new ObjectAce(flags, qualifier, accessMask, sid, objectFlags, objectType, inheritedObjectType, isCallback: false, null)) : ((QualifiedAce)new CommonAce(flags, qualifier, accessMask, sid, isCallback: false, null));
898  if (!InspectAce(ref ace, this is DiscretionaryAcl))
899  {
900  return;
901  }
902  for (int i = 0; i < Count; i++)
903  {
904  QualifiedAce qualifiedAce = _acl[i] as QualifiedAce;
905  if (!(qualifiedAce == null) && (qualifiedAce.AceFlags & AceFlags.Inherited) == AceFlags.None && qualifiedAce.AceQualifier == qualifier && !(qualifiedAce.SecurityIdentifier != sid))
906  {
907  _acl.RemoveAce(i);
908  i--;
909  }
910  }
911  _acl.InsertAce(_acl.Count, ace);
912  _isDirty = true;
913  OnAclModificationTried();
914  }
915 
916  internal bool RemoveQualifiedAces(SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, bool saclSemantics, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType)
917  {
918  if (accessMask == 0)
919  {
920  throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), "accessMask");
921  }
922  if (qualifier == AceQualifier.SystemAudit && (flags & AceFlags.AuditFlags) == AceFlags.None)
923  {
924  throw new ArgumentException(Environment.GetResourceString("Arg_EnumAtLeastOneFlag"), "flags");
925  }
926  if (sid == null)
927  {
928  throw new ArgumentNullException("sid");
929  }
930  ThrowIfNotCanonical();
931  bool flag = true;
932  bool flag2 = true;
933  int num = accessMask;
934  AceFlags aceFlags = flags;
935  byte[] binaryForm = new byte[BinaryLength];
936  GetBinaryForm(binaryForm, 0);
937  while (true)
938  {
939  try
940  {
941  for (int i = 0; i < Count; i++)
942  {
943  QualifiedAce qualifiedAce = _acl[i] as QualifiedAce;
944  if (!(qualifiedAce == null) && (qualifiedAce.AceFlags & AceFlags.Inherited) == AceFlags.None && qualifiedAce.AceQualifier == qualifier && !(qualifiedAce.SecurityIdentifier != sid))
945  {
946  if (IsDS)
947  {
948  accessMask = num;
949  bool flag3 = !GetAccessMaskForRemoval(qualifiedAce, objectFlags, objectType, ref accessMask);
950  if ((qualifiedAce.AccessMask & accessMask) == 0)
951  {
952  continue;
953  }
954  flags = aceFlags;
955  bool flag4 = !GetInheritanceFlagsForRemoval(qualifiedAce, objectFlags, inheritedObjectType, ref flags);
956  if (((qualifiedAce.AceFlags & AceFlags.ContainerInherit) == AceFlags.None && (flags & AceFlags.ContainerInherit) != 0 && (flags & AceFlags.InheritOnly) != 0) || ((flags & AceFlags.ContainerInherit) == AceFlags.None && (qualifiedAce.AceFlags & AceFlags.ContainerInherit) != 0 && (qualifiedAce.AceFlags & AceFlags.InheritOnly) != 0) || ((aceFlags & AceFlags.ContainerInherit) != 0 && (aceFlags & AceFlags.InheritOnly) != 0 && (flags & AceFlags.ContainerInherit) == AceFlags.None))
957  {
958  continue;
959  }
960  if (flag3 | flag4)
961  {
962  flag2 = false;
963  break;
964  }
965  }
966  else if ((qualifiedAce.AccessMask & accessMask) == 0)
967  {
968  continue;
969  }
970  if (!saclSemantics || (qualifiedAce.AceFlags & flags & AceFlags.AuditFlags) != 0)
971  {
972  AceFlags aceFlags2 = AceFlags.None;
973  int num2 = 0;
974  ObjectAceFlags objectFlags2 = ObjectAceFlags.None;
975  Guid objectType2 = Guid.Empty;
976  Guid inheritedObjectType2 = Guid.Empty;
977  AceFlags aceFlags3 = AceFlags.None;
978  int accessMask2 = 0;
979  ObjectAceFlags objectFlags3 = ObjectAceFlags.None;
980  Guid objectType3 = Guid.Empty;
981  Guid inheritedObjectType3 = Guid.Empty;
982  AceFlags aceFlags4 = AceFlags.None;
983  int num3 = 0;
984  ObjectAceFlags objectFlags4 = ObjectAceFlags.None;
985  Guid objectType4 = Guid.Empty;
986  Guid inheritedObjectType4 = Guid.Empty;
987  AceFlags result = AceFlags.None;
988  bool total = false;
989  aceFlags2 = qualifiedAce.AceFlags;
990  num2 = (qualifiedAce.AccessMask & ~accessMask);
991  if (qualifiedAce is ObjectAce)
992  {
993  GetObjectTypesForSplit(qualifiedAce as ObjectAce, num2, aceFlags2, out objectFlags2, out objectType2, out inheritedObjectType2);
994  }
995  if (saclSemantics)
996  {
997  aceFlags3 = (AceFlags)((int)qualifiedAce.AceFlags & (int)(byte)(~(uint)(flags & AceFlags.AuditFlags)));
998  accessMask2 = (qualifiedAce.AccessMask & accessMask);
999  if (qualifiedAce is ObjectAce)
1000  {
1001  GetObjectTypesForSplit(qualifiedAce as ObjectAce, accessMask2, aceFlags3, out objectFlags3, out objectType3, out inheritedObjectType3);
1002  }
1003  }
1004  aceFlags4 = ((qualifiedAce.AceFlags & AceFlags.InheritanceFlags) | (flags & qualifiedAce.AceFlags & AceFlags.AuditFlags));
1005  num3 = (qualifiedAce.AccessMask & accessMask);
1006  if (!saclSemantics || (aceFlags4 & AceFlags.AuditFlags) != 0)
1007  {
1008  if (!RemoveInheritanceBits(aceFlags4, flags, IsDS, out result, out total))
1009  {
1010  flag2 = false;
1011  break;
1012  }
1013  if (!total)
1014  {
1015  result |= (aceFlags4 & AceFlags.AuditFlags);
1016  if (qualifiedAce is ObjectAce)
1017  {
1018  GetObjectTypesForSplit(qualifiedAce as ObjectAce, num3, result, out objectFlags4, out objectType4, out inheritedObjectType4);
1019  }
1020  }
1021  }
1022  if (!flag)
1023  {
1024  if (num2 != 0)
1025  {
1026  if (qualifiedAce is ObjectAce && (((ObjectAce)qualifiedAce).ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent) != 0 && (objectFlags2 & ObjectAceFlags.ObjectAceTypePresent) == ObjectAceFlags.None)
1027  {
1028  _acl.RemoveAce(i);
1029  ObjectAce ace = new ObjectAce(aceFlags2, qualifier, num2, qualifiedAce.SecurityIdentifier, objectFlags2, objectType2, inheritedObjectType2, isCallback: false, null);
1030  _acl.InsertAce(i, ace);
1031  }
1032  else
1033  {
1034  qualifiedAce.AceFlags = aceFlags2;
1035  qualifiedAce.AccessMask = num2;
1036  if (qualifiedAce is ObjectAce)
1037  {
1038  ObjectAce objectAce = qualifiedAce as ObjectAce;
1039  objectAce.ObjectAceFlags = objectFlags2;
1040  objectAce.ObjectAceType = objectType2;
1041  objectAce.InheritedObjectAceType = inheritedObjectType2;
1042  }
1043  }
1044  }
1045  else
1046  {
1047  _acl.RemoveAce(i);
1048  i--;
1049  }
1050  if (saclSemantics && (aceFlags3 & AceFlags.AuditFlags) != 0)
1051  {
1052  QualifiedAce ace2 = (!(qualifiedAce is CommonAce)) ? ((QualifiedAce)new ObjectAce(aceFlags3, qualifier, accessMask2, qualifiedAce.SecurityIdentifier, objectFlags3, objectType3, inheritedObjectType3, isCallback: false, null)) : ((QualifiedAce)new CommonAce(aceFlags3, qualifier, accessMask2, qualifiedAce.SecurityIdentifier, isCallback: false, null));
1053  i++;
1054  _acl.InsertAce(i, ace2);
1055  }
1056  if (!total)
1057  {
1058  QualifiedAce ace2 = (!(qualifiedAce is CommonAce)) ? ((QualifiedAce)new ObjectAce(result, qualifier, num3, qualifiedAce.SecurityIdentifier, objectFlags4, objectType4, inheritedObjectType4, isCallback: false, null)) : ((QualifiedAce)new CommonAce(result, qualifier, num3, qualifiedAce.SecurityIdentifier, isCallback: false, null));
1059  i++;
1060  _acl.InsertAce(i, ace2);
1061  }
1062  }
1063  }
1064  }
1065  }
1066  }
1067  catch (OverflowException)
1068  {
1069  _acl.SetBinaryForm(binaryForm, 0);
1070  return false;
1071  }
1072  if (!flag || !flag2)
1073  {
1074  break;
1075  }
1076  flag = false;
1077  }
1078  OnAclModificationTried();
1079  return flag2;
1080  }
1081 
1082  internal void RemoveQualifiedAcesSpecific(SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType)
1083  {
1084  if (accessMask == 0)
1085  {
1086  throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), "accessMask");
1087  }
1088  if (qualifier == AceQualifier.SystemAudit && (flags & AceFlags.AuditFlags) == AceFlags.None)
1089  {
1090  throw new ArgumentException(Environment.GetResourceString("Arg_EnumAtLeastOneFlag"), "flags");
1091  }
1092  if (sid == null)
1093  {
1094  throw new ArgumentNullException("sid");
1095  }
1096  ThrowIfNotCanonical();
1097  for (int i = 0; i < Count; i++)
1098  {
1099  QualifiedAce qualifiedAce = _acl[i] as QualifiedAce;
1100  if (qualifiedAce == null || (qualifiedAce.AceFlags & AceFlags.Inherited) != 0 || qualifiedAce.AceQualifier != qualifier || qualifiedAce.SecurityIdentifier != sid || qualifiedAce.AceFlags != flags || qualifiedAce.AccessMask != accessMask)
1101  {
1102  continue;
1103  }
1104  if (IsDS)
1105  {
1106  if (qualifiedAce is ObjectAce && objectFlags != 0)
1107  {
1108  ObjectAce objectAce = qualifiedAce as ObjectAce;
1109  if (!objectAce.ObjectTypesMatch(objectFlags, objectType) || !objectAce.InheritedObjectTypesMatch(objectFlags, inheritedObjectType))
1110  {
1111  continue;
1112  }
1113  }
1114  else if (qualifiedAce is ObjectAce || objectFlags != 0)
1115  {
1116  continue;
1117  }
1118  }
1119  _acl.RemoveAce(i);
1120  i--;
1121  }
1122  OnAclModificationTried();
1123  }
1124 
1125  internal virtual void OnAclModificationTried()
1126  {
1127  }
1128 
1132  public sealed override void GetBinaryForm(byte[] binaryForm, int offset)
1133  {
1134  CanonicalizeIfNecessary();
1135  _acl.GetBinaryForm(binaryForm, offset);
1136  }
1137 
1139  public void RemoveInheritedAces()
1140  {
1141  ThrowIfNotCanonical();
1142  for (int num = _acl.Count - 1; num >= 0; num--)
1143  {
1144  GenericAce genericAce = _acl[num];
1145  if ((genericAce.AceFlags & AceFlags.Inherited) != 0)
1146  {
1147  _acl.RemoveAce(num);
1148  }
1149  }
1150  OnAclModificationTried();
1151  }
1152 
1155  public void Purge(SecurityIdentifier sid)
1156  {
1157  if (sid == null)
1158  {
1159  throw new ArgumentNullException("sid");
1160  }
1161  ThrowIfNotCanonical();
1162  for (int num = Count - 1; num >= 0; num--)
1163  {
1164  KnownAce knownAce = _acl[num] as KnownAce;
1165  if (!(knownAce == null) && (knownAce.AceFlags & AceFlags.Inherited) == AceFlags.None && knownAce.SecurityIdentifier == sid)
1166  {
1167  _acl.RemoveAce(num);
1168  }
1169  }
1170  OnAclModificationTried();
1171  }
1172  }
1173 }
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
PropagationFlags
Specifies how Access Control Entries (ACEs) are propagated to child objects. These flags are signific...
bool IsCanonical
Gets a Boolean value that specifies whether the access control entries (ACEs) in the current T:System...
Definition: CommonAcl.cs:81
override void GetBinaryForm(byte[] binaryForm, int offset)
Marshals the contents of the T:System.Security.AccessControl.RawAcl object into the specified byte ar...
Definition: RawAcl.cs:174
override int BinaryLength
Gets the length, in bytes, of the binary representation of the current T:System.Security....
Definition: RawAcl.cs:23
sealed override void GetBinaryForm(byte[] binaryForm, int offset)
Marshals the contents of the T:System.Security.AccessControl.CommonAcl object into the specified byte...
Definition: CommonAcl.cs:1132
Definition: __Canon.cs:3
AceType
Defines the available access control entry (ACE) types.
Definition: AceType.cs:4
Represents an Access Control Entry (ACE), and is the base class for all other ACE classes.
Definition: GenericAce.cs:6
SecurityIdentifier SecurityIdentifier
Gets or sets the T:System.Security.Principal.SecurityIdentifier object associated with this T:System....
Definition: KnownAce.cs:31
Represents an Access Control List (ACL).
Definition: RawAcl.cs:6
AceFlags AceFlags
Gets or sets the T:System.Security.AccessControl.AceFlags associated with this T:System....
Definition: GenericAce.cs:23
sealed override byte Revision
Gets the revision level of the T:System.Security.AccessControl.CommonAcl.
Definition: CommonAcl.cs:54
sealed override int BinaryLength
Gets the length, in bytes, of the binary representation of the current T:System.Security....
Definition: CommonAcl.cs:70
Provides information about, and means to manipulate, the current environment and platform....
Definition: Environment.cs:21
A logical OR of F:System.Security.AccessControl.AceFlags.ObjectInherit, F:System.Security....
sealed override int Count
Gets the number of access control entries (ACEs) in the current T:System.Security....
Definition: CommonAcl.cs:59
void InsertAce(int index, GenericAce ace)
Inserts the specified Access Control Entry (ACE) at the specified index.
Definition: RawAcl.cs:204
Represents an access control list (ACL) and is the base class for the T:System.Security....
Definition: CommonAcl.cs:6
void RemoveInheritedAces()
Removes all inherited access control entries (ACEs) from this T:System.Security.AccessControl....
Definition: CommonAcl.cs:1139
override int Count
Gets the number of access control entries (ACEs) in the current T:System.Security....
Definition: RawAcl.cs:18
AceFlags
Specifies the inheritance and auditing behavior of an access control entry (ACE).
Definition: AceFlags.cs:5
AccessControlType
Specifies whether an T:System.Security.AccessControl.AccessRule object is used to allow or deny acces...
Specifies the discretionary access control list (DACL).
override byte Revision
Gets the revision level of the T:System.Security.AccessControl.RawAcl.
Definition: RawAcl.cs:14
Encapsulates all Access Control Entry (ACE) types currently defined by Microsoft Corporation....
Definition: KnownAce.cs:6
Represents an access control list (ACL) and is the base class for the T:System.Security....
Definition: GenericAcl.cs:6
AceQualifier
Specifies the function of an access control entry (ACE).
Definition: AceQualifier.cs:4
Represents a security identifier (SID) and provides marshaling and comparison operations for SIDs.
bool IsContainer
Sets whether the T:System.Security.AccessControl.CommonAcl object is a container.
Definition: CommonAcl.cs:86
void Purge(SecurityIdentifier sid)
Removes all access control entries (ACEs) contained by this T:System.Security.AccessControl....
Definition: CommonAcl.cs:1155
The exception that is thrown when an invoked method is not supported, or when there is an attempt to ...
bool IsDS
Sets whether the current T:System.Security.AccessControl.CommonAcl object is a directory object acces...
Definition: CommonAcl.cs:91
void RemoveAce(int index)
Removes the Access Control Entry (ACE) at the specified location.
Definition: RawAcl.cs:220
ObjectAceFlags
Specifies the presence of object types for Access Control Entries (ACEs).