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