LCOV - code coverage report
Current view: top level - source3/lib/smbconf - smbconf_reg.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 373 551 67.7 %
Date: 2021-09-23 10:06:22 Functions: 30 34 88.2 %

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

Generated by: LCOV version 1.13