Implement RawSecurityDescriptor.
[mono.git] / mcs / class / corlib / System.Security.AccessControl / RawSecurityDescriptor.cs
1 //
2 // System.Security.AccessControl.RawSecurityDescriptor implementation
3 //
4 // Author:
5 //      Dick Porter  <dick@ximian.com>
6 //      Kenneth Bell
7 //
8 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30
31 using System.Security.Principal;
32
33 namespace System.Security.AccessControl {
34         public sealed class RawSecurityDescriptor : GenericSecurityDescriptor {
35                 private ControlFlags control_flags;
36                 private SecurityIdentifier owner_sid;
37                 private SecurityIdentifier group_sid;
38                 private RawAcl system_acl;
39                 private RawAcl discretionary_acl;
40                 private byte resourcemgr_control;
41
42                 public RawSecurityDescriptor (string sddlForm)
43                 {
44                         if (sddlForm == null)
45                                 throw new ArgumentNullException ("sddlForm");
46                         
47                         ParseSddl (sddlForm.Replace (" ", ""));
48                         
49                         control_flags |= ControlFlags.SelfRelative;
50                 }
51
52                 public RawSecurityDescriptor (byte[] binaryForm, int offset)
53                 {
54                         if (binaryForm == null)
55                                 throw new ArgumentNullException("binaryForm");
56                         
57                         if (offset < 0 || offset > binaryForm.Length - 0x14)
58                                 throw new ArgumentOutOfRangeException("offset", offset, "Offset out of range");
59                         
60                         if (binaryForm[offset] != 1)
61                                 throw new ArgumentException("Unrecognized Security Descriptor revision.", "binaryForm");
62                         
63                         resourcemgr_control = binaryForm[offset + 0x01];
64                         control_flags = (ControlFlags)ReadUShort(binaryForm, offset + 0x02);
65                         
66                         int ownerPos = ReadInt(binaryForm, offset + 0x04);
67                         int groupPos = ReadInt(binaryForm, offset + 0x08);
68                         int saclPos = ReadInt(binaryForm, offset + 0x0C);
69                         int daclPos = ReadInt(binaryForm, offset + 0x10);
70                         
71                         if (ownerPos != 0)
72                                 owner_sid = new SecurityIdentifier(binaryForm, ownerPos);
73                         
74                         if (groupPos != 0)
75                                 group_sid = new SecurityIdentifier(binaryForm, groupPos);
76                         
77                         if (saclPos != 0)
78                                 system_acl = new RawAcl(binaryForm, saclPos);
79                         
80                         if (daclPos != 0)
81                                 discretionary_acl = new RawAcl(binaryForm, daclPos);
82                 }
83
84                 public RawSecurityDescriptor (ControlFlags flags,
85                                               SecurityIdentifier owner,
86                                               SecurityIdentifier @group,
87                                               RawAcl systemAcl,
88                                               RawAcl discretionaryAcl)
89                 {
90                         control_flags = flags;
91                         owner_sid = owner;
92                         group_sid = @group;
93                         system_acl = systemAcl;
94                         discretionary_acl = discretionaryAcl;
95                 }
96
97                 public override ControlFlags ControlFlags {
98                         get { return control_flags; }
99                 }
100
101                 public RawAcl DiscretionaryAcl {
102                         get { return discretionary_acl; }
103                         set { discretionary_acl = value; }
104                 }
105
106                 public override SecurityIdentifier Group {
107                         get { return group_sid; }
108                         set { group_sid = value; }
109                 }
110
111                 public override SecurityIdentifier Owner {
112                         get { return owner_sid; }
113                         set { owner_sid = value; }
114                 }
115
116                 public byte ResourceManagerControl {
117                         get { return resourcemgr_control; }
118                         set { resourcemgr_control = value; }
119                 }
120
121                 public RawAcl SystemAcl {
122                         get { return system_acl; }
123                         set { system_acl = value; }
124                 }
125
126                 public void SetFlags (ControlFlags flags)
127                 {
128                         control_flags = flags | ControlFlags.SelfRelative;
129                 }
130
131                 internal override GenericAcl InternalDacl {
132                         get { return this.DiscretionaryAcl; }
133                 }
134
135                 internal override GenericAcl InternalSacl {
136                         get { return this.SystemAcl; }
137                 }
138
139                 internal override byte InternalReservedField {
140                         get { return this.ResourceManagerControl; }
141                 }
142
143                 private void ParseSddl (string sddlForm)
144                 {
145                         ControlFlags flags = ControlFlags.None;
146                         
147                         int pos = 0;
148                         while (pos < sddlForm.Length - 2) {
149                                 switch (sddlForm.Substring (pos, 2)) {
150                                 case "O:":
151                                         pos += 2;
152                                         Owner = SecurityIdentifier.ParseSddlForm (sddlForm, ref pos);
153                                         break;
154                                 
155                                 case "G:":
156                                         pos += 2;
157                                         Group = SecurityIdentifier.ParseSddlForm (sddlForm, ref pos);
158                                         break;
159                                 
160                                 case "D:":
161                                         pos += 2;
162                                         DiscretionaryAcl = RawAcl.ParseSddlForm (sddlForm, true, ref flags, ref pos);
163                                         flags |= ControlFlags.DiscretionaryAclPresent;
164                                         break;
165                                 
166                                 case "S:":
167                                         pos += 2;
168                                         SystemAcl = RawAcl.ParseSddlForm (sddlForm, false, ref flags, ref pos);
169                                         flags |= ControlFlags.SystemAclPresent;
170                                         break;
171                                 default:
172                                         
173                                         throw new ArgumentException ("Invalid SDDL.", "sddlForm");
174                                 }
175                         }
176                         
177                         if (pos != sddlForm.Length) {
178                                 throw new ArgumentException ("Invalid SDDL.", "sddlForm");
179                         }
180                         
181                         SetFlags (flags);
182                 }
183                 
184                 private ushort ReadUShort (byte[] buffer, int offset)
185                 {
186                         return (ushort)((((int)buffer[offset + 0]) << 0)
187                                         | (((int)buffer[offset + 1]) << 8));
188                 }
189                 
190                 private int ReadInt (byte[] buffer, int offset)
191                 {
192                         return (((int)buffer[offset + 0]) << 0)
193                                 | (((int)buffer[offset + 1]) << 8)
194                                 | (((int)buffer[offset + 2]) << 16)
195                                 | (((int)buffer[offset + 3]) << 24);
196                 }
197         }
198 }
199