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/>.
23 #include "reg_cachehook.h"
25 #include "reg_util_internal.h"
26 #include "reg_dispatcher.h"
27 #include "reg_objects.h"
30 #define DBGC_CLASS DBGC_REGISTRY
32 /*******************************************************************
33 Note: topkeypat is the *full* path that this *key will be
34 loaded into (including the name of the key)
35 ********************************************************************/
37 static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath,
41 struct registry_key_handle registry_key;
42 struct regval_ctr *values;
43 struct regsubkey_ctr *subkeys;
46 WERROR result = WERR_OK;
48 /* initialize the struct registry_key_handle structure */
50 registry_key.ops = reghook_cache_find(topkeypath);
51 if (!registry_key.ops) {
52 DEBUG(0, ("reg_load_tree: Failed to assign registry_ops "
53 "to [%s]\n", topkeypath));
57 registry_key.name = talloc_strdup(regfile->mem_ctx, topkeypath);
58 if (!registry_key.name) {
59 DEBUG(0, ("reg_load_tree: Talloc failed for reg_key.name!\n"));
63 /* now start parsing the values and subkeys */
65 result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
66 W_ERROR_NOT_OK_RETURN(result);
68 result = regval_ctr_init(subkeys, &values);
69 W_ERROR_NOT_OK_RETURN(result);
71 /* copy values into the struct regval_ctr */
73 for (i=0; i<key->num_values; i++) {
74 regval_ctr_addvalue(values, key->values[i].valuename,
77 (key->values[i].data_size & ~VK_DATA_IN_OFFSET));
80 /* copy subkeys into the struct regsubkey_ctr */
82 key->subkey_index = 0;
83 while ((subkey = regfio_fetch_subkey( regfile, key ))) {
84 result = regsubkey_ctr_addkey(subkeys, subkey->keyname);
85 if (!W_ERROR_IS_OK(result)) {
91 /* write this key and values out */
93 if (!store_reg_values(®istry_key, values)
94 || !store_reg_keys(®istry_key, subkeys))
96 DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
97 result = WERR_REG_IO_FAILURE;
100 TALLOC_FREE(subkeys);
102 if (!W_ERROR_IS_OK(result)) {
106 /* now continue to load each subkey registry tree */
108 key->subkey_index = 0;
109 while ((subkey = regfio_fetch_subkey(regfile, key))) {
110 path = talloc_asprintf(regfile->mem_ctx,
117 result = reg_load_tree(regfile, path, subkey);
118 if (!W_ERROR_IS_OK(result)) {
126 /*******************************************************************
127 ********************************************************************/
129 static WERROR restore_registry_key(struct registry_key_handle *krecord,
133 REGF_NK_REC *rootkey;
136 /* open the registry file....fail if the file already exists */
138 regfile = regfio_open(fname, (O_RDONLY), 0);
139 if (regfile == NULL) {
140 DEBUG(0, ("restore_registry_key: failed to open \"%s\" (%s)\n",
141 fname, strerror(errno)));
142 return ntstatus_to_werror(map_nt_error_from_unix(errno));
145 /* get the rootkey from the regf file and then load the tree
146 via recursive calls */
148 if (!(rootkey = regfio_rootkey(regfile))) {
149 regfio_close(regfile);
150 return WERR_REG_FILE_INVALID;
153 result = reg_load_tree(regfile, krecord->name, rootkey);
157 regfio_close(regfile);
162 WERROR reg_restorekey(struct registry_key *key, const char *fname)
164 return restore_registry_key(key->key, fname);
167 /********************************************************************
168 ********************************************************************/
170 static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath,
174 struct regval_ctr *values;
175 struct regsubkey_ctr *subkeys;
177 char *key_tmp = NULL;
178 char *keyname, *parentpath;
179 char *subkeypath = NULL;
181 struct registry_key_handle registry_key;
182 WERROR result = WERR_OK;
183 struct security_descriptor *sec_desc = NULL;
186 return WERR_GENERAL_FAILURE;
190 return WERR_OBJECT_PATH_INVALID;
193 /* split up the registry key path */
195 key_tmp = talloc_strdup(regfile->mem_ctx, keypath);
199 if (!reg_split_key(key_tmp, &parentpath, &keyname)) {
200 return WERR_OBJECT_PATH_INVALID;
204 keyname = parentpath;
207 /* we need a registry_key_handle object here to enumerate subkeys and values */
209 ZERO_STRUCT(registry_key);
211 registry_key.name = talloc_strdup(regfile->mem_ctx, keypath);
212 if (registry_key.name == NULL) {
216 registry_key.ops = reghook_cache_find(registry_key.name);
217 if (registry_key.ops == NULL) {
221 /* lookup the values and subkeys */
223 result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
224 W_ERROR_NOT_OK_RETURN(result);
226 result = regval_ctr_init(subkeys, &values);
227 W_ERROR_NOT_OK_RETURN(result);
229 fetch_reg_keys(®istry_key, subkeys);
230 fetch_reg_values(®istry_key, values);
232 result = regkey_get_secdesc(regfile->mem_ctx, ®istry_key, &sec_desc);
233 if (!W_ERROR_IS_OK(result)) {
237 /* write out this key */
239 key = regfio_write_key(regfile, keyname, values, subkeys, sec_desc,
242 result = WERR_CAN_NOT_COMPLETE;
246 /* write each one of the subkeys out */
248 num_subkeys = regsubkey_ctr_numkeys(subkeys);
249 for (i=0; i<num_subkeys; i++) {
250 subkeyname = regsubkey_ctr_specific_key(subkeys, i);
251 subkeypath = talloc_asprintf(regfile->mem_ctx, "%s\\%s",
252 keypath, subkeyname);
253 if (subkeypath == NULL) {
257 result = reg_write_tree(regfile, subkeypath, key);
258 if (!W_ERROR_IS_OK(result))
262 DEBUG(6, ("reg_write_tree: wrote key [%s]\n", keypath));
265 TALLOC_FREE(subkeys);
266 TALLOC_FREE(registry_key.name);
271 static WERROR backup_registry_key(struct registry_key_handle *krecord,
277 /* open the registry file....fail if the file already exists */
279 regfile = regfio_open(fname, (O_RDWR|O_CREAT|O_EXCL),
281 if (regfile == NULL) {
282 DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n",
283 fname, strerror(errno) ));
284 return ntstatus_to_werror(map_nt_error_from_unix(errno));
287 /* write the registry tree to the file */
289 result = reg_write_tree(regfile, krecord->name, NULL);
293 regfio_close(regfile);
298 WERROR reg_savekey(struct registry_key *key, const char *fname)
300 return backup_registry_key(key->key, fname);