~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source4/lib/registry/util.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:
2
2
   Unix SMB/CIFS implementation.
3
3
   Transparent registry backend handling
4
4
   Copyright (C) Jelmer Vernooij                        2003-2007.
 
5
   Copyright (C) Wilco Baan Hofman                      2010.
5
6
 
6
7
   This program is free software; you can redistribute it and/or modify
7
8
   it under the terms of the GNU General Public License as published by
20
21
#include "includes.h"
21
22
#include "lib/registry/registry.h"
22
23
#include "librpc/gen_ndr/winreg.h"
23
 
 
24
 
/**
25
 
 * @file
26
 
 * @brief Registry utility functions
27
 
 */
28
 
 
29
 
static const struct {
30
 
        uint32_t id;
31
 
        const char *name;
32
 
} reg_value_types[] = {
33
 
        { REG_SZ, "REG_SZ" },
34
 
        { REG_DWORD, "REG_DWORD" },
35
 
        { REG_BINARY, "REG_BINARY" },
36
 
        { REG_EXPAND_SZ, "REG_EXPAND_SZ" },
37
 
        { REG_NONE, "REG_NONE" },
38
 
        { 0, NULL }
39
 
};
40
 
 
41
 
/** Return string description of registry value type */
42
 
_PUBLIC_ const char *str_regtype(int type)
43
 
{
44
 
        int i;
45
 
        for (i = 0; reg_value_types[i].name; i++) {
46
 
                if (reg_value_types[i].id == type)
47
 
                        return reg_value_types[i].name;
48
 
        }
49
 
 
50
 
        return "Unknown";
51
 
}
52
 
 
53
 
_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, 
54
 
                                   struct smb_iconv_convenience *iconv_convenience,
55
 
                                   uint32_t type,
 
24
#include "lib/util/data_blob.h"
 
25
 
 
26
_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type,
56
27
                                   const DATA_BLOB data)
57
28
{
58
29
        char *ret = NULL;
63
34
        switch (type) {
64
35
                case REG_EXPAND_SZ:
65
36
                case REG_SZ:
66
 
                        convert_string_talloc_convenience(mem_ctx, iconv_convenience, CH_UTF16, CH_UNIX,
 
37
                        convert_string_talloc(mem_ctx,
 
38
                                              CH_UTF16, CH_UNIX,
67
39
                                              data.data, data.length,
68
40
                                              (void **)&ret, NULL, false);
69
 
                        return ret;
 
41
                        break;
 
42
                case REG_DWORD:
 
43
                case REG_DWORD_BIG_ENDIAN:
 
44
                        SMB_ASSERT(data.length == sizeof(uint32_t));
 
45
                        ret = talloc_asprintf(mem_ctx, "0x%8.8x",
 
46
                                              IVAL(data.data, 0));
 
47
                        break;
 
48
                case REG_QWORD:
 
49
                        SMB_ASSERT(data.length == sizeof(uint64_t));
 
50
                        ret = talloc_asprintf(mem_ctx, "0x%16.16llx",
 
51
                                              (long long)BVAL(data.data, 0));
 
52
                        break;
70
53
                case REG_BINARY:
71
 
                        ret = data_blob_hex_string(mem_ctx, &data);
72
 
                        return ret;
73
 
                case REG_DWORD:
74
 
                        if (*(int *)data.data == 0)
75
 
                                return talloc_strdup(mem_ctx, "0");
76
 
                        return talloc_asprintf(mem_ctx, "0x%x",
77
 
                                               *(int *)data.data);
 
54
                        ret = data_blob_hex_string_upper(mem_ctx, &data);
 
55
                        break;
 
56
                case REG_NONE:
 
57
                        /* "NULL" is the right return value */
 
58
                        break;
78
59
                case REG_MULTI_SZ:
 
60
                        /* FIXME: We don't support this yet */
 
61
                        break;
 
62
                default:
79
63
                        /* FIXME */
80
 
                        break;
81
 
                default:
 
64
                        /* Other datatypes aren't supported -> return "NULL" */
82
65
                        break;
83
66
        }
84
67
 
86
69
}
87
70
 
88
71
/** Generate a string that describes a registry value */
89
 
_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, 
90
 
                                   struct smb_iconv_convenience *iconv_convenience, 
 
72
_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx,
91
73
                                   const char *name,
92
74
                                   uint32_t data_type,
93
75
                                   const DATA_BLOB data)
94
76
{
95
77
        return talloc_asprintf(mem_ctx, "%s = %s : %s", name?name:"<No Name>",
96
78
                               str_regtype(data_type),
97
 
                               reg_val_data_string(mem_ctx, iconv_convenience, data_type, data));
98
 
}
99
 
 
100
 
_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, 
101
 
                                struct smb_iconv_convenience *iconv_convenience,
102
 
                                const char *type_str,
103
 
                                const char *data_str, uint32_t *type,
104
 
                                DATA_BLOB *data)
105
 
{
106
 
        int i;
107
 
        *type = -1;
108
 
 
109
 
        /* Find the correct type */
110
 
        for (i = 0; reg_value_types[i].name; i++) {
111
 
                if (!strcmp(reg_value_types[i].name, type_str)) {
112
 
                        *type = reg_value_types[i].id;
113
 
                        break;
 
79
                               reg_val_data_string(mem_ctx, data_type, data));
 
80
}
 
81
 
 
82
/*
 
83
 * This implements reading hex bytes that include comma's.
 
84
 * It was previously handled by strhex_to_data_blob, but that did not cover
 
85
 * the format used by windows.
 
86
 */
 
87
static DATA_BLOB reg_strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *str)
 
88
{
 
89
        DATA_BLOB ret;
 
90
        const char *HEXCHARS = "0123456789ABCDEF";
 
91
        size_t i, j;
 
92
        char *hi, *lo;
 
93
 
 
94
        ret = data_blob_talloc_zero(mem_ctx, (strlen(str)+(strlen(str) % 3))/3);
 
95
        j = 0;
 
96
        for (i = 0; i < strlen(str); i++) {
 
97
                hi = strchr(HEXCHARS, toupper(str[i]));
 
98
                if (hi == NULL)
 
99
                        continue;
 
100
 
 
101
                i++;
 
102
                lo = strchr(HEXCHARS, toupper(str[i]));
 
103
                if (lo == NULL)
 
104
                        break;
 
105
 
 
106
                ret.data[j] = PTR_DIFF(hi, HEXCHARS) << 4;
 
107
                ret.data[j] += PTR_DIFF(lo, HEXCHARS);
 
108
                j++;
 
109
 
 
110
                if (j > ret.length) {
 
111
                        DEBUG(0, ("Trouble converting hex string to bin\n"));
 
112
                        break;
 
113
                }
 
114
        }
 
115
        return ret;
 
116
}
 
117
 
 
118
 
 
119
_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str,
 
120
                                const char *data_str, uint32_t *type, DATA_BLOB *data)
 
121
{
 
122
        char *tmp_type_str, *p, *q;
 
123
        int result;
 
124
 
 
125
        *type = regtype_by_string(type_str);
 
126
 
 
127
        if (*type == -1) {
 
128
                /* Normal windows format is hex, hex(type int as string),
 
129
                   dword or just a string. */
 
130
                if (strncmp(type_str, "hex(", 4) == 0) {
 
131
                        /* there is a hex string with the value type between
 
132
                           the braces */
 
133
                        tmp_type_str = talloc_strdup(mem_ctx, type_str);
 
134
                        q = p = tmp_type_str + strlen("hex(");
 
135
 
 
136
                        /* Go to the closing brace or end of the string */
 
137
                        while (*q != ')' && *q != '\0') q++;
 
138
                        *q = '\0';
 
139
 
 
140
                        /* Convert hex string to int, store it in type */
 
141
                        result = sscanf(p, "%x", type);
 
142
                        if (!result) {
 
143
                                DEBUG(0, ("Could not convert hex to int\n"));
 
144
                                return false;
 
145
                        }
 
146
                        talloc_free(tmp_type_str);
 
147
                } else if (strcmp(type_str, "hex") == 0) {
 
148
                        *type = REG_BINARY;
 
149
                } else if (strcmp(type_str, "dword") == 0) {
 
150
                        *type = REG_DWORD;
114
151
                }
115
152
        }
116
153
 
119
156
 
120
157
        /* Convert data appropriately */
121
158
 
122
 
        switch (*type)
123
 
        {
 
159
        switch (*type) {
124
160
                case REG_SZ:
 
161
                        return convert_string_talloc(mem_ctx,
 
162
                                                     CH_UNIX, CH_UTF16,
 
163
                                                     data_str, strlen(data_str)+1,
 
164
                                                     (void **)&data->data,
 
165
                                                     &data->length, false);
 
166
                        break;
 
167
                case REG_MULTI_SZ:
125
168
                case REG_EXPAND_SZ:
126
 
                convert_string_talloc_convenience(mem_ctx, iconv_convenience, CH_UNIX, CH_UTF16,
127
 
                                                     data_str, strlen(data_str),
128
 
                                                     (void **)&data->data, &data->length, false);
129
 
                        break;
130
 
 
131
 
                case REG_DWORD: {
132
 
                        uint32_t tmp = strtol(data_str, NULL, 0);
133
 
                        *data = data_blob_talloc(mem_ctx, &tmp, 4);
134
 
                        }
135
 
                        break;
136
 
 
 
169
                case REG_BINARY:
 
170
                        *data = reg_strhex_to_data_blob(mem_ctx, data_str);
 
171
                        break;
 
172
                case REG_DWORD:
 
173
                case REG_DWORD_BIG_ENDIAN: {
 
174
                        uint32_t tmp = strtol(data_str, NULL, 16);
 
175
                        *data = data_blob_talloc(mem_ctx, NULL, sizeof(uint32_t));
 
176
                        if (data->data == NULL) return false;
 
177
                        SIVAL(data->data, 0, tmp);
 
178
                        }
 
179
                        break;
 
180
                case REG_QWORD: {
 
181
                        uint64_t tmp = strtoll(data_str, NULL, 16);
 
182
                        *data = data_blob_talloc(mem_ctx, NULL, sizeof(uint64_t));
 
183
                        if (data->data == NULL) return false;
 
184
                        SBVAL(data->data, 0, tmp);
 
185
                        }
 
186
                        break;
137
187
                case REG_NONE:
138
188
                        ZERO_STRUCTP(data);
139
189
                        break;
140
 
 
141
 
                case REG_BINARY:
142
 
                        *data = strhex_to_data_blob(mem_ctx, data_str);
143
 
                        break;
144
 
 
145
190
                default:
146
191
                        /* FIXME */
 
192
                        /* Other datatypes aren't supported -> return no success */
147
193
                        return false;
148
194
        }
149
195
        return true;
155
201
{
156
202
        struct registry_key *predef;
157
203
        WERROR error;
158
 
        int predeflength;
 
204
        size_t predeflength;
159
205
        char *predefname;
160
206
 
161
207
        if (strchr(name, '\\') != NULL)
164
210
                predeflength = strlen(name);
165
211
 
166
212
        predefname = talloc_strndup(mem_ctx, name, predeflength);
 
213
        W_ERROR_HAVE_NO_MEMORY(predefname);
167
214
        error = reg_get_predefined_key_by_name(handle, predefname, &predef);
168
215
        talloc_free(predefname);
169
216
 
192
239
        }
193
240
 
194
241
        parent_name = talloc_strndup(mem_ctx, path, strrchr(path, '\\')-path);
195
 
 
 
242
        W_ERROR_HAVE_NO_MEMORY(parent_name);
196
243
        error = reg_open_key_abs(mem_ctx, ctx, parent_name, parent);
 
244
        talloc_free(parent_name);
197
245
        if (!W_ERROR_IS_OK(error)) {
198
246
                return error;
199
247
        }
200
248
 
201
249
        *name = talloc_strdup(mem_ctx, strrchr(path, '\\')+1);
 
250
        W_ERROR_HAVE_NO_MEMORY(*name);
202
251
 
203
252
        return WERR_OK;
204
253
}
216
265
 
217
266
        error = get_abs_parent(mem_ctx, ctx, path, &parent, &n);
218
267
        if (W_ERROR_IS_OK(error)) {
219
 
                error = reg_key_del(parent, n);
 
268
                error = reg_key_del(mem_ctx, parent, n);
220
269
        }
221
270
 
222
271
        talloc_free(mem_ctx);
233
282
        const char *n;
234
283
        WERROR error;
235
284
 
 
285
        *result = NULL;
 
286
 
236
287
        if (!strchr(path, '\\')) {
237
288
                return WERR_ALREADY_EXISTS;
238
289
        }