Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * Group Policy Object Support
4 : * Copyright (C) Guenther Deschner 2007-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.h"
22 : #include "libgpo/gpo_proto.h"
23 : #include "registry.h"
24 : #include "registry/reg_api.h"
25 : #include "registry/reg_backend_db.h"
26 : #include "registry/reg_api_util.h"
27 : #include "registry/reg_init_basic.h"
28 : #include "../libcli/security/security.h"
29 : #include "libcli/security/dom_sid.h"
30 : #include "../libcli/registry/util_reg.h"
31 :
32 :
33 : /****************************************************************
34 : ****************************************************************/
35 :
36 0 : struct security_token *registry_create_system_token(TALLOC_CTX *mem_ctx)
37 : {
38 0 : struct security_token *token = NULL;
39 :
40 0 : token = talloc_zero(mem_ctx, struct security_token);
41 0 : if (!token) {
42 0 : DEBUG(1,("talloc failed\n"));
43 0 : return NULL;
44 : }
45 :
46 0 : token->privilege_mask = SE_ALL_PRIVS;
47 :
48 0 : if (!NT_STATUS_IS_OK(add_sid_to_array(token, &global_sid_System,
49 : &token->sids, &token->num_sids))) {
50 0 : DEBUG(1,("Error adding nt-authority system sid to token\n"));
51 0 : return NULL;
52 : }
53 :
54 0 : return token;
55 : }
56 :
57 : /****************************************************************
58 : ****************************************************************/
59 :
60 0 : WERROR gp_init_reg_ctx(TALLOC_CTX *mem_ctx,
61 : const char *initial_path,
62 : uint32_t desired_access,
63 : const struct security_token *token,
64 : struct gp_registry_context **reg_ctx)
65 : {
66 : struct gp_registry_context *tmp_ctx;
67 : WERROR werr;
68 :
69 0 : if (!reg_ctx) {
70 0 : return WERR_INVALID_PARAMETER;
71 : }
72 :
73 0 : werr = registry_init_basic();
74 0 : if (!W_ERROR_IS_OK(werr)) {
75 0 : return werr;
76 : }
77 :
78 0 : tmp_ctx = talloc_zero(mem_ctx, struct gp_registry_context);
79 0 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
80 :
81 0 : if (token) {
82 0 : tmp_ctx->token = token;
83 : } else {
84 0 : tmp_ctx->token = registry_create_system_token(mem_ctx);
85 : }
86 0 : if (!tmp_ctx->token) {
87 0 : TALLOC_FREE(tmp_ctx);
88 0 : return WERR_NOT_ENOUGH_MEMORY;
89 : }
90 :
91 0 : werr = regdb_open();
92 0 : if (!W_ERROR_IS_OK(werr)) {
93 0 : return werr;
94 : }
95 :
96 0 : if (initial_path) {
97 0 : tmp_ctx->path = talloc_strdup(mem_ctx, initial_path);
98 0 : if (!tmp_ctx->path) {
99 0 : TALLOC_FREE(tmp_ctx);
100 0 : return WERR_NOT_ENOUGH_MEMORY;
101 : }
102 :
103 0 : werr = reg_open_path(mem_ctx, tmp_ctx->path, desired_access,
104 : tmp_ctx->token, &tmp_ctx->curr_key);
105 0 : if (!W_ERROR_IS_OK(werr)) {
106 0 : TALLOC_FREE(tmp_ctx);
107 0 : return werr;
108 : }
109 : }
110 :
111 0 : *reg_ctx = tmp_ctx;
112 :
113 0 : return WERR_OK;
114 : }
115 :
116 : /****************************************************************
117 : ****************************************************************/
118 :
119 0 : void gp_free_reg_ctx(struct gp_registry_context *reg_ctx)
120 : {
121 0 : TALLOC_FREE(reg_ctx);
122 0 : }
123 :
124 : /****************************************************************
125 : ****************************************************************/
126 :
127 0 : WERROR gp_store_reg_subkey(TALLOC_CTX *mem_ctx,
128 : const char *subkeyname,
129 : struct registry_key *curr_key,
130 : struct registry_key **new_key)
131 : {
132 0 : enum winreg_CreateAction action = REG_ACTION_NONE;
133 : WERROR werr;
134 :
135 0 : werr = reg_createkey(mem_ctx, curr_key, subkeyname,
136 : REG_KEY_WRITE, new_key, &action);
137 0 : if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
138 0 : return WERR_OK;
139 : }
140 :
141 0 : return werr;
142 : }
143 :
144 : /****************************************************************
145 : ****************************************************************/
146 :
147 0 : WERROR gp_read_reg_subkey(TALLOC_CTX *mem_ctx,
148 : struct gp_registry_context *reg_ctx,
149 : const char *subkeyname,
150 : struct registry_key **key)
151 : {
152 0 : const char *tmp = NULL;
153 :
154 0 : if (!reg_ctx || !subkeyname || !key) {
155 0 : return WERR_INVALID_PARAMETER;
156 : }
157 :
158 0 : tmp = talloc_asprintf(mem_ctx, "%s\\%s", reg_ctx->path, subkeyname);
159 0 : W_ERROR_HAVE_NO_MEMORY(tmp);
160 :
161 0 : return reg_open_path(mem_ctx, tmp, REG_KEY_READ,
162 : reg_ctx->token, key);
163 : }
164 :
165 : /****************************************************************
166 : ****************************************************************/
167 :
168 0 : WERROR gp_store_reg_val_sz(TALLOC_CTX *mem_ctx,
169 : struct registry_key *key,
170 : const char *val_name,
171 : const char *val)
172 : {
173 : struct registry_value reg_val;
174 :
175 0 : reg_val.type = REG_SZ;
176 0 : if (!push_reg_sz(mem_ctx, ®_val.data, val)) {
177 0 : return WERR_NOT_ENOUGH_MEMORY;
178 : }
179 :
180 0 : return reg_setvalue(key, val_name, ®_val);
181 : }
182 :
183 : /****************************************************************
184 : ****************************************************************/
185 :
186 0 : static WERROR gp_store_reg_val_dword(TALLOC_CTX *mem_ctx,
187 : struct registry_key *key,
188 : const char *val_name,
189 : uint32_t val)
190 : {
191 : struct registry_value reg_val;
192 :
193 0 : reg_val.type = REG_DWORD;
194 0 : reg_val.data = data_blob_talloc(mem_ctx, NULL, 4);
195 0 : SIVAL(reg_val.data.data, 0, val);
196 :
197 0 : return reg_setvalue(key, val_name, ®_val);
198 : }
199 :
200 : /****************************************************************
201 : ****************************************************************/
202 :
203 0 : WERROR gp_read_reg_val_sz(TALLOC_CTX *mem_ctx,
204 : struct registry_key *key,
205 : const char *val_name,
206 : const char **val)
207 : {
208 : WERROR werr;
209 0 : struct registry_value *reg_val = NULL;
210 :
211 0 : werr = reg_queryvalue(mem_ctx, key, val_name, ®_val);
212 0 : W_ERROR_NOT_OK_RETURN(werr);
213 :
214 0 : if (reg_val->type != REG_SZ) {
215 0 : return WERR_INVALID_DATATYPE;
216 : }
217 :
218 0 : if (!pull_reg_sz(mem_ctx, ®_val->data, val)) {
219 0 : return WERR_NOT_ENOUGH_MEMORY;
220 : }
221 :
222 0 : return WERR_OK;
223 : }
224 :
225 : /****************************************************************
226 : ****************************************************************/
227 :
228 0 : static WERROR gp_read_reg_val_dword(TALLOC_CTX *mem_ctx,
229 : struct registry_key *key,
230 : const char *val_name,
231 : uint32_t *val)
232 : {
233 : WERROR werr;
234 0 : struct registry_value *reg_val = NULL;
235 :
236 0 : werr = reg_queryvalue(mem_ctx, key, val_name, ®_val);
237 0 : W_ERROR_NOT_OK_RETURN(werr);
238 :
239 0 : if (reg_val->type != REG_DWORD) {
240 0 : return WERR_INVALID_DATATYPE;
241 : }
242 :
243 0 : if (reg_val->data.length < 4) {
244 0 : return WERR_INSUFFICIENT_BUFFER;
245 : }
246 0 : *val = IVAL(reg_val->data.data, 0);
247 :
248 0 : return WERR_OK;
249 : }
250 :
251 : /****************************************************************
252 : ****************************************************************/
253 :
254 0 : static WERROR gp_store_reg_gpovals(TALLOC_CTX *mem_ctx,
255 : struct registry_key *key,
256 : struct GROUP_POLICY_OBJECT *gpo)
257 : {
258 : WERROR werr;
259 :
260 0 : if (!key || !gpo) {
261 0 : return WERR_INVALID_PARAMETER;
262 : }
263 :
264 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "Version",
265 : gpo->version);
266 0 : W_ERROR_NOT_OK_RETURN(werr);
267 :
268 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "WQLFilterPass",
269 : true); /* fake */
270 0 : W_ERROR_NOT_OK_RETURN(werr);
271 :
272 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "AccessDenied",
273 : false); /* fake */
274 0 : W_ERROR_NOT_OK_RETURN(werr);
275 :
276 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "GPO-Disabled",
277 0 : (gpo->options & GPO_FLAG_DISABLE));
278 0 : W_ERROR_NOT_OK_RETURN(werr);
279 :
280 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "Options",
281 : gpo->options);
282 0 : W_ERROR_NOT_OK_RETURN(werr);
283 :
284 0 : werr = gp_store_reg_val_sz(mem_ctx, key, "GPOID",
285 : gpo->name);
286 0 : W_ERROR_NOT_OK_RETURN(werr);
287 :
288 0 : werr = gp_store_reg_val_sz(mem_ctx, key, "SOM",
289 0 : gpo->link ? gpo->link : "");
290 0 : W_ERROR_NOT_OK_RETURN(werr);
291 :
292 0 : werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
293 : gpo->display_name);
294 0 : W_ERROR_NOT_OK_RETURN(werr);
295 :
296 0 : werr = gp_store_reg_val_sz(mem_ctx, key, "WQL-Id",
297 : "");
298 0 : W_ERROR_NOT_OK_RETURN(werr);
299 :
300 0 : return werr;
301 : }
302 :
303 : /****************************************************************
304 : ****************************************************************/
305 :
306 0 : static const char *gp_reg_groupmembership_path(TALLOC_CTX *mem_ctx,
307 : const struct dom_sid *sid,
308 : uint32_t flags)
309 : {
310 : struct dom_sid_buf sidbuf;
311 :
312 0 : if (flags & GPO_LIST_FLAG_MACHINE) {
313 0 : return "GroupMembership";
314 : }
315 :
316 0 : return talloc_asprintf(
317 : mem_ctx,
318 : "%s\\%s",
319 : dom_sid_str_buf(sid, &sidbuf),
320 : "GroupMembership");
321 : }
322 :
323 : /****************************************************************
324 : ****************************************************************/
325 :
326 0 : static WERROR gp_reg_del_groupmembership(TALLOC_CTX *mem_ctx,
327 : struct registry_key *key,
328 : const struct security_token *token,
329 : uint32_t flags)
330 : {
331 0 : const char *path = NULL;
332 :
333 0 : path = gp_reg_groupmembership_path(mem_ctx, &token->sids[0],
334 : flags);
335 0 : W_ERROR_HAVE_NO_MEMORY(path);
336 :
337 0 : return reg_deletekey_recursive(key, path);
338 :
339 : }
340 :
341 : /****************************************************************
342 : ****************************************************************/
343 :
344 0 : static WERROR gp_reg_store_groupmembership(TALLOC_CTX *mem_ctx,
345 : struct gp_registry_context *reg_ctx,
346 : const struct security_token *token,
347 : uint32_t flags)
348 : {
349 0 : struct registry_key *key = NULL;
350 : WERROR werr;
351 0 : uint32_t i = 0;
352 0 : const char *valname = NULL;
353 0 : const char *path = NULL;
354 0 : int count = 0;
355 :
356 0 : path = gp_reg_groupmembership_path(mem_ctx, &token->sids[0],
357 : flags);
358 0 : W_ERROR_HAVE_NO_MEMORY(path);
359 :
360 0 : gp_reg_del_groupmembership(mem_ctx, reg_ctx->curr_key, token, flags);
361 :
362 0 : werr = gp_store_reg_subkey(mem_ctx, path,
363 : reg_ctx->curr_key, &key);
364 0 : W_ERROR_NOT_OK_RETURN(werr);
365 :
366 0 : for (i=0; i<token->num_sids; i++) {
367 : struct dom_sid_buf buf;
368 :
369 0 : valname = talloc_asprintf(mem_ctx, "Group%d", count++);
370 0 : W_ERROR_HAVE_NO_MEMORY(valname);
371 :
372 0 : werr = gp_store_reg_val_sz(
373 : mem_ctx,
374 : key,
375 : valname,
376 0 : dom_sid_str_buf(&token->sids[i], &buf));
377 0 : W_ERROR_NOT_OK_RETURN(werr);
378 : }
379 :
380 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "Count", count);
381 0 : W_ERROR_NOT_OK_RETURN(werr);
382 :
383 0 : return WERR_OK;
384 : }
385 :
386 : /****************************************************************
387 : ****************************************************************/
388 : #if 0
389 : /* not used yet */
390 : static WERROR gp_reg_read_groupmembership(TALLOC_CTX *mem_ctx,
391 : struct gp_registry_context *reg_ctx,
392 : const struct dom_sid *object_sid,
393 : struct security_token **token,
394 : uint32_t flags)
395 : {
396 : struct registry_key *key = NULL;
397 : WERROR werr;
398 : int i = 0;
399 : const char *valname = NULL;
400 : const char *val = NULL;
401 : const char *path = NULL;
402 : uint32_t count = 0;
403 : int num_token_sids = 0;
404 : struct security_token *tmp_token = NULL;
405 :
406 : tmp_token = talloc_zero(mem_ctx, struct security_token);
407 : W_ERROR_HAVE_NO_MEMORY(tmp_token);
408 :
409 : path = gp_reg_groupmembership_path(mem_ctx, object_sid, flags);
410 : W_ERROR_HAVE_NO_MEMORY(path);
411 :
412 : werr = gp_read_reg_subkey(mem_ctx, reg_ctx, path, &key);
413 : W_ERROR_NOT_OK_RETURN(werr);
414 :
415 : werr = gp_read_reg_val_dword(mem_ctx, key, "Count", &count);
416 : W_ERROR_NOT_OK_RETURN(werr);
417 :
418 : for (i=0; i<count; i++) {
419 :
420 : valname = talloc_asprintf(mem_ctx, "Group%d", i);
421 : W_ERROR_HAVE_NO_MEMORY(valname);
422 :
423 : werr = gp_read_reg_val_sz(mem_ctx, key, valname, &val);
424 : W_ERROR_NOT_OK_RETURN(werr);
425 :
426 : if (!string_to_sid(&tmp_token->sids[num_token_sids++],
427 : val)) {
428 : return WERR_INSUFFICIENT_BUFFER;
429 : }
430 : }
431 :
432 : tmp_token->num_sids = num_token_sids;
433 :
434 : *token = tmp_token;
435 :
436 : return WERR_OK;
437 : }
438 : #endif
439 : /****************************************************************
440 : ****************************************************************/
441 :
442 0 : static const char *gp_req_state_path(TALLOC_CTX *mem_ctx,
443 : const struct dom_sid *sid,
444 : uint32_t flags)
445 : {
446 : struct dom_sid_buf sidbuf;
447 :
448 0 : if (flags & GPO_LIST_FLAG_MACHINE) {
449 0 : return GPO_REG_STATE_MACHINE;
450 : }
451 :
452 0 : return talloc_asprintf(
453 : mem_ctx,
454 : "%s\\%s",
455 : "State",
456 : dom_sid_str_buf(sid, &sidbuf));
457 : }
458 :
459 : /****************************************************************
460 : ****************************************************************/
461 :
462 0 : static WERROR gp_del_reg_state(TALLOC_CTX *mem_ctx,
463 : struct registry_key *key,
464 : const char *path)
465 : {
466 0 : return reg_deletesubkeys_recursive(key, path);
467 : }
468 :
469 : /****************************************************************
470 : ****************************************************************/
471 :
472 0 : WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx,
473 : uint32_t flags,
474 : const char *dn,
475 : const struct security_token *token,
476 : struct GROUP_POLICY_OBJECT *gpo_list)
477 : {
478 0 : struct gp_registry_context *reg_ctx = NULL;
479 0 : WERROR werr = WERR_GEN_FAILURE;
480 0 : const char *subkeyname = NULL;
481 : struct GROUP_POLICY_OBJECT *gpo;
482 0 : int count = 0;
483 : struct registry_key *key;
484 :
485 0 : werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE,
486 : token, ®_ctx);
487 0 : W_ERROR_NOT_OK_RETURN(werr);
488 :
489 0 : werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key,
490 0 : &token->sids[0]);
491 0 : if (!W_ERROR_IS_OK(werr)) {
492 0 : DEBUG(0,("failed to secure key: %s\n", win_errstr(werr)));
493 0 : goto done;
494 : }
495 :
496 0 : werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags);
497 0 : if (!W_ERROR_IS_OK(werr)) {
498 0 : DEBUG(0,("failed to store group membership: %s\n", win_errstr(werr)));
499 0 : goto done;
500 : }
501 :
502 0 : subkeyname = gp_req_state_path(mem_ctx, &token->sids[0], flags);
503 0 : if (!subkeyname) {
504 0 : werr = WERR_NOT_ENOUGH_MEMORY;
505 0 : goto done;
506 : }
507 :
508 0 : werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname);
509 0 : if (!W_ERROR_IS_OK(werr)) {
510 0 : DEBUG(0,("failed to delete old state: %s\n", win_errstr(werr)));
511 : /* goto done; */
512 : }
513 :
514 0 : werr = gp_store_reg_subkey(mem_ctx, subkeyname,
515 0 : reg_ctx->curr_key, ®_ctx->curr_key);
516 0 : if (!W_ERROR_IS_OK(werr)) {
517 0 : goto done;
518 : }
519 :
520 0 : werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key,
521 : "Distinguished-Name", dn);
522 0 : if (!W_ERROR_IS_OK(werr)) {
523 0 : goto done;
524 : }
525 :
526 : /* store link list */
527 :
528 0 : werr = gp_store_reg_subkey(mem_ctx, "GPLink-List",
529 0 : reg_ctx->curr_key, &key);
530 0 : if (!W_ERROR_IS_OK(werr)) {
531 0 : goto done;
532 : }
533 :
534 : /* store gpo list */
535 :
536 0 : werr = gp_store_reg_subkey(mem_ctx, "GPO-List",
537 0 : reg_ctx->curr_key, ®_ctx->curr_key);
538 0 : if (!W_ERROR_IS_OK(werr)) {
539 0 : goto done;
540 : }
541 :
542 0 : for (gpo = gpo_list; gpo; gpo = gpo->next) {
543 :
544 0 : subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
545 0 : if (!subkeyname) {
546 0 : werr = WERR_NOT_ENOUGH_MEMORY;
547 0 : goto done;
548 : }
549 :
550 0 : werr = gp_store_reg_subkey(mem_ctx, subkeyname,
551 0 : reg_ctx->curr_key, &key);
552 0 : if (!W_ERROR_IS_OK(werr)) {
553 0 : goto done;
554 : }
555 :
556 0 : werr = gp_store_reg_gpovals(mem_ctx, key, gpo);
557 0 : if (!W_ERROR_IS_OK(werr)) {
558 0 : DEBUG(0,("gp_reg_state_store: "
559 : "gp_store_reg_gpovals failed for %s: %s\n",
560 : gpo->display_name, win_errstr(werr)));
561 0 : goto done;
562 : }
563 : }
564 0 : done:
565 0 : gp_free_reg_ctx(reg_ctx);
566 0 : return werr;
567 : }
568 :
569 : /****************************************************************
570 : ****************************************************************/
571 :
572 0 : static WERROR gp_read_reg_gpovals(TALLOC_CTX *mem_ctx,
573 : struct registry_key *key,
574 : struct GROUP_POLICY_OBJECT *gpo)
575 : {
576 : WERROR werr;
577 :
578 0 : if (!key || !gpo) {
579 0 : return WERR_INVALID_PARAMETER;
580 : }
581 :
582 0 : werr = gp_read_reg_val_dword(mem_ctx, key, "Version",
583 : &gpo->version);
584 0 : W_ERROR_NOT_OK_RETURN(werr);
585 :
586 0 : werr = gp_read_reg_val_dword(mem_ctx, key, "Options",
587 : &gpo->options);
588 0 : W_ERROR_NOT_OK_RETURN(werr);
589 :
590 0 : werr = gp_read_reg_val_sz(mem_ctx, key, "GPOID",
591 : &gpo->name);
592 0 : W_ERROR_NOT_OK_RETURN(werr);
593 :
594 0 : werr = gp_read_reg_val_sz(mem_ctx, key, "SOM",
595 : &gpo->link);
596 0 : W_ERROR_NOT_OK_RETURN(werr);
597 :
598 0 : werr = gp_read_reg_val_sz(mem_ctx, key, "DisplayName",
599 : &gpo->display_name);
600 0 : W_ERROR_NOT_OK_RETURN(werr);
601 :
602 0 : return werr;
603 : }
604 :
605 : /****************************************************************
606 : ****************************************************************/
607 :
608 0 : static WERROR gp_read_reg_gpo(TALLOC_CTX *mem_ctx,
609 : struct registry_key *key,
610 : struct GROUP_POLICY_OBJECT **gpo_ret)
611 : {
612 0 : struct GROUP_POLICY_OBJECT *gpo = NULL;
613 : WERROR werr;
614 :
615 0 : if (!gpo_ret || !key) {
616 0 : return WERR_INVALID_PARAMETER;
617 : }
618 :
619 0 : gpo = talloc_zero(mem_ctx, struct GROUP_POLICY_OBJECT);
620 0 : W_ERROR_HAVE_NO_MEMORY(gpo);
621 :
622 0 : werr = gp_read_reg_gpovals(mem_ctx, key, gpo);
623 0 : W_ERROR_NOT_OK_RETURN(werr);
624 :
625 0 : *gpo_ret = gpo;
626 :
627 0 : return werr;
628 : }
629 :
630 : /****************************************************************
631 : ****************************************************************/
632 :
633 0 : WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx,
634 : uint32_t flags,
635 : const struct dom_sid *sid,
636 : struct GROUP_POLICY_OBJECT **gpo_list)
637 : {
638 0 : struct gp_registry_context *reg_ctx = NULL;
639 0 : WERROR werr = WERR_GEN_FAILURE;
640 0 : const char *subkeyname = NULL;
641 0 : struct GROUP_POLICY_OBJECT *gpo = NULL;
642 0 : int count = 0;
643 0 : struct registry_key *key = NULL;
644 0 : const char *path = NULL;
645 0 : const char *gp_state_path = NULL;
646 :
647 0 : if (!gpo_list) {
648 0 : return WERR_INVALID_PARAMETER;
649 : }
650 :
651 0 : ZERO_STRUCTP(gpo_list);
652 :
653 0 : gp_state_path = gp_req_state_path(mem_ctx, sid, flags);
654 0 : if (!gp_state_path) {
655 0 : werr = WERR_NOT_ENOUGH_MEMORY;
656 0 : goto done;
657 : }
658 :
659 0 : path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
660 : KEY_GROUP_POLICY,
661 : gp_state_path,
662 : "GPO-List");
663 0 : if (!path) {
664 0 : werr = WERR_NOT_ENOUGH_MEMORY;
665 0 : goto done;
666 : }
667 :
668 0 : werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, ®_ctx);
669 0 : if (!W_ERROR_IS_OK(werr)) {
670 0 : goto done;
671 : }
672 :
673 : while (1) {
674 :
675 0 : subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
676 0 : if (!subkeyname) {
677 0 : werr = WERR_NOT_ENOUGH_MEMORY;
678 0 : goto done;
679 : }
680 :
681 0 : werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key);
682 0 : if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
683 0 : werr = WERR_OK;
684 0 : break;
685 : }
686 0 : if (!W_ERROR_IS_OK(werr)) {
687 0 : DEBUG(0,("gp_reg_state_read: "
688 : "gp_read_reg_subkey gave: %s\n",
689 : win_errstr(werr)));
690 0 : goto done;
691 : }
692 :
693 0 : werr = gp_read_reg_gpo(mem_ctx, key, &gpo);
694 0 : if (!W_ERROR_IS_OK(werr)) {
695 0 : goto done;
696 : }
697 :
698 0 : DLIST_ADD(*gpo_list, gpo);
699 : }
700 :
701 0 : done:
702 0 : gp_free_reg_ctx(reg_ctx);
703 0 : return werr;
704 : }
705 :
706 : /****************************************************************
707 : ****************************************************************/
708 :
709 0 : static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
710 : const struct dom_sid *sid,
711 : struct security_descriptor **sd,
712 : size_t *sd_size)
713 : {
714 : struct security_ace ace[6];
715 : uint32_t mask;
716 :
717 0 : struct security_acl *theacl = NULL;
718 :
719 : uint8_t inherit_flags;
720 :
721 0 : mask = REG_KEY_ALL;
722 0 : init_sec_ace(&ace[0],
723 : &global_sid_System,
724 : SEC_ACE_TYPE_ACCESS_ALLOWED,
725 : mask, 0);
726 :
727 0 : mask = REG_KEY_ALL;
728 0 : init_sec_ace(&ace[1],
729 : &global_sid_Builtin_Administrators,
730 : SEC_ACE_TYPE_ACCESS_ALLOWED,
731 : mask, 0);
732 :
733 0 : mask = REG_KEY_READ;
734 0 : init_sec_ace(&ace[2],
735 : sid ? sid : &global_sid_Authenticated_Users,
736 : SEC_ACE_TYPE_ACCESS_ALLOWED,
737 : mask, 0);
738 :
739 0 : inherit_flags = SEC_ACE_FLAG_OBJECT_INHERIT |
740 : SEC_ACE_FLAG_CONTAINER_INHERIT |
741 : SEC_ACE_FLAG_INHERIT_ONLY;
742 :
743 0 : mask = REG_KEY_ALL;
744 0 : init_sec_ace(&ace[3],
745 : &global_sid_System,
746 : SEC_ACE_TYPE_ACCESS_ALLOWED,
747 : mask, inherit_flags);
748 :
749 0 : mask = REG_KEY_ALL;
750 0 : init_sec_ace(&ace[4],
751 : &global_sid_Builtin_Administrators,
752 : SEC_ACE_TYPE_ACCESS_ALLOWED,
753 : mask, inherit_flags);
754 :
755 0 : mask = REG_KEY_READ;
756 0 : init_sec_ace(&ace[5],
757 : sid ? sid : &global_sid_Authenticated_Users,
758 : SEC_ACE_TYPE_ACCESS_ALLOWED,
759 : mask, inherit_flags);
760 :
761 0 : theacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
762 0 : W_ERROR_HAVE_NO_MEMORY(theacl);
763 :
764 0 : *sd = make_sec_desc(mem_ctx, SD_REVISION,
765 : SEC_DESC_SELF_RELATIVE |
766 : SEC_DESC_DACL_AUTO_INHERITED | /* really ? */
767 : SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */
768 : NULL, NULL, NULL,
769 : theacl, sd_size);
770 0 : W_ERROR_HAVE_NO_MEMORY(*sd);
771 :
772 0 : return WERR_OK;
773 : }
774 :
775 : /****************************************************************
776 : ****************************************************************/
777 :
778 0 : WERROR gp_secure_key(TALLOC_CTX *mem_ctx,
779 : uint32_t flags,
780 : struct registry_key *key,
781 : const struct dom_sid *sid)
782 : {
783 0 : struct security_descriptor *sd = NULL;
784 0 : size_t sd_size = 0;
785 0 : const struct dom_sid *sd_sid = NULL;
786 : WERROR werr;
787 :
788 0 : if (!(flags & GPO_LIST_FLAG_MACHINE)) {
789 0 : sd_sid = sid;
790 : }
791 :
792 0 : werr = gp_reg_generate_sd(mem_ctx, sd_sid, &sd, &sd_size);
793 0 : W_ERROR_NOT_OK_RETURN(werr);
794 :
795 0 : return reg_setkeysecurity(key, sd);
796 : }
797 :
798 : /****************************************************************
799 : ****************************************************************/
800 :
801 0 : void dump_reg_val(int lvl, const char *direction,
802 : const char *key, const char *subkey,
803 : struct registry_value *val)
804 : {
805 0 : int i = 0;
806 0 : const char *type_str = NULL;
807 :
808 0 : if (!val) {
809 0 : DEBUG(lvl,("no val!\n"));
810 0 : return;
811 : }
812 :
813 0 : type_str = str_regtype(val->type);
814 :
815 0 : DEBUG(lvl,("\tdump_reg_val:\t%s '%s'\n\t\t\t'%s' %s: ",
816 : direction, key, subkey, type_str));
817 :
818 0 : switch (val->type) {
819 0 : case REG_DWORD: {
820 : uint32_t v;
821 0 : if (val->data.length < 4) {
822 0 : break;
823 : }
824 0 : v = IVAL(val->data.data, 0);
825 0 : DEBUG(lvl,("%d (0x%08x)\n",
826 : (int)v, v));
827 0 : break;
828 : }
829 0 : case REG_QWORD: {
830 : uint64_t v;
831 0 : if (val->data.length < 8) {
832 0 : break;
833 : }
834 0 : v = BVAL(val->data.data, 0);
835 0 : DEBUG(lvl,("%d (0x%016llx)\n",
836 : (int)v,
837 : (unsigned long long)v));
838 0 : break;
839 : }
840 0 : case REG_SZ: {
841 : const char *s;
842 0 : if (!pull_reg_sz(talloc_tos(), &val->data, &s)) {
843 0 : break;
844 : }
845 0 : DEBUG(lvl,("%s (length: %d)\n",
846 : s, (int)strlen_m(s)));
847 0 : break;
848 : }
849 0 : case REG_MULTI_SZ: {
850 : const char **a;
851 0 : if (!pull_reg_multi_sz(talloc_tos(), &val->data, &a)) {
852 0 : break;
853 : }
854 0 : for (i=0; a[i] != NULL; i++) {
855 : ;;
856 : }
857 0 : DEBUG(lvl,("(num_strings: %d)\n", i));
858 0 : for (i=0; a[i] != NULL; i++) {
859 0 : DEBUGADD(lvl,("\t%s\n", a[i]));
860 : }
861 0 : break;
862 : }
863 0 : case REG_NONE:
864 0 : DEBUG(lvl,("\n"));
865 0 : break;
866 0 : case REG_BINARY:
867 0 : dump_data(lvl, val->data.data,
868 0 : val->data.length);
869 0 : break;
870 0 : default:
871 0 : DEBUG(lvl,("unsupported type: %d\n", val->type));
872 0 : break;
873 : }
874 : }
875 :
876 : /****************************************************************
877 : ****************************************************************/
878 :
879 0 : void dump_reg_entry(uint32_t flags,
880 : const char *dir,
881 : struct gp_registry_entry *entry)
882 : {
883 0 : if (!(flags & GPO_INFO_FLAG_VERBOSE))
884 0 : return;
885 :
886 0 : dump_reg_val(1, dir,
887 : entry->key,
888 : entry->value,
889 : entry->data);
890 : }
891 :
892 : /****************************************************************
893 : ****************************************************************/
894 :
895 0 : void dump_reg_entries(uint32_t flags,
896 : const char *dir,
897 : struct gp_registry_entry *entries,
898 : size_t num_entries)
899 : {
900 : size_t i;
901 :
902 0 : if (!(flags & GPO_INFO_FLAG_VERBOSE))
903 0 : return;
904 :
905 0 : for (i=0; i < num_entries; i++) {
906 0 : dump_reg_entry(flags, dir, &entries[i]);
907 : }
908 : }
909 :
910 : /****************************************************************
911 : ****************************************************************/
912 :
913 0 : bool add_gp_registry_entry_to_array(TALLOC_CTX *mem_ctx,
914 : struct gp_registry_entry *entry,
915 : struct gp_registry_entry **entries,
916 : size_t *num)
917 : {
918 0 : *entries = talloc_realloc(mem_ctx, *entries,
919 : struct gp_registry_entry,
920 : (*num)+1);
921 :
922 0 : if (*entries == NULL) {
923 0 : *num = 0;
924 0 : return false;
925 : }
926 :
927 0 : (*entries)[*num].action = entry->action;
928 0 : (*entries)[*num].key = entry->key;
929 0 : (*entries)[*num].value = entry->value;
930 0 : (*entries)[*num].data = entry->data;
931 :
932 0 : *num += 1;
933 0 : return true;
934 : }
935 :
936 : /****************************************************************
937 : ****************************************************************/
938 :
939 0 : static const char *gp_reg_action_str(enum gp_reg_action action)
940 : {
941 0 : switch (action) {
942 0 : case GP_REG_ACTION_NONE:
943 0 : return "GP_REG_ACTION_NONE";
944 0 : case GP_REG_ACTION_ADD_VALUE:
945 0 : return "GP_REG_ACTION_ADD_VALUE";
946 0 : case GP_REG_ACTION_ADD_KEY:
947 0 : return "GP_REG_ACTION_ADD_KEY";
948 0 : case GP_REG_ACTION_DEL_VALUES:
949 0 : return "GP_REG_ACTION_DEL_VALUES";
950 0 : case GP_REG_ACTION_DEL_VALUE:
951 0 : return "GP_REG_ACTION_DEL_VALUE";
952 0 : case GP_REG_ACTION_DEL_ALL_VALUES:
953 0 : return "GP_REG_ACTION_DEL_ALL_VALUES";
954 0 : case GP_REG_ACTION_DEL_KEYS:
955 0 : return "GP_REG_ACTION_DEL_KEYS";
956 0 : case GP_REG_ACTION_SEC_KEY_SET:
957 0 : return "GP_REG_ACTION_SEC_KEY_SET";
958 0 : case GP_REG_ACTION_SEC_KEY_RESET:
959 0 : return "GP_REG_ACTION_SEC_KEY_RESET";
960 0 : default:
961 0 : return "unknown";
962 : }
963 : }
964 :
965 : /****************************************************************
966 : ****************************************************************/
967 :
968 0 : WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx,
969 : struct registry_key *root_key,
970 : struct gp_registry_context *reg_ctx,
971 : struct gp_registry_entry *entry,
972 : const struct security_token *token,
973 : uint32_t flags)
974 : {
975 : WERROR werr;
976 0 : struct registry_key *key = NULL;
977 :
978 0 : if (flags & GPO_INFO_FLAG_VERBOSE) {
979 0 : printf("about to store key: [%s]\n", entry->key);
980 0 : printf(" value: [%s]\n", entry->value);
981 0 : printf(" data: [%s]\n", str_regtype(entry->data->type));
982 0 : printf(" action: [%s]\n", gp_reg_action_str(entry->action));
983 : }
984 :
985 0 : werr = gp_store_reg_subkey(mem_ctx, entry->key,
986 : root_key, &key);
987 : /* reg_ctx->curr_key, &key); */
988 0 : if (!W_ERROR_IS_OK(werr)) {
989 0 : DEBUG(0,("gp_store_reg_subkey failed: %s\n", win_errstr(werr)));
990 0 : return werr;
991 : }
992 :
993 0 : switch (entry->action) {
994 0 : case GP_REG_ACTION_NONE:
995 : case GP_REG_ACTION_ADD_KEY:
996 0 : return WERR_OK;
997 :
998 0 : case GP_REG_ACTION_SEC_KEY_SET:
999 0 : werr = gp_secure_key(mem_ctx, flags,
1000 : key,
1001 0 : &token->sids[0]);
1002 0 : if (!W_ERROR_IS_OK(werr)) {
1003 0 : DEBUG(0,("reg_apply_registry_entry: "
1004 : "gp_secure_key failed: %s\n",
1005 : win_errstr(werr)));
1006 0 : return werr;
1007 : }
1008 0 : break;
1009 0 : case GP_REG_ACTION_ADD_VALUE:
1010 0 : werr = reg_setvalue(key, entry->value, entry->data);
1011 0 : if (!W_ERROR_IS_OK(werr)) {
1012 0 : DEBUG(0,("reg_apply_registry_entry: "
1013 : "reg_setvalue failed: %s\n",
1014 : win_errstr(werr)));
1015 0 : dump_reg_entry(flags, "STORE", entry);
1016 0 : return werr;
1017 : }
1018 0 : break;
1019 0 : case GP_REG_ACTION_DEL_VALUE:
1020 0 : werr = reg_deletevalue(key, entry->value);
1021 0 : if (!W_ERROR_IS_OK(werr)) {
1022 0 : DEBUG(0,("reg_apply_registry_entry: "
1023 : "reg_deletevalue failed: %s\n",
1024 : win_errstr(werr)));
1025 0 : dump_reg_entry(flags, "STORE", entry);
1026 0 : return werr;
1027 : }
1028 0 : break;
1029 0 : case GP_REG_ACTION_DEL_ALL_VALUES:
1030 0 : werr = reg_deleteallvalues(key);
1031 0 : if (!W_ERROR_IS_OK(werr)) {
1032 0 : DEBUG(0,("reg_apply_registry_entry: "
1033 : "reg_deleteallvalues failed: %s\n",
1034 : win_errstr(werr)));
1035 0 : dump_reg_entry(flags, "STORE", entry);
1036 0 : return werr;
1037 : }
1038 0 : break;
1039 0 : case GP_REG_ACTION_DEL_VALUES:
1040 : case GP_REG_ACTION_DEL_KEYS:
1041 : case GP_REG_ACTION_SEC_KEY_RESET:
1042 0 : DEBUG(0,("reg_apply_registry_entry: "
1043 : "not yet supported: %s (%d)\n",
1044 : gp_reg_action_str(entry->action),
1045 : entry->action));
1046 0 : return WERR_NOT_SUPPORTED;
1047 0 : default:
1048 0 : DEBUG(0,("invalid action: %d\n", entry->action));
1049 0 : return WERR_INVALID_PARAMETER;
1050 : }
1051 :
1052 0 : return werr;
1053 : }
|