Honor SeTakeOwnershiPrivilege when client asks for SEC_STD_WRITE_OWNER but has no...
[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         *access_granted = access_desired;
164         bits_remaining = access_desired;
165
166         /* handle the maximum allowed flag */
167         if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
168                 uint32_t orig_access_desired = access_desired;
169
170                 access_desired |= access_check_max_allowed(sd, token);
171                 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
172                 *access_granted = access_desired;
173                 bits_remaining = access_desired;
174
175                 DEBUG(10,("se_access_check: MAX desired = 0x%x, granted = 0x%x, remaining = 0x%x\n",
176                         orig_access_desired,
177                         *access_granted,
178                         bits_remaining));
179         }
180
181         /* s3 had this with #if 0 previously. To be sure the merge
182            doesn't change any behaviour, we have the above #if check
183            on _SAMBA_BUILD_. */
184         if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
185                 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
186                         bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
187                 } else {
188                         return NT_STATUS_PRIVILEGE_NOT_HELD;
189                 }
190         }
191
192         /* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */
193         if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
194             security_token_has_sid(token, sd->owner_sid)) {
195                 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
196         }
197
198         /* TODO: remove this, as it is file server specific */
199         if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
200             security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
201                 bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
202         }
203         if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
204             security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
205                 bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
206         }
207
208         if ((bits_remaining & SEC_STD_WRITE_OWNER) &&
209              security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
210                 bits_remaining &= ~(SEC_STD_WRITE_OWNER);
211         }
212
213         /* a NULL dacl allows access */
214         if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
215                 *access_granted = access_desired;
216                 return NT_STATUS_OK;
217         }
218
219         if (sd->dacl == NULL) {
220                 goto done;
221         }
222
223         /* check each ace in turn. */
224         for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
225                 struct security_ace *ace = &sd->dacl->aces[i];
226
227                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
228                         continue;
229                 }
230
231                 if (!security_token_has_sid(token, &ace->trustee)) {
232                         continue;
233                 }
234
235                 switch (ace->type) {
236                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
237                         bits_remaining &= ~ace->access_mask;
238                         break;
239                 case SEC_ACE_TYPE_ACCESS_DENIED:
240                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
241                         explicitly_denied_bits |= (bits_remaining & ace->access_mask);
242                         break;
243                 default:        /* Other ACE types not handled/supported */
244                         break;
245                 }
246         }
247
248         bits_remaining |= explicitly_denied_bits;
249
250 done:
251         if (bits_remaining != 0) {
252                 *access_granted = bits_remaining;
253                 return NT_STATUS_ACCESS_DENIED;
254         }
255
256         return NT_STATUS_OK;
257 }
258
259
260 static const struct GUID *get_ace_object_type(struct security_ace *ace)
261 {
262         struct GUID *type;
263
264         if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT)
265                 type = &ace->object.object.type.type;
266         else if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)
267                 type = &ace->object.object.inherited_type.inherited_type; /* This doesn't look right. Is something wrong with the IDL? */
268         else
269                 type = NULL;
270
271         return type;
272
273 }
274
275 /* modified access check for the purposes of DS security
276  * Lots of code duplication, it will ve united in just one
277  * function eventually */
278
279 NTSTATUS sec_access_check_ds(const struct security_descriptor *sd,
280                              const struct security_token *token,
281                              uint32_t access_desired,
282                              uint32_t *access_granted,
283                              struct object_tree *tree,
284                              struct dom_sid *replace_sid)
285 {
286         uint32_t i;
287         uint32_t bits_remaining;
288         struct object_tree *node;
289         const struct GUID *type;
290         struct dom_sid *ps_sid = dom_sid_parse_talloc(NULL, SID_NT_SELF);
291
292         *access_granted = access_desired;
293         bits_remaining = access_desired;
294
295         /* handle the maximum allowed flag */
296         if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
297                 access_desired |= access_check_max_allowed(sd, token);
298                 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
299                 *access_granted = access_desired;
300                 bits_remaining = access_desired;
301         }
302
303         if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
304                 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
305                         bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
306                 } else {
307                         talloc_free(ps_sid);
308                         return NT_STATUS_PRIVILEGE_NOT_HELD;
309                 }
310         }
311
312         /* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */
313         if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
314             security_token_has_sid(token, sd->owner_sid)) {
315                 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
316         }
317
318         /* TODO: remove this, as it is file server specific */
319         if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
320             security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
321                 bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
322         }
323         if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
324             security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
325                 bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
326         }
327
328         /* a NULL dacl allows access */
329         if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
330                 *access_granted = access_desired;
331                 talloc_free(ps_sid);
332                 return NT_STATUS_OK;
333         }
334
335         if (sd->dacl == NULL) {
336                 goto done;
337         }
338
339         /* check each ace in turn. */
340         for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
341                 struct dom_sid *trustee;
342                 struct security_ace *ace = &sd->dacl->aces[i];
343
344                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
345                         continue;
346                 }
347                 if (dom_sid_equal(&ace->trustee, ps_sid) && replace_sid) {
348                         trustee = replace_sid;
349                 }
350                 else
351                 {
352                         trustee = &ace->trustee;
353                 }
354                 if (!security_token_has_sid(token, trustee)) {
355                         continue;
356                 }
357
358                 switch (ace->type) {
359                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
360                         if (tree)
361                                 object_tree_modify_access(tree, ace->access_mask);
362
363                         bits_remaining &= ~ace->access_mask;
364                         break;
365                 case SEC_ACE_TYPE_ACCESS_DENIED:
366                         if (bits_remaining & ace->access_mask) {
367                                 talloc_free(ps_sid);
368                                 return NT_STATUS_ACCESS_DENIED;
369                         }
370                         break;
371                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
372                 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
373                         /* check only in case we have provided a tree,
374                          * the ACE has an object type and that type
375                          * is in the tree                           */
376                         type = get_ace_object_type(ace);
377
378                         if (!tree)
379                                 continue;
380
381                         if (!type)
382                                 node = tree;
383                         else
384                                 if (!(node = get_object_tree_by_GUID(tree, type)))
385                                         continue;
386
387                         if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
388                                 object_tree_modify_access(node, ace->access_mask);
389                                 if (node->remaining_access == 0) {
390                                         talloc_free(ps_sid);
391                                         return NT_STATUS_OK;
392                                 }
393                         } else {
394                                 if (node->remaining_access & ace->access_mask){
395                                         talloc_free(ps_sid);
396                                         return NT_STATUS_ACCESS_DENIED;
397                                 }
398                         }
399                         break;
400                 default:        /* Other ACE types not handled/supported */
401                         break;
402                 }
403         }
404
405 done:
406         talloc_free(ps_sid);
407         if (bits_remaining != 0) {
408                 return NT_STATUS_ACCESS_DENIED;
409         }
410
411         return NT_STATUS_OK;
412 }