~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/libgpo/gpext/gpext.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Unix SMB/CIFS implementation.
 
3
 *  Group Policy Support
 
4
 *  Copyright (C) Guenther Deschner 2007-2008
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 3 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include "includes.h"
 
21
 
 
22
static struct gp_extension *extensions = NULL;
 
23
 
 
24
/****************************************************************
 
25
****************************************************************/
 
26
 
 
27
struct gp_extension *get_gp_extension_list(void)
 
28
{
 
29
        return extensions;
 
30
}
 
31
 
 
32
/****************************************************************
 
33
****************************************************************/
 
34
 
 
35
/* see http://support.microsoft.com/kb/216358/en-us/ for more info */
 
36
 
 
37
struct gp_extension_reg_table gpext_reg_vals[] = {
 
38
        { "DllName", REG_EXPAND_SZ },
 
39
        { "ProcessGroupPolicy", REG_SZ },
 
40
        { "NoMachinePolicy", REG_DWORD },
 
41
        { "NoUserPolicy", REG_DWORD },
 
42
        { "NoSlowLink", REG_DWORD },
 
43
        { "NoBackgroundPolicy", REG_DWORD },
 
44
        { "NoGPOListChanges", REG_DWORD },
 
45
        { "PerUserLocalSettings", REG_DWORD },
 
46
        { "RequiresSuccessfulRegistry", REG_DWORD },
 
47
        { "EnableAsynchronousProcessing", REG_DWORD },
 
48
        { "ExtensionDebugLevel", REG_DWORD },
 
49
        /* new */
 
50
        { "GenerateGroupPolicy", REG_SZ }, /* not supported on w2k */
 
51
        { "NotifyLinkTransition", REG_DWORD },
 
52
        { "ProcessGroupPolicyEx", REG_SZ }, /* not supported on w2k */
 
53
        { "ExtensionEventSource", REG_MULTI_SZ }, /* not supported on w2k */
 
54
        { "GenerateGroupPolicy", REG_SZ },
 
55
        { "MaxNoGPOListChangesInterval", REG_DWORD },
 
56
        { NULL, REG_NONE }
 
57
};
 
58
 
 
59
/****************************************************************
 
60
****************************************************************/
 
61
 
 
62
static struct gp_extension *get_extension_by_name(struct gp_extension *be,
 
63
                                                  const char *name)
 
64
{
 
65
        struct gp_extension *b;
 
66
 
 
67
        for (b = be; b; b = b->next) {
 
68
                if (strequal(b->name, name)) {
 
69
                        return b;
 
70
                }
 
71
        }
 
72
 
 
73
        return NULL;
 
74
}
 
75
 
 
76
/****************************************************************
 
77
****************************************************************/
 
78
 
 
79
static struct gp_extension_methods *get_methods_by_name(struct gp_extension *be,
 
80
                                                        const char *name)
 
81
{
 
82
        struct gp_extension *b;
 
83
 
 
84
        for (b = be; b; b = b->next) {
 
85
                if (strequal(b->name, name)) {
 
86
                        return b->methods;
 
87
                }
 
88
        }
 
89
 
 
90
        return NULL;
 
91
}
 
92
 
 
93
/****************************************************************
 
94
****************************************************************/
 
95
 
 
96
NTSTATUS unregister_gp_extension(const char *name)
 
97
{
 
98
        struct gp_extension *ext;
 
99
 
 
100
        ext = get_extension_by_name(extensions, name);
 
101
        if (!ext) {
 
102
                return NT_STATUS_OK;
 
103
        }
 
104
 
 
105
        DLIST_REMOVE(extensions, ext);
 
106
        TALLOC_FREE(ext);
 
107
 
 
108
        DEBUG(2,("Successfully removed GP extension '%s'\n", name));
 
109
 
 
110
        return NT_STATUS_OK;
 
111
}
 
112
 
 
113
/****************************************************************
 
114
****************************************************************/
 
115
 
 
116
NTSTATUS register_gp_extension(TALLOC_CTX *gpext_ctx,
 
117
                               int version,
 
118
                               const char *name,
 
119
                               const char *guid,
 
120
                               struct gp_extension_methods *methods)
 
121
{
 
122
        struct gp_extension_methods *test;
 
123
        struct gp_extension *entry;
 
124
        NTSTATUS status;
 
125
 
 
126
        if (!gpext_ctx) {
 
127
                return NT_STATUS_INTERNAL_DB_ERROR;
 
128
        }
 
129
 
 
130
        if ((version != SMB_GPEXT_INTERFACE_VERSION)) {
 
131
                DEBUG(0,("Failed to register gp extension.\n"
 
132
                         "The module was compiled against "
 
133
                         "SMB_GPEXT_INTERFACE_VERSION %d,\n"
 
134
                         "current SMB_GPEXT_INTERFACE_VERSION is %d.\n"
 
135
                         "Please recompile against the current "
 
136
                         "version of samba!\n",
 
137
                         version, SMB_GPEXT_INTERFACE_VERSION));
 
138
                return NT_STATUS_OBJECT_TYPE_MISMATCH;
 
139
        }
 
140
 
 
141
        if (!guid || !name || !name[0] || !methods) {
 
142
                DEBUG(0,("Called with NULL pointer or empty name!\n"));
 
143
                return NT_STATUS_INVALID_PARAMETER;
 
144
        }
 
145
 
 
146
        test = get_methods_by_name(extensions, name);
 
147
        if (test) {
 
148
                DEBUG(0,("GP extension module %s already registered!\n",
 
149
                        name));
 
150
                return NT_STATUS_OBJECT_NAME_COLLISION;
 
151
        }
 
152
 
 
153
        entry = TALLOC_ZERO_P(gpext_ctx, struct gp_extension);
 
154
        NT_STATUS_HAVE_NO_MEMORY(entry);
 
155
 
 
156
        entry->name = talloc_strdup(gpext_ctx, name);
 
157
        NT_STATUS_HAVE_NO_MEMORY(entry->name);
 
158
 
 
159
        entry->guid = TALLOC_ZERO_P(gpext_ctx, struct GUID);
 
160
        NT_STATUS_HAVE_NO_MEMORY(entry->guid);
 
161
        status = GUID_from_string(guid, entry->guid);
 
162
        NT_STATUS_NOT_OK_RETURN(status);
 
163
 
 
164
        entry->methods = methods;
 
165
        DLIST_ADD(extensions, entry);
 
166
 
 
167
        DEBUG(2,("Successfully added GP extension '%s' %s\n",
 
168
                name, GUID_string2(gpext_ctx, entry->guid)));
 
169
 
 
170
        return NT_STATUS_OK;
 
171
}
 
172
 
 
173
/****************************************************************
 
174
****************************************************************/
 
175
 
 
176
static NTSTATUS gp_extension_init_module(TALLOC_CTX *mem_ctx,
 
177
                                         const char *name,
 
178
                                         struct gp_extension **gpext)
 
179
{
 
180
        NTSTATUS status;
 
181
        struct gp_extension *ext = NULL;
 
182
 
 
183
        ext = TALLOC_ZERO_P(mem_ctx, struct gp_extension);
 
184
        NT_STATUS_HAVE_NO_MEMORY(gpext);
 
185
 
 
186
        ext->methods = get_methods_by_name(extensions, name);
 
187
        if (!ext->methods) {
 
188
 
 
189
                status = smb_probe_module(SAMBA_SUBSYSTEM_GPEXT,
 
190
                                          name);
 
191
                if (!NT_STATUS_IS_OK(status)) {
 
192
                        return status;
 
193
                }
 
194
 
 
195
                ext->methods = get_methods_by_name(extensions, name);
 
196
                if (!ext->methods) {
 
197
                        return NT_STATUS_DLL_INIT_FAILED;
 
198
                }
 
199
        }
 
200
 
 
201
        *gpext = ext;
 
202
 
 
203
        return NT_STATUS_OK;
 
204
}
 
205
 
 
206
/****************************************************************
 
207
****************************************************************/
 
208
 
 
209
static bool add_gp_extension_reg_entry_to_array(TALLOC_CTX *mem_ctx,
 
210
                                                struct gp_extension_reg_entry *entry,
 
211
                                                struct gp_extension_reg_entry **entries,
 
212
                                                size_t *num)
 
213
{
 
214
        *entries = TALLOC_REALLOC_ARRAY(mem_ctx, *entries,
 
215
                                        struct gp_extension_reg_entry,
 
216
                                        (*num)+1);
 
217
        if (*entries == NULL) {
 
218
                *num = 0;
 
219
                return false;
 
220
        }
 
221
 
 
222
        (*entries)[*num].value = entry->value;
 
223
        (*entries)[*num].data = entry->data;
 
224
 
 
225
        *num += 1;
 
226
        return true;
 
227
}
 
228
 
 
229
/****************************************************************
 
230
****************************************************************/
 
231
 
 
232
static bool add_gp_extension_reg_info_entry_to_array(TALLOC_CTX *mem_ctx,
 
233
                                                     struct gp_extension_reg_info_entry *entry,
 
234
                                                     struct gp_extension_reg_info_entry **entries,
 
235
                                                     size_t *num)
 
236
{
 
237
        *entries = TALLOC_REALLOC_ARRAY(mem_ctx, *entries,
 
238
                                        struct gp_extension_reg_info_entry,
 
239
                                        (*num)+1);
 
240
        if (*entries == NULL) {
 
241
                *num = 0;
 
242
                return false;
 
243
        }
 
244
 
 
245
        (*entries)[*num].guid = entry->guid;
 
246
        (*entries)[*num].num_entries = entry->num_entries;
 
247
        (*entries)[*num].entries = entry->entries;
 
248
 
 
249
        *num += 1;
 
250
        return true;
 
251
}
 
252
 
 
253
/****************************************************************
 
254
****************************************************************/
 
255
 
 
256
static NTSTATUS gp_ext_info_add_reg(TALLOC_CTX *mem_ctx,
 
257
                                    struct gp_extension_reg_info_entry *entry,
 
258
                                    const char *value,
 
259
                                    enum winreg_Type type,
 
260
                                    const char *data_s)
 
261
{
 
262
        struct gp_extension_reg_entry *reg_entry = NULL;
 
263
        struct registry_value *data = NULL;
 
264
 
 
265
        reg_entry = TALLOC_ZERO_P(mem_ctx, struct gp_extension_reg_entry);
 
266
        NT_STATUS_HAVE_NO_MEMORY(reg_entry);
 
267
 
 
268
        data = TALLOC_ZERO_P(mem_ctx, struct registry_value);
 
269
        NT_STATUS_HAVE_NO_MEMORY(data);
 
270
 
 
271
        data->type = type;
 
272
 
 
273
        switch (type) {
 
274
                case REG_SZ:
 
275
                case REG_EXPAND_SZ:
 
276
                        data->v.sz.str = talloc_strdup(mem_ctx, data_s);
 
277
                        NT_STATUS_HAVE_NO_MEMORY(data->v.sz.str);
 
278
                        data->v.sz.len = strlen(data_s);
 
279
                        break;
 
280
                case REG_DWORD:
 
281
                        data->v.dword = atoi(data_s);
 
282
                        break;
 
283
                default:
 
284
                        return NT_STATUS_NOT_SUPPORTED;
 
285
        }
 
286
 
 
287
        reg_entry->value = value;
 
288
        reg_entry->data = data;
 
289
 
 
290
        if (!add_gp_extension_reg_entry_to_array(mem_ctx, reg_entry,
 
291
                                                 &entry->entries,
 
292
                                                 &entry->num_entries)) {
 
293
                return NT_STATUS_NO_MEMORY;
 
294
        }
 
295
 
 
296
        return NT_STATUS_OK;
 
297
}
 
298
 
 
299
/****************************************************************
 
300
****************************************************************/
 
301
 
 
302
static NTSTATUS gp_ext_info_add_reg_table(TALLOC_CTX *mem_ctx,
 
303
                                          const char *module,
 
304
                                          struct gp_extension_reg_info_entry *entry,
 
305
                                          struct gp_extension_reg_table *table)
 
306
{
 
307
        NTSTATUS status;
 
308
        const char *module_name = NULL;
 
309
        int i;
 
310
 
 
311
        module_name = talloc_asprintf(mem_ctx, "%s.%s", module, shlib_ext());
 
312
        NT_STATUS_HAVE_NO_MEMORY(module_name);
 
313
 
 
314
        status = gp_ext_info_add_reg(mem_ctx, entry,
 
315
                                     "DllName", REG_EXPAND_SZ, module_name);
 
316
        NT_STATUS_NOT_OK_RETURN(status);
 
317
 
 
318
        for (i=0; table[i].val; i++) {
 
319
                status = gp_ext_info_add_reg(mem_ctx, entry,
 
320
                                             table[i].val,
 
321
                                             table[i].type,
 
322
                                             table[i].data);
 
323
                NT_STATUS_NOT_OK_RETURN(status);
 
324
        }
 
325
 
 
326
        return status;
 
327
}
 
328
 
 
329
/****************************************************************
 
330
****************************************************************/
 
331
 
 
332
NTSTATUS gp_ext_info_add_entry(TALLOC_CTX *mem_ctx,
 
333
                               const char *module,
 
334
                               const char *ext_guid,
 
335
                               struct gp_extension_reg_table *table,
 
336
                               struct gp_extension_reg_info *info)
 
337
{
 
338
        NTSTATUS status;
 
339
        struct gp_extension_reg_info_entry *entry = NULL;
 
340
 
 
341
        entry = TALLOC_ZERO_P(mem_ctx, struct gp_extension_reg_info_entry);
 
342
        NT_STATUS_HAVE_NO_MEMORY(entry);
 
343
 
 
344
        status = GUID_from_string(ext_guid, &entry->guid);
 
345
        NT_STATUS_NOT_OK_RETURN(status);
 
346
 
 
347
        status = gp_ext_info_add_reg_table(mem_ctx, module, entry, table);
 
348
        NT_STATUS_NOT_OK_RETURN(status);
 
349
 
 
350
        if (!add_gp_extension_reg_info_entry_to_array(mem_ctx, entry,
 
351
                                                      &info->entries,
 
352
                                                      &info->num_entries)) {
 
353
                return NT_STATUS_NO_MEMORY;
 
354
        }
 
355
 
 
356
        return NT_STATUS_OK;
 
357
}
 
358
 
 
359
/****************************************************************
 
360
****************************************************************/
 
361
 
 
362
static bool gp_extension_reg_info_verify_entry(struct gp_extension_reg_entry *entry)
 
363
{
 
364
        int i;
 
365
 
 
366
        for (i=0; gpext_reg_vals[i].val; i++) {
 
367
 
 
368
                if ((strequal(entry->value, gpext_reg_vals[i].val)) &&
 
369
                    (entry->data->type == gpext_reg_vals[i].type)) {
 
370
                        return true;
 
371
                }
 
372
        }
 
373
 
 
374
        return false;
 
375
}
 
376
 
 
377
/****************************************************************
 
378
****************************************************************/
 
379
 
 
380
static bool gp_extension_reg_info_verify(struct gp_extension_reg_info_entry *entry)
 
381
{
 
382
        int i;
 
383
 
 
384
        for (i=0; i < entry->num_entries; i++) {
 
385
                if (!gp_extension_reg_info_verify_entry(&entry->entries[i])) {
 
386
                        return false;
 
387
                }
 
388
        }
 
389
 
 
390
        return true;
 
391
}
 
392
 
 
393
/****************************************************************
 
394
****************************************************************/
 
395
 
 
396
static WERROR gp_extension_store_reg_vals(TALLOC_CTX *mem_ctx,
 
397
                                          struct registry_key *key,
 
398
                                          struct gp_extension_reg_info_entry *entry)
 
399
{
 
400
        WERROR werr = WERR_OK;
 
401
        size_t i;
 
402
 
 
403
        for (i=0; i < entry->num_entries; i++) {
 
404
 
 
405
                werr = reg_setvalue(key,
 
406
                                    entry->entries[i].value,
 
407
                                    entry->entries[i].data);
 
408
                W_ERROR_NOT_OK_RETURN(werr);
 
409
        }
 
410
 
 
411
        return werr;
 
412
}
 
413
 
 
414
/****************************************************************
 
415
****************************************************************/
 
416
 
 
417
static WERROR gp_extension_store_reg_entry(TALLOC_CTX *mem_ctx,
 
418
                                           struct gp_registry_context *reg_ctx,
 
419
                                           struct gp_extension_reg_info_entry *entry)
 
420
{
 
421
        WERROR werr;
 
422
        struct registry_key *key = NULL;
 
423
        const char *subkeyname = NULL;
 
424
 
 
425
        if (!gp_extension_reg_info_verify(entry)) {
 
426
                return WERR_INVALID_PARAM;
 
427
        }
 
428
 
 
429
        subkeyname = GUID_string2(mem_ctx, &entry->guid);
 
430
        W_ERROR_HAVE_NO_MEMORY(subkeyname);
 
431
 
 
432
        strupper_m(CONST_DISCARD(char *,subkeyname));
 
433
 
 
434
        werr = gp_store_reg_subkey(mem_ctx,
 
435
                                   subkeyname,
 
436
                                   reg_ctx->curr_key,
 
437
                                   &key);
 
438
        W_ERROR_NOT_OK_RETURN(werr);
 
439
 
 
440
        werr = gp_extension_store_reg_vals(mem_ctx,
 
441
                                           key,
 
442
                                           entry);
 
443
        W_ERROR_NOT_OK_RETURN(werr);
 
444
 
 
445
        return werr;
 
446
}
 
447
 
 
448
/****************************************************************
 
449
****************************************************************/
 
450
 
 
451
static WERROR gp_extension_store_reg(TALLOC_CTX *mem_ctx,
 
452
                                     struct gp_registry_context *reg_ctx,
 
453
                                     struct gp_extension_reg_info *info)
 
454
{
 
455
        WERROR werr = WERR_OK;
 
456
        int i;
 
457
 
 
458
        if (!info) {
 
459
                return WERR_OK;
 
460
        }
 
461
 
 
462
        for (i=0; i < info->num_entries; i++) {
 
463
                werr = gp_extension_store_reg_entry(mem_ctx,
 
464
                                                    reg_ctx,
 
465
                                                    &info->entries[i]);
 
466
                W_ERROR_NOT_OK_RETURN(werr);
 
467
        }
 
468
 
 
469
        return werr;
 
470
}
 
471
 
 
472
/****************************************************************
 
473
****************************************************************/
 
474
 
 
475
static NTSTATUS gp_glob_ext_list(TALLOC_CTX *mem_ctx,
 
476
                                 const char ***ext_list,
 
477
                                 size_t *ext_list_len)
 
478
{
 
479
        SMB_STRUCT_DIR *dir = NULL;
 
480
        SMB_STRUCT_DIRENT *dirent = NULL;
 
481
 
 
482
        dir = sys_opendir(modules_path(SAMBA_SUBSYSTEM_GPEXT));
 
483
        if (!dir) {
 
484
                return map_nt_error_from_unix(errno);
 
485
        }
 
486
 
 
487
        while ((dirent = sys_readdir(dir))) {
 
488
 
 
489
                fstring name; /* forgive me... */
 
490
                char *p;
 
491
 
 
492
                if ((strequal(dirent->d_name, ".")) ||
 
493
                    (strequal(dirent->d_name, ".."))) {
 
494
                        continue;
 
495
                }
 
496
 
 
497
                p = strrchr(dirent->d_name, '.');
 
498
                if (!p) {
 
499
                        sys_closedir(dir);
 
500
                        return NT_STATUS_NO_MEMORY;
 
501
                }
 
502
 
 
503
                if (!strcsequal(p+1, shlib_ext())) {
 
504
                        DEBUG(10,("gp_glob_ext_list: not a *.so file: %s\n",
 
505
                                dirent->d_name));
 
506
                        continue;
 
507
                }
 
508
 
 
509
                fstrcpy(name, dirent->d_name);
 
510
                name[PTR_DIFF(p, dirent->d_name)] = 0;
 
511
 
 
512
                if (!add_string_to_array(mem_ctx, name, ext_list,
 
513
                                         (int *)ext_list_len)) {
 
514
                        sys_closedir(dir);
 
515
                        return NT_STATUS_NO_MEMORY;
 
516
                }
 
517
        }
 
518
 
 
519
        sys_closedir(dir);
 
520
 
 
521
        return NT_STATUS_OK;
 
522
}
 
523
 
 
524
/****************************************************************
 
525
****************************************************************/
 
526
 
 
527
NTSTATUS shutdown_gp_extensions(void)
 
528
{
 
529
        struct gp_extension *ext = NULL;
 
530
 
 
531
        for (ext = extensions; ext; ext = ext->next) {
 
532
                if (ext->methods && ext->methods->shutdown) {
 
533
                        ext->methods->shutdown();
 
534
                }
 
535
        }
 
536
 
 
537
        return NT_STATUS_OK;
 
538
}
 
539
 
 
540
/****************************************************************
 
541
****************************************************************/
 
542
 
 
543
NTSTATUS init_gp_extensions(TALLOC_CTX *mem_ctx)
 
544
{
 
545
        NTSTATUS status;
 
546
        WERROR werr;
 
547
        int i = 0;
 
548
        const char **ext_array = NULL;
 
549
        size_t ext_array_len = 0;
 
550
        struct gp_extension *gpext = NULL;
 
551
        struct gp_registry_context *reg_ctx = NULL;
 
552
 
 
553
        if (get_gp_extension_list()) {
 
554
                return NT_STATUS_OK;
 
555
        }
 
556
 
 
557
        status = gp_glob_ext_list(mem_ctx, &ext_array, &ext_array_len);
 
558
        NT_STATUS_NOT_OK_RETURN(status);
 
559
 
 
560
        for (i=0; i<ext_array_len; i++) {
 
561
 
 
562
                struct gp_extension_reg_info *info = NULL;
 
563
 
 
564
                status = gp_extension_init_module(mem_ctx, ext_array[i],
 
565
                                                  &gpext);
 
566
                if (!NT_STATUS_IS_OK(status)) {
 
567
                        goto out;
 
568
                }
 
569
 
 
570
                if (gpext->methods->get_reg_config) {
 
571
 
 
572
                        status = gpext->methods->initialize(mem_ctx);
 
573
                        if (!NT_STATUS_IS_OK(status)) {
 
574
                                gpext->methods->shutdown();
 
575
                                goto out;
 
576
                        }
 
577
 
 
578
                        status = gpext->methods->get_reg_config(mem_ctx,
 
579
                                                                &info);
 
580
                        if (!NT_STATUS_IS_OK(status)) {
 
581
                                gpext->methods->shutdown();
 
582
                                goto out;
 
583
                        }
 
584
 
 
585
                        if (!reg_ctx) {
 
586
                                struct nt_user_token *token;
 
587
 
 
588
                                token = registry_create_system_token(mem_ctx);
 
589
                                NT_STATUS_HAVE_NO_MEMORY(token);
 
590
 
 
591
                                werr = gp_init_reg_ctx(mem_ctx,
 
592
                                                       KEY_WINLOGON_GPEXT_PATH,
 
593
                                                       REG_KEY_WRITE,
 
594
                                                       token,
 
595
                                                       &reg_ctx);
 
596
                                if (!W_ERROR_IS_OK(werr)) {
 
597
                                        status = werror_to_ntstatus(werr);
 
598
                                        gpext->methods->shutdown();
 
599
                                        goto out;
 
600
                                }
 
601
                        }
 
602
 
 
603
                        werr = gp_extension_store_reg(mem_ctx, reg_ctx, info);
 
604
                        if (!W_ERROR_IS_OK(werr)) {
 
605
                                DEBUG(1,("gp_extension_store_reg failed: %s\n",
 
606
                                        win_errstr(werr)));
 
607
                                TALLOC_FREE(info);
 
608
                                gpext->methods->shutdown();
 
609
                                status = werror_to_ntstatus(werr);
 
610
                                goto out;
 
611
                        }
 
612
                        TALLOC_FREE(info);
 
613
                }
 
614
 
 
615
        }
 
616
 
 
617
 out:
 
618
        TALLOC_FREE(reg_ctx);
 
619
 
 
620
        return status;
 
621
}
 
622
 
 
623
/****************************************************************
 
624
****************************************************************/
 
625
 
 
626
NTSTATUS free_gp_extensions(void)
 
627
{
 
628
        struct gp_extension *ext, *ext_next = NULL;
 
629
 
 
630
        for (ext = extensions; ext; ext = ext_next) {
 
631
                ext_next = ext->next;
 
632
                DLIST_REMOVE(extensions, ext);
 
633
                TALLOC_FREE(ext);
 
634
        }
 
635
 
 
636
        extensions = NULL;
 
637
 
 
638
        return NT_STATUS_OK;
 
639
}
 
640
 
 
641
/****************************************************************
 
642
****************************************************************/
 
643
 
 
644
void debug_gpext_header(int lvl,
 
645
                        const char *name,
 
646
                        uint32_t flags,
 
647
                        struct GROUP_POLICY_OBJECT *gpo,
 
648
                        const char *extension_guid,
 
649
                        const char *snapin_guid)
 
650
{
 
651
        char *flags_str = NULL;
 
652
 
 
653
        DEBUG(lvl,("%s\n", name));
 
654
        DEBUGADD(lvl,("\tgpo:           %s (%s)\n", gpo->name,
 
655
                gpo->display_name));
 
656
        DEBUGADD(lvl,("\tcse extension: %s (%s)\n", extension_guid,
 
657
                cse_gpo_guid_string_to_name(extension_guid)));
 
658
        DEBUGADD(lvl,("\tgplink:        %s\n", gpo->link));
 
659
        DEBUGADD(lvl,("\tsnapin:        %s (%s)\n", snapin_guid,
 
660
                cse_snapin_gpo_guid_string_to_name(snapin_guid)));
 
661
 
 
662
        flags_str = gpo_flag_str(flags);
 
663
        DEBUGADD(lvl,("\tflags:         0x%08x %s\n", flags, flags_str));
 
664
        SAFE_FREE(flags_str);
 
665
}
 
666
 
 
667
NTSTATUS process_gpo_list_with_extension(ADS_STRUCT *ads,
 
668
                           TALLOC_CTX *mem_ctx,
 
669
                           uint32_t flags,
 
670
                           const struct nt_user_token *token,
 
671
                           struct GROUP_POLICY_OBJECT *gpo_list,
 
672
                           const char *extension_guid,
 
673
                           const char *snapin_guid)
 
674
{
 
675
        return NT_STATUS_OK;
 
676
}
 
677
 
 
678
/****************************************************************
 
679
****************************************************************/
 
680
 
 
681
NTSTATUS gpext_process_extension(ADS_STRUCT *ads,
 
682
                                 TALLOC_CTX *mem_ctx,
 
683
                                 uint32_t flags,
 
684
                                 const struct nt_user_token *token,
 
685
                                 struct registry_key *root_key,
 
686
                                 struct GROUP_POLICY_OBJECT *gpo,
 
687
                                 const char *extension_guid,
 
688
                                 const char *snapin_guid)
 
689
{
 
690
        NTSTATUS status;
 
691
        struct gp_extension *ext = NULL;
 
692
        struct GUID guid;
 
693
        bool cse_found = false;
 
694
 
 
695
        status = init_gp_extensions(mem_ctx);
 
696
        if (!NT_STATUS_IS_OK(status)) {
 
697
                DEBUG(1,("init_gp_extensions failed: %s\n",
 
698
                        nt_errstr(status)));
 
699
                return status;
 
700
        }
 
701
 
 
702
        status = GUID_from_string(extension_guid, &guid);
 
703
        if (!NT_STATUS_IS_OK(status)) {
 
704
                return status;
 
705
        }
 
706
 
 
707
        for (ext = extensions; ext; ext = ext->next) {
 
708
 
 
709
                if (GUID_equal(ext->guid, &guid)) {
 
710
                        cse_found = true;
 
711
                        break;
 
712
                }
 
713
        }
 
714
 
 
715
        if (!cse_found) {
 
716
                goto no_ext;
 
717
        }
 
718
 
 
719
        status = ext->methods->initialize(mem_ctx);
 
720
        NT_STATUS_NOT_OK_RETURN(status);
 
721
 
 
722
        status = ext->methods->process_group_policy(ads,
 
723
                                                    mem_ctx,
 
724
                                                    flags,
 
725
                                                    root_key,
 
726
                                                    token,
 
727
                                                    gpo,
 
728
                                                    extension_guid,
 
729
                                                    snapin_guid);
 
730
        if (!NT_STATUS_IS_OK(status)) {
 
731
                ext->methods->shutdown();
 
732
        }
 
733
 
 
734
        return status;
 
735
 
 
736
 no_ext:
 
737
        if (flags & GPO_INFO_FLAG_VERBOSE) {
 
738
                DEBUG(0,("process_extension: no extension available for:\n"));
 
739
                DEBUGADD(0,("%s (%s) (snapin: %s)\n",
 
740
                        extension_guid,
 
741
                        cse_gpo_guid_string_to_name(extension_guid),
 
742
                        snapin_guid));
 
743
        }
 
744
 
 
745
        return NT_STATUS_OK;
 
746
}