source: branches/samba-3.5.x/libgpo/gpo_ldap.c@ 738

Last change on this file since 738 was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 20.8 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 * Group Policy Object Support
4 * Copyright (C) Guenther Deschner 2005,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#if _SAMBA_BUILD_ == 4
22#include "libgpo/gpo.h"
23#include "libgpo/gpo_s4.h"
24#include "source4/libgpo/ads_convenience.h"
25#endif
26
27/****************************************************************
28 parse the raw extension string into a GP_EXT structure
29****************************************************************/
30
31bool ads_parse_gp_ext(TALLOC_CTX *mem_ctx,
32 const char *extension_raw,
33 struct GP_EXT **gp_ext)
34{
35 bool ret = false;
36 struct GP_EXT *ext = NULL;
37 char **ext_list = NULL;
38 char **ext_strings = NULL;
39 int i;
40
41 if (!extension_raw) {
42 goto parse_error;
43 }
44
45 DEBUG(20,("ads_parse_gp_ext: %s\n", extension_raw));
46
47 ext = talloc_zero(mem_ctx, struct GP_EXT);
48 if (!ext) {
49 goto parse_error;
50 }
51
52 ext_list = str_list_make(mem_ctx, extension_raw, "]");
53 if (!ext_list) {
54 goto parse_error;
55 }
56
57 for (i = 0; ext_list[i] != NULL; i++) {
58 /* no op */
59 }
60
61 ext->num_exts = i;
62
63 if (ext->num_exts) {
64 ext->extensions = talloc_zero_array(mem_ctx, char *,
65 ext->num_exts);
66 ext->extensions_guid = talloc_zero_array(mem_ctx, char *,
67 ext->num_exts);
68 ext->snapins = talloc_zero_array(mem_ctx, char *,
69 ext->num_exts);
70 ext->snapins_guid = talloc_zero_array(mem_ctx, char *,
71 ext->num_exts);
72 }
73
74 ext->gp_extension = talloc_strdup(mem_ctx, extension_raw);
75
76 if (!ext->extensions || !ext->extensions_guid ||
77 !ext->snapins || !ext->snapins_guid ||
78 !ext->gp_extension) {
79 goto parse_error;
80 }
81
82 for (i = 0; ext_list[i] != NULL; i++) {
83
84 int k;
85 char *p, *q;
86
87 DEBUGADD(10,("extension #%d\n", i));
88
89 p = ext_list[i];
90
91 if (p[0] == '[') {
92 p++;
93 }
94
95 ext_strings = str_list_make(mem_ctx, p, "}");
96 if (ext_strings == NULL) {
97 goto parse_error;
98 }
99
100 for (k = 0; ext_strings[k] != NULL; k++) {
101 /* no op */
102 }
103
104 q = ext_strings[0];
105
106 if (q[0] == '{') {
107 q++;
108 }
109
110 ext->extensions[i] = talloc_strdup(mem_ctx,
111 cse_gpo_guid_string_to_name(q));
112 ext->extensions_guid[i] = talloc_strdup(mem_ctx, q);
113
114 /* we might have no name for the guid */
115 if (ext->extensions_guid[i] == NULL) {
116 goto parse_error;
117 }
118
119 for (k = 1; ext_strings[k] != NULL; k++) {
120
121 char *m = ext_strings[k];
122
123 if (m[0] == '{') {
124 m++;
125 }
126
127 /* FIXME: theoretically there could be more than one
128 * snapin per extension */
129 ext->snapins[i] = talloc_strdup(mem_ctx,
130 cse_snapin_gpo_guid_string_to_name(m));
131 ext->snapins_guid[i] = talloc_strdup(mem_ctx, m);
132
133 /* we might have no name for the guid */
134 if (ext->snapins_guid[i] == NULL) {
135 goto parse_error;
136 }
137 }
138 }
139
140 *gp_ext = ext;
141
142 ret = true;
143
144 parse_error:
145 talloc_free(ext_list);
146 talloc_free(ext_strings);
147
148 return ret;
149}
150
151#ifdef HAVE_LDAP
152
153/****************************************************************
154 parse the raw link string into a GP_LINK structure
155****************************************************************/
156
157static ADS_STATUS gpo_parse_gplink(TALLOC_CTX *mem_ctx,
158 const char *gp_link_raw,
159 uint32_t options,
160 struct GP_LINK *gp_link)
161{
162 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
163 char **link_list;
164 int i;
165
166 ZERO_STRUCTP(gp_link);
167
168 DEBUG(10,("gpo_parse_gplink: gPLink: %s\n", gp_link_raw));
169
170 link_list = str_list_make_v3(mem_ctx, gp_link_raw, "]");
171 if (!link_list) {
172 goto parse_error;
173 }
174
175 for (i = 0; link_list[i] != NULL; i++) {
176 /* no op */
177 }
178
179 gp_link->gp_opts = options;
180 gp_link->num_links = i;
181
182 if (gp_link->num_links) {
183 gp_link->link_names = talloc_zero_array(mem_ctx, char *,
184 gp_link->num_links);
185 gp_link->link_opts = talloc_zero_array(mem_ctx, uint32_t,
186 gp_link->num_links);
187 }
188
189 gp_link->gp_link = talloc_strdup(mem_ctx, gp_link_raw);
190
191 if (!gp_link->link_names || !gp_link->link_opts || !gp_link->gp_link) {
192 goto parse_error;
193 }
194
195 for (i = 0; link_list[i] != NULL; i++) {
196
197 char *p, *q;
198
199 DEBUGADD(10,("gpo_parse_gplink: processing link #%d\n", i));
200
201 q = link_list[i];
202 if (q[0] == '[') {
203 q++;
204 };
205
206 p = strchr(q, ';');
207
208 if (p == NULL) {
209 goto parse_error;
210 }
211
212 gp_link->link_names[i] = talloc_strdup(mem_ctx, q);
213 if (gp_link->link_names[i] == NULL) {
214 goto parse_error;
215 }
216 gp_link->link_names[i][PTR_DIFF(p, q)] = 0;
217
218 gp_link->link_opts[i] = atoi(p + 1);
219
220 DEBUGADD(10,("gpo_parse_gplink: link: %s\n",
221 gp_link->link_names[i]));
222 DEBUGADD(10,("gpo_parse_gplink: opt: %d\n",
223 gp_link->link_opts[i]));
224
225 }
226
227 status = ADS_SUCCESS;
228
229 parse_error:
230 talloc_free(link_list);
231
232 return status;
233}
234
235/****************************************************************
236 helper call to get a GP_LINK structure from a linkdn
237****************************************************************/
238
239ADS_STATUS ads_get_gpo_link(ADS_STRUCT *ads,
240 TALLOC_CTX *mem_ctx,
241 const char *link_dn,
242 struct GP_LINK *gp_link_struct)
243{
244 ADS_STATUS status;
245 const char *attrs[] = {"gPLink", "gPOptions", NULL};
246 LDAPMessage *res = NULL;
247 const char *gp_link;
248 uint32_t gp_options;
249
250 ZERO_STRUCTP(gp_link_struct);
251
252 status = ads_search_dn(ads, &res, link_dn, attrs);
253 if (!ADS_ERR_OK(status)) {
254 DEBUG(10,("ads_get_gpo_link: search failed with %s\n",
255 ads_errstr(status)));
256 return status;
257 }
258
259 if (ads_count_replies(ads, res) != 1) {
260 DEBUG(10,("ads_get_gpo_link: no result\n"));
261 ads_msgfree(ads, res);
262 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
263 }
264
265 gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink");
266 if (gp_link == NULL) {
267 DEBUG(10,("ads_get_gpo_link: no 'gPLink' attribute found\n"));
268 ads_msgfree(ads, res);
269 return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE);
270 }
271
272 /* perfectly legal to have no options */
273 if (!ads_pull_uint32(ads, res, "gPOptions", &gp_options)) {
274 DEBUG(10,("ads_get_gpo_link: "
275 "no 'gPOptions' attribute found\n"));
276 gp_options = 0;
277 }
278
279 ads_msgfree(ads, res);
280
281 return gpo_parse_gplink(mem_ctx, gp_link, gp_options, gp_link_struct);
282}
283
284/****************************************************************
285 helper call to add a gp link
286****************************************************************/
287
288ADS_STATUS ads_add_gpo_link(ADS_STRUCT *ads,
289 TALLOC_CTX *mem_ctx,
290 const char *link_dn,
291 const char *gpo_dn,
292 uint32_t gpo_opt)
293{
294 ADS_STATUS status;
295 const char *attrs[] = {"gPLink", NULL};
296 LDAPMessage *res = NULL;
297 const char *gp_link, *gp_link_new;
298 ADS_MODLIST mods;
299
300 /* although ADS allows to set anything here, we better check here if
301 * the gpo_dn is sane */
302
303 if (!strnequal(gpo_dn, "LDAP://CN={", strlen("LDAP://CN={")) != 0) {
304 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
305 }
306
307 status = ads_search_dn(ads, &res, link_dn, attrs);
308 if (!ADS_ERR_OK(status)) {
309 DEBUG(10,("ads_add_gpo_link: search failed with %s\n",
310 ads_errstr(status)));
311 return status;
312 }
313
314 if (ads_count_replies(ads, res) != 1) {
315 DEBUG(10,("ads_add_gpo_link: no result\n"));
316 ads_msgfree(ads, res);
317 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
318 }
319
320 gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink");
321 if (gp_link == NULL) {
322 gp_link_new = talloc_asprintf(mem_ctx, "[%s;%d]",
323 gpo_dn, gpo_opt);
324 } else {
325 gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]",
326 gp_link, gpo_dn, gpo_opt);
327 }
328
329 ads_msgfree(ads, res);
330 ADS_ERROR_HAVE_NO_MEMORY(gp_link_new);
331
332 mods = ads_init_mods(mem_ctx);
333 ADS_ERROR_HAVE_NO_MEMORY(mods);
334
335 status = ads_mod_str(mem_ctx, &mods, "gPLink", gp_link_new);
336 if (!ADS_ERR_OK(status)) {
337 return status;
338 }
339
340 return ads_gen_mod(ads, link_dn, mods);
341}
342
343/****************************************************************
344 helper call to delete add a gp link
345****************************************************************/
346
347/* untested & broken */
348ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads,
349 TALLOC_CTX *mem_ctx,
350 const char *link_dn,
351 const char *gpo_dn)
352{
353 ADS_STATUS status;
354 const char *attrs[] = {"gPLink", NULL};
355 LDAPMessage *res = NULL;
356 const char *gp_link, *gp_link_new = NULL;
357 ADS_MODLIST mods;
358
359 /* check for a sane gpo_dn */
360 if (gpo_dn[0] != '[') {
361 DEBUG(10,("ads_delete_gpo_link: first char not: [\n"));
362 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
363 }
364
365 if (gpo_dn[strlen(gpo_dn)] != ']') {
366 DEBUG(10,("ads_delete_gpo_link: last char not: ]\n"));
367 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
368 }
369
370 status = ads_search_dn(ads, &res, link_dn, attrs);
371 if (!ADS_ERR_OK(status)) {
372 DEBUG(10,("ads_delete_gpo_link: search failed with %s\n",
373 ads_errstr(status)));
374 return status;
375 }
376
377 if (ads_count_replies(ads, res) != 1) {
378 DEBUG(10,("ads_delete_gpo_link: no result\n"));
379 ads_msgfree(ads, res);
380 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
381 }
382
383 gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink");
384 if (gp_link == NULL) {
385 return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE);
386 }
387
388 /* find link to delete */
389 /* gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]", gp_link,
390 gpo_dn, gpo_opt); */
391
392 ads_msgfree(ads, res);
393 ADS_ERROR_HAVE_NO_MEMORY(gp_link_new);
394
395 mods = ads_init_mods(mem_ctx);
396 ADS_ERROR_HAVE_NO_MEMORY(mods);
397
398 status = ads_mod_str(mem_ctx, &mods, "gPLink", gp_link_new);
399 if (!ADS_ERR_OK(status)) {
400 return status;
401 }
402
403 return ads_gen_mod(ads, link_dn, mods);
404}
405
406/****************************************************************
407 parse a GROUP_POLICY_OBJECT structure from an LDAPMessage result
408****************************************************************/
409
410 ADS_STATUS ads_parse_gpo(ADS_STRUCT *ads,
411 TALLOC_CTX *mem_ctx,
412 LDAPMessage *res,
413 const char *gpo_dn,
414 struct GROUP_POLICY_OBJECT *gpo)
415{
416 ZERO_STRUCTP(gpo);
417
418 ADS_ERROR_HAVE_NO_MEMORY(res);
419
420 if (gpo_dn) {
421 gpo->ds_path = talloc_strdup(mem_ctx, gpo_dn);
422 } else {
423 gpo->ds_path = ads_get_dn(ads, mem_ctx, res);
424 }
425
426 ADS_ERROR_HAVE_NO_MEMORY(gpo->ds_path);
427
428 if (!ads_pull_uint32(ads, res, "versionNumber", &gpo->version)) {
429 return ADS_ERROR(LDAP_NO_MEMORY);
430 }
431
432 if (!ads_pull_uint32(ads, res, "flags", &gpo->options)) {
433 return ADS_ERROR(LDAP_NO_MEMORY);
434 }
435
436 gpo->file_sys_path = ads_pull_string(ads, mem_ctx, res,
437 "gPCFileSysPath");
438 ADS_ERROR_HAVE_NO_MEMORY(gpo->file_sys_path);
439
440 gpo->display_name = ads_pull_string(ads, mem_ctx, res,
441 "displayName");
442 ADS_ERROR_HAVE_NO_MEMORY(gpo->display_name);
443
444 gpo->name = ads_pull_string(ads, mem_ctx, res,
445 "name");
446 ADS_ERROR_HAVE_NO_MEMORY(gpo->name);
447
448 gpo->machine_extensions = ads_pull_string(ads, mem_ctx, res,
449 "gPCMachineExtensionNames");
450 gpo->user_extensions = ads_pull_string(ads, mem_ctx, res,
451 "gPCUserExtensionNames");
452
453 ads_pull_sd(ads, mem_ctx, res, "ntSecurityDescriptor",
454 &gpo->security_descriptor);
455 ADS_ERROR_HAVE_NO_MEMORY(gpo->security_descriptor);
456
457 return ADS_ERROR(LDAP_SUCCESS);
458}
459
460/****************************************************************
461 get a GROUP_POLICY_OBJECT structure based on different input parameters
462****************************************************************/
463
464ADS_STATUS ads_get_gpo(ADS_STRUCT *ads,
465 TALLOC_CTX *mem_ctx,
466 const char *gpo_dn,
467 const char *display_name,
468 const char *guid_name,
469 struct GROUP_POLICY_OBJECT *gpo)
470{
471 ADS_STATUS status;
472 LDAPMessage *res = NULL;
473 char *dn;
474 const char *filter;
475 const char *attrs[] = {
476 "cn",
477 "displayName",
478 "flags",
479 "gPCFileSysPath",
480 "gPCFunctionalityVersion",
481 "gPCMachineExtensionNames",
482 "gPCUserExtensionNames",
483 "gPCWQLFilter",
484 "name",
485 "ntSecurityDescriptor",
486 "versionNumber",
487 NULL};
488 uint32_t sd_flags = DACL_SECURITY_INFORMATION;
489
490 ZERO_STRUCTP(gpo);
491
492 if (!gpo_dn && !display_name && !guid_name) {
493 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
494 }
495
496 if (gpo_dn) {
497
498 if (strnequal(gpo_dn, "LDAP://", strlen("LDAP://")) != 0) {
499 gpo_dn = gpo_dn + strlen("LDAP://");
500 }
501
502 status = ads_search_retry_dn_sd_flags(ads, &res,
503 sd_flags,
504 gpo_dn, attrs);
505
506 } else if (display_name || guid_name) {
507
508 filter = talloc_asprintf(mem_ctx,
509 "(&(objectclass=groupPolicyContainer)(%s=%s))",
510 display_name ? "displayName" : "name",
511 display_name ? display_name : guid_name);
512 ADS_ERROR_HAVE_NO_MEMORY(filter);
513
514 status = ads_do_search_all_sd_flags(ads, ads->config.bind_path,
515 LDAP_SCOPE_SUBTREE, filter,
516 attrs, sd_flags, &res);
517 }
518
519 if (!ADS_ERR_OK(status)) {
520 DEBUG(10,("ads_get_gpo: search failed with %s\n",
521 ads_errstr(status)));
522 return status;
523 }
524
525 if (ads_count_replies(ads, res) != 1) {
526 DEBUG(10,("ads_get_gpo: no result\n"));
527 ads_msgfree(ads, res);
528 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
529 }
530
531 dn = ads_get_dn(ads, mem_ctx, res);
532 if (dn == NULL) {
533 ads_msgfree(ads, res);
534 return ADS_ERROR(LDAP_NO_MEMORY);
535 }
536
537 status = ads_parse_gpo(ads, mem_ctx, res, dn, gpo);
538 ads_msgfree(ads, res);
539 TALLOC_FREE(dn);
540
541 return status;
542}
543
544/****************************************************************
545 add a gplink to the GROUP_POLICY_OBJECT linked list
546****************************************************************/
547
548static ADS_STATUS add_gplink_to_gpo_list(ADS_STRUCT *ads,
549 TALLOC_CTX *mem_ctx,
550 struct GROUP_POLICY_OBJECT **gpo_list,
551 const char *link_dn,
552 struct GP_LINK *gp_link,
553 enum GPO_LINK_TYPE link_type,
554 bool only_add_forced_gpos,
555 const NT_USER_TOKEN *token)
556{
557 ADS_STATUS status;
558 int i;
559
560 for (i = 0; i < gp_link->num_links; i++) {
561
562 struct GROUP_POLICY_OBJECT *new_gpo = NULL;
563
564 if (gp_link->link_opts[i] & GPO_LINK_OPT_DISABLED) {
565 DEBUG(10,("skipping disabled GPO\n"));
566 continue;
567 }
568
569 if (only_add_forced_gpos) {
570
571 if (!(gp_link->link_opts[i] & GPO_LINK_OPT_ENFORCED)) {
572 DEBUG(10,("skipping nonenforced GPO link "
573 "because GPOPTIONS_BLOCK_INHERITANCE "
574 "has been set\n"));
575 continue;
576 } else {
577 DEBUG(10,("adding enforced GPO link although "
578 "the GPOPTIONS_BLOCK_INHERITANCE "
579 "has been set\n"));
580 }
581 }
582
583 new_gpo = TALLOC_ZERO_P(mem_ctx, struct GROUP_POLICY_OBJECT);
584 ADS_ERROR_HAVE_NO_MEMORY(new_gpo);
585
586 status = ads_get_gpo(ads, mem_ctx, gp_link->link_names[i],
587 NULL, NULL, new_gpo);
588 if (!ADS_ERR_OK(status)) {
589 DEBUG(10,("failed to get gpo: %s\n",
590 gp_link->link_names[i]));
591 return status;
592 }
593
594 status = ADS_ERROR_NT(gpo_apply_security_filtering(new_gpo,
595 token));
596 if (!ADS_ERR_OK(status)) {
597 DEBUG(10,("skipping GPO \"%s\" as object "
598 "has no access to it\n",
599 new_gpo->display_name));
600 talloc_free(new_gpo);
601 continue;
602 }
603
604 new_gpo->link = link_dn;
605 new_gpo->link_type = link_type;
606
607 DLIST_ADD(*gpo_list, new_gpo);
608
609 DEBUG(10,("add_gplink_to_gplist: added GPLINK #%d %s "
610 "to GPO list\n", i, gp_link->link_names[i]));
611 }
612
613 return ADS_ERROR(LDAP_SUCCESS);
614}
615
616/****************************************************************
617****************************************************************/
618
619ADS_STATUS ads_get_sid_token(ADS_STRUCT *ads,
620 TALLOC_CTX *mem_ctx,
621 const char *dn,
622 NT_USER_TOKEN **token)
623{
624 ADS_STATUS status;
625 DOM_SID object_sid;
626 DOM_SID primary_group_sid;
627 DOM_SID *ad_token_sids;
628 size_t num_ad_token_sids = 0;
629 DOM_SID *token_sids;
630 size_t num_token_sids = 0;
631 NT_USER_TOKEN *new_token = NULL;
632 int i;
633
634 status = ads_get_tokensids(ads, mem_ctx, dn,
635 &object_sid, &primary_group_sid,
636 &ad_token_sids, &num_ad_token_sids);
637 if (!ADS_ERR_OK(status)) {
638 return status;
639 }
640
641 token_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, 1);
642 ADS_ERROR_HAVE_NO_MEMORY(token_sids);
643
644 status = ADS_ERROR_NT(add_sid_to_array_unique(mem_ctx,
645 &primary_group_sid,
646 &token_sids,
647 &num_token_sids));
648 if (!ADS_ERR_OK(status)) {
649 return status;
650 }
651
652 for (i = 0; i < num_ad_token_sids; i++) {
653
654 if (sid_check_is_in_builtin(&ad_token_sids[i])) {
655 continue;
656 }
657
658 status = ADS_ERROR_NT(add_sid_to_array_unique(mem_ctx,
659 &ad_token_sids[i],
660 &token_sids,
661 &num_token_sids));
662 if (!ADS_ERR_OK(status)) {
663 return status;
664 }
665 }
666
667 new_token = create_local_nt_token(mem_ctx, &object_sid, false,
668 num_token_sids, token_sids);
669 ADS_ERROR_HAVE_NO_MEMORY(new_token);
670
671 *token = new_token;
672
673 debug_nt_user_token(DBGC_CLASS, 5, *token);
674
675 return ADS_ERROR_LDAP(LDAP_SUCCESS);
676}
677
678/****************************************************************
679****************************************************************/
680
681static ADS_STATUS add_local_policy_to_gpo_list(TALLOC_CTX *mem_ctx,
682 struct GROUP_POLICY_OBJECT **gpo_list,
683 enum GPO_LINK_TYPE link_type)
684{
685 struct GROUP_POLICY_OBJECT *gpo = NULL;
686
687 ADS_ERROR_HAVE_NO_MEMORY(gpo_list);
688
689 gpo = TALLOC_ZERO_P(mem_ctx, struct GROUP_POLICY_OBJECT);
690 ADS_ERROR_HAVE_NO_MEMORY(gpo);
691
692 gpo->name = talloc_strdup(mem_ctx, "Local Policy");
693 ADS_ERROR_HAVE_NO_MEMORY(gpo->name);
694
695 gpo->display_name = talloc_strdup(mem_ctx, "Local Policy");
696 ADS_ERROR_HAVE_NO_MEMORY(gpo->display_name);
697
698 gpo->link_type = link_type;
699
700 DLIST_ADD(*gpo_list, gpo);
701
702 return ADS_ERROR_NT(NT_STATUS_OK);
703}
704
705/****************************************************************
706 get the full list of GROUP_POLICY_OBJECTs for a given dn
707****************************************************************/
708
709ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads,
710 TALLOC_CTX *mem_ctx,
711 const char *dn,
712 uint32_t flags,
713 const NT_USER_TOKEN *token,
714 struct GROUP_POLICY_OBJECT **gpo_list)
715{
716 /* (L)ocal (S)ite (D)omain (O)rganizational(U)nit */
717
718 ADS_STATUS status;
719 struct GP_LINK gp_link;
720 const char *parent_dn, *site_dn, *tmp_dn;
721 bool add_only_forced_gpos = false;
722
723 ZERO_STRUCTP(gpo_list);
724
725 if (!dn) {
726 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
727 }
728
729 DEBUG(10,("ads_get_gpo_list: getting GPO list for [%s]\n", dn));
730
731 /* (L)ocal */
732 status = add_local_policy_to_gpo_list(mem_ctx, gpo_list,
733 GP_LINK_LOCAL);
734 if (!ADS_ERR_OK(status)) {
735 return status;
736 }
737
738 /* (S)ite */
739
740 /* are site GPOs valid for users as well ??? */
741 if (flags & GPO_LIST_FLAG_MACHINE) {
742
743 status = ads_site_dn_for_machine(ads, mem_ctx,
744 ads->config.ldap_server_name,
745 &site_dn);
746 if (!ADS_ERR_OK(status)) {
747 return status;
748 }
749
750 DEBUG(10,("ads_get_gpo_list: query SITE: [%s] for GPOs\n",
751 site_dn));
752
753 status = ads_get_gpo_link(ads, mem_ctx, site_dn, &gp_link);
754 if (ADS_ERR_OK(status)) {
755
756 if (DEBUGLEVEL >= 100) {
757 dump_gplink(ads, mem_ctx, &gp_link);
758 }
759
760 status = add_gplink_to_gpo_list(ads, mem_ctx, gpo_list,
761 site_dn, &gp_link,
762 GP_LINK_SITE,
763 add_only_forced_gpos,
764 token);
765 if (!ADS_ERR_OK(status)) {
766 return status;
767 }
768
769 if (flags & GPO_LIST_FLAG_SITEONLY) {
770 return ADS_ERROR(LDAP_SUCCESS);
771 }
772
773 /* inheritance can't be blocked at the site level */
774 }
775 }
776
777 tmp_dn = dn;
778
779 while ((parent_dn = ads_parent_dn(tmp_dn)) &&
780 (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path)))) {
781
782 /* (D)omain */
783
784 /* An account can just be a member of one domain */
785 if (strncmp(parent_dn, "DC=", strlen("DC=")) == 0) {
786
787 DEBUG(10,("ads_get_gpo_list: query DC: [%s] for GPOs\n",
788 parent_dn));
789
790 status = ads_get_gpo_link(ads, mem_ctx, parent_dn,
791 &gp_link);
792 if (ADS_ERR_OK(status)) {
793
794 if (DEBUGLEVEL >= 100) {
795 dump_gplink(ads, mem_ctx, &gp_link);
796 }
797
798 /* block inheritance from now on */
799 if (gp_link.gp_opts &
800 GPOPTIONS_BLOCK_INHERITANCE) {
801 add_only_forced_gpos = true;
802 }
803
804 status = add_gplink_to_gpo_list(ads,
805 mem_ctx,
806 gpo_list,
807 parent_dn,
808 &gp_link,
809 GP_LINK_DOMAIN,
810 add_only_forced_gpos,
811 token);
812 if (!ADS_ERR_OK(status)) {
813 return status;
814 }
815 }
816 }
817
818 tmp_dn = parent_dn;
819 }
820
821 /* reset dn again */
822 tmp_dn = dn;
823
824 while ((parent_dn = ads_parent_dn(tmp_dn)) &&
825 (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path)))) {
826
827
828 /* (O)rganizational(U)nit */
829
830 /* An account can be a member of more OUs */
831 if (strncmp(parent_dn, "OU=", strlen("OU=")) == 0) {
832
833 DEBUG(10,("ads_get_gpo_list: query OU: [%s] for GPOs\n",
834 parent_dn));
835
836 status = ads_get_gpo_link(ads, mem_ctx, parent_dn,
837 &gp_link);
838 if (ADS_ERR_OK(status)) {
839
840 if (DEBUGLEVEL >= 100) {
841 dump_gplink(ads, mem_ctx, &gp_link);
842 }
843
844 /* block inheritance from now on */
845 if (gp_link.gp_opts &
846 GPOPTIONS_BLOCK_INHERITANCE) {
847 add_only_forced_gpos = true;
848 }
849
850 status = add_gplink_to_gpo_list(ads,
851 mem_ctx,
852 gpo_list,
853 parent_dn,
854 &gp_link,
855 GP_LINK_OU,
856 add_only_forced_gpos,
857 token);
858 if (!ADS_ERR_OK(status)) {
859 return status;
860 }
861 }
862 }
863
864 tmp_dn = parent_dn;
865
866 };
867
868 return ADS_ERROR(LDAP_SUCCESS);
869}
870
871#endif /* HAVE_LDAP */
Note: See TracBrowser for help on using the repository browser.