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