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 23718 : 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 23718 : parent_path.predefined_key = predefined_key;
57 23718 : parent_path.elements = elements;
58 :
59 23718 : local_key = talloc(ctx, struct local_key);
60 23718 : if (local_key != NULL) {
61 23718 : local_key->hive_key = talloc_reference(local_key, hive);
62 23718 : local_key->global.context = talloc_reference(local_key, ctx);
63 23718 : local_key->path = parent_path;
64 : }
65 :
66 23718 : return (struct registry_key *)local_key;
67 : }
68 :
69 :
70 6306 : 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 : char *orig, *curbegin, *curend;
76 6306 : struct local_key *local_parent = talloc_get_type(parent,
77 : struct local_key);
78 6306 : struct hive_key *curkey = local_parent->hive_key;
79 : WERROR error;
80 6306 : const char **elements = NULL;
81 : int el;
82 :
83 6306 : if (path == NULL || path[0] == '\0') {
84 0 : return WERR_INVALID_PARAMETER;
85 : }
86 :
87 6306 : orig = talloc_strdup(mem_ctx, path);
88 6306 : W_ERROR_HAVE_NO_MEMORY(orig);
89 6306 : curbegin = orig;
90 6306 : curend = strchr(orig, '\\');
91 :
92 6306 : if (local_parent->path.elements != NULL) {
93 0 : elements = talloc_array(mem_ctx, const char *,
94 : str_list_length(local_parent->path.elements) + 1);
95 0 : W_ERROR_HAVE_NO_MEMORY(elements);
96 0 : for (el = 0; local_parent->path.elements[el] != NULL; el++) {
97 0 : elements[el] = talloc_reference(elements,
98 : local_parent->path.elements[el]);
99 : }
100 0 : elements[el] = NULL;
101 : } else {
102 6306 : elements = NULL;
103 6306 : el = 0;
104 : }
105 :
106 : do {
107 13827 : if (curend != NULL)
108 7521 : *curend = '\0';
109 13827 : elements = talloc_realloc(mem_ctx, elements, const char *, el+2);
110 13827 : W_ERROR_HAVE_NO_MEMORY(elements);
111 13827 : elements[el] = talloc_strdup(elements, curbegin);
112 13827 : W_ERROR_HAVE_NO_MEMORY(elements[el]);
113 13827 : el++;
114 13827 : elements[el] = NULL;
115 13827 : error = hive_get_key_by_name(mem_ctx, curkey,
116 : curbegin, &curkey);
117 13827 : if (!W_ERROR_IS_OK(error)) {
118 320 : DEBUG(2, ("Opening key %s failed: %s\n", curbegin,
119 : win_errstr(error)));
120 320 : talloc_free(orig);
121 320 : return error;
122 : }
123 13507 : if (curend == NULL)
124 5986 : break;
125 7521 : curbegin = curend + 1;
126 7521 : curend = strchr(curbegin, '\\');
127 7521 : } while (curbegin[0] != '\0');
128 5986 : talloc_free(orig);
129 :
130 6832 : *result = reg_import_hive_key(local_parent->global.context, curkey,
131 : local_parent->path.predefined_key,
132 5986 : talloc_steal(curkey, elements));
133 :
134 5986 : return WERR_OK;
135 : }
136 :
137 8408 : WERROR local_get_predefined_key(struct registry_context *ctx,
138 : uint32_t key_id, struct registry_key **key)
139 : {
140 8408 : struct registry_local *rctx = talloc_get_type(ctx,
141 : struct registry_local);
142 : struct mountpoint *mp;
143 :
144 8897 : for (mp = rctx->mountpoints; mp != NULL; mp = mp->next) {
145 16210 : if (mp->path.predefined_key == key_id &&
146 8408 : mp->path.elements == NULL)
147 8408 : break;
148 : }
149 :
150 8408 : if (mp == NULL)
151 0 : return WERR_FILE_NOT_FOUND;
152 :
153 8408 : *key = reg_import_hive_key(ctx, mp->key,
154 : mp->path.predefined_key,
155 : mp->path.elements);
156 :
157 8408 : return WERR_OK;
158 : }
159 :
160 240 : 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 240 : const struct local_key *local = (const struct local_key *)key;
167 :
168 240 : return hive_enum_key(mem_ctx, local->hive_key, idx, name, keyclass,
169 : last_changed_time);
170 : }
171 :
172 9324 : 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 : char *orig, *curbegin, *curend;
180 9324 : struct local_key *local_parent = talloc_get_type(parent,
181 : struct local_key);
182 9324 : struct hive_key *curkey = local_parent->hive_key;
183 : WERROR error;
184 9324 : const char **elements = NULL;
185 : int el;
186 :
187 9324 : if (path == NULL || path[0] == '\0') {
188 0 : return WERR_INVALID_PARAMETER;
189 : }
190 :
191 9324 : orig = talloc_strdup(mem_ctx, path);
192 9324 : W_ERROR_HAVE_NO_MEMORY(orig);
193 9324 : curbegin = orig;
194 9324 : curend = strchr(orig, '\\');
195 :
196 9324 : if (local_parent->path.elements != NULL) {
197 5545 : elements = talloc_array(mem_ctx, const char *,
198 : str_list_length(local_parent->path.elements) + 1);
199 5545 : W_ERROR_HAVE_NO_MEMORY(elements);
200 16341 : for (el = 0; local_parent->path.elements[el] != NULL; el++) {
201 10796 : elements[el] = talloc_reference(elements,
202 : local_parent->path.elements[el]);
203 : }
204 5545 : elements[el] = NULL;
205 : } else {
206 3779 : elements = NULL;
207 3779 : el = 0;
208 : }
209 :
210 : do {
211 11324 : if (curend != NULL)
212 2000 : *curend = '\0';
213 11324 : elements = talloc_realloc(mem_ctx, elements, const char *, el+2);
214 11324 : W_ERROR_HAVE_NO_MEMORY(elements);
215 11324 : elements[el] = talloc_strdup(elements, curbegin);
216 11324 : W_ERROR_HAVE_NO_MEMORY(elements[el]);
217 11324 : el++;
218 11324 : elements[el] = NULL;
219 11324 : error = hive_get_key_by_name(mem_ctx, curkey,
220 : curbegin, &curkey);
221 11324 : if (W_ERROR_EQUAL(error, WERR_FILE_NOT_FOUND)) {
222 3958 : error = hive_key_add_name(mem_ctx, curkey, curbegin,
223 : key_class, security,
224 : &curkey);
225 : }
226 11324 : 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 11324 : if (curend == NULL)
233 9324 : break;
234 2000 : curbegin = curend + 1;
235 2000 : curend = strchr(curbegin, '\\');
236 2000 : } while (curbegin[0] != '\0');
237 9324 : talloc_free(orig);
238 :
239 11048 : *result = reg_import_hive_key(local_parent->global.context, curkey,
240 : local_parent->path.predefined_key,
241 9324 : talloc_steal(curkey, elements));
242 :
243 9324 : return WERR_OK;
244 : }
245 :
246 1881 : static WERROR local_set_value(struct registry_key *key, const char *name,
247 : uint32_t type, const DATA_BLOB data)
248 : {
249 1881 : struct local_key *local = (struct local_key *)key;
250 :
251 1881 : if (name == NULL) {
252 0 : return WERR_INVALID_PARAMETER;
253 : }
254 :
255 1881 : return hive_key_set_value(local->hive_key, name, type, data);
256 : }
257 :
258 8160 : 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 8160 : const struct local_key *local = (const struct local_key *)key;
263 :
264 8160 : if (name == NULL) {
265 240 : return WERR_INVALID_PARAMETER;
266 : }
267 :
268 7920 : return hive_get_value(mem_ctx, local->hive_key, name, type, data);
269 : }
270 :
271 480 : 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 480 : const struct local_key *local = (const struct local_key *)key;
278 :
279 480 : return hive_get_value_by_index(mem_ctx, local->hive_key, idx,
280 : name, type, data);
281 : }
282 :
283 2560 : static WERROR local_delete_key(TALLOC_CTX *mem_ctx, struct registry_key *key,
284 : const char *name)
285 : {
286 2560 : const struct local_key *local = (const struct local_key *)key;
287 :
288 2560 : if (name == NULL) {
289 0 : return WERR_INVALID_PARAMETER;
290 : }
291 :
292 2560 : return hive_key_del(mem_ctx, local->hive_key, name);
293 : }
294 :
295 1440 : static WERROR local_delete_value(TALLOC_CTX *mem_ctx, struct registry_key *key,
296 : const char *name)
297 : {
298 1440 : const struct local_key *local = (const struct local_key *)key;
299 :
300 1440 : if (name == NULL) {
301 0 : return WERR_INVALID_PARAMETER;
302 : }
303 :
304 1440 : return hive_key_del_value(mem_ctx, local->hive_key, name);
305 : }
306 :
307 640 : static WERROR local_flush_key(struct registry_key *key)
308 : {
309 640 : const struct local_key *local = (const struct local_key *)key;
310 :
311 640 : return hive_key_flush(local->hive_key);
312 : }
313 :
314 241 : 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 241 : const struct local_key *local = (const struct local_key *)key;
325 :
326 241 : 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 0 : static WERROR local_set_sec_desc(struct registry_key *key,
340 : const struct security_descriptor *security)
341 : {
342 0 : const struct local_key *local = (const struct local_key *)key;
343 :
344 0 : 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 470 : WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx)
364 : {
365 470 : struct registry_local *ret = talloc_zero(mem_ctx,
366 : struct registry_local);
367 :
368 470 : W_ERROR_HAVE_NO_MEMORY(ret);
369 :
370 470 : ret->ops = &local_ops;
371 :
372 470 : *ctx = (struct registry_context *)ret;
373 :
374 470 : return WERR_OK;
375 : }
376 :
377 1439 : 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 1439 : struct registry_local *reg_local = talloc_get_type(rctx,
383 : struct registry_local);
384 : struct mountpoint *mp;
385 1439 : unsigned int i = 0;
386 :
387 1439 : mp = talloc(rctx, struct mountpoint);
388 1439 : W_ERROR_HAVE_NO_MEMORY(mp);
389 1439 : mp->path.predefined_key = key_id;
390 1439 : mp->prev = mp->next = NULL;
391 1439 : mp->key = hive_key;
392 1439 : 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 1439 : mp->path.elements = NULL;
403 : }
404 :
405 1439 : DLIST_ADD(reg_local->mountpoints, mp);
406 :
407 1439 : return WERR_OK;
408 : }
|