2 * Unix SMB/CIFS implementation.
3 * Group Policy Object Support
4 * Copyright (C) Jelmer Vernooij 2008
5 * Copyright (C) Wilco Baan Hofman 2008-2010
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "param/param.h"
23 #include "lib/ldb-samba/ldb_wrap.h"
24 #include "auth/credentials/credentials.h"
25 #include "../librpc/gen_ndr/nbt.h"
26 #include "libcli/libcli.h"
27 #include "libnet/libnet.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
29 #include "../libcli/security/security.h"
30 #include "libcli/ldap/ldap_ndr.h"
31 #include "../lib/talloc/talloc.h"
32 #include "lib/policy/policy.h"
34 struct gpo_stringmap {
38 static const struct gpo_stringmap gplink_options [] = {
39 { "GPLINK_OPT_DISABLE", GPLINK_OPT_DISABLE },
40 { "GPLINK_OPT_ENFORCE", GPLINK_OPT_ENFORCE },
43 static const struct gpo_stringmap gpo_flags [] = {
44 { "GPO_FLAG_USER_DISABLE", GPO_FLAG_USER_DISABLE },
45 { "GPO_FLAG_MACHINE_DISABLE", GPO_FLAG_MACHINE_DISABLE },
49 static NTSTATUS parse_gpo(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct gp_object **ret)
51 struct gp_object *gpo = talloc(mem_ctx, struct gp_object);
52 enum ndr_err_code ndr_err;
53 const DATA_BLOB *data;
55 NT_STATUS_HAVE_NO_MEMORY(gpo);
57 gpo->dn = talloc_strdup(mem_ctx, ldb_dn_get_linearized(msg->dn));
58 if (gpo->dn == NULL) {
60 return NT_STATUS_NO_MEMORY;
63 DEBUG(9, ("Parsing GPO LDAP data for %s\n", gpo->dn));
65 gpo->display_name = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "displayName", ""));
66 if (gpo->display_name == NULL) {
68 return NT_STATUS_NO_MEMORY;
71 gpo->name = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "name", ""));
72 if (gpo->name == NULL) {
74 return NT_STATUS_NO_MEMORY;
77 gpo->flags = ldb_msg_find_attr_as_uint(msg, "flags", 0);
78 gpo->version = ldb_msg_find_attr_as_uint(msg, "versionNumber", 0);
80 gpo->file_sys_path = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "gPCFileSysPath", ""));
81 if (gpo->file_sys_path == NULL) {
83 return NT_STATUS_NO_MEMORY;
86 /* Pull the security descriptor through the NDR library */
87 data = ldb_msg_find_ldb_val(msg, "nTSecurityDescriptor");
88 gpo->security_descriptor = talloc(gpo, struct security_descriptor);
89 if (gpo->security_descriptor == NULL) {
91 return NT_STATUS_NO_MEMORY;
94 ndr_err = ndr_pull_struct_blob(data,
96 gpo->security_descriptor,
97 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
98 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
99 return ndr_map_error2ntstatus(ndr_err);
106 NTSTATUS gp_get_gpo_flags(TALLOC_CTX *mem_ctx, uint32_t flags, const char ***ret)
108 unsigned int i, count=0;
109 const char **flag_strs = talloc_array(mem_ctx, const char *, 1);
111 NT_STATUS_HAVE_NO_MEMORY(flag_strs);
115 for (i = 0; gpo_flags[i].str != NULL; i++) {
116 if (flags & gpo_flags[i].flags) {
117 flag_strs = talloc_realloc(mem_ctx, flag_strs, const char *, count+2);
118 NT_STATUS_HAVE_NO_MEMORY(flag_strs);
119 flag_strs[count] = gpo_flags[i].str;
120 flag_strs[count+1] = NULL;
128 NTSTATUS gp_get_gplink_options(TALLOC_CTX *mem_ctx, uint32_t options, const char ***ret)
130 unsigned int i, count=0;
131 const char **flag_strs = talloc_array(mem_ctx, const char *, 1);
133 NT_STATUS_HAVE_NO_MEMORY(flag_strs);
136 for (i = 0; gplink_options[i].str != NULL; i++) {
137 if (options & gplink_options[i].flags) {
138 flag_strs = talloc_realloc(mem_ctx, flag_strs, const char *, count+2);
139 NT_STATUS_HAVE_NO_MEMORY(flag_strs);
140 flag_strs[count] = gplink_options[i].str;
141 flag_strs[count+1] = NULL;
149 NTSTATUS gp_init(TALLOC_CTX *mem_ctx,
150 struct loadparm_context *lp_ctx,
151 struct cli_credentials *credentials,
152 struct tevent_context *ev_ctx,
153 struct gp_context **gp_ctx)
156 struct libnet_LookupDCs *io;
158 struct libnet_context *net_ctx;
159 struct ldb_context *ldb_ctx;
162 /* Initialise the libnet context */
163 net_ctx = libnet_context_init(ev_ctx, lp_ctx);
164 net_ctx->cred = credentials;
166 /* Prepare libnet lookup structure for looking a DC (PDC is correct). */
167 io = talloc_zero(mem_ctx, struct libnet_LookupDCs);
168 NT_STATUS_HAVE_NO_MEMORY(io);
169 io->in.name_type = NBT_NAME_PDC;
170 io->in.domain_name = lpcfg_workgroup(lp_ctx);
172 /* Find Active DC's */
173 rv = libnet_LookupDCs(net_ctx, mem_ctx, io);
174 if (!NT_STATUS_IS_OK(rv)) {
175 DEBUG(0, ("Failed to lookup DCs in domain\n"));
179 /* Connect to ldap://DC_NAME with all relevant contexts*/
180 url = talloc_asprintf(mem_ctx, "ldap://%s", io->out.dcs[0].name);
181 NT_STATUS_HAVE_NO_MEMORY(url);
182 ldb_ctx = ldb_wrap_connect(mem_ctx, net_ctx->event_ctx, lp_ctx,
183 url, NULL, net_ctx->cred, 0);
184 if (ldb_ctx == NULL) {
185 DEBUG(0, ("Can't connect to DC's LDAP with url %s\n", url));
186 return NT_STATUS_UNSUCCESSFUL;
189 *gp_ctx = talloc_zero(mem_ctx, struct gp_context);
190 NT_STATUS_HAVE_NO_MEMORY(gp_ctx);
192 (*gp_ctx)->lp_ctx = lp_ctx;
193 (*gp_ctx)->credentials = credentials;
194 (*gp_ctx)->ev_ctx = ev_ctx;
195 (*gp_ctx)->ldb_ctx = ldb_ctx;
196 (*gp_ctx)->active_dc = talloc_reference(*gp_ctx, &io->out.dcs[0]);
198 /* We don't need to keep the libnet context */
199 talloc_free(net_ctx);
203 NTSTATUS gp_list_all_gpos(struct gp_context *gp_ctx, struct gp_object ***ret)
205 struct ldb_result *result;
210 struct gp_object **gpo;
211 unsigned int i; /* same as in struct ldb_result */
214 /* Create a forked memory context, as a base for everything here */
215 mem_ctx = talloc_new(gp_ctx);
216 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
218 /* Create full ldb dn of the policies base object */
219 dn = ldb_get_default_basedn(gp_ctx->ldb_ctx);
220 rv = ldb_dn_add_child(dn, ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Policies,CN=System"));
222 DEBUG(0, ("Can't append subtree to DN\n"));
223 talloc_free(mem_ctx);
224 return NT_STATUS_UNSUCCESSFUL;
227 DEBUG(10, ("Searching for policies in DN: %s\n", ldb_dn_get_linearized(dn)));
229 attrs = talloc_array(mem_ctx, const char *, 7);
231 TALLOC_FREE(mem_ctx);
232 return NT_STATUS_NO_MEMORY;
235 attrs[0] = "nTSecurityDescriptor";
236 attrs[1] = "versionNumber";
239 attrs[4] = "displayName";
240 attrs[5] = "gPCFileSysPath";
243 rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_ONELEVEL, attrs, "(objectClass=groupPolicyContainer)");
244 if (rv != LDB_SUCCESS) {
245 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
246 talloc_free(mem_ctx);
247 return NT_STATUS_UNSUCCESSFUL;
250 gpo = talloc_array(gp_ctx, struct gp_object *, result->count+1);
252 TALLOC_FREE(mem_ctx);
253 return NT_STATUS_NO_MEMORY;
256 gpo[result->count] = NULL;
258 for (i = 0; i < result->count; i++) {
259 status = parse_gpo(gp_ctx, result->msgs[i], &gpo[i]);
260 if (!NT_STATUS_IS_OK(status)) {
261 DEBUG(0, ("Failed to parse GPO.\n"));
262 talloc_free(mem_ctx);
267 talloc_free(mem_ctx);
273 NTSTATUS gp_get_gpo_info(struct gp_context *gp_ctx, const char *dn_str, struct gp_object **ret)
275 struct ldb_result *result;
277 struct gp_object *gpo;
283 /* Create a forked memory context, as a base for everything here */
284 mem_ctx = talloc_new(gp_ctx);
285 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
287 /* Create an ldb dn struct for the dn string */
288 dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
290 attrs = talloc_array(mem_ctx, const char *, 7);
292 TALLOC_FREE(mem_ctx);
293 return NT_STATUS_NO_MEMORY;
296 attrs[0] = "nTSecurityDescriptor";
297 attrs[1] = "versionNumber";
300 attrs[4] = "displayName";
301 attrs[5] = "gPCFileSysPath";
304 rv = ldb_search(gp_ctx->ldb_ctx,
310 "objectClass=groupPolicyContainer");
311 if (rv != LDB_SUCCESS) {
312 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
313 talloc_free(mem_ctx);
314 return NT_STATUS_UNSUCCESSFUL;
317 /* We expect exactly one record */
318 if (result->count != 1) {
319 DEBUG(0, ("Could not find GPC with dn %s\n", dn_str));
320 talloc_free(mem_ctx);
321 return NT_STATUS_NOT_FOUND;
324 status = parse_gpo(gp_ctx, result->msgs[0], &gpo);
325 if (!NT_STATUS_IS_OK(status)) {
326 DEBUG(0, ("Failed to parse GPO.\n"));
327 talloc_free(mem_ctx);
331 talloc_free(mem_ctx);
337 static NTSTATUS parse_gplink (TALLOC_CTX *mem_ctx, const char *gplink_str, struct gp_link ***ret)
341 struct gp_link **gplinks;
343 const char *gplink_start = "[LDAP://";
345 gplinks = talloc_array(mem_ctx, struct gp_link *, 1);
346 NT_STATUS_HAVE_NO_MEMORY(gplinks);
350 /* Assuming every gPLink starts with "[LDAP://" */
351 start = strlen(gplink_start);
353 for (pos = start; pos < strlen(gplink_str); pos++) {
354 if (gplink_str[pos] == ';') {
355 gplinks = talloc_realloc(mem_ctx, gplinks, struct gp_link *, idx+2);
356 NT_STATUS_HAVE_NO_MEMORY(gplinks);
357 gplinks[idx] = talloc(mem_ctx, struct gp_link);
358 NT_STATUS_HAVE_NO_MEMORY(gplinks[idx]);
359 gplinks[idx]->dn = talloc_strndup(mem_ctx,
362 if (gplinks[idx]->dn == NULL) {
363 TALLOC_FREE(gplinks);
364 return NT_STATUS_NO_MEMORY;
367 for (start = pos + 1; gplink_str[pos] != ']'; pos++);
369 buf = talloc_strndup(gplinks, gplink_str + start, pos - start);
371 TALLOC_FREE(gplinks);
372 return NT_STATUS_NO_MEMORY;
374 gplinks[idx]->options = (uint32_t) strtoll(buf, &end, 0);
377 /* Set the last entry in the array to be NULL */
378 gplinks[idx + 1] = NULL;
380 /* Increment the array index, the string position past
381 the next "[LDAP://", and set the start reference */
383 pos += strlen(gplink_start)+1;
393 NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *dn_str, struct gp_link ***ret)
397 struct ldb_result *result;
398 struct gp_link **gplinks;
404 /* Create a forked memory context, as a base for everything here */
405 mem_ctx = talloc_new(gp_ctx);
406 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
408 dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
410 rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, NULL, "(objectclass=*)");
411 if (rv != LDB_SUCCESS) {
412 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
413 talloc_free(mem_ctx);
414 return NT_STATUS_UNSUCCESSFUL;
417 for (i = 0; i < result->count; i++) {
418 struct ldb_message_element *element = \
419 ldb_msg_find_element(result->msgs[i], "gPLink");
420 if (element != NULL) {
421 SMB_ASSERT(element->num_values > 0);
422 gplink_str = talloc_strdup(
424 (char *) element->values[0].data);
425 if (gplink_str == NULL) {
426 TALLOC_FREE(mem_ctx);
427 return NT_STATUS_NO_MEMORY;
432 gplink_str = talloc_strdup(mem_ctx, "");
433 if (gplink_str == NULL) {
434 TALLOC_FREE(mem_ctx);
435 return NT_STATUS_NO_MEMORY;
440 status = parse_gplink(gp_ctx, gplink_str, &gplinks);
441 if (!NT_STATUS_IS_OK(status)) {
442 DEBUG(0, ("Failed to parse gPLink\n"));
446 talloc_free(mem_ctx);
452 NTSTATUS gp_list_gpos(struct gp_context *gp_ctx, struct security_token *token, const char ***ret)
456 struct ldb_result *result;
459 struct ldb_message_element *element;
461 const char *attrs[] = { "objectClass", NULL };
464 unsigned int count = 0;
467 ACCOUNT_TYPE_USER = 0,
468 ACCOUNT_TYPE_MACHINE = 1
471 /* Create a forked memory context, as a base for everything here */
472 mem_ctx = talloc_new(gp_ctx);
473 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
475 sid = ldap_encode_ndr_dom_sid(mem_ctx,
476 &token->sids[PRIMARY_USER_SID_INDEX]);
477 NT_STATUS_HAVE_NO_MEMORY(sid);
479 /* Find the user DN and objectclass via the sid from the security token */
480 rv = ldb_search(gp_ctx->ldb_ctx,
483 ldb_get_default_basedn(gp_ctx->ldb_ctx),
486 "(&(objectclass=user)(objectSid=%s))", sid);
487 if (rv != LDB_SUCCESS) {
488 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv),
489 ldb_errstring(gp_ctx->ldb_ctx)));
490 talloc_free(mem_ctx);
491 return NT_STATUS_UNSUCCESSFUL;
493 if (result->count != 1) {
494 DEBUG(0, ("Could not find user with sid %s.\n", sid));
495 talloc_free(mem_ctx);
496 return NT_STATUS_UNSUCCESSFUL;
498 DEBUG(10,("Found DN for this user: %s\n", ldb_dn_get_linearized(result->msgs[0]->dn)));
500 element = ldb_msg_find_element(result->msgs[0], "objectClass");
502 /* We need to know if this account is a user or machine. */
503 account_type = ACCOUNT_TYPE_USER;
504 for (i = 0; i < element->num_values; i++) {
505 if (strcmp((char *)element->values[i].data, "computer") == 0) {
506 account_type = ACCOUNT_TYPE_MACHINE;
507 DEBUG(10, ("This user is a machine\n"));
511 gpos = talloc_array(gp_ctx, const char *, 1);
513 TALLOC_FREE(mem_ctx);
514 return NT_STATUS_NO_MEMORY;
518 /* Walk through the containers until we hit the root */
520 dn = ldb_dn_get_parent(mem_ctx, result->msgs[0]->dn);
521 while (ldb_dn_compare_base(ldb_get_default_basedn(gp_ctx->ldb_ctx), dn) == 0) {
522 const char *gpo_attrs[] = { "gPLink", "gPOptions", NULL };
523 struct gp_link **gplinks;
524 enum gpo_inheritance gpoptions;
526 DEBUG(10, ("Getting gPLinks for DN: %s\n", ldb_dn_get_linearized(dn)));
528 /* Get the gPLink and gPOptions attributes from the container */
529 rv = ldb_search(gp_ctx->ldb_ctx,
536 if (rv != LDB_SUCCESS) {
537 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv),
538 ldb_errstring(gp_ctx->ldb_ctx)));
539 talloc_free(mem_ctx);
540 return NT_STATUS_UNSUCCESSFUL;
543 /* Parse the gPLink attribute, put it into a nice struct array */
544 status = parse_gplink(mem_ctx, ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", ""), &gplinks);
545 if (!NT_STATUS_IS_OK(status)) {
546 DEBUG(0, ("Failed to parse gPLink\n"));
547 talloc_free(mem_ctx);
551 /* Check all group policy links on this container */
552 for (i = 0; gplinks[i] != NULL; i++) {
553 struct gp_object *gpo;
554 uint32_t access_granted;
556 /* If inheritance was blocked at a higher level and this
557 * gplink is not enforced, it should not be applied */
558 if (!inherit && !(gplinks[i]->options & GPLINK_OPT_ENFORCE))
561 /* Don't apply disabled links */
562 if (gplinks[i]->options & GPLINK_OPT_DISABLE)
565 /* Get GPO information */
566 status = gp_get_gpo_info(gp_ctx, gplinks[i]->dn, &gpo);
567 if (!NT_STATUS_IS_OK(status)) {
568 DEBUG(0, ("Failed to get gpo information for %s\n", gplinks[i]->dn));
569 talloc_free(mem_ctx);
573 /* If the account does not have read access, this GPO does not apply
575 status = se_access_check(gpo->security_descriptor,
577 (SEC_STD_READ_CONTROL | SEC_ADS_LIST | SEC_ADS_READ_PROP),
579 if (!NT_STATUS_IS_OK(status)) {
583 /* If the account is a user and the GPO has user disabled flag, or
584 * a machine and the GPO has machine disabled flag, this GPO does
585 * not apply to this account */
586 if ((account_type == ACCOUNT_TYPE_USER &&
587 (gpo->flags & GPO_FLAG_USER_DISABLE)) ||
588 (account_type == ACCOUNT_TYPE_MACHINE &&
589 (gpo->flags & GPO_FLAG_MACHINE_DISABLE))) {
593 /* Add the GPO to the list */
594 gpos = talloc_realloc(gp_ctx, gpos, const char *, count+2);
596 TALLOC_FREE(mem_ctx);
597 return NT_STATUS_NO_MEMORY;
599 gpos[count] = talloc_strdup(gp_ctx, gplinks[i]->dn);
600 if (gpos[count] == NULL) {
601 TALLOC_FREE(mem_ctx);
602 return NT_STATUS_NO_MEMORY;
604 gpos[count+1] = NULL;
611 /* If inheritance is blocked, then we should only add enforced gPLinks
613 gpoptions = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
614 if (gpoptions == GPO_BLOCK_INHERITANCE) {
617 dn = ldb_dn_get_parent(mem_ctx, dn);
620 talloc_free(mem_ctx);
626 NTSTATUS gp_set_gplink(struct gp_context *gp_ctx, const char *dn_str, struct gp_link *gplink)
629 struct ldb_result *result;
631 struct ldb_message *msg;
632 const char *attrs[] = { "gPLink", NULL };
633 const char *gplink_str;
637 /* Create a forked memory context, as a base for everything here */
638 mem_ctx = talloc_new(gp_ctx);
639 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
641 dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
643 rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
644 if (rv != LDB_SUCCESS) {
645 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
646 talloc_free(mem_ctx);
647 return NT_STATUS_UNSUCCESSFUL;
650 if (result->count != 1) {
651 talloc_free(mem_ctx);
652 return NT_STATUS_NOT_FOUND;
655 gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
657 /* If this GPO link already exists, alter the options, else add it */
658 if ((start = strcasestr(gplink_str, gplink->dn)) != NULL) {
659 start += strlen(gplink->dn);
662 while (*start != ']' && *start != '\0') {
665 gplink_str = talloc_asprintf(mem_ctx, "%s;%d%s", gplink_str, gplink->options, start);
666 if (gplink_str == NULL) {
667 TALLOC_FREE(mem_ctx);
668 return NT_STATUS_NO_MEMORY;
672 /* Prepend the new GPO link to the string. This list is backwards in priority. */
673 gplink_str = talloc_asprintf(mem_ctx, "[LDAP://%s;%d]%s", gplink->dn, gplink->options, gplink_str);
674 if (gplink_str == NULL) {
675 TALLOC_FREE(mem_ctx);
676 return NT_STATUS_NO_MEMORY;
682 msg = ldb_msg_new(mem_ctx);
684 TALLOC_FREE(mem_ctx);
685 return NT_STATUS_NO_MEMORY;
690 rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
691 if (rv != LDB_SUCCESS) {
692 DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
693 talloc_free(mem_ctx);
694 return NT_STATUS_UNSUCCESSFUL;
696 msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
698 rv = ldb_modify(gp_ctx->ldb_ctx, msg);
699 if (rv != LDB_SUCCESS) {
700 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
701 talloc_free(mem_ctx);
702 return NT_STATUS_UNSUCCESSFUL;
705 talloc_free(mem_ctx);
709 NTSTATUS gp_del_gplink(struct gp_context *gp_ctx, const char *dn_str, const char *gplink_dn)
712 struct ldb_result *result;
714 struct ldb_message *msg;
715 const char *attrs[] = { "gPLink", NULL };
716 const char *gplink_str, *search_string;
720 /* Create a forked memory context, as a base for everything here */
721 mem_ctx = talloc_new(gp_ctx);
722 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
724 dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
726 rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
727 if (rv != LDB_SUCCESS) {
728 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
729 talloc_free(mem_ctx);
730 return NT_STATUS_UNSUCCESSFUL;
733 if (result->count != 1) {
734 talloc_free(mem_ctx);
735 return NT_STATUS_NOT_FOUND;
738 gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
740 /* If this GPO link already exists, alter the options, else add it */
741 search_string = talloc_asprintf(mem_ctx, "[LDAP://%s]", gplink_dn);
742 if (search_string == NULL) {
743 TALLOC_FREE(mem_ctx);
744 return NT_STATUS_NO_MEMORY;
747 p = strcasestr(gplink_str, search_string);
749 talloc_free(mem_ctx);
750 return NT_STATUS_NOT_FOUND;
755 while (*p != ']' && *p != '\0') {
759 gplink_str = talloc_asprintf(mem_ctx, "%s%s", gplink_str, p);
760 if (gplink_str == NULL) {
761 TALLOC_FREE(mem_ctx);
762 return NT_STATUS_NO_MEMORY;
766 msg = ldb_msg_new(mem_ctx);
768 TALLOC_FREE(mem_ctx);
769 return NT_STATUS_NO_MEMORY;
774 if (strcmp(gplink_str, "") == 0) {
775 rv = ldb_msg_add_empty(msg, "gPLink", LDB_FLAG_MOD_DELETE, NULL);
776 if (rv != LDB_SUCCESS) {
777 DEBUG(0, ("LDB message add empty element failed: %s\n", ldb_strerror(rv)));
778 talloc_free(mem_ctx);
779 return NT_STATUS_UNSUCCESSFUL;
782 rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
783 if (rv != LDB_SUCCESS) {
784 DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
785 talloc_free(mem_ctx);
786 return NT_STATUS_UNSUCCESSFUL;
788 msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
790 rv = ldb_modify(gp_ctx->ldb_ctx, msg);
791 if (rv != LDB_SUCCESS) {
792 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
793 talloc_free(mem_ctx);
794 return NT_STATUS_UNSUCCESSFUL;
797 talloc_free(mem_ctx);
801 NTSTATUS gp_get_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance *inheritance)
804 struct ldb_result *result;
806 const char *attrs[] = { "gPOptions", NULL };
809 /* Create a forked memory context, as a base for everything here */
810 mem_ctx = talloc_new(gp_ctx);
811 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
813 dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
815 rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
816 if (rv != LDB_SUCCESS) {
817 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
818 talloc_free(mem_ctx);
819 return NT_STATUS_UNSUCCESSFUL;
822 if (result->count != 1) {
823 talloc_free(mem_ctx);
824 return NT_STATUS_NOT_FOUND;
827 *inheritance = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
829 talloc_free(mem_ctx);
833 NTSTATUS gp_set_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance inheritance)
835 char *inheritance_string;
836 struct ldb_message *msg;
839 msg = ldb_msg_new(gp_ctx);
840 NT_STATUS_HAVE_NO_MEMORY(msg);
842 msg->dn = ldb_dn_new(msg, gp_ctx->ldb_ctx, dn_str);
844 inheritance_string = talloc_asprintf(msg, "%d", inheritance);
845 if (inheritance_string == NULL) {
847 return NT_STATUS_NO_MEMORY;
850 rv = ldb_msg_add_string(msg, "gPOptions", inheritance_string);
851 if (rv != LDB_SUCCESS) {
852 DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
854 return NT_STATUS_UNSUCCESSFUL;
856 msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
858 rv = ldb_modify(gp_ctx->ldb_ctx, msg);
859 if (rv != LDB_SUCCESS) {
860 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
862 return NT_STATUS_UNSUCCESSFUL;
869 NTSTATUS gp_create_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo)
871 struct ldb_message *msg;
874 char *dn_str, *flags_str, *version_str;
875 struct ldb_dn *child_dn, *gpo_dn;
877 mem_ctx = talloc_new(gp_ctx);
878 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
881 msg = ldb_msg_new(mem_ctx);
883 TALLOC_FREE(mem_ctx);
884 return NT_STATUS_NO_MEMORY;
887 msg->dn = ldb_get_default_basedn(gp_ctx->ldb_ctx);
888 dn_str = talloc_asprintf(mem_ctx, "CN=%s,CN=Policies,CN=System", gpo->name);
889 if (dn_str == NULL) {
890 TALLOC_FREE(mem_ctx);
891 return NT_STATUS_NO_MEMORY;
894 child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
895 rv = ldb_dn_add_child(msg->dn, child_dn);
896 if (!rv) goto ldb_msg_add_error;
898 flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
899 if (flags_str == NULL) {
900 TALLOC_FREE(mem_ctx);
901 return NT_STATUS_NO_MEMORY;
904 version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
905 if (version_str == NULL) {
906 TALLOC_FREE(mem_ctx);
907 return NT_STATUS_NO_MEMORY;
910 rv = ldb_msg_add_string(msg, "objectClass", "top");
911 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
912 rv = ldb_msg_add_string(msg, "objectClass", "container");
913 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
914 rv = ldb_msg_add_string(msg, "objectClass", "groupPolicyContainer");
915 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
916 rv = ldb_msg_add_string(msg, "displayName", gpo->display_name);
917 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
918 rv = ldb_msg_add_string(msg, "name", gpo->name);
919 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
920 rv = ldb_msg_add_string(msg, "CN", gpo->name);
921 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
922 rv = ldb_msg_add_string(msg, "gPCFileSysPath", gpo->file_sys_path);
923 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
924 rv = ldb_msg_add_string(msg, "flags", flags_str);
925 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
926 rv = ldb_msg_add_string(msg, "versionNumber", version_str);
927 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
928 rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
929 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
930 rv = ldb_msg_add_string(msg, "gpCFunctionalityVersion", "2");
931 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
933 rv = ldb_add(gp_ctx->ldb_ctx, msg);
934 if (rv != LDB_SUCCESS) {
935 DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
936 talloc_free(mem_ctx);
937 return NT_STATUS_UNSUCCESSFUL;
943 msg = ldb_msg_new(mem_ctx);
945 TALLOC_FREE(mem_ctx);
946 return NT_STATUS_NO_MEMORY;
949 msg->dn = ldb_dn_copy(mem_ctx, gpo_dn);
950 child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=User");
951 rv = ldb_dn_add_child(msg->dn, child_dn);
952 if (!rv) goto ldb_msg_add_error;
954 rv = ldb_msg_add_string(msg, "objectClass", "top");
955 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
956 rv = ldb_msg_add_string(msg, "objectClass", "container");
957 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
958 rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
959 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
960 rv = ldb_msg_add_string(msg, "CN", "User");
961 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
962 rv = ldb_msg_add_string(msg, "name", "User");
963 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
965 rv = ldb_add(gp_ctx->ldb_ctx, msg);
966 if (rv != LDB_SUCCESS) {
967 DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
968 talloc_free(mem_ctx);
969 return NT_STATUS_UNSUCCESSFUL;
973 msg = ldb_msg_new(mem_ctx);
975 TALLOC_FREE(mem_ctx);
976 return NT_STATUS_NO_MEMORY;
979 msg->dn = ldb_dn_copy(mem_ctx, gpo_dn);
980 child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Machine");
981 rv = ldb_dn_add_child(msg->dn, child_dn);
982 if (!rv) goto ldb_msg_add_error;
984 rv = ldb_msg_add_string(msg, "objectClass", "top");
985 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
986 rv = ldb_msg_add_string(msg, "objectClass", "container");
987 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
988 rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
989 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
990 rv = ldb_msg_add_string(msg, "CN", "Machine");
991 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
992 rv = ldb_msg_add_string(msg, "name", "Machine");
993 if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
995 rv = ldb_add(gp_ctx->ldb_ctx, msg);
996 if (rv != LDB_SUCCESS) {
997 DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
998 talloc_free(mem_ctx);
999 return NT_STATUS_UNSUCCESSFUL;
1002 gpo->dn = talloc_strdup(gpo, ldb_dn_get_linearized(gpo_dn));
1003 if (gpo->dn == NULL) {
1004 TALLOC_FREE(mem_ctx);
1005 return NT_STATUS_NO_MEMORY;
1008 talloc_free(mem_ctx);
1009 return NT_STATUS_OK;
1012 DEBUG(0, ("LDB Error adding element to ldb message\n"));
1013 talloc_free(mem_ctx);
1014 return NT_STATUS_UNSUCCESSFUL;
1017 NTSTATUS gp_set_ads_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd)
1019 TALLOC_CTX *mem_ctx;
1021 enum ndr_err_code ndr_err;
1022 struct ldb_message *msg;
1025 /* Create a forked memory context to clean up easily */
1026 mem_ctx = talloc_new(gp_ctx);
1027 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
1029 /* Push the security descriptor through the NDR library */
1030 ndr_err = ndr_push_struct_blob(&data,
1033 (ndr_push_flags_fn_t)ndr_push_security_descriptor);
1034 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1035 return ndr_map_error2ntstatus(ndr_err);
1039 /* Create a LDB message */
1040 msg = ldb_msg_new(mem_ctx);
1042 TALLOC_FREE(mem_ctx);
1043 return NT_STATUS_NO_MEMORY;
1046 msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
1048 rv = ldb_msg_add_value(msg, "nTSecurityDescriptor", &data, NULL);
1049 if (rv != LDB_SUCCESS) {
1050 DEBUG(0, ("LDB message add element failed for adding nTSecurityDescriptor: %s\n", ldb_strerror(rv)));
1051 talloc_free(mem_ctx);
1052 return NT_STATUS_UNSUCCESSFUL;
1054 msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
1056 rv = ldb_modify(gp_ctx->ldb_ctx, msg);
1057 if (rv != LDB_SUCCESS) {
1058 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
1059 talloc_free(mem_ctx);
1060 return NT_STATUS_UNSUCCESSFUL;
1063 talloc_free(mem_ctx);
1064 return NT_STATUS_OK;
1067 /* This function sets flags, version and displayName on a GPO */
1068 NTSTATUS gp_set_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo)
1071 TALLOC_CTX *mem_ctx;
1072 struct ldb_message *msg;
1073 char *version_str, *flags_str;
1075 mem_ctx = talloc_new(gp_ctx);
1077 msg = ldb_msg_new(mem_ctx);
1079 TALLOC_FREE(mem_ctx);
1080 return NT_STATUS_NO_MEMORY;
1083 msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, gpo->dn);
1085 version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
1087 TALLOC_FREE(mem_ctx);
1088 return NT_STATUS_NO_MEMORY;
1091 flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
1093 TALLOC_FREE(mem_ctx);
1094 return NT_STATUS_NO_MEMORY;
1097 rv = ldb_msg_add_string(msg, "flags", flags_str);
1098 if (rv != LDB_SUCCESS) {
1099 DEBUG(0, ("LDB message add string failed for flags: %s\n", ldb_strerror(rv)));
1100 talloc_free(mem_ctx);
1101 return NT_STATUS_UNSUCCESSFUL;
1103 msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
1105 rv = ldb_msg_add_string(msg, "version", version_str);
1106 if (rv != LDB_SUCCESS) {
1107 DEBUG(0, ("LDB message add string failed for version: %s\n", ldb_strerror(rv)));
1108 talloc_free(mem_ctx);
1109 return NT_STATUS_UNSUCCESSFUL;
1111 msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
1113 rv = ldb_msg_add_string(msg, "displayName", gpo->display_name);
1114 if (rv != LDB_SUCCESS) {
1115 DEBUG(0, ("LDB message add string failed for displayName: %s\n", ldb_strerror(rv)));
1116 talloc_free(mem_ctx);
1117 return NT_STATUS_UNSUCCESSFUL;
1119 msg->elements[2].flags = LDB_FLAG_MOD_REPLACE;
1121 rv = ldb_modify(gp_ctx->ldb_ctx, msg);
1122 if (rv != LDB_SUCCESS) {
1123 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
1124 talloc_free(mem_ctx);
1125 return NT_STATUS_UNSUCCESSFUL;
1128 talloc_free(mem_ctx);
1129 return NT_STATUS_OK;