2 // RawSecurityDescriptorTest.cs - NUnit Test Cases for RawSecurityDescriptor
9 using System.Security.AccessControl;
10 using System.Security.Principal;
11 using NUnit.Framework;
13 namespace MonoTests.System.Security.AccessControl {
16 public class RawSecurityDescriptorTest {
17 private void CheckSddlConstructor (string sddl, byte[] expectedBinary)
19 RawSecurityDescriptor sd = new RawSecurityDescriptor (sddl);
21 Assert.That (sd.BinaryLength, Is.GreaterThanOrEqualTo (0));
22 byte[] buffer = new byte[sd.BinaryLength];
24 sd.GetBinaryForm (buffer, 0);
25 Assert.AreEqual (expectedBinary, buffer);
28 private void CheckBinaryConstructor (string expectedSddl, byte[] binary)
30 RawSecurityDescriptor sd = new RawSecurityDescriptor (binary, 0);
32 Assert.AreEqual (sd.BinaryLength, binary.Length);
33 Assert.AreEqual (expectedSddl, sd.GetSddlForm (AccessControlSections.All));
36 private void CheckRoundTrip (string sddl)
38 RawSecurityDescriptor sd = new RawSecurityDescriptor (sddl);
40 byte[] buffer = new byte[sd.BinaryLength];
41 sd.GetBinaryForm (buffer, 0);
43 sd = new RawSecurityDescriptor (buffer, 0);
44 Assert.AreEqual (sddl, sd.GetSddlForm (AccessControlSections.All));
48 public void ConstructorEmptyString ()
50 byte[] sdBinary = new byte[] {
51 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
53 CheckSddlConstructor ("", sdBinary);
57 public void ConstructorString ()
59 byte[] sdBinary = new byte[] {
60 0x01, 0x00, 0x04, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
62 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
63 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
65 0x00, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x01, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x14, 0x00, 0x3F, 0x00, 0x0E, 0x10, 0x01, 0x01,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
68 CheckSddlConstructor ("O:BUG:BAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)", sdBinary);
69 CheckSddlConstructor ("G:BAO:BUD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)", sdBinary);
70 CheckSddlConstructor ("G:BAD:(A; ;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)O:BU", sdBinary);
71 CheckSddlConstructor ("O:buG:baD:(a;;rpwpccdclcswrcwdwoga;;;s-1-0-0)", sdBinary);
73 sdBinary = new byte[] {
74 0x01, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
77 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
80 CheckSddlConstructor ("O:BUG:BA", sdBinary);
82 sdBinary = new byte[] {
83 0x01, 0x00, 0x04, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
85 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
86 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
88 0x00, 0x00, 0x04, 0x00, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00,
89 0x05, 0x00, 0x38, 0x00, 0x3F, 0x00, 0x0E, 0x10, 0x03, 0x00,
90 0x00, 0x00, 0x53, 0x1A, 0x72, 0xAB, 0x2F, 0x1E, 0xD0, 0x11,
91 0x98, 0x19, 0x00, 0xAA, 0x00, 0x40, 0x52, 0x9B, 0x53, 0x1A,
92 0x72, 0xAB, 0x2F, 0x1E, 0xD0, 0x11, 0x98, 0x19, 0x00, 0xAA,
93 0x00, 0x40, 0x52, 0x9B, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
95 CheckSddlConstructor ("O:BUG:BAD:(OA;;RPWPCCDCLCSWRCWDWOGA;ab721a53-1e2f-11d0-9819-00aa0040529b;ab721a53-1e2f-11d0-9819-00aa0040529b;S-1-0-0)", sdBinary);
99 public void ConstructorBinary ()
101 byte[] sdBinary = new byte[] {
102 0x01, 0x00, 0x04, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
104 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
105 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
107 0x00, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x01, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x14, 0x00, 0x3F, 0x00, 0x0E, 0x10, 0x01, 0x01,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
110 CheckBinaryConstructor ("O:BUG:BAD:(A;;CCDCLCSWRPWPRCWDWOGA;;;S-1-0-0)", sdBinary);
111 sdBinary = new byte[] {
112 0x01, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
115 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
118 CheckBinaryConstructor ("O:BUG:BA", sdBinary);
120 sdBinary = new byte[] {
121 0x01, 0x00, 0x04, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
123 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
124 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
126 0x00, 0x00, 0x04, 0x00, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00,
127 0x05, 0x00, 0x38, 0x00, 0x3F, 0x00, 0x0E, 0x10, 0x03, 0x00,
128 0x00, 0x00, 0x53, 0x1A, 0x72, 0xAB, 0x2F, 0x1E, 0xD0, 0x11,
129 0x98, 0x19, 0x00, 0xAA, 0x00, 0x40, 0x52, 0x9B, 0x53, 0x1A,
130 0x72, 0xAB, 0x2F, 0x1E, 0xD0, 0x11, 0x98, 0x19, 0x00, 0xAA,
131 0x00, 0x40, 0x52, 0x9B, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
133 CheckBinaryConstructor ("O:BUG:BAD:(OA;;CCDCLCSWRPWPRCWDWOGA;ab721a53-1e2f-11d0-9819-00aa0040529b;ab721a53-1e2f-11d0-9819-00aa0040529b;S-1-0-0)", sdBinary);
137 public void FlagMismatch ()
139 // Check setting DACL-present flag on empty SD
140 RawSecurityDescriptor sd = new RawSecurityDescriptor ("");
141 Assert.AreEqual (20, sd.BinaryLength);
142 sd.SetFlags (ControlFlags.DiscretionaryAclPresent);
143 Assert.AreEqual (20, sd.BinaryLength);
144 byte[] buffer = new byte[sd.BinaryLength];
145 sd.GetBinaryForm (buffer, 0);
146 byte[] sdBinary = new byte[] {
147 0x01, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
149 Assert.AreEqual (sdBinary, buffer);
151 // Check unsetting DACL-present flag on SD with DACL
152 sd = new RawSecurityDescriptor ("O:BUG:BAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)");
153 Assert.AreEqual (80, sd.BinaryLength);
154 sd.SetFlags (sd.ControlFlags & ~ControlFlags.DiscretionaryAclPresent);
155 Assert.AreEqual (ControlFlags.SelfRelative, sd.ControlFlags);
156 Assert.AreEqual (52, sd.BinaryLength);
157 buffer = new byte[sd.BinaryLength];
158 sd.GetBinaryForm (buffer, 0);
159 sdBinary = new byte[] {
160 0x01, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
163 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
166 Assert.AreEqual (sdBinary, buffer);
170 public void GetBinaryForm ()
172 RawSecurityDescriptor sd = new RawSecurityDescriptor ("");
173 sd.Owner = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
174 sd.Group = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
175 sd.DiscretionaryAcl = new RawAcl (1, 0);
176 sd.SystemAcl = new RawAcl (1, 0);
177 sd.SetFlags (sd.ControlFlags | ControlFlags.DiscretionaryAclPresent | ControlFlags.SystemAclPresent);
180 byte[] buffer = new byte[sd.BinaryLength];
181 sd.GetBinaryForm (buffer, 0);
182 byte[] sdBinary = new byte[] {
183 0x01, 0x00, 0x14, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
184 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
185 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
186 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
187 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
188 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
189 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 };
190 Assert.AreEqual (sdBinary, buffer);
192 // Add an ACE to the DACL
193 SecurityIdentifier builtInAdmins = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
194 CommonAce ace = new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 0x7FFFFFFF, builtInAdmins, false, null);
195 sd.DiscretionaryAcl.InsertAce (0, ace);
196 buffer = new byte[sd.BinaryLength];
197 sd.GetBinaryForm (buffer, 0);
198 sdBinary = new byte[] {
199 0x01, 0x00, 0x14, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
200 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
201 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
202 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
204 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x01, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
206 0x18, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x01, 0x02, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
209 Assert.AreEqual (sdBinary, buffer);
211 // This time with an Object ACE
212 ObjectAce objectAce = new ObjectAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 0x12345678, builtInAdmins, ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent, new Guid ("189c0dc7-b849-4dea-93a5-6d4cb8857a5c"), new Guid ("53b4a3d4-fe39-468b-bc60-b4fcba772fa5"), false, null);
213 sd.DiscretionaryAcl = new RawAcl (2, 0);
214 sd.DiscretionaryAcl.InsertAce (0, objectAce);
215 buffer = new byte[sd.BinaryLength];
216 sd.GetBinaryForm (buffer, 0);
217 sdBinary = new byte[] {
218 0x01, 0x00, 0x14, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
219 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
220 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
221 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
222 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
223 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
224 0x02, 0x00, 0x44, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x10,
225 0x3C, 0x00, 0x78, 0x56, 0x34, 0x12, 0x03, 0x00, 0x00, 0x00,
226 0xC7, 0x0D, 0x9C, 0x18, 0x49, 0xB8, 0xEA, 0x4D, 0x93, 0xA5,
227 0x6D, 0x4C, 0xB8, 0x85, 0x7A, 0x5C, 0xD4, 0xA3, 0xB4, 0x53,
228 0x39, 0xFE, 0x8B, 0x46, 0xBC, 0x60, 0xB4, 0xFC, 0xBA, 0x77,
229 0x2F, 0xA5, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
230 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00 };
231 Assert.AreEqual (sdBinary, buffer);
235 public void GetSddlForm ()
237 RawSecurityDescriptor sd = new RawSecurityDescriptor ("");
238 Assert.AreEqual ("", sd.GetSddlForm (AccessControlSections.All));
240 // Ask for part of SD that isn't represented
241 sd.Owner = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
242 sd.Group = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
243 Assert.AreEqual ("", sd.GetSddlForm (AccessControlSections.Access));
246 sd.DiscretionaryAcl = new RawAcl (2, 0);
247 sd.SystemAcl = new RawAcl (1, 0);
248 sd.SetFlags (sd.ControlFlags | ControlFlags.DiscretionaryAclPresent | ControlFlags.SystemAclPresent);
249 Assert.AreEqual ("O:BUG:BAD:S:", sd.GetSddlForm (AccessControlSections.All));
251 // Add an ACE to the DACL
252 SecurityIdentifier builtInAdmins = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
253 CommonAce ace = new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 0x7FFFFFFF, builtInAdmins, false, null);
254 sd.DiscretionaryAcl.InsertAce (0, ace);
255 Assert.AreEqual ("O:BUG:BAD:(A;;0x7fffffff;;;BA)S:", sd.GetSddlForm (AccessControlSections.All));
257 // Add second ACE to the DACL
258 SecurityIdentifier randomUser = new SecurityIdentifier ("S-1-5-21-324-23423-234-334");
259 ace = new CommonAce (AceFlags.Inherited | AceFlags.ContainerInherit, AceQualifier.AccessDenied, 0x12345678, randomUser, true, null);
260 sd.DiscretionaryAcl.InsertAce (0, ace);
261 Assert.AreEqual ("O:BUD:(XD;CIID;0x12345678;;;S-1-5-21-324-23423-234-334)(A;;0x7fffffff;;;BA)", sd.GetSddlForm (AccessControlSections.Owner | AccessControlSections.Access));
264 sd.SetFlags (sd.ControlFlags | ControlFlags.DiscretionaryAclProtected | ControlFlags.DiscretionaryAclAutoInherited | ControlFlags.DiscretionaryAclAutoInheritRequired | ControlFlags.SystemAclAutoInherited);
265 sd.DiscretionaryAcl = new RawAcl (1, 0);
266 ace = new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 0x7FFFFFFF, builtInAdmins, false, null);
267 sd.DiscretionaryAcl.InsertAce (0, ace);
268 Assert.AreEqual ("O:BUG:BAD:PARAI(A;;0x7fffffff;;;BA)S:AI", sd.GetSddlForm (AccessControlSections.All));
270 sd.SetFlags (sd.ControlFlags | ControlFlags.ServerSecurity | ControlFlags.DiscretionaryAclDefaulted);
271 Assert.AreEqual ("O:BUG:BAD:PARAI(A;;0x7fffffff;;;BA)S:AI", sd.GetSddlForm (AccessControlSections.All));
275 public void RoundTrip ()
277 CheckRoundTrip ("O:BUG:BAD:(A;;CCDCLCSWRPWPRCWDWOGA;;;S-1-0-0)");
278 CheckRoundTrip ("O:BUG:BAD:(A;;KR;;;S-1-0-0)");
279 CheckRoundTrip ("O:BUG:BAD:(OA;;CCDCLCSWRPWPRCWDWOGA;ab721a53-1e2f-11d0-9819-00aa0040529b;ab721a53-1e2f-11d0-9819-00aa0040529b;S-1-0-0)");
280 CheckRoundTrip ("O:BUG:BAD:(A;;CCDCLCSWRPRC;;;S-1-0-0)");
281 CheckRoundTrip ("O:SYG:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)");
282 CheckRoundTrip ("O:SYG:BAD:(A;OICINPIOID;0x12019f;;;SY)");
283 CheckRoundTrip ("O:SYG:BAS:(AU;SAFA;0x12019f;;;SY)");