~ubuntu-branches/ubuntu/precise/samba/precise

« back to all changes in this revision

Viewing changes to source4/lib/policy/gp_ldap.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
181
        *gp_ctx = talloc_zero(mem_ctx, struct gp_context);
 
182
        NT_STATUS_HAVE_NO_MEMORY(gp_ctx);
 
183
 
 
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];
 
189
 
 
190
        /* We don't need to keep the libnet context */
 
191
        talloc_free(net_ctx);
 
192
        return NT_STATUS_OK;
 
193
}
 
194
 
 
195
NTSTATUS gp_list_all_gpos(struct gp_context *gp_ctx, struct gp_object ***ret)
 
196
{
 
197
        struct ldb_result *result;
 
198
        int rv;
 
199
        NTSTATUS status;
 
200
        TALLOC_CTX *mem_ctx;
 
201
        struct ldb_dn *dn;
 
202
        struct gp_object **gpo;
 
203
        unsigned int i; /* same as in struct ldb_result */
 
204
        const char **attrs;
 
205
 
 
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);
 
209
 
 
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"));
 
213
        if (!rv) {
 
214
                DEBUG(0, ("Can't append subtree to DN\n"));
 
215
                talloc_free(mem_ctx);
 
216
                return NT_STATUS_UNSUCCESSFUL;
 
217
        }
 
218
 
 
219
        DEBUG(10, ("Searching for policies in DN: %s\n", ldb_dn_get_linearized(dn)));
 
220
 
 
221
        attrs = talloc_array(mem_ctx, const char *, 7);
 
222
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(attrs, mem_ctx);
 
223
 
 
224
        attrs[0] = "nTSecurityDescriptor";
 
225
        attrs[1] = "versionNumber";
 
226
        attrs[2] = "flags";
 
227
        attrs[3] = "name";
 
228
        attrs[4] = "displayName";
 
229
        attrs[5] = "gPCFileSysPath";
 
230
        attrs[6] = NULL;
 
231
 
 
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;
 
237
        }
 
238
 
 
239
        gpo = talloc_array(gp_ctx, struct gp_object *, result->count+1);
 
240
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo, mem_ctx);
 
241
 
 
242
        gpo[result->count] = NULL;
 
243
 
 
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);
 
249
                        return status;
 
250
                }
 
251
        }
 
252
 
 
253
        talloc_free(mem_ctx);
 
254
 
 
255
        *ret = gpo;
 
256
        return NT_STATUS_OK;
 
257
}
 
258
 
 
259
NTSTATUS gp_get_gpo_info(struct gp_context *gp_ctx, const char *dn_str, struct gp_object **ret)
 
260
{
 
261
        struct ldb_result *result;
 
262
        struct ldb_dn *dn;
 
263
        struct gp_object *gpo;
 
264
        int rv;
 
265
        NTSTATUS status;
 
266
        TALLOC_CTX *mem_ctx;
 
267
        const char **attrs;
 
268
 
 
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);
 
272
 
 
273
        /* Create an ldb dn struct for the dn string */
 
274
        dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
 
275
 
 
276
        attrs = talloc_array(mem_ctx, const char *, 7);
 
277
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(attrs, mem_ctx);
 
278
 
 
279
        attrs[0] = "nTSecurityDescriptor";
 
280
        attrs[1] = "versionNumber";
 
281
        attrs[2] = "flags";
 
282
        attrs[3] = "name";
 
283
        attrs[4] = "displayName";
 
284
        attrs[5] = "gPCFileSysPath";
 
285
        attrs[6] = NULL;
 
286
 
 
287
        rv = ldb_search(gp_ctx->ldb_ctx,
 
288
                        mem_ctx,
 
289
                        &result,
 
290
                        dn,
 
291
                        LDB_SCOPE_BASE,
 
292
                        attrs,
 
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;
 
298
        }
 
299
 
 
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;
 
305
        }
 
306
 
 
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);
 
311
                return status;
 
312
        }
 
313
 
 
314
        talloc_free(mem_ctx);
 
315
 
 
316
        *ret = gpo;
 
317
        return NT_STATUS_OK;
 
318
}
 
319
 
 
320
static NTSTATUS parse_gplink (TALLOC_CTX *mem_ctx, const char *gplink_str, struct gp_link ***ret)
 
321
{
 
322
        int start, idx=0;
 
323
        int pos;
 
324
        struct gp_link **gplinks;
 
325
        char *buf, *end;
 
326
        const char *gplink_start = "[LDAP://";
 
327
 
 
328
        gplinks = talloc_array(mem_ctx, struct gp_link *, 1);
 
329
        NT_STATUS_HAVE_NO_MEMORY(gplinks);
 
330
 
 
331
        gplinks[0] = NULL;
 
332
 
 
333
        /* Assuming every gPLink starts with "[LDAP://" */
 
334
        start = strlen(gplink_start);
 
335
 
 
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,
 
343
                                                          gplink_str + start,
 
344
                                                          pos - start);
 
345
                        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplinks[idx]->dn, gplinks);
 
346
 
 
347
                        for (start = pos + 1; gplink_str[pos] != ']'; pos++);
 
348
 
 
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);
 
352
                        talloc_free(buf);
 
353
 
 
354
                        /* Set the last entry in the array to be NULL */
 
355
                        gplinks[idx + 1] = NULL;
 
356
 
 
357
                        /* Increment the array index, the string position past
 
358
                           the next "[LDAP://", and set the start reference */
 
359
                        idx++;
 
360
                        pos += strlen(gplink_start)+1;
 
361
                        start = pos;
 
362
                }
 
363
        }
 
364
 
 
365
        *ret = gplinks;
 
366
        return NT_STATUS_OK;
 
367
}
 
368
 
 
369
 
 
370
NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *dn_str, struct gp_link ***ret)
 
371
{
 
372
        TALLOC_CTX *mem_ctx;
 
373
        struct ldb_dn *dn;
 
374
        struct ldb_result *result;
 
375
        struct gp_link **gplinks;
 
376
        char *gplink_str;
 
377
        int rv;
 
378
        unsigned int i, j;
 
379
        NTSTATUS status;
 
380
 
 
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);
 
384
 
 
385
        dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
 
386
 
 
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;
 
392
        }
 
393
 
 
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];
 
397
 
 
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);
 
402
                                goto found;
 
403
                        }
 
404
                }
 
405
        }
 
406
        gplink_str = talloc_strdup(mem_ctx, "");
 
407
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
 
408
 
 
409
        found:
 
410
 
 
411
        status = parse_gplink(gp_ctx, gplink_str, &gplinks);
 
412
        if (!NT_STATUS_IS_OK(status)) {
 
413
                DEBUG(0, ("Failed to parse gPLink\n"));
 
414
                return status;
 
415
        }
 
416
 
 
417
        talloc_free(mem_ctx);
 
418
 
 
419
        *ret = gplinks;
 
420
        return NT_STATUS_OK;
 
421
}
 
422
 
 
423
NTSTATUS gp_list_gpos(struct gp_context *gp_ctx, struct security_token *token, const char ***ret)
 
424
{
 
425
        TALLOC_CTX *mem_ctx;
 
426
        const char **gpos;
 
427
        struct ldb_result *result;
 
428
        char *sid;
 
429
        struct ldb_dn *dn;
 
430
        struct ldb_message_element *element;
 
431
        bool inherit;
 
432
        const char *attrs[] = { "objectClass", NULL };
 
433
        int rv;
 
434
        NTSTATUS status;
 
435
        unsigned int count = 0;
 
436
        unsigned int i;
 
437
        enum {
 
438
                ACCOUNT_TYPE_USER = 0,
 
439
                ACCOUNT_TYPE_MACHINE = 1
 
440
        } account_type;
 
441
 
 
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);
 
445
 
 
446
        sid = ldap_encode_ndr_dom_sid(mem_ctx,
 
447
                                      &token->sids[PRIMARY_USER_SID_INDEX]);
 
448
        NT_STATUS_HAVE_NO_MEMORY(sid);
 
449
 
 
450
        /* Find the user DN and objectclass via the sid from the security token */
 
451
        rv = ldb_search(gp_ctx->ldb_ctx,
 
452
                        mem_ctx,
 
453
                        &result,
 
454
                        ldb_get_default_basedn(gp_ctx->ldb_ctx),
 
455
                        LDB_SCOPE_SUBTREE,
 
456
                        attrs,
 
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;
 
463
        }
 
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;
 
468
        }
 
469
        DEBUG(10,("Found DN for this user: %s\n", ldb_dn_get_linearized(result->msgs[0]->dn)));
 
470
 
 
471
        element = ldb_msg_find_element(result->msgs[0], "objectClass");
 
472
 
 
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"));
 
479
                }
 
480
        }
 
481
 
 
482
        gpos = talloc_array(gp_ctx, const char *, 1);
 
483
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpos, mem_ctx);
 
484
        gpos[0] = NULL;
 
485
 
 
486
        /* Walk through the containers until we hit the root */
 
487
        inherit = 1;
 
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;
 
493
 
 
494
                DEBUG(10, ("Getting gPLinks for DN: %s\n", ldb_dn_get_linearized(dn)));
 
495
 
 
496
                /* Get the gPLink and gPOptions attributes from the container */
 
497
                rv = ldb_search(gp_ctx->ldb_ctx,
 
498
                                mem_ctx,
 
499
                                &result,
 
500
                                dn,
 
501
                                LDB_SCOPE_BASE,
 
502
                                gpo_attrs,
 
503
                                "objectclass=*");
 
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;
 
509
                }
 
510
 
 
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);
 
516
                        return status;
 
517
                }
 
518
 
 
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;
 
523
 
 
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))
 
527
                                continue;
 
528
 
 
529
                        /* Don't apply disabled links */
 
530
                        if (gplinks[i]->options & GPLINK_OPT_DISABLE)
 
531
                                continue;
 
532
 
 
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);
 
538
                                return status;
 
539
                        }
 
540
 
 
541
                        /* If the account does not have read access, this GPO does not apply
 
542
                         * to this account */
 
543
                        status = se_access_check(gpo->security_descriptor,
 
544
                                        token,
 
545
                                        (SEC_STD_READ_CONTROL | SEC_ADS_LIST | SEC_ADS_READ_PROP),
 
546
                                        &access_granted);
 
547
                        if (!NT_STATUS_IS_OK(status)) {
 
548
                                continue;
 
549
                        }
 
550
 
 
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))) {
 
558
                                continue;
 
559
                        }
 
560
 
 
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;
 
567
                        count++;
 
568
 
 
569
                        /* Clean up */
 
570
                        talloc_free(gpo);
 
571
                }
 
572
 
 
573
                /* If inheritance is blocked, then we should only add enforced gPLinks
 
574
                 * higher up */
 
575
                gpoptions = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
 
576
                if (gpoptions == GPO_BLOCK_INHERITANCE) {
 
577
                        inherit = 0;
 
578
                }
 
579
                dn = ldb_dn_get_parent(mem_ctx, dn);
 
580
        }
 
581
 
 
582
        talloc_free(mem_ctx);
 
583
 
 
584
        *ret = gpos;
 
585
        return NT_STATUS_OK;
 
586
}
 
587
 
 
588
NTSTATUS gp_set_gplink(struct gp_context *gp_ctx, const char *dn_str, struct gp_link *gplink)
 
589
{
 
590
        TALLOC_CTX *mem_ctx;
 
591
        struct ldb_result *result;
 
592
        struct ldb_dn *dn;
 
593
        struct ldb_message *msg;
 
594
        const char *attrs[] = { "gPLink", NULL };
 
595
        const char *gplink_str;
 
596
        int rv;
 
597
        char *start;
 
598
 
 
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);
 
602
 
 
603
        dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
 
604
 
 
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;
 
610
        }
 
611
 
 
612
        if (result->count != 1) {
 
613
                talloc_free(mem_ctx);
 
614
                return NT_STATUS_NOT_FOUND;
 
615
        }
 
616
 
 
617
        gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
 
618
 
 
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);
 
622
                *start = '\0';
 
623
                start++;
 
624
                while (*start != ']' && *start != '\0') {
 
625
                        start++;
 
626
                }
 
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);
 
629
 
 
630
        } else {
 
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);
 
634
        }
 
635
 
 
636
 
 
637
 
 
638
        msg = ldb_msg_new(mem_ctx);
 
639
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
 
640
 
 
641
        msg->dn = dn;
 
642
 
 
643
        rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
 
644
        if (rv != 0) {
 
645
                DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
 
646
                talloc_free(mem_ctx);
 
647
                return NT_STATUS_UNSUCCESSFUL;
 
648
        }
 
649
        msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
 
650
 
 
651
        rv = ldb_modify(gp_ctx->ldb_ctx, msg);
 
652
        if (rv != 0) {
 
653
                DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
 
654
                talloc_free(mem_ctx);
 
655
                return NT_STATUS_UNSUCCESSFUL;
 
656
        }
 
657
 
 
658
        talloc_free(mem_ctx);
 
659
        return NT_STATUS_OK;
 
660
}
 
661
 
 
662
NTSTATUS gp_del_gplink(struct gp_context *gp_ctx, const char *dn_str, const char *gplink_dn)
 
663
{
 
664
        TALLOC_CTX *mem_ctx;
 
665
        struct ldb_result *result;
 
666
        struct ldb_dn *dn;
 
667
        struct ldb_message *msg;
 
668
        const char *attrs[] = { "gPLink", NULL };
 
669
        const char *gplink_str, *search_string;
 
670
        int rv;
 
671
        char *p;
 
672
 
 
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);
 
676
 
 
677
        dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
 
678
 
 
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;
 
684
        }
 
685
 
 
686
        if (result->count != 1) {
 
687
                talloc_free(mem_ctx);
 
688
                return NT_STATUS_NOT_FOUND;
 
689
        }
 
690
 
 
691
        gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
 
692
 
 
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);
 
696
 
 
697
        p = strcasestr(gplink_str, search_string);
 
698
        if (p == NULL) {
 
699
                talloc_free(mem_ctx);
 
700
                return NT_STATUS_NOT_FOUND;
 
701
        }
 
702
 
 
703
        *p = '\0';
 
704
        p++;
 
705
        while (*p != ']' && *p != '\0') {
 
706
                p++;
 
707
        }
 
708
        p++;
 
709
        gplink_str = talloc_asprintf(mem_ctx, "%s%s", gplink_str, p);
 
710
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gplink_str, mem_ctx);
 
711
 
 
712
 
 
713
        msg = ldb_msg_new(mem_ctx);
 
714
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
 
715
 
 
716
        msg->dn = dn;
 
717
 
 
718
        if (strcmp(gplink_str, "") == 0) {
 
719
                rv = ldb_msg_add_empty(msg, "gPLink", LDB_FLAG_MOD_DELETE, NULL);
 
720
                if (rv != 0) {
 
721
                        DEBUG(0, ("LDB message add empty element failed: %s\n", ldb_strerror(rv)));
 
722
                        talloc_free(mem_ctx);
 
723
                        return NT_STATUS_UNSUCCESSFUL;
 
724
                }
 
725
        } else {
 
726
                rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
 
727
                if (rv != 0) {
 
728
                        DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
 
729
                        talloc_free(mem_ctx);
 
730
                        return NT_STATUS_UNSUCCESSFUL;
 
731
                }
 
732
                msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
 
733
        }
 
734
        rv = ldb_modify(gp_ctx->ldb_ctx, msg);
 
735
        if (rv != 0) {
 
736
                DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
 
737
                talloc_free(mem_ctx);
 
738
                return NT_STATUS_UNSUCCESSFUL;
 
739
        }
 
740
 
 
741
        talloc_free(mem_ctx);
 
742
        return NT_STATUS_OK;
 
743
}
 
744
 
 
745
NTSTATUS gp_get_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance *inheritance)
 
746
{
 
747
        TALLOC_CTX *mem_ctx;
 
748
        struct ldb_result *result;
 
749
        struct ldb_dn *dn;
 
750
        const char *attrs[] = { "gPOptions", NULL };
 
751
        int rv;
 
752
 
 
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);
 
756
 
 
757
        dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
 
758
 
 
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;
 
764
        }
 
765
 
 
766
        if (result->count != 1) {
 
767
                talloc_free(mem_ctx);
 
768
                return NT_STATUS_NOT_FOUND;
 
769
        }
 
770
 
 
771
        *inheritance = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
 
772
 
 
773
        talloc_free(mem_ctx);
 
774
        return NT_STATUS_OK;
 
775
}
 
776
 
 
777
NTSTATUS gp_set_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance inheritance)
 
778
{
 
779
        char *inheritance_string;
 
780
        struct ldb_message *msg;
 
781
        int rv;
 
782
 
 
783
        msg = ldb_msg_new(gp_ctx);
 
784
        NT_STATUS_HAVE_NO_MEMORY(msg);
 
785
 
 
786
        msg->dn = ldb_dn_new(msg, gp_ctx->ldb_ctx, dn_str);
 
787
 
 
788
        inheritance_string = talloc_asprintf(msg, "%d", inheritance);
 
789
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(inheritance_string, msg);
 
790
 
 
791
        rv = ldb_msg_add_string(msg, "gPOptions", inheritance_string);
 
792
        if (rv != 0) {
 
793
                DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
 
794
                talloc_free(msg);
 
795
                return NT_STATUS_UNSUCCESSFUL;
 
796
        }
 
797
        msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
 
798
 
 
799
        rv = ldb_modify(gp_ctx->ldb_ctx, msg);
 
800
        if (rv != 0) {
 
801
                DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
 
802
                talloc_free(msg);
 
803
                return NT_STATUS_UNSUCCESSFUL;
 
804
        }
 
805
 
 
806
        talloc_free(msg);
 
807
        return NT_STATUS_OK;
 
808
}
 
809
 
 
810
NTSTATUS gp_create_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo)
 
811
{
 
812
        struct ldb_message *msg;
 
813
        TALLOC_CTX *mem_ctx;
 
814
        int rv;
 
815
        char *dn_str, *flags_str, *version_str;
 
816
        struct ldb_dn *child_dn, *gpo_dn;
 
817
 
 
818
        mem_ctx = talloc_new(gp_ctx);
 
819
        NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
 
820
 
 
821
        /* CN={GUID} */
 
822
        msg = ldb_msg_new(mem_ctx);
 
823
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
 
824
 
 
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);
 
828
 
 
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;
 
832
 
 
833
        flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
 
834
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(flags_str, mem_ctx);
 
835
 
 
836
        version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
 
837
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(version_str, mem_ctx);
 
838
 
 
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;
 
861
 
 
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;
 
867
        }
 
868
 
 
869
        gpo_dn = msg->dn;
 
870
 
 
871
        /* CN=User */
 
872
        msg = ldb_msg_new(mem_ctx);
 
873
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
 
874
 
 
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;
 
879
 
 
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;
 
890
 
 
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;
 
896
        }
 
897
 
 
898
        /* CN=Machine */
 
899
        msg = ldb_msg_new(mem_ctx);
 
900
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
 
901
 
 
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;
 
906
 
 
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;
 
917
 
 
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;
 
923
        }
 
924
 
 
925
        gpo->dn = talloc_strdup(gpo, ldb_dn_get_linearized(gpo_dn));
 
926
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(gpo->dn, mem_ctx);
 
927
 
 
928
        talloc_free(mem_ctx);
 
929
        return NT_STATUS_OK;
 
930
 
 
931
        ldb_msg_add_error:
 
932
        DEBUG(0, ("LDB Error adding element to ldb message\n"));
 
933
        talloc_free(mem_ctx);
 
934
        return NT_STATUS_UNSUCCESSFUL;
 
935
}
 
936
 
 
937
NTSTATUS gp_set_ads_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd)
 
938
{
 
939
        TALLOC_CTX *mem_ctx;
 
940
        DATA_BLOB data;
 
941
        enum ndr_err_code ndr_err;
 
942
        struct ldb_message *msg;
 
943
        int rv;
 
944
 
 
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);
 
948
 
 
949
        /* Push the security descriptor through the NDR library */
 
950
        ndr_err = ndr_push_struct_blob(&data,
 
951
                        mem_ctx,
 
952
                        sd,
 
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);
 
956
        }
 
957
 
 
958
 
 
959
        /* Create a LDB message */
 
960
        msg = ldb_msg_new(mem_ctx);
 
961
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
 
962
 
 
963
        msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
 
964
 
 
965
        rv = ldb_msg_add_value(msg, "nTSecurityDescriptor", &data, NULL);
 
966
        if (rv != 0) {
 
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;
 
970
        }
 
971
        msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
 
972
 
 
973
        rv = ldb_modify(gp_ctx->ldb_ctx, msg);
 
974
        if (rv != 0) {
 
975
                DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
 
976
                talloc_free(mem_ctx);
 
977
                return NT_STATUS_UNSUCCESSFUL;
 
978
        }
 
979
 
 
980
        talloc_free(mem_ctx);
 
981
        return NT_STATUS_OK;
 
982
}
 
983
 
 
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)
 
986
{
 
987
        int rv;
 
988
        TALLOC_CTX *mem_ctx;
 
989
        struct ldb_message *msg;
 
990
        char *version_str, *flags_str;
 
991
 
 
992
        mem_ctx = talloc_new(gp_ctx);
 
993
 
 
994
        msg = ldb_msg_new(mem_ctx);
 
995
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
 
996
 
 
997
        msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, gpo->dn);
 
998
 
 
999
        version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
 
1000
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
 
1001
 
 
1002
        flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
 
1003
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, mem_ctx);
 
1004
 
 
1005
        rv = ldb_msg_add_string(msg, "flags", flags_str);
 
1006
        if (rv != 0) {
 
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;
 
1010
        }
 
1011
        msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
 
1012
 
 
1013
        rv = ldb_msg_add_string(msg, "version", version_str);
 
1014
        if (rv != 0) {
 
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;
 
1018
        }
 
1019
        msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
 
1020
 
 
1021
        rv = ldb_msg_add_string(msg, "displayName", gpo->display_name);
 
1022
        if (rv != 0) {
 
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;
 
1026
        }
 
1027
        msg->elements[2].flags = LDB_FLAG_MOD_REPLACE;
 
1028
 
 
1029
        rv = ldb_modify(gp_ctx->ldb_ctx, msg);
 
1030
        if (rv != 0) {
 
1031
                DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
 
1032
                talloc_free(mem_ctx);
 
1033
                return NT_STATUS_UNSUCCESSFUL;
 
1034
        }
 
1035
 
 
1036
        talloc_free(mem_ctx);
 
1037
        return NT_STATUS_OK;
 
1038
}