r23792: convert Samba4 to GPLv3
[kai/samba-autobuild/.git] / source4 / libcli / security / access_check.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    security access checking routines
5
6    Copyright (C) Andrew Tridgell 2004
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "libcli/security/security.h"
24
25
26 /*
27   perform a SEC_FLAG_MAXIMUM_ALLOWED access check
28 */
29 static uint32_t access_check_max_allowed(const struct security_descriptor *sd, 
30                                          const struct security_token *token)
31 {
32         uint32_t denied = 0, granted = 0;
33         unsigned i;
34         
35         if (security_token_has_sid(token, sd->owner_sid)) {
36                 granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE;
37         } else if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
38                 granted |= SEC_STD_DELETE;
39         }
40
41         for (i = 0;i<sd->dacl->num_aces; i++) {
42                 struct security_ace *ace = &sd->dacl->aces[i];
43
44                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
45                         continue;
46                 }
47
48                 if (!security_token_has_sid(token, &ace->trustee)) {
49                         continue;
50                 }
51
52                 switch (ace->type) {
53                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
54                         granted |= ace->access_mask;
55                         break;
56                 case SEC_ACE_TYPE_ACCESS_DENIED:
57                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
58                         denied |= ace->access_mask;
59                         break;
60                 default:        /* Other ACE types not handled/supported */
61                         break;
62                 }
63         }
64
65         return granted & ~denied;
66 }
67
68 /*
69   the main entry point for access checking. 
70 */
71 NTSTATUS sec_access_check(const struct security_descriptor *sd, 
72                           const struct security_token *token,
73                           uint32_t access_desired,
74                           uint32_t *access_granted)
75 {
76         int i;
77         uint32_t bits_remaining;
78
79         *access_granted = access_desired;
80         bits_remaining = access_desired;
81
82         /* handle the maximum allowed flag */
83         if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
84                 access_desired |= access_check_max_allowed(sd, token);
85                 access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
86                 *access_granted = access_desired;
87                 bits_remaining = access_desired & ~SEC_STD_DELETE;
88         }
89
90         if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
91                 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
92                         bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
93                 } else {
94                         return NT_STATUS_PRIVILEGE_NOT_HELD;
95                 }
96         }
97
98         /* dacl not present allows access */
99         if (!(sd->type & SEC_DESC_DACL_PRESENT)) {
100                 *access_granted = access_desired;
101                 return NT_STATUS_OK;
102         }
103
104         /* empty dacl denies access */
105         if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
106                 return NT_STATUS_ACCESS_DENIED;
107         }
108
109         /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */
110         if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) &&
111             security_token_has_sid(token, sd->owner_sid)) {
112                 bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE);
113         }
114         if ((bits_remaining & SEC_STD_DELETE) &&
115             security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
116                 bits_remaining &= ~SEC_STD_DELETE;
117         }
118
119         /* check each ace in turn. */
120         for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
121                 struct security_ace *ace = &sd->dacl->aces[i];
122
123                 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
124                         continue;
125                 }
126
127                 if (!security_token_has_sid(token, &ace->trustee)) {
128                         continue;
129                 }
130
131                 switch (ace->type) {
132                 case SEC_ACE_TYPE_ACCESS_ALLOWED:
133                         bits_remaining &= ~ace->access_mask;
134                         break;
135                 case SEC_ACE_TYPE_ACCESS_DENIED:
136                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
137                         if (bits_remaining & ace->access_mask) {
138                                 return NT_STATUS_ACCESS_DENIED;
139                         }
140                         break;
141                 default:        /* Other ACE types not handled/supported */
142                         break;
143                 }
144         }
145
146         if (bits_remaining != 0) {
147                 return NT_STATUS_ACCESS_DENIED;
148         }
149
150         return NT_STATUS_OK;
151 }