2 Unix SMB/Netbios implementation.
4 Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
5 Copyright (C) Tim Potter 2000.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern int DEBUGLEVEL;
28 /* Process an access allowed ACE */
30 static BOOL ace_grant(uint32 mask, uint32 *acc_desired, uint32 *acc_granted)
34 /* If there are any matches in the ACE mask and desired access,
35 turn them off in the desired access and on in the granted
38 if (*acc_desired == SEC_RIGHTS_MAXIMUM_ALLOWED) {
42 matches = mask & *acc_desired;
46 *acc_desired = *acc_desired & ~matches;
47 *acc_granted = *acc_granted | matches;
50 return *acc_desired == 0;
53 /* Process an access denied ACE */
55 static BOOL ace_deny(uint32 mask, uint32 *acc_desired, uint32 *acc_granted)
59 /* If there are any matches in the ACE mask and the desired access,
60 all bits are turned off in the desired and granted mask. */
62 if (*acc_desired == SEC_RIGHTS_MAXIMUM_ALLOWED) {
65 matches = mask & *acc_desired;
69 *acc_desired = *acc_granted = 0;
72 return *acc_desired == 0;
75 /* Check an ACE against a SID. We return true if the ACE clears all the
76 permission bits in the access desired mask. This indicates that we have
77 make a decision to deny or allow access and the status is updated
80 static BOOL check_ace(SEC_ACE *ace, BOOL is_owner, DOM_SID *sid,
81 uint32 *acc_desired, uint32 *acc_granted,
84 uint32 mask = ace->info.mask;
86 /* Inherit only is ignored */
88 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
92 /* Some debugging stuff */
94 if (DEBUGLEVEL >= 3) {
95 fstring ace_sid_str, sid_str;
96 fstring ace_name, ace_name_dom, name, name_dom;
99 sid_to_string(sid_str, sid);
100 sid_to_string(ace_sid_str, &ace->sid);
102 if (!winbind_lookup_sid(sid, name_dom, name, &name_type)) {
103 fstrcpy(name_dom, "UNKNOWN");
104 fstrcpy(name, "UNKNOWN");
107 if (!winbind_lookup_sid(&ace->sid, ace_name_dom, ace_name,
109 fstrcpy(ace_name_dom, "UNKNOWN");
110 fstrcpy(ace_name, "UNKNOWN");
113 DEBUG(3, ("checking %s ACE sid %s (%s%s%s) mask 0x%08x "
114 "against sid %s (%s%s%s)\n",
115 (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) ?
116 "allowed" : ((ace->type ==
117 SEC_ACE_TYPE_ACCESS_DENIED) ?
118 "denied" : "unknown"),
119 ace_sid_str, ace_name_dom, lp_winbind_separator(),
120 ace_name, mask, sid_str, name_dom,
121 lp_winbind_separator(), name));
124 /* Only owner allowed write-owner rights */
127 mask &= (~SEC_RIGHTS_WRITE_OWNER);
130 /* Check the ACE value. This updates the access_desired and
131 access_granted values appropriately. */
135 /* Access allowed ACE */
137 case SEC_ACE_TYPE_ACCESS_ALLOWED: {
139 /* Everyone - or us */
141 if (sid_equal(&ace->sid, global_sid_everyone) ||
142 sid_equal(&ace->sid, sid)) {
144 /* Return true if access has been allowed */
146 if (ace_grant(mask, acc_desired,
148 *status = NT_STATUS_NO_PROBLEMO;
149 DEBUG(3, ("access granted\n"));
157 /* Access denied ACE */
159 case SEC_ACE_TYPE_ACCESS_DENIED: {
161 /* Everyone - or us */
163 if (sid_equal(&ace->sid, global_sid_everyone) ||
164 sid_equal(&ace->sid, sid)) {
166 /* Return false if access has been denied */
168 if (ace_deny(mask, acc_desired,
170 *status = NT_STATUS_ACCESS_DENIED;
171 DEBUG(3, ("access denied\n"));
179 /* Unimplemented ACE types. These are ignored. */
181 case SEC_ACE_TYPE_SYSTEM_ALARM:
182 case SEC_ACE_TYPE_SYSTEM_AUDIT: {
183 *status = NT_STATUS_NOT_IMPLEMENTED;
187 /* Unknown ACE type */
190 *status = NT_STATUS_INVALID_PARAMETER;
195 /* There are still some bits set in the access desired mask that
196 haven't been cleared by an ACE. More checking is required. */
201 /* Check access rights of a user against a security descriptor. Look at
202 each ACE in the security descriptor until an access denied ACE denies
203 any of the desired rights to the user or any of the users groups, or one
204 or more ACEs explicitly grant all requested access rights. See
205 "Access-Checking" document in MSDN. */
207 BOOL se_access_check(SEC_DESC *sd, uid_t uid, gid_t gid, int ngroups,
208 gid_t *groups, uint32 acc_desired,
209 uint32 *acc_granted, uint32 *status)
211 DOM_SID user_sid, group_sid;
212 DOM_SID **group_sids = NULL;
214 uint ngroup_sids = 0;
216 uint8 check_ace_type;
218 if (!status || !acc_granted) return False;
220 *status = NT_STATUS_ACCESS_DENIED;
223 /* No security descriptor allows all access */
226 *status = NT_STATUS_NOPROBLEMO;
227 *acc_granted = acc_desired;
233 /* If desired access mask is empty then no access is allowed */
235 if (acc_desired == 0) {
239 /* We must know the owner sid */
241 if (sd->owner_sid == NULL) {
242 DEBUG(1, ("no owner for security descriptor\n"));
246 /* Create user sid */
248 if (!winbind_uid_to_sid(uid, &user_sid)) {
249 DEBUG(3, ("could not lookup sid for uid %d\n", uid));
252 /* If we're the owner, then we can do anything */
254 if (sid_equal(&user_sid, sd->owner_sid)) {
255 *status = NT_STATUS_NOPROBLEMO;
256 *acc_granted = acc_desired;
262 /* Create group sid */
264 if (!winbind_gid_to_sid(gid, &group_sid)) {
265 DEBUG(3, ("could not lookup sid for gid %d\n", gid));
268 /* Create array of group sids */
270 add_sid_to_array(&ngroup_sids, &group_sids, &group_sid);
272 for (i = 0; i < ngroups; i++) {
273 if (groups[i] != gid) {
274 if (winbind_gid_to_sid(groups[i], &group_sid)) {
276 /* If we're a group member then we can also
279 if (sid_equal(&group_sid, sd->grp_sid)) {
280 *status = NT_STATUS_NOPROBLEMO;
281 *acc_granted = acc_desired;
287 add_sid_to_array(&ngroup_sids, &group_sids,
290 DEBUG(3, ("could not lookup sid for gid %d\n",
296 /* ACL must have something in it */
300 if (acl == NULL || acl->ace == NULL || acl->num_aces == 0) {
302 /* Checks against a NULL ACL succeed and return access
303 granted = access requested. */
305 *status = NT_STATUS_NOPROBLEMO;
306 *acc_granted = acc_desired;
312 /* Check each ACE in ACL. We break out of the loop if an ACE is
313 either explicitly denied or explicitly allowed by the
314 check_ace2() function. We also check the Access Denied ACEs
315 before Access allowed ones as the Platform SDK documentation is
316 unclear whether ACEs in a ACL are necessarily always in this
317 order. See the discussion on "Order of ACEs in a DACL" in
320 check_ace_type = SEC_ACE_TYPE_ACCESS_DENIED;
324 for (i = 0; i < acl->num_aces; i++) {
325 SEC_ACE *ace = &acl->ace[i];
330 if (ace->type == check_ace_type &&
331 check_ace(ace, False, &user_sid, &acc_desired,
332 acc_granted, status)) {
336 /* Check group sids */
338 for (j = 0; j < ngroup_sids; j++) {
340 is_group_owner = sd->grp_sid ?
341 sid_equal(group_sids[j], sd->grp_sid) : False;
343 if (ace->type == check_ace_type &&
344 check_ace(ace, is_group_owner, group_sids[j],
345 &acc_desired, acc_granted, status)) {
351 /* Check access allowed ACEs */
353 if (check_ace_type == SEC_ACE_TYPE_ACCESS_DENIED) {
354 check_ace_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
359 free_sid_array(ngroup_sids, group_sids);
361 /* If any access desired bits are still on, return access denied
362 and turn off any bits already granted. */
366 *status = NT_STATUS_ACCESS_DENIED;
369 return *status == NT_STATUS_NOPROBLEMO;