Fix some nonempty blank lines
[Samba.git] / source / lib / util_seaccess.c
blobfdc10f20ab62568ba9c2f7eda49ea8a8e18f1752
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 | SEC_STD_DELETE;
116 } else if (user_has_privileges(token, &se_restore)) {
117 granted |= SEC_STD_DELETE;
120 if (sd->dacl == NULL) {
121 return granted & ~denied;
124 for (i = 0;i<sd->dacl->num_aces; i++) {
125 struct security_ace *ace = &sd->dacl->aces[i];
127 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
128 continue;
131 if (!is_sid_in_token(token, &ace->trustee)) {
132 continue;
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;
148 return granted & ~denied;
152 the main entry point for access checking.
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;
162 *access_granted = access_desired;
163 bits_remaining = access_desired;
165 /* handle the maximum allowed flag */
166 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
167 uint32_t orig_access_desired = access_desired;
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 & ~SEC_STD_DELETE;
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));
180 #if 0
181 /* We need to support SeSecurityPrivilege for this. */
183 if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
184 if (user_has_privileges(token, &sec_security)) {
185 bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
186 } else {
187 return NT_STATUS_PRIVILEGE_NOT_HELD;
190 #endif
192 /* a NULL dacl allows access */
193 if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
194 *access_granted = access_desired;
195 return NT_STATUS_OK;
198 /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */
199 if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) &&
200 is_sid_in_token(token, sd->owner_sid)) {
201 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE);
203 if ((bits_remaining & SEC_STD_DELETE) &&
204 user_has_privileges(token, &se_restore)) {
205 bits_remaining &= ~SEC_STD_DELETE;
208 if (sd->dacl == NULL) {
209 goto done;
212 /* check each ace in turn. */
213 for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
214 struct security_ace *ace = &sd->dacl->aces[i];
216 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
217 continue;
220 if (!is_sid_in_token(token, &ace->trustee)) {
221 continue;
224 switch (ace->type) {
225 case SEC_ACE_TYPE_ACCESS_ALLOWED:
226 bits_remaining &= ~ace->access_mask;
227 break;
228 case SEC_ACE_TYPE_ACCESS_DENIED:
229 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
230 if (bits_remaining & ace->access_mask) {
231 return NT_STATUS_ACCESS_DENIED;
233 break;
234 default: /* Other ACE types not handled/supported */
235 break;
239 done:
240 if (bits_remaining != 0) {
241 return NT_STATUS_ACCESS_DENIED;
244 return NT_STATUS_OK;
247 /*******************************************************************
248 samr_make_sam_obj_sd
249 ********************************************************************/
251 NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
253 DOM_SID adm_sid;
254 DOM_SID act_sid;
256 SEC_ACE ace[3];
258 SEC_ACL *psa = NULL;
260 sid_copy(&adm_sid, &global_sid_Builtin);
261 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
263 sid_copy(&act_sid, &global_sid_Builtin);
264 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
266 /*basic access for every one*/
267 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
268 GENERIC_RIGHTS_SAM_EXECUTE | GENERIC_RIGHTS_SAM_READ, 0);
270 /*full access for builtin aliases Administrators and Account Operators*/
271 init_sec_ace(&ace[1], &adm_sid,
272 SEC_ACE_TYPE_ACCESS_ALLOWED, GENERIC_RIGHTS_SAM_ALL_ACCESS, 0);
273 init_sec_ace(&ace[2], &act_sid,
274 SEC_ACE_TYPE_ACCESS_ALLOWED, GENERIC_RIGHTS_SAM_ALL_ACCESS, 0);
276 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
277 return NT_STATUS_NO_MEMORY;
279 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
280 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
281 psa, sd_size)) == NULL)
282 return NT_STATUS_NO_MEMORY;
284 return NT_STATUS_OK;