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