Line data Source code
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 32304 : 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 3511 : struct local_key *local_key;
54 3511 : struct reg_key_path parent_path;
55 :
56 32304 : parent_path.predefined_key = predefined_key;
57 32304 : parent_path.elements = elements;
58 :
59 32304 : local_key = talloc(ctx, struct local_key);
60 32304 : if (local_key != NULL) {
61 32304 : local_key->hive_key = talloc_reference(local_key, hive);
62 32304 : local_key->global.context = talloc_reference(local_key, ctx);
63 32304 : local_key->path = parent_path;
64 : }
65 :
66 32304 : return (struct registry_key *)local_key;
67 : }
68 :
69 :
70 8569 : static WERROR local_open_key(TALLOC_CTX *mem_ctx,
71 : struct registry_key *parent,
72 : const char *path,
73 : struct registry_key **result)
74 : {
75 933 : char *orig, *curbegin, *curend;
76 8569 : struct local_key *local_parent = talloc_get_type(parent,
77 : struct local_key);
78 8569 : struct hive_key *curkey = local_parent->hive_key;
79 933 : WERROR error;
80 8569 : const char **elements = NULL;
81 933 : int el;
82 :
83 8569 : if (path == NULL || path[0] == '\0') {
84 0 : return WERR_INVALID_PARAMETER;
85 : }
86 :
87 8569 : orig = talloc_strdup(mem_ctx, path);
88 8569 : W_ERROR_HAVE_NO_MEMORY(orig);
89 8569 : curbegin = orig;
90 8569 : curend = strchr(orig, '\\');
91 :
92 8569 : if (local_parent->path.elements != NULL) {
93 22 : elements = talloc_array(mem_ctx, const char *,
94 : str_list_length(local_parent->path.elements) + 1);
95 22 : W_ERROR_HAVE_NO_MEMORY(elements);
96 84 : for (el = 0; local_parent->path.elements[el] != NULL; el++) {
97 62 : elements[el] = talloc_reference(elements,
98 : local_parent->path.elements[el]);
99 : }
100 22 : elements[el] = NULL;
101 : } else {
102 7636 : elements = NULL;
103 7636 : el = 0;
104 : }
105 :
106 1963 : do {
107 18625 : if (curend != NULL)
108 10056 : *curend = '\0';
109 18625 : elements = talloc_realloc(mem_ctx, elements, const char *, el+2);
110 18625 : W_ERROR_HAVE_NO_MEMORY(elements);
111 18625 : elements[el] = talloc_strdup(elements, curbegin);
112 18625 : W_ERROR_HAVE_NO_MEMORY(elements[el]);
113 18625 : el++;
114 18625 : elements[el] = NULL;
115 18625 : error = hive_get_key_by_name(mem_ctx, curkey,
116 : curbegin, &curkey);
117 18625 : if (!W_ERROR_IS_OK(error)) {
118 326 : DEBUG(2, ("Opening key %s failed: %s\n", curbegin,
119 : win_errstr(error)));
120 326 : talloc_free(orig);
121 326 : return error;
122 : }
123 18299 : if (curend == NULL)
124 7316 : break;
125 10056 : curbegin = curend + 1;
126 10056 : curend = strchr(curbegin, '\\');
127 10056 : } while (curbegin[0] != '\0');
128 8243 : talloc_free(orig);
129 :
130 17413 : *result = reg_import_hive_key(local_parent->global.context, curkey,
131 : local_parent->path.predefined_key,
132 8243 : talloc_steal(curkey, elements));
133 :
134 8243 : return WERR_OK;
135 : }
136 :
137 11692 : WERROR local_get_predefined_key(struct registry_context *ctx,
138 : uint32_t key_id, struct registry_key **key)
139 : {
140 11692 : struct registry_local *rctx = talloc_get_type(ctx,
141 : struct registry_local);
142 1359 : struct mountpoint *mp;
143 :
144 12275 : for (mp = rctx->mountpoints; mp != NULL; mp = mp->next) {
145 12246 : if (mp->path.predefined_key == key_id &&
146 11663 : mp->path.elements == NULL)
147 10333 : break;
148 : }
149 :
150 11692 : if (mp == NULL)
151 29 : return WERR_FILE_NOT_FOUND;
152 :
153 11663 : *key = reg_import_hive_key(ctx, mp->key,
154 : mp->path.predefined_key,
155 : mp->path.elements);
156 :
157 11663 : return WERR_OK;
158 : }
159 :
160 260 : static WERROR local_enum_key(TALLOC_CTX *mem_ctx,
161 : const struct registry_key *key, uint32_t idx,
162 : const char **name,
163 : const char **keyclass,
164 : NTTIME *last_changed_time)
165 : {
166 260 : const struct local_key *local = (const struct local_key *)key;
167 :
168 260 : return hive_enum_key(mem_ctx, local->hive_key, idx, name, keyclass,
169 : last_changed_time);
170 : }
171 :
172 12398 : static WERROR local_create_key(TALLOC_CTX *mem_ctx,
173 : struct registry_key *parent,
174 : const char *path,
175 : const char *key_class,
176 : struct security_descriptor *security,
177 : struct registry_key **result)
178 : {
179 1254 : char *orig, *curbegin, *curend;
180 12398 : struct local_key *local_parent = talloc_get_type(parent,
181 : struct local_key);
182 12398 : struct hive_key *curkey = local_parent->hive_key;
183 1254 : WERROR error;
184 12398 : const char **elements = NULL;
185 1254 : int el;
186 :
187 12398 : if (path == NULL || path[0] == '\0') {
188 0 : return WERR_INVALID_PARAMETER;
189 : }
190 :
191 12398 : orig = talloc_strdup(mem_ctx, path);
192 12398 : W_ERROR_HAVE_NO_MEMORY(orig);
193 12398 : curbegin = orig;
194 12398 : curend = strchr(orig, '\\');
195 :
196 12398 : if (local_parent->path.elements != NULL) {
197 7609 : elements = talloc_array(mem_ctx, const char *,
198 : str_list_length(local_parent->path.elements) + 1);
199 7609 : W_ERROR_HAVE_NO_MEMORY(elements);
200 22433 : for (el = 0; local_parent->path.elements[el] != NULL; el++) {
201 14824 : elements[el] = talloc_reference(elements,
202 : local_parent->path.elements[el]);
203 : }
204 7609 : elements[el] = NULL;
205 : } else {
206 4374 : elements = NULL;
207 4374 : el = 0;
208 : }
209 :
210 1255 : do {
211 14399 : if (curend != NULL)
212 2001 : *curend = '\0';
213 14399 : elements = talloc_realloc(mem_ctx, elements, const char *, el+2);
214 14399 : W_ERROR_HAVE_NO_MEMORY(elements);
215 14399 : elements[el] = talloc_strdup(elements, curbegin);
216 14399 : W_ERROR_HAVE_NO_MEMORY(elements[el]);
217 14399 : el++;
218 14399 : elements[el] = NULL;
219 14399 : error = hive_get_key_by_name(mem_ctx, curkey,
220 : curbegin, &curkey);
221 14399 : if (W_ERROR_EQUAL(error, WERR_FILE_NOT_FOUND)) {
222 4872 : error = hive_key_add_name(mem_ctx, curkey, curbegin,
223 : key_class, security,
224 : &curkey);
225 : }
226 14399 : if (!W_ERROR_IS_OK(error)) {
227 0 : DEBUG(2, ("Open/Creation of key %s failed: %s\n",
228 : curbegin, win_errstr(error)));
229 0 : talloc_free(orig);
230 0 : return error;
231 : }
232 14399 : if (curend == NULL)
233 11144 : break;
234 2001 : curbegin = curend + 1;
235 2001 : curend = strchr(curbegin, '\\');
236 2001 : } while (curbegin[0] != '\0');
237 12398 : talloc_free(orig);
238 :
239 26050 : *result = reg_import_hive_key(local_parent->global.context, curkey,
240 : local_parent->path.predefined_key,
241 12398 : talloc_steal(curkey, elements));
242 :
243 12398 : return WERR_OK;
244 : }
245 :
246 3028 : static WERROR local_set_value(struct registry_key *key, const char *name,
247 : uint32_t type, const DATA_BLOB data)
248 : {
249 3028 : struct local_key *local = (struct local_key *)key;
250 :
251 3028 : if (name == NULL) {
252 0 : return WERR_INVALID_PARAMETER;
253 : }
254 :
255 3028 : return hive_key_set_value(local->hive_key, name, type, data);
256 : }
257 :
258 8165 : static WERROR local_get_value(TALLOC_CTX *mem_ctx,
259 : const struct registry_key *key,
260 : const char *name, uint32_t *type, DATA_BLOB *data)
261 : {
262 8165 : const struct local_key *local = (const struct local_key *)key;
263 :
264 8165 : if (name == NULL) {
265 240 : return WERR_INVALID_PARAMETER;
266 : }
267 :
268 7925 : return hive_get_value(mem_ctx, local->hive_key, name, type, data);
269 : }
270 :
271 2885 : static WERROR local_enum_value(TALLOC_CTX *mem_ctx,
272 : const struct registry_key *key, uint32_t idx,
273 : const char **name,
274 : uint32_t *type,
275 : DATA_BLOB *data)
276 : {
277 2885 : const struct local_key *local = (const struct local_key *)key;
278 :
279 2885 : return hive_get_value_by_index(mem_ctx, local->hive_key, idx,
280 : name, type, data);
281 : }
282 :
283 2564 : static WERROR local_delete_key(TALLOC_CTX *mem_ctx, struct registry_key *key,
284 : const char *name)
285 : {
286 2564 : const struct local_key *local = (const struct local_key *)key;
287 :
288 2564 : if (name == NULL) {
289 0 : return WERR_INVALID_PARAMETER;
290 : }
291 :
292 2564 : return hive_key_del(mem_ctx, local->hive_key, name);
293 : }
294 :
295 2403 : static WERROR local_delete_value(TALLOC_CTX *mem_ctx, struct registry_key *key,
296 : const char *name)
297 : {
298 2403 : const struct local_key *local = (const struct local_key *)key;
299 :
300 2403 : if (name == NULL) {
301 0 : return WERR_INVALID_PARAMETER;
302 : }
303 :
304 2403 : return hive_key_del_value(mem_ctx, local->hive_key, name);
305 : }
306 :
307 641 : static WERROR local_flush_key(struct registry_key *key)
308 : {
309 641 : const struct local_key *local = (const struct local_key *)key;
310 :
311 641 : return hive_key_flush(local->hive_key);
312 : }
313 :
314 268 : static WERROR local_get_key_info(TALLOC_CTX *mem_ctx,
315 : const struct registry_key *key,
316 : const char **classname,
317 : uint32_t *num_subkeys,
318 : uint32_t *num_values,
319 : NTTIME *last_change_time,
320 : uint32_t *max_subkeynamelen,
321 : uint32_t *max_valnamelen,
322 : uint32_t *max_valbufsize)
323 : {
324 268 : const struct local_key *local = (const struct local_key *)key;
325 :
326 268 : return hive_key_get_info(mem_ctx, local->hive_key,
327 : classname, num_subkeys, num_values,
328 : last_change_time, max_subkeynamelen,
329 : max_valnamelen, max_valbufsize);
330 : }
331 0 : static WERROR local_get_sec_desc(TALLOC_CTX *mem_ctx,
332 : const struct registry_key *key,
333 : struct security_descriptor **security)
334 : {
335 0 : const struct local_key *local = (const struct local_key *)key;
336 :
337 0 : return hive_get_sec_desc(mem_ctx, local->hive_key, security);
338 : }
339 1 : static WERROR local_set_sec_desc(struct registry_key *key,
340 : const struct security_descriptor *security)
341 : {
342 1 : const struct local_key *local = (const struct local_key *)key;
343 :
344 1 : return hive_set_sec_desc(local->hive_key, security);
345 : }
346 : const static struct registry_operations local_ops = {
347 : .name = "local",
348 : .open_key = local_open_key,
349 : .get_predefined_key = local_get_predefined_key,
350 : .enum_key = local_enum_key,
351 : .create_key = local_create_key,
352 : .set_value = local_set_value,
353 : .get_value = local_get_value,
354 : .enum_value = local_enum_value,
355 : .delete_key = local_delete_key,
356 : .delete_value = local_delete_value,
357 : .flush_key = local_flush_key,
358 : .get_key_info = local_get_key_info,
359 : .get_sec_desc = local_get_sec_desc,
360 : .set_sec_desc = local_set_sec_desc,
361 : };
362 :
363 534 : WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx)
364 : {
365 534 : struct registry_local *ret = talloc_zero(mem_ctx,
366 : struct registry_local);
367 :
368 534 : W_ERROR_HAVE_NO_MEMORY(ret);
369 :
370 534 : ret->ops = &local_ops;
371 :
372 534 : *ctx = (struct registry_context *)ret;
373 :
374 534 : return WERR_OK;
375 : }
376 :
377 1506 : WERROR reg_mount_hive(struct registry_context *rctx,
378 : struct hive_key *hive_key,
379 : uint32_t key_id,
380 : const char **elements)
381 : {
382 1506 : struct registry_local *reg_local = talloc_get_type(rctx,
383 : struct registry_local);
384 32 : struct mountpoint *mp;
385 1506 : unsigned int i = 0;
386 :
387 1506 : mp = talloc(rctx, struct mountpoint);
388 1506 : W_ERROR_HAVE_NO_MEMORY(mp);
389 1506 : mp->path.predefined_key = key_id;
390 1506 : mp->prev = mp->next = NULL;
391 1506 : mp->key = hive_key;
392 1506 : if (elements != NULL && elements[0] != NULL) {
393 0 : mp->path.elements = talloc_array(mp, const char *,
394 : str_list_length(elements));
395 0 : W_ERROR_HAVE_NO_MEMORY(mp->path.elements);
396 0 : for (i = 0; elements[i] != NULL; i++) {
397 0 : mp->path.elements[i] = talloc_reference(mp->path.elements,
398 : elements[i]);
399 : }
400 0 : mp->path.elements[i] = NULL;
401 : } else {
402 1506 : mp->path.elements = NULL;
403 : }
404 :
405 1506 : DLIST_ADD(reg_local->mountpoints, mp);
406 :
407 1506 : return WERR_OK;
408 : }
|