source: vendor/3.5.0/source3/lib/util_seaccess.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 7.8 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 | SEC_STD_DELETE;
116 } else if (user_has_privileges(token, &se_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 (!is_sid_in_token(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*/
156NTSTATUS se_access_check(const struct security_descriptor *sd,
157 const NT_USER_TOKEN *token,
158 uint32_t access_desired,
159 uint32_t *access_granted)
160{
161 int 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#if 0
183 /* We need to support SeSecurityPrivilege for this. */
184
185 if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
186 if (user_has_privileges(token, &sec_security)) {
187 bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
188 } else {
189 return NT_STATUS_PRIVILEGE_NOT_HELD;
190 }
191 }
192#endif
193
194 /* a NULL dacl allows access */
195 if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
196 *access_granted = access_desired;
197 return NT_STATUS_OK;
198 }
199
200 /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */
201 if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) &&
202 is_sid_in_token(token, sd->owner_sid)) {
203 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE);
204 }
205 if ((bits_remaining & SEC_STD_DELETE) &&
206 user_has_privileges(token, &se_restore)) {
207 bits_remaining &= ~SEC_STD_DELETE;
208 }
209
210 if (sd->dacl == NULL) {
211 goto done;
212 }
213
214 /* check each ace in turn. */
215 for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
216 struct security_ace *ace = &sd->dacl->aces[i];
217
218 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
219 continue;
220 }
221
222 if (!is_sid_in_token(token, &ace->trustee)) {
223 continue;
224 }
225
226 switch (ace->type) {
227 case SEC_ACE_TYPE_ACCESS_ALLOWED:
228 bits_remaining &= ~ace->access_mask;
229 break;
230 case SEC_ACE_TYPE_ACCESS_DENIED:
231 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
232 if (bits_remaining & ace->access_mask) {
233 return NT_STATUS_ACCESS_DENIED;
234 }
235 break;
236 default: /* Other ACE types not handled/supported */
237 break;
238 }
239 }
240
241done:
242 if (bits_remaining != 0) {
243 *access_granted = bits_remaining;
244 return NT_STATUS_ACCESS_DENIED;
245 }
246
247 return NT_STATUS_OK;
248}
249
250/*******************************************************************
251 samr_make_sam_obj_sd
252 ********************************************************************/
253
254NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
255{
256 DOM_SID adm_sid;
257 DOM_SID act_sid;
258
259 SEC_ACE ace[3];
260
261 SEC_ACL *psa = NULL;
262
263 sid_copy(&adm_sid, &global_sid_Builtin);
264 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
265
266 sid_copy(&act_sid, &global_sid_Builtin);
267 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
268
269 /*basic access for every one*/
270 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
271 GENERIC_RIGHTS_SAM_EXECUTE | GENERIC_RIGHTS_SAM_READ, 0);
272
273 /*full access for builtin aliases Administrators and Account Operators*/
274 init_sec_ace(&ace[1], &adm_sid,
275 SEC_ACE_TYPE_ACCESS_ALLOWED, GENERIC_RIGHTS_SAM_ALL_ACCESS, 0);
276 init_sec_ace(&ace[2], &act_sid,
277 SEC_ACE_TYPE_ACCESS_ALLOWED, GENERIC_RIGHTS_SAM_ALL_ACCESS, 0);
278
279 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
280 return NT_STATUS_NO_MEMORY;
281
282 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
283 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
284 psa, sd_size)) == NULL)
285 return NT_STATUS_NO_MEMORY;
286
287 return NT_STATUS_OK;
288}
Note: See TracBrowser for help on using the repository browser.