2 Unix SMB/CIFS implementation.
3 Transparent registry backend handling
4 Copyright (C) Jelmer Vernooij 2003-2007.
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.
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.
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.
22 #include "../lib/util/dlinklist.h"
23 #include "lib/registry/registry.h"
24 #include "system/filesys.h"
27 uint32_t predefined_key
;
28 const char **elements
;
31 struct registry_local
{
32 const struct registry_operations
*ops
;
35 struct reg_key_path path
;
37 struct mountpoint
*prev
, *next
;
42 struct registry_key global
;
43 struct reg_key_path path
;
44 struct hive_key
*hive_key
;
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
)
53 struct local_key
*local_key
;
54 struct reg_key_path parent_path
;
56 parent_path
.predefined_key
= predefined_key
;
57 parent_path
.elements
= elements
;
59 local_key
= talloc(ctx
, struct local_key
);
60 if (local_key
!= NULL
) {
61 local_key
->hive_key
= talloc_reference(local_key
, hive
);
62 local_key
->global
.context
= talloc_reference(local_key
, ctx
);
63 local_key
->path
= parent_path
;
66 return (struct registry_key
*)local_key
;
70 static WERROR
local_open_key(TALLOC_CTX
*mem_ctx
,
71 struct registry_key
*parent
,
73 struct registry_key
**result
)
75 char *orig
, *curbegin
, *curend
;
76 struct local_key
*local_parent
= talloc_get_type(parent
,
78 struct hive_key
*curkey
= local_parent
->hive_key
;
80 const char **elements
= NULL
;
83 if (path
== NULL
|| path
[0] == '\0') {
84 return WERR_INVALID_PARAMETER
;
87 orig
= talloc_strdup(mem_ctx
, path
);
88 W_ERROR_HAVE_NO_MEMORY(orig
);
90 curend
= strchr(orig
, '\\');
92 if (local_parent
->path
.elements
!= NULL
) {
93 elements
= talloc_array(mem_ctx
, const char *,
94 str_list_length(local_parent
->path
.elements
) + 1);
95 W_ERROR_HAVE_NO_MEMORY(elements
);
96 for (el
= 0; local_parent
->path
.elements
[el
] != NULL
; el
++) {
97 elements
[el
] = talloc_reference(elements
,
98 local_parent
->path
.elements
[el
]);
109 elements
= talloc_realloc(mem_ctx
, elements
, const char *, el
+2);
110 W_ERROR_HAVE_NO_MEMORY(elements
);
111 elements
[el
] = talloc_strdup(elements
, curbegin
);
112 W_ERROR_HAVE_NO_MEMORY(elements
[el
]);
115 error
= hive_get_key_by_name(mem_ctx
, curkey
,
117 if (!W_ERROR_IS_OK(error
)) {
118 DEBUG(2, ("Opening key %s failed: %s\n", curbegin
,
125 curbegin
= curend
+ 1;
126 curend
= strchr(curbegin
, '\\');
127 } while (curbegin
[0] != '\0');
130 *result
= reg_import_hive_key(local_parent
->global
.context
, curkey
,
131 local_parent
->path
.predefined_key
,
132 talloc_steal(curkey
, elements
));
137 WERROR
local_get_predefined_key(struct registry_context
*ctx
,
138 uint32_t key_id
, struct registry_key
**key
)
140 struct registry_local
*rctx
= talloc_get_type(ctx
,
141 struct registry_local
);
142 struct mountpoint
*mp
;
144 for (mp
= rctx
->mountpoints
; mp
!= NULL
; mp
= mp
->next
) {
145 if (mp
->path
.predefined_key
== key_id
&&
146 mp
->path
.elements
== NULL
)
151 return WERR_FILE_NOT_FOUND
;
153 *key
= reg_import_hive_key(ctx
, mp
->key
,
154 mp
->path
.predefined_key
,
160 static WERROR
local_enum_key(TALLOC_CTX
*mem_ctx
,
161 const struct registry_key
*key
, uint32_t idx
,
163 const char **keyclass
,
164 NTTIME
*last_changed_time
)
166 const struct local_key
*local
= (const struct local_key
*)key
;
168 return hive_enum_key(mem_ctx
, local
->hive_key
, idx
, name
, keyclass
,
172 static WERROR
local_create_key(TALLOC_CTX
*mem_ctx
,
173 struct registry_key
*parent
,
175 const char *key_class
,
176 struct security_descriptor
*security
,
177 struct registry_key
**result
)
179 char *orig
, *curbegin
, *curend
;
180 struct local_key
*local_parent
= talloc_get_type(parent
,
182 struct hive_key
*curkey
= local_parent
->hive_key
;
184 const char **elements
= NULL
;
187 if (path
== NULL
|| path
[0] == '\0') {
188 return WERR_INVALID_PARAMETER
;
191 orig
= talloc_strdup(mem_ctx
, path
);
192 W_ERROR_HAVE_NO_MEMORY(orig
);
194 curend
= strchr(orig
, '\\');
196 if (local_parent
->path
.elements
!= NULL
) {
197 elements
= talloc_array(mem_ctx
, const char *,
198 str_list_length(local_parent
->path
.elements
) + 1);
199 W_ERROR_HAVE_NO_MEMORY(elements
);
200 for (el
= 0; local_parent
->path
.elements
[el
] != NULL
; el
++) {
201 elements
[el
] = talloc_reference(elements
,
202 local_parent
->path
.elements
[el
]);
213 elements
= talloc_realloc(mem_ctx
, elements
, const char *, el
+2);
214 W_ERROR_HAVE_NO_MEMORY(elements
);
215 elements
[el
] = talloc_strdup(elements
, curbegin
);
216 W_ERROR_HAVE_NO_MEMORY(elements
[el
]);
219 error
= hive_get_key_by_name(mem_ctx
, curkey
,
221 if (W_ERROR_EQUAL(error
, WERR_FILE_NOT_FOUND
)) {
222 error
= hive_key_add_name(mem_ctx
, curkey
, curbegin
,
226 if (!W_ERROR_IS_OK(error
)) {
227 DEBUG(2, ("Open/Creation of key %s failed: %s\n",
228 curbegin
, win_errstr(error
)));
234 curbegin
= curend
+ 1;
235 curend
= strchr(curbegin
, '\\');
236 } while (curbegin
[0] != '\0');
239 *result
= reg_import_hive_key(local_parent
->global
.context
, curkey
,
240 local_parent
->path
.predefined_key
,
241 talloc_steal(curkey
, elements
));
246 static WERROR
local_set_value(struct registry_key
*key
, const char *name
,
247 uint32_t type
, const DATA_BLOB data
)
249 struct local_key
*local
= (struct local_key
*)key
;
252 return WERR_INVALID_PARAMETER
;
255 return hive_key_set_value(local
->hive_key
, name
, type
, data
);
258 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
)
262 const struct local_key
*local
= (const struct local_key
*)key
;
265 return WERR_INVALID_PARAMETER
;
268 return hive_get_value(mem_ctx
, local
->hive_key
, name
, type
, data
);
271 static WERROR
local_enum_value(TALLOC_CTX
*mem_ctx
,
272 const struct registry_key
*key
, uint32_t idx
,
277 const struct local_key
*local
= (const struct local_key
*)key
;
279 return hive_get_value_by_index(mem_ctx
, local
->hive_key
, idx
,
283 static WERROR
local_delete_key(TALLOC_CTX
*mem_ctx
, struct registry_key
*key
,
286 const struct local_key
*local
= (const struct local_key
*)key
;
289 return WERR_INVALID_PARAMETER
;
292 return hive_key_del(mem_ctx
, local
->hive_key
, name
);
295 static WERROR
local_delete_value(TALLOC_CTX
*mem_ctx
, struct registry_key
*key
,
298 const struct local_key
*local
= (const struct local_key
*)key
;
301 return WERR_INVALID_PARAMETER
;
304 return hive_key_del_value(mem_ctx
, local
->hive_key
, name
);
307 static WERROR
local_flush_key(struct registry_key
*key
)
309 const struct local_key
*local
= (const struct local_key
*)key
;
311 return hive_key_flush(local
->hive_key
);
314 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
)
324 const struct local_key
*local
= (const struct local_key
*)key
;
326 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
);
331 static WERROR
local_get_sec_desc(TALLOC_CTX
*mem_ctx
,
332 const struct registry_key
*key
,
333 struct security_descriptor
**security
)
335 const struct local_key
*local
= (const struct local_key
*)key
;
337 return hive_get_sec_desc(mem_ctx
, local
->hive_key
, security
);
339 static WERROR
local_set_sec_desc(struct registry_key
*key
,
340 const struct security_descriptor
*security
)
342 const struct local_key
*local
= (const struct local_key
*)key
;
344 return hive_set_sec_desc(local
->hive_key
, security
);
346 const static struct registry_operations local_ops
= {
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
,
363 WERROR
reg_open_local(TALLOC_CTX
*mem_ctx
, struct registry_context
**ctx
)
365 struct registry_local
*ret
= talloc_zero(mem_ctx
,
366 struct registry_local
);
368 W_ERROR_HAVE_NO_MEMORY(ret
);
370 ret
->ops
= &local_ops
;
372 *ctx
= (struct registry_context
*)ret
;
377 WERROR
reg_mount_hive(struct registry_context
*rctx
,
378 struct hive_key
*hive_key
,
380 const char **elements
)
382 struct registry_local
*reg_local
= talloc_get_type(rctx
,
383 struct registry_local
);
384 struct mountpoint
*mp
;
387 mp
= talloc(rctx
, struct mountpoint
);
388 W_ERROR_HAVE_NO_MEMORY(mp
);
389 mp
->path
.predefined_key
= key_id
;
390 mp
->prev
= mp
->next
= NULL
;
392 if (elements
!= NULL
&& elements
[0] != NULL
) {
393 mp
->path
.elements
= talloc_array(mp
, const char *,
394 str_list_length(elements
));
395 W_ERROR_HAVE_NO_MEMORY(mp
->path
.elements
);
396 for (i
= 0; elements
[i
] != NULL
; i
++) {
397 mp
->path
.elements
[i
] = talloc_reference(mp
->path
.elements
,
400 mp
->path
.elements
[i
] = NULL
;
402 mp
->path
.elements
= NULL
;
405 DLIST_ADD(reg_local
->mountpoints
, mp
);