c390be2ad3d0f490c3f445127d22c79bf9f9fffa
[bbaumbach/samba-autobuild/.git] / source4 / lib / policy / gp_ldap.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  Group Policy Object Support
4  *  Copyright (C) Jelmer Vernooij 2008
5  *  Copyright (C) Wilco Baan Hofman 2008-2010
6  *
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.
11  *
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.
16  *
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/>.
19  */
20 #include "includes.h"
21 #include "param/param.h"
22 #include <ldb.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"
33
34 struct gpo_stringmap {
35         const char *str;
36         uint32_t flags;
37 };
38 static const struct gpo_stringmap gplink_options [] = {
39         { "GPLINK_OPT_DISABLE", GPLINK_OPT_DISABLE },
40         { "GPLINK_OPT_ENFORCE", GPLINK_OPT_ENFORCE },
41         { NULL, 0 }
42 };
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 },
46         { NULL, 0 }
47 };
48 static const struct gpo_stringmap gpo_inheritance [] = {
49         { "GPO_INHERIT", GPO_INHERIT },
50         { "GPO_BLOCK_INHERITANCE", GPO_BLOCK_INHERITANCE },
51         { NULL, 0 }
52 };
53
54
55 static NTSTATUS parse_gpo(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct gp_object **ret)
56 {
57         struct gp_object *gpo = talloc(mem_ctx, struct gp_object);
58         enum ndr_err_code ndr_err;
59         const DATA_BLOB *data;
60
61         NT_STATUS_HAVE_NO_MEMORY(gpo);
62
63         gpo->dn = talloc_strdup(mem_ctx, ldb_dn_get_linearized(msg->dn));
64         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->dn, gpo);
65
66         DEBUG(9, ("Parsing GPO LDAP data for %s\n", gpo->dn));
67
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);
70
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);
73
74         gpo->flags = ldb_msg_find_attr_as_uint(msg, "flags", 0);
75         gpo->version = ldb_msg_find_attr_as_uint(msg, "versionNumber", 0);
76
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);
79
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);
84
85         ndr_err = ndr_pull_struct_blob(data,
86                         mem_ctx,
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);
91         }
92
93         *ret = gpo;
94         return NT_STATUS_OK;
95 }
96
97 NTSTATUS gp_get_gpo_flags(TALLOC_CTX *mem_ctx, uint32_t flags, const char ***ret)
98 {
99         unsigned int i, count=0;
100         const char **flag_strs = talloc_array(mem_ctx, const char *, 1);
101
102         NT_STATUS_HAVE_NO_MEMORY(flag_strs);
103
104         flag_strs[0] = NULL;
105
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;
112                         count++;
113                 }
114         }
115         *ret = flag_strs;
116         return NT_STATUS_OK;
117 }
118
119 NTSTATUS gp_get_gplink_options(TALLOC_CTX *mem_ctx, uint32_t options, const char ***ret)
120 {
121         unsigned int i, count=0;
122         const char **flag_strs = talloc_array(mem_ctx, const char *, 1);
123
124         NT_STATUS_HAVE_NO_MEMORY(flag_strs);
125         flag_strs[0] = NULL;
126
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;
133                         count++;
134                 }
135         }
136         *ret = flag_strs;
137         return NT_STATUS_OK;
138 }
139
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)
145 {
146
147         struct libnet_LookupDCs *io;
148         char *url;
149         struct libnet_context *net_ctx;
150         struct ldb_context *ldb_ctx;
151         NTSTATUS rv;
152
153         /* Initialise the libnet context */
154         net_ctx = libnet_context_init(ev_ctx, lp_ctx);
155         net_ctx->cred = credentials;
156
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);
162
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"));
167                 return rv;
168         }
169
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;
178         }
179
180         *gp_ctx = talloc_zero(mem_ctx, struct gp_context);
181         NT_STATUS_HAVE_NO_MEMORY(gp_ctx);
182
183         (*gp_ctx)->lp_ctx = lp_ctx;
184         (*gp_ctx)->credentials = credentials;
185         (*gp_ctx)->ev_ctx = ev_ctx;
186         (*gp_ctx)->ldb_ctx = ldb_ctx;
187         (*gp_ctx)->active_dc = talloc_reference(*gp_ctx, &io->out.dcs[0]);
188
189         /* We don't need to keep the libnet context */
190         talloc_free(net_ctx);
191         return NT_STATUS_OK;
192 }
193
194 NTSTATUS gp_list_all_gpos(struct gp_context *gp_ctx, struct gp_object ***ret)
195 {
196         struct ldb_result *result;
197         int rv;
198         NTSTATUS status;
199         TALLOC_CTX *mem_ctx;
200         struct ldb_dn *dn;
201         struct gp_object **gpo;
202         unsigned int i; /* same as in struct ldb_result */
203         const char **attrs;
204
205         /* Create a forked memory context, as a base for everything here */
206         mem_ctx = talloc_new(gp_ctx);
207         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
208
209         /* Create full ldb dn of the policies base object */
210         dn = ldb_get_default_basedn(gp_ctx->ldb_ctx);
211         rv = ldb_dn_add_child(dn, ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Policies,CN=System"));
212         if (!rv) {
213                 DEBUG(0, ("Can't append subtree to DN\n"));
214                 talloc_free(mem_ctx);
215                 return NT_STATUS_UNSUCCESSFUL;
216         }
217
218         DEBUG(10, ("Searching for policies in DN: %s\n", ldb_dn_get_linearized(dn)));
219
220         attrs = talloc_array(mem_ctx, const char *, 7);
221         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(attrs, mem_ctx);
222
223         attrs[0] = "nTSecurityDescriptor";
224         attrs[1] = "versionNumber";
225         attrs[2] = "flags";
226         attrs[3] = "name";
227         attrs[4] = "displayName";
228         attrs[5] = "gPCFileSysPath";
229         attrs[6] = NULL;
230
231         rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_ONELEVEL, attrs, "(objectClass=groupPolicyContainer)");
232         if (rv != LDB_SUCCESS) {
233                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
234                 talloc_free(mem_ctx);
235                 return NT_STATUS_UNSUCCESSFUL;
236         }
237
238         gpo = talloc_array(gp_ctx, struct gp_object *, result->count+1);
239         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo, mem_ctx);
240
241         gpo[result->count] = NULL;
242
243         for (i = 0; i < result->count; i++) {
244                 status = parse_gpo(gp_ctx, result->msgs[i], &gpo[i]);
245                 if (!NT_STATUS_IS_OK(status)) {
246                         DEBUG(0, ("Failed to parse GPO.\n"));
247                         talloc_free(mem_ctx);
248                         return status;
249                 }
250         }
251
252         talloc_free(mem_ctx);
253
254         *ret = gpo;
255         return NT_STATUS_OK;
256 }
257
258 NTSTATUS gp_get_gpo_info(struct gp_context *gp_ctx, const char *dn_str, struct gp_object **ret)
259 {
260         struct ldb_result *result;
261         struct ldb_dn *dn;
262         struct gp_object *gpo;
263         int rv;
264         NTSTATUS status;
265         TALLOC_CTX *mem_ctx;
266         const char **attrs;
267
268         /* Create a forked memory context, as a base for everything here */
269         mem_ctx = talloc_new(gp_ctx);
270         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
271
272         /* Create an ldb dn struct for the dn string */
273         dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
274
275         attrs = talloc_array(mem_ctx, const char *, 7);
276         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(attrs, mem_ctx);
277
278         attrs[0] = "nTSecurityDescriptor";
279         attrs[1] = "versionNumber";
280         attrs[2] = "flags";
281         attrs[3] = "name";
282         attrs[4] = "displayName";
283         attrs[5] = "gPCFileSysPath";
284         attrs[6] = NULL;
285
286         rv = ldb_search(gp_ctx->ldb_ctx,
287                         mem_ctx,
288                         &result,
289                         dn,
290                         LDB_SCOPE_BASE,
291                         attrs,
292                         "objectClass=groupPolicyContainer");
293         if (rv != LDB_SUCCESS) {
294                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
295                 talloc_free(mem_ctx);
296                 return NT_STATUS_UNSUCCESSFUL;
297         }
298
299         /* We expect exactly one record */
300         if (result->count != 1) {
301                 DEBUG(0, ("Could not find GPC with dn %s\n", dn_str));
302                 talloc_free(mem_ctx);
303                 return NT_STATUS_NOT_FOUND;
304         }
305
306         status = parse_gpo(gp_ctx, result->msgs[0], &gpo);
307         if (!NT_STATUS_IS_OK(status)) {
308                 DEBUG(0, ("Failed to parse GPO.\n"));
309                 talloc_free(mem_ctx);
310                 return status;
311         }
312
313         talloc_free(mem_ctx);
314
315         *ret = gpo;
316         return NT_STATUS_OK;
317 }
318
319 static NTSTATUS parse_gplink (TALLOC_CTX *mem_ctx, const char *gplink_str, struct gp_link ***ret)
320 {
321         int start, idx=0;
322         int pos;
323         struct gp_link **gplinks;
324         char *buf, *end;
325         const char *gplink_start = "[LDAP://";
326
327         gplinks = talloc_array(mem_ctx, struct gp_link *, 1);
328         NT_STATUS_HAVE_NO_MEMORY(gplinks);
329
330         gplinks[0] = NULL;
331
332         /* Assuming every gPLink starts with "[LDAP://" */
333         start = strlen(gplink_start);
334
335         for (pos = start; pos < strlen(gplink_str); pos++) {
336                 if (gplink_str[pos] == ';') {
337                         gplinks = talloc_realloc(mem_ctx, gplinks, struct gp_link *, idx+2);
338                         NT_STATUS_HAVE_NO_MEMORY(gplinks);
339                         gplinks[idx] = talloc(mem_ctx, struct gp_link);
340                         NT_STATUS_HAVE_NO_MEMORY(gplinks[idx]);
341                         gplinks[idx]->dn = talloc_strndup(mem_ctx,
342                                                           gplink_str + start,
343                                                           pos - start);
344                         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplinks[idx]->dn, gplinks);
345
346                         for (start = pos + 1; gplink_str[pos] != ']'; pos++);
347
348                         buf = talloc_strndup(gplinks, gplink_str + start, pos - start);
349                         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(buf, gplinks);
350                         gplinks[idx]->options = (uint32_t) strtoll(buf, &end, 0);
351                         talloc_free(buf);
352
353                         /* Set the last entry in the array to be NULL */
354                         gplinks[idx + 1] = NULL;
355
356                         /* Increment the array index, the string position past
357                            the next "[LDAP://", and set the start reference */
358                         idx++;
359                         pos += strlen(gplink_start)+1;
360                         start = pos;
361                 }
362         }
363
364         *ret = gplinks;
365         return NT_STATUS_OK;
366 }
367
368
369 NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *dn_str, struct gp_link ***ret)
370 {
371         TALLOC_CTX *mem_ctx;
372         struct ldb_dn *dn;
373         struct ldb_result *result;
374         struct gp_link **gplinks;
375         char *gplink_str;
376         int rv;
377         unsigned int i, j;
378         NTSTATUS status;
379
380         /* Create a forked memory context, as a base for everything here */
381         mem_ctx = talloc_new(gp_ctx);
382         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
383
384         dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
385
386         rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, NULL, "(objectclass=*)");
387         if (rv != LDB_SUCCESS) {
388                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
389                 talloc_free(mem_ctx);
390                 return NT_STATUS_UNSUCCESSFUL;
391         }
392
393         for (i = 0; i < result->count; i++) {
394                 for (j = 0; j < result->msgs[i]->num_elements; j++) {
395                         struct ldb_message_element *element = &result->msgs[i]->elements[j];
396
397                         if (strcmp(element->name, "gPLink") == 0) {
398                                 SMB_ASSERT(element->num_values > 0);
399                                 gplink_str = talloc_strdup(mem_ctx, (char *) element->values[0].data);
400                                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
401                                 goto found;
402                         }
403                 }
404         }
405         gplink_str = talloc_strdup(mem_ctx, "");
406         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
407
408         found:
409
410         status = parse_gplink(gp_ctx, gplink_str, &gplinks);
411         if (!NT_STATUS_IS_OK(status)) {
412                 DEBUG(0, ("Failed to parse gPLink\n"));
413                 return status;
414         }
415
416         talloc_free(mem_ctx);
417
418         *ret = gplinks;
419         return NT_STATUS_OK;
420 }
421
422 NTSTATUS gp_list_gpos(struct gp_context *gp_ctx, struct security_token *token, const char ***ret)
423 {
424         TALLOC_CTX *mem_ctx;
425         const char **gpos;
426         struct ldb_result *result;
427         char *sid;
428         struct ldb_dn *dn;
429         struct ldb_message_element *element;
430         bool inherit;
431         const char *attrs[] = { "objectClass", NULL };
432         int rv;
433         NTSTATUS status;
434         unsigned int count = 0;
435         unsigned int i;
436         enum {
437                 ACCOUNT_TYPE_USER = 0,
438                 ACCOUNT_TYPE_MACHINE = 1
439         } account_type;
440
441         /* Create a forked memory context, as a base for everything here */
442         mem_ctx = talloc_new(gp_ctx);
443         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
444
445         sid = ldap_encode_ndr_dom_sid(mem_ctx,
446                                       &token->sids[PRIMARY_USER_SID_INDEX]);
447         NT_STATUS_HAVE_NO_MEMORY(sid);
448
449         /* Find the user DN and objectclass via the sid from the security token */
450         rv = ldb_search(gp_ctx->ldb_ctx,
451                         mem_ctx,
452                         &result,
453                         ldb_get_default_basedn(gp_ctx->ldb_ctx),
454                         LDB_SCOPE_SUBTREE,
455                         attrs,
456                         "(&(objectclass=user)(objectSid=%s))", sid);
457         if (rv != LDB_SUCCESS) {
458                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv),
459                                 ldb_errstring(gp_ctx->ldb_ctx)));
460                 talloc_free(mem_ctx);
461                 return NT_STATUS_UNSUCCESSFUL;
462         }
463         if (result->count != 1) {
464                 DEBUG(0, ("Could not find user with sid %s.\n", sid));
465                 talloc_free(mem_ctx);
466                 return NT_STATUS_UNSUCCESSFUL;
467         }
468         DEBUG(10,("Found DN for this user: %s\n", ldb_dn_get_linearized(result->msgs[0]->dn)));
469
470         element = ldb_msg_find_element(result->msgs[0], "objectClass");
471
472         /* We need to know if this account is a user or machine. */
473         account_type = ACCOUNT_TYPE_USER;
474         for (i = 0; i < element->num_values; i++) {
475                 if (strcmp((char *)element->values[i].data, "computer") == 0) {
476                         account_type = ACCOUNT_TYPE_MACHINE;
477                         DEBUG(10, ("This user is a machine\n"));
478                 }
479         }
480
481         gpos = talloc_array(gp_ctx, const char *, 1);
482         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpos, mem_ctx);
483         gpos[0] = NULL;
484
485         /* Walk through the containers until we hit the root */
486         inherit = 1;
487         dn = ldb_dn_get_parent(mem_ctx, result->msgs[0]->dn);
488         while (ldb_dn_compare_base(ldb_get_default_basedn(gp_ctx->ldb_ctx), dn) == 0) {
489                 const char *gpo_attrs[] = { "gPLink", "gPOptions", NULL };
490                 struct gp_link **gplinks;
491                 enum gpo_inheritance gpoptions;
492
493                 DEBUG(10, ("Getting gPLinks for DN: %s\n", ldb_dn_get_linearized(dn)));
494
495                 /* Get the gPLink and gPOptions attributes from the container */
496                 rv = ldb_search(gp_ctx->ldb_ctx,
497                                 mem_ctx,
498                                 &result,
499                                 dn,
500                                 LDB_SCOPE_BASE,
501                                 gpo_attrs,
502                                 "objectclass=*");
503                 if (rv != LDB_SUCCESS) {
504                         DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv),
505                                         ldb_errstring(gp_ctx->ldb_ctx)));
506                         talloc_free(mem_ctx);
507                         return NT_STATUS_UNSUCCESSFUL;
508                 }
509
510                 /* Parse the gPLink attribute, put it into a nice struct array */
511                 status = parse_gplink(mem_ctx, ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", ""), &gplinks);
512                 if (!NT_STATUS_IS_OK(status)) {
513                         DEBUG(0, ("Failed to parse gPLink\n"));
514                         talloc_free(mem_ctx);
515                         return status;
516                 }
517
518                 /* Check all group policy links on this container */
519                 for (i = 0; gplinks[i] != NULL; i++) {
520                         struct gp_object *gpo;
521                         uint32_t access_granted;
522
523                         /* If inheritance was blocked at a higher level and this
524                          * gplink is not enforced, it should not be applied */
525                         if (!inherit && !(gplinks[i]->options & GPLINK_OPT_ENFORCE))
526                                 continue;
527
528                         /* Don't apply disabled links */
529                         if (gplinks[i]->options & GPLINK_OPT_DISABLE)
530                                 continue;
531
532                         /* Get GPO information */
533                         status = gp_get_gpo_info(gp_ctx, gplinks[i]->dn, &gpo);
534                         if (!NT_STATUS_IS_OK(status)) {
535                                 DEBUG(0, ("Failed to get gpo information for %s\n", gplinks[i]->dn));
536                                 talloc_free(mem_ctx);
537                                 return status;
538                         }
539
540                         /* If the account does not have read access, this GPO does not apply
541                          * to this account */
542                         status = se_access_check(gpo->security_descriptor,
543                                         token,
544                                         (SEC_STD_READ_CONTROL | SEC_ADS_LIST | SEC_ADS_READ_PROP),
545                                         &access_granted);
546                         if (!NT_STATUS_IS_OK(status)) {
547                                 continue;
548                         }
549
550                         /* If the account is a user and the GPO has user disabled flag, or
551                          * a machine and the GPO has machine disabled flag, this GPO does
552                          * not apply to this account */
553                         if ((account_type == ACCOUNT_TYPE_USER &&
554                                         (gpo->flags & GPO_FLAG_USER_DISABLE)) ||
555                                         (account_type == ACCOUNT_TYPE_MACHINE &&
556                                         (gpo->flags & GPO_FLAG_MACHINE_DISABLE))) {
557                                 continue;
558                         }
559
560                         /* Add the GPO to the list */
561                         gpos = talloc_realloc(gp_ctx, gpos, const char *, count+2);
562                         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpos, mem_ctx);
563                         gpos[count] = talloc_strdup(gp_ctx, gplinks[i]->dn);
564                         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpos[count], mem_ctx);
565                         gpos[count+1] = NULL;
566                         count++;
567
568                         /* Clean up */
569                         talloc_free(gpo);
570                 }
571
572                 /* If inheritance is blocked, then we should only add enforced gPLinks
573                  * higher up */
574                 gpoptions = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
575                 if (gpoptions == GPO_BLOCK_INHERITANCE) {
576                         inherit = 0;
577                 }
578                 dn = ldb_dn_get_parent(mem_ctx, dn);
579         }
580
581         talloc_free(mem_ctx);
582
583         *ret = gpos;
584         return NT_STATUS_OK;
585 }
586
587 NTSTATUS gp_set_gplink(struct gp_context *gp_ctx, const char *dn_str, struct gp_link *gplink)
588 {
589         TALLOC_CTX *mem_ctx;
590         struct ldb_result *result;
591         struct ldb_dn *dn;
592         struct ldb_message *msg;
593         const char *attrs[] = { "gPLink", NULL };
594         const char *gplink_str;
595         int rv;
596         char *start;
597
598         /* Create a forked memory context, as a base for everything here */
599         mem_ctx = talloc_new(gp_ctx);
600         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
601
602         dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
603
604         rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
605         if (rv != LDB_SUCCESS) {
606                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
607                 talloc_free(mem_ctx);
608                 return NT_STATUS_UNSUCCESSFUL;
609         }
610
611         if (result->count != 1) {
612                 talloc_free(mem_ctx);
613                 return NT_STATUS_NOT_FOUND;
614         }
615
616         gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
617
618         /* If this GPO link already exists, alter the options, else add it */
619         if ((start = strcasestr(gplink_str, gplink->dn)) != NULL) {
620                 start += strlen(gplink->dn);
621                 *start = '\0';
622                 start++;
623                 while (*start != ']' && *start != '\0') {
624                         start++;
625                 }
626                 gplink_str = talloc_asprintf(mem_ctx, "%s;%d%s", gplink_str, gplink->options, start);
627                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
628
629         } else {
630                 /* Prepend the new GPO link to the string. This list is backwards in priority. */
631                 gplink_str = talloc_asprintf(mem_ctx, "[LDAP://%s;%d]%s", gplink->dn, gplink->options, gplink_str);
632                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
633         }
634
635
636
637         msg = ldb_msg_new(mem_ctx);
638         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
639
640         msg->dn = dn;
641
642         rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
643         if (rv != LDB_SUCCESS) {
644                 DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
645                 talloc_free(mem_ctx);
646                 return NT_STATUS_UNSUCCESSFUL;
647         }
648         msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
649
650         rv = ldb_modify(gp_ctx->ldb_ctx, msg);
651         if (rv != LDB_SUCCESS) {
652                 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
653                 talloc_free(mem_ctx);
654                 return NT_STATUS_UNSUCCESSFUL;
655         }
656
657         talloc_free(mem_ctx);
658         return NT_STATUS_OK;
659 }
660
661 NTSTATUS gp_del_gplink(struct gp_context *gp_ctx, const char *dn_str, const char *gplink_dn)
662 {
663         TALLOC_CTX *mem_ctx;
664         struct ldb_result *result;
665         struct ldb_dn *dn;
666         struct ldb_message *msg;
667         const char *attrs[] = { "gPLink", NULL };
668         const char *gplink_str, *search_string;
669         int rv;
670         char *p;
671
672         /* Create a forked memory context, as a base for everything here */
673         mem_ctx = talloc_new(gp_ctx);
674         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
675
676         dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
677
678         rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
679         if (rv != LDB_SUCCESS) {
680                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
681                 talloc_free(mem_ctx);
682                 return NT_STATUS_UNSUCCESSFUL;
683         }
684
685         if (result->count != 1) {
686                 talloc_free(mem_ctx);
687                 return NT_STATUS_NOT_FOUND;
688         }
689
690         gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
691
692         /* If this GPO link already exists, alter the options, else add it */
693         search_string = talloc_asprintf(mem_ctx, "[LDAP://%s]", gplink_dn);
694         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(search_string, mem_ctx);
695
696         p = strcasestr(gplink_str, search_string);
697         if (p == NULL) {
698                 talloc_free(mem_ctx);
699                 return NT_STATUS_NOT_FOUND;
700         }
701
702         *p = '\0';
703         p++;
704         while (*p != ']' && *p != '\0') {
705                 p++;
706         }
707         p++;
708         gplink_str = talloc_asprintf(mem_ctx, "%s%s", gplink_str, p);
709         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
710
711
712         msg = ldb_msg_new(mem_ctx);
713         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
714
715         msg->dn = dn;
716
717         if (strcmp(gplink_str, "") == 0) {
718                 rv = ldb_msg_add_empty(msg, "gPLink", LDB_FLAG_MOD_DELETE, NULL);
719                 if (rv != LDB_SUCCESS) {
720                         DEBUG(0, ("LDB message add empty element failed: %s\n", ldb_strerror(rv)));
721                         talloc_free(mem_ctx);
722                         return NT_STATUS_UNSUCCESSFUL;
723                 }
724         } else {
725                 rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
726                 if (rv != LDB_SUCCESS) {
727                         DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
728                         talloc_free(mem_ctx);
729                         return NT_STATUS_UNSUCCESSFUL;
730                 }
731                 msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
732         }
733         rv = ldb_modify(gp_ctx->ldb_ctx, msg);
734         if (rv != LDB_SUCCESS) {
735                 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
736                 talloc_free(mem_ctx);
737                 return NT_STATUS_UNSUCCESSFUL;
738         }
739
740         talloc_free(mem_ctx);
741         return NT_STATUS_OK;
742 }
743
744 NTSTATUS gp_get_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance *inheritance)
745 {
746         TALLOC_CTX *mem_ctx;
747         struct ldb_result *result;
748         struct ldb_dn *dn;
749         const char *attrs[] = { "gPOptions", NULL };
750         int rv;
751
752         /* Create a forked memory context, as a base for everything here */
753         mem_ctx = talloc_new(gp_ctx);
754         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
755
756         dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
757
758         rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
759         if (rv != LDB_SUCCESS) {
760                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
761                 talloc_free(mem_ctx);
762                 return NT_STATUS_UNSUCCESSFUL;
763         }
764
765         if (result->count != 1) {
766                 talloc_free(mem_ctx);
767                 return NT_STATUS_NOT_FOUND;
768         }
769
770         *inheritance = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
771
772         talloc_free(mem_ctx);
773         return NT_STATUS_OK;
774 }
775
776 NTSTATUS gp_set_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance inheritance)
777 {
778         char *inheritance_string;
779         struct ldb_message *msg;
780         int rv;
781
782         msg = ldb_msg_new(gp_ctx);
783         NT_STATUS_HAVE_NO_MEMORY(msg);
784
785         msg->dn = ldb_dn_new(msg, gp_ctx->ldb_ctx, dn_str);
786
787         inheritance_string = talloc_asprintf(msg, "%d", inheritance);
788         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(inheritance_string, msg);
789
790         rv = ldb_msg_add_string(msg, "gPOptions", inheritance_string);
791         if (rv != LDB_SUCCESS) {
792                 DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
793                 talloc_free(msg);
794                 return NT_STATUS_UNSUCCESSFUL;
795         }
796         msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
797
798         rv = ldb_modify(gp_ctx->ldb_ctx, msg);
799         if (rv != LDB_SUCCESS) {
800                 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
801                 talloc_free(msg);
802                 return NT_STATUS_UNSUCCESSFUL;
803         }
804
805         talloc_free(msg);
806         return NT_STATUS_OK;
807 }
808
809 NTSTATUS gp_create_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo)
810 {
811         struct ldb_message *msg;
812         TALLOC_CTX *mem_ctx;
813         int rv;
814         char *dn_str, *flags_str, *version_str;
815         struct ldb_dn *child_dn, *gpo_dn;
816
817         mem_ctx = talloc_new(gp_ctx);
818         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
819
820         /* CN={GUID} */
821         msg = ldb_msg_new(mem_ctx);
822         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
823
824         msg->dn = ldb_get_default_basedn(gp_ctx->ldb_ctx);
825         dn_str = talloc_asprintf(mem_ctx, "CN=%s,CN=Policies,CN=System", gpo->name);
826         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dn_str, mem_ctx);
827
828         child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
829         rv = ldb_dn_add_child(msg->dn, child_dn);
830         if (!rv) goto ldb_msg_add_error;
831
832         flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
833         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(flags_str, mem_ctx);
834
835         version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
836         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(version_str, mem_ctx);
837
838         rv = ldb_msg_add_string(msg, "objectClass", "top");
839         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
840         rv = ldb_msg_add_string(msg, "objectClass", "container");
841         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
842         rv = ldb_msg_add_string(msg, "objectClass", "groupPolicyContainer");
843         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
844         rv = ldb_msg_add_string(msg, "displayName", gpo->display_name);
845         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
846         rv = ldb_msg_add_string(msg, "name", gpo->name);
847         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
848         rv = ldb_msg_add_string(msg, "CN", gpo->name);
849         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
850         rv = ldb_msg_add_string(msg, "gPCFileSysPath", gpo->file_sys_path);
851         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
852         rv = ldb_msg_add_string(msg, "flags", flags_str);
853         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
854         rv = ldb_msg_add_string(msg, "versionNumber", version_str);
855         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
856         rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
857         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
858         rv = ldb_msg_add_string(msg, "gpCFunctionalityVersion", "2");
859         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
860
861         rv = ldb_add(gp_ctx->ldb_ctx, msg);
862         if (rv != LDB_SUCCESS) {
863                 DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
864                 talloc_free(mem_ctx);
865                 return NT_STATUS_UNSUCCESSFUL;
866         }
867
868         gpo_dn = msg->dn;
869
870         /* CN=User */
871         msg = ldb_msg_new(mem_ctx);
872         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
873
874         msg->dn = ldb_dn_copy(mem_ctx, gpo_dn);
875         child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=User");
876         rv = ldb_dn_add_child(msg->dn, child_dn);
877         if (!rv) goto ldb_msg_add_error;
878
879         rv = ldb_msg_add_string(msg, "objectClass", "top");
880         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
881         rv = ldb_msg_add_string(msg, "objectClass", "container");
882         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
883         rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
884         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
885         rv = ldb_msg_add_string(msg, "CN", "User");
886         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
887         rv = ldb_msg_add_string(msg, "name", "User");
888         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
889
890         rv = ldb_add(gp_ctx->ldb_ctx, msg);
891         if (rv != LDB_SUCCESS) {
892                 DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
893                 talloc_free(mem_ctx);
894                 return NT_STATUS_UNSUCCESSFUL;
895         }
896
897         /* CN=Machine */
898         msg = ldb_msg_new(mem_ctx);
899         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
900
901         msg->dn = ldb_dn_copy(mem_ctx, gpo_dn);
902         child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Machine");
903         rv = ldb_dn_add_child(msg->dn, child_dn);
904         if (!rv) goto ldb_msg_add_error;
905
906         rv = ldb_msg_add_string(msg, "objectClass", "top");
907         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
908         rv = ldb_msg_add_string(msg, "objectClass", "container");
909         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
910         rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
911         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
912         rv = ldb_msg_add_string(msg, "CN", "Machine");
913         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
914         rv = ldb_msg_add_string(msg, "name", "Machine");
915         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
916
917         rv = ldb_add(gp_ctx->ldb_ctx, msg);
918         if (rv != LDB_SUCCESS) {
919                 DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
920                 talloc_free(mem_ctx);
921                 return NT_STATUS_UNSUCCESSFUL;
922         }
923
924         gpo->dn = talloc_strdup(gpo, ldb_dn_get_linearized(gpo_dn));
925         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->dn, mem_ctx);
926
927         talloc_free(mem_ctx);
928         return NT_STATUS_OK;
929
930         ldb_msg_add_error:
931         DEBUG(0, ("LDB Error adding element to ldb message\n"));
932         talloc_free(mem_ctx);
933         return NT_STATUS_UNSUCCESSFUL;
934 }
935
936 NTSTATUS gp_set_ads_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd)
937 {
938         TALLOC_CTX *mem_ctx;
939         DATA_BLOB data;
940         enum ndr_err_code ndr_err;
941         struct ldb_message *msg;
942         int rv;
943
944         /* Create a forked memory context to clean up easily */
945         mem_ctx = talloc_new(gp_ctx);
946         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
947
948         /* Push the security descriptor through the NDR library */
949         ndr_err = ndr_push_struct_blob(&data,
950                         mem_ctx,
951                         sd,
952                         (ndr_push_flags_fn_t)ndr_push_security_descriptor);
953         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
954                 return ndr_map_error2ntstatus(ndr_err);
955         }
956
957
958         /* Create a LDB message */
959         msg = ldb_msg_new(mem_ctx);
960         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
961
962         msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
963
964         rv = ldb_msg_add_value(msg, "nTSecurityDescriptor", &data, NULL);
965         if (rv != LDB_SUCCESS) {
966                 DEBUG(0, ("LDB message add element failed for adding nTSecurityDescriptor: %s\n", ldb_strerror(rv)));
967                 talloc_free(mem_ctx);
968                 return NT_STATUS_UNSUCCESSFUL;
969         }
970         msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
971
972         rv = ldb_modify(gp_ctx->ldb_ctx, msg);
973         if (rv != LDB_SUCCESS) {
974                 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
975                 talloc_free(mem_ctx);
976                 return NT_STATUS_UNSUCCESSFUL;
977         }
978
979         talloc_free(mem_ctx);
980         return NT_STATUS_OK;
981 }
982
983 /* This function sets flags, version and displayName on a GPO */
984 NTSTATUS gp_set_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo)
985 {
986         int rv;
987         TALLOC_CTX *mem_ctx;
988         struct ldb_message *msg;
989         char *version_str, *flags_str;
990
991         mem_ctx = talloc_new(gp_ctx);
992
993         msg = ldb_msg_new(mem_ctx);
994         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
995
996         msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, gpo->dn);
997
998         version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
999         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
1000
1001         flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
1002         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
1003
1004         rv = ldb_msg_add_string(msg, "flags", flags_str);
1005         if (rv != LDB_SUCCESS) {
1006                 DEBUG(0, ("LDB message add string failed for flags: %s\n", ldb_strerror(rv)));
1007                 talloc_free(mem_ctx);
1008                 return NT_STATUS_UNSUCCESSFUL;
1009         }
1010         msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
1011
1012         rv = ldb_msg_add_string(msg, "version", version_str);
1013         if (rv != LDB_SUCCESS) {
1014                 DEBUG(0, ("LDB message add string failed for version: %s\n", ldb_strerror(rv)));
1015                 talloc_free(mem_ctx);
1016                 return NT_STATUS_UNSUCCESSFUL;
1017         }
1018         msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
1019
1020         rv = ldb_msg_add_string(msg, "displayName", gpo->display_name);
1021         if (rv != LDB_SUCCESS) {
1022                 DEBUG(0, ("LDB message add string failed for displayName: %s\n", ldb_strerror(rv)));
1023                 talloc_free(mem_ctx);
1024                 return NT_STATUS_UNSUCCESSFUL;
1025         }
1026         msg->elements[2].flags = LDB_FLAG_MOD_REPLACE;
1027
1028         rv = ldb_modify(gp_ctx->ldb_ctx, msg);
1029         if (rv != LDB_SUCCESS) {
1030                 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
1031                 talloc_free(mem_ctx);
1032                 return NT_STATUS_UNSUCCESSFUL;
1033         }
1034
1035         talloc_free(mem_ctx);
1036         return NT_STATUS_OK;
1037 }