2 * Unix SMB/CIFS implementation.
3 * Virtual Windows Registry Layer
4 * Copyright (C) Volker Lendecke 2006
5 * Copyright (C) Michael Adam 2007-2008
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "system/filesys.h"
24 #include "reg_api_regf.h"
25 #include "reg_cachehook.h"
27 #include "reg_util_internal.h"
28 #include "reg_dispatcher.h"
31 #define DBGC_CLASS DBGC_REGISTRY
33 /*******************************************************************
34 Note: topkeypat is the *full* path that this *key will be
35 loaded into (including the name of the key)
36 ********************************************************************/
38 static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath,
42 struct registry_key_handle registry_key;
43 struct regval_ctr *values;
44 struct regsubkey_ctr *subkeys;
47 WERROR result = WERR_OK;
49 /* initialize the struct registry_key_handle structure */
51 registry_key.ops = reghook_cache_find(topkeypath);
52 if (!registry_key.ops) {
53 DEBUG(0, ("reg_load_tree: Failed to assign registry_ops "
54 "to [%s]\n", topkeypath));
58 registry_key.name = talloc_strdup(regfile->mem_ctx, topkeypath);
59 if (!registry_key.name) {
60 DEBUG(0, ("reg_load_tree: Talloc failed for reg_key.name!\n"));
64 /* now start parsing the values and subkeys */
66 result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
67 W_ERROR_NOT_OK_RETURN(result);
69 result = regval_ctr_init(subkeys, &values);
70 W_ERROR_NOT_OK_RETURN(result);
72 /* copy values into the struct regval_ctr */
74 for (i=0; i<key->num_values; i++) {
75 regval_ctr_addvalue(values, key->values[i].valuename,
78 (key->values[i].data_size & ~VK_DATA_IN_OFFSET));
81 /* copy subkeys into the struct regsubkey_ctr */
83 key->subkey_index = 0;
84 while ((subkey = regfio_fetch_subkey( regfile, key ))) {
85 result = regsubkey_ctr_addkey(subkeys, subkey->keyname);
86 if (!W_ERROR_IS_OK(result)) {
92 /* write this key and values out */
94 if (!store_reg_values(®istry_key, values)
95 || !store_reg_keys(®istry_key, subkeys))
97 DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
98 result = WERR_REG_IO_FAILURE;
101 TALLOC_FREE(subkeys);
103 if (!W_ERROR_IS_OK(result)) {
107 /* now continue to load each subkey registry tree */
109 key->subkey_index = 0;
110 while ((subkey = regfio_fetch_subkey(regfile, key))) {
111 path = talloc_asprintf(regfile->mem_ctx,
118 result = reg_load_tree(regfile, path, subkey);
119 if (!W_ERROR_IS_OK(result)) {
127 /*******************************************************************
128 ********************************************************************/
130 static WERROR restore_registry_key(struct registry_key_handle *krecord,
134 REGF_NK_REC *rootkey;
137 /* open the registry file....fail if the file already exists */
139 regfile = regfio_open(fname, (O_RDONLY), 0);
140 if (regfile == NULL) {
141 DEBUG(0, ("restore_registry_key: failed to open \"%s\" (%s)\n",
142 fname, strerror(errno)));
143 return ntstatus_to_werror(map_nt_error_from_unix(errno));
146 /* get the rootkey from the regf file and then load the tree
147 via recursive calls */
149 if (!(rootkey = regfio_rootkey(regfile))) {
150 regfio_close(regfile);
151 return WERR_REG_FILE_INVALID;
154 result = reg_load_tree(regfile, krecord->name, rootkey);
158 regfio_close(regfile);
163 WERROR reg_restorekey(struct registry_key *key, const char *fname)
165 return restore_registry_key(key->key, fname);
168 /********************************************************************
169 ********************************************************************/
171 static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath,
175 struct regval_ctr *values;
176 struct regsubkey_ctr *subkeys;
178 char *key_tmp = NULL;
179 char *keyname, *parentpath;
180 char *subkeypath = NULL;
182 struct registry_key_handle registry_key;
183 WERROR result = WERR_OK;
184 struct security_descriptor *sec_desc = NULL;
187 return WERR_GENERAL_FAILURE;
191 return WERR_OBJECT_PATH_INVALID;
194 /* split up the registry key path */
196 key_tmp = talloc_strdup(regfile->mem_ctx, keypath);
200 if (!reg_split_key(key_tmp, &parentpath, &keyname)) {
201 return WERR_OBJECT_PATH_INVALID;
205 keyname = parentpath;
208 /* we need a registry_key_handle object here to enumerate subkeys and values */
210 ZERO_STRUCT(registry_key);
212 registry_key.name = talloc_strdup(regfile->mem_ctx, keypath);
213 if (registry_key.name == NULL) {
217 registry_key.ops = reghook_cache_find(registry_key.name);
218 if (registry_key.ops == NULL) {
222 /* lookup the values and subkeys */
224 result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
225 W_ERROR_NOT_OK_RETURN(result);
227 result = regval_ctr_init(subkeys, &values);
228 W_ERROR_NOT_OK_RETURN(result);
230 fetch_reg_keys(®istry_key, subkeys);
231 fetch_reg_values(®istry_key, values);
233 result = regkey_get_secdesc(regfile->mem_ctx, ®istry_key, &sec_desc);
234 if (!W_ERROR_IS_OK(result)) {
238 /* write out this key */
240 key = regfio_write_key(regfile, keyname, values, subkeys, sec_desc,
243 result = WERR_CAN_NOT_COMPLETE;
247 /* write each one of the subkeys out */
249 num_subkeys = regsubkey_ctr_numkeys(subkeys);
250 for (i=0; i<num_subkeys; i++) {
251 subkeyname = regsubkey_ctr_specific_key(subkeys, i);
252 subkeypath = talloc_asprintf(regfile->mem_ctx, "%s\\%s",
253 keypath, subkeyname);
254 if (subkeypath == NULL) {
258 result = reg_write_tree(regfile, subkeypath, key);
259 if (!W_ERROR_IS_OK(result))
263 DEBUG(6, ("reg_write_tree: wrote key [%s]\n", keypath));
266 TALLOC_FREE(subkeys);
267 TALLOC_FREE(registry_key.name);
272 static WERROR backup_registry_key(struct registry_key_handle *krecord,
278 /* open the registry file....fail if the file already exists */
280 regfile = regfio_open(fname, (O_RDWR|O_CREAT|O_EXCL),
282 if (regfile == NULL) {
283 DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n",
284 fname, strerror(errno) ));
285 return ntstatus_to_werror(map_nt_error_from_unix(errno));
288 /* write the registry tree to the file */
290 result = reg_write_tree(regfile, krecord->name, NULL);
294 regfio_close(regfile);
299 WERROR reg_savekey(struct registry_key *key, const char *fname)
301 return backup_registry_key(key->key, fname);