~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/lib/registry/local.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
   Transparent registry backend handling
 
4
   Copyright (C) Jelmer Vernooij                        2003-2007.
 
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, write to the Free Software
 
18
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
*/
 
20
 
 
21
#include "includes.h"
 
22
#include "../lib/util/dlinklist.h"
 
23
#include "lib/registry/registry.h"
 
24
#include "system/filesys.h"
 
25
 
 
26
struct reg_key_path {
 
27
        uint32_t predefined_key;
 
28
        const char **elements;
 
29
};
 
30
 
 
31
struct registry_local {
 
32
        const struct registry_operations *ops;
 
33
 
 
34
        struct mountpoint {
 
35
                struct reg_key_path path;
 
36
                struct hive_key *key;
 
37
                struct mountpoint *prev, *next;
 
38
        } *mountpoints;
 
39
};
 
40
 
 
41
struct local_key {
 
42
        struct registry_key global;
 
43
        struct reg_key_path path;
 
44
        struct hive_key *hive_key;
 
45
};
 
46
 
 
47
 
 
48
struct registry_key *reg_import_hive_key(struct registry_context *ctx,
 
49
                                         struct hive_key *hive,
 
50
                                         uint32_t predefined_key,
 
51
                                         const char **elements)
 
52
{
 
53
        struct local_key *local_key;
 
54
        struct reg_key_path parent_path;
 
55
 
 
56
        parent_path.predefined_key = predefined_key;
 
57
        parent_path.elements = elements;
 
58
 
 
59
        local_key = talloc(ctx, struct local_key);
 
60
        local_key->hive_key = talloc_steal(local_key, hive);
 
61
        local_key->global.context = talloc_reference(local_key, ctx);
 
62
        local_key->path = parent_path;
 
63
 
 
64
        return (struct registry_key *)local_key;
 
65
}
 
66
 
 
67
 
 
68
static WERROR local_open_key(TALLOC_CTX *mem_ctx,
 
69
                             struct registry_key *parent,
 
70
                             const char *path,
 
71
                             struct registry_key **result)
 
72
{
 
73
        char *orig = talloc_strdup(mem_ctx, path),
 
74
                 *curbegin = orig,
 
75
                 *curend = strchr(orig, '\\');
 
76
        struct local_key *local_parent = talloc_get_type(parent,
 
77
                                                         struct local_key);
 
78
        struct hive_key *curkey = local_parent->hive_key;
 
79
        WERROR error;
 
80
        const char **elements = NULL;
 
81
        int el;
 
82
 
 
83
        if (local_parent->path.elements != NULL) {
 
84
                elements = talloc_array(mem_ctx, const char *,
 
85
                                        str_list_length(local_parent->path.elements) + 1);
 
86
                for (el = 0; local_parent->path.elements[el] != NULL; el++) {
 
87
                        elements[el] = talloc_reference(elements,
 
88
                                                        local_parent->path.elements[el]);
 
89
                }
 
90
                elements[el] = NULL;
 
91
        } else {
 
92
                elements = NULL;
 
93
                el = 0;
 
94
        }
 
95
 
 
96
        while (curbegin != NULL && *curbegin) {
 
97
                if (curend != NULL)
 
98
                        *curend = '\0';
 
99
                elements = talloc_realloc(mem_ctx, elements, const char *, el+2);
 
100
                elements[el] = talloc_strdup(elements, curbegin);
 
101
                el++;
 
102
                elements[el] = NULL;
 
103
                error = hive_get_key_by_name(mem_ctx, curkey,
 
104
                                             curbegin, &curkey);
 
105
                if (!W_ERROR_IS_OK(error)) {
 
106
                        DEBUG(2, ("Opening key %s failed: %s\n", curbegin,
 
107
                                win_errstr(error)));
 
108
                        talloc_free(orig);
 
109
                        return error;
 
110
                }
 
111
                if (curend == NULL)
 
112
                        break;
 
113
                curbegin = curend + 1;
 
114
                curend = strchr(curbegin, '\\');
 
115
        }
 
116
        talloc_free(orig);
 
117
 
 
118
        *result = reg_import_hive_key(local_parent->global.context, curkey,
 
119
                                      local_parent->path.predefined_key,
 
120
                                      talloc_steal(curkey, elements));
 
121
 
 
122
        return WERR_OK;
 
123
}
 
124
 
 
125
WERROR local_get_predefined_key(struct registry_context *ctx,
 
126
                                uint32_t key_id, struct registry_key **key)
 
127
{
 
128
        struct registry_local *rctx = talloc_get_type(ctx,
 
129
                                                      struct registry_local);
 
130
        struct mountpoint *mp;
 
131
 
 
132
        for (mp = rctx->mountpoints; mp != NULL; mp = mp->next) {
 
133
                if (mp->path.predefined_key == key_id &&
 
134
                        mp->path.elements == NULL)
 
135
                        break;
 
136
        }
 
137
 
 
138
        if (mp == NULL)
 
139
                return WERR_BADFILE;
 
140
 
 
141
        *key = reg_import_hive_key(ctx, mp->key,
 
142
                                   mp->path.predefined_key,
 
143
                                   mp->path.elements);
 
144
 
 
145
        return WERR_OK;
 
146
}
 
147
 
 
148
static WERROR local_enum_key(TALLOC_CTX *mem_ctx,
 
149
                             const struct registry_key *key, uint32_t idx,
 
150
                             const char **name,
 
151
                             const char **keyclass,
 
152
                             NTTIME *last_changed_time)
 
153
{
 
154
        const struct local_key *local = (const struct local_key *)key;
 
155
 
 
156
        return hive_enum_key(mem_ctx, local->hive_key, idx, name, keyclass,
 
157
                             last_changed_time);
 
158
}
 
159
 
 
160
static WERROR local_create_key(TALLOC_CTX *mem_ctx,
 
161
                               struct registry_key *parent_key,
 
162
                               const char *name,
 
163
                               const char *key_class,
 
164
                               struct security_descriptor *security,
 
165
                               struct registry_key **key)
 
166
{
 
167
        struct local_key *local_parent;
 
168
        struct hive_key *hivekey;
 
169
        const char **elements;
 
170
        int i;
 
171
        const char *last_part;
 
172
 
 
173
        last_part = strrchr(name, '\\');
 
174
        if (last_part == NULL) {
 
175
                last_part = name;
 
176
                local_parent = (struct local_key *)parent_key;
 
177
        } else {
 
178
                W_ERROR_NOT_OK_RETURN(reg_open_key(mem_ctx, parent_key,
 
179
                                                   talloc_strndup(mem_ctx, name, last_part-name),
 
180
                                                   (struct registry_key **)&local_parent));
 
181
                last_part++;
 
182
        }
 
183
 
 
184
        W_ERROR_NOT_OK_RETURN(hive_key_add_name(mem_ctx, local_parent->hive_key,
 
185
                                                last_part, key_class, security,
 
186
                                                &hivekey));
 
187
 
 
188
        if (local_parent->path.elements != NULL) {
 
189
                elements = talloc_array(hivekey, const char *,
 
190
                                        str_list_length(local_parent->path.elements)+2);
 
191
                for (i = 0; local_parent->path.elements[i] != NULL; i++) {
 
192
                        elements[i] = talloc_reference(elements,
 
193
                                                       local_parent->path.elements[i]);
 
194
                }
 
195
        } else {
 
196
                elements = talloc_array(hivekey, const char *, 2);
 
197
                i = 0;
 
198
        }
 
199
 
 
200
        elements[i] = talloc_strdup(elements, name);
 
201
        elements[i+1] = NULL;
 
202
 
 
203
        *key = reg_import_hive_key(local_parent->global.context, hivekey,
 
204
                                   local_parent->path.predefined_key,
 
205
                                   elements);
 
206
 
 
207
        return WERR_OK;
 
208
}
 
209
 
 
210
static WERROR local_set_value(struct registry_key *key, const char *name,
 
211
                              uint32_t type, const DATA_BLOB data)
 
212
{
 
213
        struct local_key *local = (struct local_key *)key;
 
214
 
 
215
        return hive_key_set_value(local->hive_key, name, type, data);
 
216
}
 
217
 
 
218
static WERROR local_get_value(TALLOC_CTX *mem_ctx,
 
219
                              const struct registry_key *key,
 
220
                              const char *name, uint32_t *type, DATA_BLOB *data)
 
221
{
 
222
        const struct local_key *local = (const struct local_key *)key;
 
223
 
 
224
        return hive_get_value(mem_ctx, local->hive_key, name, type, data);
 
225
}
 
226
 
 
227
static WERROR local_enum_value(TALLOC_CTX *mem_ctx,
 
228
                               const struct registry_key *key, uint32_t idx,
 
229
                               const char **name,
 
230
                               uint32_t *type,
 
231
                               DATA_BLOB *data)
 
232
{
 
233
        const struct local_key *local = (const struct local_key *)key;
 
234
 
 
235
        return hive_get_value_by_index(mem_ctx, local->hive_key, idx,
 
236
                                       name, type, data);
 
237
}
 
238
 
 
239
static WERROR local_delete_key(struct registry_key *key, const char *name)
 
240
{
 
241
        const struct local_key *local = (const struct local_key *)key;
 
242
 
 
243
        return hive_key_del(local->hive_key, name);
 
244
}
 
245
 
 
246
static WERROR local_delete_value(struct registry_key *key, const char *name)
 
247
{
 
248
        const struct local_key *local = (const struct local_key *)key;
 
249
 
 
250
        return hive_key_del_value(local->hive_key, name);
 
251
}
 
252
 
 
253
static WERROR local_flush_key(struct registry_key *key)
 
254
{
 
255
        const struct local_key *local = (const struct local_key *)key;
 
256
 
 
257
        return hive_key_flush(local->hive_key);
 
258
}
 
259
 
 
260
static WERROR local_get_key_info(TALLOC_CTX *mem_ctx,
 
261
                                 const struct registry_key *key,
 
262
                                 const char **classname,
 
263
                                 uint32_t *num_subkeys,
 
264
                                 uint32_t *num_values,
 
265
                                 NTTIME *last_change_time,
 
266
                                 uint32_t *max_subkeynamelen,
 
267
                                 uint32_t *max_valnamelen,
 
268
                                 uint32_t *max_valbufsize)
 
269
{
 
270
        const struct local_key *local = (const struct local_key *)key;
 
271
 
 
272
        return hive_key_get_info(mem_ctx, local->hive_key,
 
273
                                 classname, num_subkeys, num_values,
 
274
                                 last_change_time, max_subkeynamelen, 
 
275
                                 max_valnamelen, max_valbufsize);
 
276
}
 
277
static WERROR local_get_sec_desc(TALLOC_CTX *mem_ctx, 
 
278
                                 const struct registry_key *key, 
 
279
                                 struct security_descriptor **security)
 
280
{
 
281
        const struct local_key *local = (const struct local_key *)key;
 
282
 
 
283
        return hive_get_sec_desc(mem_ctx, local->hive_key, security);
 
284
}
 
285
static WERROR local_set_sec_desc(struct registry_key *key, 
 
286
                                 const struct security_descriptor *security)
 
287
{
 
288
        const struct local_key *local = (const struct local_key *)key;
 
289
 
 
290
        return hive_set_sec_desc(local->hive_key, security);
 
291
}
 
292
const static struct registry_operations local_ops = {
 
293
        .name = "local",
 
294
        .open_key = local_open_key,
 
295
        .get_predefined_key = local_get_predefined_key,
 
296
        .enum_key = local_enum_key,
 
297
        .create_key = local_create_key,
 
298
        .set_value = local_set_value,
 
299
        .get_value = local_get_value,
 
300
        .enum_value = local_enum_value,
 
301
        .delete_key = local_delete_key,
 
302
        .delete_value = local_delete_value,
 
303
        .flush_key = local_flush_key,
 
304
        .get_key_info = local_get_key_info,
 
305
        .get_sec_desc = local_get_sec_desc,
 
306
        .set_sec_desc = local_set_sec_desc,
 
307
};
 
308
 
 
309
WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx)
 
310
{
 
311
        struct registry_local *ret = talloc_zero(mem_ctx,
 
312
                                                 struct registry_local);
 
313
 
 
314
        W_ERROR_HAVE_NO_MEMORY(ret);
 
315
 
 
316
        ret->ops = &local_ops;
 
317
 
 
318
        *ctx = (struct registry_context *)ret;
 
319
 
 
320
        return WERR_OK;
 
321
}
 
322
 
 
323
WERROR reg_mount_hive(struct registry_context *rctx,
 
324
                      struct hive_key *hive_key,
 
325
                      uint32_t key_id,
 
326
                      const char **elements)
 
327
{
 
328
        struct registry_local *reg_local = talloc_get_type(rctx,
 
329
                                                           struct registry_local);
 
330
        struct mountpoint *mp = talloc(rctx, struct mountpoint);
 
331
        int i = 0;
 
332
 
 
333
        mp->path.predefined_key = key_id;
 
334
        mp->prev = mp->next = NULL;
 
335
        mp->key = hive_key;
 
336
        if (elements != NULL && str_list_length(elements) != 0) {
 
337
                mp->path.elements = talloc_array(mp, const char *,
 
338
                                                 str_list_length(elements));
 
339
                for (i = 0; elements[i] != NULL; i++) {
 
340
                        mp->path.elements[i] = talloc_reference(mp->path.elements,
 
341
                                                                elements[i]);
 
342
                }
 
343
                mp->path.elements[i] = NULL;
 
344
        } else {
 
345
                mp->path.elements = NULL;
 
346
        }
 
347
 
 
348
        DLIST_ADD(reg_local->mountpoints, mp);
 
349
 
 
350
        return WERR_OK;
 
351
}