s3: Fix bug #9085.
[Samba.git] / source3 / lib / util_seaccess.c
blob9f8d3fad6a8424c5a03faef02413dc7cfd2eabb8
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
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
25 extern NT_USER_TOKEN anonymous_token;
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 *access_mask, const struct generic_mapping *mapping)
34 uint32 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 *access_mask, struct standard_mapping *mapping)
87 uint32 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 NT_USER_TOKEN *token)
111 uint32_t denied = 0, granted = 0;
112 unsigned i;
114 if (is_sid_in_token(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 (!is_sid_in_token(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 NT_USER_TOKEN *token,
156 uint32_t access_desired,
157 uint32_t *access_granted)
159 int i;
160 uint32_t bits_remaining;
161 uint32_t explicitly_denied_bits = 0;
163 *access_granted = access_desired;
164 bits_remaining = access_desired;
166 /* handle the maximum allowed flag */
167 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
168 uint32_t orig_access_desired = access_desired;
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;
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));
181 if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
182 if (user_has_privileges(token, &se_security)) {
183 bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
184 } else {
185 return NT_STATUS_PRIVILEGE_NOT_HELD;
189 /* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */
190 if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
191 is_sid_in_token(token, sd->owner_sid)) {
192 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
194 if ((bits_remaining & SEC_STD_DELETE) &&
195 user_has_privileges(token, &se_restore)) {
196 bits_remaining &= ~SEC_STD_DELETE;
199 /* a NULL dacl allows access */
200 if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
201 *access_granted = access_desired;
202 return NT_STATUS_OK;
205 if (sd->dacl == NULL) {
206 goto done;
209 /* check each ace in turn. */
210 for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
211 struct security_ace *ace = &sd->dacl->aces[i];
213 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
214 continue;
217 if (!is_sid_in_token(token, &ace->trustee)) {
218 continue;
221 switch (ace->type) {
222 case SEC_ACE_TYPE_ACCESS_ALLOWED:
223 bits_remaining &= ~ace->access_mask;
224 break;
225 case SEC_ACE_TYPE_ACCESS_DENIED:
226 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
227 explicitly_denied_bits |= (bits_remaining & ace->access_mask);
228 break;
229 default: /* Other ACE types not handled/supported */
230 break;
234 bits_remaining |= explicitly_denied_bits;
236 done:
237 if (bits_remaining != 0) {
238 *access_granted = bits_remaining;
239 return NT_STATUS_ACCESS_DENIED;
242 return NT_STATUS_OK;
245 /*******************************************************************
246 samr_make_sam_obj_sd
247 ********************************************************************/
249 NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
251 DOM_SID adm_sid;
252 DOM_SID act_sid;
254 SEC_ACE ace[3];
256 SEC_ACL *psa = NULL;
258 sid_copy(&adm_sid, &global_sid_Builtin);
259 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
261 sid_copy(&act_sid, &global_sid_Builtin);
262 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
264 /*basic access for every one*/
265 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
266 GENERIC_RIGHTS_SAM_EXECUTE | GENERIC_RIGHTS_SAM_READ, 0);
268 /*full access for builtin aliases Administrators and Account Operators*/
269 init_sec_ace(&ace[1], &adm_sid,
270 SEC_ACE_TYPE_ACCESS_ALLOWED, GENERIC_RIGHTS_SAM_ALL_ACCESS, 0);
271 init_sec_ace(&ace[2], &act_sid,
272 SEC_ACE_TYPE_ACCESS_ALLOWED, GENERIC_RIGHTS_SAM_ALL_ACCESS, 0);
274 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
275 return NT_STATUS_NO_MEMORY;
277 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
278 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
279 psa, sd_size)) == NULL)
280 return NT_STATUS_NO_MEMORY;
282 return NT_STATUS_OK;