LCOV - code coverage report
Current view: top level - lib/param - loadparm.c (source / functions) Hit Total Coverage
Test: coverage report for recycleplus df22b230 Lines: 1315 1624 81.0 %
Date: 2024-02-14 10:14:15 Functions: 106 117 90.6 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Parameter loading functions
       4             :    Copyright (C) Karl Auer 1993-1998
       5             : 
       6             :    Largely re-written by Andrew Tridgell, September 1994
       7             : 
       8             :    Copyright (C) Simo Sorce 2001
       9             :    Copyright (C) Alexander Bokovoy 2002
      10             :    Copyright (C) Stefan (metze) Metzmacher 2002
      11             :    Copyright (C) Jim McDonough (jmcd@us.ibm.com)  2003.
      12             :    Copyright (C) James Myers 2003 <myersjj@samba.org>
      13             :    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
      14             :    Copyright (C) Andrew Bartlett 2011-2012
      15             : 
      16             :    This program is free software; you can redistribute it and/or modify
      17             :    it under the terms of the GNU General Public License as published by
      18             :    the Free Software Foundation; either version 3 of the License, or
      19             :    (at your option) any later version.
      20             : 
      21             :    This program is distributed in the hope that it will be useful,
      22             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      23             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      24             :    GNU General Public License for more details.
      25             : 
      26             :    You should have received a copy of the GNU General Public License
      27             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      28             : */
      29             : 
      30             : /*
      31             :  *  Load parameters.
      32             :  *
      33             :  *  This module provides suitable callback functions for the params
      34             :  *  module. It builds the internal table of service details which is
      35             :  *  then used by the rest of the server.
      36             :  *
      37             :  * To add a parameter:
      38             :  *
      39             :  * 1) add it to the global or service structure definition
      40             :  * 2) add it to the parm_table
      41             :  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
      42             :  * 4) If it's a global then initialise it in init_globals. If a local
      43             :  *    (ie. service) parameter then initialise it in the sDefault structure
      44             :  *
      45             :  *
      46             :  * Notes:
      47             :  *   The configuration file is processed sequentially for speed. It is NOT
      48             :  *   accessed randomly as happens in 'real' Windows. For this reason, there
      49             :  *   is a fair bit of sequence-dependent code here - ie., code which assumes
      50             :  *   that certain things happen before others. In particular, the code which
      51             :  *   happens at the boundary between sections is delicately poised, so be
      52             :  *   careful!
      53             :  *
      54             :  */
      55             : 
      56             : #include "includes.h"
      57             : #include "version.h"
      58             : #include "dynconfig/dynconfig.h"
      59             : #include "system/time.h"
      60             : #include "system/locale.h"
      61             : #include "system/network.h" /* needed for TCP_NODELAY */
      62             : #include "../lib/util/dlinklist.h"
      63             : #include "lib/param/param.h"
      64             : #define LOADPARM_SUBSTITUTION_INTERNALS 1
      65             : #include "lib/param/loadparm.h"
      66             : #include "auth/gensec/gensec.h"
      67             : #include "lib/param/s3_param.h"
      68             : #include "lib/util/bitmap.h"
      69             : #include "libcli/smb/smb_constants.h"
      70             : #include "tdb.h"
      71             : #include "librpc/gen_ndr/nbt.h"
      72             : #include "librpc/gen_ndr/dns.h"
      73             : #include "librpc/gen_ndr/security.h"
      74             : #include "libds/common/roles.h"
      75             : #include "lib/util/samba_util.h"
      76             : #include "libcli/auth/ntlm_check.h"
      77             : #include "lib/crypto/gnutls_helpers.h"
      78             : #include "lib/util/smb_strtox.h"
      79             : #include "auth/credentials/credentials.h"
      80             : 
      81             : #ifdef HAVE_HTTPCONNECTENCRYPT
      82             : #include <cups/http.h>
      83             : #endif
      84             : 
      85             : #define standard_sub_basic talloc_strdup
      86             : 
      87             : #include "lib/param/param_global.h"
      88             : 
      89      230559 : struct loadparm_service *lpcfg_default_service(struct loadparm_context *lp_ctx)
      90             : {
      91      230559 :         return lp_ctx->sDefault;
      92             : }
      93             : 
      94          58 : int lpcfg_rpc_low_port(struct loadparm_context *lp_ctx)
      95             : {
      96          58 :         return lp_ctx->globals->rpc_low_port;
      97             : }
      98             : 
      99          58 : int lpcfg_rpc_high_port(struct loadparm_context *lp_ctx)
     100             : {
     101          58 :         return lp_ctx->globals->rpc_high_port;
     102             : }
     103             : 
     104      433109 : enum samba_weak_crypto lpcfg_weak_crypto(struct loadparm_context *lp_ctx)
     105             : {
     106      433109 :         if (lp_ctx->globals->weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) {
     107        8929 :                 lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED;
     108             : 
     109        8929 :                 if (samba_gnutls_weak_crypto_allowed()) {
     110        8929 :                         lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED;
     111             :                 }
     112             :         }
     113             : 
     114      433109 :         return lp_ctx->globals->weak_crypto;
     115             : }
     116             : 
     117             : /**
     118             :  * Convenience routine to grab string parameters into temporary memory
     119             :  * and run standard_sub_basic on them.
     120             :  *
     121             :  * The buffers can be written to by
     122             :  * callers without affecting the source string.
     123             :  */
     124             : 
     125     7141273 : static const char *lpcfg_string(const char *s)
     126             : {
     127             : #if 0  /* until REWRITE done to make thread-safe */
     128             :         size_t len = s ? strlen(s) : 0;
     129             :         char *ret;
     130             : #endif
     131             : 
     132             :         /* The follow debug is useful for tracking down memory problems
     133             :            especially if you have an inner loop that is calling a lp_*()
     134             :            function that returns a string.  Perhaps this debug should be
     135             :            present all the time? */
     136             : 
     137             : #if 0
     138             :         DEBUG(10, ("lpcfg_string(%s)\n", s));
     139             : #endif
     140             : 
     141             : #if 0  /* until REWRITE done to make thread-safe */
     142             :         if (!lp_talloc)
     143             :                 lp_talloc = talloc_init("lp_talloc");
     144             : 
     145             :         ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
     146             : 
     147             :         if (!ret)
     148             :                 return NULL;
     149             : 
     150             :         if (!s)
     151             :                 *ret = 0;
     152             :         else
     153             :                 strlcpy(ret, s, len);
     154             : 
     155             :         if (trim_string(ret, "\"", "\"")) {
     156             :                 if (strchr(ret,'"') != NULL)
     157             :                         strlcpy(ret, s, len);
     158             :         }
     159             : 
     160             :         standard_sub_basic(ret,len+100);
     161             :         return (ret);
     162             : #endif
     163     7141273 :         return s;
     164             : }
     165             : 
     166             : /*
     167             :    In this section all the functions that are used to access the
     168             :    parameters from the rest of the program are defined
     169             : */
     170             : 
     171             : /*
     172             :  * the creation of separate lpcfg_*() and lp_*() functions is to allow
     173             :  * for code compatibility between existing Samba4 and Samba3 code.
     174             :  */
     175             : 
     176             : /* this global context supports the lp_*() function varients */
     177             : static struct loadparm_context *global_loadparm_context;
     178             : 
     179             : #define FN_GLOBAL_SUBSTITUTED_STRING(fn_name,var_name) \
     180             :  _PUBLIC_ char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx, \
     181             :                  const struct loadparm_substitution *lp_sub, TALLOC_CTX *mem_ctx) \
     182             : { \
     183             :          if (lp_ctx == NULL) return NULL;                               \
     184             :          return lpcfg_substituted_string(mem_ctx, lp_sub, \
     185             :                          lp_ctx->globals->var_name ? lp_ctx->globals->var_name : ""); \
     186             : }
     187             : 
     188             : #define FN_GLOBAL_CONST_STRING(fn_name,var_name)                                \
     189             :  _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
     190             :         if (lp_ctx == NULL) return NULL;                                \
     191             :         return lp_ctx->globals->var_name ? lpcfg_string(lp_ctx->globals->var_name) : ""; \
     192             : }
     193             : 
     194             : #define FN_GLOBAL_LIST(fn_name,var_name)                                \
     195             :  _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
     196             :          if (lp_ctx == NULL) return NULL;                               \
     197             :          return lp_ctx->globals->var_name;                                \
     198             :  }
     199             : 
     200             : #define FN_GLOBAL_BOOL(fn_name,var_name) \
     201             :  _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {\
     202             :          if (lp_ctx == NULL) return false;                              \
     203             :          return lp_ctx->globals->var_name;                                \
     204             : }
     205             : 
     206             : #define FN_GLOBAL_INTEGER(fn_name,var_name) \
     207             :  _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
     208             :          return lp_ctx->globals->var_name;                                \
     209             :  }
     210             : 
     211             : /* Local parameters don't need the ->s3_fns because the struct
     212             :  * loadparm_service is shared and lpcfg_service() checks the ->s3_fns
     213             :  * hook */
     214             : #define FN_LOCAL_SUBSTITUTED_STRING(fn_name,val) \
     215             :  _PUBLIC_ char *lpcfg_ ## fn_name(struct loadparm_service *service, \
     216             :                                         struct loadparm_service *sDefault, TALLOC_CTX *ctx) { \
     217             :          return(talloc_strdup(ctx, lpcfg_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val)))); \
     218             :  }
     219             : 
     220             : #define FN_LOCAL_CONST_STRING(fn_name,val) \
     221             :  _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_service *service, \
     222             :                                         struct loadparm_service *sDefault) { \
     223             :          return((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val)); \
     224             :  }
     225             : 
     226             : #define FN_LOCAL_LIST(fn_name,val) \
     227             :  _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_service *service, \
     228             :                                          struct loadparm_service *sDefault) {\
     229             :          return(const char **)(service != NULL && service->val != NULL? service->val : sDefault->val); \
     230             :  }
     231             : 
     232             : #define FN_LOCAL_PARM_BOOL(fn_name, val) FN_LOCAL_BOOL(fn_name, val)
     233             : 
     234             : #define FN_LOCAL_BOOL(fn_name,val) \
     235             :  _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_service *service, \
     236             :                                  struct loadparm_service *sDefault) {   \
     237             :          return((service != NULL)? service->val : sDefault->val); \
     238             :  }
     239             : 
     240             : #define FN_LOCAL_INTEGER(fn_name,val) \
     241             :  _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_service *service, \
     242             :                                 struct loadparm_service *sDefault) {    \
     243             :          return((service != NULL)? service->val : sDefault->val); \
     244             :  }
     245             : 
     246             : #define FN_LOCAL_PARM_INTEGER(fn_name, val) FN_LOCAL_INTEGER(fn_name, val)
     247             : 
     248             : #define FN_LOCAL_CHAR(fn_name,val) \
     249             :  _PUBLIC_ char lpcfg_ ## fn_name(struct loadparm_service *service, \
     250             :                                 struct loadparm_service *sDefault) {    \
     251             :          return((service != NULL)? service->val : sDefault->val); \
     252             :  }
     253             : 
     254             : #define FN_LOCAL_PARM_CHAR(fn_name,val) FN_LOCAL_CHAR(fn_name, val)
     255             : 
     256             : #include "lib/param/param_functions.c"
     257             : 
     258             : /* These functions cannot be auto-generated */
     259           0 : FN_LOCAL_BOOL(autoloaded, autoloaded)
     260     3787380 : FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
     261             : 
     262             : /* local prototypes */
     263             : static struct loadparm_service *lpcfg_getservicebyname(struct loadparm_context *lp_ctx,
     264             :                                         const char *pszServiceName);
     265             : static bool do_section(const char *pszSectionName, void *);
     266             : static bool set_variable_helper(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
     267             :                                 const char *pszParmName, const char *pszParmValue);
     268             : static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx,
     269             :                                        struct loadparm_service *service,
     270             :                                        const char *pszParmName,
     271             :                                        const char *pszParmValue, int flags);
     272             : 
     273             : /* The following are helper functions for parametrical options support. */
     274             : /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
     275             : /* Actual parametrical functions are quite simple */
     276     5024799 : struct parmlist_entry *get_parametric_helper(struct loadparm_service *service,
     277             :                                              const char *type, const char *option,
     278             :                                              struct parmlist_entry *global_opts)
     279     5024799 : {
     280     5024799 :         size_t type_len = strlen(type);
     281     5024799 :         size_t option_len = strlen(option);
     282     5024799 :         char param_key[type_len + option_len + 2];
     283     5024799 :         struct parmlist_entry *data = NULL;
     284             : 
     285     5024799 :         snprintf(param_key, sizeof(param_key), "%s:%s", type, option);
     286             : 
     287             :         /*
     288             :          * Try to fetch the option from the data.
     289             :          */
     290     5024799 :         if (service != NULL) {
     291       96327 :                 data = service->param_opt;
     292      148083 :                 while (data != NULL) {
     293       55746 :                         if (strwicmp(data->key, param_key) == 0) {
     294        3990 :                                 return data;
     295             :                         }
     296       51756 :                         data = data->next;
     297             :                 }
     298             :         }
     299             : 
     300             :         /*
     301             :          * Fall back to fetching from the globals.
     302             :          */
     303     5020809 :         data = global_opts;
     304   156942468 :         while (data != NULL) {
     305   152331470 :                 if (strwicmp(data->key, param_key) == 0) {
     306      409811 :                         return data;
     307             :                 }
     308   151921659 :                 data = data->next;
     309             :         }
     310             : 
     311     4610998 :         return NULL;
     312             : }
     313             : 
     314     4841702 : const char *lpcfg_get_parametric(struct loadparm_context *lp_ctx,
     315             :                               struct loadparm_service *service,
     316             :                               const char *type, const char *option)
     317             : {
     318             :         struct parmlist_entry *data;
     319             : 
     320     4841702 :         if (lp_ctx == NULL)
     321           0 :                 return NULL;
     322             : 
     323     4841702 :         data = get_parametric_helper(service,
     324     4841702 :                                      type, option, lp_ctx->globals->param_opt);
     325             : 
     326     4841702 :         if (data == NULL) {
     327     4452773 :                 return NULL;
     328             :         } else {
     329      388929 :                 return data->value;
     330             :         }
     331             : }
     332             : 
     333             : 
     334             : /**
     335             :  * convenience routine to return int parameters.
     336             :  */
     337      520592 : int lp_int(const char *s)
     338             : {
     339             : 
     340      520592 :         if (!s || !*s) {
     341           0 :                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
     342           0 :                 return -1;
     343             :         }
     344             : 
     345      520592 :         return strtol(s, NULL, 0);
     346             : }
     347             : 
     348             : /**
     349             :  * convenience routine to return unsigned long parameters.
     350             :  */
     351        4018 : unsigned long lp_ulong(const char *s)
     352             : {
     353        4018 :         int error = 0;
     354             :         unsigned long int ret;
     355             : 
     356        4018 :         if (!s || !*s) {
     357           0 :                 DBG_DEBUG("lp_ulong(%s): is called with NULL!\n",s);
     358           0 :                 return -1;
     359             :         }
     360             : 
     361        4018 :         ret = smb_strtoul(s, NULL, 0, &error, SMB_STR_STANDARD);
     362        4018 :         if (error != 0) {
     363           0 :                 DBG_DEBUG("lp_ulong(%s): conversion failed\n",s);
     364           0 :                 return -1;
     365             :         }
     366             : 
     367        4018 :         return ret;
     368             : }
     369             : 
     370             : /**
     371             :  * convenience routine to return unsigned long long parameters.
     372             :  */
     373           0 : unsigned long long lp_ulonglong(const char *s)
     374             : {
     375           0 :         int error = 0;
     376             :         unsigned long long int ret;
     377             : 
     378           0 :         if (!s || !*s) {
     379           0 :                 DBG_DEBUG("lp_ulonglong(%s): is called with NULL!\n", s);
     380           0 :                 return -1;
     381             :         }
     382             : 
     383           0 :         ret = smb_strtoull(s, NULL, 0, &error, SMB_STR_STANDARD);
     384           0 :         if (error != 0) {
     385           0 :                 DBG_DEBUG("lp_ulonglong(%s): conversion failed\n",s);
     386           0 :                 return -1;
     387             :         }
     388             : 
     389           0 :         return ret;
     390             : }
     391             : 
     392             : /**
     393             :  * convenience routine to return unsigned long parameters.
     394             :  */
     395           0 : static long lp_long(const char *s)
     396             : {
     397             : 
     398           0 :         if (!s) {
     399           0 :                 DEBUG(0,("lp_long(%s): is called with NULL!\n",s));
     400           0 :                 return -1;
     401             :         }
     402             : 
     403           0 :         return strtol(s, NULL, 0);
     404             : }
     405             : 
     406             : /**
     407             :  * convenience routine to return unsigned long parameters.
     408             :  */
     409           0 : static double lp_double(const char *s)
     410             : {
     411             : 
     412           0 :         if (!s) {
     413           0 :                 DEBUG(0,("lp_double(%s): is called with NULL!\n",s));
     414           0 :                 return -1;
     415             :         }
     416             : 
     417           0 :         return strtod(s, NULL);
     418             : }
     419             : 
     420             : /**
     421             :  * convenience routine to return boolean parameters.
     422             :  */
     423      298917 : bool lp_bool(const char *s)
     424             : {
     425      298917 :         bool ret = false;
     426             : 
     427      298917 :         if (!s || !*s) {
     428          14 :                 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
     429          14 :                 return false;
     430             :         }
     431             : 
     432      298903 :         if (!set_boolean(s, &ret)) {
     433           0 :                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
     434           0 :                 return false;
     435             :         }
     436             : 
     437      298903 :         return ret;
     438             : }
     439             : 
     440             : /**
     441             :  * Return parametric option from a given service. Type is a part of option before ':'
     442             :  * Parametric option has following syntax: 'Type: option = value'
     443             :  * Returned value is allocated in 'lp_talloc' context
     444             :  */
     445             : 
     446      515223 : const char *lpcfg_parm_string(struct loadparm_context *lp_ctx,
     447             :                               struct loadparm_service *service, const char *type,
     448             :                               const char *option)
     449             : {
     450      515223 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     451             : 
     452      515223 :         if (value)
     453       33564 :                 return lpcfg_string(value);
     454             : 
     455      481659 :         return NULL;
     456             : }
     457             : 
     458             : /**
     459             :  * Return parametric option from a given service. Type is a part of option before ':'
     460             :  * Parametric option has following syntax: 'Type: option = value'
     461             :  * Returned value is allocated in 'lp_talloc' context
     462             :  */
     463             : 
     464           0 : const char **lpcfg_parm_string_list(TALLOC_CTX *mem_ctx,
     465             :                                     struct loadparm_context *lp_ctx,
     466             :                                     struct loadparm_service *service,
     467             :                                     const char *type,
     468             :                                     const char *option, const char *separator)
     469             : {
     470           0 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     471             : 
     472           0 :         if (value != NULL) {
     473           0 :                 char **l = str_list_make(mem_ctx, value, separator);
     474           0 :                 return discard_const_p(const char *, l);
     475             :         }
     476             : 
     477           0 :         return NULL;
     478             : }
     479             : 
     480             : /**
     481             :  * Return parametric option from a given service. Type is a part of option before ':'
     482             :  * Parametric option has following syntax: 'Type: option = value'
     483             :  */
     484             : 
     485      481957 : int lpcfg_parm_int(struct loadparm_context *lp_ctx,
     486             :                    struct loadparm_service *service, const char *type,
     487             :                    const char *option, int default_v)
     488             : {
     489      481957 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     490             : 
     491      481957 :         if (value)
     492       41009 :                 return lp_int(value);
     493             : 
     494      440948 :         return default_v;
     495             : }
     496             : 
     497             : /**
     498             :  * Return parametric option from a given service. Type is a part of
     499             :  * option before ':'.
     500             :  * Parametric option has following syntax: 'Type: option = value'.
     501             :  */
     502             : 
     503           0 : int lpcfg_parm_bytes(struct loadparm_context *lp_ctx,
     504             :                   struct loadparm_service *service, const char *type,
     505             :                   const char *option, int default_v)
     506             : {
     507             :         uint64_t bval;
     508             : 
     509           0 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     510             : 
     511           0 :         if (value && conv_str_size_error(value, &bval)) {
     512           0 :                 if (bval <= INT_MAX) {
     513           0 :                         return (int)bval;
     514             :                 }
     515             :         }
     516             : 
     517           0 :         return default_v;
     518             : }
     519             : 
     520             : /**
     521             :  * Return parametric option from a given service.
     522             :  * Type is a part of option before ':'
     523             :  * Parametric option has following syntax: 'Type: option = value'
     524             :  */
     525       22078 : unsigned long lpcfg_parm_ulong(struct loadparm_context *lp_ctx,
     526             :                             struct loadparm_service *service, const char *type,
     527             :                             const char *option, unsigned long default_v)
     528             : {
     529       22078 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     530             : 
     531       22078 :         if (value)
     532        4018 :                 return lp_ulong(value);
     533             : 
     534       18060 :         return default_v;
     535             : }
     536             : 
     537             : /**
     538             :  * Return parametric option from a given service.
     539             :  * Type is a part of option before ':'
     540             :  * Parametric option has following syntax: 'Type: option = value'
     541             :  */
     542           0 : unsigned long long lpcfg_parm_ulonglong(struct loadparm_context *lp_ctx,
     543             :                                         struct loadparm_service *service,
     544             :                                         const char *type, const char *option,
     545             :                                         unsigned long long default_v)
     546             : {
     547           0 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     548             : 
     549           0 :         if (value) {
     550           0 :                 return lp_ulonglong(value);
     551             :         }
     552             : 
     553           0 :         return default_v;
     554             : }
     555             : 
     556         513 : long lpcfg_parm_long(struct loadparm_context *lp_ctx,
     557             :                      struct loadparm_service *service, const char *type,
     558             :                      const char *option, long default_v)
     559             : {
     560         513 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     561             : 
     562         513 :         if (value)
     563           0 :                 return lp_long(value);
     564             : 
     565         513 :         return default_v;
     566             : }
     567             : 
     568           0 : double lpcfg_parm_double(struct loadparm_context *lp_ctx,
     569             :                       struct loadparm_service *service, const char *type,
     570             :                       const char *option, double default_v)
     571             : {
     572           0 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     573             : 
     574           0 :         if (value != NULL)
     575           0 :                 return lp_double(value);
     576             : 
     577           0 :         return default_v;
     578             : }
     579             : 
     580             : /**
     581             :  * Return parametric option from a given service. Type is a part of option before ':'
     582             :  * Parametric option has following syntax: 'Type: option = value'
     583             :  */
     584             : 
     585     3790162 : bool lpcfg_parm_bool(struct loadparm_context *lp_ctx,
     586             :                      struct loadparm_service *service, const char *type,
     587             :                      const char *option, bool default_v)
     588             : {
     589     3790162 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     590             : 
     591     3790162 :         if (value != NULL)
     592      281063 :                 return lp_bool(value);
     593             : 
     594     3509099 :         return default_v;
     595             : }
     596             : 
     597             : 
     598             : /* this is used to prevent lots of mallocs of size 1 */
     599             : static const char lpcfg_string_empty[] = "";
     600             : 
     601             : /**
     602             :  Free a string value.
     603             : **/
     604    14925247 : void lpcfg_string_free(char **s)
     605             : {
     606    14925247 :         if (s == NULL) {
     607           0 :                 return;
     608             :         }
     609    14925247 :         if (*s == lpcfg_string_empty) {
     610     4640140 :                 *s = NULL;
     611     4640140 :                 return;
     612             :         }
     613    10285107 :         TALLOC_FREE(*s);
     614             : }
     615             : 
     616             : /**
     617             :  * Set a string value, deallocating any existing space, and allocing the space
     618             :  * for the string
     619             :  */
     620    12681109 : bool lpcfg_string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
     621             : {
     622    12681109 :         lpcfg_string_free(dest);
     623             : 
     624    12681109 :         if ((src == NULL) || (*src == '\0')) {
     625     7445605 :                 *dest = discard_const_p(char, lpcfg_string_empty);
     626     7445605 :                 return true;
     627             :         }
     628             : 
     629     5235504 :         *dest = talloc_strdup(mem_ctx, src);
     630     5235504 :         if ((*dest) == NULL) {
     631           0 :                 DEBUG(0,("Out of memory in string_set\n"));
     632           0 :                 return false;
     633             :         }
     634             : 
     635     5235504 :         return true;
     636             : }
     637             : 
     638             : /**
     639             :  * Set a string value, deallocating any existing space, and allocing the space
     640             :  * for the string
     641             :  */
     642       67020 : bool lpcfg_string_set_upper(TALLOC_CTX *mem_ctx, char **dest, const char *src)
     643             : {
     644       67020 :         lpcfg_string_free(dest);
     645             : 
     646       67020 :         if ((src == NULL) || (*src == '\0')) {
     647           6 :                 *dest = discard_const_p(char, lpcfg_string_empty);
     648           6 :                 return true;
     649             :         }
     650             : 
     651       67014 :         *dest = strupper_talloc(mem_ctx, src);
     652       67014 :         if ((*dest) == NULL) {
     653           0 :                 DEBUG(0,("Out of memory in string_set_upper\n"));
     654           0 :                 return false;
     655             :         }
     656             : 
     657       67014 :         return true;
     658             : }
     659             : 
     660             : 
     661             : 
     662             : /**
     663             :  * Add a new service to the services array initialising it with the given
     664             :  * service.
     665             :  */
     666             : 
     667      132332 : struct loadparm_service *lpcfg_add_service(struct loadparm_context *lp_ctx,
     668             :                                            const struct loadparm_service *pservice,
     669             :                                            const char *name)
     670             : {
     671             :         int i;
     672      132332 :         int num_to_alloc = lp_ctx->iNumServices + 1;
     673             :         struct parmlist_entry *data, *pdata;
     674             : 
     675      132332 :         if (lp_ctx->s3_fns != NULL) {
     676           0 :                 smb_panic("Add a service should not be called on an s3 loadparm ctx");
     677             :         }
     678             : 
     679      132332 :         if (pservice == NULL) {
     680          57 :                 pservice = lp_ctx->sDefault;
     681             :         }
     682             : 
     683             :         /* it might already exist */
     684      132332 :         if (name) {
     685      132332 :                 struct loadparm_service *service = lpcfg_getservicebyname(lp_ctx,
     686             :                                                                     name);
     687      132332 :                 if (service != NULL) {
     688             :                         /* Clean all parametric options for service */
     689             :                         /* They will be added during parsing again */
     690       74454 :                         data = service->param_opt;
     691      210121 :                         while (data) {
     692      135667 :                                 pdata = data->next;
     693      135667 :                                 talloc_free(data);
     694      135667 :                                 data = pdata;
     695             :                         }
     696       74454 :                         service->param_opt = NULL;
     697       74454 :                         return service;
     698             :                 }
     699             :         }
     700             : 
     701             :         /* find an invalid one */
     702      811923 :         for (i = 0; i < lp_ctx->iNumServices; i++)
     703      754045 :                 if (lp_ctx->services[i] == NULL)
     704           0 :                         break;
     705             : 
     706             :         /* if not, then create one */
     707       57878 :         if (i == lp_ctx->iNumServices) {
     708             :                 struct loadparm_service **tsp;
     709             : 
     710       57878 :                 tsp = talloc_realloc(lp_ctx, lp_ctx->services, struct loadparm_service *, num_to_alloc);
     711             : 
     712       57878 :                 if (!tsp) {
     713           0 :                         DEBUG(0,("lpcfg_add_service: failed to enlarge services!\n"));
     714           0 :                         return NULL;
     715             :                 } else {
     716       57878 :                         lp_ctx->services = tsp;
     717       57878 :                         lp_ctx->services[lp_ctx->iNumServices] = NULL;
     718             :                 }
     719             : 
     720       57878 :                 lp_ctx->iNumServices++;
     721             :         }
     722             : 
     723       57878 :         lp_ctx->services[i] = talloc_zero(lp_ctx->services, struct loadparm_service);
     724       57878 :         if (lp_ctx->services[i] == NULL) {
     725           0 :                 DEBUG(0,("lpcfg_add_service: out of memory!\n"));
     726           0 :                 return NULL;
     727             :         }
     728       57878 :         copy_service(lp_ctx->services[i], pservice, NULL);
     729       57878 :         if (name != NULL)
     730       57878 :                 lpcfg_string_set(lp_ctx->services[i], &lp_ctx->services[i]->szService, name);
     731       57878 :         return lp_ctx->services[i];
     732             : }
     733             : 
     734             : /**
     735             :  * Map a parameter's string representation to something we can use.
     736             :  * Returns False if the parameter string is not recognised, else TRUE.
     737             :  */
     738             : 
     739     5313106 : int lpcfg_map_parameter(const char *pszParmName)
     740             : {
     741             :         int iIndex;
     742             : 
     743  1712743508 :         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
     744  1711852238 :                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
     745     4421836 :                         return iIndex;
     746             : 
     747             :         /* Warn only if it isn't parametric option */
     748      891270 :         if (strchr(pszParmName, ':') == NULL)
     749           0 :                 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
     750             :         /* We do return 'fail' for parametric options as well because they are
     751             :            stored in different storage
     752             :          */
     753      891270 :         return -1;
     754             : }
     755             : 
     756             : 
     757             : /**
     758             :   return the parameter structure for a parameter
     759             : */
     760       25193 : struct parm_struct *lpcfg_parm_struct(struct loadparm_context *lp_ctx, const char *name)
     761             : {
     762       25193 :         int num = lpcfg_map_parameter(name);
     763             : 
     764       25193 :         if (num < 0) {
     765           0 :                 return NULL;
     766             :         }
     767             : 
     768       25193 :         return &parm_table[num];
     769             : }
     770             : 
     771             : /**
     772             :   return the parameter pointer for a parameter
     773             : */
     774     3172906 : void *lpcfg_parm_ptr(struct loadparm_context *lp_ctx,
     775             :                   struct loadparm_service *service, struct parm_struct *parm)
     776             : {
     777     3172906 :         if (lp_ctx->s3_fns) {
     778      402740 :                 return lp_ctx->s3_fns->get_parm_ptr(service, parm);
     779             :         }
     780             : 
     781     2770166 :         if (service == NULL) {
     782     2766244 :                 if (parm->p_class == P_LOCAL)
     783      354323 :                         return ((char *)lp_ctx->sDefault)+parm->offset;
     784     2411921 :                 else if (parm->p_class == P_GLOBAL)
     785     2411921 :                         return ((char *)lp_ctx->globals)+parm->offset;
     786           0 :                 else return NULL;
     787             :         } else {
     788        3922 :                 return ((char *)service) + parm->offset;
     789             :         }
     790             : }
     791             : 
     792             : /**
     793             :   return the parameter pointer for a parameter
     794             : */
     795      310393 : bool lpcfg_parm_is_cmdline(struct loadparm_context *lp_ctx, const char *name)
     796             : {
     797             :         int parmnum;
     798             : 
     799      310393 :         parmnum = lpcfg_map_parameter(name);
     800      310393 :         if (parmnum == -1) return false;
     801             : 
     802      310393 :         return lp_ctx->flags[parmnum] & FLAG_CMDLINE;
     803             : }
     804             : 
     805           0 : bool lpcfg_parm_is_unspecified(struct loadparm_context *lp_ctx, const char *name)
     806             : {
     807             :         int parmnum;
     808             : 
     809           0 :         parmnum = lpcfg_map_parameter(name);
     810           0 :         if (parmnum == -1) return false;
     811             : 
     812           0 :         return lp_ctx->flags[parmnum] & FLAG_DEFAULT;
     813             : }
     814             : 
     815             : /**
     816             :  * Find a service by name. Otherwise works like get_service.
     817             :  */
     818             : 
     819      227263 : static struct loadparm_service *lpcfg_getservicebyname(struct loadparm_context *lp_ctx,
     820             :                                         const char *pszServiceName)
     821             : {
     822             :         int iService;
     823             : 
     824      227263 :         if (lp_ctx->s3_fns) {
     825       57913 :                 return lp_ctx->s3_fns->get_service(pszServiceName);
     826             :         }
     827             : 
     828     2451967 :         for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--)
     829     4788176 :                 if (lp_ctx->services[iService] != NULL &&
     830     2394088 :                     strwicmp(lp_ctx->services[iService]->szService, pszServiceName) == 0) {
     831      111471 :                         return lp_ctx->services[iService];
     832             :                 }
     833             : 
     834       57879 :         return NULL;
     835             : }
     836             : 
     837             : /**
     838             :  * Add a parametric option to a parmlist_entry,
     839             :  * replacing old value, if already present.
     840             :  */
     841      973128 : void set_param_opt(TALLOC_CTX *mem_ctx,
     842             :                    struct parmlist_entry **opt_list,
     843             :                    const char *opt_name,
     844             :                    const char *opt_value,
     845             :                    unsigned priority)
     846             : {
     847             :         struct parmlist_entry *new_opt, *opt;
     848             : 
     849      973128 :         opt = *opt_list;
     850             : 
     851             :         /* Traverse destination */
     852    10604680 :         while (opt) {
     853             :                 /* If we already have same option, override it */
     854     9864436 :                 if (strwicmp(opt->key, opt_name) == 0) {
     855      232884 :                         if ((opt->priority & FLAG_CMDLINE) &&
     856        5081 :                             !(priority & FLAG_CMDLINE)) {
     857             :                                 /* it's been marked as not to be
     858             :                                    overridden */
     859         135 :                                 return;
     860             :                         }
     861      232749 :                         TALLOC_FREE(opt->list);
     862      232749 :                         lpcfg_string_set(opt, &opt->value, opt_value);
     863      232749 :                         opt->priority = priority;
     864      232749 :                         return;
     865             :                 }
     866     9631552 :                 opt = opt->next;
     867             :         }
     868             : 
     869      740244 :         new_opt = talloc_pooled_object(
     870             :                 mem_ctx, struct parmlist_entry,
     871             :                 2, strlen(opt_name) + 1 + strlen(opt_value) + 1);
     872      740244 :         if (new_opt == NULL) {
     873           0 :                 smb_panic("OOM");
     874             :         }
     875      740244 :         new_opt->key = NULL;
     876      740244 :         lpcfg_string_set(new_opt, &new_opt->key, opt_name);
     877      740244 :         new_opt->value = NULL;
     878      740244 :         lpcfg_string_set(new_opt, &new_opt->value, opt_value);
     879             : 
     880      740244 :         new_opt->list = NULL;
     881      740244 :         new_opt->priority = priority;
     882      740244 :         DLIST_ADD(*opt_list, new_opt);
     883             : }
     884             : 
     885             : /**
     886             :  * Copy a service structure to another.
     887             :  * If pcopymapDest is NULL then copy all fields
     888             :  */
     889             : 
     890      191996 : void copy_service(struct loadparm_service *pserviceDest,
     891             :                   const struct loadparm_service *pserviceSource,
     892             :                   struct bitmap *pcopymapDest)
     893             : {
     894             :         int i;
     895      191996 :         bool bcopyall = (pcopymapDest == NULL);
     896             :         struct parmlist_entry *data;
     897             : 
     898    99453928 :         for (i = 0; parm_table[i].label; i++)
     899    99261932 :                 if (parm_table[i].p_class == P_LOCAL &&
     900    14903853 :                     (bcopyall || bitmap_query(pcopymapDest, i))) {
     901    29949122 :                         const void *src_ptr =
     902    29949122 :                                 ((const char *)pserviceSource) + parm_table[i].offset;
     903    29949122 :                         void *dest_ptr =
     904    29949122 :                                 ((char *)pserviceDest) + parm_table[i].offset;
     905             : 
     906    29949122 :                         switch (parm_table[i].type) {
     907    14550078 :                                 case P_BOOL:
     908             :                                 case P_BOOLREV:
     909    14550078 :                                         *(bool *)dest_ptr = *(const bool *)src_ptr;
     910    14550078 :                                         break;
     911             : 
     912     6130341 :                                 case P_INTEGER:
     913             :                                 case P_BYTES:
     914             :                                 case P_OCTAL:
     915             :                                 case P_ENUM:
     916     6130341 :                                         *(int *)dest_ptr = *(const int *)src_ptr;
     917     6130341 :                                         break;
     918             : 
     919      191996 :                                 case P_CHAR:
     920      191996 :                                         *(char *)dest_ptr = *(const char *)src_ptr;
     921      191996 :                                         break;
     922             : 
     923     6612539 :                                 case P_STRING:
     924     6612539 :                                         lpcfg_string_set(pserviceDest,
     925             :                                                    (char **)dest_ptr,
     926             :                                                    *(const char * const *)src_ptr);
     927     6612539 :                                         break;
     928             : 
     929           0 :                                 case P_USTRING:
     930           0 :                                         lpcfg_string_set_upper(pserviceDest,
     931             :                                                          (char **)dest_ptr,
     932             :                                                          *(const char * const *)src_ptr);
     933           0 :                                         break;
     934     2464168 :                                 case P_CMDLIST:
     935             :                                 case P_LIST:
     936     2464168 :                                         TALLOC_FREE(*((char ***)dest_ptr));
     937     2464168 :                                         *(char ***)dest_ptr = str_list_copy(pserviceDest,
     938             :                                                                             *discard_const_p(const char **, src_ptr));
     939     2464168 :                                         break;
     940           0 :                                 default:
     941           0 :                                         break;
     942             :                         }
     943             :                 }
     944             : 
     945      191996 :         if (bcopyall) {
     946       97067 :                 init_copymap(pserviceDest);
     947       97067 :                 if (pserviceSource->copymap)
     948           2 :                         bitmap_copy(pserviceDest->copymap,
     949           2 :                                     pserviceSource->copymap);
     950             :         }
     951             : 
     952      273836 :         for (data = pserviceSource->param_opt; data != NULL; data = data->next) {
     953       81840 :                 set_param_opt(pserviceDest, &pserviceDest->param_opt,
     954       81840 :                               data->key, data->value, data->priority);
     955             :         }
     956      191996 : }
     957             : 
     958             : /**
     959             :  * Check a service for consistency. Return False if the service is in any way
     960             :  * incomplete or faulty, else True.
     961             :  */
     962      332703 : bool lpcfg_service_ok(struct loadparm_service *service)
     963             : {
     964             :         bool bRetval;
     965             : 
     966      332703 :         bRetval = true;
     967      332703 :         if (service->szService[0] == '\0') {
     968           0 :                 DEBUG(0, ("The following message indicates an internal error:\n"));
     969           0 :                 DEBUG(0, ("No service name in service entry.\n"));
     970           0 :                 bRetval = false;
     971             :         }
     972             : 
     973             :         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
     974             :         /* I can't see why you'd want a non-printable printer service...        */
     975      332703 :         if (strwicmp(service->szService, PRINTERS_NAME) == 0) {
     976           0 :                 if (!service->printable) {
     977           0 :                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
     978             :                                service->szService));
     979           0 :                         service->printable = true;
     980             :                 }
     981             :                 /* [printers] service must also be non-browsable. */
     982           0 :                 if (service->browseable)
     983           0 :                         service->browseable = false;
     984             :         }
     985             : 
     986      332708 :         if (service->path[0] == '\0' &&
     987           5 :             strwicmp(service->szService, HOMES_NAME) != 0 &&
     988           2 :             service->msdfs_proxy[0] == '\0')
     989             :         {
     990           2 :                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
     991             :                         service->szService));
     992           2 :                 service->available = false;
     993             :         }
     994             : 
     995      332703 :         if (!service->available)
     996           2 :                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
     997             :                           service->szService));
     998             : 
     999      332703 :         return bRetval;
    1000             : }
    1001             : 
    1002             : 
    1003             : /*******************************************************************
    1004             :  Keep a linked list of all config files so we know when one has changed
    1005             :  it's date and needs to be reloaded.
    1006             : ********************************************************************/
    1007             : 
    1008       42377 : void add_to_file_list(TALLOC_CTX *mem_ctx, struct file_lists **list,
    1009             :                              const char *fname, const char *subfname)
    1010             : {
    1011       42377 :         struct file_lists *f = *list;
    1012             : 
    1013       72313 :         while (f) {
    1014       45178 :                 if (f->name && !strcmp(f->name, fname))
    1015       15242 :                         break;
    1016       29936 :                 f = f->next;
    1017             :         }
    1018             : 
    1019       42377 :         if (!f) {
    1020       27135 :                 f = talloc_zero(mem_ctx, struct file_lists);
    1021       27135 :                 if (!f)
    1022           0 :                         goto fail;
    1023       27135 :                 f->next = *list;
    1024       27135 :                 f->name = talloc_strdup(f, fname);
    1025       27135 :                 if (!f->name) {
    1026           0 :                         TALLOC_FREE(f);
    1027           0 :                         goto fail;
    1028             :                 }
    1029       27135 :                 f->subfname = talloc_strdup(f, subfname);
    1030       27135 :                 if (!f->subfname) {
    1031           0 :                         TALLOC_FREE(f);
    1032           0 :                         goto fail;
    1033             :                 }
    1034       27135 :                 *list = f;
    1035             :         }
    1036             : 
    1037             :         /* If file_modtime() fails it leaves f->modtime as zero. */
    1038       42377 :         (void)file_modtime(subfname, &f->modtime);
    1039       42377 :         return;
    1040             : 
    1041           0 : fail:
    1042           0 :         DEBUG(0, ("Unable to add file to file list: %s\n", fname));
    1043             : 
    1044             : }
    1045             : 
    1046             : /*
    1047             :  * set the value for a P_ENUM
    1048             :  */
    1049      603796 : bool lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
    1050             :                               int *ptr )
    1051             : {
    1052             :         int i;
    1053             : 
    1054     2376600 :         for (i = 0; parm->enum_list[i].name; i++) {
    1055     2376600 :                 if (strwicmp(pszParmValue, parm->enum_list[i].name) == 0) {
    1056      603796 :                         *ptr = parm->enum_list[i].value;
    1057      603796 :                         return true;
    1058             :                 }
    1059             :         }
    1060           0 :         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
    1061             :                   pszParmValue, parm->label));
    1062           0 :         return false;
    1063             : }
    1064             : 
    1065             : 
    1066             : /***************************************************************************
    1067             :  Handle the "realm" parameter
    1068             : ***************************************************************************/
    1069             : 
    1070       22443 : bool handle_realm(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1071             :                   const char *pszParmValue, char **ptr)
    1072             : {
    1073             :         char *upper;
    1074             :         char *lower;
    1075             : 
    1076       22443 :         upper = strupper_talloc(lp_ctx, pszParmValue);
    1077       22443 :         if (upper == NULL) {
    1078           0 :                 return false;
    1079             :         }
    1080             : 
    1081       22443 :         lower = strlower_talloc(lp_ctx, pszParmValue);
    1082       22443 :         if (lower == NULL) {
    1083           0 :                 TALLOC_FREE(upper);
    1084           0 :                 return false;
    1085             :         }
    1086             : 
    1087       22443 :         lpcfg_string_set(lp_ctx->globals->ctx, &lp_ctx->globals->realm, upper);
    1088       22443 :         lpcfg_string_set(lp_ctx->globals->ctx, &lp_ctx->globals->dnsdomain, lower);
    1089             : 
    1090       22443 :         return true;
    1091             : }
    1092             : 
    1093             : /***************************************************************************
    1094             :  Handle the include operation.
    1095             : ***************************************************************************/
    1096             : 
    1097       14653 : bool handle_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1098             :                            const char *pszParmValue, char **ptr)
    1099             : {
    1100             :         char *fname;
    1101             :         const char *substitution_variable_substring;
    1102             :         char next_char;
    1103             : 
    1104       14653 :         if (lp_ctx->s3_fns) {
    1105       13903 :                 return lp_ctx->s3_fns->lp_include(lp_ctx, service, pszParmValue, ptr);
    1106             :         }
    1107             : 
    1108         750 :         fname = standard_sub_basic(lp_ctx, pszParmValue);
    1109             : 
    1110         750 :         add_to_file_list(lp_ctx, &lp_ctx->file_lists, pszParmValue, fname);
    1111             : 
    1112         750 :         lpcfg_string_set(lp_ctx, ptr, fname);
    1113             : 
    1114         750 :         if (file_exist(fname))
    1115         642 :                 return pm_process(fname, do_section, lpcfg_do_parameter, lp_ctx);
    1116             : 
    1117             :        /*
    1118             :         * If the file doesn't exist, we check that it isn't due to variable
    1119             :         * substitution
    1120             :         */
    1121         108 :         substitution_variable_substring = strchr(fname, '%');
    1122             : 
    1123         108 :         if (substitution_variable_substring != NULL) {
    1124         107 :                 next_char = substitution_variable_substring[1];
    1125         107 :                 if ((next_char >= 'a' && next_char <= 'z')
    1126         107 :                     || (next_char >= 'A' && next_char <= 'Z')) {
    1127         107 :                         DEBUG(2, ("Tried to load %s but variable substitution in "
    1128             :                                  "filename, ignoring file.\n", fname));
    1129         107 :                         return true;
    1130             :                 }
    1131             :         }
    1132             : 
    1133           1 :         DEBUG(2, ("Can't find include file %s\n", fname));
    1134             : 
    1135           1 :         return false;
    1136             : }
    1137             : 
    1138             : /***************************************************************************
    1139             :  Handle the interpretation of the copy parameter.
    1140             : ***************************************************************************/
    1141             : 
    1142       94931 : bool handle_copy(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1143             :                         const char *pszParmValue, char **ptr)
    1144             : {
    1145             :         bool bRetval;
    1146       94931 :         struct loadparm_service *serviceTemp = NULL;
    1147             : 
    1148       94931 :         bRetval = false;
    1149             : 
    1150       94931 :         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
    1151             : 
    1152       94931 :         serviceTemp = lpcfg_getservicebyname(lp_ctx, pszParmValue);
    1153             : 
    1154       94931 :         if (service == NULL) {
    1155           2 :                 DEBUG(0, ("Unable to copy service - invalid service destination.\n"));
    1156           2 :                 return false;
    1157             :         }
    1158             : 
    1159       94929 :         if (serviceTemp != NULL) {
    1160       94929 :                 if (serviceTemp == service) {
    1161           0 :                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
    1162             :                 } else {
    1163       94929 :                         copy_service(service,
    1164             :                                      serviceTemp,
    1165             :                                      service->copymap);
    1166       94929 :                         lpcfg_string_set(service, ptr, pszParmValue);
    1167             : 
    1168       94929 :                         bRetval = true;
    1169             :                 }
    1170             :         } else {
    1171           0 :                 DEBUG(0, ("Unable to copy service - source not found: %s\n",
    1172             :                           pszParmValue));
    1173           0 :                 bRetval = false;
    1174             :         }
    1175             : 
    1176       94929 :         return bRetval;
    1177             : }
    1178             : 
    1179       38584 : bool handle_debug_list(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1180             :                         const char *pszParmValue, char **ptr)
    1181             : {
    1182       38584 :         lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1183             : 
    1184       38584 :         return debug_parse_levels(pszParmValue);
    1185             : }
    1186             : 
    1187       33500 : bool handle_logfile(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1188             :                     const char *pszParmValue, char **ptr)
    1189             : {
    1190       33500 :         if (lp_ctx->s3_fns == NULL) {
    1191       20974 :                 debug_set_logfile(pszParmValue);
    1192             :         }
    1193             : 
    1194       33500 :         lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1195             : 
    1196       33500 :         return true;
    1197             : }
    1198             : 
    1199             : /*
    1200             :  * These special charset handling methods only run in the source3 code.
    1201             :  */
    1202             : 
    1203        8500 : bool handle_charset(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1204             :                         const char *pszParmValue, char **ptr)
    1205             : {
    1206        8500 :         if (lp_ctx->s3_fns) {
    1207           6 :                 if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
    1208           5 :                         struct smb_iconv_handle *ret = NULL;
    1209             : 
    1210           5 :                         ret = reinit_iconv_handle(NULL,
    1211             :                                                   lpcfg_dos_charset(lp_ctx),
    1212             :                                                   lpcfg_unix_charset(lp_ctx));
    1213           5 :                         if (ret == NULL) {
    1214           0 :                                 smb_panic("reinit_iconv_handle failed");
    1215             :                         }
    1216             :                 }
    1217             : 
    1218             :         }
    1219        8500 :         return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1220             : 
    1221             : }
    1222             : 
    1223        8497 : bool handle_dos_charset(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1224             :                         const char *pszParmValue, char **ptr)
    1225             : {
    1226        8497 :         bool is_utf8 = false;
    1227        8497 :         size_t len = strlen(pszParmValue);
    1228             : 
    1229        8497 :         if (lp_ctx->s3_fns) {
    1230           4 :                 if (len == 4 || len == 5) {
    1231             :                         /* Don't use StrCaseCmp here as we don't want to
    1232             :                            initialize iconv. */
    1233           0 :                         if ((toupper_m(pszParmValue[0]) == 'U') &&
    1234           0 :                             (toupper_m(pszParmValue[1]) == 'T') &&
    1235           0 :                             (toupper_m(pszParmValue[2]) == 'F')) {
    1236           0 :                                 if (len == 4) {
    1237           0 :                                         if (pszParmValue[3] == '8') {
    1238           0 :                                                 is_utf8 = true;
    1239             :                                         }
    1240             :                                 } else {
    1241           0 :                                         if (pszParmValue[3] == '-' &&
    1242           0 :                                             pszParmValue[4] == '8') {
    1243           0 :                                                 is_utf8 = true;
    1244             :                                         }
    1245             :                                 }
    1246             :                         }
    1247             :                 }
    1248             : 
    1249           4 :                 if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
    1250           4 :                         struct smb_iconv_handle *ret = NULL;
    1251           4 :                         if (is_utf8) {
    1252           0 :                                 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
    1253             :                                         "be UTF8, using (default value) %s instead.\n",
    1254             :                                         DEFAULT_DOS_CHARSET));
    1255           0 :                                 pszParmValue = DEFAULT_DOS_CHARSET;
    1256             :                         }
    1257           4 :                         ret = reinit_iconv_handle(NULL,
    1258             :                                                 lpcfg_dos_charset(lp_ctx),
    1259             :                                                 lpcfg_unix_charset(lp_ctx));
    1260           4 :                         if (ret == NULL) {
    1261           0 :                                 smb_panic("reinit_iconv_handle failed");
    1262             :                         }
    1263             :                 }
    1264             :         }
    1265             : 
    1266        8497 :         return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1267             : }
    1268             : 
    1269       12308 : bool handle_printing(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1270             :                             const char *pszParmValue, char **ptr)
    1271             : {
    1272             :         static int parm_num = -1;
    1273             : 
    1274       12308 :         if (parm_num == -1) {
    1275        2627 :                 parm_num = lpcfg_map_parameter("printing");
    1276             :         }
    1277             : 
    1278       12308 :         if (!lp_set_enum_parm(&parm_table[parm_num], pszParmValue, (int*)ptr)) {
    1279           0 :                 return false;
    1280             :         }
    1281             : 
    1282       12308 :         if (lp_ctx->s3_fns) {
    1283        7390 :                 if (service == NULL) {
    1284        7390 :                         init_printer_values(lp_ctx, lp_ctx->globals->ctx, lp_ctx->sDefault);
    1285             :                 } else {
    1286           0 :                         init_printer_values(lp_ctx, service, service);
    1287             :                 }
    1288             :         }
    1289             : 
    1290       12308 :         return true;
    1291             : }
    1292             : 
    1293           9 : bool handle_ldap_debug_level(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1294             :                              const char *pszParmValue, char **ptr)
    1295             : {
    1296           9 :         lp_ctx->globals->ldap_debug_level = lp_int(pszParmValue);
    1297             : 
    1298           9 :         if (lp_ctx->s3_fns) {
    1299           6 :                 lp_ctx->s3_fns->init_ldap_debugging();
    1300             :         }
    1301           9 :         return true;
    1302             : }
    1303             : 
    1304             : /*
    1305             :  * idmap related parameters
    1306             :  */
    1307             : 
    1308        8500 : bool handle_idmap_backend(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1309             :                           const char *pszParmValue, char **ptr)
    1310             : {
    1311        8500 :         if (lp_ctx->s3_fns) {
    1312           6 :                 lp_do_parameter_parametric(lp_ctx, service, "idmap config * : backend",
    1313             :                                            pszParmValue, 0);
    1314             :         }
    1315             : 
    1316        8500 :         return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1317             : }
    1318             : 
    1319           9 : bool handle_idmap_uid(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1320             :                       const char *pszParmValue, char **ptr)
    1321             : {
    1322           9 :         if (lp_ctx->s3_fns) {
    1323           6 :                 lp_do_parameter_parametric(lp_ctx, service, "idmap config * : range",
    1324             :                                            pszParmValue, 0);
    1325             :         }
    1326             : 
    1327           9 :         return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1328             : }
    1329             : 
    1330           9 : bool handle_idmap_gid(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1331             :                       const char *pszParmValue, char **ptr)
    1332             : {
    1333           9 :         if (lp_ctx->s3_fns) {
    1334           6 :                 lp_do_parameter_parametric(lp_ctx, service, "idmap config * : range",
    1335             :                                            pszParmValue, 0);
    1336             :         }
    1337             : 
    1338           9 :         return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1339             : }
    1340             : 
    1341        8494 : bool handle_smb_ports(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1342             :                       const char *pszParmValue, char **ptr)
    1343             : {
    1344             :         static int parm_num = -1;
    1345             :         int i;
    1346             :         const char **list;
    1347             : 
    1348        8494 :         if (!pszParmValue || !*pszParmValue) {
    1349           0 :                 return false;
    1350             :         }
    1351             : 
    1352        8494 :         if (parm_num == -1) {
    1353        8441 :                 parm_num = lpcfg_map_parameter("smb ports");
    1354        8441 :                 if (parm_num == -1) {
    1355           0 :                         return false;
    1356             :                 }
    1357             :         }
    1358             : 
    1359        8494 :         if (!set_variable_helper(lp_ctx->globals->ctx, parm_num, ptr, "smb ports",
    1360             :                                 pszParmValue)) {
    1361           0 :                 return false;
    1362             :         }
    1363             : 
    1364        8494 :         list = lp_ctx->globals->smb_ports;
    1365        8494 :         if (list == NULL) {
    1366           0 :                 return false;
    1367             :         }
    1368             : 
    1369             :         /* Check that each port is a valid integer and within range */
    1370       25482 :         for (i = 0; list[i] != NULL; i++) {
    1371       16988 :                 char *end = NULL;
    1372       16988 :                 int port = 0;
    1373       16988 :                 port = strtol(list[i], &end, 10);
    1374       16988 :                 if (*end != '\0' || port <= 0 || port > 65535) {
    1375           0 :                         TALLOC_FREE(list);
    1376           0 :                         return false;
    1377             :                 }
    1378             :         }
    1379             : 
    1380        8494 :         return true;
    1381             : }
    1382             : 
    1383        8494 : bool handle_rpc_server_dynamic_port_range(struct loadparm_context *lp_ctx,
    1384             :                                           struct loadparm_service *service,
    1385             :                                           const char *pszParmValue,
    1386             :                                           char **ptr)
    1387             : {
    1388             :         static int parm_num = -1;
    1389        8494 :         int low_port = -1, high_port = -1;
    1390             :         int rc;
    1391             : 
    1392        8494 :         if (parm_num == -1) {
    1393        8441 :                 parm_num = lpcfg_map_parameter("rpc server dynamic port range");
    1394        8441 :                 if (parm_num == -1) {
    1395           0 :                         return false;
    1396             :                 }
    1397             :         }
    1398             : 
    1399        8494 :         if (pszParmValue == NULL || pszParmValue[0] == '\0') {
    1400           0 :                 return false;
    1401             :         }
    1402             : 
    1403        8494 :         rc = sscanf(pszParmValue, "%d - %d", &low_port, &high_port);
    1404        8494 :         if (rc != 2) {
    1405           0 :                 return false;
    1406             :         }
    1407             : 
    1408        8494 :         if (low_port > high_port) {
    1409           0 :                 return false;
    1410             :         }
    1411             : 
    1412        8494 :         if (low_port < SERVER_TCP_PORT_MIN|| high_port > SERVER_TCP_PORT_MAX) {
    1413           0 :                 return false;
    1414             :         }
    1415             : 
    1416        8494 :         if (!set_variable_helper(lp_ctx->globals->ctx, parm_num, ptr,
    1417             :                                  "rpc server dynamic port range",
    1418             :                                  pszParmValue)) {
    1419           0 :                 return false;
    1420             :         }
    1421             : 
    1422        8494 :         lp_ctx->globals->rpc_low_port = low_port;
    1423        8494 :         lp_ctx->globals->rpc_high_port = high_port;
    1424             : 
    1425        8494 :         return true;
    1426             : }
    1427             : 
    1428        8500 : bool handle_smb2_max_credits(struct loadparm_context *lp_ctx,
    1429             :                              struct loadparm_service *service,
    1430             :                              const char *pszParmValue, char **ptr)
    1431             : {
    1432        8500 :         int value = lp_int(pszParmValue);
    1433             : 
    1434        8500 :         if (value <= 0) {
    1435           0 :                 value = DEFAULT_SMB2_MAX_CREDITS;
    1436             :         }
    1437             : 
    1438        8500 :         *(int *)ptr = value;
    1439             : 
    1440        8500 :         return true;
    1441             : }
    1442             : 
    1443           0 : bool handle_cups_encrypt(struct loadparm_context *lp_ctx,
    1444             :                          struct loadparm_service *service,
    1445             :                          const char *pszParmValue, char **ptr)
    1446             : {
    1447           0 :         int result = 0;
    1448             : #ifdef HAVE_HTTPCONNECTENCRYPT
    1449           0 :         int value = lp_int(pszParmValue);
    1450             : 
    1451           0 :         switch (value) {
    1452           0 :                 case Auto:
    1453           0 :                         result = HTTP_ENCRYPT_REQUIRED;
    1454           0 :                         break;
    1455           0 :                 case true:
    1456           0 :                         result = HTTP_ENCRYPT_ALWAYS;
    1457           0 :                         break;
    1458           0 :                 case false:
    1459           0 :                         result = HTTP_ENCRYPT_NEVER;
    1460           0 :                         break;
    1461           0 :                 default:
    1462           0 :                         result = 0;
    1463           0 :                         break;
    1464             :         }
    1465             : #endif
    1466           0 :         *(int *)ptr = result;
    1467             : 
    1468           0 :         return true;
    1469             : }
    1470             : 
    1471             : /***************************************************************************
    1472             :  Initialise a copymap.
    1473             : ***************************************************************************/
    1474             : 
    1475             : /**
    1476             :  * Initializes service copymap
    1477             :  * Note: pservice *must* be valid TALLOC_CTX
    1478             :  */
    1479       97067 : void init_copymap(struct loadparm_service *pservice)
    1480             : {
    1481             :         int i;
    1482             : 
    1483       97067 :         TALLOC_FREE(pservice->copymap);
    1484             : 
    1485       97067 :         pservice->copymap = bitmap_talloc(pservice, num_parameters());
    1486       97067 :         if (!pservice->copymap) {
    1487           0 :                 DEBUG(0,
    1488             :                       ("Couldn't allocate copymap!! (size %d)\n",
    1489             :                        (int)num_parameters()));
    1490             :         } else {
    1491    50377773 :                 for (i = 0; i < num_parameters(); i++) {
    1492    50280706 :                         bitmap_set(pservice->copymap, i);
    1493             :                 }
    1494             :         }
    1495       97067 : }
    1496             : 
    1497             : /**
    1498             :  * Process a parametric option
    1499             :  */
    1500      891175 : static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx,
    1501             :                                        struct loadparm_service *service,
    1502             :                                        const char *pszParmName,
    1503             :                                        const char *pszParmValue, int flags)
    1504             : {
    1505             :         struct parmlist_entry **data;
    1506             :         char *name;
    1507             :         TALLOC_CTX *mem_ctx;
    1508             : 
    1509      891175 :         while (isspace((unsigned char)*pszParmName)) {
    1510           0 :                 pszParmName++;
    1511             :         }
    1512             : 
    1513      891175 :         name = strlower_talloc(lp_ctx, pszParmName);
    1514      891175 :         if (!name) return false;
    1515             : 
    1516      891175 :         if (service == NULL) {
    1517      516548 :                 data = &lp_ctx->globals->param_opt;
    1518             :                 /**
    1519             :                  * s3 code cannot deal with parametric options stored on the globals ctx.
    1520             :                  */
    1521      516548 :                 if (lp_ctx->s3_fns != NULL) {
    1522      122625 :                         mem_ctx = NULL;
    1523             :                 } else {
    1524      393923 :                         mem_ctx = lp_ctx->globals->ctx;
    1525             :                 }
    1526             :         } else {
    1527      374627 :                 data = &service->param_opt;
    1528      374627 :                 mem_ctx = service;
    1529             :         }
    1530             : 
    1531      891175 :         set_param_opt(mem_ctx, data, name, pszParmValue, flags);
    1532             : 
    1533      891175 :         talloc_free(name);
    1534             : 
    1535      891175 :         return true;
    1536             : }
    1537             : 
    1538     3780090 : static bool set_variable_helper(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
    1539             :                          const char *pszParmName, const char *pszParmValue)
    1540             : {
    1541             :         size_t i;
    1542             : 
    1543             :         /* switch on the type of variable it is */
    1544     3780090 :         switch (parm_table[parmnum].type)
    1545             :         {
    1546     1200086 :                 case P_BOOL: {
    1547             :                         bool b;
    1548     1200086 :                         if (!set_boolean(pszParmValue, &b)) {
    1549           0 :                                 DEBUG(0, ("set_variable_helper(%s): value is not "
    1550             :                                           "boolean!\n", pszParmValue));
    1551           0 :                                 return false;
    1552             :                         }
    1553     1200086 :                         *(bool *)parm_ptr = b;
    1554             :                         }
    1555     1200086 :                         break;
    1556             : 
    1557        2607 :                 case P_BOOLREV: {
    1558             :                         bool b;
    1559        2607 :                         if (!set_boolean(pszParmValue, &b)) {
    1560           0 :                                 DEBUG(0, ("set_variable_helper(%s): value is not "
    1561             :                                           "boolean!\n", pszParmValue));
    1562           0 :                                 return false;
    1563             :                         }
    1564        2607 :                         *(bool *)parm_ptr = !b;
    1565             :                         }
    1566        2607 :                         break;
    1567             : 
    1568      471011 :                 case P_INTEGER:
    1569      471011 :                         *(int *)parm_ptr = lp_int(pszParmValue);
    1570      471011 :                         break;
    1571             : 
    1572        8500 :                 case P_CHAR:
    1573        8500 :                         *(char *)parm_ptr = *pszParmValue;
    1574        8500 :                         break;
    1575             : 
    1576       64588 :                 case P_OCTAL:
    1577       64588 :                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
    1578       64588 :                         if ( i != 1 ) {
    1579           0 :                                 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
    1580           0 :                                 return false;
    1581             :                         }
    1582       64588 :                         break;
    1583             : 
    1584       78404 :                 case P_BYTES:
    1585             :                 {
    1586             :                         uint64_t val;
    1587       78404 :                         if (conv_str_size_error(pszParmValue, &val)) {
    1588       78404 :                                 if (val <= INT_MAX) {
    1589       78404 :                                         *(int *)parm_ptr = (int)val;
    1590       78404 :                                         break;
    1591             :                                 }
    1592             :                         }
    1593             : 
    1594           0 :                         DEBUG(0, ("set_variable_helper(%s): value is not "
    1595             :                                   "a valid size specifier!\n", pszParmValue));
    1596           0 :                         return false;
    1597             :                 }
    1598             : 
    1599      287342 :                 case P_CMDLIST:
    1600      287342 :                         TALLOC_FREE(*(char ***)parm_ptr);
    1601      287342 :                         *(char ***)parm_ptr = str_list_make_v3(mem_ctx,
    1602             :                                                         pszParmValue, NULL);
    1603      287342 :                         break;
    1604             : 
    1605      129091 :                 case P_LIST:
    1606             :                 {
    1607      129091 :                         char **new_list = str_list_make_v3(mem_ctx,
    1608             :                                                         pszParmValue, NULL);
    1609      129091 :                         if (new_list == NULL) {
    1610           3 :                                 break;
    1611             :                         }
    1612             : 
    1613      194930 :                         for (i=0; new_list[i]; i++) {
    1614      171415 :                                 if (*(const char ***)parm_ptr != NULL &&
    1615      101937 :                                     new_list[i][0] == '+' &&
    1616       49332 :                                     new_list[i][1])
    1617             :                                 {
    1618       49332 :                                         if (!str_list_check(*(const char ***)parm_ptr,
    1619       49332 :                                                             &new_list[i][1])) {
    1620       22594 :                                                 *(const char ***)parm_ptr = str_list_add(*(const char ***)parm_ptr,
    1621       22594 :                                                                                          &new_list[i][1]);
    1622             :                                         }
    1623      122083 :                                 } else if (*(const char ***)parm_ptr != NULL &&
    1624       52605 :                                            new_list[i][0] == '-' &&
    1625       16510 :                                            new_list[i][1])
    1626             :                                 {
    1627       16510 :                                         str_list_remove(*(const char ***)parm_ptr,
    1628       16510 :                                                         &new_list[i][1]);
    1629             :                                 } else {
    1630      105573 :                                         if (i != 0) {
    1631           0 :                                                 DEBUG(0, ("Unsupported list syntax for: %s = %s\n",
    1632             :                                                           pszParmName, pszParmValue));
    1633           0 :                                                 return false;
    1634             :                                         }
    1635      105573 :                                         *(char ***)parm_ptr = new_list;
    1636      105573 :                                         break;
    1637             :                                 }
    1638             :                         }
    1639      129088 :                         break;
    1640             :                 }
    1641             : 
    1642      991564 :                 case P_STRING:
    1643      991564 :                         lpcfg_string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
    1644      991564 :                         break;
    1645             : 
    1646       67020 :                 case P_USTRING:
    1647       67020 :                         lpcfg_string_set_upper(mem_ctx, (char **)parm_ptr, pszParmValue);
    1648       67020 :                         break;
    1649             : 
    1650      479877 :                 case P_ENUM:
    1651      479877 :                         if (!lp_set_enum_parm(&parm_table[parmnum], pszParmValue, (int*)parm_ptr)) {
    1652           0 :                                 return false;
    1653             :                         }
    1654      479877 :                         break;
    1655             : 
    1656             :         }
    1657             : 
    1658     3780090 :         return true;
    1659             : 
    1660             : }
    1661             : 
    1662        8494 : bool handle_name_resolve_order(struct loadparm_context *lp_ctx,
    1663             :                                struct loadparm_service *service,
    1664             :                                const char *pszParmValue, char **ptr)
    1665             : {
    1666        8494 :         const char **valid_values = NULL;
    1667        8494 :         const char **values_to_set = NULL;
    1668             :         int i;
    1669        8494 :         bool value_is_valid = false;
    1670        8494 :         valid_values = str_list_make_v3_const(NULL,
    1671             :                                               DEFAULT_NAME_RESOLVE_ORDER,
    1672             :                                               NULL);
    1673        8494 :         if (valid_values == NULL) {
    1674           0 :                 DBG_ERR("OOM: failed to make string list from %s\n",
    1675             :                         DEFAULT_NAME_RESOLVE_ORDER);
    1676           0 :                 goto out;
    1677             :         }
    1678        8494 :         values_to_set = str_list_make_v3_const(lp_ctx->globals->ctx,
    1679             :                                                pszParmValue,
    1680             :                                                NULL);
    1681        8494 :         if (values_to_set == NULL) {
    1682           0 :                 DBG_ERR("OOM: failed to make string list from %s\n",
    1683             :                         pszParmValue);
    1684           0 :                 goto out;
    1685             :         }
    1686        8494 :         TALLOC_FREE(lp_ctx->globals->name_resolve_order);
    1687       42470 :         for (i = 0; values_to_set[i] != NULL; i++) {
    1688       33976 :                 value_is_valid = str_list_check(valid_values, values_to_set[i]);
    1689       33976 :                 if (!value_is_valid) {
    1690           0 :                         DBG_ERR("WARNING: Ignoring invalid list value '%s' "
    1691             :                                 "for parameter 'name resolve order'\n",
    1692             :                                 values_to_set[i]);
    1693           0 :                         break;
    1694             :                 }
    1695             :         }
    1696        8494 : out:
    1697        8494 :         if (value_is_valid) {
    1698        8494 :                 lp_ctx->globals->name_resolve_order = values_to_set;
    1699             :         } else {
    1700           0 :                 TALLOC_FREE(values_to_set);
    1701             :         }
    1702        8494 :         TALLOC_FREE(valid_values);
    1703        8494 :         return value_is_valid;
    1704             : }
    1705             : 
    1706           9 : bool handle_kdc_default_domain_supported_enctypes(struct loadparm_context *lp_ctx,
    1707             :                                                   struct loadparm_service *service,
    1708             :                                                   const char *pszParmValue, char **ptr)
    1709             : {
    1710           9 :         char **enctype_list = NULL;
    1711           9 :         char **enctype = NULL;
    1712           9 :         uint32_t result = 0;
    1713           9 :         bool ok = true;
    1714             : 
    1715           9 :         enctype_list = str_list_make(NULL, pszParmValue, NULL);
    1716           9 :         if (enctype_list == NULL) {
    1717           0 :                 DBG_ERR("OOM: failed to make string list from %s\n",
    1718             :                         pszParmValue);
    1719           0 :                 ok = false;
    1720           0 :                 goto out;
    1721             :         }
    1722             : 
    1723          18 :         for (enctype = enctype_list; *enctype != NULL; ++enctype) {
    1724          18 :                 if (strwicmp(*enctype, "arcfour-hmac-md5") == 0 ||
    1725           9 :                     strwicmp(*enctype, "rc4-hmac") == 0)
    1726             :                 {
    1727           0 :                         result |= KERB_ENCTYPE_RC4_HMAC_MD5;
    1728             :                 }
    1729          18 :                 else if (strwicmp(*enctype, "aes128-cts-hmac-sha1-96") == 0 ||
    1730           9 :                          strwicmp(*enctype, "aes128-cts") == 0)
    1731             :                 {
    1732           0 :                         result |= KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96;
    1733             :                 }
    1734          18 :                 else if (strwicmp(*enctype, "aes256-cts-hmac-sha1-96") == 0 ||
    1735           9 :                          strwicmp(*enctype, "aes256-cts") == 0)
    1736             :                 {
    1737           0 :                         result |= KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96;
    1738             :                 }
    1739          18 :                 else if (strwicmp(*enctype, "aes256-cts-hmac-sha1-96-sk") == 0 ||
    1740           9 :                          strwicmp(*enctype, "aes256-cts-sk") == 0)
    1741             :                 {
    1742           0 :                         result |= KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96_SK;
    1743             :                 }
    1744             :                 else {
    1745           9 :                         const char *bitstr = *enctype;
    1746             :                         int base;
    1747             :                         int error;
    1748             :                         unsigned long bit;
    1749             : 
    1750             :                         /* See if the bit's specified in hexadecimal. */
    1751           9 :                         if (bitstr[0] == '0' &&
    1752           3 :                             (bitstr[1] == 'x' || bitstr[2] == 'X'))
    1753             :                         {
    1754           0 :                                 base = 16;
    1755           0 :                                 bitstr += 2;
    1756             :                         }
    1757             :                         else {
    1758           9 :                                 base = 10;
    1759             :                         }
    1760             : 
    1761           9 :                         bit = smb_strtoul(bitstr, NULL, base, &error, SMB_STR_FULL_STR_CONV);
    1762           9 :                         if (error) {
    1763           0 :                                 DBG_ERR("WARNING: Ignoring invalid value '%s' "
    1764             :                                         "for parameter 'kdc default domain supported enctypes'\n",
    1765             :                                         *enctype);
    1766           0 :                                 ok = false;
    1767             :                         } else {
    1768           9 :                                 result |= bit;
    1769             :                         }
    1770             :                 }
    1771             :         }
    1772             : 
    1773           9 :         *(int *)ptr = result;
    1774           9 : out:
    1775           9 :         TALLOC_FREE(enctype_list);
    1776             : 
    1777           9 :         return ok;
    1778             : }
    1779             : 
    1780           9 : bool handle_kdc_supported_enctypes(struct loadparm_context *lp_ctx,
    1781             :                                    struct loadparm_service *service,
    1782             :                                    const char *pszParmValue, char **ptr)
    1783             : {
    1784           9 :         char **enctype_list = NULL;
    1785           9 :         char **enctype = NULL;
    1786           9 :         uint32_t result = 0;
    1787           9 :         bool ok = true;
    1788             : 
    1789           9 :         enctype_list = str_list_make(NULL, pszParmValue, NULL);
    1790           9 :         if (enctype_list == NULL) {
    1791           0 :                 DBG_ERR("OOM: failed to make string list from %s\n",
    1792             :                         pszParmValue);
    1793           0 :                 ok = false;
    1794           0 :                 goto out;
    1795             :         }
    1796             : 
    1797          18 :         for (enctype = enctype_list; *enctype != NULL; ++enctype) {
    1798          18 :                 if (strwicmp(*enctype, "arcfour-hmac-md5") == 0 ||
    1799           9 :                     strwicmp(*enctype, "rc4-hmac") == 0)
    1800             :                 {
    1801           0 :                         result |= KERB_ENCTYPE_RC4_HMAC_MD5;
    1802             :                 }
    1803          18 :                 else if (strwicmp(*enctype, "aes128-cts-hmac-sha1-96") == 0 ||
    1804           9 :                          strwicmp(*enctype, "aes128-cts") == 0)
    1805             :                 {
    1806           0 :                         result |= KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96;
    1807             :                 }
    1808          18 :                 else if (strwicmp(*enctype, "aes256-cts-hmac-sha1-96") == 0 ||
    1809           9 :                          strwicmp(*enctype, "aes256-cts") == 0)
    1810             :                 {
    1811           0 :                         result |= KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96;
    1812             :                 }
    1813             :                 else {
    1814           9 :                         const char *bitstr = *enctype;
    1815             :                         int base;
    1816             :                         int error;
    1817             :                         unsigned long bit;
    1818             : 
    1819             :                         /* See if the bit's specified in hexadecimal. */
    1820           9 :                         if (bitstr[0] == '0' &&
    1821           3 :                             (bitstr[1] == 'x' || bitstr[2] == 'X'))
    1822             :                         {
    1823           0 :                                 base = 16;
    1824           0 :                                 bitstr += 2;
    1825             :                         }
    1826             :                         else {
    1827           9 :                                 base = 10;
    1828             :                         }
    1829             : 
    1830           9 :                         bit = smb_strtoul(bitstr, NULL, base, &error, SMB_STR_FULL_STR_CONV);
    1831           9 :                         if (error) {
    1832           0 :                                 DBG_ERR("WARNING: Ignoring invalid value '%s' "
    1833             :                                         "for parameter 'kdc default domain supported enctypes'\n",
    1834             :                                         *enctype);
    1835           0 :                                 ok = false;
    1836             :                         } else {
    1837           9 :                                 result |= bit;
    1838             :                         }
    1839             :                 }
    1840             :         }
    1841             : 
    1842           9 :         *(int *)ptr = result;
    1843           9 : out:
    1844           9 :         TALLOC_FREE(enctype_list);
    1845             : 
    1846           9 :         return ok;
    1847             : }
    1848             : 
    1849     4039045 : static bool set_variable(TALLOC_CTX *mem_ctx, struct loadparm_service *service,
    1850             :                          int parmnum, void *parm_ptr,
    1851             :                          const char *pszParmName, const char *pszParmValue,
    1852             :                          struct loadparm_context *lp_ctx, bool on_globals)
    1853             : {
    1854             :         int i;
    1855             :         bool ok;
    1856             : 
    1857             :         /* if it is a special case then go ahead */
    1858     4039045 :         if (parm_table[parmnum].special) {
    1859      275943 :                 ok = parm_table[parmnum].special(lp_ctx, service, pszParmValue,
    1860             :                                                   (char **)parm_ptr);
    1861             :         } else {
    1862     3763102 :                 ok = set_variable_helper(mem_ctx, parmnum, parm_ptr,
    1863             :                                          pszParmName, pszParmValue);
    1864             :         }
    1865             : 
    1866     4039045 :         if (!ok) {
    1867           3 :                 return false;
    1868             :         }
    1869             : 
    1870     4039042 :         if (on_globals && (lp_ctx->flags[parmnum] & FLAG_DEFAULT)) {
    1871      245805 :                 lp_ctx->flags[parmnum] &= ~FLAG_DEFAULT;
    1872             :                 /* we have to also unset FLAG_DEFAULT on aliases */
    1873      251510 :                 for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) {
    1874        5705 :                         lp_ctx->flags[i] &= ~FLAG_DEFAULT;
    1875             :                 }
    1876      281751 :                 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset;i++) {
    1877       35946 :                         lp_ctx->flags[i] &= ~FLAG_DEFAULT;
    1878             :                 }
    1879             :         }
    1880     4039042 :         return true;
    1881             : }
    1882             : 
    1883             : 
    1884     3636648 : bool lpcfg_do_global_parameter(struct loadparm_context *lp_ctx,
    1885             :                                const char *pszParmName, const char *pszParmValue)
    1886             : {
    1887     3636648 :         int parmnum = lpcfg_map_parameter(pszParmName);
    1888             :         void *parm_ptr;
    1889             : 
    1890     3636648 :         if (parmnum < 0) {
    1891      504476 :                 if (strchr(pszParmName, ':')) {
    1892      504476 :                         return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName, pszParmValue, 0);
    1893             :                 }
    1894           0 :                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
    1895           0 :                 return true;
    1896             :         }
    1897             : 
    1898             :         /* if the flag has been set on the command line, then don't allow override,
    1899             :            but don't report an error */
    1900     3132172 :         if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) {
    1901        8499 :                 return true;
    1902             :         }
    1903             : 
    1904     3123673 :         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
    1905      211856 :                 char *suppress_env = getenv("SAMBA_DEPRECATED_SUPPRESS");
    1906      211856 :                 bool print_warning = (suppress_env == NULL
    1907      211856 :                                       || suppress_env[0] == '\0');
    1908      211856 :                 if (print_warning) {
    1909           0 :                         DBG_WARNING("WARNING: The \"%s\" option "
    1910             :                                     "is deprecated\n",
    1911             :                                     pszParmName);
    1912             : 
    1913             :                 }
    1914             :         }
    1915             : 
    1916     3123673 :         parm_ptr = lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[parmnum]);
    1917             : 
    1918     3123673 :         return set_variable(lp_ctx->globals->ctx, NULL, parmnum, parm_ptr,
    1919             :                             pszParmName, pszParmValue, lp_ctx, true);
    1920             : }
    1921             : 
    1922     1290003 : bool lpcfg_do_service_parameter(struct loadparm_context *lp_ctx,
    1923             :                                 struct loadparm_service *service,
    1924             :                                 const char *pszParmName, const char *pszParmValue)
    1925             : {
    1926             :         void *parm_ptr;
    1927             :         int i;
    1928     1290003 :         int parmnum = lpcfg_map_parameter(pszParmName);
    1929             : 
    1930     1290003 :         if (parmnum < 0) {
    1931      374627 :                 if (strchr(pszParmName, ':')) {
    1932      374627 :                         return lp_do_parameter_parametric(lp_ctx, service, pszParmName, pszParmValue, 0);
    1933             :                 }
    1934           0 :                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
    1935           0 :                 return true;
    1936             :         }
    1937             : 
    1938             :         /* if the flag has been set on the command line, then don't allow override,
    1939             :            but don't report an error */
    1940      915376 :         if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) {
    1941           4 :                 return true;
    1942             :         }
    1943             : 
    1944      915372 :         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
    1945           0 :                 char *suppress_env = getenv("SAMBA_DEPRECATED_SUPPRESS");
    1946           0 :                 bool print_warning = (suppress_env == NULL
    1947           0 :                                       || suppress_env[0] == '\0');
    1948           0 :                 if (print_warning) {
    1949           0 :                         DBG_WARNING("WARNING: The \"%s\" option "
    1950             :                                     "is deprecated\n",
    1951             :                                     pszParmName);
    1952             : 
    1953             :                 }
    1954             :         }
    1955             : 
    1956      915372 :         if (parm_table[parmnum].p_class == P_GLOBAL) {
    1957           0 :                 DEBUG(0,
    1958             :                       ("Global parameter %s found in service section!\n",
    1959             :                        pszParmName));
    1960           0 :                 return true;
    1961             :         }
    1962      915372 :         parm_ptr = ((char *)service) + parm_table[parmnum].offset;
    1963             : 
    1964      915372 :         if (!service->copymap)
    1965           0 :                 init_copymap(service);
    1966             : 
    1967             :         /* this handles the aliases - set the copymap for other
    1968             :          * entries with the same data pointer */
    1969   474162696 :         for (i = 0; parm_table[i].label; i++)
    1970   473247324 :                 if (parm_table[i].offset == parm_table[parmnum].offset &&
    1971     2473333 :                     parm_table[i].p_class == parm_table[parmnum].p_class)
    1972     1647279 :                         bitmap_clear(service->copymap, i);
    1973             : 
    1974      915372 :         return set_variable(service, service, parmnum, parm_ptr, pszParmName,
    1975             :                             pszParmValue, lp_ctx, false);
    1976             : }
    1977             : 
    1978             : /**
    1979             :  * Process a parameter.
    1980             :  */
    1981             : 
    1982     1513759 : bool lpcfg_do_parameter(const char *pszParmName, const char *pszParmValue,
    1983             :                          void *userdata)
    1984             : {
    1985     1513759 :         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
    1986             : 
    1987     1513759 :         if (lp_ctx->bInGlobalSection)
    1988     1024026 :                 return lpcfg_do_global_parameter(lp_ctx, pszParmName,
    1989             :                                               pszParmValue);
    1990             :         else
    1991      489733 :                 return lpcfg_do_service_parameter(lp_ctx, lp_ctx->currentService,
    1992             :                                                   pszParmName, pszParmValue);
    1993             : }
    1994             : 
    1995             : /*
    1996             :   variable argument do parameter
    1997             : */
    1998             : bool lpcfg_do_global_parameter_var(struct loadparm_context *lp_ctx, const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
    1999      128885 : bool lpcfg_do_global_parameter_var(struct loadparm_context *lp_ctx,
    2000             :                                 const char *pszParmName, const char *fmt, ...)
    2001             : {
    2002             :         char *s;
    2003             :         bool ret;
    2004             :         va_list ap;
    2005             : 
    2006      128885 :         va_start(ap, fmt);
    2007      128885 :         s = talloc_vasprintf(NULL, fmt, ap);
    2008      128885 :         va_end(ap);
    2009      128885 :         ret = lpcfg_do_global_parameter(lp_ctx, pszParmName, s);
    2010      128885 :         talloc_free(s);
    2011      128885 :         return ret;
    2012             : }
    2013             : 
    2014             : 
    2015             : /*
    2016             :   set a parameter from the commandline - this is called from command line parameter
    2017             :   parsing code. It sets the parameter then marks the parameter as unable to be modified
    2018             :   by smb.conf processing
    2019             : */
    2020       22485 : bool lpcfg_set_cmdline(struct loadparm_context *lp_ctx, const char *pszParmName,
    2021             :                        const char *pszParmValue)
    2022             : {
    2023             :         int parmnum;
    2024             :         int i;
    2025             : 
    2026       25362 :         while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
    2027             : 
    2028       22485 :         parmnum = lpcfg_map_parameter(pszParmName);
    2029             : 
    2030       22485 :         if (parmnum < 0 && strchr(pszParmName, ':')) {
    2031             :                 /* set a parametric option */
    2032             :                 bool ok;
    2033       12054 :                 ok = lp_do_parameter_parametric(lp_ctx, NULL, pszParmName,
    2034             :                                                 pszParmValue, FLAG_CMDLINE);
    2035       12054 :                 if (lp_ctx->s3_fns != NULL) {
    2036         113 :                         if (ok) {
    2037         113 :                                 lp_ctx->s3_fns->store_cmdline(pszParmName, pszParmValue);
    2038             :                         }
    2039             :                 }
    2040       12054 :                 return ok;
    2041             :         }
    2042             : 
    2043       10431 :         if (parmnum < 0) {
    2044           0 :                 DEBUG(0,("Unknown option '%s'\n", pszParmName));
    2045           0 :                 return false;
    2046             :         }
    2047             : 
    2048             :         /* reset the CMDLINE flag in case this has been called before */
    2049       10431 :         lp_ctx->flags[parmnum] &= ~FLAG_CMDLINE;
    2050             : 
    2051       10431 :         if (!lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) {
    2052           3 :                 return false;
    2053             :         }
    2054             : 
    2055       10428 :         lp_ctx->flags[parmnum] |= FLAG_CMDLINE;
    2056             : 
    2057             :         /* we have to also set FLAG_CMDLINE on aliases */
    2058       10428 :         for (i=parmnum-1;
    2059       10646 :              i>=0 && parm_table[i].p_class == parm_table[parmnum].p_class &&
    2060        9761 :              parm_table[i].offset == parm_table[parmnum].offset;
    2061         218 :              i--) {
    2062         218 :                 lp_ctx->flags[i] |= FLAG_CMDLINE;
    2063             :         }
    2064       10428 :         for (i=parmnum+1;
    2065       15328 :              i<num_parameters() &&
    2066       15328 :              parm_table[i].p_class == parm_table[parmnum].p_class &&
    2067       13165 :              parm_table[i].offset == parm_table[parmnum].offset;
    2068        4900 :              i++) {
    2069        4900 :                 lp_ctx->flags[i] |= FLAG_CMDLINE;
    2070             :         }
    2071             : 
    2072       10428 :         if (lp_ctx->s3_fns != NULL) {
    2073        6720 :                 lp_ctx->s3_fns->store_cmdline(pszParmName, pszParmValue);
    2074             :         }
    2075             : 
    2076       10428 :         return true;
    2077             : }
    2078             : 
    2079             : /*
    2080             :   set a option from the commandline in 'a=b' format. Use to support --option
    2081             : */
    2082        4815 : bool lpcfg_set_option(struct loadparm_context *lp_ctx, const char *option)
    2083             : {
    2084             :         char *p, *s;
    2085             :         bool ret;
    2086             : 
    2087        4815 :         s = talloc_strdup(NULL, option);
    2088        4815 :         if (!s) {
    2089           0 :                 return false;
    2090             :         }
    2091             : 
    2092        4815 :         p = strchr(s, '=');
    2093        4815 :         if (!p) {
    2094           0 :                 talloc_free(s);
    2095           0 :                 return false;
    2096             :         }
    2097             : 
    2098        4815 :         *p = 0;
    2099             : 
    2100        4815 :         ret = lpcfg_set_cmdline(lp_ctx, s, p+1);
    2101        4815 :         talloc_free(s);
    2102        4815 :         return ret;
    2103             : }
    2104             : 
    2105             : 
    2106             : #define BOOLSTR(b) ((b) ? "Yes" : "No")
    2107             : 
    2108             : /**
    2109             :  * Print a parameter of the specified type.
    2110             :  */
    2111             : 
    2112       41569 : void lpcfg_print_parameter(struct parm_struct *p, void *ptr, FILE * f)
    2113             : {
    2114             :         /* For the seperation of lists values that we print below */
    2115       41569 :         const char *list_sep = ", ";
    2116             :         int i;
    2117       41569 :         switch (p->type)
    2118             :         {
    2119        3620 :                 case P_ENUM:
    2120       14930 :                         for (i = 0; p->enum_list[i].name; i++) {
    2121       14930 :                                 if (*(int *)ptr == p->enum_list[i].value) {
    2122        3620 :                                         fprintf(f, "%s",
    2123        3620 :                                                 p->enum_list[i].name);
    2124        3620 :                                         break;
    2125             :                                 }
    2126             :                         }
    2127        3620 :                         break;
    2128             : 
    2129       13016 :                 case P_BOOL:
    2130       13016 :                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
    2131       13016 :                         break;
    2132             : 
    2133          12 :                 case P_BOOLREV:
    2134          12 :                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
    2135          12 :                         break;
    2136             : 
    2137        5455 :                 case P_INTEGER:
    2138             :                 case P_BYTES:
    2139        5455 :                         fprintf(f, "%d", *(int *)ptr);
    2140        5455 :                         break;
    2141             : 
    2142          63 :                 case P_CHAR:
    2143          63 :                         fprintf(f, "%c", *(char *)ptr);
    2144          63 :                         break;
    2145             : 
    2146         661 :                 case P_OCTAL: {
    2147         661 :                         int val = *(int *)ptr;
    2148         661 :                         if (val == -1) {
    2149           0 :                                 fprintf(f, "-1");
    2150             :                         } else {
    2151         661 :                                 fprintf(f, "0%03o", val);
    2152             :                         }
    2153         661 :                         break;
    2154             :                 }
    2155             : 
    2156        3070 :                 case P_CMDLIST:
    2157        3070 :                         list_sep = " ";
    2158             : 
    2159             :                         FALL_THROUGH;
    2160        4206 :                 case P_LIST:
    2161        4206 :                         if ((char ***)ptr && *(char ***)ptr) {
    2162        2875 :                                 char **list = *(char ***)ptr;
    2163       14836 :                                 for (; *list; list++) {
    2164             :                                         /* surround strings with whitespace in double quotes */
    2165       11961 :                                         if (*(list+1) == NULL) {
    2166             :                                                 /* last item, no extra separator */
    2167        2875 :                                                 list_sep = "";
    2168             :                                         }
    2169       11961 :                                         if ( strchr_m( *list, ' ' ) ) {
    2170          24 :                                                 fprintf(f, "\"%s\"%s", *list, list_sep);
    2171             :                                         } else {
    2172       11937 :                                                 fprintf(f, "%s%s", *list, list_sep);
    2173             :                                         }
    2174             :                                 }
    2175             :                         }
    2176        4206 :                         break;
    2177             : 
    2178       14536 :                 case P_STRING:
    2179             :                 case P_USTRING:
    2180       14536 :                         if (*(char **)ptr) {
    2181       14536 :                                 fprintf(f, "%s", *(char **)ptr);
    2182             :                         }
    2183       14536 :                         break;
    2184             :         }
    2185       41569 : }
    2186             : 
    2187             : /**
    2188             :  * Check if two parameters are equal.
    2189             :  */
    2190             : 
    2191      338238 : static bool lpcfg_equal_parameter(parm_type type, void *ptr1, void *ptr2)
    2192             : {
    2193      338238 :         switch (type) {
    2194      166668 :                 case P_BOOL:
    2195             :                 case P_BOOLREV:
    2196      166668 :                         return (*((bool *)ptr1) == *((bool *)ptr2));
    2197             : 
    2198       68628 :                 case P_INTEGER:
    2199             :                 case P_ENUM:
    2200             :                 case P_OCTAL:
    2201             :                 case P_BYTES:
    2202       68628 :                         return (*((int *)ptr1) == *((int *)ptr2));
    2203             : 
    2204        2451 :                 case P_CHAR:
    2205        2451 :                         return (*((char *)ptr1) == *((char *)ptr2));
    2206             : 
    2207       24510 :                 case P_LIST:
    2208             :                 case P_CMDLIST:
    2209       24510 :                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
    2210             : 
    2211       75981 :                 case P_STRING:
    2212             :                 case P_USTRING:
    2213             :                 {
    2214       75981 :                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
    2215       75981 :                         if (p1 && !*p1)
    2216       54438 :                                 p1 = NULL;
    2217       75981 :                         if (p2 && !*p2)
    2218       58029 :                                 p2 = NULL;
    2219       75981 :                         return (p1 == p2 || strequal(p1, p2));
    2220             :                 }
    2221             :         }
    2222           0 :         return false;
    2223             : }
    2224             : 
    2225             : /**
    2226             :  * Process a new section (service).
    2227             :  *
    2228             :  * At this stage all sections are services.
    2229             :  * Later we'll have special sections that permit server parameters to be set.
    2230             :  * Returns True on success, False on failure.
    2231             :  */
    2232             : 
    2233      149884 : static bool do_section(const char *pszSectionName, void *userdata)
    2234             : {
    2235      149884 :         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
    2236             :         bool bRetval;
    2237             :         bool isglobal;
    2238             : 
    2239      149884 :         if (lp_ctx->s3_fns != NULL) {
    2240           0 :                 return lp_ctx->s3_fns->do_section(pszSectionName, lp_ctx);
    2241             :         }
    2242             : 
    2243      282298 :         isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
    2244      132414 :                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
    2245             : 
    2246             :         /* if we've just struck a global section, note the fact. */
    2247      149884 :         lp_ctx->bInGlobalSection = isglobal;
    2248             : 
    2249             :         /* check for multiple global sections */
    2250      149884 :         if (lp_ctx->bInGlobalSection) {
    2251       17609 :                 DEBUG(4, ("Processing section \"[%s]\"\n", pszSectionName));
    2252       17609 :                 bRetval = true;
    2253       17609 :                 goto out;
    2254             :         }
    2255             : 
    2256             :         /* if we have a current service, tidy it up before moving on */
    2257      132275 :         bRetval = true;
    2258             : 
    2259      132275 :         if (lp_ctx->currentService != NULL)
    2260      121208 :                 bRetval = lpcfg_service_ok(lp_ctx->currentService);
    2261             : 
    2262             :         /* if all is still well, move to the next record in the services array */
    2263      132275 :         if (bRetval) {
    2264             :                 /* We put this here to avoid an odd message order if messages are */
    2265             :                 /* issued by the post-processing of a previous section. */
    2266      132275 :                 DEBUG(4, ("Processing section \"[%s]\"\n", pszSectionName));
    2267             : 
    2268      132275 :                 if ((lp_ctx->currentService = lpcfg_add_service(lp_ctx, lp_ctx->sDefault,
    2269             :                                                                    pszSectionName))
    2270             :                     == NULL) {
    2271           0 :                         DEBUG(0, ("Failed to add a new service\n"));
    2272           0 :                         bRetval = false;
    2273           0 :                         goto out;
    2274             :                 }
    2275             :         }
    2276      132275 : out:
    2277      149884 :         return bRetval;
    2278             : }
    2279             : 
    2280             : 
    2281             : /**
    2282             :  * Determine if a particular base parameter is currently set to the default value.
    2283             :  */
    2284             : 
    2285        7529 : static bool is_default(void *base_structure, int i)
    2286             : {
    2287        7529 :         void *def_ptr = ((char *)base_structure) + parm_table[i].offset;
    2288        7529 :         switch (parm_table[i].type) {
    2289        1028 :                 case P_CMDLIST:
    2290             :                 case P_LIST:
    2291        1028 :                         return str_list_equal((const char * const *)parm_table[i].def.lvalue,
    2292             :                                               *(const char * const **)def_ptr);
    2293        3785 :                 case P_STRING:
    2294             :                 case P_USTRING:
    2295        3785 :                         return strequal(parm_table[i].def.svalue,
    2296             :                                         *(char **)def_ptr);
    2297        1416 :                 case P_BOOL:
    2298             :                 case P_BOOLREV:
    2299        1416 :                         return parm_table[i].def.bvalue ==
    2300        1416 :                                 *(bool *)def_ptr;
    2301        1300 :                 case P_INTEGER:
    2302             :                 case P_CHAR:
    2303             :                 case P_OCTAL:
    2304             :                 case P_BYTES:
    2305             :                 case P_ENUM:
    2306        1300 :                         return parm_table[i].def.ivalue ==
    2307        1300 :                                 *(int *)def_ptr;
    2308             :         }
    2309           0 :         return false;
    2310             : }
    2311             : 
    2312             : /**
    2313             :  *Display the contents of the global structure.
    2314             :  */
    2315             : 
    2316        1140 : void lpcfg_dump_globals(struct loadparm_context *lp_ctx, FILE *f,
    2317             :                          bool show_defaults)
    2318             : {
    2319             :         int i;
    2320             :         struct parmlist_entry *data;
    2321             : 
    2322        1140 :         fprintf(f, "# Global parameters\n[global]\n");
    2323             : 
    2324      590520 :         for (i = 0; parm_table[i].label; i++) {
    2325      589380 :                 if (parm_table[i].p_class != P_GLOBAL) {
    2326      178980 :                         continue;
    2327             :                 }
    2328             : 
    2329      410400 :                 if (parm_table[i].flags & FLAG_SYNONYM) {
    2330       22800 :                         continue;
    2331             :                 }
    2332             : 
    2333      387600 :                 if (!show_defaults) {
    2334      368900 :                         if (lp_ctx->flags && (lp_ctx->flags[i] & FLAG_DEFAULT)) {
    2335      362413 :                                 continue;
    2336             :                         }
    2337             : 
    2338        6487 :                         if (is_default(lp_ctx->globals, i)) {
    2339        1032 :                                 continue;
    2340             :                         }
    2341             :                 }
    2342             : 
    2343       24155 :                 fprintf(f, "\t%s = ", parm_table[i].label);
    2344       24155 :                 lpcfg_print_parameter(&parm_table[i], lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[i]), f);
    2345       24155 :                 fprintf(f, "\n");
    2346             :         }
    2347        1140 :         if (lp_ctx->globals->param_opt != NULL) {
    2348        8792 :                 for (data = lp_ctx->globals->param_opt; data;
    2349        7652 :                      data = data->next) {
    2350        7652 :                         if (!show_defaults && (data->priority & FLAG_DEFAULT)) {
    2351        1859 :                                 continue;
    2352             :                         }
    2353        5793 :                         fprintf(f, "\t%s = %s\n", data->key, data->value);
    2354             :                 }
    2355             :         }
    2356             : 
    2357        1140 : }
    2358             : 
    2359             : /**
    2360             :  * Display the contents of a single services record.
    2361             :  */
    2362             : 
    2363        3591 : void lpcfg_dump_a_service(struct loadparm_service * pService, struct loadparm_service *sDefault, FILE * f,
    2364             :                           unsigned int *flags, bool show_defaults)
    2365             : {
    2366             :         int i;
    2367             :         struct parmlist_entry *data;
    2368             : 
    2369        3591 :         if (pService != sDefault)
    2370        2451 :                 fprintf(f, "\n[%s]\n", pService->szService);
    2371             : 
    2372     1860138 :         for (i = 0; parm_table[i].label; i++) {
    2373     1856547 :                 if (parm_table[i].p_class != P_LOCAL) {
    2374     1292760 :                         continue;
    2375             :                 }
    2376             : 
    2377      563787 :                 if (parm_table[i].flags & FLAG_SYNONYM) {
    2378       64638 :                         continue;
    2379             :                 }
    2380             : 
    2381      499149 :                 if (*parm_table[i].label == '-') {
    2382        3591 :                         continue;
    2383             :                 }
    2384             : 
    2385      495558 :                 if (pService == sDefault) {
    2386      157320 :                         if (!show_defaults) {
    2387      149730 :                                 if (flags && (flags[i] & FLAG_DEFAULT)) {
    2388      148688 :                                         continue;
    2389             :                                 }
    2390             : 
    2391        1042 :                                 if (is_default(sDefault, i)) {
    2392         193 :                                         continue;
    2393             :                                 }
    2394             :                         }
    2395             :                 } else {
    2396             :                         bool equal;
    2397             : 
    2398      338238 :                         equal = lpcfg_equal_parameter(parm_table[i].type,
    2399             :                                                       ((char *)pService) +
    2400      338238 :                                                       parm_table[i].offset,
    2401             :                                                       ((char *)sDefault) +
    2402      338238 :                                                       parm_table[i].offset);
    2403      338238 :                         if (equal) {
    2404      332015 :                                 continue;
    2405             :                         }
    2406             :                 }
    2407             : 
    2408       14662 :                 fprintf(f, "\t%s = ", parm_table[i].label);
    2409       14662 :                 lpcfg_print_parameter(&parm_table[i],
    2410       14662 :                                 ((char *)pService) + parm_table[i].offset, f);
    2411       14662 :                 fprintf(f, "\n");
    2412             :         }
    2413        3591 :         if (pService->param_opt != NULL) {
    2414        5726 :                 for (data = pService->param_opt; data; data = data->next) {
    2415        4311 :                         if (!show_defaults && (data->priority & FLAG_DEFAULT)) {
    2416           0 :                                 continue;
    2417             :                         }
    2418        4311 :                         fprintf(f, "\t%s = %s\n", data->key, data->value);
    2419             :                 }
    2420             :         }
    2421        3591 : }
    2422             : 
    2423        2890 : bool lpcfg_dump_a_parameter(struct loadparm_context *lp_ctx,
    2424             :                             struct loadparm_service *service,
    2425             :                             const char *parm_name, FILE * f)
    2426             : {
    2427             :         struct parm_struct *parm;
    2428             :         void *ptr;
    2429             :         char *local_parm_name;
    2430             :         char *parm_opt;
    2431             :         const char *parm_opt_value;
    2432             : 
    2433             :         /* check for parametrical option */
    2434        2890 :         local_parm_name = talloc_strdup(lp_ctx, parm_name);
    2435        2890 :         if (local_parm_name == NULL) {
    2436           0 :                 return false;
    2437             :         }
    2438             : 
    2439        2890 :         parm_opt = strchr( local_parm_name, ':');
    2440             : 
    2441        2890 :         if (parm_opt) {
    2442         138 :                 *parm_opt = '\0';
    2443         138 :                 parm_opt++;
    2444         138 :                 if (strlen(parm_opt)) {
    2445         138 :                         parm_opt_value = lpcfg_parm_string(lp_ctx, service,
    2446             :                                 local_parm_name, parm_opt);
    2447         138 :                         if (parm_opt_value) {
    2448         138 :                                 fprintf(f, "%s\n", parm_opt_value);
    2449         138 :                                 TALLOC_FREE(local_parm_name);
    2450         138 :                                 return true;
    2451             :                         }
    2452             :                 }
    2453           0 :                 TALLOC_FREE(local_parm_name);
    2454           0 :                 return false;
    2455             :         }
    2456        2752 :         TALLOC_FREE(local_parm_name);
    2457             : 
    2458             :         /* parameter is not parametric, search the table */
    2459        2752 :         parm = lpcfg_parm_struct(lp_ctx, parm_name);
    2460        2752 :         if (!parm) {
    2461           0 :                 return false;
    2462             :         }
    2463             : 
    2464        2752 :         if (service != NULL && parm->p_class == P_GLOBAL) {
    2465           0 :                 return false;
    2466             :         }
    2467             : 
    2468        2752 :         ptr = lpcfg_parm_ptr(lp_ctx, service,parm);
    2469             : 
    2470        2752 :         lpcfg_print_parameter(parm, ptr, f);
    2471        2752 :         fprintf(f, "\n");
    2472        2752 :         return true;
    2473             : }
    2474             : 
    2475             : /**
    2476             :  * Auto-load some home services.
    2477             :  */
    2478       19439 : static void lpcfg_add_auto_services(struct loadparm_context *lp_ctx,
    2479             :                                     const char *str)
    2480             : {
    2481       19439 :         return;
    2482             : }
    2483             : 
    2484             : /***************************************************************************
    2485             :  Initialise the sDefault parameter structure for the printer values.
    2486             : ***************************************************************************/
    2487             : 
    2488       14913 : void init_printer_values(struct loadparm_context *lp_ctx, TALLOC_CTX *ctx,
    2489             :                          struct loadparm_service *pService)
    2490             : {
    2491             :         /* choose defaults depending on the type of printing */
    2492       14913 :         switch (pService->printing) {
    2493           0 :                 case PRINT_BSD:
    2494             :                 case PRINT_AIX:
    2495             :                 case PRINT_LPRNT:
    2496             :                 case PRINT_LPROS2:
    2497           0 :                         lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
    2498           0 :                         lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
    2499           0 :                         lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
    2500           0 :                         break;
    2501             : 
    2502           0 :                 case PRINT_LPRNG:
    2503             :                 case PRINT_PLP:
    2504           0 :                         lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
    2505           0 :                         lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
    2506           0 :                         lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
    2507           0 :                         lpcfg_string_set(ctx, &pService->queuepause_command, "lpc stop '%p'");
    2508           0 :                         lpcfg_string_set(ctx, &pService->queueresume_command, "lpc start '%p'");
    2509           0 :                         lpcfg_string_set(ctx, &pService->lppause_command, "lpc hold '%p' %j");
    2510           0 :                         lpcfg_string_set(ctx, &pService->lpresume_command, "lpc release '%p' %j");
    2511           0 :                         break;
    2512             : 
    2513       14913 :                 case PRINT_CUPS:
    2514             :                 case PRINT_IPRINT:
    2515             :                         /* set the lpq command to contain the destination printer
    2516             :                            name only.  This is used by cups_queue_get() */
    2517       14913 :                         lpcfg_string_set(ctx, &pService->lpq_command, "%p");
    2518       14913 :                         lpcfg_string_set(ctx, &pService->lprm_command, "");
    2519       14913 :                         lpcfg_string_set(ctx, &pService->print_command, "");
    2520       14913 :                         lpcfg_string_set(ctx, &pService->lppause_command, "");
    2521       14913 :                         lpcfg_string_set(ctx, &pService->lpresume_command, "");
    2522       14913 :                         lpcfg_string_set(ctx, &pService->queuepause_command, "");
    2523       14913 :                         lpcfg_string_set(ctx, &pService->queueresume_command, "");
    2524       14913 :                         break;
    2525             : 
    2526           0 :                 case PRINT_SYSV:
    2527             :                 case PRINT_HPUX:
    2528           0 :                         lpcfg_string_set(ctx, &pService->lpq_command, "lpstat -o%p");
    2529           0 :                         lpcfg_string_set(ctx, &pService->lprm_command, "cancel %p-%j");
    2530           0 :                         lpcfg_string_set(ctx, &pService->print_command, "lp -c -d%p %s; rm %s");
    2531           0 :                         lpcfg_string_set(ctx, &pService->queuepause_command, "disable %p");
    2532           0 :                         lpcfg_string_set(ctx, &pService->queueresume_command, "enable %p");
    2533             : #ifndef HPUX
    2534           0 :                         lpcfg_string_set(ctx, &pService->lppause_command, "lp -i %p-%j -H hold");
    2535           0 :                         lpcfg_string_set(ctx, &pService->lpresume_command, "lp -i %p-%j -H resume");
    2536             : #endif /* HPUX */
    2537           0 :                         break;
    2538             : 
    2539           0 :                 case PRINT_QNX:
    2540           0 :                         lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P%p");
    2541           0 :                         lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P%p %j");
    2542           0 :                         lpcfg_string_set(ctx, &pService->print_command, "lp -r -P%p %s");
    2543           0 :                         break;
    2544             : 
    2545             : #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
    2546             : 
    2547           0 :         case PRINT_TEST:
    2548             :         case PRINT_VLP: {
    2549             :                 const char *tdbfile;
    2550           0 :                 TALLOC_CTX *tmp_ctx = talloc_new(ctx);
    2551             :                 const char *tmp;
    2552             : 
    2553           0 :                 tmp = lpcfg_parm_string(lp_ctx, NULL, "vlp", "tdbfile");
    2554           0 :                 if (tmp == NULL) {
    2555           0 :                         tmp = "/tmp/vlp.tdb";
    2556             :                 }
    2557             : 
    2558           0 :                 tdbfile = talloc_asprintf(tmp_ctx, "tdbfile=%s", tmp);
    2559           0 :                 if (tdbfile == NULL) {
    2560           0 :                         tdbfile="tdbfile=/tmp/vlp.tdb";
    2561             :                 }
    2562             : 
    2563           0 :                 tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
    2564             :                                       tdbfile);
    2565           0 :                 lpcfg_string_set(ctx, &pService->print_command,
    2566             :                            tmp ? tmp : "vlp print %p %s");
    2567             : 
    2568           0 :                 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
    2569             :                                       tdbfile);
    2570           0 :                 lpcfg_string_set(ctx, &pService->lpq_command,
    2571             :                            tmp ? tmp : "vlp lpq %p");
    2572             : 
    2573           0 :                 tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
    2574             :                                       tdbfile);
    2575           0 :                 lpcfg_string_set(ctx, &pService->lprm_command,
    2576             :                            tmp ? tmp : "vlp lprm %p %j");
    2577             : 
    2578           0 :                 tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
    2579             :                                       tdbfile);
    2580           0 :                 lpcfg_string_set(ctx, &pService->lppause_command,
    2581             :                            tmp ? tmp : "vlp lppause %p %j");
    2582             : 
    2583           0 :                 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
    2584             :                                       tdbfile);
    2585           0 :                 lpcfg_string_set(ctx, &pService->lpresume_command,
    2586             :                            tmp ? tmp : "vlp lpresume %p %j");
    2587             : 
    2588           0 :                 tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
    2589             :                                       tdbfile);
    2590           0 :                 lpcfg_string_set(ctx, &pService->queuepause_command,
    2591             :                            tmp ? tmp : "vlp queuepause %p");
    2592             : 
    2593           0 :                 tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
    2594             :                                       tdbfile);
    2595           0 :                 lpcfg_string_set(ctx, &pService->queueresume_command,
    2596             :                            tmp ? tmp : "vlp queueresume %p");
    2597           0 :                 TALLOC_FREE(tmp_ctx);
    2598             : 
    2599           0 :                 break;
    2600             :         }
    2601             : #endif /* DEVELOPER */
    2602             : 
    2603             :         }
    2604       14913 : }
    2605             : 
    2606             : 
    2607           0 : static int lpcfg_destructor(struct loadparm_context *lp_ctx)
    2608             : {
    2609             :         struct parmlist_entry *data;
    2610             : 
    2611           0 :         if (lp_ctx->refuse_free) {
    2612             :                 /* someone is trying to free the
    2613             :                    global_loadparm_context.
    2614             :                    We can't allow that. */
    2615           0 :                 return -1;
    2616             :         }
    2617             : 
    2618           0 :         if (lp_ctx->globals->param_opt != NULL) {
    2619             :                 struct parmlist_entry *next;
    2620           0 :                 for (data = lp_ctx->globals->param_opt; data; data=next) {
    2621           0 :                         next = data->next;
    2622           0 :                         if (data->priority & FLAG_CMDLINE) continue;
    2623           0 :                         DLIST_REMOVE(lp_ctx->globals->param_opt, data);
    2624           0 :                         talloc_free(data);
    2625             :                 }
    2626             :         }
    2627             : 
    2628           0 :         return 0;
    2629             : }
    2630             : 
    2631             : /**
    2632             :  * Initialise the global parameter structure.
    2633             :  *
    2634             :  * Note that most callers should use loadparm_init_global() instead
    2635             :  */
    2636        8491 : struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
    2637             : {
    2638             :         int i;
    2639             :         char *myname;
    2640             :         struct loadparm_context *lp_ctx;
    2641             :         struct parmlist_entry *parm;
    2642             :         char *logfile;
    2643             : 
    2644        8491 :         lp_ctx = talloc_zero(mem_ctx, struct loadparm_context);
    2645        8491 :         if (lp_ctx == NULL)
    2646           0 :                 return NULL;
    2647             : 
    2648        8491 :         talloc_set_destructor(lp_ctx, lpcfg_destructor);
    2649        8491 :         lp_ctx->bInGlobalSection = true;
    2650        8491 :         lp_ctx->globals = talloc_zero(lp_ctx, struct loadparm_global);
    2651             :         /* This appears odd, but globals in s3 isn't a pointer */
    2652        8491 :         lp_ctx->globals->ctx = lp_ctx->globals;
    2653        8491 :         lp_ctx->globals->rpc_low_port = SERVER_TCP_LOW_PORT;
    2654        8491 :         lp_ctx->globals->rpc_high_port = SERVER_TCP_HIGH_PORT;
    2655        8491 :         lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_UNKNOWN;
    2656        8491 :         lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
    2657        8491 :         lp_ctx->flags = talloc_zero_array(lp_ctx, unsigned int, num_parameters());
    2658             : 
    2659        8491 :         lp_ctx->sDefault->max_print_jobs = 1000;
    2660        8491 :         lp_ctx->sDefault->available = true;
    2661        8491 :         lp_ctx->sDefault->browseable = true;
    2662        8491 :         lp_ctx->sDefault->read_only = true;
    2663        8491 :         lp_ctx->sDefault->map_archive = true;
    2664        8491 :         lp_ctx->sDefault->strict_locking = true;
    2665        8491 :         lp_ctx->sDefault->oplocks = true;
    2666        8491 :         lp_ctx->sDefault->create_mask = 0744;
    2667        8491 :         lp_ctx->sDefault->force_create_mode = 0000;
    2668        8491 :         lp_ctx->sDefault->directory_mask = 0755;
    2669        8491 :         lp_ctx->sDefault->force_directory_mode = 0000;
    2670        8491 :         lp_ctx->sDefault->aio_read_size = 1;
    2671        8491 :         lp_ctx->sDefault->aio_write_size = 1;
    2672        8491 :         lp_ctx->sDefault->smbd_search_ask_sharemode = true;
    2673        8491 :         lp_ctx->sDefault->smbd_getinfo_ask_sharemode = true;
    2674        8491 :         lp_ctx->sDefault->volume_serial_number = -1;
    2675             : 
    2676        8491 :         DEBUG(3, ("Initialising global parameters\n"));
    2677             : 
    2678     4398338 :         for (i = 0; parm_table[i].label; i++) {
    2679     4389847 :                 if ((parm_table[i].type == P_STRING ||
    2680     3201107 :                      parm_table[i].type == P_USTRING) &&
    2681     1214213 :                     !(lp_ctx->flags[i] & FLAG_CMDLINE)) {
    2682             :                         TALLOC_CTX *parent_mem;
    2683             :                         char **r;
    2684     1214213 :                         if (parm_table[i].p_class == P_LOCAL) {
    2685      297185 :                                 parent_mem = lp_ctx->sDefault;
    2686      297185 :                                 r = (char **)(((char *)lp_ctx->sDefault) + parm_table[i].offset);
    2687             :                         } else {
    2688      917028 :                                 parent_mem = lp_ctx->globals;
    2689      917028 :                                 r = (char **)(((char *)lp_ctx->globals) + parm_table[i].offset);
    2690             :                         }
    2691     1214213 :                         lpcfg_string_set(parent_mem, r, "");
    2692             :                 }
    2693             :         }
    2694             : 
    2695        8491 :         logfile = talloc_asprintf(lp_ctx, "%s/log.samba", dyn_LOGFILEBASE);
    2696        8491 :         lpcfg_do_global_parameter(lp_ctx, "log file", logfile);
    2697        8491 :         talloc_free(logfile);
    2698             : 
    2699        8491 :         lpcfg_do_global_parameter(lp_ctx, "log level", "0");
    2700             : 
    2701        8491 :         lpcfg_do_global_parameter(lp_ctx, "syslog", "1");
    2702        8491 :         lpcfg_do_global_parameter(lp_ctx, "syslog only", "No");
    2703        8491 :         lpcfg_do_global_parameter(lp_ctx, "debug timestamp", "Yes");
    2704        8491 :         lpcfg_do_global_parameter(lp_ctx, "debug prefix timestamp", "No");
    2705        8491 :         lpcfg_do_global_parameter(lp_ctx, "debug hires timestamp", "Yes");
    2706        8491 :         lpcfg_do_global_parameter(lp_ctx, "debug syslog format", "No");
    2707        8491 :         lpcfg_do_global_parameter(lp_ctx, "debug pid", "No");
    2708        8491 :         lpcfg_do_global_parameter(lp_ctx, "debug uid", "No");
    2709        8491 :         lpcfg_do_global_parameter(lp_ctx, "debug class", "No");
    2710             : 
    2711        8491 :         lpcfg_do_global_parameter(lp_ctx, "server role", "auto");
    2712        8491 :         lpcfg_do_global_parameter(lp_ctx, "domain logons", "No");
    2713        8491 :         lpcfg_do_global_parameter(lp_ctx, "domain master", "Auto");
    2714             : 
    2715             :         /* options that can be set on the command line must be initialised via
    2716             :            the slower lpcfg_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */
    2717             : #ifdef TCP_NODELAY
    2718        8491 :         lpcfg_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY");
    2719             : #endif
    2720        8491 :         lpcfg_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP);
    2721        8491 :         myname = get_myname(lp_ctx);
    2722        8491 :         lpcfg_do_global_parameter(lp_ctx, "netbios name", myname);
    2723        8491 :         talloc_free(myname);
    2724        8491 :         lpcfg_do_global_parameter(lp_ctx,
    2725             :                                   "name resolve order",
    2726             :                                   DEFAULT_NAME_RESOLVE_ORDER);
    2727             : 
    2728        8491 :         lpcfg_do_global_parameter(lp_ctx, "fstype", "NTFS");
    2729             : 
    2730        8491 :         lpcfg_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
    2731        8491 :         lpcfg_do_global_parameter(lp_ctx, "max connections", "0");
    2732             : 
    2733        8491 :         lpcfg_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper wkssvc samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver");
    2734        8491 :         lpcfg_do_global_parameter(lp_ctx, "server services", "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns");
    2735        8491 :         lpcfg_do_global_parameter(lp_ctx, "kccsrv:samba_kcc", "true");
    2736             :         /* the winbind method for domain controllers is for both RODC
    2737             :            auth forwarding and for trusted domains */
    2738        8491 :         lpcfg_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
    2739        8491 :         lpcfg_do_global_parameter(lp_ctx, "binddns dir", dyn_BINDDNS_DIR);
    2740        8491 :         lpcfg_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
    2741             : 
    2742             :         /* This hive should be dynamically generated by Samba using
    2743             :            data from the sam, but for the moment leave it in a tdb to
    2744             :            keep regedt32 from popping up an annoying dialog. */
    2745        8491 :         lpcfg_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb");
    2746             : 
    2747             :         /* using UTF8 by default allows us to support all chars */
    2748        8491 :         lpcfg_do_global_parameter(lp_ctx, "unix charset", "UTF-8");
    2749             : 
    2750             :         /* Use codepage 850 as a default for the dos character set */
    2751        8491 :         lpcfg_do_global_parameter(lp_ctx, "dos charset", "CP850");
    2752             : 
    2753             :         /*
    2754             :          * Allow the default PASSWD_CHAT to be overridden in local.h.
    2755             :          */
    2756        8491 :         lpcfg_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT);
    2757             : 
    2758        8491 :         lpcfg_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR);
    2759        8491 :         lpcfg_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR);
    2760        8491 :         lpcfg_do_global_parameter(lp_ctx, "state directory", dyn_STATEDIR);
    2761        8491 :         lpcfg_do_global_parameter(lp_ctx, "cache directory", dyn_CACHEDIR);
    2762        8491 :         lpcfg_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
    2763             : 
    2764        8491 :         lpcfg_do_global_parameter(lp_ctx, "nbt client socket address", "0.0.0.0");
    2765        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "server string",
    2766             :                                    "Samba %s", SAMBA_VERSION_STRING);
    2767             : 
    2768        8491 :         lpcfg_do_global_parameter(lp_ctx, "password server", "*");
    2769             : 
    2770        8491 :         lpcfg_do_global_parameter(lp_ctx, "max mux", "50");
    2771        8491 :         lpcfg_do_global_parameter(lp_ctx, "max xmit", "16644");
    2772        8491 :         lpcfg_do_global_parameter(lp_ctx, "host msdfs", "true");
    2773             : 
    2774        8491 :         lpcfg_do_global_parameter(lp_ctx, "LargeReadwrite", "True");
    2775        8491 :         lpcfg_do_global_parameter(lp_ctx, "server min protocol", "SMB2_02");
    2776        8491 :         lpcfg_do_global_parameter(lp_ctx, "server max protocol", "SMB3");
    2777        8491 :         lpcfg_do_global_parameter(lp_ctx, "client min protocol", "SMB2_02");
    2778        8491 :         lpcfg_do_global_parameter(lp_ctx, "client max protocol", "default");
    2779        8491 :         lpcfg_do_global_parameter(lp_ctx, "client ipc min protocol", "default");
    2780        8491 :         lpcfg_do_global_parameter(lp_ctx, "client ipc max protocol", "default");
    2781        8491 :         lpcfg_do_global_parameter(lp_ctx, "security", "AUTO");
    2782        8491 :         lpcfg_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
    2783        8491 :         lpcfg_do_global_parameter(lp_ctx, "ReadRaw", "True");
    2784        8491 :         lpcfg_do_global_parameter(lp_ctx, "WriteRaw", "True");
    2785        8491 :         lpcfg_do_global_parameter(lp_ctx, "NullPasswords", "False");
    2786        8491 :         lpcfg_do_global_parameter(lp_ctx, "old password allowed period", "60");
    2787        8491 :         lpcfg_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
    2788             : 
    2789        8491 :         lpcfg_do_global_parameter(lp_ctx, "TimeServer", "False");
    2790        8491 :         lpcfg_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False");
    2791        8491 :         lpcfg_do_global_parameter(lp_ctx, "Unicode", "True");
    2792        8491 :         lpcfg_do_global_parameter(lp_ctx, "ClientLanManAuth", "False");
    2793        8491 :         lpcfg_do_global_parameter(lp_ctx, "ClientNTLMv2Auth", "True");
    2794        8491 :         lpcfg_do_global_parameter(lp_ctx, "LanmanAuth", "False");
    2795        8491 :         lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "ntlmv2-only");
    2796        8491 :         lpcfg_do_global_parameter(lp_ctx, "NT hash store", "always");
    2797        8491 :         lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False");
    2798        8491 :         lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False");
    2799             : 
    2800        8491 :         lpcfg_do_global_parameter(lp_ctx, "allow dcerpc auth level connect", "False");
    2801             : 
    2802        8491 :         lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True");
    2803             : 
    2804        8491 :         lpcfg_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
    2805        8491 :         lpcfg_do_global_parameter(lp_ctx, "LocalMaster", "True");
    2806             : 
    2807        8491 :         lpcfg_do_global_parameter(lp_ctx, "wins support", "False");
    2808        8491 :         lpcfg_do_global_parameter(lp_ctx, "dns proxy", "True");
    2809             : 
    2810        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbind separator", "\\");
    2811        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
    2812        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbind scan trusted domains", "False");
    2813        8491 :         lpcfg_do_global_parameter(lp_ctx, "require strong key", "True");
    2814        8491 :         lpcfg_do_global_parameter(lp_ctx, "reject md5 servers", "True");
    2815        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
    2816        8491 :         lpcfg_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR);
    2817        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "gpo update command", "%s/samba-gpupdate", dyn_SCRIPTSBINDIR);
    2818        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "apply group policies", "False");
    2819        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "dns update command", "%s/samba_dnsupdate", dyn_SCRIPTSBINDIR);
    2820        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "spn update command", "%s/samba_spnupdate", dyn_SCRIPTSBINDIR);
    2821        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "samba kcc command",
    2822             :                                         "%s/samba_kcc", dyn_SCRIPTSBINDIR);
    2823             : #ifdef MIT_KDC_PATH
    2824        1520 :         lpcfg_do_global_parameter_var(lp_ctx,
    2825             :                                       "mit kdc command",
    2826             :                                       MIT_KDC_PATH);
    2827             : #endif
    2828        8491 :         lpcfg_do_global_parameter(lp_ctx, "template shell", "/bin/false");
    2829        8491 :         lpcfg_do_global_parameter(lp_ctx, "template homedir", "/home/%D/%U");
    2830             : 
    2831        8491 :         lpcfg_do_global_parameter(lp_ctx, "client signing", "default");
    2832        8491 :         lpcfg_do_global_parameter(lp_ctx, "client ipc signing", "default");
    2833        8491 :         lpcfg_do_global_parameter(lp_ctx, "server signing", "default");
    2834             : 
    2835        8491 :         lpcfg_do_global_parameter(lp_ctx, "use mmap", "True");
    2836             : 
    2837        8491 :         lpcfg_do_global_parameter(lp_ctx, "smb ports", "445 139");
    2838        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "nbt port", "%d", NBT_NAME_SERVICE_PORT);
    2839        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "dgram port", "%d", NBT_DGRAM_SERVICE_PORT);
    2840        8491 :         lpcfg_do_global_parameter(lp_ctx, "cldap port", "389");
    2841        8491 :         lpcfg_do_global_parameter(lp_ctx, "krb5 port", "88");
    2842        8491 :         lpcfg_do_global_parameter(lp_ctx, "kpasswd port", "464");
    2843        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "dns port", "%d", DNS_SERVICE_PORT);
    2844             : 
    2845        8491 :         lpcfg_do_global_parameter(lp_ctx, "kdc enable fast", "True");
    2846             : 
    2847        8491 :         lpcfg_do_global_parameter(lp_ctx, "nt status support", "True");
    2848             : 
    2849        8491 :         lpcfg_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */
    2850        8491 :         lpcfg_do_global_parameter(lp_ctx, "min wins ttl", "21600");
    2851             : 
    2852        8491 :         lpcfg_do_global_parameter(lp_ctx, "tls enabled", "True");
    2853        8491 :         lpcfg_do_global_parameter(lp_ctx, "tls verify peer", "as_strict_as_possible");
    2854        8491 :         lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
    2855        8491 :         lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
    2856        8491 :         lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
    2857        8491 :         lpcfg_do_global_parameter(lp_ctx,
    2858             :                                   "tls priority",
    2859             :                                   "NORMAL:-VERS-SSL3.0");
    2860             : 
    2861        8491 :         lpcfg_do_global_parameter(lp_ctx, "nsupdate command", "/usr/bin/nsupdate -g");
    2862             : 
    2863        8491 :         lpcfg_do_global_parameter(lp_ctx, "allow dns updates", "secure only");
    2864        8491 :         lpcfg_do_global_parameter(lp_ctx, "dns zone scavenging", "False");
    2865        8491 :         lpcfg_do_global_parameter(lp_ctx, "dns forwarder", "");
    2866             : 
    2867        8491 :         lpcfg_do_global_parameter(lp_ctx, "algorithmic rid base", "1000");
    2868             : 
    2869        8491 :         lpcfg_do_global_parameter(lp_ctx, "enhanced browsing", "True");
    2870             : 
    2871        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbind nss info", "template");
    2872             : 
    2873        8491 :         lpcfg_do_global_parameter(lp_ctx, "server schannel", "True");
    2874        8491 :         lpcfg_do_global_parameter(lp_ctx, "server schannel require seal", "True");
    2875        8491 :         lpcfg_do_global_parameter(lp_ctx, "reject md5 clients", "True");
    2876             : 
    2877        8491 :         lpcfg_do_global_parameter(lp_ctx, "short preserve case", "True");
    2878             : 
    2879        8491 :         lpcfg_do_global_parameter(lp_ctx, "max open files", "16384");
    2880             : 
    2881        8491 :         lpcfg_do_global_parameter(lp_ctx, "cups connection timeout", "30");
    2882             : 
    2883        8491 :         lpcfg_do_global_parameter(lp_ctx, "locking", "True");
    2884             : 
    2885        8491 :         lpcfg_do_global_parameter(lp_ctx, "block size", "1024");
    2886             : 
    2887        8491 :         lpcfg_do_global_parameter(lp_ctx, "client use spnego", "True");
    2888             : 
    2889        8491 :         lpcfg_do_global_parameter(lp_ctx, "change notify", "True");
    2890             : 
    2891        8491 :         lpcfg_do_global_parameter(lp_ctx, "name cache timeout", "660");
    2892             : 
    2893        8491 :         lpcfg_do_global_parameter(lp_ctx, "defer sharing violations", "True");
    2894             : 
    2895        8491 :         lpcfg_do_global_parameter(lp_ctx, "ldap replication sleep", "1000");
    2896             : 
    2897        8491 :         lpcfg_do_global_parameter(lp_ctx, "idmap backend", "tdb");
    2898             : 
    2899        8491 :         lpcfg_do_global_parameter(lp_ctx, "enable privileges", "True");
    2900             : 
    2901        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max write", "%u", DEFAULT_SMB2_MAX_WRITE);
    2902             : 
    2903        8491 :         lpcfg_do_global_parameter(lp_ctx, "passdb backend", "tdbsam");
    2904             : 
    2905        8491 :         lpcfg_do_global_parameter(lp_ctx, "deadtime", "10080");
    2906             : 
    2907        8491 :         lpcfg_do_global_parameter(lp_ctx, "getwd cache", "True");
    2908             : 
    2909        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbind nested groups", "True");
    2910             : 
    2911        8491 :         lpcfg_do_global_parameter(lp_ctx, "mangled names", "illegal");
    2912             : 
    2913        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max credits", "%u", DEFAULT_SMB2_MAX_CREDITS);
    2914             : 
    2915        8491 :         lpcfg_do_global_parameter(lp_ctx, "ldap ssl", "start tls");
    2916             : 
    2917        8491 :         lpcfg_do_global_parameter(lp_ctx, "ldap deref", "auto");
    2918             : 
    2919        8491 :         lpcfg_do_global_parameter(lp_ctx, "lm interval", "60");
    2920             : 
    2921        8491 :         lpcfg_do_global_parameter(lp_ctx, "mangling method", "hash2");
    2922             : 
    2923        8491 :         lpcfg_do_global_parameter(lp_ctx, "hide dot files", "True");
    2924             : 
    2925        8491 :         lpcfg_do_global_parameter(lp_ctx, "browse list", "True");
    2926             : 
    2927        8491 :         lpcfg_do_global_parameter(lp_ctx, "passwd chat timeout", "2");
    2928             : 
    2929        8491 :         lpcfg_do_global_parameter(lp_ctx, "guest account", GUEST_ACCOUNT);
    2930             : 
    2931        8491 :         lpcfg_do_global_parameter(lp_ctx, "client schannel", "True");
    2932             : 
    2933        8491 :         lpcfg_do_global_parameter(lp_ctx, "smb encrypt", "default");
    2934             : 
    2935        8491 :         lpcfg_do_global_parameter(lp_ctx, "max log size", "5000");
    2936             : 
    2937        8491 :         lpcfg_do_global_parameter(lp_ctx, "idmap negative cache time", "120");
    2938             : 
    2939        8491 :         lpcfg_do_global_parameter(lp_ctx, "ldap follow referral", "auto");
    2940             : 
    2941        8491 :         lpcfg_do_global_parameter(lp_ctx, "multicast dns register", "yes");
    2942             : 
    2943        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbind reconnect delay", "30");
    2944             : 
    2945        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbind request timeout", "60");
    2946             : 
    2947        8491 :         lpcfg_do_global_parameter(lp_ctx, "nt acl support", "yes");
    2948             : 
    2949        8491 :         lpcfg_do_global_parameter(lp_ctx, "acl check permissions", "yes");
    2950             : 
    2951        8491 :         lpcfg_do_global_parameter(lp_ctx, "keepalive", "300");
    2952             : 
    2953        8491 :         lpcfg_do_global_parameter(lp_ctx, "smbd profiling level", "off");
    2954             : 
    2955        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbind cache time", "300");
    2956             : 
    2957        8491 :         lpcfg_do_global_parameter(lp_ctx, "level2 oplocks", "yes");
    2958             : 
    2959        8491 :         lpcfg_do_global_parameter(lp_ctx, "show add printer wizard", "yes");
    2960             : 
    2961        8491 :         lpcfg_do_global_parameter(lp_ctx, "ldap page size", "1000");
    2962             : 
    2963        8491 :         lpcfg_do_global_parameter(lp_ctx, "kernel share modes", "no");
    2964             : 
    2965        8491 :         lpcfg_do_global_parameter(lp_ctx, "strict locking", "Auto");
    2966             : 
    2967        8491 :         lpcfg_do_global_parameter(lp_ctx, "strict sync", "yes");
    2968             : 
    2969        8491 :         lpcfg_do_global_parameter(lp_ctx, "map readonly", "no");
    2970             : 
    2971        8491 :         lpcfg_do_global_parameter(lp_ctx, "allow trusted domains", "yes");
    2972             : 
    2973        8491 :         lpcfg_do_global_parameter(lp_ctx, "default devmode", "yes");
    2974             : 
    2975        8491 :         lpcfg_do_global_parameter(lp_ctx, "os level", "20");
    2976             : 
    2977        8491 :         lpcfg_do_global_parameter(lp_ctx, "dos filetimes", "yes");
    2978             : 
    2979        8491 :         lpcfg_do_global_parameter(lp_ctx, "mangling char", "~");
    2980             : 
    2981        8491 :         lpcfg_do_global_parameter(lp_ctx, "printcap cache time", "750");
    2982             : 
    2983        8491 :         lpcfg_do_global_parameter(lp_ctx, "create krb5 conf", "yes");
    2984             : 
    2985        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbind max clients", "200");
    2986             : 
    2987        8491 :         lpcfg_do_global_parameter(lp_ctx, "acl map full control", "yes");
    2988             : 
    2989        8491 :         lpcfg_do_global_parameter(lp_ctx, "nt pipe support", "yes");
    2990             : 
    2991        8491 :         lpcfg_do_global_parameter(lp_ctx, "ldap debug threshold", "10");
    2992             : 
    2993        8491 :         lpcfg_do_global_parameter(lp_ctx, "client ldap sasl wrapping", "seal");
    2994             : 
    2995        8491 :         lpcfg_do_global_parameter(lp_ctx, "mdns name", "netbios");
    2996             : 
    2997        8491 :         lpcfg_do_global_parameter(lp_ctx, "ldap server require strong auth", "yes");
    2998             : 
    2999        8491 :         lpcfg_do_global_parameter(lp_ctx, "follow symlinks", "yes");
    3000             : 
    3001        8491 :         lpcfg_do_global_parameter(lp_ctx, "machine password timeout", "604800");
    3002             : 
    3003        8491 :         lpcfg_do_global_parameter(lp_ctx, "ldap connection timeout", "2");
    3004             : 
    3005        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbind expand groups", "0");
    3006             : 
    3007        8491 :         lpcfg_do_global_parameter(lp_ctx, "stat cache", "yes");
    3008             : 
    3009        8491 :         lpcfg_do_global_parameter(lp_ctx, "lpq cache time", "30");
    3010             : 
    3011        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max trans", "%u", DEFAULT_SMB2_MAX_TRANSACT);
    3012             : 
    3013        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max read", "%u", DEFAULT_SMB2_MAX_READ);
    3014             : 
    3015        8491 :         lpcfg_do_global_parameter(lp_ctx, "durable handles", "yes");
    3016             : 
    3017        8491 :         lpcfg_do_global_parameter(lp_ctx, "max stat cache size", "512");
    3018             : 
    3019        8491 :         lpcfg_do_global_parameter(lp_ctx, "ldap passwd sync", "no");
    3020             : 
    3021        8491 :         lpcfg_do_global_parameter(lp_ctx, "kernel change notify", "yes");
    3022             : 
    3023        8491 :         lpcfg_do_global_parameter(lp_ctx, "max ttl", "259200");
    3024             : 
    3025        8491 :         lpcfg_do_global_parameter(lp_ctx, "blocking locks", "yes");
    3026             : 
    3027        8491 :         lpcfg_do_global_parameter(lp_ctx, "load printers", "yes");
    3028             : 
    3029        8491 :         lpcfg_do_global_parameter(lp_ctx, "idmap cache time", "604800");
    3030             : 
    3031        8491 :         lpcfg_do_global_parameter(lp_ctx, "preserve case", "yes");
    3032             : 
    3033        8491 :         lpcfg_do_global_parameter(lp_ctx, "lm announce", "auto");
    3034             : 
    3035        8491 :         lpcfg_do_global_parameter(lp_ctx, "afs token lifetime", "604800");
    3036             : 
    3037        8491 :         lpcfg_do_global_parameter(lp_ctx, "enable core files", "yes");
    3038             : 
    3039        8491 :         lpcfg_do_global_parameter(lp_ctx, "winbind max domain connections", "1");
    3040             : 
    3041        8491 :         lpcfg_do_global_parameter(lp_ctx, "case sensitive", "auto");
    3042             : 
    3043        8491 :         lpcfg_do_global_parameter(lp_ctx, "ldap timeout", "15");
    3044             : 
    3045        8491 :         lpcfg_do_global_parameter(lp_ctx, "mangle prefix", "1");
    3046             : 
    3047        8491 :         lpcfg_do_global_parameter(lp_ctx, "posix locking", "yes");
    3048             : 
    3049        8491 :         lpcfg_do_global_parameter(lp_ctx, "lock spin time", "200");
    3050             : 
    3051        8491 :         lpcfg_do_global_parameter(lp_ctx, "directory name cache size", "100");
    3052             : 
    3053        8491 :         lpcfg_do_global_parameter(lp_ctx, "nmbd bind explicit broadcast", "yes");
    3054             : 
    3055        8491 :         lpcfg_do_global_parameter(lp_ctx, "init logon delay", "100");
    3056             : 
    3057        8491 :         lpcfg_do_global_parameter(lp_ctx, "usershare owner only", "yes");
    3058             : 
    3059        8491 :         lpcfg_do_global_parameter(lp_ctx, "-valid", "yes");
    3060             : 
    3061        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "usershare path", "%s/usershares", get_dyn_STATEDIR());
    3062             : 
    3063             : #ifdef DEVELOPER
    3064        8491 :         lpcfg_do_global_parameter_var(lp_ctx, "panic action", "/bin/sleep 999999999");
    3065             : #endif
    3066             : 
    3067        8491 :         lpcfg_do_global_parameter(lp_ctx, "smb passwd file", get_dyn_SMB_PASSWD_FILE());
    3068             : 
    3069        8491 :         lpcfg_do_global_parameter(lp_ctx, "logon home", "\\\\%N\\%U");
    3070             : 
    3071        8491 :         lpcfg_do_global_parameter(lp_ctx, "logon path", "\\\\%N\\%U\\profile");
    3072             : 
    3073        8491 :         lpcfg_do_global_parameter(lp_ctx, "printjob username", "%U");
    3074             : 
    3075        8491 :         lpcfg_do_global_parameter(lp_ctx, "aio max threads", "100");
    3076             : 
    3077        8491 :         lpcfg_do_global_parameter(lp_ctx, "smb2 leases", "yes");
    3078             : 
    3079        8491 :         lpcfg_do_global_parameter(lp_ctx, "server multi channel support", "yes");
    3080             : 
    3081        8491 :         lpcfg_do_global_parameter(lp_ctx, "kerberos encryption types", "all");
    3082             : 
    3083        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3084             :                                   "rpc server dynamic port range",
    3085             :                                   "49152-65535");
    3086             : 
    3087        8491 :         lpcfg_do_global_parameter(lp_ctx, "prefork children", "4");
    3088        8491 :         lpcfg_do_global_parameter(lp_ctx, "prefork backoff increment", "10");
    3089        8491 :         lpcfg_do_global_parameter(lp_ctx, "prefork maximum backoff", "120");
    3090             : 
    3091        8491 :         lpcfg_do_global_parameter(lp_ctx, "check parent directory delete on close", "no");
    3092             : 
    3093        8491 :         lpcfg_do_global_parameter(lp_ctx, "ea support", "yes");
    3094             : 
    3095        8491 :         lpcfg_do_global_parameter(lp_ctx, "store dos attributes", "yes");
    3096             : 
    3097        8491 :         lpcfg_do_global_parameter(lp_ctx, "debug encryption", "no");
    3098             : 
    3099        8491 :         lpcfg_do_global_parameter(lp_ctx, "spotlight backend", "noindex");
    3100             : 
    3101        8491 :         lpcfg_do_global_parameter(
    3102             :                 lp_ctx, "ldap max anonymous request size", "256000");
    3103        8491 :         lpcfg_do_global_parameter(
    3104             :                 lp_ctx, "ldap max authenticated request size", "16777216");
    3105        8491 :         lpcfg_do_global_parameter(
    3106             :                 lp_ctx, "ldap max search request size", "256000");
    3107             : 
    3108             :         /* Async DNS query timeout in seconds. */
    3109        8491 :         lpcfg_do_global_parameter(lp_ctx, "async dns timeout", "10");
    3110             : 
    3111        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3112             :                                   "client smb encrypt",
    3113             :                                   "default");
    3114             : 
    3115        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3116             :                                   "client use kerberos",
    3117             :                                   "desired");
    3118             : 
    3119        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3120             :                                   "client protection",
    3121             :                                   "default");
    3122             : 
    3123        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3124             :                                   "smbd max xattr size",
    3125             :                                   "65536");
    3126             : 
    3127        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3128             :                                   "acl flag inherited canonicalization",
    3129             :                                   "yes");
    3130             : 
    3131        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3132             :                                   "winbind use krb5 enterprise principals",
    3133             :                                   "yes");
    3134             : 
    3135        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3136             :                                   "client smb3 signing algorithms",
    3137             :                                   DEFAULT_SMB3_SIGNING_ALGORITHMS);
    3138        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3139             :                                   "server smb3 signing algorithms",
    3140             :                                   DEFAULT_SMB3_SIGNING_ALGORITHMS);
    3141             : 
    3142        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3143             :                                   "client smb3 encryption algorithms",
    3144             :                                   DEFAULT_SMB3_ENCRYPTION_ALGORITHMS);
    3145        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3146             :                                   "server smb3 encryption algorithms",
    3147             :                                   DEFAULT_SMB3_ENCRYPTION_ALGORITHMS);
    3148             : 
    3149        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3150             :                                   "min domain uid",
    3151             :                                   "1000");
    3152             : 
    3153        8491 :         lpcfg_do_global_parameter(lp_ctx,
    3154             :                                   "rpc start on demand helpers",
    3155             :                                   "yes");
    3156             : 
    3157     4398338 :         for (i = 0; parm_table[i].label; i++) {
    3158     4389847 :                 if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
    3159     4389847 :                         lp_ctx->flags[i] |= FLAG_DEFAULT;
    3160             :                 }
    3161             :         }
    3162             : 
    3163       33964 :         for (parm=lp_ctx->globals->param_opt; parm; parm=parm->next) {
    3164       25473 :                 if (!(parm->priority & FLAG_CMDLINE)) {
    3165       25473 :                         parm->priority |= FLAG_DEFAULT;
    3166             :                 }
    3167             :         }
    3168             : 
    3169        8491 :         for (parm=lp_ctx->sDefault->param_opt; parm; parm=parm->next) {
    3170           0 :                 if (!(parm->priority & FLAG_CMDLINE)) {
    3171           0 :                         parm->priority |= FLAG_DEFAULT;
    3172             :                 }
    3173             :         }
    3174             : 
    3175        8491 :         return lp_ctx;
    3176             : }
    3177             : 
    3178             : /**
    3179             :  * Initialise the global parameter structure.
    3180             :  */
    3181       48485 : struct loadparm_context *loadparm_init_global(bool load_default)
    3182             : {
    3183       48485 :         if (global_loadparm_context == NULL) {
    3184        8440 :                 global_loadparm_context = loadparm_init(NULL);
    3185             :         }
    3186       48485 :         if (global_loadparm_context == NULL) {
    3187           0 :                 return NULL;
    3188             :         }
    3189       48485 :         global_loadparm_context->global = true;
    3190       48485 :         if (load_default && !global_loadparm_context->loaded) {
    3191          15 :                 lpcfg_load_default(global_loadparm_context);
    3192             :         }
    3193       48485 :         global_loadparm_context->refuse_free = true;
    3194       48485 :         return global_loadparm_context;
    3195             : }
    3196             : 
    3197             : /**
    3198             :  * Initialise the global parameter structure.
    3199             :  */
    3200      154389 : struct loadparm_context *loadparm_init_s3(TALLOC_CTX *mem_ctx,
    3201             :                                           const struct loadparm_s3_helpers *s3_fns)
    3202             : {
    3203      154389 :         struct loadparm_context *loadparm_context = talloc_zero(mem_ctx, struct loadparm_context);
    3204      154389 :         if (!loadparm_context) {
    3205           0 :                 return NULL;
    3206             :         }
    3207      154389 :         loadparm_context->s3_fns = s3_fns;
    3208      154389 :         loadparm_context->globals = s3_fns->globals;
    3209      154389 :         loadparm_context->flags = s3_fns->flags;
    3210             : 
    3211      154389 :         return loadparm_context;
    3212             : }
    3213             : 
    3214      251760 : const char *lpcfg_configfile(struct loadparm_context *lp_ctx)
    3215             : {
    3216      251760 :         return lp_ctx->szConfigFile;
    3217             : }
    3218             : 
    3219       20073 : const char *lp_default_path(void)
    3220             : {
    3221       20073 :     if (getenv("SMB_CONF_PATH"))
    3222       19743 :         return getenv("SMB_CONF_PATH");
    3223             :     else
    3224         330 :         return dyn_CONFIGFILE;
    3225             : }
    3226             : 
    3227             : /**
    3228             :  * Update the internal state of a loadparm context after settings
    3229             :  * have changed.
    3230             :  */
    3231       19439 : static bool lpcfg_update(struct loadparm_context *lp_ctx)
    3232             : {
    3233             :         struct debug_settings settings;
    3234             :         int max_protocol, min_protocol;
    3235             :         TALLOC_CTX *tmp_ctx;
    3236             :         const struct loadparm_substitution *lp_sub =
    3237       19439 :                 lpcfg_noop_substitution();
    3238             : 
    3239       19439 :         tmp_ctx = talloc_new(lp_ctx);
    3240       19439 :         if (tmp_ctx == NULL) {
    3241           0 :                 return false;
    3242             :         }
    3243             : 
    3244       19439 :         lpcfg_add_auto_services(lp_ctx, lpcfg_auto_services(lp_ctx, lp_sub, tmp_ctx));
    3245             : 
    3246       19439 :         if (!lp_ctx->globals->wins_server_list && lp_ctx->globals->we_are_a_wins_server) {
    3247        3563 :                 lpcfg_do_global_parameter(lp_ctx, "wins server", "127.0.0.1");
    3248             :         }
    3249             : 
    3250       19439 :         if (!lp_ctx->global) {
    3251          79 :                 TALLOC_FREE(tmp_ctx);
    3252          79 :                 return true;
    3253             :         }
    3254             : 
    3255       19360 :         panic_action = lp_ctx->globals->panic_action;
    3256             : 
    3257       19360 :         reload_charcnv(lp_ctx);
    3258             : 
    3259       19360 :         ZERO_STRUCT(settings);
    3260             :         /* Add any more debug-related smb.conf parameters created in
    3261             :          * future here */
    3262       19360 :         settings.timestamp_logs = lp_ctx->globals->timestamp_logs;
    3263       19360 :         settings.debug_prefix_timestamp = lp_ctx->globals->debug_prefix_timestamp;
    3264       19360 :         settings.debug_hires_timestamp = lp_ctx->globals->debug_hires_timestamp;
    3265       19360 :         settings.debug_syslog_format = lp_ctx->globals->debug_syslog_format;
    3266       19360 :         settings.debug_pid = lp_ctx->globals->debug_pid;
    3267       19360 :         settings.debug_uid = lp_ctx->globals->debug_uid;
    3268       19360 :         settings.debug_class = lp_ctx->globals->debug_class;
    3269       19360 :         settings.max_log_size = lp_ctx->globals->max_log_size;
    3270       19360 :         debug_set_settings(&settings, lp_ctx->globals->logging,
    3271       19360 :                            lp_ctx->globals->syslog,
    3272       19360 :                            lp_ctx->globals->syslog_only);
    3273             : 
    3274             :         /* FIXME: This is a bit of a hack, but we can't use a global, since
    3275             :          * not everything that uses lp also uses the socket library */
    3276       19360 :         if (lpcfg_parm_bool(lp_ctx, NULL, "socket", "testnonblock", false)) {
    3277         176 :                 setenv("SOCKET_TESTNONBLOCK", "1", 1);
    3278             :         } else {
    3279       19184 :                 unsetenv("SOCKET_TESTNONBLOCK");
    3280             :         }
    3281             : 
    3282             :         /* Check if command line max protocol < min protocol, if so
    3283             :          * report a warning to the user.
    3284             :          */
    3285       19360 :         max_protocol = lpcfg_client_max_protocol(lp_ctx);
    3286       19360 :         min_protocol = lpcfg_client_min_protocol(lp_ctx);
    3287       19360 :         if (lpcfg_client_max_protocol(lp_ctx) < lpcfg_client_min_protocol(lp_ctx)) {
    3288             :                 const char *max_protocolp, *min_protocolp;
    3289           0 :                 max_protocolp = lpcfg_get_smb_protocol(max_protocol);
    3290           0 :                 min_protocolp = lpcfg_get_smb_protocol(min_protocol);
    3291           0 :                 DBG_ERR("Max protocol %s is less than min protocol %s.\n",
    3292             :                         max_protocolp, min_protocolp);
    3293             :         }
    3294             : 
    3295       19360 :         TALLOC_FREE(tmp_ctx);
    3296       19360 :         return true;
    3297             : }
    3298             : 
    3299          18 : bool lpcfg_load_default(struct loadparm_context *lp_ctx)
    3300             : {
    3301             :     const char *path;
    3302             : 
    3303          18 :     path = lp_default_path();
    3304             : 
    3305          18 :     if (!file_exist(path)) {
    3306             :             /* We allow the default smb.conf file to not exist,
    3307             :              * basically the equivalent of an empty file. */
    3308           2 :             return lpcfg_update(lp_ctx);
    3309             :     }
    3310             : 
    3311          16 :     return lpcfg_load(lp_ctx, path);
    3312             : }
    3313             : 
    3314             : /**
    3315             :  * Load the services array from the services file.
    3316             :  *
    3317             :  * Return True on success, False on failure.
    3318             :  */
    3319       20333 : static bool lpcfg_load_internal(struct loadparm_context *lp_ctx,
    3320             :                                 const char *filename, bool set_global)
    3321             : {
    3322             :         char *n2;
    3323             :         bool bRetval;
    3324             : 
    3325       20333 :         if (lp_ctx->szConfigFile != NULL) {
    3326       11453 :                 talloc_free(discard_const_p(char, lp_ctx->szConfigFile));
    3327       11453 :                 lp_ctx->szConfigFile = NULL;
    3328             :         }
    3329             : 
    3330       20333 :         lp_ctx->szConfigFile = talloc_strdup(lp_ctx, filename);
    3331             : 
    3332       20333 :         if (lp_ctx->s3_fns) {
    3333         803 :                 return lp_ctx->s3_fns->load(filename);
    3334             :         }
    3335             : 
    3336       19530 :         lp_ctx->bInGlobalSection = true;
    3337       19530 :         n2 = standard_sub_basic(lp_ctx, lp_ctx->szConfigFile);
    3338       19530 :         DEBUG(2, ("lpcfg_load: refreshing parameters from %s\n", n2));
    3339             : 
    3340       19530 :         add_to_file_list(lp_ctx, &lp_ctx->file_lists, lp_ctx->szConfigFile, n2);
    3341             : 
    3342             :         /* We get sections first, so have to start 'behind' to make up */
    3343       19530 :         lp_ctx->currentService = NULL;
    3344       19530 :         bRetval = pm_process(n2, do_section, lpcfg_do_parameter, lp_ctx);
    3345             : 
    3346             :         /* finish up the last section */
    3347       19530 :         DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
    3348       19530 :         if (bRetval)
    3349       19437 :                 if (lp_ctx->currentService != NULL)
    3350       11067 :                         bRetval = lpcfg_service_ok(lp_ctx->currentService);
    3351             : 
    3352       19530 :         bRetval = bRetval && lpcfg_update(lp_ctx);
    3353             : 
    3354             :         /* we do this unconditionally, so that it happens even
    3355             :            for a missing smb.conf */
    3356       19530 :         reload_charcnv(lp_ctx);
    3357             : 
    3358       19530 :         if (bRetval == true && set_global) {
    3359             :                 /* set this up so that any child python tasks will
    3360             :                    find the right smb.conf */
    3361       19386 :                 setenv("SMB_CONF_PATH", filename, 1);
    3362             : 
    3363             :                 /* set the context used by the lp_*() function
    3364             :                    varients */
    3365       19386 :                 global_loadparm_context = lp_ctx;
    3366       19386 :                 lp_ctx->loaded = true;
    3367             :         }
    3368             : 
    3369       19530 :         return bRetval;
    3370             : }
    3371             : 
    3372          51 : bool lpcfg_load_no_global(struct loadparm_context *lp_ctx, const char *filename)
    3373             : {
    3374          51 :     return lpcfg_load_internal(lp_ctx, filename, false);
    3375             : }
    3376             : 
    3377       20282 : bool lpcfg_load(struct loadparm_context *lp_ctx, const char *filename)
    3378             : {
    3379       20282 :     return lpcfg_load_internal(lp_ctx, filename, true);
    3380             : }
    3381             : 
    3382             : /**
    3383             :  * Return the max number of services.
    3384             :  */
    3385             : 
    3386        4212 : int lpcfg_numservices(struct loadparm_context *lp_ctx)
    3387             : {
    3388        4212 :         if (lp_ctx->s3_fns) {
    3389           0 :                 return lp_ctx->s3_fns->get_numservices();
    3390             :         }
    3391             : 
    3392        4212 :         return lp_ctx->iNumServices;
    3393             : }
    3394             : 
    3395             : /**
    3396             :  * Display the contents of the services array in human-readable form.
    3397             :  */
    3398             : 
    3399         674 : void lpcfg_dump(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults,
    3400             :              int maxtoprint)
    3401             : {
    3402             :         int iService;
    3403             : 
    3404         674 :         if (lp_ctx->s3_fns) {
    3405           0 :                 lp_ctx->s3_fns->dump(f, show_defaults, maxtoprint);
    3406           0 :                 return;
    3407             :         }
    3408             : 
    3409         674 :         lpcfg_dump_globals(lp_ctx, f, show_defaults);
    3410             : 
    3411         674 :         lpcfg_dump_a_service(lp_ctx->sDefault, lp_ctx->sDefault, f, lp_ctx->flags, show_defaults);
    3412             : 
    3413        2893 :         for (iService = 0; iService < maxtoprint; iService++)
    3414        2219 :                 lpcfg_dump_one(f, show_defaults, lp_ctx->services[iService], lp_ctx->sDefault);
    3415             : }
    3416             : 
    3417             : /**
    3418             :  * Display the contents of one service in human-readable form.
    3419             :  */
    3420        2219 : void lpcfg_dump_one(FILE *f, bool show_defaults, struct loadparm_service *service, struct loadparm_service *sDefault)
    3421             : {
    3422        2219 :         if (service != NULL) {
    3423        2219 :                 if (service->szService[0] == '\0')
    3424           0 :                         return;
    3425        2219 :                 lpcfg_dump_a_service(service, sDefault, f, NULL, show_defaults);
    3426             :         }
    3427             : }
    3428             : 
    3429        4274 : struct loadparm_service *lpcfg_servicebynum(struct loadparm_context *lp_ctx,
    3430             :                                             int snum)
    3431             : {
    3432        4274 :         if (lp_ctx->s3_fns) {
    3433           0 :                 return lp_ctx->s3_fns->get_servicebynum(snum);
    3434             :         }
    3435             : 
    3436        4274 :         return lp_ctx->services[snum];
    3437             : }
    3438             : 
    3439        7589 : struct loadparm_service *lpcfg_service(struct loadparm_context *lp_ctx,
    3440             :                                     const char *service_name)
    3441             : {
    3442             :         int iService;
    3443             :         char *serviceName;
    3444             : 
    3445        7589 :         if (lp_ctx->s3_fns) {
    3446           0 :                 return lp_ctx->s3_fns->get_service(service_name);
    3447             :         }
    3448             : 
    3449       57325 :         for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--) {
    3450       57248 :                 if (lp_ctx->services[iService] &&
    3451       57248 :                     lp_ctx->services[iService]->szService) {
    3452             :                         /*
    3453             :                          * The substitution here is used to support %U is
    3454             :                          * service names
    3455             :                          */
    3456       57248 :                         serviceName = standard_sub_basic(
    3457       57248 :                                         lp_ctx->services[iService],
    3458       57248 :                                         lp_ctx->services[iService]->szService);
    3459       57248 :                         if (strequal(serviceName, service_name)) {
    3460        7512 :                                 talloc_free(serviceName);
    3461        7512 :                                 return lp_ctx->services[iService];
    3462             :                         }
    3463       49736 :                         talloc_free(serviceName);
    3464             :                 }
    3465             :         }
    3466             : 
    3467          77 :         DEBUG(7,("lpcfg_servicenumber: couldn't find %s\n", service_name));
    3468          77 :         return NULL;
    3469             : }
    3470             : 
    3471        7854 : const char *lpcfg_servicename(const struct loadparm_service *service)
    3472             : {
    3473        7854 :         return service ? lpcfg_string((const char *)service->szService) : NULL;
    3474             : }
    3475             : 
    3476          54 : struct smb_iconv_handle *lpcfg_iconv_handle(struct loadparm_context *lp_ctx)
    3477             : {
    3478          54 :         if (lp_ctx == NULL) {
    3479           0 :                 return get_iconv_handle();
    3480             :         }
    3481          54 :         return lp_ctx->iconv_handle;
    3482             : }
    3483             : 
    3484       55029 : _PUBLIC_ void reload_charcnv(struct loadparm_context *lp_ctx)
    3485             : {
    3486       55029 :         if (!lp_ctx->global) {
    3487          79 :                 return;
    3488             :         }
    3489             : 
    3490       54950 :         lp_ctx->iconv_handle =
    3491       54950 :                 reinit_iconv_handle(lp_ctx,
    3492             :                                     lpcfg_dos_charset(lp_ctx),
    3493             :                                     lpcfg_unix_charset(lp_ctx));
    3494       54950 :         if (lp_ctx->iconv_handle == NULL) {
    3495           0 :                 smb_panic("reinit_iconv_handle failed");
    3496             :         }
    3497             : }
    3498             : 
    3499          50 : _PUBLIC_ char *lpcfg_tls_keyfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3500             : {
    3501          50 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_keyfile(lp_ctx));
    3502             : }
    3503             : 
    3504          50 : _PUBLIC_ char *lpcfg_tls_certfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3505             : {
    3506          50 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_certfile(lp_ctx));
    3507             : }
    3508             : 
    3509         455 : _PUBLIC_ char *lpcfg_tls_cafile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3510             : {
    3511         455 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_cafile(lp_ctx));
    3512             : }
    3513             : 
    3514         455 : _PUBLIC_ char *lpcfg_tls_crlfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3515             : {
    3516         455 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_crlfile(lp_ctx));
    3517             : }
    3518             : 
    3519          50 : _PUBLIC_ char *lpcfg_tls_dhpfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3520             : {
    3521          50 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_dhpfile(lp_ctx));
    3522             : }
    3523             : 
    3524      131098 : struct gensec_settings *lpcfg_gensec_settings(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3525             : {
    3526      131098 :         struct gensec_settings *settings = talloc_zero(mem_ctx, struct gensec_settings);
    3527      131098 :         if (settings == NULL)
    3528           0 :                 return NULL;
    3529      131098 :         SMB_ASSERT(lp_ctx != NULL);
    3530      131098 :         settings->lp_ctx = talloc_reference(settings, lp_ctx);
    3531      131098 :         settings->target_hostname = lpcfg_parm_string(lp_ctx, NULL, "gensec", "target_hostname");
    3532      131098 :         return settings;
    3533             : }
    3534             : 
    3535      363500 : int lpcfg_server_role(struct loadparm_context *lp_ctx)
    3536             : {
    3537      363500 :         int domain_master = lpcfg__domain_master(lp_ctx);
    3538             : 
    3539      727000 :         return lp_find_server_role(lpcfg__server_role(lp_ctx),
    3540             :                                    lpcfg__security(lp_ctx),
    3541      363500 :                                    lpcfg__domain_logons(lp_ctx),
    3542             :                                    (domain_master == true) ||
    3543             :                                    (domain_master == Auto));
    3544             : }
    3545             : 
    3546       44384 : int lpcfg_security(struct loadparm_context *lp_ctx)
    3547             : {
    3548       44384 :         return lp_find_security(lpcfg__server_role(lp_ctx),
    3549             :                                 lpcfg__security(lp_ctx));
    3550             : }
    3551             : 
    3552       38720 : int lpcfg_client_max_protocol(struct loadparm_context *lp_ctx)
    3553             : {
    3554       38720 :         int client_max_protocol = lpcfg__client_max_protocol(lp_ctx);
    3555       38720 :         if (client_max_protocol == PROTOCOL_DEFAULT) {
    3556       38704 :                 return PROTOCOL_LATEST;
    3557             :         }
    3558          16 :         return client_max_protocol;
    3559             : }
    3560             : 
    3561        3650 : int lpcfg_client_ipc_min_protocol(struct loadparm_context *lp_ctx)
    3562             : {
    3563        3650 :         int client_ipc_min_protocol = lpcfg__client_ipc_min_protocol(lp_ctx);
    3564        3650 :         if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
    3565        3650 :                 client_ipc_min_protocol = lpcfg_client_min_protocol(lp_ctx);
    3566             :         }
    3567        3650 :         if (client_ipc_min_protocol < PROTOCOL_NT1) {
    3568        3389 :                 return PROTOCOL_NT1;
    3569             :         }
    3570         261 :         return client_ipc_min_protocol;
    3571             : }
    3572             : 
    3573        3650 : int lpcfg_client_ipc_max_protocol(struct loadparm_context *lp_ctx)
    3574             : {
    3575        3650 :         int client_ipc_max_protocol = lpcfg__client_ipc_max_protocol(lp_ctx);
    3576        3650 :         if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
    3577        3650 :                 return PROTOCOL_LATEST;
    3578             :         }
    3579           0 :         if (client_ipc_max_protocol < PROTOCOL_NT1) {
    3580           0 :                 return PROTOCOL_NT1;
    3581             :         }
    3582           0 :         return client_ipc_max_protocol;
    3583             : }
    3584             : 
    3585      107636 : int lpcfg_client_ipc_signing(struct loadparm_context *lp_ctx)
    3586             : {
    3587      107636 :         int client_ipc_signing = lpcfg__client_ipc_signing(lp_ctx);
    3588      107636 :         if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
    3589      107636 :                 return SMB_SIGNING_REQUIRED;
    3590             :         }
    3591           0 :         return client_ipc_signing;
    3592             : }
    3593             : 
    3594       96460 : enum credentials_use_kerberos lpcfg_client_use_kerberos(struct loadparm_context *lp_ctx)
    3595             : {
    3596       96460 :         if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
    3597           0 :                 return CRED_USE_KERBEROS_REQUIRED;
    3598             :         }
    3599             : 
    3600       96460 :         return lpcfg__client_use_kerberos(lp_ctx);
    3601             : }
    3602             : 
    3603       12856 : bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandatory)
    3604             : {
    3605       12856 :         bool allowed = true;
    3606       12856 :         enum smb_signing_setting signing_setting = lpcfg_server_signing(lp_ctx);
    3607             : 
    3608       12856 :         *mandatory = false;
    3609             : 
    3610       12856 :         if (signing_setting == SMB_SIGNING_DEFAULT) {
    3611             :                 /*
    3612             :                  * If we are a domain controller, SMB signing is
    3613             :                  * really important, as it can prevent a number of
    3614             :                  * attacks on communications between us and the
    3615             :                  * clients
    3616             :                  *
    3617             :                  * However, it really sucks (no sendfile, CPU
    3618             :                  * overhead) performance-wise when used on a
    3619             :                  * file server, so disable it by default
    3620             :                  * on non-DCs
    3621             :                  */
    3622             : 
    3623       11850 :                 if (lpcfg_server_role(lp_ctx) >= ROLE_ACTIVE_DIRECTORY_DC) {
    3624        9572 :                         signing_setting = SMB_SIGNING_REQUIRED;
    3625             :                 } else {
    3626        2278 :                         signing_setting = SMB_SIGNING_OFF;
    3627             :                 }
    3628             :         }
    3629             : 
    3630       12856 :         switch (signing_setting) {
    3631       10444 :         case SMB_SIGNING_REQUIRED:
    3632       10444 :                 *mandatory = true;
    3633       10444 :                 break;
    3634         134 :         case SMB_SIGNING_DESIRED:
    3635             :         case SMB_SIGNING_IF_REQUIRED:
    3636         134 :                 break;
    3637        2278 :         case SMB_SIGNING_OFF:
    3638        2278 :                 allowed = false;
    3639        2278 :                 break;
    3640           0 :         case SMB_SIGNING_DEFAULT:
    3641             :         case SMB_SIGNING_IPC_DEFAULT:
    3642           0 :                 smb_panic(__location__);
    3643             :                 break;
    3644             :         }
    3645             : 
    3646       12856 :         return allowed;
    3647             : }
    3648             : 
    3649      167911 : int lpcfg_tdb_hash_size(struct loadparm_context *lp_ctx, const char *name)
    3650             : {
    3651             :         const char *base;
    3652             : 
    3653      167911 :         if (name == NULL) {
    3654           0 :                 return 0;
    3655             :         }
    3656             : 
    3657      167911 :         base = strrchr_m(name, '/');
    3658      167911 :         if (base != NULL) {
    3659      167911 :                 base += 1;
    3660             :         } else {
    3661           0 :                 base = name;
    3662             :         }
    3663      167911 :         return lpcfg_parm_int(lp_ctx, NULL, "tdb_hashsize", base, 0);
    3664             : 
    3665             : }
    3666             : 
    3667      629156 : int lpcfg_tdb_flags(struct loadparm_context *lp_ctx, int tdb_flags)
    3668             : {
    3669      629156 :         if (!lpcfg_use_mmap(lp_ctx)) {
    3670       15806 :                 tdb_flags |= TDB_NOMMAP;
    3671             :         }
    3672      629156 :         return tdb_flags;
    3673             : }
    3674             : 
    3675             : /*
    3676             :  * Do not allow LanMan auth if unless NTLMv1 is also allowed
    3677             :  *
    3678             :  * This also ensures it is disabled if NTLM is totally disabled
    3679             :  */
    3680       12692 : bool lpcfg_lanman_auth(struct loadparm_context *lp_ctx)
    3681             : {
    3682       12692 :         enum ntlm_auth_level ntlm_auth_level = lpcfg_ntlm_auth(lp_ctx);
    3683             : 
    3684       12692 :         if (ntlm_auth_level == NTLM_AUTH_ON) {
    3685       11711 :                 return lpcfg__lanman_auth(lp_ctx);
    3686             :         } else {
    3687         981 :                 return false;
    3688             :         }
    3689             : }
    3690             : 
    3691       33351 : static char *lpcfg_noop_substitution_fn(
    3692             :                         TALLOC_CTX *mem_ctx,
    3693             :                         const struct loadparm_substitution *lp_sub,
    3694             :                         const char *raw_value,
    3695             :                         void *private_data)
    3696             : {
    3697       33351 :         return talloc_strdup(mem_ctx, raw_value);
    3698             : }
    3699             : 
    3700             : static const struct loadparm_substitution global_noop_substitution = {
    3701             :         .substituted_string_fn = lpcfg_noop_substitution_fn,
    3702             : };
    3703             : 
    3704       33615 : const struct loadparm_substitution *lpcfg_noop_substitution(void)
    3705             : {
    3706       33615 :         return &global_noop_substitution;
    3707             : }
    3708             : 
    3709      278738 : char *lpcfg_substituted_string(TALLOC_CTX *mem_ctx,
    3710             :                                const struct loadparm_substitution *lp_sub,
    3711             :                                const char *raw_value)
    3712             : {
    3713      557476 :         return lp_sub->substituted_string_fn(mem_ctx,
    3714             :                                              lp_sub,
    3715             :                                              raw_value,
    3716      278738 :                                              lp_sub->private_data);
    3717             : }
    3718             : 
    3719             : /**
    3720             :  * @brief Parse a string value of a given parameter to its integer enum value.
    3721             :  *
    3722             :  * @param[in]  param_name    The parameter name (e.g. 'client smb encrypt')
    3723             :  *
    3724             :  * @param[in]  param_value   The parameter value (e.g. 'required').
    3725             :  *
    3726             :  * @return The integer value of the enum the param_value matches or INT32_MIN
    3727             :  * on error.
    3728             :  */
    3729         115 : int32_t lpcfg_parse_enum_vals(const char *param_name,
    3730             :                               const char *param_value)
    3731             : {
    3732         115 :         struct parm_struct *parm = NULL;
    3733         115 :         int32_t ret = INT32_MIN;
    3734             :         bool ok;
    3735             : 
    3736         115 :         parm = lpcfg_parm_struct(NULL, param_name);
    3737         115 :         if (parm == NULL) {
    3738           0 :                 return INT32_MIN;
    3739             :         }
    3740             : 
    3741         115 :         ok = lp_set_enum_parm(parm, param_value, &ret);
    3742         115 :         if (!ok) {
    3743           0 :                 return INT32_MIN;
    3744             :         }
    3745             : 
    3746         115 :         return ret;
    3747             : }

Generated by: LCOV version 1.14