2 // System.Security.AccessControl.ObjectAce implementation
5 // Dick Porter <dick@ximian.com>
6 // Atsushi Enomoto <atsushi@ximian.com>
8 // James Bellinger <jfb@zer7.com>
10 // Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
11 // Copyright (C) 2012 James Bellinger
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Security.Principal;
34 using System.Globalization;
36 namespace System.Security.AccessControl
38 public sealed class ObjectAce : QualifiedAce
40 private Guid object_ace_type;
41 private Guid inherited_object_type;
42 private ObjectAceFlags object_ace_flags;
44 public ObjectAce (AceFlags aceFlags, AceQualifier qualifier,
45 int accessMask, SecurityIdentifier sid,
46 ObjectAceFlags flags, Guid type,
47 Guid inheritedType, bool isCallback,
49 : base (ConvertType(qualifier, isCallback), aceFlags, opaque)
51 AccessMask = accessMask;
52 SecurityIdentifier = sid;
53 ObjectAceFlags = flags;
55 InheritedObjectAceType = inheritedType;
58 internal ObjectAce (AceType type, AceFlags flags, int accessMask,
59 SecurityIdentifier sid, ObjectAceFlags objFlags,
60 Guid objType, Guid inheritedType, byte[] opaque)
61 : base(type, flags, opaque)
63 AccessMask = accessMask;
64 SecurityIdentifier = sid;
65 ObjectAceFlags = objFlags;
66 ObjectAceType = objType;
67 InheritedObjectAceType = inheritedType;
70 internal ObjectAce(byte[] binaryForm, int offset)
71 : base(binaryForm, offset)
73 int len = ReadUShort(binaryForm, offset + 2);
74 int lenMinimum = 12 + SecurityIdentifier.MinBinaryLength;
76 if (offset > binaryForm.Length - len)
77 throw new ArgumentException("Invalid ACE - truncated", "binaryForm");
79 throw new ArgumentException("Invalid ACE", "binaryForm");
81 AccessMask = ReadInt(binaryForm, offset + 4);
82 ObjectAceFlags = (ObjectAceFlags)ReadInt(binaryForm, offset + 8);
84 if (ObjectAceTypePresent) lenMinimum += 16;
85 if (InheritedObjectAceTypePresent) lenMinimum += 16;
87 throw new ArgumentException("Invalid ACE", "binaryForm");
90 if (ObjectAceTypePresent) {
91 ObjectAceType = ReadGuid(binaryForm, offset + pos); pos += 16;
93 if (InheritedObjectAceTypePresent) {
94 InheritedObjectAceType = ReadGuid(binaryForm, offset + pos); pos += 16;
97 SecurityIdentifier = new SecurityIdentifier(binaryForm, offset + pos);
98 pos += SecurityIdentifier.BinaryLength;
100 int opaqueLen = len - pos;
102 byte[] opaque = new byte[opaqueLen];
103 Array.Copy(binaryForm, offset + pos, opaque, 0, opaqueLen);
108 public override int BinaryLength
111 int length = 12 + SecurityIdentifier.BinaryLength + OpaqueLength;
112 if (ObjectAceTypePresent) length += 16;
113 if (InheritedObjectAceTypePresent) length += 16;
118 public Guid InheritedObjectAceType {
119 get { return inherited_object_type; }
120 set { inherited_object_type = value; }
123 bool InheritedObjectAceTypePresent {
124 get { return 0 != (ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent); }
127 public ObjectAceFlags ObjectAceFlags {
128 get { return object_ace_flags; }
129 set { object_ace_flags = value; }
132 public Guid ObjectAceType {
133 get { return object_ace_type; }
134 set { object_ace_type = value; }
137 bool ObjectAceTypePresent {
138 get { return 0 != (ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent); }
141 public override void GetBinaryForm (byte[] binaryForm, int offset)
143 int len = BinaryLength;
144 binaryForm[offset++] = (byte)this.AceType;
145 binaryForm[offset++] = (byte)this.AceFlags;
146 WriteUShort ((ushort)len, binaryForm, offset); offset += 2;
147 WriteInt (AccessMask, binaryForm, offset); offset += 4;
148 WriteInt ((int)ObjectAceFlags, binaryForm, offset); offset += 4;
150 if (0 != (ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent)) {
151 WriteGuid (ObjectAceType, binaryForm, offset); offset += 16;
153 if (0 != (ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent)) {
154 WriteGuid (InheritedObjectAceType, binaryForm, offset); offset += 16;
157 SecurityIdentifier.GetBinaryForm (binaryForm, offset);
158 offset += SecurityIdentifier.BinaryLength;
160 byte[] opaque = GetOpaque ();
161 if (opaque != null) {
162 Array.Copy (opaque, 0, binaryForm, offset, opaque.Length);
163 offset += opaque.Length;
167 public static int MaxOpaqueLength (bool isCallback)
169 // Varies by platform?
173 internal override string GetSddlForm()
175 if (OpaqueLength != 0)
176 throw new NotImplementedException (
177 "Unable to convert conditional ACEs to SDDL");
180 if ((ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent) != 0)
181 objType = object_ace_type.ToString("D");
183 string inhObjType = "";
184 if ((ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent) != 0)
185 inhObjType = inherited_object_type.ToString("D");
187 return string.Format (CultureInfo.InvariantCulture,
188 "({0};{1};{2};{3};{4};{5})",
189 GetSddlAceType (AceType),
190 GetSddlAceFlags (AceFlags),
191 GetSddlAccessRights (AccessMask),
194 SecurityIdentifier.GetSddlForm ());
197 private static AceType ConvertType(AceQualifier qualifier, bool isCallback)
201 case AceQualifier.AccessAllowed:
203 return AceType.AccessAllowedCallbackObject;
205 return AceType.AccessAllowedObject;
207 case AceQualifier.AccessDenied:
209 return AceType.AccessDeniedCallbackObject;
211 return AceType.AccessDeniedObject;
213 case AceQualifier.SystemAlarm:
215 return AceType.SystemAlarmCallbackObject;
217 return AceType.SystemAlarmObject;
219 case AceQualifier.SystemAudit:
221 return AceType.SystemAuditCallbackObject;
223 return AceType.SystemAuditObject;
226 throw new ArgumentException("Unrecognized ACE qualifier: " + qualifier, "qualifier");
230 private void WriteGuid (Guid val, byte[] buffer,
233 byte[] guidData = val.ToByteArray();
234 Array.Copy(guidData, 0, buffer, offset, 16);
237 private Guid ReadGuid(byte[] buffer, int offset)
239 byte[] temp = new byte[16];
240 Array.Copy(buffer, offset, temp, 0, 16);
241 return new Guid(temp);