• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.5.8/source4/lib/registry/
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
26struct reg_key_path {
27	uint32_t predefined_key;
28	const char **elements;
29};
30
31struct 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
41struct local_key {
42	struct registry_key global;
43	struct reg_key_path path;
44	struct hive_key *hive_key;
45};
46
47
48struct 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
68static 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
125WERROR 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
148static 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
160static 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
210static 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
218static 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
227static 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
239static 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
246static 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
253static 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
260static 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}
277static 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}
285static 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}
292const 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
309WERROR 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
323WERROR 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}
352