source: vendor/current/source3/lib/util_seaccess.c@ 597

Last change on this file since 597 was 597, checked in by Herwig Bauernfeind, 14 years ago

Samba 3.5: Update vendor to version 3.5.9

File size: 7.9 KB
Line 
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
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.
13
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.
18
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/>.
21*/
22
23#include "includes.h"
24
25extern NT_USER_TOKEN anonymous_token;
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
32void se_map_generic(uint32 *access_mask, const struct generic_mapping *mapping)
33{
34 uint32 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
66void 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
85void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping)
86{
87 uint32 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*/
108static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
109 const NT_USER_TOKEN *token)
110{
111 uint32_t denied = 0, granted = 0;
112 unsigned i;
113
114 if (is_sid_in_token(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 (!is_sid_in_token(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*/
154NTSTATUS se_access_check(const struct security_descriptor *sd,
155 const NT_USER_TOKEN *token,
156 uint32_t access_desired,
157 uint32_t *access_granted)
158{
159 int 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 if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
181 if (user_has_privileges(token, &se_security)) {
182 bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
183 } else {
184 return NT_STATUS_PRIVILEGE_NOT_HELD;
185 }
186 }
187
188 /* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */
189 if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
190 is_sid_in_token(token, sd->owner_sid)) {
191 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
192 }
193 if ((bits_remaining & SEC_STD_DELETE) &&
194 user_has_privileges(token, &se_restore)) {
195 bits_remaining &= ~SEC_STD_DELETE;
196 }
197
198 /* a NULL dacl allows access */
199 if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
200 *access_granted = access_desired;
201 return NT_STATUS_OK;
202 }
203
204 if (sd->dacl == NULL) {
205 goto done;
206 }
207
208 /* check each ace in turn. */
209 for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
210 struct security_ace *ace = &sd->dacl->aces[i];
211
212 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
213 continue;
214 }
215
216 if (!is_sid_in_token(token, &ace->trustee)) {
217 continue;
218 }
219
220 switch (ace->type) {
221 case SEC_ACE_TYPE_ACCESS_ALLOWED:
222 bits_remaining &= ~ace->access_mask;
223 break;
224 case SEC_ACE_TYPE_ACCESS_DENIED:
225 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
226 if (bits_remaining & ace->access_mask) {
227 return NT_STATUS_ACCESS_DENIED;
228 }
229 break;
230 default: /* Other ACE types not handled/supported */
231 break;
232 }
233 }
234
235done:
236 if (bits_remaining != 0) {
237 *access_granted = bits_remaining;
238 return NT_STATUS_ACCESS_DENIED;
239 }
240
241 return NT_STATUS_OK;
242}
243
244/*******************************************************************
245 samr_make_sam_obj_sd
246 ********************************************************************/
247
248NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
249{
250 DOM_SID adm_sid;
251 DOM_SID act_sid;
252
253 SEC_ACE ace[3];
254
255 SEC_ACL *psa = NULL;
256
257 sid_copy(&adm_sid, &global_sid_Builtin);
258 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
259
260 sid_copy(&act_sid, &global_sid_Builtin);
261 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
262
263 /*basic access for every one*/
264 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
265 GENERIC_RIGHTS_SAM_EXECUTE | GENERIC_RIGHTS_SAM_READ, 0);
266
267 /*full access for builtin aliases Administrators and Account Operators*/
268 init_sec_ace(&ace[1], &adm_sid,
269 SEC_ACE_TYPE_ACCESS_ALLOWED, GENERIC_RIGHTS_SAM_ALL_ACCESS, 0);
270 init_sec_ace(&ace[2], &act_sid,
271 SEC_ACE_TYPE_ACCESS_ALLOWED, GENERIC_RIGHTS_SAM_ALL_ACCESS, 0);
272
273 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
274 return NT_STATUS_NO_MEMORY;
275
276 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
277 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
278 psa, sd_size)) == NULL)
279 return NT_STATUS_NO_MEMORY;
280
281 return NT_STATUS_OK;
282}
Note: See TracBrowser for help on using the repository browser.