~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source3/libgpo/gpext/registry.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
1
/*
2
2
 *  Unix SMB/CIFS implementation.
3
3
 *  Group Policy Support
4
 
 *  Copyright (C) Guenther Deschner 2007-2008
 
4
 *  Copyright (C) Guenther Deschner 2007-2008,2010
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
19
19
 
20
20
#include "includes.h"
21
21
#include "../libgpo/gpo_ini.h"
 
22
#include "../libgpo/gpo.h"
 
23
#include "libgpo/gpo_proto.h"
 
24
#include "registry.h"
 
25
#include "../librpc/gen_ndr/ndr_preg.h"
22
26
 
23
27
#define GP_EXT_NAME "registry"
24
28
 
32
36
 
33
37
static TALLOC_CTX *ctx = NULL;
34
38
 
35
 
struct gp_registry_file_header {
36
 
        uint32_t signature;
37
 
        uint32_t version;
38
 
};
39
 
 
40
 
struct gp_registry_file_entry {
41
 
        UNISTR key;
42
 
        UNISTR value;
43
 
        enum winreg_Type type;
44
 
        size_t size;
45
 
        uint8_t *data;
46
 
};
47
 
 
48
 
struct gp_registry_file {
49
 
        struct gp_registry_file_header header;
50
 
        size_t num_entries;
51
 
        struct gp_registry_entry *entries;
52
 
};
53
 
 
54
 
/****************************************************************
55
 
****************************************************************/
56
 
 
57
 
static bool reg_parse_header(const char *desc,
58
 
                             struct gp_registry_file_header *header,
59
 
                             prs_struct *ps,
60
 
                             int depth)
61
 
{
62
 
        if (!header)
63
 
                return false;
64
 
 
65
 
        prs_debug(ps, depth, desc, "reg_parse_header");
66
 
        depth++;
67
 
 
68
 
        if (!prs_uint32("signature", ps, depth, &header->signature))
69
 
                return false;
70
 
 
71
 
        if (!prs_uint32("version", ps, depth, &header->version))
72
 
                return false;
73
 
 
74
 
        return true;
75
 
}
76
 
 
77
 
/****************************************************************
78
 
****************************************************************/
79
 
 
80
 
static bool reg_parse_and_verify_ucs2_char(const char *desc,
81
 
                                           char character,
82
 
                                           prs_struct *ps,
83
 
                                           int depth)
84
 
{
85
 
        uint16_t tmp;
86
 
 
87
 
        if (!prs_uint16(desc, ps, depth, &tmp))
88
 
                return false;
89
 
 
90
 
        if (tmp != UCS2_CHAR(character))
91
 
                return false;
92
 
 
93
 
        return true;
94
 
}
95
 
 
96
 
/****************************************************************
97
 
****************************************************************/
98
 
 
99
 
static bool reg_parse_init(prs_struct *ps, int depth)
100
 
{
101
 
        return reg_parse_and_verify_ucs2_char("initiator '['", '[',
102
 
                                              ps, depth);
103
 
}
104
 
 
105
 
/****************************************************************
106
 
****************************************************************/
107
 
 
108
 
static bool reg_parse_sep(prs_struct *ps, int depth)
109
 
{
110
 
        return reg_parse_and_verify_ucs2_char("separator ';'", ';',
111
 
                                              ps, depth);
112
 
}
113
 
 
114
 
/****************************************************************
115
 
****************************************************************/
116
 
 
117
 
static bool reg_parse_term(prs_struct *ps, int depth)
118
 
{
119
 
        return reg_parse_and_verify_ucs2_char("terminator ']'", ']',
120
 
                                              ps, depth);
121
 
}
122
 
 
123
 
 
124
 
/****************************************************************
125
 
* [key;value;type;size;data]
126
 
****************************************************************/
127
 
 
128
 
static bool reg_parse_entry(TALLOC_CTX *mem_ctx,
129
 
                            const char *desc,
130
 
                            struct gp_registry_file_entry *entry,
131
 
                            prs_struct *ps,
132
 
                            int depth)
133
 
{
134
 
        uint32_t size = 0;
135
 
 
136
 
        if (!entry)
137
 
                return false;
138
 
 
139
 
        prs_debug(ps, depth, desc, "reg_parse_entry");
140
 
        depth++;
141
 
 
142
 
        ZERO_STRUCTP(entry);
143
 
 
144
 
        if (!reg_parse_init(ps, depth))
145
 
                return false;
146
 
 
147
 
        if (!prs_unistr("key", ps, depth, &entry->key))
148
 
                return false;
149
 
 
150
 
        if (!reg_parse_sep(ps, depth))
151
 
                return false;
152
 
 
153
 
        if (!prs_unistr("value", ps, depth, &entry->value))
154
 
                return false;
155
 
 
156
 
        if (!reg_parse_sep(ps, depth))
157
 
                return false;
158
 
 
159
 
        if (!prs_uint32("type", ps, depth, &entry->type))
160
 
                return false;
161
 
 
162
 
        if (!reg_parse_sep(ps, depth))
163
 
                return false;
164
 
 
165
 
        if (!prs_uint32("size", ps, depth, &size))
166
 
                return false;
167
 
 
168
 
        entry->size = size;
169
 
 
170
 
        if (!reg_parse_sep(ps, depth))
171
 
                return false;
172
 
 
173
 
        if (entry->size) {
174
 
                entry->data = TALLOC_ZERO_ARRAY(mem_ctx, uint8, entry->size);
175
 
                if (!entry->data)
176
 
                        return false;
177
 
        }
178
 
 
179
 
        if (!prs_uint8s(false, "data", ps, depth, entry->data, entry->size))
180
 
                return false;
181
 
 
182
 
        if (!reg_parse_term(ps, depth))
183
 
                return false;
184
 
 
185
 
        return true;
186
 
}
187
 
 
188
39
/****************************************************************
189
40
****************************************************************/
190
41
 
191
42
static bool reg_parse_value(TALLOC_CTX *mem_ctx,
192
 
                            char **value,
 
43
                            const char **value,
193
44
                            enum gp_reg_action *action)
194
45
{
195
46
        if (!*value) {
251
102
****************************************************************/
252
103
 
253
104
static bool gp_reg_entry_from_file_entry(TALLOC_CTX *mem_ctx,
254
 
                                         struct gp_registry_file_entry *file_entry,
 
105
                                         struct preg_entry *r,
255
106
                                         struct gp_registry_entry **reg_entry)
256
107
{
257
108
        struct registry_value *data = NULL;
258
109
        struct gp_registry_entry *entry = NULL;
259
 
        char *key = NULL;
260
 
        char *value = NULL;
261
110
        enum gp_reg_action action = GP_REG_ACTION_NONE;
262
 
        size_t converted_size;
263
111
 
264
112
        ZERO_STRUCTP(*reg_entry);
265
113
 
267
115
        if (!data)
268
116
                return false;
269
117
 
270
 
        if (strlen_w((const smb_ucs2_t *)file_entry->key.buffer) <= 0)
271
 
                return false;
272
 
 
273
 
        if (!pull_ucs2_talloc(mem_ctx, &key, file_entry->key.buffer,
274
 
                              &converted_size))
275
 
        {
276
 
                return false;
277
 
        }
278
 
 
279
 
        if (strlen_w((const smb_ucs2_t *)file_entry->value.buffer) > 0 &&
280
 
            !pull_ucs2_talloc(mem_ctx, &value, file_entry->value.buffer,
281
 
                              &converted_size))
282
 
        {
283
 
                        return false;
284
 
        }
285
 
 
286
 
        if (!reg_parse_value(mem_ctx, &value, &action))
287
 
                return false;
288
 
 
289
 
        data->type = file_entry->type;
290
 
 
291
 
        switch (data->type) {
292
 
                case REG_DWORD:
293
 
                        data->v.dword = atoi((char *)file_entry->data);
294
 
                        break;
295
 
                case REG_BINARY:
296
 
                        data->v.binary = data_blob_talloc(mem_ctx,
297
 
                                                          file_entry->data,
298
 
                                                          file_entry->size);
299
 
                        break;
300
 
                case REG_NONE:
301
 
                        break;
302
 
                case REG_SZ:
303
 
                        if (!pull_ucs2_talloc(mem_ctx, &data->v.sz.str,
304
 
                                              (const smb_ucs2_t *)
305
 
                                              file_entry->data,
306
 
                                              &data->v.sz.len)) {
307
 
                                data->v.sz.len = -1;
308
 
                        }
309
 
 
310
 
                        break;
311
 
                case REG_DWORD_BIG_ENDIAN:
312
 
                case REG_EXPAND_SZ:
313
 
                case REG_LINK:
314
 
                case REG_MULTI_SZ:
315
 
                case REG_QWORD:
316
 
/*              case REG_DWORD_LITTLE_ENDIAN: */
317
 
/*              case REG_QWORD_LITTLE_ENDIAN: */
318
 
                        printf("not yet implemented: %d\n", data->type);
319
 
                        return false;
320
 
                default:
321
 
                        printf("invalid reg type defined: %d\n", data->type);
322
 
                        return false;
323
 
 
324
 
        }
 
118
        data->type = r->type;
 
119
        data->data = data_blob_talloc(data, r->data, r->size);
325
120
 
326
121
        entry = TALLOC_ZERO_P(mem_ctx, struct gp_registry_entry);
327
122
        if (!entry)
328
123
                return false;
329
124
 
330
 
        entry->key = key;
331
 
        entry->value = value;
 
125
        if (!reg_parse_value(mem_ctx, &r->valuename, &action))
 
126
                return false;
 
127
 
 
128
        entry->key = talloc_strdup(entry, r->keyname);
 
129
        entry->value = talloc_strdup(entry, r->valuename);
332
130
        entry->data = data;
333
131
        entry->action = action;
334
132
 
338
136
}
339
137
 
340
138
/****************************************************************
341
 
* [key;value;type;size;data][key;value;type;size;data]...
342
 
****************************************************************/
343
 
 
344
 
static bool reg_parse_entries(TALLOC_CTX *mem_ctx,
345
 
                              const char *desc,
346
 
                              struct gp_registry_entry **entries,
347
 
                              size_t *num_entries,
348
 
                              prs_struct *ps,
349
 
                              int depth)
350
 
{
351
 
 
352
 
        if (!entries || !num_entries)
353
 
                return false;
354
 
 
355
 
        prs_debug(ps, depth, desc, "reg_parse_entries");
356
 
        depth++;
357
 
 
358
 
        *entries = NULL;
359
 
        *num_entries = 0;
360
 
 
361
 
        while (ps->buffer_size > ps->data_offset) {
362
 
 
363
 
                struct gp_registry_file_entry f_entry;
364
 
                struct gp_registry_entry *r_entry = NULL;
365
 
 
366
 
                if (!reg_parse_entry(mem_ctx, desc, &f_entry,
367
 
                                     ps, depth))
368
 
                        return false;
369
 
 
370
 
                if (!gp_reg_entry_from_file_entry(mem_ctx,
371
 
                                                  &f_entry,
372
 
                                                  &r_entry))
373
 
                        return false;
374
 
 
375
 
                if (!add_gp_registry_entry_to_array(mem_ctx,
376
 
                                                    r_entry,
377
 
                                                    entries,
378
 
                                                    num_entries))
379
 
                        return false;
380
 
        }
381
 
 
382
 
        return true;
383
 
}
384
 
 
385
 
/****************************************************************
386
139
****************************************************************/
387
140
 
388
141
static NTSTATUS reg_parse_registry(TALLOC_CTX *mem_ctx,
389
142
                                   uint32_t flags,
390
143
                                   const char *filename,
391
 
                                   struct gp_registry_entry **entries,
392
 
                                   size_t *num_entries)
 
144
                                   struct gp_registry_entry **entries_p,
 
145
                                   size_t *num_entries_p)
393
146
{
394
 
        uint16_t *buf = NULL;
395
 
        size_t n = 0;
 
147
        DATA_BLOB blob;
396
148
        NTSTATUS status;
397
 
        prs_struct ps;
398
 
        struct gp_registry_file *reg_file;
 
149
        enum ndr_err_code ndr_err;
399
150
        const char *real_filename = NULL;
400
 
 
401
 
        reg_file = TALLOC_ZERO_P(mem_ctx, struct gp_registry_file);
402
 
        NT_STATUS_HAVE_NO_MEMORY(reg_file);
 
151
        struct preg_file r;
 
152
        struct gp_registry_entry *entries = NULL;
 
153
        size_t num_entries = 0;
 
154
        int i;
403
155
 
404
156
        status = gp_find_file(mem_ctx,
405
157
                              flags,
407
159
                              GP_REGPOL_FILE,
408
160
                              &real_filename);
409
161
        if (!NT_STATUS_IS_OK(status)) {
410
 
                TALLOC_FREE(reg_file);
411
162
                return status;
412
163
        }
413
164
 
414
 
        buf = (uint16 *)file_load(real_filename, &n, 0, NULL);
415
 
        if (!buf) {
416
 
                TALLOC_FREE(reg_file);
 
165
        blob.data = (uint8_t *)file_load(real_filename, &blob.length, 0, NULL);
 
166
        if (!blob.data) {
417
167
                return NT_STATUS_CANNOT_LOAD_REGISTRY_FILE;
418
168
        }
419
169
 
420
 
        if (!prs_init(&ps, n, mem_ctx, UNMARSHALL)) {
421
 
                status = NT_STATUS_NO_MEMORY;
422
 
                goto out;
423
 
        }
424
 
 
425
 
        if (!prs_copy_data_in(&ps, (char *)buf, n)) {
426
 
                status = NT_STATUS_NO_MEMORY;
427
 
                goto out;
428
 
        }
429
 
 
430
 
        prs_set_offset(&ps, 0);
431
 
 
432
 
        if (!reg_parse_header("header", &reg_file->header, &ps, 0)) {
433
 
                status = NT_STATUS_REGISTRY_IO_FAILED;
434
 
                goto out;
435
 
        }
436
 
 
437
 
        if (reg_file->header.signature != GP_REGPOL_FILE_SIGNATURE) {
438
 
                status = NT_STATUS_INVALID_PARAMETER;
439
 
                goto out;
440
 
        }
441
 
 
442
 
        if (reg_file->header.version != GP_REGPOL_FILE_VERSION) {
443
 
                status = NT_STATUS_INVALID_PARAMETER;
444
 
                goto out;
445
 
        }
446
 
 
447
 
        if (!reg_parse_entries(mem_ctx, "entries", &reg_file->entries,
448
 
                               &reg_file->num_entries, &ps, 0)) {
449
 
                status = NT_STATUS_REGISTRY_IO_FAILED;
450
 
                goto out;
451
 
        }
452
 
 
453
 
        *entries = reg_file->entries;
454
 
        *num_entries = reg_file->num_entries;
 
170
        ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
 
171
                        (ndr_pull_flags_fn_t)ndr_pull_preg_file);
 
172
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 
173
                status = ndr_map_error2ntstatus(ndr_err);
 
174
                goto out;
 
175
        }
 
176
 
 
177
        if (!strequal(r.header.signature, "PReg")) {
 
178
                status = NT_STATUS_INVALID_PARAMETER;
 
179
                goto out;
 
180
        }
 
181
 
 
182
        if (r.header.version != GP_REGPOL_FILE_VERSION) {
 
183
                status = NT_STATUS_INVALID_PARAMETER;
 
184
                goto out;
 
185
        }
 
186
 
 
187
        for (i=0; i < r.num_entries; i++) {
 
188
 
 
189
                struct gp_registry_entry *r_entry = NULL;
 
190
 
 
191
                if (!gp_reg_entry_from_file_entry(mem_ctx,
 
192
                                                  &r.entries[i],
 
193
                                                  &r_entry)) {
 
194
                        status = NT_STATUS_NO_MEMORY;
 
195
                        goto out;
 
196
                }
 
197
 
 
198
                if (!add_gp_registry_entry_to_array(mem_ctx,
 
199
                                                    r_entry,
 
200
                                                    &entries,
 
201
                                                    &num_entries)) {
 
202
                        status = NT_STATUS_NO_MEMORY;
 
203
                        goto out;
 
204
                }
 
205
        }
 
206
 
 
207
        *entries_p = entries;
 
208
        *num_entries_p = num_entries;
455
209
 
456
210
        status = NT_STATUS_OK;
457
211
 
458
212
 out:
459
 
        TALLOC_FREE(buf);
460
 
        prs_mem_free(&ps);
461
 
 
 
213
        data_blob_free(&blob);
462
214
        return status;
463
215
}
464
216
 
466
218
****************************************************************/
467
219
 
468
220
static WERROR reg_apply_registry(TALLOC_CTX *mem_ctx,
469
 
                                 const struct nt_user_token *token,
 
221
                                 const struct security_token *token,
470
222
                                 struct registry_key *root_key,
471
223
                                 uint32_t flags,
472
224
                                 struct gp_registry_entry *entries,
521
273
                                              TALLOC_CTX *mem_ctx,
522
274
                                              uint32_t flags,
523
275
                                              struct registry_key *root_key,
524
 
                                              const struct nt_user_token *token,
 
276
                                              const struct security_token *token,
525
277
                                              struct GROUP_POLICY_OBJECT *gpo,
526
278
                                              const char *extension_guid,
527
279
                                              const char *snapin_guid)