LCOV - code coverage report
Current view: top level - source3/lib/smbconf - smbconf_reg.c (source / functions) Hit Total Coverage
Test: coverage report for master 70ed9daf Lines: 425 614 69.2 %
Date: 2024-01-11 09:59:51 Functions: 32 34 94.1 %

          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     3038829 : static struct reg_private_data *rpd(struct smbconf_ctx *ctx)
      49             : {
      50     3038829 :         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       20435 : bool smbconf_reg_parameter_is_valid(const char *param_name)
      58             : {
      59             :         /* hard code the list of forbidden names here for now */
      60       20435 :         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       20435 :         const char **forbidden = NULL;
      76             : 
      77       20435 :         if (!lp_parameter_is_valid(param_name)) {
      78           2 :                 return false;
      79             :         }
      80             : 
      81      142951 :         for (forbidden = forbidden_names; *forbidden != NULL; forbidden++) {
      82      122538 :                 if (strwicmp(param_name, *forbidden) == 0) {
      83          20 :                         return false;
      84             :                 }
      85             :         }
      86             : 
      87       20369 :         return true;
      88             : }
      89             : 
      90             : /**
      91             :  * Open a subkey of the base key (i.e a service)
      92             :  */
      93     2811721 : 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          78 :         WERROR werr;
     100             : 
     101     2811721 :         if (servicename == NULL) {
     102           0 :                 *key = rpd(ctx)->base_key;
     103           0 :                 return SBC_ERR_OK;
     104             :         }
     105     2811721 :         werr = reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename,
     106             :                            desired_access, key);
     107     2811721 :         if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
     108     2803142 :                 return SBC_ERR_NO_SUCH_SERVICE;
     109             :         }
     110        8552 :         if (!W_ERROR_IS_OK(werr)) {
     111           0 :                 return SBC_ERR_NOMEM;
     112             :         }
     113             : 
     114        8501 :         return SBC_ERR_OK;
     115             : }
     116             : 
     117             : /**
     118             :  * check if a value exists in a given registry key
     119             :  */
     120        4745 : static bool smbconf_value_exists(struct registry_key *key, const char *param)
     121             : {
     122        4745 :         bool ret = false;
     123          17 :         WERROR werr;
     124        4745 :         TALLOC_CTX *ctx = talloc_stackframe();
     125        4745 :         struct registry_value *value = NULL;
     126             : 
     127        4745 :         werr = reg_queryvalue(ctx, key, param, &value);
     128        4745 :         if (W_ERROR_IS_OK(werr)) {
     129          21 :                 ret = true;
     130             :         }
     131             : 
     132        4745 :         talloc_free(ctx);
     133        4745 :         return ret;
     134             : }
     135             : 
     136             : /**
     137             :  * create a subkey of the base key (i.e. a service...)
     138             :  */
     139         661 : 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          14 :         WERROR werr;
     145         661 :         sbcErr err = SBC_ERR_OK;
     146          14 :         TALLOC_CTX *create_ctx;
     147         661 :         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         661 :         create_ctx = talloc_stackframe();
     153             : 
     154         661 :         werr = reg_createkey(mem_ctx, rpd(ctx)->base_key, subkeyname,
     155             :                              REG_KEY_WRITE, newkey, &action);
     156         661 :         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         661 :         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         661 :         talloc_free(create_ctx);
     167         661 :         return err;
     168             : }
     169             : 
     170             : /**
     171             :  * add a value to a key.
     172             :  */
     173        2890 : static sbcErr smbconf_reg_set_value(struct registry_key *key,
     174             :                                     const char *valname,
     175             :                                     const char *valstr)
     176             : {
     177          21 :         struct registry_value val;
     178          21 :         WERROR werr;
     179          21 :         sbcErr err;
     180          21 :         char *subkeyname;
     181          21 :         const char *canon_valname;
     182          21 :         const char *canon_valstr;
     183        2890 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     184             : 
     185        2890 :         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        2890 :         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        2890 :         subkeyname = strrchr_m(key->key->name, '\\');
     199        2890 :         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        2890 :         subkeyname++;
     206        5538 :         if (!strequal(subkeyname, GLOBAL_NAME) &&
     207        2648 :             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        2890 :         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        2890 :         ZERO_STRUCT(val);
     231             : 
     232        2890 :         val.type = REG_SZ;
     233        2890 :         if (!push_reg_sz(tmp_ctx, &val.data, canon_valstr)) {
     234           0 :                 err = SBC_ERR_NOMEM;
     235           0 :                 goto done;
     236             :         }
     237             : 
     238        2890 :         werr = reg_setvalue(key, canon_valname, &val);
     239        2890 :         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        2869 :         err = SBC_ERR_OK;
     248        2890 : done:
     249        2890 :         talloc_free(tmp_ctx);
     250        2890 :         return err;
     251             : }
     252             : 
     253           6 : 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           0 :         WERROR werr;
     259           6 :         sbcErr err = SBC_ERR_OK;
     260           0 :         struct registry_value *value;
     261           0 :         uint32_t count;
     262           6 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     263           0 :         const char **array;
     264             : 
     265           6 :         if (strings == NULL) {
     266           0 :                 err = SBC_ERR_INVALID_PARAM;
     267           0 :                 goto done;
     268             :         }
     269             : 
     270           6 :         array = talloc_zero_array(tmp_ctx, const char *, num_strings + 1);
     271           6 :         if (array == NULL) {
     272           0 :                 err = SBC_ERR_NOMEM;
     273           0 :                 goto done;
     274             :         }
     275             : 
     276           6 :         value = talloc_zero(tmp_ctx, struct registry_value);
     277           6 :         if (value == NULL) {
     278           0 :                 err = SBC_ERR_NOMEM;
     279           0 :                 goto done;
     280             :         }
     281             : 
     282           6 :         value->type = REG_MULTI_SZ;
     283             : 
     284          18 :         for (count = 0; count < num_strings; count++) {
     285          12 :                 array[count] = talloc_strdup(value, strings[count]);
     286          12 :                 if (array[count] == NULL) {
     287           0 :                         err = SBC_ERR_NOMEM;
     288           0 :                         goto done;
     289             :                 }
     290             :         }
     291             : 
     292           6 :         if (!push_reg_multi_sz(value, &value->data, array)) {
     293           0 :                 err = SBC_ERR_NOMEM;
     294           0 :                 goto done;
     295             :         }
     296             : 
     297           6 :         werr = reg_setvalue(key, valname, value);
     298           6 :         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           6 : done:
     305           6 :         talloc_free(tmp_ctx);
     306           6 :         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       17483 : static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx,
     317             :                                            struct registry_value *value)
     318             : {
     319       17483 :         char *result = NULL;
     320             : 
     321             :         /* alternatively, create a new talloc context? */
     322       17483 :         if (mem_ctx == NULL) {
     323           0 :                 return result;
     324             :         }
     325             : 
     326       17483 :         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       17483 :         case REG_SZ:
     334             :         case REG_EXPAND_SZ: {
     335          20 :                 const char *s;
     336       17483 :                 if (!pull_reg_sz(mem_ctx, &value->data, &s)) {
     337           0 :                         break;
     338             :                 }
     339       17483 :                 result = talloc_strdup(mem_ctx, s);
     340       17483 :                 break;
     341             :         }
     342           0 :         case REG_MULTI_SZ: {
     343           0 :                 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       17463 :         return result;
     367             : }
     368             : 
     369        4295 : 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           9 :         WERROR werr;
     375           9 :         sbcErr err;
     376           9 :         uint32_t count;
     377        4295 :         struct registry_value *value = NULL;
     378        4295 :         char **tmp_includes = NULL;
     379        4295 :         const char **array = NULL;
     380        4295 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     381             : 
     382        4295 :         if (!smbconf_value_exists(key, INCLUDES_VALNAME)) {
     383             :                 /* no includes */
     384        4289 :                 *num_includes = 0;
     385        4289 :                 *includes = NULL;
     386        4289 :                 err = SBC_ERR_OK;
     387        4289 :                 goto done;
     388             :         }
     389             : 
     390           6 :         werr = reg_queryvalue(tmp_ctx, key, INCLUDES_VALNAME, &value);
     391           6 :         if (!W_ERROR_IS_OK(werr)) {
     392           0 :                 err = SBC_ERR_ACCESS_DENIED;
     393           0 :                 goto done;
     394             :         }
     395             : 
     396           6 :         if (value->type != REG_MULTI_SZ) {
     397             :                 /* wrong type -- ignore */
     398           0 :                 err = SBC_ERR_OK;
     399           0 :                 goto done;
     400             :         }
     401             : 
     402           6 :         if (!pull_reg_multi_sz(tmp_ctx, &value->data, &array)) {
     403           0 :                 err = SBC_ERR_NOMEM;
     404           0 :                 goto done;
     405             :         }
     406             : 
     407          22 :         for (count = 0; array[count] != NULL; count++) {
     408          16 :                 err = smbconf_add_string_to_array(tmp_ctx,
     409             :                                         &tmp_includes,
     410             :                                         count,
     411          16 :                                         array[count]);
     412          16 :                 if (!SBC_ERROR_IS_OK(err)) {
     413           0 :                         goto done;
     414             :                 }
     415             :         }
     416             : 
     417           6 :         if (count > 0) {
     418           6 :                 *includes = talloc_move(mem_ctx, &tmp_includes);
     419           6 :                 if (*includes == NULL) {
     420           0 :                         err = SBC_ERR_NOMEM;
     421           0 :                         goto done;
     422             :                 }
     423           6 :                 *num_includes = count;
     424             :         } else {
     425           0 :                 *num_includes = 0;
     426           0 :                 *includes = NULL;
     427             :         }
     428             : 
     429           6 :         err = SBC_ERR_OK;
     430        4295 : done:
     431        4295 :         talloc_free(tmp_ctx);
     432        4295 :         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        4287 : 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        4287 :         TALLOC_CTX *tmp_ctx = NULL;
     446           9 :         WERROR werr;
     447           9 :         sbcErr err;
     448           9 :         uint32_t count;
     449        4287 :         struct registry_value *valvalue = NULL;
     450        4287 :         char *valname = NULL;
     451        4287 :         uint32_t tmp_num_values = 0;
     452        4287 :         char **tmp_valnames = NULL;
     453        4287 :         char **tmp_valstrings = NULL;
     454        4287 :         uint32_t num_includes = 0;
     455        4287 :         char **includes = NULL;
     456             : 
     457        4287 :         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        4287 :         tmp_ctx = talloc_stackframe();
     465             : 
     466        4287 :         for (count = 0;
     467       21766 :              werr = reg_enumvalue(tmp_ctx, key, count, &valname, &valvalue),
     468       21737 :              W_ERROR_IS_OK(werr);
     469       17479 :              count++)
     470             :         {
     471          20 :                 char *valstring;
     472             : 
     473       17479 :                 if (!smbconf_reg_parameter_is_valid(valname)) {
     474           2 :                         continue;
     475             :                 }
     476             : 
     477       17477 :                 err = smbconf_add_string_to_array(tmp_ctx,
     478             :                                                   &tmp_valnames,
     479             :                                                   tmp_num_values, valname);
     480       17477 :                 if (!SBC_ERROR_IS_OK(err)) {
     481           0 :                         goto done;
     482             :                 }
     483             : 
     484       17477 :                 valstring = smbconf_format_registry_value(tmp_ctx, valvalue);
     485       17477 :                 err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
     486             :                                                   tmp_num_values, valstring);
     487       17477 :                 if (!SBC_ERROR_IS_OK(err)) {
     488           0 :                         goto done;
     489             :                 }
     490       17477 :                 tmp_num_values++;
     491             :         }
     492        4287 :         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        4287 :         err = smbconf_reg_get_includes_internal(tmp_ctx, key, &num_includes,
     499             :                                                  &includes);
     500        4287 :         if (!SBC_ERROR_IS_OK(err)) {
     501           0 :                 goto done;
     502             :         }
     503             : 
     504        4293 :         for (count = 0; count < num_includes; count++) {
     505           6 :                 err = smbconf_add_string_to_array(tmp_ctx, &tmp_valnames,
     506             :                                                   tmp_num_values, "include");
     507           6 :                 if (!SBC_ERROR_IS_OK(err)) {
     508           0 :                         goto done;
     509             :                 }
     510             : 
     511           6 :                 err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
     512             :                                                   tmp_num_values,
     513           6 :                                                   includes[count]);
     514           6 :                 if (!SBC_ERROR_IS_OK(err)) {
     515           0 :                         goto done;
     516             :                 }
     517             : 
     518           6 :                 tmp_num_values++;
     519             :         }
     520             : 
     521        4287 :         *num_values = tmp_num_values;
     522        4287 :         if (tmp_num_values > 0) {
     523        4275 :                 *value_names = talloc_move(mem_ctx, &tmp_valnames);
     524        4275 :                 *value_strings = talloc_move(mem_ctx, &tmp_valstrings);
     525             :         } else {
     526          12 :                 *value_names = NULL;
     527          12 :                 *value_strings = NULL;
     528             :         }
     529             : 
     530        4287 : done:
     531        4287 :         talloc_free(tmp_ctx);
     532        4287 :         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           0 :         WERROR werr;
     541           0 :         sbcErr err;
     542           0 :         char *valname;
     543           0 :         struct registry_value *valvalue;
     544           0 :         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        1041 : static sbcErr smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
     584             : {
     585          12 :         WERROR werr;
     586          12 :         sbcErr err;
     587          12 :         struct security_token *token;
     588             : 
     589        1041 :         if (path == NULL) {
     590        1041 :                 path = KEY_SMBCONF;
     591             :         }
     592        1041 :         ctx->path = talloc_strdup(ctx, path);
     593        1041 :         if (ctx->path == NULL) {
     594           0 :                 err = SBC_ERR_NOMEM;
     595           0 :                 goto done;
     596             :         }
     597             : 
     598        1041 :         ctx->data = talloc_zero(ctx, struct reg_private_data);
     599             : 
     600        1041 :         werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
     601        1041 :         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        1041 :         rpd(ctx)->open = false;
     607             : 
     608        1041 :         werr = registry_init_smbconf(path);
     609        1041 :         if (!W_ERROR_IS_OK(werr)) {
     610           0 :                 err = SBC_ERR_BADFILE;
     611           0 :                 goto done;
     612             :         }
     613             : 
     614        1041 :         err = ctx->ops->open_conf(ctx);
     615        1041 :         if (!SBC_ERROR_IS_OK(err)) {
     616           0 :                 DEBUG(1, ("Error opening the registry.\n"));
     617           0 :                 goto done;
     618             :         }
     619             : 
     620        1053 :         werr = reg_open_path(ctx, ctx->path,
     621             :                              KEY_ENUMERATE_SUB_KEYS | REG_KEY_WRITE,
     622        1041 :                              token, &rpd(ctx)->base_key);
     623        1041 :         if (!W_ERROR_IS_OK(werr)) {
     624           0 :                 err = SBC_ERR_UNKNOWN_FAILURE;
     625           0 :                 goto done;
     626             :         }
     627             : 
     628        1041 : done:
     629        1041 :         return err;
     630             : }
     631             : 
     632         607 : static int smbconf_reg_shutdown(struct smbconf_ctx *ctx)
     633             : {
     634         607 :         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           2 : 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           2 :         return true;
     655             : }
     656             : 
     657        2091 : static sbcErr smbconf_reg_open(struct smbconf_ctx *ctx)
     658             : {
     659          12 :         WERROR werr;
     660             : 
     661        2091 :         if (rpd(ctx)->open) {
     662        1050 :                 return SBC_ERR_OK;
     663             :         }
     664             : 
     665        1041 :         werr = regdb_open();
     666        1041 :         if (!W_ERROR_IS_OK(werr)) {
     667           0 :                 return SBC_ERR_BADFILE;
     668             :         }
     669             : 
     670        1041 :         rpd(ctx)->open = true;
     671        1041 :         return SBC_ERR_OK;
     672             : }
     673             : 
     674         607 : static int smbconf_reg_close(struct smbconf_ctx *ctx)
     675             : {
     676          12 :         int ret;
     677             : 
     678         607 :         if (!rpd(ctx)->open) {
     679           0 :                 return 0;
     680             :         }
     681             : 
     682         607 :         ret = regdb_close();
     683         607 :         if (ret == 0) {
     684         607 :                 rpd(ctx)->open = false;
     685             :         }
     686         595 :         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        1050 : static void smbconf_reg_get_csn(struct smbconf_ctx *ctx,
     694             :                                 struct smbconf_csn *csn,
     695             :                                 const char *service, const char *param)
     696             : {
     697        1050 :         if (csn == NULL) {
     698           0 :                 return;
     699             :         }
     700             : 
     701        1050 :         if (!SBC_ERROR_IS_OK(ctx->ops->open_conf(ctx))) {
     702           0 :                 return;
     703             :         }
     704             : 
     705        1050 :         csn->csn = (uint64_t)regdb_get_seqnum();
     706             : }
     707             : 
     708             : /**
     709             :  * Drop the whole configuration (restarting empty) - registry version
     710             :  */
     711          41 : static sbcErr smbconf_reg_drop(struct smbconf_ctx *ctx)
     712             : {
     713          11 :         char *path, *p;
     714          11 :         WERROR werr;
     715          41 :         sbcErr err = SBC_ERR_OK;
     716          41 :         struct registry_key *parent_key = NULL;
     717          41 :         struct registry_key *new_key = NULL;
     718          41 :         TALLOC_CTX* mem_ctx = talloc_stackframe();
     719          11 :         enum winreg_CreateAction action;
     720          11 :         struct security_token *token;
     721             : 
     722          41 :         werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
     723          41 :         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          41 :         path = talloc_strdup(mem_ctx, ctx->path);
     730          41 :         if (path == NULL) {
     731           0 :                 err = SBC_ERR_NOMEM;
     732           0 :                 goto done;
     733             :         }
     734          41 :         p = strrchr(path, '\\');
     735          41 :         if (p == NULL) {
     736           0 :                 err = SBC_ERR_INVALID_PARAM;
     737           0 :                 goto done;
     738             :         }
     739          41 :         *p = '\0';
     740          41 :         werr = reg_open_path(mem_ctx, path, REG_KEY_WRITE, token,
     741             :                              &parent_key);
     742          41 :         if (!W_ERROR_IS_OK(werr)) {
     743           0 :                 err = SBC_ERR_IO_FAILURE;
     744           0 :                 goto done;
     745             :         }
     746             : 
     747          41 :         werr = reg_deletesubkeys_recursive(parent_key, p+1);
     748          41 :         if (!W_ERROR_IS_OK(werr)) {
     749           0 :                 err = SBC_ERR_IO_FAILURE;
     750           0 :                 goto done;
     751             :         }
     752             : 
     753          41 :         werr = reg_createkey(mem_ctx, parent_key, p+1, REG_KEY_WRITE,
     754             :                              &new_key, &action);
     755          41 :         if (!W_ERROR_IS_OK(werr)) {
     756           0 :                 err = SBC_ERR_IO_FAILURE;
     757           0 :                 goto done;
     758             :         }
     759             : 
     760          41 : done:
     761          41 :         talloc_free(mem_ctx);
     762          41 :         return err;
     763             : }
     764             : 
     765             : /**
     766             :  * get the list of share names defined in the configuration.
     767             :  * registry version.
     768             :  */
     769         261 : 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           5 :         uint32_t count;
     775         261 :         uint32_t added_count = 0;
     776         261 :         TALLOC_CTX *tmp_ctx = NULL;
     777           5 :         WERROR werr;
     778         261 :         sbcErr err = SBC_ERR_OK;
     779         261 :         char *subkey_name = NULL;
     780         261 :         char **tmp_share_names = NULL;
     781             : 
     782         261 :         if ((num_shares == NULL) || (share_names == NULL)) {
     783           0 :                 return SBC_ERR_INVALID_PARAM;
     784             :         }
     785             : 
     786         261 :         tmp_ctx = talloc_stackframe();
     787             : 
     788             :         /* make sure "global" is always listed first */
     789         261 :         if (smbconf_share_exists(ctx, GLOBAL_NAME)) {
     790          16 :                 err = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
     791             :                                                   added_count, GLOBAL_NAME);
     792          16 :                 if (!SBC_ERROR_IS_OK(err)) {
     793           0 :                         goto done;
     794             :                 }
     795          16 :                 added_count++;
     796             :         }
     797             : 
     798         256 :         for (count = 0;
     799        3914 :              werr = reg_enumkey(tmp_ctx, rpd(ctx)->base_key, count,
     800             :                                 &subkey_name, NULL),
     801        3902 :              W_ERROR_IS_OK(werr);
     802        3653 :              count++)
     803             :         {
     804        3653 :                 if (strequal(subkey_name, GLOBAL_NAME)) {
     805          16 :                         continue;
     806             :                 }
     807             : 
     808        3637 :                 err = smbconf_add_string_to_array(tmp_ctx,
     809             :                                                    &tmp_share_names,
     810             :                                                    added_count,
     811             :                                                    subkey_name);
     812        3637 :                 if (!SBC_ERROR_IS_OK(err)) {
     813           0 :                         goto done;
     814             :                 }
     815        3637 :                 added_count++;
     816             :         }
     817         261 :         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
     818           0 :                 err = SBC_ERR_NO_MORE_ITEMS;
     819           0 :                 goto done;
     820             :         }
     821         261 :         err = SBC_ERR_OK;
     822             : 
     823         261 :         *num_shares = added_count;
     824         261 :         if (added_count > 0) {
     825          64 :                 *share_names = talloc_move(mem_ctx, &tmp_share_names);
     826             :         } else {
     827         197 :                 *share_names = NULL;
     828             :         }
     829             : 
     830         261 : done:
     831         261 :         talloc_free(tmp_ctx);
     832         261 :         return err;
     833             : }
     834             : 
     835             : /**
     836             :  * check if a share/service of a given name exists - registry version
     837             :  */
     838     2804076 : static bool smbconf_reg_share_exists(struct smbconf_ctx *ctx,
     839             :                                      const char *servicename)
     840             : {
     841     2804076 :         bool ret = false;
     842          40 :         sbcErr err;
     843     2804076 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
     844     2804076 :         struct registry_key *key = NULL;
     845             : 
     846     2804076 :         err = smbconf_reg_open_service_key(mem_ctx, ctx, servicename,
     847             :                                            REG_KEY_READ, &key);
     848     2804076 :         if (SBC_ERROR_IS_OK(err)) {
     849         911 :                 ret = true;
     850             :         }
     851             : 
     852     2804076 :         talloc_free(mem_ctx);
     853     2804076 :         return ret;
     854             : }
     855             : 
     856             : /**
     857             :  * Add a service if it does not already exist - registry version
     858             :  */
     859         661 : static sbcErr smbconf_reg_create_share(struct smbconf_ctx *ctx,
     860             :                                        const char *servicename)
     861             : {
     862          14 :         sbcErr err;
     863         661 :         struct registry_key *key = NULL;
     864         661 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     865             : 
     866         661 :         if (servicename == NULL) {
     867           0 :                 return SBC_ERR_OK;
     868             :         }
     869             : 
     870         661 :         err = smbconf_reg_create_service_key(tmp_ctx, ctx,
     871             :                                              servicename, &key);
     872             : 
     873         661 :         talloc_free(tmp_ctx);
     874         661 :         return err;
     875             : }
     876             : 
     877             : /**
     878             :  * get a definition of a share (service) from configuration.
     879             :  */
     880        4287 : 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           9 :         sbcErr err;
     886        4287 :         struct registry_key *key = NULL;
     887        4287 :         struct smbconf_service *tmp_service = NULL;
     888        4287 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     889             : 
     890        4287 :         err = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename,
     891             :                                            REG_KEY_READ, &key);
     892        4287 :         if (!SBC_ERROR_IS_OK(err)) {
     893           0 :                 goto done;
     894             :         }
     895             : 
     896        4287 :         tmp_service = talloc_zero(tmp_ctx, struct smbconf_service);
     897        4287 :         if (tmp_service == NULL) {
     898           0 :                 err = SBC_ERR_NOMEM;
     899           0 :                 goto done;
     900             :         }
     901             : 
     902        4287 :         if (servicename != NULL) {
     903           9 :                 WERROR werr;
     904        4287 :                 uint32_t count = 0;
     905        4287 :                 char *name = NULL;
     906             : 
     907             :                 /*
     908             :                  * Determine correct upper/lowercase.
     909             :                  */
     910        4287 :                 for (count = 0;
     911      216087 :                      werr = reg_enumkey(tmp_ctx, rpd(ctx)->base_key, count,
     912             :                                         &name, NULL),
     913      216087 :                              W_ERROR_IS_OK(werr);
     914      211800 :                      count++) {
     915      216087 :                         if (!strequal(name, servicename)) {
     916      211800 :                                 continue;
     917             :                         }
     918             : 
     919        4287 :                         tmp_service->name = talloc_strdup(tmp_service, name);
     920        4287 :                         if (tmp_service->name == NULL) {
     921           0 :                                 err = SBC_ERR_NOMEM;
     922           0 :                                 goto done;
     923             :                         }
     924        4278 :                         break;
     925             :                 }
     926             :         }
     927             : 
     928        4296 :         err = smbconf_reg_get_values(tmp_service, key,
     929        4278 :                                      &(tmp_service->num_params),
     930        4278 :                                      &(tmp_service->param_names),
     931        4287 :                                      &(tmp_service->param_values));
     932        4287 :         if (SBC_ERROR_IS_OK(err)) {
     933        4287 :                 *service = talloc_move(mem_ctx, &tmp_service);
     934             :         }
     935             : 
     936           0 : done:
     937        4287 :         talloc_free(tmp_ctx);
     938        4287 :         return err;
     939             : }
     940             : 
     941             : /**
     942             :  * delete a service from configuration
     943             :  */
     944          18 : static sbcErr smbconf_reg_delete_share(struct smbconf_ctx *ctx,
     945             :                                        const char *servicename)
     946             : {
     947           1 :         WERROR werr;
     948          18 :         sbcErr err = SBC_ERR_OK;
     949          18 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
     950             : 
     951          18 :         if (servicename != NULL) {
     952          18 :                 werr = reg_deletekey_recursive(rpd(ctx)->base_key, servicename);
     953          18 :                 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          18 :         talloc_free(mem_ctx);
     961          18 :         return err;
     962             : }
     963             : 
     964             : /**
     965             :  * set a configuration parameter to the value provided.
     966             :  */
     967        2890 : static sbcErr smbconf_reg_set_parameter(struct smbconf_ctx *ctx,
     968             :                                         const char *service,
     969             :                                         const char *param,
     970             :                                         const char *valstr)
     971             : {
     972          21 :         sbcErr err;
     973        2890 :         struct registry_key *key = NULL;
     974        2890 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
     975             : 
     976        2890 :         err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
     977             :                                            REG_KEY_WRITE, &key);
     978        2890 :         if (!SBC_ERROR_IS_OK(err)) {
     979           0 :                 goto done;
     980             :         }
     981             : 
     982        2890 :         err = smbconf_reg_set_value(key, param, valstr);
     983             : 
     984        2890 : done:
     985        2890 :         talloc_free(mem_ctx);
     986        2890 :         return err;
     987             : }
     988             : 
     989             : /**
     990             :  * get the value of a configuration parameter as a string
     991             :  */
     992           6 : 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           0 :         WERROR werr;
     999           0 :         sbcErr err;
    1000           6 :         struct registry_key *key = NULL;
    1001           6 :         struct registry_value *value = NULL;
    1002             : 
    1003           6 :         err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
    1004             :                                            REG_KEY_READ, &key);
    1005           6 :         if (!SBC_ERROR_IS_OK(err)) {
    1006           0 :                 goto done;
    1007             :         }
    1008             : 
    1009           6 :         if (!smbconf_reg_parameter_is_valid(param)) {
    1010           0 :                 err = SBC_ERR_INVALID_PARAM;
    1011           0 :                 goto done;
    1012             :         }
    1013             : 
    1014           6 :         if (!smbconf_value_exists(key, param)) {
    1015           0 :                 err = SBC_ERR_INVALID_PARAM;
    1016           0 :                 goto done;
    1017             :         }
    1018             : 
    1019           6 :         werr = reg_queryvalue(mem_ctx, key, param, &value);
    1020           6 :         if (!W_ERROR_IS_OK(werr)) {
    1021           0 :                 err = SBC_ERR_NOMEM;
    1022           0 :                 goto done;
    1023             :         }
    1024             : 
    1025           6 :         *valstr = smbconf_format_registry_value(mem_ctx, value);
    1026           6 :         if (*valstr == NULL) {
    1027           0 :                 err = SBC_ERR_NOMEM;
    1028             :         }
    1029             : 
    1030           6 : done:
    1031           6 :         talloc_free(key);
    1032           6 :         talloc_free(value);
    1033           6 :         return err;
    1034             : }
    1035             : 
    1036             : /**
    1037             :  * delete a parameter from configuration
    1038             :  */
    1039           7 : static sbcErr smbconf_reg_delete_parameter(struct smbconf_ctx *ctx,
    1040             :                                            const char *service,
    1041             :                                            const char *param)
    1042             : {
    1043           7 :         struct registry_key *key = NULL;
    1044           3 :         WERROR werr;
    1045           3 :         sbcErr err;
    1046           7 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
    1047             : 
    1048           7 :         err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
    1049             :                                            REG_KEY_ALL, &key);
    1050           7 :         if (!SBC_ERROR_IS_OK(err)) {
    1051           2 :                 goto done;
    1052             :         }
    1053             : 
    1054           5 :         if (!smbconf_reg_parameter_is_valid(param)) {
    1055           0 :                 err = SBC_ERR_INVALID_PARAM;
    1056           0 :                 goto done;
    1057             :         }
    1058             : 
    1059           5 :         if (!smbconf_value_exists(key, param)) {
    1060           0 :                 err = SBC_ERR_OK;
    1061           0 :                 goto done;
    1062             :         }
    1063             : 
    1064           5 :         werr = reg_deletevalue(key, param);
    1065           5 :         if (!W_ERROR_IS_OK(werr)) {
    1066           0 :                 err = SBC_ERR_ACCESS_DENIED;
    1067             :         }
    1068             : 
    1069           5 : done:
    1070           7 :         talloc_free(mem_ctx);
    1071           7 :         return err;
    1072             : }
    1073             : 
    1074           8 : 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           0 :         sbcErr err;
    1081           8 :         struct registry_key *key = NULL;
    1082           8 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1083             : 
    1084           8 :         err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
    1085             :                                            REG_KEY_READ, &key);
    1086           8 :         if (!SBC_ERROR_IS_OK(err)) {
    1087           0 :                 goto done;
    1088             :         }
    1089             : 
    1090           8 :         err = smbconf_reg_get_includes_internal(mem_ctx, key, num_includes,
    1091             :                                                  includes);
    1092           8 :         if (!SBC_ERROR_IS_OK(err)) {
    1093           0 :                 goto done;
    1094             :         }
    1095             : 
    1096           8 : done:
    1097           8 :         talloc_free(tmp_ctx);
    1098           8 :         return err;
    1099             : }
    1100             : 
    1101         437 : 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           5 :         sbcErr err;
    1107         437 :         struct registry_key *key = NULL;
    1108         437 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1109             : 
    1110         437 :         err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
    1111             :                                            REG_KEY_ALL, &key);
    1112         437 :         if (!SBC_ERROR_IS_OK(err)) {
    1113           0 :                 goto done;
    1114             :         }
    1115             : 
    1116         437 :         if (num_includes == 0) {
    1117           5 :                 WERROR werr;
    1118         431 :                 if (!smbconf_value_exists(key, INCLUDES_VALNAME)) {
    1119         431 :                         err = SBC_ERR_OK;
    1120         431 :                         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           6 :                 err = smbconf_reg_set_multi_sz_value(key, INCLUDES_VALNAME,
    1129             :                                                       num_includes, includes);
    1130             :         }
    1131             : 
    1132         437 : done:
    1133         437 :         talloc_free(tmp_ctx);
    1134         437 :         return err;
    1135             : }
    1136             : 
    1137          10 : static sbcErr smbconf_reg_delete_includes(struct smbconf_ctx *ctx,
    1138             :                                           const char *service)
    1139             : {
    1140           0 :         WERROR werr;
    1141           0 :         sbcErr err;
    1142          10 :         struct registry_key *key = NULL;
    1143          10 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1144             : 
    1145          10 :         err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
    1146             :                                            REG_KEY_ALL, &key);
    1147          10 :         if (!SBC_ERROR_IS_OK(err)) {
    1148           2 :                 goto done;
    1149             :         }
    1150             : 
    1151           8 :         if (!smbconf_value_exists(key, INCLUDES_VALNAME)) {
    1152           4 :                 err = SBC_ERR_OK;
    1153           4 :                 goto done;
    1154             :         }
    1155             : 
    1156           4 :         werr = reg_deletevalue(key, INCLUDES_VALNAME);
    1157           4 :         if (!W_ERROR_IS_OK(werr)) {
    1158           0 :                 err = SBC_ERR_ACCESS_DENIED;
    1159           0 :                 goto done;
    1160             :         }
    1161             : 
    1162           4 :         err = SBC_ERR_OK;
    1163          10 : done:
    1164          10 :         talloc_free(tmp_ctx);
    1165          10 :         return err;
    1166             : }
    1167             : 
    1168         711 : static sbcErr smbconf_reg_transaction_start(struct smbconf_ctx *ctx)
    1169             : {
    1170           9 :         WERROR werr;
    1171             : 
    1172         711 :         werr = regdb_transaction_start();
    1173         711 :         if (!W_ERROR_IS_OK(werr)) {
    1174           0 :                 return SBC_ERR_IO_FAILURE;
    1175             :         }
    1176             : 
    1177         702 :         return SBC_ERR_OK;
    1178             : }
    1179             : 
    1180         709 : static sbcErr smbconf_reg_transaction_commit(struct smbconf_ctx *ctx)
    1181             : {
    1182           7 :         WERROR werr;
    1183             : 
    1184         709 :         werr = regdb_transaction_commit();
    1185         709 :         if (!W_ERROR_IS_OK(werr)) {
    1186           0 :                 return SBC_ERR_IO_FAILURE;
    1187             :         }
    1188             : 
    1189         702 :         return SBC_ERR_OK;
    1190             : }
    1191             : 
    1192           2 : static sbcErr smbconf_reg_transaction_cancel(struct smbconf_ctx *ctx)
    1193             : {
    1194           2 :         WERROR werr;
    1195             : 
    1196           2 :         werr = regdb_transaction_cancel();
    1197           2 :         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        1041 : 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        1041 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1243        1041 :         sbcErr err = smbconf_init_internal(mem_ctx, conf_ctx, path, &smbconf_ops_reg);
    1244        1041 :         talloc_free(tmp_ctx);
    1245        1041 :         return err;
    1246             : }

Generated by: LCOV version 1.14