preparing for release of 3.0-alpha18
[Samba.git] / source / lib / util_seaccess.c
blob9fdf03adfc8b13c0eb79ada6b9c86146628adfca
1 /*
2 Unix SMB/CIFS implementation.
3 Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
4 Copyright (C) Tim Potter 2000.
5 Copyright (C) Re-written by Jeremy Allison 2000.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 /**********************************************************************************
25 Check if this ACE has a SID in common with the token.
26 **********************************************************************************/
28 static BOOL token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace)
30 size_t i;
32 for (i = 0; i < token->num_sids; i++) {
33 if (sid_equal(&ace->trustee, &token->user_sids[i]))
34 return True;
37 return False;
40 /*********************************************************************************
41 Check an ACE against a SID. We return the remaining needed permission
42 bits not yet granted. Zero means permission allowed (no more needed bits).
43 **********************************************************************************/
45 static uint32 check_ace(SEC_ACE *ace, NT_USER_TOKEN *token, uint32 acc_desired,
46 NTSTATUS *status)
48 uint32 mask = ace->info.mask;
51 * Inherit only is ignored.
54 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
55 return acc_desired;
59 * If this ACE has no SID in common with the token,
60 * ignore it as it cannot be used to make an access
61 * determination.
64 if (!token_sid_in_ace( token, ace))
65 return acc_desired;
67 switch (ace->type) {
68 case SEC_ACE_TYPE_ACCESS_ALLOWED:
70 * This is explicitly allowed.
71 * Remove the bits from the remaining
72 * access required. Return the remaining
73 * bits needed.
75 acc_desired &= ~mask;
76 break;
77 case SEC_ACE_TYPE_ACCESS_DENIED:
79 * This is explicitly denied.
80 * If any bits match terminate here,
81 * we are denied.
83 if (acc_desired & mask) {
84 *status = NT_STATUS_ACCESS_DENIED;
85 return 0xFFFFFFFF;
87 break;
88 case SEC_ACE_TYPE_SYSTEM_ALARM:
89 case SEC_ACE_TYPE_SYSTEM_AUDIT:
90 *status = NT_STATUS_NOT_IMPLEMENTED;
91 return 0xFFFFFFFF;
92 default:
93 *status = NT_STATUS_INVALID_PARAMETER;
94 return 0xFFFFFFFF;
97 return acc_desired;
100 /*********************************************************************************
101 Maximum access was requested. Calculate the max possible. Fail if it doesn't
102 include other bits requested.
103 **********************************************************************************/
105 static BOOL get_max_access( SEC_ACL *the_acl, NT_USER_TOKEN *token, uint32 *granted,
106 uint32 desired,
107 NTSTATUS *status)
109 uint32 acc_denied = 0;
110 uint32 acc_granted = 0;
111 size_t i;
113 for ( i = 0 ; i < the_acl->num_aces; i++) {
114 SEC_ACE *ace = &the_acl->ace[i];
115 uint32 mask = ace->info.mask;
117 if (!token_sid_in_ace( token, ace))
118 continue;
120 switch (ace->type) {
121 case SEC_ACE_TYPE_ACCESS_ALLOWED:
122 acc_granted |= (mask & ~acc_denied);
123 break;
124 case SEC_ACE_TYPE_ACCESS_DENIED:
125 acc_denied |= (mask & ~acc_granted);
126 break;
127 case SEC_ACE_TYPE_SYSTEM_ALARM:
128 case SEC_ACE_TYPE_SYSTEM_AUDIT:
129 *status = NT_STATUS_NOT_IMPLEMENTED;
130 *granted = 0;
131 return False;
132 default:
133 *status = NT_STATUS_INVALID_PARAMETER;
134 *granted = 0;
135 return False;
140 * If we were granted no access, or we desired bits that we
141 * didn't get, then deny.
144 if ((acc_granted == 0) || ((acc_granted & desired) != desired)) {
145 *status = NT_STATUS_ACCESS_DENIED;
146 *granted = 0;
147 return False;
151 * Return the access we did get.
154 *granted = acc_granted;
155 *status = NT_STATUS_OK;
156 return True;
159 /* Map generic access rights to object specific rights. This technique is
160 used to give meaning to assigning read, write, execute and all access to
161 objects. Each type of object has its own mapping of generic to object
162 specific access rights. */
164 void se_map_generic(uint32 *access_mask, struct generic_mapping *mapping)
166 uint32 old_mask = *access_mask;
168 if (*access_mask & GENERIC_READ_ACCESS) {
169 *access_mask &= ~GENERIC_READ_ACCESS;
170 *access_mask |= mapping->generic_read;
173 if (*access_mask & GENERIC_WRITE_ACCESS) {
174 *access_mask &= ~GENERIC_WRITE_ACCESS;
175 *access_mask |= mapping->generic_write;
178 if (*access_mask & GENERIC_EXECUTE_ACCESS) {
179 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
180 *access_mask |= mapping->generic_execute;
183 if (*access_mask & GENERIC_ALL_ACCESS) {
184 *access_mask &= ~GENERIC_ALL_ACCESS;
185 *access_mask |= mapping->generic_all;
188 if (old_mask != *access_mask) {
189 DEBUG(10, ("se_map_generic(): mapped mask 0x%08x to 0x%08x\n",
190 old_mask, *access_mask));
194 /* Map standard access rights to object specific rights. This technique is
195 used to give meaning to assigning read, write, execute and all access to
196 objects. Each type of object has its own mapping of standard to object
197 specific access rights. */
199 void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping)
201 uint32 old_mask = *access_mask;
203 if (*access_mask & READ_CONTROL_ACCESS) {
204 *access_mask &= ~READ_CONTROL_ACCESS;
205 *access_mask |= mapping->std_read;
208 if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS)) {
209 *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
210 *access_mask |= mapping->std_all;
213 if (old_mask != *access_mask) {
214 DEBUG(10, ("se_map_standard(): mapped mask 0x%08x to 0x%08x\n",
215 old_mask, *access_mask));
219 /*****************************************************************************
220 Check access rights of a user against a security descriptor. Look at
221 each ACE in the security descriptor until an access denied ACE denies
222 any of the desired rights to the user or any of the users groups, or one
223 or more ACEs explicitly grant all requested access rights. See
224 "Access-Checking" document in MSDN.
225 *****************************************************************************/
227 BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token,
228 uint32 acc_desired, uint32 *acc_granted,
229 NTSTATUS *status)
231 extern NT_USER_TOKEN anonymous_token;
232 size_t i;
233 SEC_ACL *the_acl;
234 fstring sid_str;
235 uint32 tmp_acc_desired = acc_desired;
237 if (!status || !acc_granted)
238 return False;
240 if (!token)
241 token = &anonymous_token;
243 *status = NT_STATUS_OK;
244 *acc_granted = 0;
246 DEBUG(10,("se_access_check: requested access 0x%08x, for NT token with %u entries and first sid %s.\n",
247 (unsigned int)acc_desired, (unsigned int)token->num_sids,
248 sid_to_string(sid_str, &token->user_sids[0])));
251 * No security descriptor or security descriptor with no DACL
252 * present allows all access.
255 /* ACL must have something in it */
257 if (!sd || (sd && (!(sd->type & SEC_DESC_DACL_PRESENT) || sd->dacl == NULL))) {
258 *status = NT_STATUS_OK;
259 *acc_granted = acc_desired;
260 DEBUG(5, ("se_access_check: no sd or blank DACL, access allowed\n"));
261 return True;
264 /* The user sid is the first in the token */
266 DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &token->user_sids[PRIMARY_USER_SID_INDEX]) ));
268 for (i = 1; i < token->num_sids; i++) {
269 DEBUG(3, ("se_access_check: also %s\n",
270 sid_to_string(sid_str, &token->user_sids[i])));
273 /* Is the token the owner of the SID ? */
275 if (sd->owner_sid) {
276 for (i = 0; i < token->num_sids; i++) {
277 if (sid_equal(&token->user_sids[i], sd->owner_sid)) {
279 * The owner always has SEC_RIGHTS_WRITE_DAC & READ_CONTROL.
281 if (tmp_acc_desired & WRITE_DAC_ACCESS)
282 tmp_acc_desired &= ~WRITE_DAC_ACCESS;
283 if (tmp_acc_desired & READ_CONTROL_ACCESS)
284 tmp_acc_desired &= ~READ_CONTROL_ACCESS;
289 the_acl = sd->dacl;
291 if (tmp_acc_desired & MAXIMUM_ALLOWED_ACCESS) {
292 tmp_acc_desired &= ~MAXIMUM_ALLOWED_ACCESS;
293 return get_max_access( the_acl, token, acc_granted, tmp_acc_desired,
294 status);
297 for ( i = 0 ; i < the_acl->num_aces && tmp_acc_desired != 0; i++) {
298 SEC_ACE *ace = &the_acl->ace[i];
300 DEBUG(10,("se_access_check: ACE %u: type %d, flags = 0x%02x, SID = %s mask = %x, current desired = %x\n",
301 (unsigned int)i, ace->type, ace->flags,
302 sid_to_string(sid_str, &ace->trustee),
303 (unsigned int) ace->info.mask,
304 (unsigned int)tmp_acc_desired ));
306 tmp_acc_desired = check_ace( ace, token, tmp_acc_desired, status);
307 if (NT_STATUS_V(*status)) {
308 *acc_granted = 0;
309 DEBUG(5,("se_access_check: ACE %u denied with status %s.\n", (unsigned int)i, nt_errstr(*status)));
310 return False;
315 * If there are no more desired permissions left then
316 * access was allowed.
319 if (tmp_acc_desired == 0) {
320 *acc_granted = acc_desired;
321 *status = NT_STATUS_OK;
322 DEBUG(5,("se_access_check: access (%x) granted.\n", (unsigned int)acc_desired ));
323 return True;
326 *acc_granted = 0;
327 *status = NT_STATUS_ACCESS_DENIED;
328 DEBUG(5,("se_access_check: access (%x) denied.\n", (unsigned int)acc_desired ));
329 return False;
332 /* Create a child security descriptor using another security descriptor as
333 the parent container. This child object can either be a container or
334 non-container object. */
336 SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
337 BOOL child_container)
339 SEC_DESC_BUF *sdb;
340 SEC_DESC *sd;
341 SEC_ACL *new_dacl, *the_acl;
342 SEC_ACE *new_ace_list = NULL;
343 int new_ace_list_ndx = 0, i;
344 size_t size;
346 /* Currently we only process the dacl when creating the child. The
347 sacl should also be processed but this is left out as sacls are
348 not implemented in Samba at the moment.*/
350 the_acl = parent_ctr->dacl;
352 if (!(new_ace_list = talloc(ctx, sizeof(SEC_ACE) * the_acl->num_aces)))
353 return NULL;
355 for (i = 0; the_acl && i < the_acl->num_aces; i++) {
356 SEC_ACE *ace = &the_acl->ace[i];
357 SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
358 uint8 new_flags = 0;
359 BOOL inherit = False;
360 fstring sid_str;
362 /* The OBJECT_INHERIT_ACE flag causes the ACE to be
363 inherited by non-container children objects. Container
364 children objects will inherit it as an INHERIT_ONLY
365 ACE. */
367 if (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) {
369 if (!child_container) {
370 new_flags |= SEC_ACE_FLAG_OBJECT_INHERIT;
371 } else {
372 new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
375 inherit = True;
378 /* The CONAINER_INHERIT_ACE flag means all child container
379 objects will inherit and use the ACE. */
381 if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
382 if (!child_container) {
383 inherit = False;
384 } else {
385 new_flags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
389 /* The INHERIT_ONLY_ACE is not used by the se_access_check()
390 function for the parent container, but is inherited by
391 all child objects as a normal ACE. */
393 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
394 /* Move along, nothing to see here */
397 /* The SEC_ACE_FLAG_NO_PROPAGATE_INHERIT flag means the ACE
398 is inherited by child objects but not grandchildren
399 objects. We clear the object inherit and container
400 inherit flags in the inherited ACE. */
402 if (ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
403 new_flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT |
404 SEC_ACE_FLAG_CONTAINER_INHERIT);
407 /* Add ACE to ACE list */
409 if (!inherit)
410 continue;
412 init_sec_access(&new_ace->info, ace->info.mask);
413 init_sec_ace(new_ace, &ace->trustee, ace->type,
414 new_ace->info, new_flags);
416 sid_to_string(sid_str, &ace->trustee);
418 DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
419 " inherited as %s:%d/0x%02x/0x%08x\n", sid_str,
420 ace->type, ace->flags, ace->info.mask,
421 sid_str, new_ace->type, new_ace->flags,
422 new_ace->info.mask));
424 new_ace_list_ndx++;
427 /* Create child security descriptor to return */
429 new_dacl = make_sec_acl(ctx, ACL_REVISION, new_ace_list_ndx, new_ace_list);
431 /* Use the existing user and group sids. I don't think this is
432 correct. Perhaps the user and group should be passed in as
433 parameters by the caller? */
435 sd = make_sec_desc(ctx, SEC_DESC_REVISION,
436 parent_ctr->owner_sid,
437 parent_ctr->grp_sid,
438 parent_ctr->sacl,
439 new_dacl, &size);
441 sdb = make_sec_desc_buf(ctx, size, sd);
443 return sdb;