LCOV - code coverage report
Current view: top level - source3/lib/smbconf - smbconf_reg.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 237 557 42.5 %
Date: 2024-06-13 04:01:37 Functions: 23 34 67.6 %

          Line data    Source code
       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 "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"
      31             : 
      32             : #define INCLUDES_VALNAME "includes"
      33             : 
      34             : struct reg_private_data {
      35             :         struct registry_key *base_key;
      36             :         bool open;              /* did _we_ open the registry? */
      37             : };
      38             : 
      39             : /**********************************************************************
      40             :  *
      41             :  * helper functions
      42             :  *
      43             :  **********************************************************************/
      44             : 
      45             : /**
      46             :  * a convenience helper to cast the private data structure
      47             :  */
      48      188140 : static struct reg_private_data *rpd(struct smbconf_ctx *ctx)
      49             : {
      50      188140 :         return (struct reg_private_data *)(ctx->data);
      51             : }
      52             : 
      53             : /**
      54             :  * Check whether a given parameter name is valid in the
      55             :  * smbconf registry backend.
      56             :  */
      57          25 : bool smbconf_reg_parameter_is_valid(const char *param_name)
      58             : {
      59             :         /* hard code the list of forbidden names here for now */
      60          25 :         const char *forbidden_names[] = {
      61             :                 "state directory",
      62             :                 "lock directory",
      63             :                 "lock dir",
      64             :                 "config backend",
      65             :                 "include",
      66             :                 /*
      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.
      71             :                  */
      72             :                 INCLUDES_VALNAME,
      73             :                 NULL
      74             :         };
      75          25 :         const char **forbidden = NULL;
      76             : 
      77          25 :         if (!lp_parameter_is_valid(param_name)) {
      78           0 :                 return false;
      79             :         }
      80             : 
      81         175 :         for (forbidden = forbidden_names; *forbidden != NULL; forbidden++) {
      82         150 :                 if (strwicmp(param_name, *forbidden) == 0) {
      83           0 :                         return false;
      84             :                 }
      85             :         }
      86             : 
      87          25 :         return true;
      88             : }
      89             : 
      90             : /**
      91             :  * Open a subkey of the base key (i.e a service)
      92             :  */
      93      187612 : 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)
      98             : {
      99             :         WERROR werr;
     100             : 
     101      187612 :         if (servicename == NULL) {
     102           0 :                 *key = rpd(ctx)->base_key;
     103           0 :                 return SBC_ERR_OK;
     104             :         }
     105      187612 :         werr = reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename,
     106             :                            desired_access, key);
     107      187612 :         if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
     108      187593 :                 return SBC_ERR_NO_SUCH_SERVICE;
     109             :         }
     110          19 :         if (!W_ERROR_IS_OK(werr)) {
     111           0 :                 return SBC_ERR_NOMEM;
     112             :         }
     113             : 
     114          19 :         return SBC_ERR_OK;
     115             : }
     116             : 
     117             : /**
     118             :  * check if a value exists in a given registry key
     119             :  */
     120           2 : static bool smbconf_value_exists(struct registry_key *key, const char *param)
     121             : {
     122           2 :         bool ret = false;
     123             :         WERROR werr;
     124           2 :         TALLOC_CTX *ctx = talloc_stackframe();
     125           2 :         struct registry_value *value = NULL;
     126             : 
     127           2 :         werr = reg_queryvalue(ctx, key, param, &value);
     128           2 :         if (W_ERROR_IS_OK(werr)) {
     129           0 :                 ret = true;
     130             :         }
     131             : 
     132           2 :         talloc_free(ctx);
     133           2 :         return ret;
     134             : }
     135             : 
     136             : /**
     137             :  * create a subkey of the base key (i.e. a service...)
     138             :  */
     139           1 : 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)
     143             : {
     144             :         WERROR werr;
     145           1 :         sbcErr err = SBC_ERR_OK;
     146             :         TALLOC_CTX *create_ctx;
     147           1 :         enum winreg_CreateAction action = REG_ACTION_NONE;
     148             : 
     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           1 :         create_ctx = talloc_stackframe();
     153             : 
     154           1 :         werr = reg_createkey(mem_ctx, rpd(ctx)->base_key, subkeyname,
     155             :                              REG_KEY_WRITE, newkey, &action);
     156           1 :         if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
     157           0 :                 DEBUG(10, ("Key '%s' already exists.\n", subkeyname));
     158           0 :                 err = SBC_ERR_FILE_EXISTS;
     159             :         }
     160           1 :         if (!W_ERROR_IS_OK(werr)) {
     161           0 :                 DEBUG(5, ("Error creating key %s: %s\n",
     162             :                          subkeyname, win_errstr(werr)));
     163           0 :                 err = SBC_ERR_UNKNOWN_FAILURE;
     164             :         }
     165             : 
     166           1 :         talloc_free(create_ctx);
     167           1 :         return err;
     168             : }
     169             : 
     170             : /**
     171             :  * add a value to a key.
     172             :  */
     173           9 : static sbcErr smbconf_reg_set_value(struct registry_key *key,
     174             :                                     const char *valname,
     175             :                                     const char *valstr)
     176             : {
     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           9 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     184             : 
     185           9 :         if (!lp_parameter_is_valid(valname)) {
     186           0 :                 DEBUG(5, ("Invalid parameter '%s' given.\n", valname));
     187           0 :                 err = SBC_ERR_INVALID_PARAM;
     188           0 :                 goto done;
     189             :         }
     190             : 
     191           9 :         if (!smbconf_reg_parameter_is_valid(valname)) {
     192           0 :                 DEBUG(5, ("Parameter '%s' not allowed in registry.\n",
     193             :                           valname));
     194           0 :                 err = SBC_ERR_INVALID_PARAM;
     195           0 :                 goto done;
     196             :         }
     197             : 
     198           9 :         subkeyname = strrchr_m(key->key->name, '\\');
     199           9 :         if ((subkeyname == NULL) || (*(subkeyname +1) == '\0')) {
     200           0 :                 DEBUG(5, ("Invalid registry key '%s' given as "
     201             :                           "smbconf section.\n", key->key->name));
     202           0 :                 err = SBC_ERR_INVALID_PARAM;
     203           0 :                 goto done;
     204             :         }
     205           9 :         subkeyname++;
     206          18 :         if (!strequal(subkeyname, GLOBAL_NAME) &&
     207           9 :             lp_parameter_is_global(valname))
     208             :         {
     209           0 :                 DEBUG(5, ("Global parameter '%s' not allowed in "
     210             :                           "service definition ('%s').\n", valname,
     211             :                           subkeyname));
     212           0 :                 err = SBC_ERR_INVALID_PARAM;
     213           0 :                 goto done;
     214             :         }
     215             : 
     216           9 :         if (!lp_canonicalize_parameter_with_value(valname, valstr,
     217             :                                                   &canon_valname,
     218             :                                                   &canon_valstr))
     219             :         {
     220             :                 /*
     221             :                  * We already know the parameter name is valid.
     222             :                  * So the value must be invalid.
     223             :                  */
     224           0 :                 DEBUG(5, ("invalid value '%s' given for parameter '%s'\n",
     225             :                           valstr, valname));
     226           0 :                 err = SBC_ERR_INVALID_PARAM;
     227           0 :                 goto done;
     228             :         }
     229             : 
     230           9 :         ZERO_STRUCT(val);
     231             : 
     232           9 :         val.type = REG_SZ;
     233           9 :         if (!push_reg_sz(tmp_ctx, &val.data, canon_valstr)) {
     234           0 :                 err = SBC_ERR_NOMEM;
     235           0 :                 goto done;
     236             :         }
     237             : 
     238           9 :         werr = reg_setvalue(key, canon_valname, &val);
     239           9 :         if (!W_ERROR_IS_OK(werr)) {
     240           0 :                 DEBUG(5, ("Error adding value '%s' to "
     241             :                           "key '%s': %s\n",
     242             :                           canon_valname, key->key->name, win_errstr(werr)));
     243           0 :                 err = SBC_ERR_NOMEM;
     244           0 :                 goto done;
     245             :         }
     246             : 
     247           9 :         err = SBC_ERR_OK;
     248           9 : done:
     249           9 :         talloc_free(tmp_ctx);
     250           9 :         return err;
     251             : }
     252             : 
     253           0 : 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)
     257             : {
     258             :         WERROR werr;
     259           0 :         sbcErr err = SBC_ERR_OK;
     260             :         struct registry_value *value;
     261             :         uint32_t count;
     262           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     263             :         const char **array;
     264             : 
     265           0 :         if (strings == NULL) {
     266           0 :                 err = SBC_ERR_INVALID_PARAM;
     267           0 :                 goto done;
     268             :         }
     269             : 
     270           0 :         array = talloc_zero_array(tmp_ctx, const char *, num_strings + 1);
     271           0 :         if (array == NULL) {
     272           0 :                 err = SBC_ERR_NOMEM;
     273           0 :                 goto done;
     274             :         }
     275             : 
     276           0 :         value = talloc_zero(tmp_ctx, struct registry_value);
     277           0 :         if (value == NULL) {
     278           0 :                 err = SBC_ERR_NOMEM;
     279           0 :                 goto done;
     280             :         }
     281             : 
     282           0 :         value->type = REG_MULTI_SZ;
     283             : 
     284           0 :         for (count = 0; count < num_strings; count++) {
     285           0 :                 array[count] = talloc_strdup(value, strings[count]);
     286           0 :                 if (array[count] == NULL) {
     287           0 :                         err = SBC_ERR_NOMEM;
     288           0 :                         goto done;
     289             :                 }
     290             :         }
     291             : 
     292           0 :         if (!push_reg_multi_sz(value, &value->data, array)) {
     293           0 :                 err = SBC_ERR_NOMEM;
     294           0 :                 goto done;
     295             :         }
     296             : 
     297           0 :         werr = reg_setvalue(key, valname, value);
     298           0 :         if (!W_ERROR_IS_OK(werr)) {
     299           0 :                 DEBUG(5, ("Error adding value '%s' to key '%s': %s\n",
     300             :                           valname, key->key->name, win_errstr(werr)));
     301           0 :                 err = SBC_ERR_ACCESS_DENIED;
     302             :         }
     303             : 
     304           0 : done:
     305           0 :         talloc_free(tmp_ctx);
     306           0 :         return err;
     307             : }
     308             : 
     309             : /**
     310             :  * format a registry_value into a string.
     311             :  *
     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.
     315             :  */
     316          11 : static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx,
     317             :                                            struct registry_value *value)
     318             : {
     319          11 :         char *result = NULL;
     320             : 
     321             :         /* alternatively, create a new talloc context? */
     322          11 :         if (mem_ctx == NULL) {
     323           0 :                 return result;
     324             :         }
     325             : 
     326          11 :         switch (value->type) {
     327           0 :         case REG_DWORD:
     328           0 :                 if (value->data.length >= 4) {
     329           0 :                         uint32_t v = IVAL(value->data.data, 0);
     330           0 :                         result = talloc_asprintf(mem_ctx, "%d", v);
     331             :                 }
     332           0 :                 break;
     333          11 :         case REG_SZ:
     334             :         case REG_EXPAND_SZ: {
     335             :                 const char *s;
     336          11 :                 if (!pull_reg_sz(mem_ctx, &value->data, &s)) {
     337           0 :                         break;
     338             :                 }
     339          11 :                 result = talloc_strdup(mem_ctx, s);
     340          11 :                 break;
     341             :         }
     342           0 :         case REG_MULTI_SZ: {
     343             :                 uint32_t j;
     344           0 :                 const char **a = NULL;
     345           0 :                 if (!pull_reg_multi_sz(mem_ctx, &value->data, &a)) {
     346           0 :                         break;
     347             :                 }
     348           0 :                 for (j = 0; a[j] != NULL; j++) {
     349           0 :                         result = talloc_asprintf(mem_ctx, "%s\"%s\" ",
     350             :                                                  result ? result : "" ,
     351           0 :                                                  a[j]);
     352           0 :                         if (result == NULL) {
     353           0 :                                 break;
     354             :                         }
     355             :                 }
     356           0 :                 break;
     357             :         }
     358           0 :         case REG_BINARY:
     359           0 :                 result = talloc_asprintf(mem_ctx, "binary (%d bytes)",
     360           0 :                                          (int)value->data.length);
     361           0 :                 break;
     362           0 :         default:
     363           0 :                 result = talloc_asprintf(mem_ctx, "<unprintable>");
     364           0 :                 break;
     365             :         }
     366          11 :         return result;
     367             : }
     368             : 
     369           2 : static sbcErr smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx,
     370             :                                                 struct registry_key *key,
     371             :                                                 uint32_t *num_includes,
     372             :                                                 char ***includes)
     373             : {
     374             :         WERROR werr;
     375             :         sbcErr err;
     376             :         uint32_t count;
     377           2 :         struct registry_value *value = NULL;
     378           2 :         char **tmp_includes = NULL;
     379           2 :         const char **array = NULL;
     380           2 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     381             : 
     382           2 :         if (!smbconf_value_exists(key, INCLUDES_VALNAME)) {
     383             :                 /* no includes */
     384           2 :                 *num_includes = 0;
     385           2 :                 *includes = NULL;
     386           2 :                 err = SBC_ERR_OK;
     387           2 :                 goto done;
     388             :         }
     389             : 
     390           0 :         werr = reg_queryvalue(tmp_ctx, key, INCLUDES_VALNAME, &value);
     391           0 :         if (!W_ERROR_IS_OK(werr)) {
     392           0 :                 err = SBC_ERR_ACCESS_DENIED;
     393           0 :                 goto done;
     394             :         }
     395             : 
     396           0 :         if (value->type != REG_MULTI_SZ) {
     397             :                 /* wrong type -- ignore */
     398           0 :                 err = SBC_ERR_OK;
     399           0 :                 goto done;
     400             :         }
     401             : 
     402           0 :         if (!pull_reg_multi_sz(tmp_ctx, &value->data, &array)) {
     403           0 :                 err = SBC_ERR_NOMEM;
     404           0 :                 goto done;
     405             :         }
     406             : 
     407           0 :         for (count = 0; array[count] != NULL; count++) {
     408           0 :                 err = smbconf_add_string_to_array(tmp_ctx,
     409             :                                         &tmp_includes,
     410             :                                         count,
     411           0 :                                         array[count]);
     412           0 :                 if (!SBC_ERROR_IS_OK(err)) {
     413           0 :                         goto done;
     414             :                 }
     415             :         }
     416             : 
     417           0 :         if (count > 0) {
     418           0 :                 *includes = talloc_move(mem_ctx, &tmp_includes);
     419           0 :                 if (*includes == NULL) {
     420           0 :                         err = SBC_ERR_NOMEM;
     421           0 :                         goto done;
     422             :                 }
     423           0 :                 *num_includes = count;
     424             :         } else {
     425           0 :                 *num_includes = 0;
     426           0 :                 *includes = NULL;
     427             :         }
     428             : 
     429           0 :         err = SBC_ERR_OK;
     430           2 : done:
     431           2 :         talloc_free(tmp_ctx);
     432           2 :         return err;
     433             : }
     434             : 
     435             : /**
     436             :  * Get the values of a key as a list of value names
     437             :  * and a list of value strings (ordered)
     438             :  */
     439           2 : 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)
     444             : {
     445           2 :         TALLOC_CTX *tmp_ctx = NULL;
     446             :         WERROR werr;
     447             :         sbcErr err;
     448             :         uint32_t count;
     449           2 :         struct registry_value *valvalue = NULL;
     450           2 :         char *valname = NULL;
     451           2 :         uint32_t tmp_num_values = 0;
     452           2 :         char **tmp_valnames = NULL;
     453           2 :         char **tmp_valstrings = NULL;
     454           2 :         uint32_t num_includes = 0;
     455           2 :         char **includes = NULL;
     456             : 
     457           2 :         if ((num_values == NULL) || (value_names == NULL) ||
     458             :             (value_strings == NULL))
     459             :         {
     460           0 :                 err = SBC_ERR_INVALID_PARAM;
     461           0 :                 goto done;
     462             :         }
     463             : 
     464           2 :         tmp_ctx = talloc_stackframe();
     465             : 
     466          15 :         for (count = 0;
     467          13 :              werr = reg_enumvalue(tmp_ctx, key, count, &valname, &valvalue),
     468          13 :              W_ERROR_IS_OK(werr);
     469          11 :              count++)
     470             :         {
     471             :                 char *valstring;
     472             : 
     473          11 :                 if (!smbconf_reg_parameter_is_valid(valname)) {
     474           0 :                         continue;
     475             :                 }
     476             : 
     477          11 :                 err = smbconf_add_string_to_array(tmp_ctx,
     478             :                                                   &tmp_valnames,
     479             :                                                   tmp_num_values, valname);
     480          11 :                 if (!SBC_ERROR_IS_OK(err)) {
     481           0 :                         goto done;
     482             :                 }
     483             : 
     484          11 :                 valstring = smbconf_format_registry_value(tmp_ctx, valvalue);
     485          11 :                 err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
     486             :                                                   tmp_num_values, valstring);
     487          11 :                 if (!SBC_ERROR_IS_OK(err)) {
     488           0 :                         goto done;
     489             :                 }
     490          11 :                 tmp_num_values++;
     491             :         }
     492           2 :         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
     493           0 :                 err = SBC_ERR_NOMEM;
     494           0 :                 goto done;
     495             :         }
     496             : 
     497             :         /* now add the includes at the end */
     498           2 :         err = smbconf_reg_get_includes_internal(tmp_ctx, key, &num_includes,
     499             :                                                  &includes);
     500           2 :         if (!SBC_ERROR_IS_OK(err)) {
     501           0 :                 goto done;
     502             :         }
     503             : 
     504           2 :         for (count = 0; count < num_includes; count++) {
     505           0 :                 err = smbconf_add_string_to_array(tmp_ctx, &tmp_valnames,
     506             :                                                   tmp_num_values, "include");
     507           0 :                 if (!SBC_ERROR_IS_OK(err)) {
     508           0 :                         goto done;
     509             :                 }
     510             : 
     511           0 :                 err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
     512             :                                                   tmp_num_values,
     513           0 :                                                   includes[count]);
     514           0 :                 if (!SBC_ERROR_IS_OK(err)) {
     515           0 :                         goto done;
     516             :                 }
     517             : 
     518           0 :                 tmp_num_values++;
     519             :         }
     520             : 
     521           2 :         *num_values = tmp_num_values;
     522           2 :         if (tmp_num_values > 0) {
     523           2 :                 *value_names = talloc_move(mem_ctx, &tmp_valnames);
     524           2 :                 *value_strings = talloc_move(mem_ctx, &tmp_valstrings);
     525             :         } else {
     526           0 :                 *value_names = NULL;
     527           0 :                 *value_strings = NULL;
     528             :         }
     529             : 
     530           2 : done:
     531           2 :         talloc_free(tmp_ctx);
     532           2 :         return err;
     533             : }
     534             : 
     535             : /**
     536             :  * delete all values from a key
     537             :  */
     538           0 : static sbcErr smbconf_reg_delete_values(struct registry_key *key)
     539             : {
     540             :         WERROR werr;
     541             :         sbcErr err;
     542             :         char *valname;
     543             :         struct registry_value *valvalue;
     544             :         uint32_t count;
     545           0 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
     546             : 
     547           0 :         for (count = 0;
     548           0 :              werr = reg_enumvalue(mem_ctx, key, count, &valname, &valvalue),
     549           0 :              W_ERROR_IS_OK(werr);
     550           0 :              count++)
     551             :         {
     552           0 :                 werr = reg_deletevalue(key, valname);
     553           0 :                 if (!W_ERROR_IS_OK(werr)) {
     554           0 :                         err = SBC_ERR_ACCESS_DENIED;
     555           0 :                         goto done;
     556             :                 }
     557             :         }
     558           0 :         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
     559           0 :                 DEBUG(1, ("smbconf_reg_delete_values: "
     560             :                           "Error enumerating values of %s: %s\n",
     561             :                           key->key->name,
     562             :                           win_errstr(werr)));
     563           0 :                 err = SBC_ERR_ACCESS_DENIED;
     564           0 :                 goto done;
     565             :         }
     566             : 
     567           0 :         err = SBC_ERR_OK;
     568             : 
     569           0 : done:
     570           0 :         talloc_free(mem_ctx);
     571           0 :         return err;
     572             : }
     573             : 
     574             : /**********************************************************************
     575             :  *
     576             :  * smbconf operations: registry implementations
     577             :  *
     578             :  **********************************************************************/
     579             : 
     580             : /**
     581             :  * initialize the registry smbconf backend
     582             :  */
     583          99 : static sbcErr smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
     584             : {
     585             :         WERROR werr;
     586             :         sbcErr err;
     587             :         struct security_token *token;
     588             : 
     589          99 :         if (path == NULL) {
     590          99 :                 path = KEY_SMBCONF;
     591             :         }
     592          99 :         ctx->path = talloc_strdup(ctx, path);
     593          99 :         if (ctx->path == NULL) {
     594           0 :                 err = SBC_ERR_NOMEM;
     595           0 :                 goto done;
     596             :         }
     597             : 
     598          99 :         ctx->data = talloc_zero(ctx, struct reg_private_data);
     599             : 
     600          99 :         werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
     601          99 :         if (!W_ERROR_IS_OK(werr)) {
     602           0 :                 DEBUG(1, ("Error creating admin token\n"));
     603           0 :                 err = SBC_ERR_UNKNOWN_FAILURE;
     604           0 :                 goto done;
     605             :         }
     606          99 :         rpd(ctx)->open = false;
     607             : 
     608          99 :         werr = registry_init_smbconf(path);
     609          99 :         if (!W_ERROR_IS_OK(werr)) {
     610           0 :                 err = SBC_ERR_BADFILE;
     611           0 :                 goto done;
     612             :         }
     613             : 
     614          99 :         err = ctx->ops->open_conf(ctx);
     615          99 :         if (!SBC_ERROR_IS_OK(err)) {
     616           0 :                 DEBUG(1, ("Error opening the registry.\n"));
     617           0 :                 goto done;
     618             :         }
     619             : 
     620          99 :         werr = reg_open_path(ctx, ctx->path,
     621             :                              KEY_ENUMERATE_SUB_KEYS | REG_KEY_WRITE,
     622          99 :                              token, &rpd(ctx)->base_key);
     623          99 :         if (!W_ERROR_IS_OK(werr)) {
     624           0 :                 err = SBC_ERR_UNKNOWN_FAILURE;
     625           0 :                 goto done;
     626             :         }
     627             : 
     628         160 : done:
     629          99 :         return err;
     630             : }
     631             : 
     632           7 : static int smbconf_reg_shutdown(struct smbconf_ctx *ctx)
     633             : {
     634           7 :         return ctx->ops->close_conf(ctx);
     635             : }
     636             : 
     637           0 : static bool smbconf_reg_requires_messaging(struct smbconf_ctx *ctx)
     638             : {
     639           0 :         if (lp_clustering() && lp_parm_bool(-1, "ctdb", "registry.tdb", true)) {
     640           0 :                 return true;
     641             :         }
     642             : 
     643           0 :         return false;
     644             : }
     645             : 
     646           0 : static bool smbconf_reg_is_writeable(struct smbconf_ctx *ctx)
     647             : {
     648             :         /*
     649             :          * The backend has write support.
     650             :          *
     651             :          *  TODO: add access checks whether the concrete
     652             :          *  config source is really writeable by the calling user.
     653             :          */
     654           0 :         return true;
     655             : }
     656             : 
     657         157 : static sbcErr smbconf_reg_open(struct smbconf_ctx *ctx)
     658             : {
     659             :         WERROR werr;
     660             : 
     661         157 :         if (rpd(ctx)->open) {
     662          58 :                 return SBC_ERR_OK;
     663             :         }
     664             : 
     665          99 :         werr = regdb_open();
     666          99 :         if (!W_ERROR_IS_OK(werr)) {
     667           0 :                 return SBC_ERR_BADFILE;
     668             :         }
     669             : 
     670          99 :         rpd(ctx)->open = true;
     671          99 :         return SBC_ERR_OK;
     672             : }
     673             : 
     674           7 : static int smbconf_reg_close(struct smbconf_ctx *ctx)
     675             : {
     676             :         int ret;
     677             : 
     678           7 :         if (!rpd(ctx)->open) {
     679           0 :                 return 0;
     680             :         }
     681             : 
     682           7 :         ret = regdb_close();
     683           7 :         if (ret == 0) {
     684           7 :                 rpd(ctx)->open = false;
     685             :         }
     686           7 :         return ret;
     687             : }
     688             : 
     689             : /**
     690             :  * Get the change sequence number of the given service/parameter.
     691             :  * service and parameter strings may be NULL.
     692             :  */
     693          58 : static void smbconf_reg_get_csn(struct smbconf_ctx *ctx,
     694             :                                 struct smbconf_csn *csn,
     695             :                                 const char *service, const char *param)
     696             : {
     697          58 :         if (csn == NULL) {
     698           0 :                 return;
     699             :         }
     700             : 
     701          58 :         if (!SBC_ERROR_IS_OK(ctx->ops->open_conf(ctx))) {
     702           0 :                 return;
     703             :         }
     704             : 
     705          58 :         csn->csn = (uint64_t)regdb_get_seqnum();
     706             : }
     707             : 
     708             : /**
     709             :  * Drop the whole configuration (restarting empty) - registry version
     710             :  */
     711           0 : static sbcErr smbconf_reg_drop(struct smbconf_ctx *ctx)
     712             : {
     713             :         char *path, *p;
     714             :         WERROR werr;
     715           0 :         sbcErr err = SBC_ERR_OK;
     716           0 :         struct registry_key *parent_key = NULL;
     717           0 :         struct registry_key *new_key = NULL;
     718           0 :         TALLOC_CTX* mem_ctx = talloc_stackframe();
     719             :         enum winreg_CreateAction action;
     720             :         struct security_token *token;
     721             : 
     722           0 :         werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
     723           0 :         if (!W_ERROR_IS_OK(werr)) {
     724           0 :                 DEBUG(1, ("Error creating admin token\n"));
     725           0 :                 err = SBC_ERR_UNKNOWN_FAILURE;
     726           0 :                 goto done;
     727             :         }
     728             : 
     729           0 :         path = talloc_strdup(mem_ctx, ctx->path);
     730           0 :         if (path == NULL) {
     731           0 :                 err = SBC_ERR_NOMEM;
     732           0 :                 goto done;
     733             :         }
     734           0 :         p = strrchr(path, '\\');
     735           0 :         if (p == NULL) {
     736           0 :                 err = SBC_ERR_INVALID_PARAM;
     737           0 :                 goto done;
     738             :         }
     739           0 :         *p = '\0';
     740           0 :         werr = reg_open_path(mem_ctx, path, REG_KEY_WRITE, token,
     741             :                              &parent_key);
     742           0 :         if (!W_ERROR_IS_OK(werr)) {
     743           0 :                 err = SBC_ERR_IO_FAILURE;
     744           0 :                 goto done;
     745             :         }
     746             : 
     747           0 :         werr = reg_deletesubkeys_recursive(parent_key, p+1);
     748           0 :         if (!W_ERROR_IS_OK(werr)) {
     749           0 :                 err = SBC_ERR_IO_FAILURE;
     750           0 :                 goto done;
     751             :         }
     752             : 
     753           0 :         werr = reg_createkey(mem_ctx, parent_key, p+1, REG_KEY_WRITE,
     754             :                              &new_key, &action);
     755           0 :         if (!W_ERROR_IS_OK(werr)) {
     756           0 :                 err = SBC_ERR_IO_FAILURE;
     757           0 :                 goto done;
     758             :         }
     759             : 
     760           0 : done:
     761           0 :         talloc_free(mem_ctx);
     762           0 :         return err;
     763             : }
     764             : 
     765             : /**
     766             :  * get the list of share names defined in the configuration.
     767             :  * registry version.
     768             :  */
     769          56 : 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)
     773             : {
     774             :         uint32_t count;
     775          56 :         uint32_t added_count = 0;
     776          56 :         TALLOC_CTX *tmp_ctx = NULL;
     777             :         WERROR werr;
     778          56 :         sbcErr err = SBC_ERR_OK;
     779          56 :         char *subkey_name = NULL;
     780          56 :         char **tmp_share_names = NULL;
     781             : 
     782          56 :         if ((num_shares == NULL) || (share_names == NULL)) {
     783           0 :                 return SBC_ERR_INVALID_PARAM;
     784             :         }
     785             : 
     786          56 :         tmp_ctx = talloc_stackframe();
     787             : 
     788             :         /* make sure "global" is always listed first */
     789          56 :         if (smbconf_share_exists(ctx, GLOBAL_NAME)) {
     790           0 :                 err = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
     791             :                                                   added_count, GLOBAL_NAME);
     792           0 :                 if (!SBC_ERROR_IS_OK(err)) {
     793           0 :                         goto done;
     794             :                 }
     795           0 :                 added_count++;
     796             :         }
     797             : 
     798          84 :         for (count = 0;
     799          56 :              werr = reg_enumkey(tmp_ctx, rpd(ctx)->base_key, count,
     800             :                                 &subkey_name, NULL),
     801          56 :              W_ERROR_IS_OK(werr);
     802           0 :              count++)
     803             :         {
     804           0 :                 if (strequal(subkey_name, GLOBAL_NAME)) {
     805           0 :                         continue;
     806             :                 }
     807             : 
     808           0 :                 err = smbconf_add_string_to_array(tmp_ctx,
     809             :                                                    &tmp_share_names,
     810             :                                                    added_count,
     811             :                                                    subkey_name);
     812           0 :                 if (!SBC_ERROR_IS_OK(err)) {
     813           0 :                         goto done;
     814             :                 }
     815           0 :                 added_count++;
     816             :         }
     817          56 :         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
     818           0 :                 err = SBC_ERR_NO_MORE_ITEMS;
     819           0 :                 goto done;
     820             :         }
     821          56 :         err = SBC_ERR_OK;
     822             : 
     823          56 :         *num_shares = added_count;
     824          56 :         if (added_count > 0) {
     825           0 :                 *share_names = talloc_move(mem_ctx, &tmp_share_names);
     826             :         } else {
     827          56 :                 *share_names = NULL;
     828             :         }
     829             : 
     830          56 : done:
     831          56 :         talloc_free(tmp_ctx);
     832          56 :         return err;
     833             : }
     834             : 
     835             : /**
     836             :  * check if a share/service of a given name exists - registry version
     837             :  */
     838      187601 : static bool smbconf_reg_share_exists(struct smbconf_ctx *ctx,
     839             :                                      const char *servicename)
     840             : {
     841      187601 :         bool ret = false;
     842             :         sbcErr err;
     843      187601 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
     844      187601 :         struct registry_key *key = NULL;
     845             : 
     846      187601 :         err = smbconf_reg_open_service_key(mem_ctx, ctx, servicename,
     847             :                                            REG_KEY_READ, &key);
     848      187601 :         if (SBC_ERROR_IS_OK(err)) {
     849           8 :                 ret = true;
     850             :         }
     851             : 
     852      187601 :         talloc_free(mem_ctx);
     853      187601 :         return ret;
     854             : }
     855             : 
     856             : /**
     857             :  * Add a service if it does not already exist - registry version
     858             :  */
     859           1 : static sbcErr smbconf_reg_create_share(struct smbconf_ctx *ctx,
     860             :                                        const char *servicename)
     861             : {
     862             :         sbcErr err;
     863           1 :         struct registry_key *key = NULL;
     864           1 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     865             : 
     866           1 :         if (servicename == NULL) {
     867           0 :                 return SBC_ERR_OK;
     868             :         }
     869             : 
     870           1 :         err = smbconf_reg_create_service_key(tmp_ctx, ctx,
     871             :                                              servicename, &key);
     872             : 
     873           1 :         talloc_free(tmp_ctx);
     874           1 :         return err;
     875             : }
     876             : 
     877             : /**
     878             :  * get a definition of a share (service) from configuration.
     879             :  */
     880           2 : static sbcErr smbconf_reg_get_share(struct smbconf_ctx *ctx,
     881             :                                     TALLOC_CTX *mem_ctx,
     882             :                                     const char *servicename,
     883             :                                     struct smbconf_service **service)
     884             : {
     885             :         sbcErr err;
     886           2 :         struct registry_key *key = NULL;
     887           2 :         struct smbconf_service *tmp_service = NULL;
     888           2 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     889             : 
     890           2 :         err = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename,
     891             :                                            REG_KEY_READ, &key);
     892           2 :         if (!SBC_ERROR_IS_OK(err)) {
     893           0 :                 goto done;
     894             :         }
     895             : 
     896           2 :         tmp_service = talloc_zero(tmp_ctx, struct smbconf_service);
     897           2 :         if (tmp_service == NULL) {
     898           0 :                 err = SBC_ERR_NOMEM;
     899           0 :                 goto done;
     900             :         }
     901             : 
     902           2 :         if (servicename != NULL) {
     903             :                 WERROR werr;
     904           2 :                 uint32_t count = 0;
     905           2 :                 char *name = NULL;
     906             : 
     907             :                 /*
     908             :                  * Determine correct upper/lowercase.
     909             :                  */
     910           4 :                 for (count = 0;
     911           2 :                      werr = reg_enumkey(tmp_ctx, rpd(ctx)->base_key, count,
     912             :                                         &name, NULL),
     913           2 :                              W_ERROR_IS_OK(werr);
     914           0 :                      count++) {
     915           2 :                         if (!strequal(name, servicename)) {
     916           0 :                                 continue;
     917             :                         }
     918             : 
     919           2 :                         tmp_service->name = talloc_strdup(tmp_service, name);
     920           2 :                         if (tmp_service->name == NULL) {
     921           0 :                                 err = SBC_ERR_NOMEM;
     922           0 :                                 goto done;
     923             :                         }
     924           2 :                         break;
     925             :                 }
     926             :         }
     927             : 
     928           6 :         err = smbconf_reg_get_values(tmp_service, key,
     929           2 :                                      &(tmp_service->num_params),
     930           2 :                                      &(tmp_service->param_names),
     931           2 :                                      &(tmp_service->param_values));
     932           2 :         if (SBC_ERROR_IS_OK(err)) {
     933           2 :                 *service = talloc_move(mem_ctx, &tmp_service);
     934             :         }
     935             : 
     936           2 : done:
     937           2 :         talloc_free(tmp_ctx);
     938           2 :         return err;
     939             : }
     940             : 
     941             : /**
     942             :  * delete a service from configuration
     943             :  */
     944           1 : static sbcErr smbconf_reg_delete_share(struct smbconf_ctx *ctx,
     945             :                                        const char *servicename)
     946             : {
     947             :         WERROR werr;
     948           1 :         sbcErr err = SBC_ERR_OK;
     949           1 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
     950             : 
     951           1 :         if (servicename != NULL) {
     952           1 :                 werr = reg_deletekey_recursive(rpd(ctx)->base_key, servicename);
     953           1 :                 if (!W_ERROR_IS_OK(werr)) {
     954           0 :                         err = SBC_ERR_ACCESS_DENIED;
     955             :                 }
     956             :         } else {
     957           0 :                 err = smbconf_reg_delete_values(rpd(ctx)->base_key);
     958             :         }
     959             : 
     960           1 :         talloc_free(mem_ctx);
     961           1 :         return err;
     962             : }
     963             : 
     964             : /**
     965             :  * set a configuration parameter to the value provided.
     966             :  */
     967           9 : static sbcErr smbconf_reg_set_parameter(struct smbconf_ctx *ctx,
     968             :                                         const char *service,
     969             :                                         const char *param,
     970             :                                         const char *valstr)
     971             : {
     972             :         sbcErr err;
     973           9 :         struct registry_key *key = NULL;
     974           9 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
     975             : 
     976           9 :         err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
     977             :                                            REG_KEY_WRITE, &key);
     978           9 :         if (!SBC_ERROR_IS_OK(err)) {
     979           0 :                 goto done;
     980             :         }
     981             : 
     982           9 :         err = smbconf_reg_set_value(key, param, valstr);
     983             : 
     984           9 : done:
     985           9 :         talloc_free(mem_ctx);
     986           9 :         return err;
     987             : }
     988             : 
     989             : /**
     990             :  * get the value of a configuration parameter as a string
     991             :  */
     992           0 : 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)
     997             : {
     998             :         WERROR werr;
     999             :         sbcErr err;
    1000           0 :         struct registry_key *key = NULL;
    1001           0 :         struct registry_value *value = NULL;
    1002             : 
    1003           0 :         err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
    1004             :                                            REG_KEY_READ, &key);
    1005           0 :         if (!SBC_ERROR_IS_OK(err)) {
    1006           0 :                 goto done;
    1007             :         }
    1008             : 
    1009           0 :         if (!smbconf_reg_parameter_is_valid(param)) {
    1010           0 :                 err = SBC_ERR_INVALID_PARAM;
    1011           0 :                 goto done;
    1012             :         }
    1013             : 
    1014           0 :         if (!smbconf_value_exists(key, param)) {
    1015           0 :                 err = SBC_ERR_INVALID_PARAM;
    1016           0 :                 goto done;
    1017             :         }
    1018             : 
    1019           0 :         werr = reg_queryvalue(mem_ctx, key, param, &value);
    1020           0 :         if (!W_ERROR_IS_OK(werr)) {
    1021           0 :                 err = SBC_ERR_NOMEM;
    1022           0 :                 goto done;
    1023             :         }
    1024             : 
    1025           0 :         *valstr = smbconf_format_registry_value(mem_ctx, value);
    1026           0 :         if (*valstr == NULL) {
    1027           0 :                 err = SBC_ERR_NOMEM;
    1028             :         }
    1029             : 
    1030           0 : done:
    1031           0 :         talloc_free(key);
    1032           0 :         talloc_free(value);
    1033           0 :         return err;
    1034             : }
    1035             : 
    1036             : /**
    1037             :  * delete a parameter from configuration
    1038             :  */
    1039           0 : static sbcErr smbconf_reg_delete_parameter(struct smbconf_ctx *ctx,
    1040             :                                            const char *service,
    1041             :                                            const char *param)
    1042             : {
    1043           0 :         struct registry_key *key = NULL;
    1044             :         WERROR werr;
    1045             :         sbcErr err;
    1046           0 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
    1047             : 
    1048           0 :         err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
    1049             :                                            REG_KEY_ALL, &key);
    1050           0 :         if (!SBC_ERROR_IS_OK(err)) {
    1051           0 :                 goto done;
    1052             :         }
    1053             : 
    1054           0 :         if (!smbconf_reg_parameter_is_valid(param)) {
    1055           0 :                 err = SBC_ERR_INVALID_PARAM;
    1056           0 :                 goto done;
    1057             :         }
    1058             : 
    1059           0 :         if (!smbconf_value_exists(key, param)) {
    1060           0 :                 err = SBC_ERR_OK;
    1061           0 :                 goto done;
    1062             :         }
    1063             : 
    1064           0 :         werr = reg_deletevalue(key, param);
    1065           0 :         if (!W_ERROR_IS_OK(werr)) {
    1066           0 :                 err = SBC_ERR_ACCESS_DENIED;
    1067             :         }
    1068             : 
    1069           0 : done:
    1070           0 :         talloc_free(mem_ctx);
    1071           0 :         return err;
    1072             : }
    1073             : 
    1074           0 : 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)
    1079             : {
    1080             :         sbcErr err;
    1081           0 :         struct registry_key *key = NULL;
    1082           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1083             : 
    1084           0 :         err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
    1085             :                                            REG_KEY_READ, &key);
    1086           0 :         if (!SBC_ERROR_IS_OK(err)) {
    1087           0 :                 goto done;
    1088             :         }
    1089             : 
    1090           0 :         err = smbconf_reg_get_includes_internal(mem_ctx, key, num_includes,
    1091             :                                                  includes);
    1092           0 :         if (!SBC_ERROR_IS_OK(err)) {
    1093           0 :                 goto done;
    1094             :         }
    1095             : 
    1096           0 : done:
    1097           0 :         talloc_free(tmp_ctx);
    1098           0 :         return err;
    1099             : }
    1100             : 
    1101           0 : static sbcErr smbconf_reg_set_includes(struct smbconf_ctx *ctx,
    1102             :                                        const char *service,
    1103             :                                        uint32_t num_includes,
    1104             :                                        const char **includes)
    1105             : {
    1106             :         sbcErr err;
    1107           0 :         struct registry_key *key = NULL;
    1108           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1109             : 
    1110           0 :         err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
    1111             :                                            REG_KEY_ALL, &key);
    1112           0 :         if (!SBC_ERROR_IS_OK(err)) {
    1113           0 :                 goto done;
    1114             :         }
    1115             : 
    1116           0 :         if (num_includes == 0) {
    1117             :                 WERROR werr;
    1118           0 :                 if (!smbconf_value_exists(key, INCLUDES_VALNAME)) {
    1119           0 :                         err = SBC_ERR_OK;
    1120           0 :                         goto done;
    1121             :                 }
    1122           0 :                 werr = reg_deletevalue(key, INCLUDES_VALNAME);
    1123           0 :                 if (!W_ERROR_IS_OK(werr)) {
    1124           0 :                         err = SBC_ERR_ACCESS_DENIED;
    1125           0 :                         goto done;
    1126             :                 }
    1127             :         } else {
    1128           0 :                 err = smbconf_reg_set_multi_sz_value(key, INCLUDES_VALNAME,
    1129             :                                                       num_includes, includes);
    1130             :         }
    1131             : 
    1132           0 : done:
    1133           0 :         talloc_free(tmp_ctx);
    1134           0 :         return err;
    1135             : }
    1136             : 
    1137           0 : static sbcErr smbconf_reg_delete_includes(struct smbconf_ctx *ctx,
    1138             :                                           const char *service)
    1139             : {
    1140             :         WERROR werr;
    1141             :         sbcErr err;
    1142           0 :         struct registry_key *key = NULL;
    1143           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1144             : 
    1145           0 :         err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
    1146             :                                            REG_KEY_ALL, &key);
    1147           0 :         if (!SBC_ERROR_IS_OK(err)) {
    1148           0 :                 goto done;
    1149             :         }
    1150             : 
    1151           0 :         if (!smbconf_value_exists(key, INCLUDES_VALNAME)) {
    1152           0 :                 err = SBC_ERR_OK;
    1153           0 :                 goto done;
    1154             :         }
    1155             : 
    1156           0 :         werr = reg_deletevalue(key, INCLUDES_VALNAME);
    1157           0 :         if (!W_ERROR_IS_OK(werr)) {
    1158           0 :                 err = SBC_ERR_ACCESS_DENIED;
    1159           0 :                 goto done;
    1160             :         }
    1161             : 
    1162           0 :         err = SBC_ERR_OK;
    1163           0 : done:
    1164           0 :         talloc_free(tmp_ctx);
    1165           0 :         return err;
    1166             : }
    1167             : 
    1168           6 : static sbcErr smbconf_reg_transaction_start(struct smbconf_ctx *ctx)
    1169             : {
    1170             :         WERROR werr;
    1171             : 
    1172           6 :         werr = regdb_transaction_start();
    1173           6 :         if (!W_ERROR_IS_OK(werr)) {
    1174           0 :                 return SBC_ERR_IO_FAILURE;
    1175             :         }
    1176             : 
    1177           6 :         return SBC_ERR_OK;
    1178             : }
    1179             : 
    1180           6 : static sbcErr smbconf_reg_transaction_commit(struct smbconf_ctx *ctx)
    1181             : {
    1182             :         WERROR werr;
    1183             : 
    1184           6 :         werr = regdb_transaction_commit();
    1185           6 :         if (!W_ERROR_IS_OK(werr)) {
    1186           0 :                 return SBC_ERR_IO_FAILURE;
    1187             :         }
    1188             : 
    1189           6 :         return SBC_ERR_OK;
    1190             : }
    1191             : 
    1192           0 : static sbcErr smbconf_reg_transaction_cancel(struct smbconf_ctx *ctx)
    1193             : {
    1194             :         WERROR werr;
    1195             : 
    1196           0 :         werr = regdb_transaction_cancel();
    1197           0 :         if (!W_ERROR_IS_OK(werr)) {
    1198           0 :                 return SBC_ERR_IO_FAILURE;
    1199             :         }
    1200             : 
    1201           0 :         return SBC_ERR_OK;
    1202             : }
    1203             : 
    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,
    1227             : };
    1228             : 
    1229             : 
    1230             : /**
    1231             :  * initialize the smbconf registry backend
    1232             :  * the only function that is exported from this module
    1233             :  */
    1234          99 : sbcErr smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
    1235             :                         const char *path)
    1236             : {
    1237             :         /*
    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.
    1241             :          */
    1242          99 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1243          99 :         sbcErr err = smbconf_init_internal(mem_ctx, conf_ctx, path, &smbconf_ops_reg);
    1244          99 :         talloc_free(tmp_ctx);
    1245          99 :         return err;
    1246             : }

Generated by: LCOV version 1.13