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 },
48
static const struct gpo_stringmap gpo_inheritance [] = {
49
{ "GPO_INHERIT", GPO_INHERIT },
50
{ "GPO_BLOCK_INHERITANCE", GPO_BLOCK_INHERITANCE },
55
static NTSTATUS parse_gpo(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct gp_object **ret)
57
struct gp_object *gpo = talloc(mem_ctx, struct gp_object);
58
enum ndr_err_code ndr_err;
59
const DATA_BLOB *data;
61
NT_STATUS_HAVE_NO_MEMORY(gpo);
63
gpo->dn = talloc_strdup(mem_ctx, ldb_dn_get_linearized(msg->dn));
64
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->dn, gpo);
66
DEBUG(9, ("Parsing GPO LDAP data for %s\n", gpo->dn));
68
gpo->display_name = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "displayName", ""));
69
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->display_name, gpo);
71
gpo->name = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "name", ""));
72
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->name, gpo);
74
gpo->flags = ldb_msg_find_attr_as_uint(msg, "flags", 0);
75
gpo->version = ldb_msg_find_attr_as_uint(msg, "versionNumber", 0);
77
gpo->file_sys_path = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "gPCFileSysPath", ""));
78
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->file_sys_path, gpo);
80
/* Pull the security descriptor through the NDR library */
81
data = ldb_msg_find_ldb_val(msg, "nTSecurityDescriptor");
82
gpo->security_descriptor = talloc(gpo, struct security_descriptor);
83
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->security_descriptor, gpo);
85
ndr_err = ndr_pull_struct_blob(data,
87
gpo->security_descriptor,
88
(ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
89
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
90
return ndr_map_error2ntstatus(ndr_err);
97
NTSTATUS gp_get_gpo_flags(TALLOC_CTX *mem_ctx, uint32_t flags, const char ***ret)
99
unsigned int i, count=0;
100
const char **flag_strs = talloc_array(mem_ctx, const char *, 1);
102
NT_STATUS_HAVE_NO_MEMORY(flag_strs);
106
for (i = 0; gpo_flags[i].str != NULL; i++) {
107
if (flags & gpo_flags[i].flags) {
108
flag_strs = talloc_realloc(mem_ctx, flag_strs, const char *, count+2);
109
NT_STATUS_HAVE_NO_MEMORY(flag_strs);
110
flag_strs[count] = gpo_flags[i].str;
111
flag_strs[count+1] = NULL;
119
NTSTATUS gp_get_gplink_options(TALLOC_CTX *mem_ctx, uint32_t options, const char ***ret)
121
unsigned int i, count=0;
122
const char **flag_strs = talloc_array(mem_ctx, const char *, 1);
124
NT_STATUS_HAVE_NO_MEMORY(flag_strs);
127
for (i = 0; gplink_options[i].str != NULL; i++) {
128
if (options & gplink_options[i].flags) {
129
flag_strs = talloc_realloc(mem_ctx, flag_strs, const char *, count+2);
130
NT_STATUS_HAVE_NO_MEMORY(flag_strs);
131
flag_strs[count] = gplink_options[i].str;
132
flag_strs[count+1] = NULL;
140
NTSTATUS gp_init(TALLOC_CTX *mem_ctx,
141
struct loadparm_context *lp_ctx,
142
struct cli_credentials *credentials,
143
struct tevent_context *ev_ctx,
144
struct gp_context **gp_ctx)
147
struct libnet_LookupDCs *io;
149
struct libnet_context *net_ctx;
150
struct ldb_context *ldb_ctx;
153
/* Initialise the libnet context */
154
net_ctx = libnet_context_init(ev_ctx, lp_ctx);
155
net_ctx->cred = credentials;
157
/* Prepare libnet lookup structure for looking a DC (PDC is correct). */
158
io = talloc_zero(mem_ctx, struct libnet_LookupDCs);
159
NT_STATUS_HAVE_NO_MEMORY(io);
160
io->in.name_type = NBT_NAME_PDC;
161
io->in.domain_name = lpcfg_workgroup(lp_ctx);
163
/* Find Active DC's */
164
rv = libnet_LookupDCs(net_ctx, mem_ctx, io);
165
if (!NT_STATUS_IS_OK(rv)) {
166
DEBUG(0, ("Failed to lookup DCs in domain\n"));
170
/* Connect to ldap://DC_NAME with all relevant contexts*/
171
url = talloc_asprintf(mem_ctx, "ldap://%s", io->out.dcs[0].name);
172
NT_STATUS_HAVE_NO_MEMORY(url);
173
ldb_ctx = ldb_wrap_connect(mem_ctx, net_ctx->event_ctx, lp_ctx,
174
url, NULL, net_ctx->cred, 0);
175
if (ldb_ctx == NULL) {
176
DEBUG(0, ("Can't connect to DC's LDAP with url %s\n", url));
177
return NT_STATUS_UNSUCCESSFUL;
181
*gp_ctx = talloc_zero(mem_ctx, struct gp_context);
182
NT_STATUS_HAVE_NO_MEMORY(gp_ctx);
184
(*gp_ctx)->lp_ctx = lp_ctx;
185
(*gp_ctx)->credentials = credentials;
186
(*gp_ctx)->ev_ctx = ev_ctx;
187
(*gp_ctx)->ldb_ctx = ldb_ctx;
188
(*gp_ctx)->active_dc = io->out.dcs[0];
190
/* We don't need to keep the libnet context */
191
talloc_free(net_ctx);
195
NTSTATUS gp_list_all_gpos(struct gp_context *gp_ctx, struct gp_object ***ret)
197
struct ldb_result *result;
202
struct gp_object **gpo;
203
unsigned int i; /* same as in struct ldb_result */
206
/* Create a forked memory context, as a base for everything here */
207
mem_ctx = talloc_new(gp_ctx);
208
NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
210
/* Create full ldb dn of the policies base object */
211
dn = ldb_get_default_basedn(gp_ctx->ldb_ctx);
212
rv = ldb_dn_add_child(dn, ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Policies,CN=System"));
214
DEBUG(0, ("Can't append subtree to DN\n"));
215
talloc_free(mem_ctx);
216
return NT_STATUS_UNSUCCESSFUL;
219
DEBUG(10, ("Searching for policies in DN: %s\n", ldb_dn_get_linearized(dn)));
221
attrs = talloc_array(mem_ctx, const char *, 7);
222
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(attrs, mem_ctx);
224
attrs[0] = "nTSecurityDescriptor";
225
attrs[1] = "versionNumber";
228
attrs[4] = "displayName";
229
attrs[5] = "gPCFileSysPath";
232
rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_ONELEVEL, attrs, "(objectClass=groupPolicyContainer)");
233
if (rv != LDB_SUCCESS) {
234
DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
235
talloc_free(mem_ctx);
236
return NT_STATUS_UNSUCCESSFUL;
239
gpo = talloc_array(gp_ctx, struct gp_object *, result->count+1);
240
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo, mem_ctx);
242
gpo[result->count] = NULL;
244
for (i = 0; i < result->count; i++) {
245
status = parse_gpo(gp_ctx, result->msgs[i], &gpo[i]);
246
if (!NT_STATUS_IS_OK(status)) {
247
DEBUG(0, ("Failed to parse GPO.\n"));
248
talloc_free(mem_ctx);
253
talloc_free(mem_ctx);
259
NTSTATUS gp_get_gpo_info(struct gp_context *gp_ctx, const char *dn_str, struct gp_object **ret)
261
struct ldb_result *result;
263
struct gp_object *gpo;
269
/* Create a forked memory context, as a base for everything here */
270
mem_ctx = talloc_new(gp_ctx);
271
NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
273
/* Create an ldb dn struct for the dn string */
274
dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
276
attrs = talloc_array(mem_ctx, const char *, 7);
277
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(attrs, mem_ctx);
279
attrs[0] = "nTSecurityDescriptor";
280
attrs[1] = "versionNumber";
283
attrs[4] = "displayName";
284
attrs[5] = "gPCFileSysPath";
287
rv = ldb_search(gp_ctx->ldb_ctx,
293
"objectClass=groupPolicyContainer");
294
if (rv != LDB_SUCCESS) {
295
DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
296
talloc_free(mem_ctx);
297
return NT_STATUS_UNSUCCESSFUL;
300
/* We expect exactly one record */
301
if (result->count != 1) {
302
DEBUG(0, ("Could not find GPC with dn %s\n", dn_str));
303
talloc_free(mem_ctx);
304
return NT_STATUS_NOT_FOUND;
307
status = parse_gpo(gp_ctx, result->msgs[0], &gpo);
308
if (!NT_STATUS_IS_OK(status)) {
309
DEBUG(0, ("Failed to parse GPO.\n"));
310
talloc_free(mem_ctx);
314
talloc_free(mem_ctx);
320
static NTSTATUS parse_gplink (TALLOC_CTX *mem_ctx, const char *gplink_str, struct gp_link ***ret)
324
struct gp_link **gplinks;
326
const char *gplink_start = "[LDAP://";
328
gplinks = talloc_array(mem_ctx, struct gp_link *, 1);
329
NT_STATUS_HAVE_NO_MEMORY(gplinks);
333
/* Assuming every gPLink starts with "[LDAP://" */
334
start = strlen(gplink_start);
336
for (pos = start; pos < strlen(gplink_str); pos++) {
337
if (gplink_str[pos] == ';') {
338
gplinks = talloc_realloc(mem_ctx, gplinks, struct gp_link *, idx+2);
339
NT_STATUS_HAVE_NO_MEMORY(gplinks);
340
gplinks[idx] = talloc(mem_ctx, struct gp_link);
341
NT_STATUS_HAVE_NO_MEMORY(gplinks[idx]);
342
gplinks[idx]->dn = talloc_strndup(mem_ctx,
345
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplinks[idx]->dn, gplinks);
347
for (start = pos + 1; gplink_str[pos] != ']'; pos++);
349
buf = talloc_strndup(gplinks, gplink_str + start, pos - start);
350
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(buf, gplinks);
351
gplinks[idx]->options = (uint32_t) strtoll(buf, &end, 0);
354
/* Set the last entry in the array to be NULL */
355
gplinks[idx + 1] = NULL;
357
/* Increment the array index, the string position past
358
the next "[LDAP://", and set the start reference */
360
pos += strlen(gplink_start)+1;
370
NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *dn_str, struct gp_link ***ret)
374
struct ldb_result *result;
375
struct gp_link **gplinks;
381
/* Create a forked memory context, as a base for everything here */
382
mem_ctx = talloc_new(gp_ctx);
383
NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
385
dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
387
rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, NULL, "(objectclass=*)");
388
if (rv != LDB_SUCCESS) {
389
DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
390
talloc_free(mem_ctx);
391
return NT_STATUS_UNSUCCESSFUL;
394
for (i = 0; i < result->count; i++) {
395
for (j = 0; j < result->msgs[i]->num_elements; j++) {
396
struct ldb_message_element *element = &result->msgs[i]->elements[j];
398
if (strcmp(element->name, "gPLink") == 0) {
399
SMB_ASSERT(element->num_values > 0);
400
gplink_str = talloc_strdup(mem_ctx, (char *) element->values[0].data);
401
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
406
gplink_str = talloc_strdup(mem_ctx, "");
407
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
411
status = parse_gplink(gp_ctx, gplink_str, &gplinks);
412
if (!NT_STATUS_IS_OK(status)) {
413
DEBUG(0, ("Failed to parse gPLink\n"));
417
talloc_free(mem_ctx);
423
NTSTATUS gp_list_gpos(struct gp_context *gp_ctx, struct security_token *token, const char ***ret)
427
struct ldb_result *result;
430
struct ldb_message_element *element;
432
const char *attrs[] = { "objectClass", NULL };
435
unsigned int count = 0;
438
ACCOUNT_TYPE_USER = 0,
439
ACCOUNT_TYPE_MACHINE = 1
442
/* Create a forked memory context, as a base for everything here */
443
mem_ctx = talloc_new(gp_ctx);
444
NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
446
sid = ldap_encode_ndr_dom_sid(mem_ctx,
447
&token->sids[PRIMARY_USER_SID_INDEX]);
448
NT_STATUS_HAVE_NO_MEMORY(sid);
450
/* Find the user DN and objectclass via the sid from the security token */
451
rv = ldb_search(gp_ctx->ldb_ctx,
454
ldb_get_default_basedn(gp_ctx->ldb_ctx),
457
"(&(objectclass=user)(objectSid=%s))", sid);
458
if (rv != LDB_SUCCESS) {
459
DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv),
460
ldb_errstring(gp_ctx->ldb_ctx)));
461
talloc_free(mem_ctx);
462
return NT_STATUS_UNSUCCESSFUL;
464
if (result->count != 1) {
465
DEBUG(0, ("Could not find user with sid %s.\n", sid));
466
talloc_free(mem_ctx);
467
return NT_STATUS_UNSUCCESSFUL;
469
DEBUG(10,("Found DN for this user: %s\n", ldb_dn_get_linearized(result->msgs[0]->dn)));
471
element = ldb_msg_find_element(result->msgs[0], "objectClass");
473
/* We need to know if this account is a user or machine. */
474
account_type = ACCOUNT_TYPE_USER;
475
for (i = 0; i < element->num_values; i++) {
476
if (strcmp((char *)element->values[i].data, "computer") == 0) {
477
account_type = ACCOUNT_TYPE_MACHINE;
478
DEBUG(10, ("This user is a machine\n"));
482
gpos = talloc_array(gp_ctx, const char *, 1);
483
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpos, mem_ctx);
486
/* Walk through the containers until we hit the root */
488
dn = ldb_dn_get_parent(mem_ctx, result->msgs[0]->dn);
489
while (ldb_dn_compare_base(ldb_get_default_basedn(gp_ctx->ldb_ctx), dn) == 0) {
490
const char *gpo_attrs[] = { "gPLink", "gPOptions", NULL };
491
struct gp_link **gplinks;
492
enum gpo_inheritance gpoptions;
494
DEBUG(10, ("Getting gPLinks for DN: %s\n", ldb_dn_get_linearized(dn)));
496
/* Get the gPLink and gPOptions attributes from the container */
497
rv = ldb_search(gp_ctx->ldb_ctx,
504
if (rv != LDB_SUCCESS) {
505
DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv),
506
ldb_errstring(gp_ctx->ldb_ctx)));
507
talloc_free(mem_ctx);
508
return NT_STATUS_UNSUCCESSFUL;
511
/* Parse the gPLink attribute, put it into a nice struct array */
512
status = parse_gplink(mem_ctx, ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", ""), &gplinks);
513
if (!NT_STATUS_IS_OK(status)) {
514
DEBUG(0, ("Failed to parse gPLink\n"));
515
talloc_free(mem_ctx);
519
/* Check all group policy links on this container */
520
for (i = 0; gplinks[i] != NULL; i++) {
521
struct gp_object *gpo;
522
uint32_t access_granted;
524
/* If inheritance was blocked at a higher level and this
525
* gplink is not enforced, it should not be applied */
526
if (!inherit && !(gplinks[i]->options & GPLINK_OPT_ENFORCE))
529
/* Don't apply disabled links */
530
if (gplinks[i]->options & GPLINK_OPT_DISABLE)
533
/* Get GPO information */
534
status = gp_get_gpo_info(gp_ctx, gplinks[i]->dn, &gpo);
535
if (!NT_STATUS_IS_OK(status)) {
536
DEBUG(0, ("Failed to get gpo information for %s\n", gplinks[i]->dn));
537
talloc_free(mem_ctx);
541
/* If the account does not have read access, this GPO does not apply
543
status = se_access_check(gpo->security_descriptor,
545
(SEC_STD_READ_CONTROL | SEC_ADS_LIST | SEC_ADS_READ_PROP),
547
if (!NT_STATUS_IS_OK(status)) {
551
/* If the account is a user and the GPO has user disabled flag, or
552
* a machine and the GPO has machine disabled flag, this GPO does
553
* not apply to this account */
554
if ((account_type == ACCOUNT_TYPE_USER &&
555
(gpo->flags & GPO_FLAG_USER_DISABLE)) ||
556
(account_type == ACCOUNT_TYPE_MACHINE &&
557
(gpo->flags & GPO_FLAG_MACHINE_DISABLE))) {
561
/* Add the GPO to the list */
562
gpos = talloc_realloc(gp_ctx, gpos, const char *, count+2);
563
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpos, mem_ctx);
564
gpos[count] = talloc_strdup(gp_ctx, gplinks[i]->dn);
565
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpos[count], mem_ctx);
566
gpos[count+1] = NULL;
573
/* If inheritance is blocked, then we should only add enforced gPLinks
575
gpoptions = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
576
if (gpoptions == GPO_BLOCK_INHERITANCE) {
579
dn = ldb_dn_get_parent(mem_ctx, dn);
582
talloc_free(mem_ctx);
588
NTSTATUS gp_set_gplink(struct gp_context *gp_ctx, const char *dn_str, struct gp_link *gplink)
591
struct ldb_result *result;
593
struct ldb_message *msg;
594
const char *attrs[] = { "gPLink", NULL };
595
const char *gplink_str;
599
/* Create a forked memory context, as a base for everything here */
600
mem_ctx = talloc_new(gp_ctx);
601
NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
603
dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
605
rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
606
if (rv != LDB_SUCCESS) {
607
DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
608
talloc_free(mem_ctx);
609
return NT_STATUS_UNSUCCESSFUL;
612
if (result->count != 1) {
613
talloc_free(mem_ctx);
614
return NT_STATUS_NOT_FOUND;
617
gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
619
/* If this GPO link already exists, alter the options, else add it */
620
if ((start = strcasestr(gplink_str, gplink->dn)) != NULL) {
621
start += strlen(gplink->dn);
624
while (*start != ']' && *start != '\0') {
627
gplink_str = talloc_asprintf(mem_ctx, "%s;%d%s", gplink_str, gplink->options, start);
628
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
631
/* Prepend the new GPO link to the string. This list is backwards in priority. */
632
gplink_str = talloc_asprintf(mem_ctx, "[LDAP://%s;%d]%s", gplink->dn, gplink->options, gplink_str);
633
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
638
msg = ldb_msg_new(mem_ctx);
639
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
643
rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
645
DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
646
talloc_free(mem_ctx);
647
return NT_STATUS_UNSUCCESSFUL;
649
msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
651
rv = ldb_modify(gp_ctx->ldb_ctx, msg);
653
DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
654
talloc_free(mem_ctx);
655
return NT_STATUS_UNSUCCESSFUL;
658
talloc_free(mem_ctx);
662
NTSTATUS gp_del_gplink(struct gp_context *gp_ctx, const char *dn_str, const char *gplink_dn)
665
struct ldb_result *result;
667
struct ldb_message *msg;
668
const char *attrs[] = { "gPLink", NULL };
669
const char *gplink_str, *search_string;
673
/* Create a forked memory context, as a base for everything here */
674
mem_ctx = talloc_new(gp_ctx);
675
NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
677
dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
679
rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
680
if (rv != LDB_SUCCESS) {
681
DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
682
talloc_free(mem_ctx);
683
return NT_STATUS_UNSUCCESSFUL;
686
if (result->count != 1) {
687
talloc_free(mem_ctx);
688
return NT_STATUS_NOT_FOUND;
691
gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
693
/* If this GPO link already exists, alter the options, else add it */
694
search_string = talloc_asprintf(mem_ctx, "[LDAP://%s]", gplink_dn);
695
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(search_string, mem_ctx);
697
p = strcasestr(gplink_str, search_string);
699
talloc_free(mem_ctx);
700
return NT_STATUS_NOT_FOUND;
705
while (*p != ']' && *p != '\0') {
709
gplink_str = talloc_asprintf(mem_ctx, "%s%s", gplink_str, p);
710
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
713
msg = ldb_msg_new(mem_ctx);
714
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
718
if (strcmp(gplink_str, "") == 0) {
719
rv = ldb_msg_add_empty(msg, "gPLink", LDB_FLAG_MOD_DELETE, NULL);
721
DEBUG(0, ("LDB message add empty element failed: %s\n", ldb_strerror(rv)));
722
talloc_free(mem_ctx);
723
return NT_STATUS_UNSUCCESSFUL;
726
rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
728
DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
729
talloc_free(mem_ctx);
730
return NT_STATUS_UNSUCCESSFUL;
732
msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
734
rv = ldb_modify(gp_ctx->ldb_ctx, msg);
736
DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
737
talloc_free(mem_ctx);
738
return NT_STATUS_UNSUCCESSFUL;
741
talloc_free(mem_ctx);
745
NTSTATUS gp_get_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance *inheritance)
748
struct ldb_result *result;
750
const char *attrs[] = { "gPOptions", NULL };
753
/* Create a forked memory context, as a base for everything here */
754
mem_ctx = talloc_new(gp_ctx);
755
NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
757
dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
759
rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
760
if (rv != LDB_SUCCESS) {
761
DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
762
talloc_free(mem_ctx);
763
return NT_STATUS_UNSUCCESSFUL;
766
if (result->count != 1) {
767
talloc_free(mem_ctx);
768
return NT_STATUS_NOT_FOUND;
771
*inheritance = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
773
talloc_free(mem_ctx);
777
NTSTATUS gp_set_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance inheritance)
779
char *inheritance_string;
780
struct ldb_message *msg;
783
msg = ldb_msg_new(gp_ctx);
784
NT_STATUS_HAVE_NO_MEMORY(msg);
786
msg->dn = ldb_dn_new(msg, gp_ctx->ldb_ctx, dn_str);
788
inheritance_string = talloc_asprintf(msg, "%d", inheritance);
789
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(inheritance_string, msg);
791
rv = ldb_msg_add_string(msg, "gPOptions", inheritance_string);
793
DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
795
return NT_STATUS_UNSUCCESSFUL;
797
msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
799
rv = ldb_modify(gp_ctx->ldb_ctx, msg);
801
DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
803
return NT_STATUS_UNSUCCESSFUL;
810
NTSTATUS gp_create_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo)
812
struct ldb_message *msg;
815
char *dn_str, *flags_str, *version_str;
816
struct ldb_dn *child_dn, *gpo_dn;
818
mem_ctx = talloc_new(gp_ctx);
819
NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
822
msg = ldb_msg_new(mem_ctx);
823
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
825
msg->dn = ldb_get_default_basedn(gp_ctx->ldb_ctx);
826
dn_str = talloc_asprintf(mem_ctx, "CN=%s,CN=Policies,CN=System", gpo->name);
827
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dn_str, mem_ctx);
829
child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
830
rv = ldb_dn_add_child(msg->dn, child_dn);
831
if (!rv) goto ldb_msg_add_error;
833
flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
834
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(flags_str, mem_ctx);
836
version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
837
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(version_str, mem_ctx);
839
rv = ldb_msg_add_string(msg, "objectClass", "top");
840
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
841
rv = ldb_msg_add_string(msg, "objectClass", "container");
842
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
843
rv = ldb_msg_add_string(msg, "objectClass", "groupPolicyContainer");
844
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
845
rv = ldb_msg_add_string(msg, "displayName", gpo->display_name);
846
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
847
rv = ldb_msg_add_string(msg, "name", gpo->name);
848
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
849
rv = ldb_msg_add_string(msg, "CN", gpo->name);
850
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
851
rv = ldb_msg_add_string(msg, "gPCFileSysPath", gpo->file_sys_path);
852
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
853
rv = ldb_msg_add_string(msg, "flags", flags_str);
854
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
855
rv = ldb_msg_add_string(msg, "versionNumber", version_str);
856
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
857
rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
858
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
859
rv = ldb_msg_add_string(msg, "gpCFunctionalityVersion", "2");
860
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
862
rv = ldb_add(gp_ctx->ldb_ctx, msg);
863
if (rv != LDB_SUCCESS) {
864
DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
865
talloc_free(mem_ctx);
866
return NT_STATUS_UNSUCCESSFUL;
872
msg = ldb_msg_new(mem_ctx);
873
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
875
msg->dn = ldb_dn_copy(mem_ctx, gpo_dn);
876
child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=User");
877
rv = ldb_dn_add_child(msg->dn, child_dn);
878
if (!rv) goto ldb_msg_add_error;
880
rv = ldb_msg_add_string(msg, "objectClass", "top");
881
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
882
rv = ldb_msg_add_string(msg, "objectClass", "container");
883
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
884
rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
885
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
886
rv = ldb_msg_add_string(msg, "CN", "User");
887
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
888
rv = ldb_msg_add_string(msg, "name", "User");
889
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
891
rv = ldb_add(gp_ctx->ldb_ctx, msg);
892
if (rv != LDB_SUCCESS) {
893
DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
894
talloc_free(mem_ctx);
895
return NT_STATUS_UNSUCCESSFUL;
899
msg = ldb_msg_new(mem_ctx);
900
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
902
msg->dn = ldb_dn_copy(mem_ctx, gpo_dn);
903
child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Machine");
904
rv = ldb_dn_add_child(msg->dn, child_dn);
905
if (!rv) goto ldb_msg_add_error;
907
rv = ldb_msg_add_string(msg, "objectClass", "top");
908
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
909
rv = ldb_msg_add_string(msg, "objectClass", "container");
910
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
911
rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
912
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
913
rv = ldb_msg_add_string(msg, "CN", "Machine");
914
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
915
rv = ldb_msg_add_string(msg, "name", "Machine");
916
if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
918
rv = ldb_add(gp_ctx->ldb_ctx, msg);
919
if (rv != LDB_SUCCESS) {
920
DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
921
talloc_free(mem_ctx);
922
return NT_STATUS_UNSUCCESSFUL;
925
gpo->dn = talloc_strdup(gpo, ldb_dn_get_linearized(gpo_dn));
926
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->dn, mem_ctx);
928
talloc_free(mem_ctx);
932
DEBUG(0, ("LDB Error adding element to ldb message\n"));
933
talloc_free(mem_ctx);
934
return NT_STATUS_UNSUCCESSFUL;
937
NTSTATUS gp_set_ads_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd)
941
enum ndr_err_code ndr_err;
942
struct ldb_message *msg;
945
/* Create a forked memory context to clean up easily */
946
mem_ctx = talloc_new(gp_ctx);
947
NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
949
/* Push the security descriptor through the NDR library */
950
ndr_err = ndr_push_struct_blob(&data,
953
(ndr_push_flags_fn_t)ndr_push_security_descriptor);
954
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
955
return ndr_map_error2ntstatus(ndr_err);
959
/* Create a LDB message */
960
msg = ldb_msg_new(mem_ctx);
961
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
963
msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
965
rv = ldb_msg_add_value(msg, "nTSecurityDescriptor", &data, NULL);
967
DEBUG(0, ("LDB message add element failed for adding nTSecurityDescriptor: %s\n", ldb_strerror(rv)));
968
talloc_free(mem_ctx);
969
return NT_STATUS_UNSUCCESSFUL;
971
msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
973
rv = ldb_modify(gp_ctx->ldb_ctx, msg);
975
DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
976
talloc_free(mem_ctx);
977
return NT_STATUS_UNSUCCESSFUL;
980
talloc_free(mem_ctx);
984
/* This function sets flags, version and displayName on a GPO */
985
NTSTATUS gp_set_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo)
989
struct ldb_message *msg;
990
char *version_str, *flags_str;
992
mem_ctx = talloc_new(gp_ctx);
994
msg = ldb_msg_new(mem_ctx);
995
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
997
msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, gpo->dn);
999
version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
1000
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
1002
flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
1003
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
1005
rv = ldb_msg_add_string(msg, "flags", flags_str);
1007
DEBUG(0, ("LDB message add string failed for flags: %s\n", ldb_strerror(rv)));
1008
talloc_free(mem_ctx);
1009
return NT_STATUS_UNSUCCESSFUL;
1011
msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
1013
rv = ldb_msg_add_string(msg, "version", version_str);
1015
DEBUG(0, ("LDB message add string failed for version: %s\n", ldb_strerror(rv)));
1016
talloc_free(mem_ctx);
1017
return NT_STATUS_UNSUCCESSFUL;
1019
msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
1021
rv = ldb_msg_add_string(msg, "displayName", gpo->display_name);
1023
DEBUG(0, ("LDB message add string failed for displayName: %s\n", ldb_strerror(rv)));
1024
talloc_free(mem_ctx);
1025
return NT_STATUS_UNSUCCESSFUL;
1027
msg->elements[2].flags = LDB_FLAG_MOD_REPLACE;
1029
rv = ldb_modify(gp_ctx->ldb_ctx, msg);
1031
DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
1032
talloc_free(mem_ctx);
1033
return NT_STATUS_UNSUCCESSFUL;
1036
talloc_free(mem_ctx);
1037
return NT_STATUS_OK;