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