s3:utils: Fix 'Usage:' for 'net ads enctypes'
[samba4-gss.git] / source3 / lib / smbconf / smbconf_reg.c
blobfc8aa62d0678079ff79a5acb8516d56b5e4831d5
1 /*
2 * Unix SMB/CIFS implementation.
3 * libsmbconf - Samba configuration library, registry backend
4 * Copyright (C) Michael Adam 2008
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.
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.
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/>.
20 #include "includes.h"
21 #include "lib/smbconf/smbconf_private.h"
22 #include "registry.h"
23 #include "registry/reg_api.h"
24 #include "registry/reg_backend_db.h"
25 #include "registry/reg_util_token.h"
26 #include "registry/reg_api_util.h"
27 #include "registry/reg_init_smbconf.h"
28 #include "lib/smbconf/smbconf_init.h"
29 #include "lib/smbconf/smbconf_reg.h"
30 #include "../libcli/registry/util_reg.h"
32 #define INCLUDES_VALNAME "includes"
34 struct reg_private_data {
35 struct registry_key *base_key;
36 bool open; /* did _we_ open the registry? */
39 /**********************************************************************
41 * helper functions
43 **********************************************************************/
45 /**
46 * a convenience helper to cast the private data structure
48 static struct reg_private_data *rpd(struct smbconf_ctx *ctx)
50 return (struct reg_private_data *)(ctx->data);
53 /**
54 * Check whether a given parameter name is valid in the
55 * smbconf registry backend.
57 bool smbconf_reg_parameter_is_valid(const char *param_name)
59 /* hard code the list of forbidden names here for now */
60 const char *forbidden_names[] = {
61 "state directory",
62 "lock directory",
63 "lock dir",
64 "config backend",
65 "include",
67 * "includes" has a special meaning internally.
68 * It is currently not necessary to list it here since it is
69 * not a valid parameter. But for clarity and safety, we keep
70 * it for now.
72 INCLUDES_VALNAME,
73 NULL
75 const char **forbidden = NULL;
77 if (!lp_parameter_is_valid(param_name)) {
78 return false;
81 for (forbidden = forbidden_names; *forbidden != NULL; forbidden++) {
82 if (strwicmp(param_name, *forbidden) == 0) {
83 return false;
87 return true;
90 /**
91 * Open a subkey of the base key (i.e a service)
93 static sbcErr smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx,
94 struct smbconf_ctx *ctx,
95 const char *servicename,
96 uint32_t desired_access,
97 struct registry_key **key)
99 WERROR werr;
101 if (servicename == NULL) {
102 *key = rpd(ctx)->base_key;
103 return SBC_ERR_OK;
105 werr = reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename,
106 desired_access, key);
107 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
108 return SBC_ERR_NO_SUCH_SERVICE;
110 if (!W_ERROR_IS_OK(werr)) {
111 return SBC_ERR_NOMEM;
114 return SBC_ERR_OK;
118 * check if a value exists in a given registry key
120 static bool smbconf_value_exists(struct registry_key *key, const char *param)
122 bool ret = false;
123 WERROR werr;
124 TALLOC_CTX *ctx = talloc_stackframe();
125 struct registry_value *value = NULL;
127 werr = reg_queryvalue(ctx, key, param, &value);
128 if (W_ERROR_IS_OK(werr)) {
129 ret = true;
132 talloc_free(ctx);
133 return ret;
137 * create a subkey of the base key (i.e. a service...)
139 static sbcErr smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
140 struct smbconf_ctx *ctx,
141 const char * subkeyname,
142 struct registry_key **newkey)
144 WERROR werr;
145 sbcErr err = SBC_ERR_OK;
146 TALLOC_CTX *create_ctx;
147 enum winreg_CreateAction action = REG_ACTION_NONE;
149 /* create a new talloc ctx for creation. it will hold
150 * the intermediate parent key (SMBCONF) for creation
151 * and will be destroyed when leaving this function... */
152 create_ctx = talloc_stackframe();
154 werr = reg_createkey(mem_ctx, rpd(ctx)->base_key, subkeyname,
155 REG_KEY_WRITE, newkey, &action);
156 if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
157 DEBUG(10, ("Key '%s' already exists.\n", subkeyname));
158 err = SBC_ERR_FILE_EXISTS;
160 if (!W_ERROR_IS_OK(werr)) {
161 DEBUG(5, ("Error creating key %s: %s\n",
162 subkeyname, win_errstr(werr)));
163 err = SBC_ERR_UNKNOWN_FAILURE;
166 talloc_free(create_ctx);
167 return err;
171 * add a value to a key.
173 static sbcErr smbconf_reg_set_value(struct registry_key *key,
174 const char *valname,
175 const char *valstr)
177 struct registry_value val;
178 WERROR werr;
179 sbcErr err;
180 char *subkeyname;
181 const char *canon_valname;
182 const char *canon_valstr;
183 TALLOC_CTX *tmp_ctx = talloc_stackframe();
185 if (!lp_parameter_is_valid(valname)) {
186 DEBUG(5, ("Invalid parameter '%s' given.\n", valname));
187 err = SBC_ERR_INVALID_PARAM;
188 goto done;
191 if (!smbconf_reg_parameter_is_valid(valname)) {
192 DEBUG(5, ("Parameter '%s' not allowed in registry.\n",
193 valname));
194 err = SBC_ERR_INVALID_PARAM;
195 goto done;
198 subkeyname = strrchr_m(key->key->name, '\\');
199 if ((subkeyname == NULL) || (*(subkeyname +1) == '\0')) {
200 DEBUG(5, ("Invalid registry key '%s' given as "
201 "smbconf section.\n", key->key->name));
202 err = SBC_ERR_INVALID_PARAM;
203 goto done;
205 subkeyname++;
206 if (!strequal(subkeyname, GLOBAL_NAME) &&
207 lp_parameter_is_global(valname))
209 DEBUG(5, ("Global parameter '%s' not allowed in "
210 "service definition ('%s').\n", valname,
211 subkeyname));
212 err = SBC_ERR_INVALID_PARAM;
213 goto done;
216 if (!lp_canonicalize_parameter_with_value(valname, valstr,
217 &canon_valname,
218 &canon_valstr))
221 * We already know the parameter name is valid.
222 * So the value must be invalid.
224 DEBUG(5, ("invalid value '%s' given for parameter '%s'\n",
225 valstr, valname));
226 err = SBC_ERR_INVALID_PARAM;
227 goto done;
230 ZERO_STRUCT(val);
232 val.type = REG_SZ;
233 if (!push_reg_sz(tmp_ctx, &val.data, canon_valstr)) {
234 err = SBC_ERR_NOMEM;
235 goto done;
238 werr = reg_setvalue(key, canon_valname, &val);
239 if (!W_ERROR_IS_OK(werr)) {
240 DEBUG(5, ("Error adding value '%s' to "
241 "key '%s': %s\n",
242 canon_valname, key->key->name, win_errstr(werr)));
243 err = SBC_ERR_NOMEM;
244 goto done;
247 err = SBC_ERR_OK;
248 done:
249 talloc_free(tmp_ctx);
250 return err;
253 static sbcErr smbconf_reg_set_multi_sz_value(struct registry_key *key,
254 const char *valname,
255 const uint32_t num_strings,
256 const char **strings)
258 WERROR werr;
259 sbcErr err = SBC_ERR_OK;
260 struct registry_value *value;
261 uint32_t count;
262 TALLOC_CTX *tmp_ctx = talloc_stackframe();
263 const char **array;
265 if (strings == NULL) {
266 err = SBC_ERR_INVALID_PARAM;
267 goto done;
270 array = talloc_zero_array(tmp_ctx, const char *, num_strings + 1);
271 if (array == NULL) {
272 err = SBC_ERR_NOMEM;
273 goto done;
276 value = talloc_zero(tmp_ctx, struct registry_value);
277 if (value == NULL) {
278 err = SBC_ERR_NOMEM;
279 goto done;
282 value->type = REG_MULTI_SZ;
284 for (count = 0; count < num_strings; count++) {
285 array[count] = talloc_strdup(value, strings[count]);
286 if (array[count] == NULL) {
287 err = SBC_ERR_NOMEM;
288 goto done;
292 if (!push_reg_multi_sz(value, &value->data, array)) {
293 err = SBC_ERR_NOMEM;
294 goto done;
297 werr = reg_setvalue(key, valname, value);
298 if (!W_ERROR_IS_OK(werr)) {
299 DEBUG(5, ("Error adding value '%s' to key '%s': %s\n",
300 valname, key->key->name, win_errstr(werr)));
301 err = SBC_ERR_ACCESS_DENIED;
304 done:
305 talloc_free(tmp_ctx);
306 return err;
310 * format a registry_value into a string.
312 * This is intended to be used for smbconf registry values,
313 * which are ar stored as REG_SZ values, so the incomplete
314 * handling should be ok.
316 static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx,
317 struct registry_value *value)
319 char *result = NULL;
321 /* alternatively, create a new talloc context? */
322 if (mem_ctx == NULL) {
323 return result;
326 switch (value->type) {
327 case REG_DWORD:
328 if (value->data.length >= 4) {
329 uint32_t v = IVAL(value->data.data, 0);
330 result = talloc_asprintf(mem_ctx, "%d", v);
332 break;
333 case REG_SZ:
334 case REG_EXPAND_SZ: {
335 const char *s;
336 if (!pull_reg_sz(mem_ctx, &value->data, &s)) {
337 break;
339 result = talloc_strdup(mem_ctx, s);
340 break;
342 case REG_MULTI_SZ: {
343 uint32_t j;
344 const char **a = NULL;
345 if (!pull_reg_multi_sz(mem_ctx, &value->data, &a)) {
346 break;
348 for (j = 0; a[j] != NULL; j++) {
349 result = talloc_asprintf(mem_ctx, "%s\"%s\" ",
350 result ? result : "" ,
351 a[j]);
352 if (result == NULL) {
353 break;
356 break;
358 case REG_BINARY:
359 result = talloc_asprintf(mem_ctx, "binary (%d bytes)",
360 (int)value->data.length);
361 break;
362 default:
363 result = talloc_asprintf(mem_ctx, "<unprintable>");
364 break;
366 return result;
369 static sbcErr smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx,
370 struct registry_key *key,
371 uint32_t *num_includes,
372 char ***includes)
374 WERROR werr;
375 sbcErr err;
376 uint32_t count;
377 struct registry_value *value = NULL;
378 char **tmp_includes = NULL;
379 const char **array = NULL;
380 TALLOC_CTX *tmp_ctx = talloc_stackframe();
382 if (!smbconf_value_exists(key, INCLUDES_VALNAME)) {
383 /* no includes */
384 *num_includes = 0;
385 *includes = NULL;
386 err = SBC_ERR_OK;
387 goto done;
390 werr = reg_queryvalue(tmp_ctx, key, INCLUDES_VALNAME, &value);
391 if (!W_ERROR_IS_OK(werr)) {
392 err = SBC_ERR_ACCESS_DENIED;
393 goto done;
396 if (value->type != REG_MULTI_SZ) {
397 /* wrong type -- ignore */
398 err = SBC_ERR_OK;
399 goto done;
402 if (!pull_reg_multi_sz(tmp_ctx, &value->data, &array)) {
403 err = SBC_ERR_NOMEM;
404 goto done;
407 for (count = 0; array[count] != NULL; count++) {
408 err = smbconf_add_string_to_array(tmp_ctx,
409 &tmp_includes,
410 count,
411 array[count]);
412 if (!SBC_ERROR_IS_OK(err)) {
413 goto done;
417 if (count > 0) {
418 *includes = talloc_move(mem_ctx, &tmp_includes);
419 if (*includes == NULL) {
420 err = SBC_ERR_NOMEM;
421 goto done;
423 *num_includes = count;
424 } else {
425 *num_includes = 0;
426 *includes = NULL;
429 err = SBC_ERR_OK;
430 done:
431 talloc_free(tmp_ctx);
432 return err;
436 * Get the values of a key as a list of value names
437 * and a list of value strings (ordered)
439 static sbcErr smbconf_reg_get_values(TALLOC_CTX *mem_ctx,
440 struct registry_key *key,
441 uint32_t *num_values,
442 char ***value_names,
443 char ***value_strings)
445 TALLOC_CTX *tmp_ctx = NULL;
446 WERROR werr;
447 sbcErr err;
448 uint32_t count;
449 struct registry_value *valvalue = NULL;
450 char *valname = NULL;
451 uint32_t tmp_num_values = 0;
452 char **tmp_valnames = NULL;
453 char **tmp_valstrings = NULL;
454 uint32_t num_includes = 0;
455 char **includes = NULL;
457 if ((num_values == NULL) || (value_names == NULL) ||
458 (value_strings == NULL))
460 err = SBC_ERR_INVALID_PARAM;
461 goto done;
464 tmp_ctx = talloc_stackframe();
466 for (count = 0;
467 werr = reg_enumvalue(tmp_ctx, key, count, &valname, &valvalue),
468 W_ERROR_IS_OK(werr);
469 count++)
471 char *valstring;
473 if (!smbconf_reg_parameter_is_valid(valname)) {
474 continue;
477 err = smbconf_add_string_to_array(tmp_ctx,
478 &tmp_valnames,
479 tmp_num_values, valname);
480 if (!SBC_ERROR_IS_OK(err)) {
481 goto done;
484 valstring = smbconf_format_registry_value(tmp_ctx, valvalue);
485 err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
486 tmp_num_values, valstring);
487 if (!SBC_ERROR_IS_OK(err)) {
488 goto done;
490 tmp_num_values++;
492 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
493 err = SBC_ERR_NOMEM;
494 goto done;
497 /* now add the includes at the end */
498 err = smbconf_reg_get_includes_internal(tmp_ctx, key, &num_includes,
499 &includes);
500 if (!SBC_ERROR_IS_OK(err)) {
501 goto done;
504 for (count = 0; count < num_includes; count++) {
505 err = smbconf_add_string_to_array(tmp_ctx, &tmp_valnames,
506 tmp_num_values, "include");
507 if (!SBC_ERROR_IS_OK(err)) {
508 goto done;
511 err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
512 tmp_num_values,
513 includes[count]);
514 if (!SBC_ERROR_IS_OK(err)) {
515 goto done;
518 tmp_num_values++;
521 *num_values = tmp_num_values;
522 if (tmp_num_values > 0) {
523 *value_names = talloc_move(mem_ctx, &tmp_valnames);
524 *value_strings = talloc_move(mem_ctx, &tmp_valstrings);
525 } else {
526 *value_names = NULL;
527 *value_strings = NULL;
530 done:
531 talloc_free(tmp_ctx);
532 return err;
536 * delete all values from a key
538 static sbcErr smbconf_reg_delete_values(struct registry_key *key)
540 WERROR werr;
541 sbcErr err;
542 char *valname;
543 struct registry_value *valvalue;
544 uint32_t count;
545 TALLOC_CTX *mem_ctx = talloc_stackframe();
547 for (count = 0;
548 werr = reg_enumvalue(mem_ctx, key, count, &valname, &valvalue),
549 W_ERROR_IS_OK(werr);
550 count++)
552 werr = reg_deletevalue(key, valname);
553 if (!W_ERROR_IS_OK(werr)) {
554 err = SBC_ERR_ACCESS_DENIED;
555 goto done;
558 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
559 DEBUG(1, ("smbconf_reg_delete_values: "
560 "Error enumerating values of %s: %s\n",
561 key->key->name,
562 win_errstr(werr)));
563 err = SBC_ERR_ACCESS_DENIED;
564 goto done;
567 err = SBC_ERR_OK;
569 done:
570 talloc_free(mem_ctx);
571 return err;
574 /**********************************************************************
576 * smbconf operations: registry implementations
578 **********************************************************************/
581 * initialize the registry smbconf backend
583 static sbcErr smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
585 WERROR werr;
586 sbcErr err;
587 struct security_token *token;
589 if (path == NULL) {
590 path = KEY_SMBCONF;
592 ctx->path = talloc_strdup(ctx, path);
593 if (ctx->path == NULL) {
594 err = SBC_ERR_NOMEM;
595 goto done;
598 ctx->data = talloc_zero(ctx, struct reg_private_data);
600 werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
601 if (!W_ERROR_IS_OK(werr)) {
602 DEBUG(1, ("Error creating admin token\n"));
603 err = SBC_ERR_UNKNOWN_FAILURE;
604 goto done;
606 rpd(ctx)->open = false;
608 werr = registry_init_smbconf(path);
609 if (!W_ERROR_IS_OK(werr)) {
610 err = SBC_ERR_BADFILE;
611 goto done;
614 err = ctx->ops->open_conf(ctx);
615 if (!SBC_ERROR_IS_OK(err)) {
616 DEBUG(1, ("Error opening the registry.\n"));
617 goto done;
620 werr = reg_open_path(ctx, ctx->path,
621 KEY_ENUMERATE_SUB_KEYS | REG_KEY_WRITE,
622 token, &rpd(ctx)->base_key);
623 if (!W_ERROR_IS_OK(werr)) {
624 err = SBC_ERR_UNKNOWN_FAILURE;
625 goto done;
628 done:
629 return err;
632 static int smbconf_reg_shutdown(struct smbconf_ctx *ctx)
634 return ctx->ops->close_conf(ctx);
637 static bool smbconf_reg_requires_messaging(struct smbconf_ctx *ctx)
639 if (lp_clustering() && lp_parm_bool(-1, "ctdb", "registry.tdb", true)) {
640 return true;
643 return false;
646 static bool smbconf_reg_is_writeable(struct smbconf_ctx *ctx)
649 * The backend has write support.
651 * TODO: add access checks whether the concrete
652 * config source is really writeable by the calling user.
654 return true;
657 static sbcErr smbconf_reg_open(struct smbconf_ctx *ctx)
659 WERROR werr;
661 if (rpd(ctx)->open) {
662 return SBC_ERR_OK;
665 werr = regdb_open();
666 if (!W_ERROR_IS_OK(werr)) {
667 return SBC_ERR_BADFILE;
670 rpd(ctx)->open = true;
671 return SBC_ERR_OK;
674 static int smbconf_reg_close(struct smbconf_ctx *ctx)
676 int ret;
678 if (!rpd(ctx)->open) {
679 return 0;
682 ret = regdb_close();
683 if (ret == 0) {
684 rpd(ctx)->open = false;
686 return ret;
690 * Get the change sequence number of the given service/parameter.
691 * service and parameter strings may be NULL.
693 static void smbconf_reg_get_csn(struct smbconf_ctx *ctx,
694 struct smbconf_csn *csn,
695 const char *service, const char *param)
697 if (csn == NULL) {
698 return;
701 if (!SBC_ERROR_IS_OK(ctx->ops->open_conf(ctx))) {
702 return;
705 csn->csn = (uint64_t)regdb_get_seqnum();
709 * Drop the whole configuration (restarting empty) - registry version
711 static sbcErr smbconf_reg_drop(struct smbconf_ctx *ctx)
713 char *path, *p;
714 WERROR werr;
715 sbcErr err = SBC_ERR_OK;
716 struct registry_key *parent_key = NULL;
717 struct registry_key *new_key = NULL;
718 TALLOC_CTX* mem_ctx = talloc_stackframe();
719 enum winreg_CreateAction action;
720 struct security_token *token;
722 werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
723 if (!W_ERROR_IS_OK(werr)) {
724 DEBUG(1, ("Error creating admin token\n"));
725 err = SBC_ERR_UNKNOWN_FAILURE;
726 goto done;
729 path = talloc_strdup(mem_ctx, ctx->path);
730 if (path == NULL) {
731 err = SBC_ERR_NOMEM;
732 goto done;
734 p = strrchr(path, '\\');
735 if (p == NULL) {
736 err = SBC_ERR_INVALID_PARAM;
737 goto done;
739 *p = '\0';
740 werr = reg_open_path(mem_ctx, path, REG_KEY_WRITE, token,
741 &parent_key);
742 if (!W_ERROR_IS_OK(werr)) {
743 err = SBC_ERR_IO_FAILURE;
744 goto done;
747 werr = reg_deletesubkeys_recursive(parent_key, p+1);
748 if (!W_ERROR_IS_OK(werr)) {
749 err = SBC_ERR_IO_FAILURE;
750 goto done;
753 werr = reg_createkey(mem_ctx, parent_key, p+1, REG_KEY_WRITE,
754 &new_key, &action);
755 if (!W_ERROR_IS_OK(werr)) {
756 err = SBC_ERR_IO_FAILURE;
757 goto done;
760 done:
761 talloc_free(mem_ctx);
762 return err;
766 * get the list of share names defined in the configuration.
767 * registry version.
769 static sbcErr smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
770 TALLOC_CTX *mem_ctx,
771 uint32_t *num_shares,
772 char ***share_names)
774 uint32_t count;
775 uint32_t added_count = 0;
776 TALLOC_CTX *tmp_ctx = NULL;
777 WERROR werr;
778 sbcErr err = SBC_ERR_OK;
779 char *subkey_name = NULL;
780 char **tmp_share_names = NULL;
782 if ((num_shares == NULL) || (share_names == NULL)) {
783 return SBC_ERR_INVALID_PARAM;
786 tmp_ctx = talloc_stackframe();
788 /* make sure "global" is always listed first */
789 if (smbconf_share_exists(ctx, GLOBAL_NAME)) {
790 err = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
791 added_count, GLOBAL_NAME);
792 if (!SBC_ERROR_IS_OK(err)) {
793 goto done;
795 added_count++;
798 for (count = 0;
799 werr = reg_enumkey(tmp_ctx, rpd(ctx)->base_key, count,
800 &subkey_name, NULL),
801 W_ERROR_IS_OK(werr);
802 count++)
804 if (strequal(subkey_name, GLOBAL_NAME)) {
805 continue;
808 err = smbconf_add_string_to_array(tmp_ctx,
809 &tmp_share_names,
810 added_count,
811 subkey_name);
812 if (!SBC_ERROR_IS_OK(err)) {
813 goto done;
815 added_count++;
817 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
818 err = SBC_ERR_NO_MORE_ITEMS;
819 goto done;
821 err = SBC_ERR_OK;
823 *num_shares = added_count;
824 if (added_count > 0) {
825 *share_names = talloc_move(mem_ctx, &tmp_share_names);
826 } else {
827 *share_names = NULL;
830 done:
831 talloc_free(tmp_ctx);
832 return err;
836 * check if a share/service of a given name exists - registry version
838 static bool smbconf_reg_share_exists(struct smbconf_ctx *ctx,
839 const char *servicename)
841 bool ret = false;
842 sbcErr err;
843 TALLOC_CTX *mem_ctx = talloc_stackframe();
844 struct registry_key *key = NULL;
846 err = smbconf_reg_open_service_key(mem_ctx, ctx, servicename,
847 REG_KEY_READ, &key);
848 if (SBC_ERROR_IS_OK(err)) {
849 ret = true;
852 talloc_free(mem_ctx);
853 return ret;
857 * Add a service if it does not already exist - registry version
859 static sbcErr smbconf_reg_create_share(struct smbconf_ctx *ctx,
860 const char *servicename)
862 sbcErr err;
863 struct registry_key *key = NULL;
864 TALLOC_CTX *tmp_ctx = talloc_stackframe();
866 if (servicename == NULL) {
867 return SBC_ERR_OK;
870 err = smbconf_reg_create_service_key(tmp_ctx, ctx,
871 servicename, &key);
873 talloc_free(tmp_ctx);
874 return err;
878 * get a definition of a share (service) from configuration.
880 static sbcErr smbconf_reg_get_share(struct smbconf_ctx *ctx,
881 TALLOC_CTX *mem_ctx,
882 const char *servicename,
883 struct smbconf_service **service)
885 sbcErr err;
886 struct registry_key *key = NULL;
887 struct smbconf_service *tmp_service = NULL;
888 TALLOC_CTX *tmp_ctx = talloc_stackframe();
890 err = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename,
891 REG_KEY_READ, &key);
892 if (!SBC_ERROR_IS_OK(err)) {
893 goto done;
896 tmp_service = talloc_zero(tmp_ctx, struct smbconf_service);
897 if (tmp_service == NULL) {
898 err = SBC_ERR_NOMEM;
899 goto done;
902 if (servicename != NULL) {
903 WERROR werr;
904 uint32_t count = 0;
905 char *name = NULL;
908 * Determine correct upper/lowercase.
910 for (count = 0;
911 werr = reg_enumkey(tmp_ctx, rpd(ctx)->base_key, count,
912 &name, NULL),
913 W_ERROR_IS_OK(werr);
914 count++) {
915 if (!strequal(name, servicename)) {
916 continue;
919 tmp_service->name = talloc_strdup(tmp_service, name);
920 if (tmp_service->name == NULL) {
921 err = SBC_ERR_NOMEM;
922 goto done;
924 break;
928 err = smbconf_reg_get_values(tmp_service, key,
929 &(tmp_service->num_params),
930 &(tmp_service->param_names),
931 &(tmp_service->param_values));
932 if (SBC_ERROR_IS_OK(err)) {
933 *service = talloc_move(mem_ctx, &tmp_service);
936 done:
937 talloc_free(tmp_ctx);
938 return err;
942 * delete a service from configuration
944 static sbcErr smbconf_reg_delete_share(struct smbconf_ctx *ctx,
945 const char *servicename)
947 WERROR werr;
948 sbcErr err = SBC_ERR_OK;
949 TALLOC_CTX *mem_ctx = talloc_stackframe();
951 if (servicename != NULL) {
952 werr = reg_deletekey_recursive(rpd(ctx)->base_key, servicename);
953 if (!W_ERROR_IS_OK(werr)) {
954 err = SBC_ERR_ACCESS_DENIED;
956 } else {
957 err = smbconf_reg_delete_values(rpd(ctx)->base_key);
960 talloc_free(mem_ctx);
961 return err;
965 * set a configuration parameter to the value provided.
967 static sbcErr smbconf_reg_set_parameter(struct smbconf_ctx *ctx,
968 const char *service,
969 const char *param,
970 const char *valstr)
972 sbcErr err;
973 struct registry_key *key = NULL;
974 TALLOC_CTX *mem_ctx = talloc_stackframe();
976 err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
977 REG_KEY_WRITE, &key);
978 if (!SBC_ERROR_IS_OK(err)) {
979 goto done;
982 err = smbconf_reg_set_value(key, param, valstr);
984 done:
985 talloc_free(mem_ctx);
986 return err;
990 * get the value of a configuration parameter as a string
992 static sbcErr smbconf_reg_get_parameter(struct smbconf_ctx *ctx,
993 TALLOC_CTX *mem_ctx,
994 const char *service,
995 const char *param,
996 char **valstr)
998 WERROR werr;
999 sbcErr err;
1000 struct registry_key *key = NULL;
1001 struct registry_value *value = NULL;
1003 err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
1004 REG_KEY_READ, &key);
1005 if (!SBC_ERROR_IS_OK(err)) {
1006 goto done;
1009 if (!smbconf_reg_parameter_is_valid(param)) {
1010 err = SBC_ERR_INVALID_PARAM;
1011 goto done;
1014 if (!smbconf_value_exists(key, param)) {
1015 err = SBC_ERR_INVALID_PARAM;
1016 goto done;
1019 werr = reg_queryvalue(mem_ctx, key, param, &value);
1020 if (!W_ERROR_IS_OK(werr)) {
1021 err = SBC_ERR_NOMEM;
1022 goto done;
1025 *valstr = smbconf_format_registry_value(mem_ctx, value);
1026 if (*valstr == NULL) {
1027 err = SBC_ERR_NOMEM;
1030 done:
1031 talloc_free(key);
1032 talloc_free(value);
1033 return err;
1037 * delete a parameter from configuration
1039 static sbcErr smbconf_reg_delete_parameter(struct smbconf_ctx *ctx,
1040 const char *service,
1041 const char *param)
1043 struct registry_key *key = NULL;
1044 WERROR werr;
1045 sbcErr err;
1046 TALLOC_CTX *mem_ctx = talloc_stackframe();
1048 err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
1049 REG_KEY_ALL, &key);
1050 if (!SBC_ERROR_IS_OK(err)) {
1051 goto done;
1054 if (!smbconf_reg_parameter_is_valid(param)) {
1055 err = SBC_ERR_INVALID_PARAM;
1056 goto done;
1059 if (!smbconf_value_exists(key, param)) {
1060 err = SBC_ERR_OK;
1061 goto done;
1064 werr = reg_deletevalue(key, param);
1065 if (!W_ERROR_IS_OK(werr)) {
1066 err = SBC_ERR_ACCESS_DENIED;
1069 done:
1070 talloc_free(mem_ctx);
1071 return err;
1074 static sbcErr smbconf_reg_get_includes(struct smbconf_ctx *ctx,
1075 TALLOC_CTX *mem_ctx,
1076 const char *service,
1077 uint32_t *num_includes,
1078 char ***includes)
1080 sbcErr err;
1081 struct registry_key *key = NULL;
1082 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1084 err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
1085 REG_KEY_READ, &key);
1086 if (!SBC_ERROR_IS_OK(err)) {
1087 goto done;
1090 err = smbconf_reg_get_includes_internal(mem_ctx, key, num_includes,
1091 includes);
1092 if (!SBC_ERROR_IS_OK(err)) {
1093 goto done;
1096 done:
1097 talloc_free(tmp_ctx);
1098 return err;
1101 static sbcErr smbconf_reg_set_includes(struct smbconf_ctx *ctx,
1102 const char *service,
1103 uint32_t num_includes,
1104 const char **includes)
1106 sbcErr err;
1107 struct registry_key *key = NULL;
1108 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1110 err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
1111 REG_KEY_ALL, &key);
1112 if (!SBC_ERROR_IS_OK(err)) {
1113 goto done;
1116 if (num_includes == 0) {
1117 WERROR werr;
1118 if (!smbconf_value_exists(key, INCLUDES_VALNAME)) {
1119 err = SBC_ERR_OK;
1120 goto done;
1122 werr = reg_deletevalue(key, INCLUDES_VALNAME);
1123 if (!W_ERROR_IS_OK(werr)) {
1124 err = SBC_ERR_ACCESS_DENIED;
1125 goto done;
1127 } else {
1128 err = smbconf_reg_set_multi_sz_value(key, INCLUDES_VALNAME,
1129 num_includes, includes);
1132 done:
1133 talloc_free(tmp_ctx);
1134 return err;
1137 static sbcErr smbconf_reg_delete_includes(struct smbconf_ctx *ctx,
1138 const char *service)
1140 WERROR werr;
1141 sbcErr err;
1142 struct registry_key *key = NULL;
1143 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1145 err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
1146 REG_KEY_ALL, &key);
1147 if (!SBC_ERROR_IS_OK(err)) {
1148 goto done;
1151 if (!smbconf_value_exists(key, INCLUDES_VALNAME)) {
1152 err = SBC_ERR_OK;
1153 goto done;
1156 werr = reg_deletevalue(key, INCLUDES_VALNAME);
1157 if (!W_ERROR_IS_OK(werr)) {
1158 err = SBC_ERR_ACCESS_DENIED;
1159 goto done;
1162 err = SBC_ERR_OK;
1163 done:
1164 talloc_free(tmp_ctx);
1165 return err;
1168 static sbcErr smbconf_reg_transaction_start(struct smbconf_ctx *ctx)
1170 WERROR werr;
1172 werr = regdb_transaction_start();
1173 if (!W_ERROR_IS_OK(werr)) {
1174 return SBC_ERR_IO_FAILURE;
1177 return SBC_ERR_OK;
1180 static sbcErr smbconf_reg_transaction_commit(struct smbconf_ctx *ctx)
1182 WERROR werr;
1184 werr = regdb_transaction_commit();
1185 if (!W_ERROR_IS_OK(werr)) {
1186 return SBC_ERR_IO_FAILURE;
1189 return SBC_ERR_OK;
1192 static sbcErr smbconf_reg_transaction_cancel(struct smbconf_ctx *ctx)
1194 WERROR werr;
1196 werr = regdb_transaction_cancel();
1197 if (!W_ERROR_IS_OK(werr)) {
1198 return SBC_ERR_IO_FAILURE;
1201 return SBC_ERR_OK;
1204 struct smbconf_ops smbconf_ops_reg = {
1205 .init = smbconf_reg_init,
1206 .shutdown = smbconf_reg_shutdown,
1207 .requires_messaging = smbconf_reg_requires_messaging,
1208 .is_writeable = smbconf_reg_is_writeable,
1209 .open_conf = smbconf_reg_open,
1210 .close_conf = smbconf_reg_close,
1211 .get_csn = smbconf_reg_get_csn,
1212 .drop = smbconf_reg_drop,
1213 .get_share_names = smbconf_reg_get_share_names,
1214 .share_exists = smbconf_reg_share_exists,
1215 .create_share = smbconf_reg_create_share,
1216 .get_share = smbconf_reg_get_share,
1217 .delete_share = smbconf_reg_delete_share,
1218 .set_parameter = smbconf_reg_set_parameter,
1219 .get_parameter = smbconf_reg_get_parameter,
1220 .delete_parameter = smbconf_reg_delete_parameter,
1221 .get_includes = smbconf_reg_get_includes,
1222 .set_includes = smbconf_reg_set_includes,
1223 .delete_includes = smbconf_reg_delete_includes,
1224 .transaction_start = smbconf_reg_transaction_start,
1225 .transaction_commit = smbconf_reg_transaction_commit,
1226 .transaction_cancel = smbconf_reg_transaction_cancel,
1231 * initialize the smbconf registry backend
1232 * the only function that is exported from this module
1234 sbcErr smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
1235 const char *path)
1238 * this tmp_ctx stackframe is required to initialize the registry backend.
1239 * Without it, the calls panics due to the use of talloc_tos in the
1240 * source3/registry code.
1242 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1243 sbcErr err = smbconf_init_internal(mem_ctx, conf_ctx, path, &smbconf_ops_reg);
1244 talloc_free(tmp_ctx);
1245 return err;