selftest: Add ldapcmp to ensure upgradeprovision of a fresh DB is a no-op
[Samba/gbeck.git] / source3 / registry / reg_import.c
blob8bcce6855e1408d0aae5f4bdd4d96a2e7150e239
1 /*
2 * Samba Unix/Linux SMB client library
3 * Adapter to use reg_parse with the registry api
5 * Copyright (C) Gregor Beck 2010
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/>.
21 #include "includes.h"
22 #include "reg_parse.h"
23 #include "reg_import.h"
24 #include "registry.h"
25 #include "registry/reg_objects.h"
26 #include <assert.h>
28 /* Debuglevel for tracing */
29 static const int TL = 2;
31 struct reg_import {
32 struct reg_parse_callback reg_parse_callback;
33 struct reg_import_callback call;
34 void *open_key;
37 static int reg_parse_callback_key(struct reg_import *cb_private,
38 const char *key[], size_t n, bool del);
40 static int reg_parse_callback_val(struct reg_import *cb_private,
41 const char *name, uint32_t type,
42 const uint8_t *data, uint32_t len);
44 static int reg_parse_callback_val_registry_value(struct reg_import *cb_private,
45 const char *name,
46 uint32_t type,
47 const uint8_t *data,
48 uint32_t len);
50 static int reg_parse_callback_val_regval_blob(struct reg_import *cb_private,
51 const char *name, uint32_t type,
52 const uint8_t *data,
53 uint32_t len);
55 static int reg_parse_callback_val_del(struct reg_import *cb_private,
56 const char *name);
58 static int reg_parse_callback_comment(struct reg_import *cb_private,
59 const char *txt);
62 /*******************************************************************************/
64 int reg_parse_callback_key(struct reg_import *p,
65 const char *key[], size_t n, bool del)
67 WERROR werr = WERR_OK;
69 DEBUG(TL, ("%s: %s\n", __FUNCTION__, key[0]));
71 if (p->open_key != NULL) {
72 werr = p->call.closekey(p->call.data, p->open_key);
73 p->open_key = NULL;
74 if (!W_ERROR_IS_OK(werr)) {
75 DEBUG(0, ("closekey failed: %s\n", win_errstr(werr)));
79 if (del) {
80 werr = p->call.deletekey(p->call.data, NULL, key[0]);
81 if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
82 /* the key didn't exist, treat as success */
83 werr = WERR_OK;
85 if (!W_ERROR_IS_OK(werr)) {
86 DEBUG(0, ("deletekey %s failed: %s\n",
87 key[0], win_errstr(werr)));
89 } else {
90 bool existing;
91 werr = p->call.createkey(p->call.data, NULL, key[0],
92 &p->open_key, &existing);
93 if (W_ERROR_IS_OK(werr)) {
94 DEBUG(TL, ("createkey %s %s\n",
95 existing ? "opened" : "created", key[0]));
96 } else {
97 DEBUG(0, ("createkey %s failed: %s\n",
98 key[0], win_errstr(werr)));
102 return W_ERROR_IS_OK(werr) ? 0 : -1;
105 #define DEBUG_ADD_HEX(LEV, PTR, LEN) \
106 do { \
107 int i; \
108 const unsigned char* ptr = (const unsigned char*)PTR; \
109 for (i=0; i<LEN; i++) { \
110 DEBUGADD(LEV, ("'%c'(%02x)%s", \
111 isprint(ptr[i]) ? ptr[i] : '.', \
112 (unsigned)ptr[i], \
113 ((i+1 < LEN) && (i+1)%8) \
114 ? ", " : "\n")); \
116 } while(0)
118 /*----------------------------------------------------------------------------*/
119 int reg_parse_callback_val(struct reg_import *p,
120 const char *name, uint32_t type,
121 const uint8_t *data, uint32_t len)
123 WERROR werr = WERR_OK;
125 DEBUG(TL, ("%s(%x): >%s< = [%x]\n", __FUNCTION__, type, name, len));
126 DEBUG_ADD_HEX(TL, data, len);
128 werr = p->call.setval.blob(p->call.data, p->open_key, name, type,
129 data, len);
130 if (!W_ERROR_IS_OK(werr)) {
131 DEBUG(0, ("setval %s failed: %s\n",
132 name, win_errstr(werr)));
135 return W_ERROR_IS_OK(werr) ? 0 : -1;
138 /*----------------------------------------------------------------------------*/
139 int reg_parse_callback_val_registry_value(struct reg_import *p,
140 const char *name, uint32_t type,
141 const uint8_t *data, uint32_t len)
143 WERROR werr = WERR_OK;
144 struct registry_value val = {
145 .type = type,
146 .data = data_blob_talloc(p, data, len),
149 DEBUG(TL, ("%s(%x): >%s< = [%x]\n", __FUNCTION__, type, name, len));
150 DEBUG_ADD_HEX(TL, data, len);
152 werr = p->call.setval.registry_value(p->call.data, p->open_key,
153 name, &val);
154 if (!W_ERROR_IS_OK(werr)) {
155 DEBUG(0, ("setval %s failed: %s\n",
156 name, win_errstr(werr)));
159 data_blob_free(&val.data);
160 return W_ERROR_IS_OK(werr) ? 0 : -1;
163 /*----------------------------------------------------------------------------*/
164 int reg_parse_callback_val_regval_blob(struct reg_import *p,
165 const char *name, uint32_t type,
166 const uint8_t *data, uint32_t len)
168 WERROR werr = WERR_OK;
169 void* mem_ctx = talloc_new(p);
170 struct regval_blob *v = NULL;
172 DEBUG(TL, ("%s(%x): >%s< = [%x]\n", __FUNCTION__, type, name, len));
173 DEBUG_ADD_HEX(TL, data, len);
175 v = regval_compose(mem_ctx, name, type, data, len);
176 if (v == NULL) {
177 DEBUG(0, ("regval_compose %s failed\n", name));
178 werr = WERR_NOMEM;
179 goto done;
182 werr = p->call.setval.regval_blob(p->call.data, p->open_key, v);
183 if (!W_ERROR_IS_OK(werr)) {
184 DEBUG(0, ("setval %s failed: %s\n",
185 name, win_errstr(werr)));
188 done:
189 talloc_free(mem_ctx);
191 return W_ERROR_IS_OK(werr) ? 0 : -1;
195 /*----------------------------------------------------------------------------*/
197 int reg_parse_callback_val_del(struct reg_import *p,
198 const char *name)
200 WERROR werr = WERR_OK;
202 DEBUG(TL, ("%s: %s\n", __FUNCTION__, name));
204 werr = p->call.deleteval(p->call.data, p->open_key, name);
205 if (!W_ERROR_IS_OK(werr)) {
206 DEBUG(0, ("deleteval %s failed: %s\n",
207 name, win_errstr(werr)));
210 return W_ERROR_IS_OK(werr) ? 0 : -1;
214 int reg_parse_callback_comment(struct reg_import *cb_private,
215 const char *txt)
217 DEBUG(TL, ("%s: %s\n", __FUNCTION__, txt));
218 return 0;
221 /******************************************************************************/
222 static int nop(void *data)
224 return 0;
228 struct reg_parse_callback *reg_import_adapter(TALLOC_CTX *talloc_ctx,
229 struct reg_import_callback cb)
231 struct reg_parse_callback *ret;
232 struct reg_import *p = talloc_zero(talloc_ctx, struct reg_import);
233 if (p == NULL) {
234 goto fail;
236 if (cb.openkey == NULL) {
237 cb.openkey = (reg_import_callback_openkey_t)&nop;
239 if (cb.closekey == NULL) {
240 cb.closekey = (reg_import_callback_closekey_t)&nop;
242 if (cb.createkey == NULL) {
243 cb.createkey = (reg_import_callback_createkey_t)&nop;
245 if (cb.deletekey == NULL) {
246 cb.deletekey = (reg_import_callback_deletekey_t)&nop;
248 if (cb.deleteval == NULL) {
249 cb.deleteval = (reg_import_callback_deleteval_t)&nop;
252 p->call = cb;
254 ret = &p->reg_parse_callback;
255 ret->key = (reg_parse_callback_key_t) &reg_parse_callback_key;
256 ret->val_del = (reg_parse_callback_val_del_t) &reg_parse_callback_val_del;
257 ret->comment = (reg_parse_callback_comment_t) &reg_parse_callback_comment;
258 ret->data = p;
260 switch (cb.setval_type) {
261 case BLOB:
262 assert(cb.setval.blob != NULL);
263 ret->val = (reg_parse_callback_val_t) &reg_parse_callback_val;
264 break;
265 case REGISTRY_VALUE:
266 assert(cb.setval.registry_value != NULL);
267 ret->val = (reg_parse_callback_val_t) &reg_parse_callback_val_registry_value;
268 break;
269 case REGVAL_BLOB:
270 assert(cb.setval.regval_blob != NULL);
271 ret->val = (reg_parse_callback_val_t) &reg_parse_callback_val_regval_blob;
272 break;
273 case NONE:
274 ret->val = NULL;
275 break;
276 default:
277 assert(false);
280 assert((struct reg_parse_callback *)p == ret);
281 return ret;
282 fail:
283 talloc_free(p);
284 return NULL;