libsmbconf: reformat smbconf_format_registry_value() - indentations/tabs
[amitay/samba.git] / source3 / lib / smbconf / smbconf_reg.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  libsmbconf - Samba configuration library, registry backend
4  *  Copyright (C) Michael Adam 2008
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 3 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "includes.h"
21 #include "smbconf_private.h"
22
23 struct reg_private_data {
24         NT_USER_TOKEN *token;
25         bool open;              /* did _we_ open the registry? */
26 };
27
28 /**********************************************************************
29  *
30  * helper functions
31  *
32  **********************************************************************/
33
34 /**
35  * a convenience helper to cast the private data structure
36  */
37 static struct reg_private_data *rpd(struct smbconf_ctx *ctx)
38 {
39         return (struct reg_private_data *)(ctx->data);
40 }
41
42 /**
43  * Open a registry key specified by "path"
44  */
45 static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx,
46                                     struct smbconf_ctx *ctx,
47                                     const char *path,
48                                     uint32 desired_access,
49                                     struct registry_key **key)
50 {
51         WERROR werr = WERR_OK;
52
53         if (ctx == NULL) {
54                 DEBUG(1, ("Error: configuration is not open!\n"));
55                 werr = WERR_INVALID_PARAM;
56                 goto done;
57         }
58
59         if (rpd(ctx)->token == NULL) {
60                 DEBUG(1, ("Error: token missing from smbconf_ctx. "
61                           "was smbconf_init() called?\n"));
62                 werr = WERR_INVALID_PARAM;
63                 goto done;
64         }
65
66         werr = ctx->ops->open_conf(ctx);
67         if (!W_ERROR_IS_OK(werr)) {
68                 DEBUG(1, ("Error opening the registry.\n"));
69                 goto done;
70         }
71
72         if (path == NULL) {
73                 DEBUG(1, ("Error: NULL path string given\n"));
74                 werr = WERR_INVALID_PARAM;
75                 goto done;
76         }
77
78         werr = reg_open_path(mem_ctx, path, desired_access, rpd(ctx)->token,
79                              key);
80
81         if (!W_ERROR_IS_OK(werr)) {
82                 DEBUG(1, ("Error opening registry path '%s': %s\n",
83                           path, dos_errstr(werr)));
84         }
85
86 done:
87         return werr;
88 }
89
90 /**
91  * Open a subkey of the base key (i.e a service)
92  */
93 static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx,
94                                            struct smbconf_ctx *ctx,
95                                            const char *servicename,
96                                            uint32 desired_access,
97                                            struct registry_key **key)
98 {
99         WERROR werr = WERR_OK;
100         char *path = NULL;
101
102         if (servicename == NULL) {
103                 DEBUG(3, ("Error: NULL servicename given.\n"));
104                 werr = WERR_INVALID_PARAM;
105                 goto done;
106         }
107
108         path = talloc_asprintf(mem_ctx, "%s\\%s", ctx->path, servicename);
109         if (path == NULL) {
110                 werr = WERR_NOMEM;
111                 goto done;
112         }
113
114         werr = smbconf_reg_open_path(mem_ctx, ctx, path, desired_access, key);
115
116 done:
117         TALLOC_FREE(path);
118         return werr;
119 }
120
121 /**
122  * open the base key
123  */
124 static WERROR smbconf_reg_open_base_key(TALLOC_CTX *mem_ctx,
125                                         struct smbconf_ctx *ctx,
126                                         uint32 desired_access,
127                                         struct registry_key **key)
128 {
129         return smbconf_reg_open_path(mem_ctx, ctx, ctx->path, desired_access,
130                                      key);
131 }
132
133 /**
134  * check if a value exists in a given registry key
135  */
136 static bool smbconf_value_exists(struct registry_key *key, const char *param)
137 {
138         bool ret = false;
139         WERROR werr = WERR_OK;
140         TALLOC_CTX *ctx = talloc_stackframe();
141         struct registry_value *value = NULL;
142
143         werr = reg_queryvalue(ctx, key, param, &value);
144         if (W_ERROR_IS_OK(werr)) {
145                 ret = true;
146         }
147
148         TALLOC_FREE(ctx);
149         return ret;
150 }
151
152 /**
153  * create a subkey of the base key (i.e. a service...)
154  */
155 static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
156                                              struct smbconf_ctx *ctx,
157                                              const char * subkeyname,
158                                              struct registry_key **newkey)
159 {
160         WERROR werr = WERR_OK;
161         struct registry_key *create_parent = NULL;
162         TALLOC_CTX *create_ctx;
163         enum winreg_CreateAction action = REG_ACTION_NONE;
164
165         /* create a new talloc ctx for creation. it will hold
166          * the intermediate parent key (SMBCONF) for creation
167          * and will be destroyed when leaving this function... */
168         if (!(create_ctx = talloc_stackframe())) {
169                 werr = WERR_NOMEM;
170                 goto done;
171         }
172
173         werr = smbconf_reg_open_base_key(create_ctx, ctx, REG_KEY_WRITE,
174                                          &create_parent);
175         if (!W_ERROR_IS_OK(werr)) {
176                 goto done;
177         }
178
179         werr = reg_createkey(mem_ctx, create_parent, subkeyname,
180                              REG_KEY_WRITE, newkey, &action);
181         if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
182                 DEBUG(10, ("Key '%s' already exists.\n", subkeyname));
183                 werr = WERR_ALREADY_EXISTS;
184         }
185         if (!W_ERROR_IS_OK(werr)) {
186                 DEBUG(5, ("Error creating key %s: %s\n",
187                          subkeyname, dos_errstr(werr)));
188         }
189
190 done:
191         TALLOC_FREE(create_ctx);
192         return werr;
193 }
194
195 /**
196  * add a value to a key.
197  */
198 static WERROR smbconf_reg_set_value(struct registry_key *key,
199                                     const char *valname,
200                                     const char *valstr)
201 {
202         struct registry_value val;
203         WERROR werr = WERR_OK;
204         char *subkeyname;
205         const char *canon_valname;
206         const char *canon_valstr;
207
208         if (!lp_canonicalize_parameter_with_value(valname, valstr,
209                                                   &canon_valname,
210                                                   &canon_valstr))
211         {
212                 if (canon_valname == NULL) {
213                         DEBUG(5, ("invalid parameter '%s' given\n",
214                                   valname));
215                 } else {
216                         DEBUG(5, ("invalid value '%s' given for "
217                                   "parameter '%s'\n", valstr, valname));
218                 }
219                 werr = WERR_INVALID_PARAM;
220                 goto done;
221         }
222
223         if (registry_smbconf_valname_forbidden(canon_valname)) {
224                 DEBUG(5, ("Parameter '%s' not allowed in registry.\n",
225                           canon_valname));
226                 werr = WERR_INVALID_PARAM;
227                 goto done;
228         }
229
230         subkeyname = strrchr_m(key->key->name, '\\');
231         if ((subkeyname == NULL) || (*(subkeyname +1) == '\0')) {
232                 DEBUG(5, ("Invalid registry key '%s' given as "
233                           "smbconf section.\n", key->key->name));
234                 werr = WERR_INVALID_PARAM;
235                 goto done;
236         }
237         subkeyname++;
238         if (!strequal(subkeyname, GLOBAL_NAME) &&
239             lp_parameter_is_global(valname))
240         {
241                 DEBUG(5, ("Global paramter '%s' not allowed in "
242                           "service definition ('%s').\n", canon_valname,
243                           subkeyname));
244                 werr = WERR_INVALID_PARAM;
245                 goto done;
246         }
247
248         ZERO_STRUCT(val);
249
250         val.type = REG_SZ;
251         val.v.sz.str = CONST_DISCARD(char *, canon_valstr);
252         val.v.sz.len = strlen(canon_valstr) + 1;
253
254         werr = reg_setvalue(key, canon_valname, &val);
255         if (!W_ERROR_IS_OK(werr)) {
256                 DEBUG(5, ("Error adding value '%s' to "
257                           "key '%s': %s\n",
258                           canon_valname, key->key->name, dos_errstr(werr)));
259         }
260
261 done:
262         return werr;
263 }
264
265 /**
266  * format a registry_value into a string.
267  *
268  * This is intended to be used for smbconf registry values,
269  * which are ar stored as REG_SZ values, so the incomplete
270  * handling should be ok.
271  */
272 static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx,
273                                            struct registry_value *value)
274 {
275         char *result = NULL;
276
277         /* alternatively, create a new talloc context? */
278         if (mem_ctx == NULL) {
279                 return result;
280         }
281
282         switch (value->type) {
283         case REG_DWORD:
284                 result = talloc_asprintf(mem_ctx, "%d", value->v.dword);
285                 break;
286         case REG_SZ:
287         case REG_EXPAND_SZ:
288                 result = talloc_asprintf(mem_ctx, "%s", value->v.sz.str);
289                 break;
290         case REG_MULTI_SZ: {
291                 uint32 j;
292                 for (j = 0; j < value->v.multi_sz.num_strings; j++) {
293                         result = talloc_asprintf(mem_ctx, "%s \"%s\" ",
294                                                  result,
295                                                  value->v.multi_sz.strings[j]);
296                         if (result == NULL) {
297                                 break;
298                         }
299                 }
300                 break;
301         }
302         case REG_BINARY:
303                 result = talloc_asprintf(mem_ctx, "binary (%d bytes)",
304                                          (int)value->v.binary.length);
305                 break;
306         default:
307                 result = talloc_asprintf(mem_ctx, "<unprintable>");
308                 break;
309         }
310         return result;
311 }
312
313 /**
314  * Get the values of a key as a list of value names
315  * and a list of value strings (ordered)
316  */
317 static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx,
318                                      struct registry_key *key,
319                                      uint32_t *num_values,
320                                      char ***value_names,
321                                      char ***value_strings)
322 {
323         TALLOC_CTX *tmp_ctx = NULL;
324         WERROR werr = WERR_OK;
325         uint32_t count;
326         struct registry_value *valvalue = NULL;
327         char *valname = NULL;
328         char **tmp_valnames = NULL;
329         char **tmp_valstrings = NULL;
330
331         if ((num_values == NULL) || (value_names == NULL) ||
332             (value_strings == NULL))
333         {
334                 werr = WERR_INVALID_PARAM;
335                 goto done;
336         }
337
338         tmp_ctx = talloc_stackframe();
339         if (tmp_ctx == NULL) {
340                 werr = WERR_NOMEM;
341                 goto done;
342         }
343
344         for (count = 0;
345              werr = reg_enumvalue(tmp_ctx, key, count, &valname, &valvalue),
346              W_ERROR_IS_OK(werr);
347              count++)
348         {
349                 char *valstring;
350
351                 werr = smbconf_add_string_to_array(tmp_ctx,
352                                                    &tmp_valnames,
353                                                    count, valname);
354                 if (!W_ERROR_IS_OK(werr)) {
355                         goto done;
356                 }
357
358                 valstring = smbconf_format_registry_value(tmp_ctx, valvalue);
359                 werr = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
360                                                    count, valstring);
361                 if (!W_ERROR_IS_OK(werr)) {
362                         goto done;
363                 }
364         }
365         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
366                 goto done;
367         }
368
369         werr = WERR_OK;
370
371         *num_values = count;
372         if (count > 0) {
373                 *value_names = talloc_move(mem_ctx, &tmp_valnames);
374                 *value_strings = talloc_move(mem_ctx, &tmp_valstrings);
375         } else {
376                 *value_names = NULL;
377                 *value_strings = NULL;
378         }
379
380 done:
381         TALLOC_FREE(tmp_ctx);
382         return werr;
383 }
384
385 /**********************************************************************
386  *
387  * smbconf operations: registry implementations
388  *
389  **********************************************************************/
390
391 /**
392  * initialize the registry smbconf backend
393  */
394 static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
395 {
396         WERROR werr = WERR_OK;
397
398         if (path == NULL) {
399                 path = KEY_SMBCONF;
400         }
401         ctx->path = talloc_strdup(ctx, path);
402         if (ctx->path == NULL) {
403                 werr = WERR_NOMEM;
404                 goto done;
405         }
406
407         ctx->data = TALLOC_ZERO_P(ctx, struct reg_private_data);
408
409         werr = ntstatus_to_werror(registry_create_admin_token(ctx,
410                                                         &(rpd(ctx)->token)));
411         if (!W_ERROR_IS_OK(werr)) {
412                 DEBUG(1, ("Error creating admin token\n"));
413                 goto done;
414         }
415         rpd(ctx)->open = false;
416
417         if (!registry_init_smbconf()) {
418                 werr = WERR_REG_IO_FAILURE;
419                 goto done;
420         }
421
422 done:
423         return werr;
424 }
425
426 static int smbconf_reg_shutdown(struct smbconf_ctx *ctx)
427 {
428         return ctx->ops->close_conf(ctx);
429 }
430
431 static WERROR smbconf_reg_open(struct smbconf_ctx *ctx)
432 {
433         WERROR werr;
434
435         if (rpd(ctx)->open) {
436                 return WERR_OK;
437         }
438
439         werr = regdb_open();
440         if (W_ERROR_IS_OK(werr)) {
441                 rpd(ctx)->open = true;
442         }
443         return werr;
444 }
445
446 static int smbconf_reg_close(struct smbconf_ctx *ctx)
447 {
448         int ret;
449
450         if (!rpd(ctx)->open) {
451                 return 0;
452         }
453
454         ret = regdb_close();
455         if (ret == 0) {
456                 rpd(ctx)->open = false;
457         }
458         return ret;
459 }
460
461 /**
462  * Get the change sequence number of the given service/parameter.
463  * service and parameter strings may be NULL.
464  */
465 static void smbconf_reg_get_csn(struct smbconf_ctx *ctx,
466                                 struct smbconf_csn *csn,
467                                 const char *service, const char *param)
468 {
469         if (csn == NULL) {
470                 return;
471         }
472
473         if (!W_ERROR_IS_OK(ctx->ops->open_conf(ctx))) {
474                 return;
475         }
476
477         csn->csn = (uint64_t)regdb_get_seqnum();
478 }
479
480 /**
481  * Drop the whole configuration (restarting empty) - registry version
482  */
483 static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx)
484 {
485         char *path, *p;
486         WERROR werr = WERR_OK;
487         struct registry_key *parent_key = NULL;
488         struct registry_key *new_key = NULL;
489         TALLOC_CTX* mem_ctx = talloc_stackframe();
490         enum winreg_CreateAction action;
491
492         path = talloc_strdup(mem_ctx, ctx->path);
493         if (path == NULL) {
494                 werr = WERR_NOMEM;
495                 goto done;
496         }
497         p = strrchr(path, '\\');
498         *p = '\0';
499         werr = smbconf_reg_open_path(mem_ctx, ctx, path, REG_KEY_WRITE,
500                                      &parent_key);
501
502         if (!W_ERROR_IS_OK(werr)) {
503                 goto done;
504         }
505
506         werr = reg_deletekey_recursive(mem_ctx, parent_key, p+1);
507
508         if (!W_ERROR_IS_OK(werr)) {
509                 goto done;
510         }
511
512         werr = reg_createkey(mem_ctx, parent_key, p+1, REG_KEY_WRITE,
513                              &new_key, &action);
514
515 done:
516         TALLOC_FREE(mem_ctx);
517         return werr;
518 }
519
520 /**
521  * get the list of share names defined in the configuration.
522  * registry version.
523  */
524 static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
525                                           TALLOC_CTX *mem_ctx,
526                                           uint32_t *num_shares,
527                                           char ***share_names)
528 {
529         uint32_t count;
530         uint32_t added_count = 0;
531         TALLOC_CTX *tmp_ctx = NULL;
532         WERROR werr = WERR_OK;
533         struct registry_key *key = NULL;
534         char *subkey_name = NULL;
535         char **tmp_share_names = NULL;
536
537         if ((num_shares == NULL) || (share_names == NULL)) {
538                 werr = WERR_INVALID_PARAM;
539                 goto done;
540         }
541
542         tmp_ctx = talloc_stackframe();
543         if (tmp_ctx == NULL) {
544                 werr = WERR_NOMEM;
545                 goto done;
546         }
547
548         /* make sure "global" is always listed first */
549         if (smbconf_share_exists(ctx, GLOBAL_NAME)) {
550                 werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
551                                                    0, GLOBAL_NAME);
552                 if (!W_ERROR_IS_OK(werr)) {
553                         goto done;
554                 }
555                 added_count++;
556         }
557
558         werr = smbconf_reg_open_base_key(tmp_ctx, ctx,
559                                          SEC_RIGHTS_ENUM_SUBKEYS, &key);
560         if (!W_ERROR_IS_OK(werr)) {
561                 goto done;
562         }
563
564         for (count = 0;
565              werr = reg_enumkey(tmp_ctx, key, count, &subkey_name, NULL),
566              W_ERROR_IS_OK(werr);
567              count++)
568         {
569                 if (strequal(subkey_name, GLOBAL_NAME)) {
570                         continue;
571                 }
572
573                 werr = smbconf_add_string_to_array(tmp_ctx,
574                                                    &tmp_share_names,
575                                                    added_count,
576                                                    subkey_name);
577                 if (!W_ERROR_IS_OK(werr)) {
578                         goto done;
579                 }
580                 added_count++;
581         }
582         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
583                 goto done;
584         }
585         werr = WERR_OK;
586
587         *num_shares = added_count;
588         if (added_count > 0) {
589                 *share_names = talloc_move(mem_ctx, &tmp_share_names);
590         } else {
591                 *share_names = NULL;
592         }
593
594 done:
595         TALLOC_FREE(tmp_ctx);
596         return werr;
597 }
598
599 /**
600  * check if a share/service of a given name exists - registry version
601  */
602 static bool smbconf_reg_share_exists(struct smbconf_ctx *ctx,
603                                      const char *servicename)
604 {
605         bool ret = false;
606         WERROR werr = WERR_OK;
607         TALLOC_CTX *mem_ctx = talloc_stackframe();
608         struct registry_key *key = NULL;
609
610         werr = smbconf_reg_open_service_key(mem_ctx, ctx, servicename,
611                                             REG_KEY_READ, &key);
612         if (W_ERROR_IS_OK(werr)) {
613                 ret = true;
614         }
615
616         TALLOC_FREE(mem_ctx);
617         return ret;
618 }
619
620 /**
621  * Add a service if it does not already exist - registry version
622  */
623 static WERROR smbconf_reg_create_share(struct smbconf_ctx *ctx,
624                                        const char *servicename)
625 {
626         WERROR werr;
627         TALLOC_CTX *mem_ctx = talloc_stackframe();
628         struct registry_key *key = NULL;
629
630         werr = smbconf_reg_create_service_key(mem_ctx, ctx, servicename, &key);
631
632         TALLOC_FREE(mem_ctx);
633         return werr;
634 }
635
636 /**
637  * get a definition of a share (service) from configuration.
638  */
639 static WERROR smbconf_reg_get_share(struct smbconf_ctx *ctx,
640                                     TALLOC_CTX *mem_ctx,
641                                     const char *servicename,
642                                     uint32_t *num_params,
643                                     char ***param_names, char ***param_values)
644 {
645         WERROR werr = WERR_OK;
646         struct registry_key *key = NULL;
647
648         werr = smbconf_reg_open_service_key(mem_ctx, ctx, servicename,
649                                             REG_KEY_READ, &key);
650         if (!W_ERROR_IS_OK(werr)) {
651                 goto done;
652         }
653
654         werr = smbconf_reg_get_values(mem_ctx, key, num_params,
655                                       param_names, param_values);
656
657 done:
658         TALLOC_FREE(key);
659         return werr;
660 }
661
662 /**
663  * delete a service from configuration
664  */
665 static WERROR smbconf_reg_delete_share(struct smbconf_ctx *ctx,
666                                        const char *servicename)
667 {
668         WERROR werr = WERR_OK;
669         struct registry_key *key = NULL;
670         TALLOC_CTX *mem_ctx = talloc_stackframe();
671
672         werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, &key);
673         if (!W_ERROR_IS_OK(werr)) {
674                 goto done;
675         }
676
677         werr = reg_deletekey_recursive(key, key, servicename);
678
679 done:
680         TALLOC_FREE(mem_ctx);
681         return werr;
682 }
683
684 /**
685  * set a configuration parameter to the value provided.
686  */
687 static WERROR smbconf_reg_set_parameter(struct smbconf_ctx *ctx,
688                                         const char *service,
689                                         const char *param,
690                                         const char *valstr)
691 {
692         WERROR werr;
693         struct registry_key *key = NULL;
694         TALLOC_CTX *mem_ctx = talloc_stackframe();
695
696         werr = smbconf_reg_open_service_key(mem_ctx, ctx, service,
697                                             REG_KEY_WRITE, &key);
698         if (!W_ERROR_IS_OK(werr)) {
699                 goto done;
700         }
701
702         werr = smbconf_reg_set_value(key, param, valstr);
703
704 done:
705         TALLOC_FREE(mem_ctx);
706         return werr;
707 }
708
709 /**
710  * get the value of a configuration parameter as a string
711  */
712 static WERROR smbconf_reg_get_parameter(struct smbconf_ctx *ctx,
713                                         TALLOC_CTX *mem_ctx,
714                                         const char *service,
715                                         const char *param,
716                                         char **valstr)
717 {
718         WERROR werr = WERR_OK;
719         struct registry_key *key = NULL;
720         struct registry_value *value = NULL;
721
722         werr = smbconf_reg_open_service_key(mem_ctx, ctx, service,
723                                             REG_KEY_READ, &key);
724         if (!W_ERROR_IS_OK(werr)) {
725                 goto done;
726         }
727
728         if (!smbconf_value_exists(key, param)) {
729                 werr = WERR_INVALID_PARAM;
730                 goto done;
731         }
732
733         werr = reg_queryvalue(mem_ctx, key, param, &value);
734         if (!W_ERROR_IS_OK(werr)) {
735                 goto done;
736         }
737
738         *valstr = smbconf_format_registry_value(mem_ctx, value);
739
740         if (*valstr == NULL) {
741                 werr = WERR_NOMEM;
742         }
743
744 done:
745         TALLOC_FREE(key);
746         TALLOC_FREE(value);
747         return werr;
748 }
749
750 /**
751  * delete a parameter from configuration
752  */
753 static WERROR smbconf_reg_delete_parameter(struct smbconf_ctx *ctx,
754                                            const char *service,
755                                            const char *param)
756 {
757         struct registry_key *key = NULL;
758         WERROR werr = WERR_OK;
759         TALLOC_CTX *mem_ctx = talloc_stackframe();
760
761         werr = smbconf_reg_open_service_key(mem_ctx, ctx, service,
762                                             REG_KEY_ALL, &key);
763         if (!W_ERROR_IS_OK(werr)) {
764                 goto done;
765         }
766
767         if (!smbconf_value_exists(key, param)) {
768                 werr = WERR_INVALID_PARAM;
769                 goto done;
770         }
771
772         werr = reg_deletevalue(key, param);
773
774 done:
775         TALLOC_FREE(mem_ctx);
776         return werr;
777 }
778
779 struct smbconf_ops smbconf_ops_reg = {
780         .init                   = smbconf_reg_init,
781         .shutdown               = smbconf_reg_shutdown,
782         .open_conf              = smbconf_reg_open,
783         .close_conf             = smbconf_reg_close,
784         .get_csn                = smbconf_reg_get_csn,
785         .drop                   = smbconf_reg_drop,
786         .get_share_names        = smbconf_reg_get_share_names,
787         .share_exists           = smbconf_reg_share_exists,
788         .create_share           = smbconf_reg_create_share,
789         .get_share              = smbconf_reg_get_share,
790         .delete_share           = smbconf_reg_delete_share,
791         .set_parameter          = smbconf_reg_set_parameter,
792         .get_parameter          = smbconf_reg_get_parameter,
793         .delete_parameter       = smbconf_reg_delete_parameter
794 };
795
796
797 /**
798  * initialize the smbconf registry backend
799  * the only function that is exported from this module
800  */
801 WERROR smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
802                         const char *path)
803 {
804         return smbconf_init(mem_ctx, conf_ctx, path, &smbconf_ops_reg);
805 }