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