s3: Simplify get_delete_on_close_token slightly
[Samba/gebeck_regimport.git] / libcli / security / access_check.c
blob7f08cb5ed851329e85c5095da1c6aa30cc8da19e
1 /*
2 Unix SMB/CIFS implementation.
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
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.
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.
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/>.
24 #include "includes.h"
25 #include "libcli/security/security.h"
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. */
32 void se_map_generic(uint32_t *access_mask, const struct generic_mapping *mapping)
34 uint32_t old_mask = *access_mask;
36 if (*access_mask & GENERIC_READ_ACCESS) {
37 *access_mask &= ~GENERIC_READ_ACCESS;
38 *access_mask |= mapping->generic_read;
41 if (*access_mask & GENERIC_WRITE_ACCESS) {
42 *access_mask &= ~GENERIC_WRITE_ACCESS;
43 *access_mask |= mapping->generic_write;
46 if (*access_mask & GENERIC_EXECUTE_ACCESS) {
47 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
48 *access_mask |= mapping->generic_execute;
51 if (*access_mask & GENERIC_ALL_ACCESS) {
52 *access_mask &= ~GENERIC_ALL_ACCESS;
53 *access_mask |= mapping->generic_all;
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));
62 /* Map generic access rights to object specific rights for all the ACE's
63 * in a security_acl.
66 void security_acl_map_generic(struct security_acl *sa,
67 const struct generic_mapping *mapping)
69 unsigned int i;
71 if (!sa) {
72 return;
75 for (i = 0; i < sa->num_aces; i++) {
76 se_map_generic(&sa->aces[i].access_mask, mapping);
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. */
85 void se_map_standard(uint32_t *access_mask, const struct standard_mapping *mapping)
87 uint32_t old_mask = *access_mask;
89 if (*access_mask & SEC_STD_READ_CONTROL) {
90 *access_mask &= ~SEC_STD_READ_CONTROL;
91 *access_mask |= mapping->std_read;
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;
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));
106 perform a SEC_FLAG_MAXIMUM_ALLOWED access check
108 static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
109 const struct security_token *token)
111 uint32_t denied = 0, granted = 0;
112 unsigned i;
114 if (security_token_has_sid(token, sd->owner_sid)) {
115 granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL;
118 if (sd->dacl == NULL) {
119 return granted & ~denied;
122 for (i = 0;i<sd->dacl->num_aces; i++) {
123 struct security_ace *ace = &sd->dacl->aces[i];
125 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
126 continue;
129 if (!security_token_has_sid(token, &ace->trustee)) {
130 continue;
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;
146 return granted & ~denied;
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.
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)
159 uint32_t i;
160 uint32_t bits_remaining;
161 uint32_t explicitly_denied_bits = 0;
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.
166 * In addition we have to accumulate these bits and apply them
167 * correctly. See bug #8795
169 uint32_t owner_rights_allowed = 0;
170 uint32_t owner_rights_denied = 0;
171 bool owner_rights_default = true;
173 *access_granted = access_desired;
174 bits_remaining = access_desired;
176 /* handle the maximum allowed flag */
177 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
178 uint32_t orig_access_desired = access_desired;
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;
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));
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;
197 if (sd->dacl == NULL) {
198 goto done;
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];
205 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
206 continue;
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.
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.
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;
226 continue;
229 if (!security_token_has_sid(token, &ace->trustee)) {
230 continue;
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;
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) {
250 * Just remove them, no need to check if they are
251 * there.
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;
261 /* Explicitly denied bits always override */
262 bits_remaining |= explicitly_denied_bits;
265 * We check privileges here because they override even DENY entries.
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;
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);
282 if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
283 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
284 bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
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);
292 done:
293 if (bits_remaining != 0) {
294 *access_granted = bits_remaining;
295 return NT_STATUS_ACCESS_DENIED;
298 return NT_STATUS_OK;
302 static const struct GUID *get_ace_object_type(struct security_ace *ace)
304 struct GUID *type;
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;
313 return type;
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 */
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)
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);
334 *access_granted = access_desired;
335 bits_remaining = access_desired;
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;
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;
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);
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);
365 if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
366 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
367 bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
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;
377 if (sd->dacl == NULL) {
378 goto done;
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];
386 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
387 continue;
389 if (dom_sid_equal(&ace->trustee, ps_sid) && replace_sid) {
390 trustee = replace_sid;
392 else
394 trustee = &ace->trustee;
396 if (!security_token_has_sid(token, trustee)) {
397 continue;
400 switch (ace->type) {
401 case SEC_ACE_TYPE_ACCESS_ALLOWED:
402 if (tree)
403 object_tree_modify_access(tree, ace->access_mask);
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;
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);
420 if (!tree)
421 continue;
423 if (!type)
424 node = tree;
425 else
426 if (!(node = get_object_tree_by_GUID(tree, type)))
427 continue;
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;
435 } else {
436 if (node->remaining_access & ace->access_mask){
437 talloc_free(ps_sid);
438 return NT_STATUS_ACCESS_DENIED;
441 break;
442 default: /* Other ACE types not handled/supported */
443 break;
447 done:
448 talloc_free(ps_sid);
449 if (bits_remaining != 0) {
450 return NT_STATUS_ACCESS_DENIED;
453 return NT_STATUS_OK;