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