r10026: Move registry header file to lib/registry
[bbaumbach/samba-autobuild/.git] / source4 / lib / registry / common / reg_interface.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Transparent registry backend handling
4    Copyright (C) Jelmer Vernooij                        2003-2004.
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 2 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 "dlinklist.h"
23 #include "lib/registry/registry.h"
24
25 /* List of available backends */
26 static struct reg_init_function_entry *backends = NULL;
27
28 static struct reg_init_function_entry *reg_find_backend_entry(const char *name);
29
30 /* Register new backend */
31 NTSTATUS registry_register(const void *_hive_ops)  
32 {
33         const struct hive_operations *hive_ops = _hive_ops;
34         struct reg_init_function_entry *entry = backends;
35
36         DEBUG(5,("Attempting to register registry backend %s\n", hive_ops->name));
37
38         /* Check for duplicates */
39         if (reg_find_backend_entry(hive_ops->name)) {
40                 DEBUG(0,("There already is a registry backend registered with the name %s!\n", hive_ops->name));
41                 return NT_STATUS_OBJECT_NAME_COLLISION;
42         }
43
44         entry = talloc(talloc_autofree_context(), struct reg_init_function_entry);
45         entry->hive_functions = hive_ops;
46
47         DLIST_ADD(backends, entry);
48         DEBUG(5,("Successfully added registry backend '%s'\n", hive_ops->name));
49         return NT_STATUS_OK;
50 }
51
52 /* Find a backend in the list of available backends */
53 static struct reg_init_function_entry *reg_find_backend_entry(const char *name)
54 {
55         struct reg_init_function_entry *entry;
56
57         entry = backends;
58
59         while(entry) {
60                 if (strcmp(entry->hive_functions->name, name) == 0) return entry;
61                 entry = entry->next;
62         }
63
64         return NULL;
65 }
66
67 /* Check whether a certain backend is present */
68 BOOL reg_has_backend(const char *backend)
69 {
70         return reg_find_backend_entry(backend) != NULL?True:False;
71 }
72
73 static struct {
74         uint32_t handle;
75         const char *name;
76 } predef_names[] = 
77 {
78         {HKEY_CLASSES_ROOT,"HKEY_CLASSES_ROOT" },
79         {HKEY_CURRENT_USER,"HKEY_CURRENT_USER" },
80         {HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" },
81         {HKEY_PERFORMANCE_DATA, "HKEY_PERFORMANCE_DATA" },
82         {HKEY_USERS, "HKEY_USERS" },
83         {HKEY_CURRENT_CONFIG, "HKEY_CURRENT_CONFIG" },
84         {HKEY_DYN_DATA, "HKEY_DYN_DATA" },
85         {HKEY_PERFORMANCE_TEXT, "HKEY_PERFORMANCE_TEXT" },
86         {HKEY_PERFORMANCE_NLSTEXT, "HKEY_PERFORMANCE_NLSTEXT" },
87         { 0, NULL }
88 };
89
90 int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **hkeys)
91 {
92         int i;
93         *predefs = talloc_array(mem_ctx, char *, ARRAY_SIZE(predef_names));
94         *hkeys = talloc_array(mem_ctx, uint32_t, ARRAY_SIZE(predef_names));
95
96         for (i = 0; predef_names[i].name; i++) {
97                 (*predefs)[i] = talloc_strdup(mem_ctx, predef_names[i].name);
98                 (*hkeys)[i] = predef_names[i].handle;
99         }
100
101         return i;
102 }
103
104 const char *reg_get_predef_name(uint32_t hkey)
105 {
106         int i;
107         for (i = 0; predef_names[i].name; i++) {
108                 if (predef_names[i].handle == hkey) return predef_names[i].name;
109         }
110
111         return NULL;
112 }
113
114 WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char *name, struct registry_key **key)
115 {
116         int i;
117         
118         for (i = 0; predef_names[i].name; i++) {
119                 if (!strcasecmp(predef_names[i].name, name)) return reg_get_predefined_key(ctx, predef_names[i].handle, key);
120         }
121
122         DEBUG(1, ("No predefined key with name '%s'\n", name));
123         
124         return WERR_BADFILE;
125 }
126
127 WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key)
128 {
129         WERROR ret = ctx->get_predefined_key(ctx, hkey, key);
130
131         if (W_ERROR_IS_OK(ret)) {
132                 (*key)->name = talloc_strdup(*key, reg_get_predef_name(hkey));
133                 (*key)->path = ""; 
134         }
135
136         return ret;
137 }
138
139 /* Open a registry file/host/etc */
140 WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *location, const char *credentials, struct registry_key **root)
141 {
142         struct registry_hive *rethive;
143         struct registry_key *retkey = NULL;
144         struct reg_init_function_entry *entry;
145         WERROR werr;
146
147         entry = reg_find_backend_entry(backend);
148         
149         if (!entry) {
150                 DEBUG(0, ("No such registry backend '%s' loaded!\n", backend));
151                 return WERR_GENERAL_FAILURE;
152         }
153
154         if(!entry->hive_functions || !entry->hive_functions->open_hive) {
155                 return WERR_NOT_SUPPORTED;
156         }
157         
158         rethive = talloc(parent_ctx, struct registry_hive);
159         rethive->location = location?talloc_strdup(rethive, location):NULL;
160         rethive->functions = entry->hive_functions;
161         rethive->backend_data = NULL;
162
163         werr = entry->hive_functions->open_hive(rethive, &retkey);
164
165         if(!W_ERROR_IS_OK(werr)) {
166                 return werr;
167         }
168
169         if(!retkey) {
170                 DEBUG(0, ("Backend %s didn't provide root key!\n", backend));
171                 return WERR_GENERAL_FAILURE;
172         }
173
174         rethive->root = retkey;
175
176         retkey->hive = rethive;
177         retkey->name = NULL;
178         retkey->path = talloc_strdup(retkey, "");
179         
180         *root = retkey;
181
182         return WERR_OK;
183 }
184
185 /* Open a key 
186  * First tries to use the open_key function from the backend
187  * then falls back to get_subkey_by_name and later get_subkey_by_index 
188  */
189 WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, struct registry_key **result)
190 {
191         WERROR error;
192
193         if(!parent) {
194                 DEBUG(0, ("Invalid parent key specified for open of '%s'\n", name));
195                 return WERR_INVALID_PARAM;
196         }
197
198         if(!parent->hive->functions->open_key && 
199            (parent->hive->functions->get_subkey_by_name || 
200            parent->hive->functions->get_subkey_by_index)) {
201                 char *orig = strdup(name), 
202                          *curbegin = orig, 
203                          *curend = strchr(orig, '\\');
204                 struct registry_key *curkey = parent;
205
206                 while(curbegin && *curbegin) {
207                         if(curend)*curend = '\0';
208                         error = reg_key_get_subkey_by_name(mem_ctx, curkey, curbegin, &curkey);
209                         if(!W_ERROR_IS_OK(error)) {
210                                 SAFE_FREE(orig);
211                                 return error;
212                         }
213                         if(!curend) break;
214                         curbegin = curend + 1;
215                         curend = strchr(curbegin, '\\');
216                 }
217                 SAFE_FREE(orig);
218
219                 *result = curkey;
220                 
221                 return WERR_OK;
222         }
223
224         if(!parent->hive->functions->open_key) {
225                 DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n"));
226                 return WERR_NOT_SUPPORTED;
227         }
228
229         error = parent->hive->functions->open_key(mem_ctx, parent, name, result);
230
231         if(!W_ERROR_IS_OK(error)) return error;
232                 
233         (*result)->hive = parent->hive;
234         (*result)->path = ((parent->hive->root == parent)?talloc_strdup(mem_ctx, name):talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name));
235         (*result)->hive = parent->hive;
236
237         return WERR_OK;
238 }
239
240 WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, int idx, struct registry_value **val)
241 {
242         if(!key) return WERR_INVALID_PARAM;
243
244         if(key->hive->functions->get_value_by_index) {
245                 WERROR status = key->hive->functions->get_value_by_index(mem_ctx, key, idx, val);
246                 if(!W_ERROR_IS_OK(status)) 
247                         return status;
248         } else {
249                 return WERR_NOT_SUPPORTED;
250         }
251         
252         return WERR_OK;
253 }
254
255 WERROR reg_key_num_subkeys(struct registry_key *key, uint32_t *count)
256 {
257         if(!key) return WERR_INVALID_PARAM;
258         
259         if(key->hive->functions->num_subkeys) {
260                 return key->hive->functions->num_subkeys(key, count);
261         }
262
263         if(key->hive->functions->get_subkey_by_index) {
264                 int i;
265                 WERROR error;
266                 struct registry_key *dest = NULL;
267                 TALLOC_CTX *mem_ctx = talloc_init("num_subkeys");
268                 
269                 for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, key, i, &dest)); i++);
270                 talloc_free(mem_ctx);
271
272                 *count = i;
273                 if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) error = WERR_OK;
274                 return error;
275         }
276
277         return WERR_NOT_SUPPORTED;
278 }
279
280 WERROR reg_key_num_values(struct registry_key *key, uint32_t *count)
281 {
282         
283         if(!key) return WERR_INVALID_PARAM;
284
285         if (key->hive->functions->num_values) {
286                 return key->hive->functions->num_values(key, count);
287         }
288
289         if(key->hive->functions->get_value_by_index) {
290                 int i;
291                 WERROR error;
292                 struct registry_value *dest;
293                 TALLOC_CTX *mem_ctx = talloc_init("num_subkeys");
294                 
295                 for(i = 0; W_ERROR_IS_OK(error = key->hive->functions->get_value_by_index(mem_ctx, key, i, &dest)); i++);
296                 talloc_free(mem_ctx);
297
298                 *count = i;
299                 if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) error = WERR_OK;
300                 return error;
301         }
302
303         return WERR_NOT_SUPPORTED;
304 }
305
306 WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, int idx, struct registry_key **subkey)
307 {
308         if(!key) return WERR_INVALID_PARAM;
309
310         if(key->hive->functions->get_subkey_by_index) {
311                 WERROR status = key->hive->functions->get_subkey_by_index(mem_ctx, key, idx, subkey);
312                 if(!NT_STATUS_IS_OK(status)) return status;
313         } else {
314                 return WERR_NOT_SUPPORTED;
315         }
316
317         if(key->hive->root == key) 
318                 (*subkey)->path = talloc_strdup(mem_ctx, (*subkey)->name);
319         else 
320                 (*subkey)->path = talloc_asprintf(mem_ctx, "%s\\%s", key->path, (*subkey)->name);
321
322         (*subkey)->hive = key->hive;
323         return WERR_OK;;
324 }
325
326 WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *name, struct registry_key **subkey)
327 {
328         int i;
329         WERROR error = WERR_OK;
330
331         if(!key) return WERR_INVALID_PARAM;
332
333         if(key->hive->functions->get_subkey_by_name) {
334                 error = key->hive->functions->get_subkey_by_name(mem_ctx, key,name,subkey);
335         } else if(key->hive->functions->open_key) {
336                 error = key->hive->functions->open_key(mem_ctx, key, name, subkey);
337         } else if(key->hive->functions->get_subkey_by_index) {
338                 for(i = 0; W_ERROR_IS_OK(error); i++) {
339                         error = reg_key_get_subkey_by_index(mem_ctx, key, i, subkey);
340                         if(W_ERROR_IS_OK(error) && !strcasecmp((*subkey)->name, name)) {
341                                 break;
342                         }
343                 }
344
345                 if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) 
346                         error = WERR_DEST_NOT_FOUND;
347         } else {
348                 return WERR_NOT_SUPPORTED;
349         }
350
351         if(!W_ERROR_IS_OK(error)) return error;
352
353         (*subkey)->path = talloc_asprintf(mem_ctx, "%s\\%s", key->path, (*subkey)->name);
354         (*subkey)->hive = key->hive;
355
356         return WERR_OK; 
357 }
358
359 WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *name, struct registry_value **val)
360 {
361         int i;
362         WERROR error = WERR_OK;
363
364         if(!key) return WERR_INVALID_PARAM;
365
366         if(key->hive->functions->get_value_by_name) {
367                 error = key->hive->functions->get_value_by_name(mem_ctx, key,name, val);
368         } else {
369                 for(i = 0; W_ERROR_IS_OK(error); i++) {
370                         error = reg_key_get_value_by_index(mem_ctx, key, i, val);
371                         if(W_ERROR_IS_OK(error) && !strcasecmp((*val)->name, name)) {
372                                 break;
373                         }
374                 }
375         }
376
377         if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS))
378                 return WERR_DEST_NOT_FOUND;
379
380         return error;
381 }
382
383 WERROR reg_key_del(struct registry_key *parent, const char *name)
384 {
385         WERROR error;
386         if(!parent) return WERR_INVALID_PARAM;
387         
388         
389         if(!parent->hive->functions->del_key)
390                 return WERR_NOT_SUPPORTED;
391         
392         error = parent->hive->functions->del_key(parent, name);
393         if(!W_ERROR_IS_OK(error)) return error;
394
395         return WERR_OK;
396 }
397
398 WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **newkey)
399 {
400         WERROR error;
401         
402         if (!parent) return WERR_INVALID_PARAM;
403         
404         if (!parent->hive->functions->add_key) {
405                 DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->hive->functions->name));
406                 return WERR_NOT_SUPPORTED;
407         }
408
409         error = parent->hive->functions->add_key(mem_ctx, parent, name, access_mask, desc, newkey);
410
411         if(!W_ERROR_IS_OK(error)) return error;
412
413         if (!*newkey) {
414                 DEBUG(0, ("Backend returned WERR_OK, but didn't specify key!\n"));
415                 return WERR_GENERAL_FAILURE;
416         }
417         
418         (*newkey)->hive = parent->hive;
419         (*newkey)->backend_data = talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name);
420
421         return WERR_OK;
422 }
423
424 WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, DATA_BLOB data)
425 {
426         /* A 'real' set function has preference */
427         if (key->hive->functions->set_value) 
428                 return key->hive->functions->set_value(key, value, type, data);
429
430         DEBUG(1, ("Backend '%s' doesn't support method set_value\n", key->hive->functions->name));
431         return WERR_NOT_SUPPORTED;
432 }
433
434
435 WERROR reg_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struct security_descriptor **secdesc)
436 {
437         /* A 'real' set function has preference */
438         if (key->hive->functions->key_get_sec_desc) 
439                 return key->hive->functions->key_get_sec_desc(ctx, key, secdesc);
440
441         DEBUG(1, ("Backend '%s' doesn't support method get_sec_desc\n", key->hive->functions->name));
442         return WERR_NOT_SUPPORTED;
443 }
444
445 WERROR reg_del_value(struct registry_key *key, const char *valname)
446 {
447         WERROR ret = WERR_OK;
448         if(!key->hive->functions->del_value)
449                 return WERR_NOT_SUPPORTED;
450
451         ret = key->hive->functions->del_value(key, valname);
452
453         if(!W_ERROR_IS_OK(ret)) return ret;
454
455         return ret;
456 }
457
458 WERROR reg_save (struct registry_context *ctx, const char *location)
459 {
460         return WERR_NOT_SUPPORTED;
461 }
462
463 WERROR reg_key_flush(struct registry_key *key)
464 {
465         if (!key) {
466                 return WERR_INVALID_PARAM;
467         }
468         
469         if (key->hive->functions->flush_key) {
470                 return key->hive->functions->flush_key(key);
471         }
472         
473         /* No need for flushing, apparently */
474         return WERR_OK;
475 }
476
477 WERROR reg_key_subkeysizes(struct registry_key *key, uint32_t *max_subkeylen, uint32_t *max_subkeysize)
478 {
479         int i = 0; 
480         struct registry_key *subkey;
481         WERROR error;
482         TALLOC_CTX *mem_ctx = talloc_init("subkeysize");
483
484         *max_subkeylen = *max_subkeysize = 0;
485
486         do {
487                 error = reg_key_get_subkey_by_index(mem_ctx, key, i, &subkey);
488
489                 if (W_ERROR_IS_OK(error)) {
490                         *max_subkeysize = MAX(*max_subkeysize, 0xFF);
491                         *max_subkeylen = MAX(*max_subkeylen, strlen(subkey->name));
492                 }
493
494                 i++;
495         } while (W_ERROR_IS_OK(error));
496
497         talloc_free(mem_ctx);
498
499         return WERR_OK;
500 }
501
502 WERROR reg_key_valuesizes(struct registry_key *key, uint32_t *max_valnamelen, uint32_t *max_valbufsize)
503 {
504         int i = 0; 
505         struct registry_value *value;
506         WERROR error;
507         TALLOC_CTX *mem_ctx = talloc_init("subkeysize");
508
509         *max_valnamelen = *max_valbufsize = 0;
510
511         do {
512                 error = reg_key_get_value_by_index(mem_ctx, key, i, &value);
513
514                 if (W_ERROR_IS_OK(error)) {
515                         if (value->name) {
516                                 *max_valnamelen = MAX(*max_valnamelen, strlen(value->name));
517                         }
518                         *max_valbufsize = MAX(*max_valbufsize, value->data.length);
519                 }
520
521                 i++;
522         } while (W_ERROR_IS_OK(error));
523
524         talloc_free(mem_ctx);
525
526         return WERR_OK;
527 }