dea0de33f93dde8fb55460e28b2ccdc141b9d9f8
[kai/samba.git] / source3 / libgpo / gpext / security.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  Group Policy Support
4  *  Copyright (C) Guenther Deschner 2005-2008
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 #include "../libgpo/gpo_ini.h"
22 #include "../libgpo/gpo.h"
23 #include "libgpo/gpo_proto.h"
24
25 #define GP_EXT_NAME "security"
26
27 #define GPTTMPL_UNIX_PATH  "Microsoft/Windows NT/SecEdit/GptTmpl.inf"
28
29 #define GPTTMPL_SECTION_UNICODE                 "Unicode"
30 #define GPTTMPL_SECTION_VERSION                 "Version"
31
32 #define GPTTMPL_SECTION_REGISTRY_VALUES         "Registry Values"
33 #define GPTTMPL_SECTION_SYSTEM_ACCESS           "System Access"
34 #define GPTTMPL_SECTION_KERBEROS_POLICY         "Kerberos Policy"
35 #define GPTTMPL_SECTION_EVENT_AUDIT             "Event Audit"
36 #define GPTTMPL_SECTION_PRIVILEGE_RIGHTS        "Privilege Rights"
37 #define GPTTMPL_SECTION_APPLICATION_LOG         "Application Log"
38 #define GPTTMPL_SECTION_SECURITY_LOG            "Security Log"
39 #define GPTTMPL_SECTION_SYSTEM_LOG              "System Log"
40 #define GPTTMPL_SECTION_GROUP_MEMBERSHIP        "Group Membership"
41 #define GPTTMPL_SECTION_FILE_SECURITY           "File Security"
42 #define GPTTMPL_SECTION_SERVICE_GENERAL_SETTING "Service General Setting"
43
44 static TALLOC_CTX *ctx = NULL;
45
46 struct gpttmpl_table {
47         const char *section;
48         const char *parameter;
49         enum winreg_Type type;
50 };
51
52 /****************************************************************
53  parse the Version section from gpttmpl file
54 ****************************************************************/
55
56 #define GPTTMPL_PARAMETER_REVISION "Revision"
57 #define GPTTMPL_PARAMETER_SIGNATURE "signature"
58 #define GPTTMPL_VALUE_CHICAGO "$CHICAGO$" /* whatever this is good for... */
59 #define GPTTMPL_PARAMETER_UNICODE "Unicode"
60
61 static NTSTATUS gpttmpl_parse_header(struct gp_inifile_context *ini_ctx,
62                                      uint32_t *version_out)
63 {
64         char *signature = NULL;
65         NTSTATUS result;
66         int version;
67         int is_unicode;
68
69         if (!ini_ctx) {
70                 return NT_STATUS_INVALID_PARAMETER;
71         }
72
73         result = gp_inifile_getstring(ini_ctx, GPTTMPL_SECTION_VERSION
74                         ":"GPTTMPL_PARAMETER_SIGNATURE, &signature);
75         if (!NT_STATUS_IS_OK(result)) {
76                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
77         }
78
79         if (!strequal(signature, GPTTMPL_VALUE_CHICAGO)) {
80                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
81         }
82         result = gp_inifile_getint(ini_ctx, GPTTMPL_SECTION_VERSION
83                         ":"GPTTMPL_PARAMETER_REVISION, &version);
84         if (!NT_STATUS_IS_OK(result)) {
85                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
86         }
87
88         if (version_out) {
89                 *version_out = version;
90         }
91
92         result = gp_inifile_getint(ini_ctx, GPTTMPL_SECTION_UNICODE
93                         ":"GPTTMPL_PARAMETER_UNICODE, &is_unicode);
94         if (!NT_STATUS_IS_OK(result) || !is_unicode) {
95                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
96         }
97
98         return NT_STATUS_OK;
99 }
100
101 /****************************************************************
102 ****************************************************************/
103
104 static NTSTATUS gpttmpl_init_context(TALLOC_CTX *mem_ctx,
105                                      uint32_t flags,
106                                      const char *unix_path,
107                                      struct gp_inifile_context **ini_ctx)
108 {
109         NTSTATUS status;
110         uint32_t version;
111         struct gp_inifile_context *tmp_ctx = NULL;
112
113         status = gp_inifile_init_context(mem_ctx, flags, unix_path,
114                                          GPTTMPL_UNIX_PATH, &tmp_ctx);
115         NT_STATUS_NOT_OK_RETURN(status);
116
117         status = gpttmpl_parse_header(tmp_ctx, &version);
118         if (!NT_STATUS_IS_OK(status)) {
119                 DEBUG(1,("gpttmpl_init_context: failed: %s\n",
120                         nt_errstr(status)));
121                 TALLOC_FREE(tmp_ctx);
122                 return status;
123         }
124
125         *ini_ctx = tmp_ctx;
126
127         return NT_STATUS_OK;
128 }
129
130 /****************************************************************
131 ****************************************************************/
132
133 static NTSTATUS gpttmpl_process(struct gp_inifile_context *ini_ctx,
134                                 struct registry_key *root_key,
135                                 uint32_t flags)
136 {
137         return NT_STATUS_OK;
138 }
139
140 /****************************************************************
141 ****************************************************************/
142
143 static NTSTATUS security_process_group_policy(ADS_STRUCT *ads,
144                                               TALLOC_CTX *mem_ctx,
145                                               uint32_t flags,
146                                               struct registry_key *root_key,
147                                               const struct security_token *token,
148                                               struct GROUP_POLICY_OBJECT *gpo,
149                                               const char *extension_guid,
150                                               const char *snapin_guid)
151 {
152         NTSTATUS status;
153         char *unix_path = NULL;
154         struct gp_inifile_context *ini_ctx = NULL;
155
156         debug_gpext_header(0, "security_process_group_policy", flags, gpo,
157                            extension_guid, snapin_guid);
158
159         /* this handler processes the gpttmpl files and merge output to the
160          * registry */
161
162         status = gpo_get_unix_path(mem_ctx, cache_path(GPO_CACHE_DIR), gpo, &unix_path);
163         if (!NT_STATUS_IS_OK(status)) {
164                 goto out;
165         }
166
167         status = gpttmpl_init_context(mem_ctx, flags, unix_path, &ini_ctx);
168         if (!NT_STATUS_IS_OK(status)) {
169                 goto out;
170         }
171
172         status = gpttmpl_process(ini_ctx, root_key, flags);
173         if (!NT_STATUS_IS_OK(status)) {
174                 goto out;
175         }
176
177  out:
178         if (!NT_STATUS_IS_OK(status)) {
179                 DEBUG(0,("security_process_group_policy: %s\n",
180                         nt_errstr(status)));
181         }
182         TALLOC_FREE(ini_ctx);
183
184         return status;
185 }
186
187 /****************************************************************
188 ****************************************************************/
189
190 static NTSTATUS security_get_reg_config(TALLOC_CTX *mem_ctx,
191                                         struct gp_extension_reg_info **reg_info)
192 {
193         NTSTATUS status;
194         struct gp_extension_reg_info *info = NULL;
195
196         struct gp_extension_reg_table table[] = {
197                 /* FIXME: how can we store the "(Default)" value ??? */
198                 /* { "", REG_SZ, "Security" }, */
199                 { "ProcessGroupPolicy", REG_SZ, "security_process_group_policy" },
200                 { "NoUserPolicy", REG_DWORD, "1" },
201                 { "ExtensionDebugLevel", REG_DWORD, "1" },
202                 { NULL, REG_NONE, NULL }
203         };
204
205         info = TALLOC_ZERO_P(mem_ctx, struct gp_extension_reg_info);
206         NT_STATUS_HAVE_NO_MEMORY(info);
207
208         status = gp_ext_info_add_entry(mem_ctx, GP_EXT_NAME,
209                                        GP_EXT_GUID_SECURITY,
210                                        table, info);
211         NT_STATUS_NOT_OK_RETURN(status);
212
213         *reg_info = info;
214
215         return NT_STATUS_OK;
216 }
217
218
219 /****************************************************************
220 ****************************************************************/
221
222 static NTSTATUS security_initialize(TALLOC_CTX *mem_ctx)
223 {
224         return NT_STATUS_OK;
225 }
226
227 /****************************************************************
228 ****************************************************************/
229
230 static NTSTATUS security_shutdown(void)
231 {
232         NTSTATUS status;
233
234         status = unregister_gp_extension(GP_EXT_NAME);
235         if (NT_STATUS_IS_OK(status)) {
236                 return status;
237         }
238
239         TALLOC_FREE(ctx);
240
241         return NT_STATUS_OK;
242 }
243
244 /****************************************************************
245 ****************************************************************/
246
247 static struct gp_extension_methods security_methods = {
248         .initialize             = security_initialize,
249         .process_group_policy   = security_process_group_policy,
250         .get_reg_config         = security_get_reg_config,
251         .shutdown               = security_shutdown
252 };
253
254 /****************************************************************
255 ****************************************************************/
256
257 NTSTATUS gpext_security_init(void)
258 {
259         NTSTATUS status;
260
261         ctx = talloc_init("gpext_security_init");
262         NT_STATUS_HAVE_NO_MEMORY(ctx);
263
264         status = register_gp_extension(ctx, SMB_GPEXT_INTERFACE_VERSION,
265                                        GP_EXT_NAME, GP_EXT_GUID_SECURITY,
266                                        &security_methods);
267         if (!NT_STATUS_IS_OK(status)) {
268                 TALLOC_FREE(ctx);
269         }
270
271         return status;
272 }