r23801: The FSF has moved around a lot. This fixes their Mass Ave address.
[bbaumbach/samba-autobuild/.git] / source3 / libgpo / gpo_sec.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  Group Policy Object Support
4  *  Copyright (C) Guenther Deschner 2007
5  *  
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "includes.h"
21
22         /* When modifiying security filtering with gpmc.msc (on w2k3) the
23          * following ACE is created in the DACL:
24
25 ------- ACE (type: 0x05, flags: 0x02, size: 0x38, mask: 0x100, object flags: 0x1)
26 access SID: $SID 
27 access type: ALLOWED OBJECT
28 Permissions:
29         [Apply Group Policy] (0x00000100)
30
31 ------- ACE (type: 0x00, flags: 0x02, size: 0x24, mask: 0x20014)
32 access SID:  $SID
33 access type: ALLOWED
34 Permissions:
35         [List Contents] (0x00000004)
36         [Read All Properties] (0x00000010)
37         [Read Permissions] (0x00020000)
38
39          * by default all "Authenticated Users" (S-1-5-11) have an ALLOW
40          * OBJECT ace with SEC_RIGHTS_APPLY_GROUP_POLICY mask */
41
42
43 /****************************************************************
44 ****************************************************************/
45
46 static BOOL gpo_sd_check_agp_access_bits(uint32 access_mask)
47 {
48         return (access_mask & SEC_RIGHTS_APPLY_GROUP_POLICY);
49 }
50
51 #if 0
52 /****************************************************************
53 ****************************************************************/
54
55 static BOOL gpo_sd_check_read_access_bits(uint32 access_mask)
56 {
57         uint32 read_bits = SEC_RIGHTS_LIST_CONTENTS |
58                            SEC_RIGHTS_READ_ALL_PROP |
59                            SEC_RIGHTS_READ_PERMS;
60
61         return (read_bits == (access_mask & read_bits));
62 }
63 #endif
64
65 /****************************************************************
66 ****************************************************************/
67
68 static BOOL gpo_sd_check_trustee_in_sid_token(const DOM_SID *trustee, 
69                                               const struct GPO_SID_TOKEN *token)
70 {
71         int i;
72
73         if (sid_equal(trustee, &token->object_sid)) {
74                 return True;
75         }
76
77         if (sid_equal(trustee, &token->primary_group_sid)) {
78                 return True;
79         }
80
81         for (i = 0; i < token->num_token_sids; i++) {
82                 if (sid_equal(trustee, &token->token_sids[i])) {
83                         return True;
84                 }
85         }
86
87         return False;
88 }
89
90 /****************************************************************
91 ****************************************************************/
92
93 static NTSTATUS gpo_sd_check_ace_denied_object(const SEC_ACE *ace, 
94                                                const struct GPO_SID_TOKEN *token) 
95 {
96         if (gpo_sd_check_agp_access_bits(ace->access_mask) &&
97             gpo_sd_check_trustee_in_sid_token(&ace->trustee, token)) {
98                 DEBUG(10,("gpo_sd_check_ace_denied_object: Access denied as of ace for %s\n", 
99                         sid_string_static(&ace->trustee)));
100                 return NT_STATUS_ACCESS_DENIED;
101         }
102
103         return STATUS_MORE_ENTRIES;
104 }
105
106 /****************************************************************
107 ****************************************************************/
108
109 static NTSTATUS gpo_sd_check_ace_allowed_object(const SEC_ACE *ace, 
110                                                 const struct GPO_SID_TOKEN *token) 
111 {
112         if (gpo_sd_check_agp_access_bits(ace->access_mask) && 
113             gpo_sd_check_trustee_in_sid_token(&ace->trustee, token)) {
114                 DEBUG(10,("gpo_sd_check_ace_allowed_object: Access granted as of ace for %s\n", 
115                         sid_string_static(&ace->trustee)));
116                 return NT_STATUS_OK;
117         }
118
119         return STATUS_MORE_ENTRIES;
120 }
121
122 /****************************************************************
123 ****************************************************************/
124
125 static NTSTATUS gpo_sd_check_ace(const SEC_ACE *ace, 
126                                  const struct GPO_SID_TOKEN *token) 
127 {
128         switch (ace->type) {
129                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
130                         return gpo_sd_check_ace_denied_object(ace, token);
131                 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
132                         return gpo_sd_check_ace_allowed_object(ace, token);
133                 default:
134                         return STATUS_MORE_ENTRIES;
135         }
136 }
137
138 /****************************************************************
139 ****************************************************************/
140
141 NTSTATUS gpo_apply_security_filtering(const struct GROUP_POLICY_OBJECT *gpo, 
142                                       const struct GPO_SID_TOKEN *token)
143 {
144         SEC_DESC *sd = gpo->security_descriptor;
145         SEC_ACL *dacl = NULL;
146         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
147         int i;
148
149         if (!token) {
150                 return NT_STATUS_INVALID_USER_BUFFER;
151         }
152
153         if (!sd) {
154                 return NT_STATUS_INVALID_SECURITY_DESCR;
155         }
156
157         dacl = sd->dacl;
158         if (!dacl) {
159                 return NT_STATUS_INVALID_SECURITY_DESCR;
160         }
161
162         /* check all aces and only return NT_STATUS_OK (== Access granted) or
163          * NT_STATUS_ACCESS_DENIED ( == Access denied) - the default is to
164          * deny access */
165
166         for (i = 0; i < dacl->num_aces; i ++) {
167
168                 status = gpo_sd_check_ace(&dacl->aces[i], token);
169
170                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
171                         return status;
172                 } else if (NT_STATUS_IS_OK(status)) {
173                         return status;
174                 }
175
176                 continue;
177         }
178
179         return NT_STATUS_ACCESS_DENIED;
180 }