libcli/auth Merge source4/libcli/security and util_sid.c into the common code
[metze/samba/wip.git] / libcli / security / access_check.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Copyright (C) Andrew Tridgell 2004
5    Copyright (C) Gerald Carter 2005
6    Copyright (C) Volker Lendecke 2007
7    Copyright (C) Jeremy Allison 2008
8    Copyright (C) Andrew Bartlett 2010
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "libcli/security/security.h"
26
27 /* Map generic access rights to object specific rights.  This technique is
28    used to give meaning to assigning read, write, execute and all access to
29    objects.  Each type of object has its own mapping of generic to object
30    specific access rights. */
31
32 void se_map_generic(uint32_t *access_mask, const struct generic_mapping *mapping)
33 {
34         uint32_t old_mask = *access_mask;
35
36         if (*access_mask & GENERIC_READ_ACCESS) {
37                 *access_mask &= ~GENERIC_READ_ACCESS;
38                 *access_mask |= mapping->generic_read;
39         }
40
41         if (*access_mask & GENERIC_WRITE_ACCESS) {
42                 *access_mask &= ~GENERIC_WRITE_ACCESS;
43                 *access_mask |= mapping->generic_write;
44         }
45
46         if (*access_mask & GENERIC_EXECUTE_ACCESS) {
47                 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
48                 *access_mask |= mapping->generic_execute;
49         }
50
51         if (*access_mask & GENERIC_ALL_ACCESS) {
52                 *access_mask &= ~GENERIC_ALL_ACCESS;
53                 *access_mask |= mapping->generic_all;
54         }
55
56         if (old_mask != *access_mask) {
57                 DEBUG(10, ("se_map_generic(): mapped mask 0x%08x to 0x%08x\n",
58                            old_mask, *access_mask));
59         }
60 }
61
62 /* Map generic access rights to object specific rights for all the ACE's
63  * in a security_acl.
64  */
65
66 void security_acl_map_generic(struct security_acl *sa,
67                                 const struct generic_mapping *mapping)
68 {
69         unsigned int i;
70
71         if (!sa) {
72                 return;
73         }
74
75         for (i = 0; i < sa->num_aces; i++) {
76                 se_map_generic(&sa->aces[i].access_mask, mapping);
77         }
78 }
79
80 /* Map standard access rights to object specific rights.  This technique is
81    used to give meaning to assigning read, write, execute and all access to
82    objects.  Each type of object has its own mapping of standard to object
83    specific access rights. */
84
85 void se_map_standard(uint32_t *access_mask, const struct standard_mapping *mapping)
86 {
87         uint32_t old_mask = *access_mask;
88
89         if (*access_mask & SEC_STD_READ_CONTROL) {
90                 *access_mask &= ~SEC_STD_READ_CONTROL;
91                 *access_mask |= mapping->std_read;
92         }
93
94         if (*access_mask & (SEC_STD_DELETE|SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|SEC_STD_SYNCHRONIZE)) {
95                 *access_mask &= ~(SEC_STD_DELETE|SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|SEC_STD_SYNCHRONIZE);
96                 *access_mask |= mapping->std_all;
97         }
98
99         if (old_mask != *access_mask) {
100                 DEBUG(10, ("se_map_standard(): mapped mask 0x%08x to 0x%08x\n",
101                            old_mask, *access_mask));
102         }
103 }
104
105 /*
106   perform a SEC_FLAG_MAXIMUM_ALLOWED access check
107 */
108 static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
109                                         const struct security_token *token)
110 {
111         uint32_t denied = 0, granted = 0;
112         unsigned i;
113
114         if (security_token_has_sid(token, sd->owner_sid)) {
115                 granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE;
116         } else if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
117                 granted |= SEC_STD_DELETE;
118         }
119
120         if (sd->dacl == NULL) {
121                 return granted & ~denied;
122         }
123
124         for (i = 0;i<sd->dacl->num_aces; i++) {
125                 struct security_ace *ace = &sd->dacl->aces[i];
126
127                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
128                         continue;
129                 }
130
131                 if (!security_token_has_sid(token, &ace->trustee)) {
132                         continue;
133                 }
134
135                 switch (ace->type) {
136                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
137                         granted |= ace->access_mask;
138                         break;
139                 case SEC_ACE_TYPE_ACCESS_DENIED:
140                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
141                         denied |= ace->access_mask;
142                         break;
143                 default:        /* Other ACE types not handled/supported */
144                         break;
145                 }
146         }
147
148         return granted & ~denied;
149 }
150
151 /*
152   The main entry point for access checking. If returning ACCESS_DENIED
153   this function returns the denied bits in the uint32_t pointed
154   to by the access_granted pointer.
155 */
156 NTSTATUS se_access_check(const struct security_descriptor *sd,
157                           const struct security_token *token,
158                           uint32_t access_desired,
159                           uint32_t *access_granted)
160 {
161         uint32_t i;
162         uint32_t bits_remaining;
163
164         *access_granted = access_desired;
165         bits_remaining = access_desired;
166
167         /* handle the maximum allowed flag */
168         if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
169                 uint32_t orig_access_desired = access_desired;
170
171                 access_desired |= access_check_max_allowed(sd, token);
172                 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
173                 *access_granted = access_desired;
174                 bits_remaining = access_desired & ~SEC_STD_DELETE;
175
176                 DEBUG(10,("se_access_check: MAX desired = 0x%x, granted = 0x%x, remaining = 0x%x\n",
177                         orig_access_desired,
178                         *access_granted,
179                         bits_remaining));
180         }
181
182         if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
183                 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
184                         bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
185                 } else {
186                         return NT_STATUS_PRIVILEGE_NOT_HELD;
187                 }
188         }
189
190         /* a NULL dacl allows access */
191         if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
192                 *access_granted = access_desired;
193                 return NT_STATUS_OK;
194         }
195
196         /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */
197         if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) &&
198             security_token_has_sid(token, sd->owner_sid)) {
199                 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE);
200         }
201         if ((bits_remaining & SEC_STD_DELETE) &&
202             (security_token_has_privilege(token, SEC_PRIV_RESTORE))) {
203                 bits_remaining &= ~SEC_STD_DELETE;
204         }
205         if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
206             security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
207                 bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
208         }
209         if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
210             security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
211                 bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
212         }
213
214         if (sd->dacl == NULL) {
215                 goto done;
216         }
217
218         /* check each ace in turn. */
219         for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
220                 struct security_ace *ace = &sd->dacl->aces[i];
221
222                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
223                         continue;
224                 }
225
226                 if (!security_token_has_sid(token, &ace->trustee)) {
227                         continue;
228                 }
229
230                 switch (ace->type) {
231                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
232                         bits_remaining &= ~ace->access_mask;
233                         break;
234                 case SEC_ACE_TYPE_ACCESS_DENIED:
235                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
236                         if (bits_remaining & ace->access_mask) {
237                                 return NT_STATUS_ACCESS_DENIED;
238                         }
239                         break;
240                 default:        /* Other ACE types not handled/supported */
241                         break;
242                 }
243         }
244
245 done:
246         if (bits_remaining != 0) {
247                 *access_granted = bits_remaining;
248                 return NT_STATUS_ACCESS_DENIED;
249         }
250
251         return NT_STATUS_OK;
252 }
253
254
255 static const struct GUID *get_ace_object_type(struct security_ace *ace)
256 {
257         struct GUID *type;
258
259         if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT)
260                 type = &ace->object.object.type.type;
261         else if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)
262                 type = &ace->object.object.inherited_type.inherited_type; /* This doesn't look right. Is something wrong with the IDL? */
263         else
264                 type = NULL;
265
266         return type;
267
268 }
269
270 /* modified access check for the purposes of DS security
271  * Lots of code duplication, it will ve united in just one
272  * function eventually */
273
274 NTSTATUS sec_access_check_ds(const struct security_descriptor *sd,
275                              const struct security_token *token,
276                              uint32_t access_desired,
277                              uint32_t *access_granted,
278                              struct object_tree *tree,
279                              struct dom_sid *replace_sid)
280 {
281         uint32_t i;
282         uint32_t bits_remaining;
283         struct object_tree *node;
284         const struct GUID *type;
285         struct dom_sid *ps_sid = dom_sid_parse_talloc(NULL, SID_NT_SELF);
286
287         *access_granted = access_desired;
288         bits_remaining = access_desired;
289
290         /* handle the maximum allowed flag */
291         if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
292                 access_desired |= access_check_max_allowed(sd, token);
293                 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
294                 *access_granted = access_desired;
295                 bits_remaining = access_desired & ~SEC_STD_DELETE;
296         }
297
298         if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
299                 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
300                         bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
301                 } else {
302                         return NT_STATUS_PRIVILEGE_NOT_HELD;
303                 }
304         }
305
306         /* a NULL dacl allows access */
307         if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
308                 *access_granted = access_desired;
309                 return NT_STATUS_OK;
310         }
311
312         /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */
313         if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) &&
314             security_token_has_sid(token, sd->owner_sid)) {
315                 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE);
316         }
317         if ((bits_remaining & SEC_STD_DELETE) &&
318             security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
319                 bits_remaining &= ~SEC_STD_DELETE;
320         }
321
322         if (sd->dacl == NULL) {
323                 goto done;
324         }
325
326         /* check each ace in turn. */
327         for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
328                 struct dom_sid *trustee;
329                 struct security_ace *ace = &sd->dacl->aces[i];
330
331                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
332                         continue;
333                 }
334                 if (dom_sid_equal(&ace->trustee, ps_sid) && replace_sid) {
335                         trustee = replace_sid;
336                 }
337                 else
338                 {
339                         trustee = &ace->trustee;
340                 }
341                 if (!security_token_has_sid(token, trustee)) {
342                         continue;
343                 }
344
345                 switch (ace->type) {
346                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
347                         if (tree)
348                                 object_tree_modify_access(tree, ace->access_mask);
349
350                         bits_remaining &= ~ace->access_mask;
351                         break;
352                 case SEC_ACE_TYPE_ACCESS_DENIED:
353                         if (bits_remaining & ace->access_mask) {
354                                 return NT_STATUS_ACCESS_DENIED;
355                         }
356                         break;
357                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
358                 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
359                         /* check only in case we have provided a tree,
360                          * the ACE has an object type and that type
361                          * is in the tree                           */
362                         type = get_ace_object_type(ace);
363
364                         if (!tree)
365                                 continue;
366
367                         if (!type)
368                                 node = tree;
369                         else
370                                 if (!(node = get_object_tree_by_GUID(tree, type)))
371                                         continue;
372
373                         if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
374                                 object_tree_modify_access(node, ace->access_mask);
375                                 if (node->remaining_access == 0) {
376                                         return NT_STATUS_OK;
377                                 }
378                         }
379                         else {
380                                 if (node->remaining_access & ace->access_mask){
381                                         return NT_STATUS_ACCESS_DENIED;
382                                 }
383                         }
384                         break;
385                 default:        /* Other ACE types not handled/supported */
386                         break;
387                 }
388         }
389
390 done:
391         if (bits_remaining != 0) {
392                 return NT_STATUS_ACCESS_DENIED;
393         }
394
395         return NT_STATUS_OK;
396 }