Fixes for various compile warnings on Solaris 8.
[abartlet/samba.git/.git] / source3 / lib / util_seaccess.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 2.0
4    Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
5    Copyright (C) Tim Potter 2000.
6
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.
11
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.
16
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.
20 */
21
22 #include "includes.h"
23 #include "nterr.h"
24 #include "sids.h"
25
26 extern int DEBUGLEVEL;
27
28 /* Process an access allowed ACE */
29
30 static BOOL ace_grant(uint32 mask, uint32 *acc_desired, uint32 *acc_granted)
31 {
32         uint32 matches;
33
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
36            mask. */ 
37
38         if (*acc_desired == SEC_RIGHTS_MAXIMUM_ALLOWED) {
39                 matches = mask;
40                 *acc_desired = mask;
41         } else {
42                 matches = mask & *acc_desired;
43         }
44
45         if (matches) {
46                 *acc_desired = *acc_desired & ~matches;
47                 *acc_granted = *acc_granted | matches;
48         }
49
50         return *acc_desired == 0;
51 }
52
53 /* Process an access denied ACE */
54
55 static BOOL ace_deny(uint32 mask, uint32 *acc_desired, uint32 *acc_granted)
56 {
57         uint32 matches;
58
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. */
61
62         if (*acc_desired == SEC_RIGHTS_MAXIMUM_ALLOWED) {
63                 matches = mask;
64         } else {
65                 matches = mask & *acc_desired;
66         }
67
68         if (matches) {
69                 *acc_desired = *acc_granted = 0;
70         }
71
72         return *acc_desired == 0;
73 }
74
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
78    accordingly. */
79
80 static BOOL check_ace(SEC_ACE *ace, BOOL is_owner, DOM_SID *sid, 
81                       uint32 *acc_desired, uint32 *acc_granted, 
82                       uint32 *status)
83 {
84         uint32 mask = ace->info.mask;
85
86         /* Inherit only is ignored */
87
88         if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
89                 return False;
90         }
91
92         /* Some debugging stuff */
93
94         if (DEBUGLEVEL >= 3) {
95                 fstring ace_sid_str, sid_str;
96                 fstring ace_name, ace_name_dom, name, name_dom;
97                 uint8 name_type;
98                 
99                 sid_to_string(sid_str, sid);
100                 sid_to_string(ace_sid_str, &ace->sid);
101
102                 if (!winbind_lookup_sid(sid, name_dom, name, &name_type)) {
103                         fstrcpy(name_dom, "UNKNOWN");
104                         fstrcpy(name, "UNKNOWN");
105                 }
106
107                 if (!winbind_lookup_sid(&ace->sid, ace_name_dom, ace_name, 
108                                         &name_type)) {
109                         fstrcpy(ace_name_dom, "UNKNOWN");
110                         fstrcpy(ace_name, "UNKNOWN");
111                 }
112
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));
122         }
123
124         /* Only owner allowed write-owner rights */
125
126         if (!is_owner) {
127                 mask &= (~SEC_RIGHTS_WRITE_OWNER);
128         }
129
130         /* Check the ACE value.  This updates the access_desired and
131            access_granted values appropriately. */
132
133         switch (ace->type) {
134
135                 /* Access allowed ACE */
136
137                 case SEC_ACE_TYPE_ACCESS_ALLOWED: {
138
139                         /* Everyone - or us */
140
141                         if (sid_equal(&ace->sid, global_sid_everyone) ||
142                             sid_equal(&ace->sid, sid)) {
143
144                                 /* Return true if access has been allowed */
145
146                                 if (ace_grant(mask, acc_desired, 
147                                               acc_granted)) {
148                                         *status = NT_STATUS_NO_PROBLEMO;
149                                         DEBUG(3, ("access granted\n"));
150                                         return True;
151                                 }
152                         }
153
154                         break;
155                 }
156
157                 /* Access denied ACE */
158
159                 case SEC_ACE_TYPE_ACCESS_DENIED: {
160
161                         /* Everyone - or us */
162
163                         if (sid_equal(&ace->sid, global_sid_everyone) ||
164                             sid_equal(&ace->sid, sid)) {
165                                 
166                                 /* Return false if access has been denied */
167
168                                 if (ace_deny(mask, acc_desired, 
169                                              acc_granted)) {
170                                         *status = NT_STATUS_ACCESS_DENIED;
171                                         DEBUG(3, ("access denied\n"));
172                                         return True;
173                                 }
174                         }
175
176                         break;
177                 }
178
179                 /* Unimplemented ACE types.  These are ignored. */
180
181                 case SEC_ACE_TYPE_SYSTEM_ALARM:
182                 case SEC_ACE_TYPE_SYSTEM_AUDIT: {
183                         *status = NT_STATUS_NOT_IMPLEMENTED;
184                         return False;
185                 }
186
187                 /* Unknown ACE type */
188
189                 default: {
190                         *status = NT_STATUS_INVALID_PARAMETER;
191                         return False;
192                 }
193         }
194
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. */
197
198         return False;
199 }
200
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. */ 
206
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)
210 {
211         DOM_SID user_sid, group_sid;
212         DOM_SID **group_sids = NULL;
213         int i, j;
214         uint ngroup_sids = 0;
215         SEC_ACL *acl;
216         uint8 check_ace_type;
217
218         if (!status || !acc_granted) return False;
219
220         *status = NT_STATUS_ACCESS_DENIED;
221         *acc_granted = 0;
222
223         /* No security descriptor allows all access */
224
225         if (!sd) {
226                 *status = NT_STATUS_NOPROBLEMO;
227                 *acc_granted = acc_desired;
228                 acc_desired = 0;
229
230                 goto done;
231         }
232
233         /* If desired access mask is empty then no access is allowed */
234
235         if (acc_desired == 0) {
236                 goto done;
237         }
238
239         /* We must know the owner sid */
240
241         if (sd->owner_sid == NULL) {
242                 DEBUG(1, ("no owner for security descriptor\n"));
243                 goto done;
244         }
245
246         /* Create user sid */
247
248         if (!winbind_uid_to_sid(uid, &user_sid)) {
249                 DEBUG(3, ("could not lookup sid for uid %d\n", uid));
250         }
251
252         /* If we're the owner, then we can do anything */
253
254         if (sid_equal(&user_sid, sd->owner_sid)) {
255                 *status = NT_STATUS_NOPROBLEMO;
256                 *acc_granted = acc_desired;
257                 acc_desired = 0;
258
259                 goto done;
260         }
261
262         /* Create group sid */
263
264         if (!winbind_gid_to_sid(gid, &group_sid)) {
265                 DEBUG(3, ("could not lookup sid for gid %d\n", gid));
266         }
267
268         /* Create array of group sids */
269
270         add_sid_to_array(&ngroup_sids, &group_sids, &group_sid);
271
272         for (i = 0; i < ngroups; i++) {
273                 if (groups[i] != gid) {
274                         if (winbind_gid_to_sid(groups[i], &group_sid)) {
275
276                                 /* If we're a group member then we can also
277                                    do anything */
278
279                                 if (sid_equal(&group_sid, sd->grp_sid)) {
280                                         *status = NT_STATUS_NOPROBLEMO;
281                                         *acc_granted = acc_desired;
282                                         acc_desired = 0;
283
284                                         goto done;
285                                 }
286
287                                 add_sid_to_array(&ngroup_sids, &group_sids, 
288                                                  &group_sid);
289                         } else {
290                                 DEBUG(3, ("could not lookup sid for gid %d\n", 
291                                           gid));
292                         }
293                 }
294         }
295
296         /* ACL must have something in it */
297
298         acl = sd->dacl;
299
300         if (acl == NULL || acl->ace == NULL || acl->num_aces == 0) {
301
302                 /* Checks against a NULL ACL succeed and return access
303                    granted = access requested. */
304
305                 *status = NT_STATUS_NOPROBLEMO;
306                 *acc_granted = acc_desired;
307                 acc_desired = 0;
308
309                 goto done;
310         }
311
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
318            MSDN. */
319
320         check_ace_type = SEC_ACE_TYPE_ACCESS_DENIED;
321
322     check_aces:
323
324         for (i = 0; i < acl->num_aces; i++) {
325                 SEC_ACE *ace = &acl->ace[i];
326                 BOOL is_group_owner;
327
328                 /* Check user sid */
329
330                 if (ace->type == check_ace_type &&
331                     check_ace(ace, False, &user_sid, &acc_desired,
332                               acc_granted, status)) {
333                         goto done;
334                 }
335
336                 /* Check group sids */
337
338                 for (j = 0; j < ngroup_sids; j++) {
339
340                         is_group_owner = sd->grp_sid ? 
341                                 sid_equal(group_sids[j], sd->grp_sid) : False;
342
343                         if (ace->type == check_ace_type &&
344                             check_ace(ace, is_group_owner, group_sids[j], 
345                                       &acc_desired, acc_granted, status)) {
346                                 goto done;
347                         }
348                 }
349         }
350
351         /* Check access allowed ACEs */
352
353         if (check_ace_type == SEC_ACE_TYPE_ACCESS_DENIED) {
354                 check_ace_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
355                 goto check_aces;
356         }
357
358  done:
359         free_sid_array(ngroup_sids, group_sids);
360         
361         /* If any access desired bits are still on, return access denied
362            and turn off any bits already granted. */
363
364         if (acc_desired) {
365                 *acc_granted = 0;
366                 *status = NT_STATUS_ACCESS_DENIED;
367         }
368
369         return *status == NT_STATUS_NOPROBLEMO;
370 }