7f08cb5ed851329e85c5095da1c6aa30cc8da19e
[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;
116         }
117
118         if (sd->dacl == NULL) {
119                 return granted & ~denied;
120         }
121
122         for (i = 0;i<sd->dacl->num_aces; i++) {
123                 struct security_ace *ace = &sd->dacl->aces[i];
124
125                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
126                         continue;
127                 }
128
129                 if (!security_token_has_sid(token, &ace->trustee)) {
130                         continue;
131                 }
132
133                 switch (ace->type) {
134                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
135                         granted |= ace->access_mask;
136                         break;
137                 case SEC_ACE_TYPE_ACCESS_DENIED:
138                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
139                         denied |= ace->access_mask;
140                         break;
141                 default:        /* Other ACE types not handled/supported */
142                         break;
143                 }
144         }
145
146         return granted & ~denied;
147 }
148
149 /*
150   The main entry point for access checking. If returning ACCESS_DENIED
151   this function returns the denied bits in the uint32_t pointed
152   to by the access_granted pointer.
153 */
154 NTSTATUS se_access_check(const struct security_descriptor *sd,
155                           const struct security_token *token,
156                           uint32_t access_desired,
157                           uint32_t *access_granted)
158 {
159         uint32_t i;
160         uint32_t bits_remaining;
161         uint32_t explicitly_denied_bits = 0;
162         /*
163          * Up until Windows Server 2008, owner always had these rights. Now
164          * we have to use Owner Rights perms if they are on the file.
165          *
166          * In addition we have to accumulate these bits and apply them
167          * correctly. See bug #8795
168          */
169         uint32_t owner_rights_allowed = 0;
170         uint32_t owner_rights_denied = 0;
171         bool owner_rights_default = true;
172
173         *access_granted = access_desired;
174         bits_remaining = access_desired;
175
176         /* handle the maximum allowed flag */
177         if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
178                 uint32_t orig_access_desired = access_desired;
179
180                 access_desired |= access_check_max_allowed(sd, token);
181                 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
182                 *access_granted = access_desired;
183                 bits_remaining = access_desired;
184
185                 DEBUG(10,("se_access_check: MAX desired = 0x%x, granted = 0x%x, remaining = 0x%x\n",
186                         orig_access_desired,
187                         *access_granted,
188                         bits_remaining));
189         }
190
191         /* a NULL dacl allows access */
192         if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
193                 *access_granted = access_desired;
194                 return NT_STATUS_OK;
195         }
196
197         if (sd->dacl == NULL) {
198                 goto done;
199         }
200
201         /* check each ace in turn. */
202         for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
203                 struct security_ace *ace = &sd->dacl->aces[i];
204
205                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
206                         continue;
207                 }
208
209                 /*
210                  * We need the Owner Rights permissions to ensure we
211                  * give or deny the correct permissions to the owner. Replace
212                  * owner_rights with the perms here if it is present.
213                  *
214                  * We don't care if we are not the owner because that is taken
215                  * care of below when we check if our token has the owner SID.
216                  *
217                  */
218                 if (dom_sid_equal(&ace->trustee, &global_sid_Owner_Rights)) {
219                         if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {
220                                 owner_rights_allowed |= ace->access_mask;
221                                 owner_rights_default = false;
222                         } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {
223                                 owner_rights_denied |= ace->access_mask;
224                                 owner_rights_default = false;
225                         }
226                         continue;
227                 }
228
229                 if (!security_token_has_sid(token, &ace->trustee)) {
230                         continue;
231                 }
232
233                 switch (ace->type) {
234                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
235                         bits_remaining &= ~ace->access_mask;
236                         break;
237                 case SEC_ACE_TYPE_ACCESS_DENIED:
238                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
239                         explicitly_denied_bits |= (bits_remaining & ace->access_mask);
240                         break;
241                 default:        /* Other ACE types not handled/supported */
242                         break;
243                 }
244         }
245
246         /* The owner always gets owner rights as defined above. */
247         if (security_token_has_sid(token, sd->owner_sid)) {
248                 if (owner_rights_default) {
249                         /*
250                          * Just remove them, no need to check if they are
251                          * there.
252                          */
253                         bits_remaining &= ~(SEC_STD_WRITE_DAC |
254                                                 SEC_STD_READ_CONTROL);
255                 } else {
256                         bits_remaining &= ~owner_rights_allowed;
257                         bits_remaining |= owner_rights_denied;
258                 }
259         }
260
261         /* Explicitly denied bits always override */
262         bits_remaining |= explicitly_denied_bits;
263
264         /*
265          * We check privileges here because they override even DENY entries.
266          */
267
268         /* Does the user have the privilege to gain SEC_PRIV_SECURITY? */
269         if (bits_remaining & SEC_FLAG_SYSTEM_SECURITY) {
270                 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
271                         bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
272                 } else {
273                         return NT_STATUS_PRIVILEGE_NOT_HELD;
274                 }
275         }
276
277         /* TODO: remove this, as it is file server specific */
278         if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
279             security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
280                 bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
281         }
282         if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
283             security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
284                 bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
285         }
286
287         if ((bits_remaining & SEC_STD_WRITE_OWNER) &&
288              security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
289                 bits_remaining &= ~(SEC_STD_WRITE_OWNER);
290         }
291
292 done:
293         if (bits_remaining != 0) {
294                 *access_granted = bits_remaining;
295                 return NT_STATUS_ACCESS_DENIED;
296         }
297
298         return NT_STATUS_OK;
299 }
300
301
302 static const struct GUID *get_ace_object_type(struct security_ace *ace)
303 {
304         struct GUID *type;
305
306         if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT)
307                 type = &ace->object.object.type.type;
308         else if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)
309                 type = &ace->object.object.inherited_type.inherited_type; /* This doesn't look right. Is something wrong with the IDL? */
310         else
311                 type = NULL;
312
313         return type;
314
315 }
316
317 /* modified access check for the purposes of DS security
318  * Lots of code duplication, it will ve united in just one
319  * function eventually */
320
321 NTSTATUS sec_access_check_ds(const struct security_descriptor *sd,
322                              const struct security_token *token,
323                              uint32_t access_desired,
324                              uint32_t *access_granted,
325                              struct object_tree *tree,
326                              struct dom_sid *replace_sid)
327 {
328         uint32_t i;
329         uint32_t bits_remaining;
330         struct object_tree *node;
331         const struct GUID *type;
332         struct dom_sid *ps_sid = dom_sid_parse_talloc(NULL, SID_NT_SELF);
333
334         *access_granted = access_desired;
335         bits_remaining = access_desired;
336
337         /* handle the maximum allowed flag */
338         if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
339                 access_desired |= access_check_max_allowed(sd, token);
340                 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
341                 *access_granted = access_desired;
342                 bits_remaining = access_desired;
343         }
344
345         if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
346                 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
347                         bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
348                 } else {
349                         talloc_free(ps_sid);
350                         return NT_STATUS_PRIVILEGE_NOT_HELD;
351                 }
352         }
353
354         /* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */
355         if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
356             security_token_has_sid(token, sd->owner_sid)) {
357                 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
358         }
359
360         /* TODO: remove this, as it is file server specific */
361         if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
362             security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
363                 bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
364         }
365         if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
366             security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
367                 bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
368         }
369
370         /* a NULL dacl allows access */
371         if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
372                 *access_granted = access_desired;
373                 talloc_free(ps_sid);
374                 return NT_STATUS_OK;
375         }
376
377         if (sd->dacl == NULL) {
378                 goto done;
379         }
380
381         /* check each ace in turn. */
382         for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
383                 struct dom_sid *trustee;
384                 struct security_ace *ace = &sd->dacl->aces[i];
385
386                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
387                         continue;
388                 }
389                 if (dom_sid_equal(&ace->trustee, ps_sid) && replace_sid) {
390                         trustee = replace_sid;
391                 }
392                 else
393                 {
394                         trustee = &ace->trustee;
395                 }
396                 if (!security_token_has_sid(token, trustee)) {
397                         continue;
398                 }
399
400                 switch (ace->type) {
401                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
402                         if (tree)
403                                 object_tree_modify_access(tree, ace->access_mask);
404
405                         bits_remaining &= ~ace->access_mask;
406                         break;
407                 case SEC_ACE_TYPE_ACCESS_DENIED:
408                         if (bits_remaining & ace->access_mask) {
409                                 talloc_free(ps_sid);
410                                 return NT_STATUS_ACCESS_DENIED;
411                         }
412                         break;
413                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
414                 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
415                         /* check only in case we have provided a tree,
416                          * the ACE has an object type and that type
417                          * is in the tree                           */
418                         type = get_ace_object_type(ace);
419
420                         if (!tree)
421                                 continue;
422
423                         if (!type)
424                                 node = tree;
425                         else
426                                 if (!(node = get_object_tree_by_GUID(tree, type)))
427                                         continue;
428
429                         if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
430                                 object_tree_modify_access(node, ace->access_mask);
431                                 if (node->remaining_access == 0) {
432                                         talloc_free(ps_sid);
433                                         return NT_STATUS_OK;
434                                 }
435                         } else {
436                                 if (node->remaining_access & ace->access_mask){
437                                         talloc_free(ps_sid);
438                                         return NT_STATUS_ACCESS_DENIED;
439                                 }
440                         }
441                         break;
442                 default:        /* Other ACE types not handled/supported */
443                         break;
444                 }
445         }
446
447 done:
448         talloc_free(ps_sid);
449         if (bits_remaining != 0) {
450                 return NT_STATUS_ACCESS_DENIED;
451         }
452
453         return NT_STATUS_OK;
454 }