d9e3210a5c7b6cbbdb1f14b4311b0a506d12970b
[kai/samba.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, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 #include "includes.h"
22
23         /* When modifiying security filtering with gpmc.msc (on w2k3) the
24          * following ACE is created in the DACL:
25
26 ------- ACE (type: 0x05, flags: 0x02, size: 0x38, mask: 0x100, object flags: 0x1)
27 access SID: $SID 
28 access type: ALLOWED OBJECT
29 Permissions:
30         [Apply Group Policy] (0x00000100)
31
32 ------- ACE (type: 0x00, flags: 0x02, size: 0x24, mask: 0x20014)
33 access SID:  $SID
34 access type: ALLOWED
35 Permissions:
36         [List Contents] (0x00000004)
37         [Read All Properties] (0x00000010)
38         [Read Permissions] (0x00020000)
39
40          * by default all "Authenticated Users" (S-1-5-11) have an ALLOW
41          * OBJECT ace with SEC_RIGHTS_APPLY_GROUP_POLICY mask */
42
43
44 /****************************************************************
45 ****************************************************************/
46
47 static BOOL gpo_sd_check_agp_access_bits(uint32 access_mask)
48 {
49         return (access_mask & SEC_RIGHTS_APPLY_GROUP_POLICY);
50 }
51
52 #if 0
53 /****************************************************************
54 ****************************************************************/
55
56 static BOOL gpo_sd_check_read_access_bits(uint32 access_mask)
57 {
58         uint32 read_bits = SEC_RIGHTS_LIST_CONTENTS |
59                            SEC_RIGHTS_READ_ALL_PROP |
60                            SEC_RIGHTS_READ_PERMS;
61
62         return (read_bits == (access_mask & read_bits));
63 }
64 #endif
65
66 /****************************************************************
67 ****************************************************************/
68
69 static BOOL gpo_sd_check_trustee_in_sid_token(const DOM_SID *trustee, 
70                                               const struct GPO_SID_TOKEN *token)
71 {
72         int i;
73
74         if (sid_equal(trustee, &token->object_sid)) {
75                 return True;
76         }
77
78         if (sid_equal(trustee, &token->primary_group_sid)) {
79                 return True;
80         }
81
82         for (i = 0; i < token->num_token_sids; i++) {
83                 if (sid_equal(trustee, &token->token_sids[i])) {
84                         return True;
85                 }
86         }
87
88         return False;
89 }
90
91 /****************************************************************
92 ****************************************************************/
93
94 static NTSTATUS gpo_sd_check_ace_denied_object(const SEC_ACE *ace, 
95                                                const struct GPO_SID_TOKEN *token) 
96 {
97         if (gpo_sd_check_agp_access_bits(ace->access_mask) &&
98             gpo_sd_check_trustee_in_sid_token(&ace->trustee, token)) {
99                 DEBUG(10,("gpo_sd_check_ace_denied_object: Access denied as of ace for %s\n", 
100                         sid_string_static(&ace->trustee)));
101                 return NT_STATUS_ACCESS_DENIED;
102         }
103
104         return STATUS_MORE_ENTRIES;
105 }
106
107 /****************************************************************
108 ****************************************************************/
109
110 static NTSTATUS gpo_sd_check_ace_allowed_object(const SEC_ACE *ace, 
111                                                 const struct GPO_SID_TOKEN *token) 
112 {
113         if (gpo_sd_check_agp_access_bits(ace->access_mask) && 
114             gpo_sd_check_trustee_in_sid_token(&ace->trustee, token)) {
115                 DEBUG(10,("gpo_sd_check_ace_allowed_object: Access granted as of ace for %s\n", 
116                         sid_string_static(&ace->trustee)));
117                 return NT_STATUS_OK;
118         }
119
120         return STATUS_MORE_ENTRIES;
121 }
122
123 /****************************************************************
124 ****************************************************************/
125
126 static NTSTATUS gpo_sd_check_ace(const SEC_ACE *ace, 
127                                  const struct GPO_SID_TOKEN *token) 
128 {
129         switch (ace->type) {
130                 case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
131                         return gpo_sd_check_ace_denied_object(ace, token);
132                 case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
133                         return gpo_sd_check_ace_allowed_object(ace, token);
134                 default:
135                         return STATUS_MORE_ENTRIES;
136         }
137 }
138
139 /****************************************************************
140 ****************************************************************/
141
142 NTSTATUS gpo_apply_security_filtering(const struct GROUP_POLICY_OBJECT *gpo, 
143                                       const struct GPO_SID_TOKEN *token)
144 {
145         SEC_DESC *sd = gpo->security_descriptor;
146         SEC_ACL *dacl = NULL;
147         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
148         int i;
149
150         if (!token) {
151                 return NT_STATUS_INVALID_USER_BUFFER;
152         }
153
154         if (!sd) {
155                 return NT_STATUS_INVALID_SECURITY_DESCR;
156         }
157
158         dacl = sd->dacl;
159         if (!dacl) {
160                 return NT_STATUS_INVALID_SECURITY_DESCR;
161         }
162
163         /* check all aces and only return NT_STATUS_OK (== Access granted) or
164          * NT_STATUS_ACCESS_DENIED ( == Access denied) - the default is to
165          * deny access */
166
167         for (i = 0; i < dacl->num_aces; i ++) {
168
169                 status = gpo_sd_check_ace(&dacl->aces[i], token);
170
171                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
172                         return status;
173                 } else if (NT_STATUS_IS_OK(status)) {
174                         return status;
175                 }
176
177                 continue;
178         }
179
180         return NT_STATUS_ACCESS_DENIED;
181 }