s3:pylibsmb: add settimeout()
[samba.git] / source3 / registry / reg_import.c
1 /*
2  * Samba Unix/Linux SMB client library
3  * Adapter to use reg_parse with the registry api
4  *
5  * Copyright (C) Gregor Beck 2010
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
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>
27
28 /* Debuglevel for tracing */
29 static const int TL = 2;
30
31 struct reg_import {
32         struct reg_parse_callback reg_parse_callback;
33         struct reg_import_callback call;
34         void *open_key;
35 };
36
37 static int reg_parse_callback_key(struct reg_import *cb_private,
38                                   const char *key[], size_t n, bool del);
39
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);
43
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);
49
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);
54
55 static int reg_parse_callback_val_del(struct reg_import *cb_private,
56                                       const char *name);
57
58 static int reg_parse_callback_comment(struct reg_import *cb_private,
59                                       const char *txt);
60
61
62 /*******************************************************************************/
63
64 int reg_parse_callback_key(struct reg_import *p,
65                            const char *key[], size_t n, bool del)
66 {
67         WERROR werr = WERR_OK;
68
69         DEBUG(TL, ("%s: %s\n", __FUNCTION__, key[0]));
70
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)));
76                 }
77         }
78
79         if (del) {
80                 werr = p->call.deletekey(p->call.data, NULL, key[0]);
81                 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
82                         /* the key didn't exist, treat as success */
83                         werr = WERR_OK;
84                 }
85                 if (!W_ERROR_IS_OK(werr)) {
86                         DEBUG(0, ("deletekey %s failed: %s\n",
87                                   key[0], win_errstr(werr)));
88                 }
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)));
99                 }
100         }
101
102         return W_ERROR_IS_OK(werr) ? 0 : -1;
103 }
104
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"));                \
115                 }                                                       \
116         } while(0)
117
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)
122 {
123         WERROR werr = WERR_OK;
124
125         DEBUG(TL, ("%s(%x): >%s< = [%x]\n",  __FUNCTION__, type, name, len));
126         DEBUG_ADD_HEX(TL, data, len);
127
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)));
133         }
134
135         return W_ERROR_IS_OK(werr) ? 0 : -1;
136 }
137
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)
142 {
143         WERROR werr = WERR_OK;
144         struct registry_value val = {
145                 .type = type,
146                 .data = data_blob_talloc(p, data, len),
147         };
148
149         DEBUG(TL, ("%s(%x): >%s< = [%x]\n", __FUNCTION__, type, name, len));
150         DEBUG_ADD_HEX(TL, data, len);
151
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)));
157         }
158
159         data_blob_free(&val.data);
160         return W_ERROR_IS_OK(werr) ? 0 : -1;
161 }
162
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)
167 {
168         WERROR werr = WERR_OK;
169         void* mem_ctx = talloc_new(p);
170         struct regval_blob *v = NULL;
171
172         DEBUG(TL, ("%s(%x): >%s< = [%x]\n", __FUNCTION__, type, name, len));
173         DEBUG_ADD_HEX(TL, data, len);
174
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_NOT_ENOUGH_MEMORY;
179                 goto done;
180         }
181
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)));
186         }
187
188 done:
189         talloc_free(mem_ctx);
190
191         return W_ERROR_IS_OK(werr) ? 0 : -1;
192 }
193
194
195 /*----------------------------------------------------------------------------*/
196
197 int reg_parse_callback_val_del(struct reg_import *p,
198                                const char *name)
199 {
200         WERROR werr = WERR_OK;
201
202         DEBUG(TL, ("%s: %s\n", __FUNCTION__, name));
203
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)));
208         }
209
210         return W_ERROR_IS_OK(werr) ? 0 : -1;
211 }
212
213
214 int reg_parse_callback_comment(struct reg_import *cb_private,
215                                const char *txt)
216 {
217         DEBUG(TL, ("%s: %s\n", __FUNCTION__, txt));
218         return 0;
219 }
220
221 /******************************************************************************/
222 static int nop(void *data)
223 {
224         return 0;
225 }
226
227
228 struct reg_parse_callback *reg_import_adapter(TALLOC_CTX *talloc_ctx,
229                                               struct reg_import_callback cb)
230 {
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;
235         }
236         if (cb.openkey == NULL) {
237                 cb.openkey = (reg_import_callback_openkey_t)&nop;
238         }
239         if (cb.closekey == NULL) {
240                 cb.closekey = (reg_import_callback_closekey_t)&nop;
241         }
242         if (cb.createkey == NULL) {
243                 cb.createkey = (reg_import_callback_createkey_t)&nop;
244         }
245         if (cb.deletekey == NULL) {
246                 cb.deletekey = (reg_import_callback_deletekey_t)&nop;
247         }
248         if (cb.deleteval == NULL) {
249                 cb.deleteval = (reg_import_callback_deleteval_t)&nop;
250         }
251
252         p->call = cb;
253
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;
259
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);
278         }
279
280         assert((struct reg_parse_callback *)p == ret);
281         return ret;
282 fail:
283         talloc_free(p);
284         return NULL;
285 }