LCOV - code coverage report
Current view: top level - lib/param - loadparm.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 1444 1722 83.9 %
Date: 2024-04-21 15:09:00 Functions: 111 117 94.9 %

          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      296064 : struct loadparm_service *lpcfg_default_service(struct loadparm_context *lp_ctx)
      90             : {
      91      296064 :         return lp_ctx->sDefault;
      92             : }
      93             : 
      94          68 : int lpcfg_rpc_low_port(struct loadparm_context *lp_ctx)
      95             : {
      96          68 :         return lp_ctx->globals->rpc_low_port;
      97             : }
      98             : 
      99          68 : int lpcfg_rpc_high_port(struct loadparm_context *lp_ctx)
     100             : {
     101          68 :         return lp_ctx->globals->rpc_high_port;
     102             : }
     103             : 
     104      943826 : enum samba_weak_crypto lpcfg_weak_crypto(struct loadparm_context *lp_ctx)
     105             : {
     106      943826 :         if (lp_ctx->globals->weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) {
     107       51118 :                 lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED;
     108             : 
     109       51118 :                 if (samba_gnutls_weak_crypto_allowed()) {
     110       51116 :                         lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED;
     111             :                 }
     112             :         }
     113             : 
     114      943826 :         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    12289387 : 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    12289387 :         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 variants */
     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     5782363 : 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    17120489 : struct parmlist_entry *get_parametric_helper(struct loadparm_service *service,
     277             :                                              const char *type, const char *option,
     278             :                                              struct parmlist_entry *global_opts)
     279    17120489 : {
     280    17120489 :         size_t type_len = strlen(type);
     281    17120489 :         size_t option_len = strlen(option);
     282    17120489 :         char param_key[type_len + option_len + 2];
     283    17120489 :         struct parmlist_entry *data = NULL;
     284             : 
     285    17120489 :         snprintf(param_key, sizeof(param_key), "%s:%s", type, option);
     286             : 
     287             :         /*
     288             :          * Try to fetch the option from the data.
     289             :          */
     290    17120489 :         if (service != NULL) {
     291     2057014 :                 data = service->param_opt;
     292     3845339 :                 while (data != NULL) {
     293     2025532 :                         if (strwicmp(data->key, param_key) == 0) {
     294      237207 :                                 return data;
     295             :                         }
     296     1788325 :                         data = data->next;
     297             :                 }
     298             :         }
     299             : 
     300             :         /*
     301             :          * Fall back to fetching from the globals.
     302             :          */
     303    12557044 :         data = global_opts;
     304   537560140 :         while (data != NULL) {
     305   522606122 :                 if (strwicmp(data->key, param_key) == 0) {
     306     1929264 :                         return data;
     307             :                 }
     308   520676858 :                 data = data->next;
     309             :         }
     310             : 
     311    10650764 :         return NULL;
     312             : }
     313             : 
     314    14207127 : const char *lpcfg_get_parametric(struct loadparm_context *lp_ctx,
     315             :                               struct loadparm_service *service,
     316             :                               const char *type, const char *option)
     317             : {
     318     4315317 :         struct parmlist_entry *data;
     319             : 
     320    14207127 :         if (lp_ctx == NULL)
     321           0 :                 return NULL;
     322             : 
     323    18522444 :         data = get_parametric_helper(service,
     324    14207127 :                                      type, option, lp_ctx->globals->param_opt);
     325             : 
     326    14207127 :         if (data == NULL) {
     327     8590614 :                 return NULL;
     328             :         } else {
     329     1322201 :                 return data->value;
     330             :         }
     331             : }
     332             : 
     333             : 
     334             : /**
     335             :  * convenience routine to return int parameters.
     336             :  */
     337      836346 : int lp_int(const char *s)
     338             : {
     339             : 
     340      836346 :         if (!s || !*s) {
     341           0 :                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
     342           0 :                 return -1;
     343             :         }
     344             : 
     345      836346 :         return strtol(s, NULL, 0);
     346             : }
     347             : 
     348             : /**
     349             :  * convenience routine to return unsigned long parameters.
     350             :  */
     351        3968 : unsigned long lp_ulong(const char *s)
     352             : {
     353        3968 :         int error = 0;
     354           0 :         unsigned long int ret;
     355             : 
     356        3968 :         if (!s || !*s) {
     357           0 :                 DBG_DEBUG("lp_ulong(%s): is called with NULL!\n",s);
     358           0 :                 return -1;
     359             :         }
     360             : 
     361        3968 :         ret = smb_strtoul(s, NULL, 0, &error, SMB_STR_STANDARD);
     362        3968 :         if (error != 0) {
     363           0 :                 DBG_DEBUG("lp_ulong(%s): conversion failed\n",s);
     364           0 :                 return -1;
     365             :         }
     366             : 
     367        3968 :         return ret;
     368             : }
     369             : 
     370             : /**
     371             :  * convenience routine to return unsigned long long parameters.
     372             :  */
     373         411 : unsigned long long lp_ulonglong(const char *s)
     374             : {
     375         411 :         int error = 0;
     376           0 :         unsigned long long int ret;
     377             : 
     378         411 :         if (!s || !*s) {
     379           0 :                 DBG_DEBUG("lp_ulonglong(%s): is called with NULL!\n", s);
     380           0 :                 return -1;
     381             :         }
     382             : 
     383         411 :         ret = smb_strtoull(s, NULL, 0, &error, SMB_STR_STANDARD);
     384         411 :         if (error != 0) {
     385           0 :                 DBG_DEBUG("lp_ulonglong(%s): conversion failed\n",s);
     386           0 :                 return -1;
     387             :         }
     388             : 
     389         411 :         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           1 : static double lp_double(const char *s)
     410             : {
     411             : 
     412           1 :         if (!s) {
     413           0 :                 DEBUG(0,("lp_double(%s): is called with NULL!\n",s));
     414           0 :                 return -1;
     415             :         }
     416             : 
     417           1 :         return strtod(s, NULL);
     418             : }
     419             : 
     420             : /**
     421             :  * convenience routine to return boolean parameters.
     422             :  */
     423     1155540 : bool lp_bool(const char *s)
     424             : {
     425     1155540 :         bool ret = false;
     426             : 
     427     1155540 :         if (!s || !*s) {
     428          28 :                 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
     429          28 :                 return false;
     430             :         }
     431             : 
     432     1155512 :         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     1155512 :         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     2120714 : const char *lpcfg_parm_string(struct loadparm_context *lp_ctx,
     447             :                               struct loadparm_service *service, const char *type,
     448             :                               const char *option)
     449             : {
     450     2120714 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     451             : 
     452     2120714 :         if (value)
     453      785973 :                 return lpcfg_string(value);
     454             : 
     455     1314778 :         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      773525 : 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      773525 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     490             : 
     491      773525 :         if (value)
     492       59265 :                 return lp_int(value);
     493             : 
     494      692585 :         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           2 : 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           2 :         uint64_t bval;
     508             : 
     509           2 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     510             : 
     511           2 :         if (value && conv_str_size_error(value, &bval)) {
     512           1 :                 if (bval <= INT_MAX) {
     513           1 :                         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       66980 : 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       66980 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     530             : 
     531       66980 :         if (value)
     532        3942 :                 return lp_ulong(value);
     533             : 
     534       62158 :         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         865 : 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         865 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     561             : 
     562         865 :         if (value)
     563           0 :                 return lp_long(value);
     564             : 
     565         841 :         return default_v;
     566             : }
     567             : 
     568           2 : 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           2 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     573             : 
     574           2 :         if (value != NULL)
     575           1 :                 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    11197743 : 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    11197743 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     590             : 
     591    11197743 :         if (value != NULL)
     592      430854 :                 return lp_bool(value);
     593             : 
     594     6515739 :         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   104293246 : void lpcfg_string_free(char **s)
     605             : {
     606   104293246 :         if (s == NULL) {
     607           0 :                 return;
     608             :         }
     609   104293246 :         if (*s == lpcfg_string_empty) {
     610    37103150 :                 *s = NULL;
     611    37103150 :                 return;
     612             :         }
     613    67190096 :         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    81491522 : bool lpcfg_string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
     621             : {
     622    81491522 :         lpcfg_string_free(dest);
     623             : 
     624    81491522 :         if ((src == NULL) || (*src == '\0')) {
     625    44783673 :                 *dest = discard_const_p(char, lpcfg_string_empty);
     626    44783673 :                 return true;
     627             :         }
     628             : 
     629    36707849 :         *dest = talloc_strdup(mem_ctx, src);
     630    36707849 :         if ((*dest) == NULL) {
     631           0 :                 DEBUG(0,("Out of memory in string_set\n"));
     632           0 :                 return false;
     633             :         }
     634             : 
     635    36588203 :         return true;
     636             : }
     637             : 
     638             : /**
     639             :  * Set a string value, deallocating any existing space, and allocing the space
     640             :  * for the string
     641             :  */
     642      178418 : bool lpcfg_string_set_upper(TALLOC_CTX *mem_ctx, char **dest, const char *src)
     643             : {
     644      178418 :         lpcfg_string_free(dest);
     645             : 
     646      178418 :         if ((src == NULL) || (*src == '\0')) {
     647           6 :                 *dest = discard_const_p(char, lpcfg_string_empty);
     648           6 :                 return true;
     649             :         }
     650             : 
     651      178412 :         *dest = strupper_talloc(mem_ctx, src);
     652      178412 :         if ((*dest) == NULL) {
     653           0 :                 DEBUG(0,("Out of memory in string_set_upper\n"));
     654           0 :                 return false;
     655             :         }
     656             : 
     657      176102 :         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      305685 : struct loadparm_service *lpcfg_add_service(struct loadparm_context *lp_ctx,
     668             :                                            const struct loadparm_service *pservice,
     669             :                                            const char *name)
     670             : {
     671        2892 :         int i;
     672      305685 :         int num_to_alloc = lp_ctx->iNumServices + 1;
     673        2892 :         struct parmlist_entry *data, *pdata;
     674             : 
     675      305685 :         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      305685 :         if (pservice == NULL) {
     680          68 :                 pservice = lp_ctx->sDefault;
     681             :         }
     682             : 
     683             :         /* it might already exist */
     684      305685 :         if (name) {
     685      305685 :                 struct loadparm_service *service = lpcfg_getservicebyname(lp_ctx,
     686             :                                                                     name);
     687      305685 :                 if (service != NULL) {
     688             :                         /* Clean all parametric options for service */
     689             :                         /* They will be added during parsing again */
     690      215496 :                         data = service->param_opt;
     691      662266 :                         while (data) {
     692      446770 :                                 pdata = data->next;
     693      446770 :                                 talloc_free(data);
     694      446770 :                                 data = pdata;
     695             :                         }
     696      215496 :                         service->param_opt = NULL;
     697      215496 :                         return service;
     698             :                 }
     699             :         }
     700             : 
     701             :         /* find an invalid one */
     702     1683128 :         for (i = 0; i < lp_ctx->iNumServices; i++)
     703     1592939 :                 if (lp_ctx->services[i] == NULL)
     704           0 :                         break;
     705             : 
     706             :         /* if not, then create one */
     707       90189 :         if (i == lp_ctx->iNumServices) {
     708        1965 :                 struct loadparm_service **tsp;
     709             : 
     710       90189 :                 tsp = talloc_realloc(lp_ctx, lp_ctx->services, struct loadparm_service *, num_to_alloc);
     711             : 
     712       90189 :                 if (!tsp) {
     713           0 :                         DEBUG(0,("lpcfg_add_service: failed to enlarge services!\n"));
     714           0 :                         return NULL;
     715             :                 } else {
     716       90189 :                         lp_ctx->services = tsp;
     717       90189 :                         lp_ctx->services[lp_ctx->iNumServices] = NULL;
     718             :                 }
     719             : 
     720       90189 :                 lp_ctx->iNumServices++;
     721             :         }
     722             : 
     723       90189 :         lp_ctx->services[i] = talloc_zero(lp_ctx->services, struct loadparm_service);
     724       90189 :         if (lp_ctx->services[i] == NULL) {
     725           0 :                 DEBUG(0,("lpcfg_add_service: out of memory!\n"));
     726           0 :                 return NULL;
     727             :         }
     728       90189 :         copy_service(lp_ctx->services[i], pservice, NULL);
     729       90189 :         if (name != NULL)
     730       90189 :                 lpcfg_string_set(lp_ctx->services[i], &lp_ctx->services[i]->szService, name);
     731       90189 :         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    23048958 : int lpcfg_map_parameter(const char *pszParmName)
     740             : {
     741      212697 :         int iIndex;
     742             : 
     743  7597736403 :         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
     744  7592360524 :                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
     745    17673079 :                         return iIndex;
     746             : 
     747             :         /* Warn only if it isn't parametric option */
     748     5375879 :         if (strchr(pszParmName, ':') == NULL)
     749           5 :                 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     5359704 :         return -1;
     754             : }
     755             : 
     756             : 
     757             : /**
     758             :   return the parameter structure for a parameter
     759             : */
     760       38653 : struct parm_struct *lpcfg_parm_struct(struct loadparm_context *lp_ctx, const char *name)
     761             : {
     762       38653 :         int num = lpcfg_map_parameter(name);
     763             : 
     764       38653 :         if (num < 0) {
     765           0 :                 return NULL;
     766             :         }
     767             : 
     768       38652 :         return &parm_table[num];
     769             : }
     770             : 
     771             : /**
     772             :   return the parameter pointer for a parameter
     773             : */
     774     7363680 : void *lpcfg_parm_ptr(struct loadparm_context *lp_ctx,
     775             :                   struct loadparm_service *service, struct parm_struct *parm)
     776             : {
     777     7363680 :         if (lp_ctx->s3_fns) {
     778     2984092 :                 return lp_ctx->s3_fns->get_parm_ptr(service, parm);
     779             :         }
     780             : 
     781     4379588 :         if (service == NULL) {
     782     4374300 :                 if (parm->p_class == P_LOCAL)
     783      596463 :                         return ((char *)lp_ctx->sDefault)+parm->offset;
     784     3777837 :                 else if (parm->p_class == P_GLOBAL)
     785     3777837 :                         return ((char *)lp_ctx->globals)+parm->offset;
     786           0 :                 else return NULL;
     787             :         } else {
     788        5288 :                 return ((char *)service) + parm->offset;
     789             :         }
     790             : }
     791             : 
     792             : /**
     793             :   return the parameter pointer for a parameter
     794             : */
     795      714252 : bool lpcfg_parm_is_cmdline(struct loadparm_context *lp_ctx, const char *name)
     796             : {
     797       11121 :         int parmnum;
     798             : 
     799      714252 :         parmnum = lpcfg_map_parameter(name);
     800      714252 :         if (parmnum == -1) return false;
     801             : 
     802      714252 :         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           0 :         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     1290271 : static struct loadparm_service *lpcfg_getservicebyname(struct loadparm_context *lp_ctx,
     820             :                                         const char *pszServiceName)
     821             : {
     822        4368 :         int iService;
     823             : 
     824     1290271 :         if (lp_ctx->s3_fns) {
     825      860778 :                 return lp_ctx->s3_fns->get_service(pszServiceName);
     826             :         }
     827             : 
     828     6971587 :         for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--)
     829    13762794 :                 if (lp_ctx->services[iService] != NULL &&
     830     6881397 :                     strwicmp(lp_ctx->services[iService]->szService, pszServiceName) == 0) {
     831      339303 :                         return lp_ctx->services[iService];
     832             :                 }
     833             : 
     834       88225 :         return NULL;
     835             : }
     836             : 
     837             : /**
     838             :  * Add a parametric option to a parmlist_entry,
     839             :  * replacing old value, if already present.
     840             :  */
     841     5727973 : 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       20228 :         struct parmlist_entry *new_opt, *opt;
     848             : 
     849     5727973 :         opt = *opt_list;
     850             : 
     851             :         /* Traverse destination */
     852    47968031 :         while (opt) {
     853             :                 /* If we already have same option, override it */
     854    42825540 :                 if (strwicmp(opt->key, opt_name) == 0) {
     855      585482 :                         if ((opt->priority & FLAG_CMDLINE) &&
     856        7717 :                             !(priority & FLAG_CMDLINE)) {
     857             :                                 /* it's been marked as not to be
     858             :                                    overridden */
     859         440 :                                 return;
     860             :                         }
     861      585020 :                         TALLOC_FREE(opt->list);
     862      585020 :                         lpcfg_string_set(opt, &opt->value, opt_value);
     863      585020 :                         opt->priority = priority;
     864      585020 :                         return;
     865             :                 }
     866    42240058 :                 opt = opt->next;
     867             :         }
     868             : 
     869     5142491 :         new_opt = talloc_pooled_object(
     870             :                 mem_ctx, struct parmlist_entry,
     871             :                 2, strlen(opt_name) + 1 + strlen(opt_value) + 1);
     872     5142491 :         if (new_opt == NULL) {
     873           0 :                 smb_panic("OOM");
     874             :         }
     875     5142491 :         new_opt->key = NULL;
     876     5142491 :         lpcfg_string_set(new_opt, &new_opt->key, opt_name);
     877     5142491 :         new_opt->value = NULL;
     878     5142491 :         lpcfg_string_set(new_opt, &new_opt->value, opt_value);
     879             : 
     880     5142491 :         new_opt->list = NULL;
     881     5142491 :         new_opt->priority = priority;
     882     5142491 :         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     1272071 : void copy_service(struct loadparm_service *pserviceDest,
     891             :                   const struct loadparm_service *pserviceSource,
     892             :                   struct bitmap *pcopymapDest)
     893             : {
     894        3509 :         int i;
     895     1272071 :         bool bcopyall = (pcopymapDest == NULL);
     896        3509 :         struct parmlist_entry *data;
     897             : 
     898   661476920 :         for (i = 0; parm_table[i].label; i++)
     899   660204849 :                 if (parm_table[i].p_class == P_LOCAL &&
     900   154579688 :                     (bcopyall || bitmap_query(pcopymapDest, i))) {
     901   197257235 :                         const void *src_ptr =
     902   197257235 :                                 ((const char *)pserviceSource) + parm_table[i].offset;
     903   197257235 :                         void *dest_ptr =
     904   196708398 :                                 ((char *)pserviceDest) + parm_table[i].offset;
     905             : 
     906   197257235 :                         switch (parm_table[i].type) {
     907    97446688 :                                 case P_BOOL:
     908             :                                 case P_BOOLREV:
     909    97446688 :                                         *(bool *)dest_ptr = *(const bool *)src_ptr;
     910    97446688 :                                         break;
     911             : 
     912    39290652 :                                 case P_INTEGER:
     913             :                                 case P_BYTES:
     914             :                                 case P_OCTAL:
     915             :                                 case P_ENUM:
     916    39290652 :                                         *(int *)dest_ptr = *(const int *)src_ptr;
     917    39290652 :                                         break;
     918             : 
     919     1272071 :                                 case P_CHAR:
     920     1272071 :                                         *(char *)dest_ptr = *(const char *)src_ptr;
     921     1272071 :                                         break;
     922             : 
     923    43228675 :                                 case P_STRING:
     924    43228675 :                                         lpcfg_string_set(pserviceDest,
     925             :                                                    (char **)dest_ptr,
     926             :                                                    *(const char * const *)src_ptr);
     927    43228675 :                                         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    16019149 :                                 case P_CMDLIST:
     935             :                                 case P_LIST:
     936    16019149 :                                         TALLOC_FREE(*((char ***)dest_ptr));
     937    16019149 :                                         *(char ***)dest_ptr = str_list_copy(pserviceDest,
     938             :                                                                             *discard_const_p(const char **, src_ptr));
     939    16019149 :                                         break;
     940           0 :                                 default:
     941           0 :                                         break;
     942             :                         }
     943             :                 }
     944             : 
     945     1272071 :         if (bcopyall) {
     946      287487 :                 init_copymap(pserviceDest);
     947      287487 :                 if (pserviceSource->copymap)
     948       11117 :                         bitmap_copy(pserviceDest->copymap,
     949       11117 :                                     pserviceSource->copymap);
     950             :         }
     951             : 
     952     1626953 :         for (data = pserviceSource->param_opt; data != NULL; data = data->next) {
     953      354882 :                 set_param_opt(pserviceDest, &pserviceDest->param_opt,
     954      354882 :                               data->key, data->value, data->priority);
     955             :         }
     956     1272071 : }
     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     3246083 : bool lpcfg_service_ok(struct loadparm_service *service)
     963             : {
     964        3035 :         bool bRetval;
     965             : 
     966     3246083 :         bRetval = true;
     967     3246083 :         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     3246083 :         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     3257270 :         if (service->path[0] == '\0' &&
     987       11187 :             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     3246083 :         if (!service->available)
     996           2 :                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
     997             :                           service->szService));
     998             : 
     999     3246083 :         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      250685 : void add_to_file_list(TALLOC_CTX *mem_ctx, struct file_lists **list,
    1009             :                              const char *fname, const char *subfname)
    1010             : {
    1011      250685 :         struct file_lists *f = *list;
    1012             : 
    1013      611639 :         while (f) {
    1014      427139 :                 if (f->name && !strcmp(f->name, fname))
    1015       66068 :                         break;
    1016      360954 :                 f = f->next;
    1017             :         }
    1018             : 
    1019      250685 :         if (!f) {
    1020      184500 :                 f = talloc_zero(mem_ctx, struct file_lists);
    1021      184500 :                 if (!f)
    1022           0 :                         goto fail;
    1023      184500 :                 f->next = *list;
    1024      184500 :                 f->name = talloc_strdup(f, fname);
    1025      184500 :                 if (!f->name) {
    1026           0 :                         TALLOC_FREE(f);
    1027           0 :                         goto fail;
    1028             :                 }
    1029      184500 :                 f->subfname = talloc_strdup(f, subfname);
    1030      184500 :                 if (!f->subfname) {
    1031           0 :                         TALLOC_FREE(f);
    1032           0 :                         goto fail;
    1033             :                 }
    1034      184500 :                 *list = f;
    1035             :         }
    1036             : 
    1037             :         /* If file_modtime() fails it leaves f->modtime as zero. */
    1038      250685 :         (void)file_modtime(subfname, &f->modtime);
    1039      250685 :         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     1867147 : bool lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
    1050             :                               int *ptr )
    1051             : {
    1052       41178 :         int i;
    1053             : 
    1054     7992994 :         for (i = 0; parm->enum_list[i].name; i++) {
    1055     7992990 :                 if (strwicmp(pszParmValue, parm->enum_list[i].name) == 0) {
    1056     1867143 :                         *ptr = parm->enum_list[i].value;
    1057     1867143 :                         return true;
    1058             :                 }
    1059             :         }
    1060           4 :         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
    1061             :                   pszParmValue, parm->label));
    1062           2 :         return false;
    1063             : }
    1064             : 
    1065             : 
    1066             : /***************************************************************************
    1067             :  Handle the "realm" parameter
    1068             : ***************************************************************************/
    1069             : 
    1070       35150 : bool handle_realm(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1071             :                   const char *pszParmValue, char **ptr)
    1072             : {
    1073         265 :         char *upper;
    1074         265 :         char *lower;
    1075             : 
    1076       35150 :         upper = strupper_talloc(lp_ctx, pszParmValue);
    1077       35150 :         if (upper == NULL) {
    1078           0 :                 return false;
    1079             :         }
    1080             : 
    1081       35150 :         lower = strlower_talloc(lp_ctx, pszParmValue);
    1082       35150 :         if (lower == NULL) {
    1083           0 :                 TALLOC_FREE(upper);
    1084           0 :                 return false;
    1085             :         }
    1086             : 
    1087       35150 :         lpcfg_string_set(lp_ctx->globals->ctx, &lp_ctx->globals->realm, upper);
    1088       35150 :         lpcfg_string_set(lp_ctx->globals->ctx, &lp_ctx->globals->dnsdomain, lower);
    1089             : 
    1090       35150 :         return true;
    1091             : }
    1092             : 
    1093             : /***************************************************************************
    1094             :  Handle the include operation.
    1095             : ***************************************************************************/
    1096             : 
    1097      170926 : bool handle_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1098             :                            const char *pszParmValue, char **ptr)
    1099             : {
    1100           0 :         char *fname;
    1101           0 :         const char *substitution_variable_substring;
    1102           0 :         char next_char;
    1103             : 
    1104      170926 :         if (lp_ctx->s3_fns) {
    1105      169232 :                 return lp_ctx->s3_fns->lp_include(lp_ctx, service, pszParmValue, ptr);
    1106             :         }
    1107             : 
    1108        1694 :         fname = standard_sub_basic(lp_ctx, pszParmValue);
    1109             : 
    1110        1694 :         add_to_file_list(lp_ctx, &lp_ctx->file_lists, pszParmValue, fname);
    1111             : 
    1112        1694 :         lpcfg_string_set(lp_ctx, ptr, fname);
    1113             : 
    1114        1694 :         if (file_exist(fname))
    1115        1450 :                 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         244 :         substitution_variable_substring = strchr(fname, '%');
    1122             : 
    1123         244 :         if (substitution_variable_substring != NULL) {
    1124         239 :                 next_char = substitution_variable_substring[1];
    1125         239 :                 if ((next_char >= 'a' && next_char <= 'z')
    1126         239 :                     || (next_char >= 'A' && next_char <= 'Z')) {
    1127         239 :                         DEBUG(2, ("Tried to load %s but variable substitution in "
    1128             :                                  "filename, ignoring file.\n", fname));
    1129         239 :                         return true;
    1130             :                 }
    1131             :         }
    1132             : 
    1133           5 :         DEBUG(2, ("Can't find include file %s\n", fname));
    1134             : 
    1135           5 :         return false;
    1136             : }
    1137             : 
    1138             : /***************************************************************************
    1139             :  Handle the interpretation of the copy parameter.
    1140             : ***************************************************************************/
    1141             : 
    1142      984586 : bool handle_copy(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1143             :                         const char *pszParmValue, char **ptr)
    1144             : {
    1145        1476 :         bool bRetval;
    1146      984586 :         struct loadparm_service *serviceTemp = NULL;
    1147             : 
    1148      984586 :         bRetval = false;
    1149             : 
    1150      984586 :         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
    1151             : 
    1152      984586 :         serviceTemp = lpcfg_getservicebyname(lp_ctx, pszParmValue);
    1153             : 
    1154      984586 :         if (service == NULL) {
    1155           2 :                 DEBUG(0, ("Unable to copy service - invalid service destination.\n"));
    1156           2 :                 return false;
    1157             :         }
    1158             : 
    1159      984584 :         if (serviceTemp != NULL) {
    1160      984584 :                 if (serviceTemp == service) {
    1161           0 :                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
    1162             :                 } else {
    1163      984584 :                         copy_service(service,
    1164             :                                      serviceTemp,
    1165             :                                      service->copymap);
    1166      984584 :                         lpcfg_string_set(service, ptr, pszParmValue);
    1167             : 
    1168      984584 :                         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      983108 :         return bRetval;
    1177             : }
    1178             : 
    1179      110221 : bool handle_debug_list(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1180             :                         const char *pszParmValue, char **ptr)
    1181             : {
    1182      110221 :         lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1183             : 
    1184      110221 :         return debug_parse_levels(pszParmValue);
    1185             : }
    1186             : 
    1187       91781 : bool handle_logfile(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1188             :                     const char *pszParmValue, char **ptr)
    1189             : {
    1190       91781 :         if (lp_ctx->s3_fns == NULL) {
    1191       33811 :                 debug_set_logfile(pszParmValue);
    1192             :         }
    1193             : 
    1194       91781 :         lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1195             : 
    1196       91781 :         return true;
    1197             : }
    1198             : 
    1199             : /*
    1200             :  * These special charset handling methods only run in the source3 code.
    1201             :  */
    1202             : 
    1203       12372 : bool handle_charset(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1204             :                         const char *pszParmValue, char **ptr)
    1205             : {
    1206       12372 :         if (lp_ctx->s3_fns) {
    1207          12 :                 if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
    1208          10 :                         struct smb_iconv_handle *ret = NULL;
    1209             : 
    1210          10 :                         ret = reinit_iconv_handle(NULL,
    1211             :                                                   lpcfg_dos_charset(lp_ctx),
    1212             :                                                   lpcfg_unix_charset(lp_ctx));
    1213          10 :                         if (ret == NULL) {
    1214           0 :                                 smb_panic("reinit_iconv_handle failed");
    1215             :                         }
    1216             :                 }
    1217             : 
    1218             :         }
    1219       12372 :         return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1220             : 
    1221             : }
    1222             : 
    1223       12375 : bool handle_dos_charset(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1224             :                         const char *pszParmValue, char **ptr)
    1225             : {
    1226       12375 :         bool is_utf8 = false;
    1227       12375 :         size_t len = strlen(pszParmValue);
    1228             : 
    1229       12375 :         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       12375 :         return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1267             : }
    1268             : 
    1269       81196 : bool handle_printing(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1270             :                             const char *pszParmValue, char **ptr)
    1271             : {
    1272         246 :         static int parm_num = -1;
    1273             : 
    1274       81196 :         if (parm_num == -1) {
    1275        7587 :                 parm_num = lpcfg_map_parameter("printing");
    1276             :         }
    1277             : 
    1278       81196 :         if (!lp_set_enum_parm(&parm_table[parm_num], pszParmValue, (int*)ptr)) {
    1279           0 :                 return false;
    1280             :         }
    1281             : 
    1282       81196 :         if (lp_ctx->s3_fns) {
    1283       62410 :                 if (service == NULL) {
    1284       62410 :                         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       80950 :         return true;
    1291             : }
    1292             : 
    1293          11 : bool handle_ldap_debug_level(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1294             :                              const char *pszParmValue, char **ptr)
    1295             : {
    1296          11 :         lp_ctx->globals->ldap_debug_level = lp_int(pszParmValue);
    1297             : 
    1298          11 :         if (lp_ctx->s3_fns) {
    1299           8 :                 lp_ctx->s3_fns->init_ldap_debugging();
    1300             :         }
    1301          11 :         return true;
    1302             : }
    1303             : 
    1304             : /*
    1305             :  * idmap related parameters
    1306             :  */
    1307             : 
    1308       12366 : bool handle_idmap_backend(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1309             :                           const char *pszParmValue, char **ptr)
    1310             : {
    1311       12366 :         if (lp_ctx->s3_fns) {
    1312           6 :                 lp_do_parameter_parametric(lp_ctx, service, "idmap config * : backend",
    1313             :                                            pszParmValue, 0);
    1314             :         }
    1315             : 
    1316       12366 :         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       12360 : bool handle_smb_ports(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1342             :                       const char *pszParmValue, char **ptr)
    1343             : {
    1344         616 :         static int parm_num = -1;
    1345         616 :         int i;
    1346         616 :         const char **list;
    1347             : 
    1348       12360 :         if (!pszParmValue || !*pszParmValue) {
    1349           0 :                 return false;
    1350             :         }
    1351             : 
    1352       12360 :         if (parm_num == -1) {
    1353       12188 :                 parm_num = lpcfg_map_parameter("smb ports");
    1354       12188 :                 if (parm_num == -1) {
    1355           0 :                         return false;
    1356             :                 }
    1357             :         }
    1358             : 
    1359       12360 :         if (!set_variable_helper(lp_ctx->globals->ctx, parm_num, ptr, "smb ports",
    1360             :                                 pszParmValue)) {
    1361           0 :                 return false;
    1362             :         }
    1363             : 
    1364       12360 :         list = lp_ctx->globals->smb_ports;
    1365       12360 :         if (list == NULL) {
    1366           0 :                 return false;
    1367             :         }
    1368             : 
    1369             :         /* Check that each port is a valid integer and within range */
    1370       37080 :         for (i = 0; list[i] != NULL; i++) {
    1371       24720 :                 char *end = NULL;
    1372       24720 :                 int port = 0;
    1373       24720 :                 port = strtol(list[i], &end, 10);
    1374       24720 :                 if (*end != '\0' || port <= 0 || port > 65535) {
    1375           0 :                         TALLOC_FREE(list);
    1376           0 :                         return false;
    1377             :                 }
    1378             :         }
    1379             : 
    1380       11744 :         return true;
    1381             : }
    1382             : 
    1383       12360 : 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         616 :         static int parm_num = -1;
    1389       12360 :         int low_port = -1, high_port = -1;
    1390         616 :         int rc;
    1391             : 
    1392       12360 :         if (parm_num == -1) {
    1393       12188 :                 parm_num = lpcfg_map_parameter("rpc server dynamic port range");
    1394       12188 :                 if (parm_num == -1) {
    1395           0 :                         return false;
    1396             :                 }
    1397             :         }
    1398             : 
    1399       12360 :         if (pszParmValue == NULL || pszParmValue[0] == '\0') {
    1400           0 :                 return false;
    1401             :         }
    1402             : 
    1403       12360 :         rc = sscanf(pszParmValue, "%d - %d", &low_port, &high_port);
    1404       12360 :         if (rc != 2) {
    1405           0 :                 return false;
    1406             :         }
    1407             : 
    1408       12360 :         if (low_port > high_port) {
    1409           0 :                 return false;
    1410             :         }
    1411             : 
    1412       12360 :         if (low_port < SERVER_TCP_PORT_MIN|| high_port > SERVER_TCP_PORT_MAX) {
    1413           0 :                 return false;
    1414             :         }
    1415             : 
    1416       12360 :         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       12360 :         lp_ctx->globals->rpc_low_port = low_port;
    1423       12360 :         lp_ctx->globals->rpc_high_port = high_port;
    1424             : 
    1425       12360 :         return true;
    1426             : }
    1427             : 
    1428       12366 : bool handle_smb2_max_credits(struct loadparm_context *lp_ctx,
    1429             :                              struct loadparm_service *service,
    1430             :                              const char *pszParmValue, char **ptr)
    1431             : {
    1432       12366 :         int value = lp_int(pszParmValue);
    1433             : 
    1434       12366 :         if (value <= 0) {
    1435           0 :                 value = DEFAULT_SMB2_MAX_CREDITS;
    1436             :         }
    1437             : 
    1438       12366 :         *(int *)ptr = value;
    1439             : 
    1440       12366 :         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      287487 : void init_copymap(struct loadparm_service *pservice)
    1480             : {
    1481        2033 :         int i;
    1482             : 
    1483      287487 :         TALLOC_FREE(pservice->copymap);
    1484             : 
    1485      287487 :         pservice->copymap = bitmap_talloc(pservice, num_parameters());
    1486      287487 :         if (!pservice->copymap) {
    1487           0 :                 DEBUG(0,
    1488             :                       ("Couldn't allocate copymap!! (size %d)\n",
    1489             :                        (int)num_parameters()));
    1490             :         } else {
    1491   149780727 :                 for (i = 0; i < num_parameters(); i++) {
    1492   149493240 :                         bitmap_set(pservice->copymap, i);
    1493             :                 }
    1494             :         }
    1495      287487 : }
    1496             : 
    1497             : /**
    1498             :  * Process a parametric option
    1499             :  */
    1500     5372452 : 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       16163 :         struct parmlist_entry **data;
    1506       16163 :         char *name;
    1507       16163 :         TALLOC_CTX *mem_ctx;
    1508             : 
    1509     5372452 :         while (isspace((unsigned char)*pszParmName)) {
    1510           0 :                 pszParmName++;
    1511             :         }
    1512             : 
    1513     5372452 :         name = strlower_talloc(lp_ctx, pszParmName);
    1514     5372452 :         if (!name) return false;
    1515             : 
    1516     5372452 :         if (service == NULL) {
    1517     1907171 :                 data = &lp_ctx->globals->param_opt;
    1518             :                 /**
    1519             :                  * s3 code cannot deal with parametric options stored on the globals ctx.
    1520             :                  */
    1521     1907171 :                 if (lp_ctx->s3_fns != NULL) {
    1522     1066047 :                         mem_ctx = NULL;
    1523             :                 } else {
    1524      840075 :                         mem_ctx = lp_ctx->globals->ctx;
    1525             :                 }
    1526             :         } else {
    1527     3465281 :                 data = &service->param_opt;
    1528     3465281 :                 mem_ctx = service;
    1529             :         }
    1530             : 
    1531     5372452 :         set_param_opt(mem_ctx, data, name, pszParmValue, flags);
    1532             : 
    1533     5372452 :         talloc_free(name);
    1534             : 
    1535     5372452 :         return true;
    1536             : }
    1537             : 
    1538    15181113 : static bool set_variable_helper(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
    1539             :                          const char *pszParmName, const char *pszParmValue)
    1540             : {
    1541      175060 :         size_t i;
    1542             : 
    1543             :         /* switch on the type of variable it is */
    1544    15181113 :         switch (parm_table[parmnum].type)
    1545             :         {
    1546     4495761 :                 case P_BOOL: {
    1547       62504 :                         bool b;
    1548     4495761 :                         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     4495761 :                         *(bool *)parm_ptr = b;
    1554             :                         }
    1555     4495761 :                         break;
    1556             : 
    1557       14919 :                 case P_BOOLREV: {
    1558           0 :                         bool b;
    1559       14919 :                         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       14919 :                         *(bool *)parm_ptr = !b;
    1565             :                         }
    1566       14919 :                         break;
    1567             : 
    1568      750877 :                 case P_INTEGER:
    1569      750877 :                         *(int *)parm_ptr = lp_int(pszParmValue);
    1570      750877 :                         break;
    1571             : 
    1572       12366 :                 case P_CHAR:
    1573       12366 :                         *(char *)parm_ptr = *pszParmValue;
    1574       12366 :                         break;
    1575             : 
    1576      346585 :                 case P_OCTAL:
    1577      346585 :                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
    1578      346585 :                         if ( i != 1 ) {
    1579           0 :                                 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
    1580           0 :                                 return false;
    1581             :                         }
    1582      345724 :                         break;
    1583             : 
    1584      196780 :                 case P_BYTES:
    1585             :                 {
    1586        4420 :                         uint64_t val;
    1587      196780 :                         if (conv_str_size_error(pszParmValue, &val)) {
    1588      196780 :                                 if (val <= INT_MAX) {
    1589      196780 :                                         *(int *)parm_ptr = (int)val;
    1590      196780 :                                         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     1983524 :                 case P_CMDLIST:
    1600     1983524 :                         TALLOC_FREE(*(char ***)parm_ptr);
    1601     1983524 :                         *(char ***)parm_ptr = str_list_make_v3(mem_ctx,
    1602             :                                                         pszParmValue, NULL);
    1603     1983524 :                         break;
    1604             : 
    1605      223167 :                 case P_LIST:
    1606             :                 {
    1607      223167 :                         char **new_list = str_list_make_v3(mem_ctx,
    1608             :                                                         pszParmValue, NULL);
    1609      223167 :                         if (new_list == NULL) {
    1610           3 :                                 break;
    1611             :                         }
    1612             : 
    1613      361924 :                         for (i=0; new_list[i]; i++) {
    1614      311056 :                                 if (*(const char ***)parm_ptr != NULL &&
    1615      209534 :                                     new_list[i][0] == '+' &&
    1616       94960 :                                     new_list[i][1])
    1617             :                                 {
    1618      111457 :                                         if (!str_list_check(*(const char ***)parm_ptr,
    1619       94960 :                                                             &new_list[i][1])) {
    1620       45003 :                                                 *(const char ***)parm_ptr = str_list_add(*(const char ***)parm_ptr,
    1621       45003 :                                                                                          &new_list[i][1]);
    1622             :                                         }
    1623      216096 :                                 } else if (*(const char ***)parm_ptr != NULL &&
    1624      114574 :                                            new_list[i][0] == '-' &&
    1625       43800 :                                            new_list[i][1])
    1626             :                                 {
    1627       43800 :                                         str_list_remove(*(const char ***)parm_ptr,
    1628       43800 :                                                         &new_list[i][1]);
    1629             :                                 } else {
    1630      172296 :                                         if (i != 0) {
    1631           0 :                                                 DEBUG(0, ("Unsupported list syntax for: %s = %s\n",
    1632             :                                                           pszParmName, pszParmValue));
    1633           0 :                                                 return false;
    1634             :                                         }
    1635      172296 :                                         *(char ***)parm_ptr = new_list;
    1636      172296 :                                         break;
    1637             :                                 }
    1638             :                         }
    1639      217220 :                         break;
    1640             :                 }
    1641             : 
    1642     5712911 :                 case P_STRING:
    1643     5712911 :                         lpcfg_string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
    1644     5712911 :                         break;
    1645             : 
    1646      178418 :                 case P_USTRING:
    1647      178418 :                         lpcfg_string_set_upper(mem_ctx, (char **)parm_ptr, pszParmValue);
    1648      178418 :                         break;
    1649             : 
    1650     1265805 :                 case P_ENUM:
    1651     1265805 :                         if (!lp_set_enum_parm(&parm_table[parmnum], pszParmValue, (int*)parm_ptr)) {
    1652           2 :                                 return false;
    1653             :                         }
    1654     1237458 :                         break;
    1655             : 
    1656             :         }
    1657             : 
    1658    15006051 :         return true;
    1659             : 
    1660             : }
    1661             : 
    1662       12370 : bool handle_name_resolve_order(struct loadparm_context *lp_ctx,
    1663             :                                struct loadparm_service *service,
    1664             :                                const char *pszParmValue, char **ptr)
    1665             : {
    1666       12370 :         const char **valid_values = NULL;
    1667       12370 :         const char **values_to_set = NULL;
    1668         616 :         int i;
    1669       12370 :         bool value_is_valid = false;
    1670       12370 :         valid_values = str_list_make_v3_const(NULL,
    1671             :                                               DEFAULT_NAME_RESOLVE_ORDER,
    1672             :                                               NULL);
    1673       12370 :         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       12370 :         values_to_set = str_list_make_v3_const(lp_ctx->globals->ctx,
    1679             :                                                pszParmValue,
    1680             :                                                NULL);
    1681       12370 :         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       12370 :         TALLOC_FREE(lp_ctx->globals->name_resolve_order);
    1687       61830 :         for (i = 0; values_to_set[i] != NULL; i++) {
    1688       49468 :                 value_is_valid = str_list_check(valid_values, values_to_set[i]);
    1689       49468 :                 if (!value_is_valid) {
    1690           8 :                         DBG_ERR("WARNING: Ignoring invalid list value '%s' "
    1691             :                                 "for parameter 'name resolve order'\n",
    1692             :                                 values_to_set[i]);
    1693           8 :                         break;
    1694             :                 }
    1695             :         }
    1696       12362 : out:
    1697       12370 :         if (value_is_valid) {
    1698       12362 :                 lp_ctx->globals->name_resolve_order = values_to_set;
    1699             :         } else {
    1700           8 :                 TALLOC_FREE(values_to_set);
    1701             :         }
    1702       12370 :         TALLOC_FREE(valid_values);
    1703       12370 :         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           0 :                         int base;
    1747           0 :                         int error;
    1748           0 :                         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           0 :                         int base;
    1816           0 :                         int error;
    1817           0 :                         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    16716869 : 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      182738 :         int i;
    1855      182738 :         bool ok;
    1856             : 
    1857             :         /* if it is a special case then go ahead */
    1858    16716869 :         if (parm_table[parmnum].special) {
    1859     1560476 :                 ok = parm_table[parmnum].special(lp_ctx, service, pszParmValue,
    1860             :                                                   (char **)parm_ptr);
    1861             :         } else {
    1862    15156393 :                 ok = set_variable_helper(mem_ctx, parmnum, parm_ptr,
    1863             :                                          pszParmName, pszParmValue);
    1864             :         }
    1865             : 
    1866    16716869 :         if (!ok) {
    1867          17 :                 return false;
    1868             :         }
    1869             : 
    1870    16716852 :         if (on_globals && (lp_ctx->flags[parmnum] & FLAG_DEFAULT)) {
    1871      381162 :                 lp_ctx->flags[parmnum] &= ~FLAG_DEFAULT;
    1872             :                 /* we have to also unset FLAG_DEFAULT on aliases */
    1873      389802 :                 for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) {
    1874        8640 :                         lp_ctx->flags[i] &= ~FLAG_DEFAULT;
    1875             :                 }
    1876      433274 :                 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset;i++) {
    1877       52112 :                         lp_ctx->flags[i] &= ~FLAG_DEFAULT;
    1878             :                 }
    1879             :         }
    1880    16534114 :         return true;
    1881             : }
    1882             : 
    1883             : 
    1884     9223991 : bool lpcfg_do_global_parameter(struct loadparm_context *lp_ctx,
    1885             :                                const char *pszParmName, const char *pszParmValue)
    1886             : {
    1887     9223991 :         int parmnum = lpcfg_map_parameter(pszParmName);
    1888      185605 :         void *parm_ptr;
    1889             : 
    1890     9223991 :         if (parmnum < 0) {
    1891     1880942 :                 if (strchr(pszParmName, ':')) {
    1892     1880940 :                         return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName, pszParmValue, 0);
    1893             :                 }
    1894           2 :                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
    1895           2 :                 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     7343049 :         if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) {
    1901       47875 :                 return true;
    1902             :         }
    1903             : 
    1904     7294868 :         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
    1905      363809 :                 char *suppress_env = getenv("SAMBA_DEPRECATED_SUPPRESS");
    1906      377604 :                 bool print_warning = (suppress_env == NULL
    1907      363809 :                                       || suppress_env[0] == '\0');
    1908      363809 :                 if (print_warning) {
    1909           4 :                         DBG_WARNING("WARNING: The \"%s\" option "
    1910             :                                     "is deprecated\n",
    1911             :                                     pszParmName);
    1912             : 
    1913             :                 }
    1914             :         }
    1915             : 
    1916     7294868 :         parm_ptr = lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[parmnum]);
    1917             : 
    1918     7294868 :         return set_variable(lp_ctx->globals->ctx, NULL, parmnum, parm_ptr,
    1919             :                             pszParmName, pszParmValue, lp_ctx, true);
    1920             : }
    1921             : 
    1922    12887510 : bool lpcfg_do_service_parameter(struct loadparm_context *lp_ctx,
    1923             :                                 struct loadparm_service *service,
    1924             :                                 const char *pszParmName, const char *pszParmValue)
    1925             : {
    1926       12691 :         void *parm_ptr;
    1927       12691 :         int i;
    1928    12887510 :         int parmnum = lpcfg_map_parameter(pszParmName);
    1929             : 
    1930    12887510 :         if (parmnum < 0) {
    1931     3465281 :                 if (strchr(pszParmName, ':')) {
    1932     3465281 :                         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     9422229 :         if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) {
    1941         228 :                 return true;
    1942             :         }
    1943             : 
    1944     9422001 :         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     9422001 :         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     9422001 :         parm_ptr = ((char *)service) + parm_table[parmnum].offset;
    1963             : 
    1964     9422001 :         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  4899440520 :         for (i = 0; parm_table[i].label; i++)
    1970  4890018519 :                 if (parm_table[i].offset == parm_table[parmnum].offset &&
    1971    24250957 :                     parm_table[i].p_class == parm_table[parmnum].p_class)
    1972    15658375 :                         bitmap_clear(service->copymap, i);
    1973             : 
    1974     9422001 :         return set_variable(service, service, parmnum, parm_ptr, pszParmName,
    1975             :                             pszParmValue, lp_ctx, false);
    1976             : }
    1977             : 
    1978             : /**
    1979             :  * Process a parameter.
    1980             :  */
    1981             : 
    1982     3121280 : bool lpcfg_do_parameter(const char *pszParmName, const char *pszParmValue,
    1983             :                          void *userdata)
    1984             : {
    1985     3121280 :         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
    1986             : 
    1987     3121280 :         if (lp_ctx->bInGlobalSection)
    1988     2075937 :                 return lpcfg_do_global_parameter(lp_ctx, pszParmName,
    1989             :                                               pszParmValue);
    1990             :         else
    1991     1045343 :                 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      187634 : bool lpcfg_do_global_parameter_var(struct loadparm_context *lp_ctx,
    2000             :                                 const char *pszParmName, const char *fmt, ...)
    2001             : {
    2002        9241 :         char *s;
    2003        9241 :         bool ret;
    2004        9241 :         va_list ap;
    2005             : 
    2006      187634 :         va_start(ap, fmt);
    2007      187634 :         s = talloc_vasprintf(NULL, fmt, ap);
    2008      187634 :         va_end(ap);
    2009      187634 :         ret = lpcfg_do_global_parameter(lp_ctx, pszParmName, s);
    2010      187634 :         talloc_free(s);
    2011      187634 :         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       62104 : bool lpcfg_set_cmdline(struct loadparm_context *lp_ctx, const char *pszParmName,
    2021             :                        const char *pszParmValue)
    2022             : {
    2023        1193 :         int parmnum;
    2024        1193 :         int i;
    2025             : 
    2026       65006 :         while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
    2027             : 
    2028       62104 :         parmnum = lpcfg_map_parameter(pszParmName);
    2029             : 
    2030       62104 :         if (parmnum < 0 && strchr(pszParmName, ':')) {
    2031             :                 /* set a parametric option */
    2032         911 :                 bool ok;
    2033       26213 :                 ok = lp_do_parameter_parametric(lp_ctx, NULL, pszParmName,
    2034             :                                                 pszParmValue, FLAG_CMDLINE);
    2035       26213 :                 if (lp_ctx->s3_fns != NULL) {
    2036         411 :                         if (ok) {
    2037         411 :                                 lp_ctx->s3_fns->store_cmdline(pszParmName, pszParmValue);
    2038             :                         }
    2039             :                 }
    2040       26213 :                 return ok;
    2041             :         }
    2042             : 
    2043       35891 :         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       35891 :         lp_ctx->flags[parmnum] &= ~FLAG_CMDLINE;
    2050             : 
    2051       35891 :         if (!lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) {
    2052           5 :                 return false;
    2053             :         }
    2054             : 
    2055       35886 :         lp_ctx->flags[parmnum] |= FLAG_CMDLINE;
    2056             : 
    2057             :         /* we have to also set FLAG_CMDLINE on aliases */
    2058       35886 :         for (i=parmnum-1;
    2059       36167 :              i>=0 && parm_table[i].p_class == parm_table[parmnum].p_class &&
    2060       35154 :              parm_table[i].offset == parm_table[parmnum].offset;
    2061         281 :              i--) {
    2062         281 :                 lp_ctx->flags[i] |= FLAG_CMDLINE;
    2063             :         }
    2064       35886 :         for (i=parmnum+1;
    2065       57382 :              i<num_parameters() &&
    2066       57019 :              parm_table[i].p_class == parm_table[parmnum].p_class &&
    2067       53976 :              parm_table[i].offset == parm_table[parmnum].offset;
    2068       21133 :              i++) {
    2069       21133 :                 lp_ctx->flags[i] |= FLAG_CMDLINE;
    2070             :         }
    2071             : 
    2072       35886 :         if (lp_ctx->s3_fns != NULL) {
    2073       31163 :                 lp_ctx->s3_fns->store_cmdline(pszParmName, pszParmValue);
    2074             :         }
    2075             : 
    2076       35604 :         return true;
    2077             : }
    2078             : 
    2079             : /*
    2080             :   set a option from the commandline in 'a=b' format. Use to support --option
    2081             : */
    2082       11361 : bool lpcfg_set_option(struct loadparm_context *lp_ctx, const char *option)
    2083             : {
    2084         375 :         char *p, *s;
    2085         375 :         bool ret;
    2086             : 
    2087       11361 :         s = talloc_strdup(NULL, option);
    2088       11361 :         if (!s) {
    2089           0 :                 return false;
    2090             :         }
    2091             : 
    2092       11361 :         p = strchr(s, '=');
    2093       11361 :         if (!p) {
    2094           1 :                 talloc_free(s);
    2095           1 :                 return false;
    2096             :         }
    2097             : 
    2098       11360 :         *p = 0;
    2099             : 
    2100       11360 :         ret = lpcfg_set_cmdline(lp_ctx, s, p+1);
    2101       11360 :         talloc_free(s);
    2102       11360 :         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       51676 : void lpcfg_print_parameter(struct parm_struct *p, void *ptr, FILE * f)
    2113             : {
    2114             :         /* For the separation of lists values that we print below */
    2115       51676 :         const char *list_sep = ", ";
    2116        1648 :         int i;
    2117       51676 :         switch (p->type)
    2118             :         {
    2119        4648 :                 case P_ENUM:
    2120       21012 :                         for (i = 0; p->enum_list[i].name; i++) {
    2121       21012 :                                 if (*(int *)ptr == p->enum_list[i].value) {
    2122        6439 :                                         fprintf(f, "%s",
    2123        4791 :                                                 p->enum_list[i].name);
    2124        4648 :                                         break;
    2125             :                                 }
    2126             :                         }
    2127        4648 :                         break;
    2128             : 
    2129       15618 :                 case P_BOOL:
    2130       15618 :                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
    2131       15193 :                         break;
    2132             : 
    2133          12 :                 case P_BOOLREV:
    2134          12 :                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
    2135          12 :                         break;
    2136             : 
    2137        6355 :                 case P_INTEGER:
    2138             :                 case P_BYTES:
    2139        6355 :                         fprintf(f, "%d", *(int *)ptr);
    2140        6166 :                         break;
    2141             : 
    2142          73 :                 case P_CHAR:
    2143          73 :                         fprintf(f, "%c", *(char *)ptr);
    2144          71 :                         break;
    2145             : 
    2146         851 :                 case P_OCTAL: {
    2147         851 :                         int val = *(int *)ptr;
    2148         851 :                         if (val == -1) {
    2149           0 :                                 fprintf(f, "-1");
    2150             :                         } else {
    2151         851 :                                 fprintf(f, "0%03o", val);
    2152             :                         }
    2153         835 :                         break;
    2154             :                 }
    2155             : 
    2156        3761 :                 case P_CMDLIST:
    2157        3761 :                         list_sep = " ";
    2158             : 
    2159         171 :                         FALL_THROUGH;
    2160        5195 :                 case P_LIST:
    2161        5195 :                         if ((char ***)ptr && *(char ***)ptr) {
    2162        3521 :                                 char **list = *(char ***)ptr;
    2163       19067 :                                 for (; *list; list++) {
    2164             :                                         /* surround strings with whitespace in double quotes */
    2165       15419 :                                         if (*(list+1) == NULL) {
    2166             :                                                 /* last item, no extra separator */
    2167        3648 :                                                 list_sep = "";
    2168             :                                         }
    2169       15419 :                                         if ( strchr_m( *list, ' ' ) ) {
    2170          24 :                                                 fprintf(f, "\"%s\"%s", *list, list_sep);
    2171             :                                         } else {
    2172       15395 :                                                 fprintf(f, "%s%s", *list, list_sep);
    2173             :                                         }
    2174             :                                 }
    2175             :                         }
    2176        5024 :                         break;
    2177             : 
    2178       18781 :                 case P_STRING:
    2179             :                 case P_USTRING:
    2180       18781 :                         if (*(char **)ptr) {
    2181       18781 :                                 fprintf(f, "%s", *(char **)ptr);
    2182             :                         }
    2183       18079 :                         break;
    2184             :         }
    2185       51676 : }
    2186             : 
    2187             : /**
    2188             :  * Check if two parameters are equal.
    2189             :  */
    2190             : 
    2191      460092 : static bool lpcfg_equal_parameter(parm_type type, void *ptr1, void *ptr2)
    2192             : {
    2193      460092 :         switch (type) {
    2194      230046 :                 case P_BOOL:
    2195             :                 case P_BOOLREV:
    2196      230046 :                         return (*((bool *)ptr1) == *((bool *)ptr2));
    2197             : 
    2198       90018 :                 case P_INTEGER:
    2199             :                 case P_ENUM:
    2200             :                 case P_OCTAL:
    2201             :                 case P_BYTES:
    2202       90018 :                         return (*((int *)ptr1) == *((int *)ptr2));
    2203             : 
    2204        3334 :                 case P_CHAR:
    2205        3334 :                         return (*((char *)ptr1) == *((char *)ptr2));
    2206             : 
    2207       33340 :                 case P_LIST:
    2208             :                 case P_CMDLIST:
    2209       33340 :                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
    2210             : 
    2211      103354 :                 case P_STRING:
    2212             :                 case P_USTRING:
    2213             :                 {
    2214      103354 :                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
    2215      103354 :                         if (p1 && !*p1)
    2216       73416 :                                 p1 = NULL;
    2217      103354 :                         if (p2 && !*p2)
    2218       78312 :                                 p2 = NULL;
    2219      103850 :                         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      342615 : static bool do_section(const char *pszSectionName, void *userdata)
    2234             : {
    2235      342615 :         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
    2236        3724 :         bool bRetval;
    2237        3724 :         bool isglobal;
    2238             : 
    2239      342615 :         if (lp_ctx->s3_fns != NULL) {
    2240           0 :                 return lp_ctx->s3_fns->do_section(pszSectionName, lp_ctx);
    2241             :         }
    2242             : 
    2243      648423 :         isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
    2244      305808 :                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
    2245             : 
    2246             :         /* if we've just struck a global section, note the fact. */
    2247      342615 :         lp_ctx->bInGlobalSection = isglobal;
    2248             : 
    2249             :         /* check for multiple global sections */
    2250      342615 :         if (lp_ctx->bInGlobalSection) {
    2251       37000 :                 DEBUG(4, ("Processing section \"[%s]\"\n", pszSectionName));
    2252       37000 :                 bRetval = true;
    2253       37000 :                 goto out;
    2254             :         }
    2255             : 
    2256             :         /* if we have a current service, tidy it up before moving on */
    2257      305615 :         bRetval = true;
    2258             : 
    2259      305615 :         if (lp_ctx->currentService != NULL)
    2260      287271 :                 bRetval = lpcfg_service_ok(lp_ctx->currentService);
    2261             : 
    2262             :         /* if all is still well, move to the next record in the services array */
    2263      305418 :         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      305615 :                 DEBUG(4, ("Processing section \"[%s]\"\n", pszSectionName));
    2267             : 
    2268      305615 :                 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      305615 : out:
    2277      338891 :         return bRetval;
    2278             : }
    2279             : 
    2280             : 
    2281             : /**
    2282             :  * Determine if a particular base parameter is currently set to the default value.
    2283             :  */
    2284             : 
    2285       10992 : static bool is_default(void *base_structure, int i)
    2286             : {
    2287       10992 :         void *def_ptr = ((char *)base_structure) + parm_table[i].offset;
    2288       10992 :         switch (parm_table[i].type) {
    2289        1439 :                 case P_CMDLIST:
    2290             :                 case P_LIST:
    2291        1439 :                         return str_list_equal((const char * const *)parm_table[i].def.lvalue,
    2292             :                                               *(const char * const **)def_ptr);
    2293        5458 :                 case P_STRING:
    2294             :                 case P_USTRING:
    2295        5458 :                         return strequal(parm_table[i].def.svalue,
    2296             :                                         *(char **)def_ptr);
    2297        2076 :                 case P_BOOL:
    2298             :                 case P_BOOLREV:
    2299        2076 :                         return parm_table[i].def.bvalue ==
    2300        2076 :                                 *(bool *)def_ptr;
    2301        2019 :                 case P_INTEGER:
    2302             :                 case P_CHAR:
    2303             :                 case P_OCTAL:
    2304             :                 case P_BYTES:
    2305             :                 case P_ENUM:
    2306        2019 :                         return parm_table[i].def.ivalue ==
    2307        2019 :                                 *(int *)def_ptr;
    2308             :         }
    2309           0 :         return false;
    2310             : }
    2311             : 
    2312             : /**
    2313             :  *Display the contents of the global structure.
    2314             :  */
    2315             : 
    2316        1296 : void lpcfg_dump_globals(struct loadparm_context *lp_ctx, FILE *f,
    2317             :                          bool show_defaults)
    2318             : {
    2319          27 :         int i;
    2320          27 :         struct parmlist_entry *data;
    2321             : 
    2322        1296 :         fprintf(f, "# Global parameters\n[global]\n");
    2323             : 
    2324      673947 :         for (i = 0; parm_table[i].label; i++) {
    2325      672624 :                 if (parm_table[i].p_class != P_GLOBAL) {
    2326      203472 :                         continue;
    2327             :                 }
    2328             : 
    2329      469152 :                 if (parm_table[i].flags & FLAG_SYNONYM) {
    2330       25920 :                         continue;
    2331             :                 }
    2332             : 
    2333      443232 :                 if (!show_defaults) {
    2334      421002 :                         if (lp_ctx->flags && (lp_ctx->flags[i] & FLAG_DEFAULT)) {
    2335      411473 :                                 continue;
    2336             :                         }
    2337             : 
    2338        9529 :                         if (is_default(lp_ctx->globals, i)) {
    2339        1385 :                                 continue;
    2340             :                         }
    2341             :                 }
    2342             : 
    2343       30374 :                 fprintf(f, "\t%s = ", parm_table[i].label);
    2344       30374 :                 lpcfg_print_parameter(&parm_table[i], lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[i]), f);
    2345       43217 :                 fprintf(f, "\n");
    2346             :         }
    2347        1296 :         if (lp_ctx->globals->param_opt != NULL) {
    2348       11670 :                 for (data = lp_ctx->globals->param_opt; data;
    2349       10374 :                      data = data->next) {
    2350       10374 :                         if (!show_defaults && (data->priority & FLAG_DEFAULT)) {
    2351        2120 :                                 continue;
    2352             :                         }
    2353        8329 :                         fprintf(f, "\t%s = %s\n", data->key, data->value);
    2354             :                 }
    2355             :         }
    2356             : 
    2357        1296 : }
    2358             : 
    2359             : /**
    2360             :  * Display the contents of a single services record.
    2361             :  */
    2362             : 
    2363        4628 : void lpcfg_dump_a_service(struct loadparm_service * pService, struct loadparm_service *sDefault, FILE * f,
    2364             :                           unsigned int *flags, bool show_defaults)
    2365             : {
    2366         112 :         int i;
    2367         112 :         struct parmlist_entry *data;
    2368             : 
    2369        4628 :         if (pService != sDefault)
    2370        3334 :                 fprintf(f, "\n[%s]\n", pService->szService);
    2371             : 
    2372     2406560 :         for (i = 0; parm_table[i].label; i++) {
    2373     2401932 :                 if (parm_table[i].p_class != P_LOCAL) {
    2374     1675336 :                         continue;
    2375             :                 }
    2376             : 
    2377      726596 :                 if (parm_table[i].flags & FLAG_SYNONYM) {
    2378       83304 :                         continue;
    2379             :                 }
    2380             : 
    2381      643292 :                 if (*parm_table[i].label == '-') {
    2382        4628 :                         continue;
    2383             :                 }
    2384             : 
    2385      638664 :                 if (pService == sDefault) {
    2386      178572 :                         if (!show_defaults) {
    2387      169602 :                                 if (flags && (flags[i] & FLAG_DEFAULT)) {
    2388      168139 :                                         continue;
    2389             :                                 }
    2390             : 
    2391        1463 :                                 if (is_default(sDefault, i)) {
    2392         215 :                                         continue;
    2393             :                                 }
    2394             :                         }
    2395             :                 } else {
    2396       12006 :                         bool equal;
    2397             : 
    2398      472098 :                         equal = lpcfg_equal_parameter(parm_table[i].type,
    2399             :                                                       ((char *)pService) +
    2400      448086 :                                                       parm_table[i].offset,
    2401             :                                                       ((char *)sDefault) +
    2402      460092 :                                                       parm_table[i].offset);
    2403      460092 :                         if (equal) {
    2404      451782 :                                 continue;
    2405             :                         }
    2406             :                 }
    2407             : 
    2408       18528 :                 fprintf(f, "\t%s = ", parm_table[i].label);
    2409       18528 :                 lpcfg_print_parameter(&parm_table[i],
    2410       18528 :                                 ((char *)pService) + parm_table[i].offset, f);
    2411       76186 :                 fprintf(f, "\n");
    2412             :         }
    2413        4628 :         if (pService->param_opt != NULL) {
    2414        7962 :                 for (data = pService->param_opt; data; data = data->next) {
    2415        5995 :                         if (!show_defaults && (data->priority & FLAG_DEFAULT)) {
    2416           0 :                                 continue;
    2417             :                         }
    2418        5995 :                         fprintf(f, "\t%s = %s\n", data->key, data->value);
    2419             :                 }
    2420             :         }
    2421        4628 : }
    2422             : 
    2423        2921 : bool lpcfg_dump_a_parameter(struct loadparm_context *lp_ctx,
    2424             :                             struct loadparm_service *service,
    2425             :                             const char *parm_name, FILE * f)
    2426             : {
    2427           9 :         struct parm_struct *parm;
    2428           9 :         void *ptr;
    2429           9 :         char *local_parm_name;
    2430           9 :         char *parm_opt;
    2431           9 :         const char *parm_opt_value;
    2432             : 
    2433             :         /* check for parametrical option */
    2434        2921 :         local_parm_name = talloc_strdup(lp_ctx, parm_name);
    2435        2921 :         if (local_parm_name == NULL) {
    2436           0 :                 return false;
    2437             :         }
    2438             : 
    2439        2921 :         parm_opt = strchr( local_parm_name, ':');
    2440             : 
    2441        2921 :         if (parm_opt) {
    2442         146 :                 *parm_opt = '\0';
    2443         146 :                 parm_opt++;
    2444         146 :                 if (strlen(parm_opt)) {
    2445         146 :                         parm_opt_value = lpcfg_parm_string(lp_ctx, service,
    2446             :                                 local_parm_name, parm_opt);
    2447         146 :                         if (parm_opt_value) {
    2448         146 :                                 fprintf(f, "%s\n", parm_opt_value);
    2449         146 :                                 TALLOC_FREE(local_parm_name);
    2450         146 :                                 return true;
    2451             :                         }
    2452             :                 }
    2453           0 :                 TALLOC_FREE(local_parm_name);
    2454           0 :                 return false;
    2455             :         }
    2456        2775 :         TALLOC_FREE(local_parm_name);
    2457             : 
    2458             :         /* parameter is not parametric, search the table */
    2459        2775 :         parm = lpcfg_parm_struct(lp_ctx, parm_name);
    2460        2775 :         if (!parm) {
    2461           0 :                 return false;
    2462             :         }
    2463             : 
    2464        2774 :         if (service != NULL && parm->p_class == P_GLOBAL) {
    2465           0 :                 return false;
    2466             :         }
    2467             : 
    2468        2774 :         ptr = lpcfg_parm_ptr(lp_ctx, service,parm);
    2469             : 
    2470        2774 :         lpcfg_print_parameter(parm, ptr, f);
    2471        2774 :         fprintf(f, "\n");
    2472        2774 :         return true;
    2473             : }
    2474             : 
    2475             : /**
    2476             :  * Auto-load some home services.
    2477             :  */
    2478       28941 : static void lpcfg_add_auto_services(struct loadparm_context *lp_ctx,
    2479             :                                     const char *str)
    2480             : {
    2481       28941 :         return;
    2482             : }
    2483             : 
    2484             : /***************************************************************************
    2485             :  Initialise the sDefault parameter structure for the printer values.
    2486             : ***************************************************************************/
    2487             : 
    2488      149598 : 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      149598 :         switch (pService->printing) {
    2493       39519 :                 case PRINT_BSD:
    2494             :                 case PRINT_AIX:
    2495             :                 case PRINT_LPRNT:
    2496             :                 case PRINT_LPROS2:
    2497       39519 :                         lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
    2498       39519 :                         lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
    2499       39519 :                         lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
    2500       39519 :                         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      110079 :                 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      110079 :                         lpcfg_string_set(ctx, &pService->lpq_command, "%p");
    2518      110079 :                         lpcfg_string_set(ctx, &pService->lprm_command, "");
    2519      110079 :                         lpcfg_string_set(ctx, &pService->print_command, "");
    2520      110079 :                         lpcfg_string_set(ctx, &pService->lppause_command, "");
    2521      110079 :                         lpcfg_string_set(ctx, &pService->lpresume_command, "");
    2522      110079 :                         lpcfg_string_set(ctx, &pService->queuepause_command, "");
    2523      110079 :                         lpcfg_string_set(ctx, &pService->queueresume_command, "");
    2524      110079 :                         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           0 :                 const char *tdbfile;
    2550           0 :                 TALLOC_CTX *tmp_ctx = talloc_new(ctx);
    2551           0 :                 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      149598 : }
    2605             : 
    2606             : 
    2607          63 : static int lpcfg_destructor(struct loadparm_context *lp_ctx)
    2608             : {
    2609          63 :         struct parmlist_entry *data;
    2610             : 
    2611          63 :         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          63 :         if (lp_ctx->globals->param_opt != NULL) {
    2619             :                 struct parmlist_entry *next;
    2620         257 :                 for (data = lp_ctx->globals->param_opt; data; data=next) {
    2621         194 :                         next = data->next;
    2622         194 :                         if (data->priority & FLAG_CMDLINE) continue;
    2623         189 :                         DLIST_REMOVE(lp_ctx->globals->param_opt, data);
    2624         189 :                         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       12357 : struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
    2637             : {
    2638         616 :         int i;
    2639         616 :         char *myname;
    2640         616 :         struct loadparm_context *lp_ctx;
    2641         616 :         struct parmlist_entry *parm;
    2642         616 :         char *logfile;
    2643             : 
    2644       12357 :         lp_ctx = talloc_zero(mem_ctx, struct loadparm_context);
    2645       12357 :         if (lp_ctx == NULL)
    2646           0 :                 return NULL;
    2647             : 
    2648       12357 :         talloc_set_destructor(lp_ctx, lpcfg_destructor);
    2649       12357 :         lp_ctx->bInGlobalSection = true;
    2650       12357 :         lp_ctx->globals = talloc_zero(lp_ctx, struct loadparm_global);
    2651             :         /* This appears odd, but globals in s3 isn't a pointer */
    2652       12357 :         lp_ctx->globals->ctx = lp_ctx->globals;
    2653       12357 :         lp_ctx->globals->rpc_low_port = SERVER_TCP_LOW_PORT;
    2654       12357 :         lp_ctx->globals->rpc_high_port = SERVER_TCP_HIGH_PORT;
    2655       12357 :         lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_UNKNOWN;
    2656       12357 :         lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
    2657       12357 :         lp_ctx->flags = talloc_zero_array(lp_ctx, unsigned int, num_parameters());
    2658             : 
    2659       12357 :         lp_ctx->sDefault->max_print_jobs = 1000;
    2660       12357 :         lp_ctx->sDefault->available = true;
    2661       12357 :         lp_ctx->sDefault->browseable = true;
    2662       12357 :         lp_ctx->sDefault->read_only = true;
    2663       12357 :         lp_ctx->sDefault->map_archive = true;
    2664       12357 :         lp_ctx->sDefault->strict_locking = true;
    2665       12357 :         lp_ctx->sDefault->oplocks = true;
    2666       12357 :         lp_ctx->sDefault->create_mask = 0744;
    2667       12357 :         lp_ctx->sDefault->force_create_mode = 0000;
    2668       12357 :         lp_ctx->sDefault->directory_mask = 0755;
    2669       12357 :         lp_ctx->sDefault->force_directory_mode = 0000;
    2670       12357 :         lp_ctx->sDefault->aio_read_size = 1;
    2671       12357 :         lp_ctx->sDefault->aio_write_size = 1;
    2672       12357 :         lp_ctx->sDefault->smbd_search_ask_sharemode = true;
    2673       12357 :         lp_ctx->sDefault->smbd_getinfo_ask_sharemode = true;
    2674       12357 :         lp_ctx->sDefault->volume_serial_number = -1;
    2675             : 
    2676       12357 :         DEBUG(3, ("Initialising global parameters\n"));
    2677             : 
    2678     6425640 :         for (i = 0; parm_table[i].label; i++) {
    2679     6413283 :                 if ((parm_table[i].type == P_STRING ||
    2680     4526802 :                      parm_table[i].type == P_USTRING) &&
    2681     1779408 :                     !(lp_ctx->flags[i] & FLAG_CMDLINE)) {
    2682       88704 :                         TALLOC_CTX *parent_mem;
    2683       88704 :                         char **r;
    2684     1779408 :                         if (parm_table[i].p_class == P_LOCAL) {
    2685      432495 :                                 parent_mem = lp_ctx->sDefault;
    2686      432495 :                                 r = (char **)(((char *)lp_ctx->sDefault) + parm_table[i].offset);
    2687             :                         } else {
    2688     1346913 :                                 parent_mem = lp_ctx->globals;
    2689     1346913 :                                 r = (char **)(((char *)lp_ctx->globals) + parm_table[i].offset);
    2690             :                         }
    2691     1779408 :                         lpcfg_string_set(parent_mem, r, "");
    2692             :                 }
    2693             :         }
    2694             : 
    2695       12357 :         logfile = talloc_asprintf(lp_ctx, "%s/log.samba", dyn_LOGFILEBASE);
    2696       12357 :         lpcfg_do_global_parameter(lp_ctx, "log file", logfile);
    2697       12357 :         talloc_free(logfile);
    2698             : 
    2699       12357 :         lpcfg_do_global_parameter(lp_ctx, "log level", "0");
    2700             : 
    2701       12357 :         lpcfg_do_global_parameter(lp_ctx, "syslog", "1");
    2702       12357 :         lpcfg_do_global_parameter(lp_ctx, "syslog only", "No");
    2703       12357 :         lpcfg_do_global_parameter(lp_ctx, "debug timestamp", "Yes");
    2704       12357 :         lpcfg_do_global_parameter(lp_ctx, "debug prefix timestamp", "No");
    2705       12357 :         lpcfg_do_global_parameter(lp_ctx, "debug hires timestamp", "Yes");
    2706       12357 :         lpcfg_do_global_parameter(lp_ctx, "debug syslog format", "No");
    2707       12357 :         lpcfg_do_global_parameter(lp_ctx, "debug pid", "No");
    2708       12357 :         lpcfg_do_global_parameter(lp_ctx, "debug uid", "No");
    2709       12357 :         lpcfg_do_global_parameter(lp_ctx, "debug class", "No");
    2710       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind debug traceid", "Yes");
    2711             : 
    2712       12357 :         lpcfg_do_global_parameter(lp_ctx, "server role", "auto");
    2713       12357 :         lpcfg_do_global_parameter(lp_ctx, "domain logons", "No");
    2714       12357 :         lpcfg_do_global_parameter(lp_ctx, "domain master", "Auto");
    2715             : 
    2716             :         /* options that can be set on the command line must be initialised via
    2717             :            the slower lpcfg_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */
    2718             : #ifdef TCP_NODELAY
    2719       12357 :         lpcfg_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY");
    2720             : #endif
    2721       12357 :         lpcfg_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP);
    2722       12357 :         myname = get_myname(lp_ctx);
    2723       12357 :         lpcfg_do_global_parameter(lp_ctx, "netbios name", myname);
    2724       12357 :         talloc_free(myname);
    2725       12357 :         lpcfg_do_global_parameter(lp_ctx,
    2726             :                                   "name resolve order",
    2727             :                                   DEFAULT_NAME_RESOLVE_ORDER);
    2728             : 
    2729       12357 :         lpcfg_do_global_parameter(lp_ctx, "fstype", "NTFS");
    2730             : 
    2731       12357 :         lpcfg_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
    2732       12357 :         lpcfg_do_global_parameter(lp_ctx, "max connections", "0");
    2733             : 
    2734       12357 :         lpcfg_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper wkssvc samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver");
    2735       12357 :         lpcfg_do_global_parameter(lp_ctx, "server services", "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns");
    2736       12357 :         lpcfg_do_global_parameter(lp_ctx, "kccsrv:samba_kcc", "true");
    2737             :         /* the winbind method for domain controllers is for both RODC
    2738             :            auth forwarding and for trusted domains */
    2739       12357 :         lpcfg_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
    2740       12357 :         lpcfg_do_global_parameter(lp_ctx, "binddns dir", dyn_BINDDNS_DIR);
    2741       12357 :         lpcfg_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
    2742             : 
    2743             :         /* This hive should be dynamically generated by Samba using
    2744             :            data from the sam, but for the moment leave it in a tdb to
    2745             :            keep regedt32 from popping up an annoying dialog. */
    2746       12357 :         lpcfg_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb");
    2747             : 
    2748             :         /* using UTF8 by default allows us to support all chars */
    2749       12357 :         lpcfg_do_global_parameter(lp_ctx, "unix charset", "UTF-8");
    2750             : 
    2751             :         /* Use codepage 850 as a default for the dos character set */
    2752       12357 :         lpcfg_do_global_parameter(lp_ctx, "dos charset", "CP850");
    2753             : 
    2754             :         /*
    2755             :          * Allow the default PASSWD_CHAT to be overridden in local.h.
    2756             :          */
    2757       12357 :         lpcfg_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT);
    2758             : 
    2759       12357 :         lpcfg_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR);
    2760       12357 :         lpcfg_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR);
    2761       12357 :         lpcfg_do_global_parameter(lp_ctx, "state directory", dyn_STATEDIR);
    2762       12357 :         lpcfg_do_global_parameter(lp_ctx, "cache directory", dyn_CACHEDIR);
    2763       12357 :         lpcfg_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
    2764             : 
    2765       12357 :         lpcfg_do_global_parameter(lp_ctx, "nbt client socket address", "0.0.0.0");
    2766       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "server string",
    2767             :                                    "Samba %s", SAMBA_VERSION_STRING);
    2768             : 
    2769       12357 :         lpcfg_do_global_parameter(lp_ctx, "password server", "*");
    2770             : 
    2771       12357 :         lpcfg_do_global_parameter(lp_ctx, "max mux", "50");
    2772       12357 :         lpcfg_do_global_parameter(lp_ctx, "max xmit", "16644");
    2773       12357 :         lpcfg_do_global_parameter(lp_ctx, "host msdfs", "true");
    2774             : 
    2775       12357 :         lpcfg_do_global_parameter(lp_ctx, "LargeReadwrite", "True");
    2776       12357 :         lpcfg_do_global_parameter(lp_ctx, "server min protocol", "SMB2_02");
    2777       12357 :         lpcfg_do_global_parameter(lp_ctx, "server max protocol", "SMB3");
    2778       12357 :         lpcfg_do_global_parameter(lp_ctx, "client min protocol", "SMB2_02");
    2779       12357 :         lpcfg_do_global_parameter(lp_ctx, "client max protocol", "default");
    2780       12357 :         lpcfg_do_global_parameter(lp_ctx, "client ipc min protocol", "default");
    2781       12357 :         lpcfg_do_global_parameter(lp_ctx, "client ipc max protocol", "default");
    2782       12357 :         lpcfg_do_global_parameter(lp_ctx, "security", "AUTO");
    2783       12357 :         lpcfg_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
    2784       12357 :         lpcfg_do_global_parameter(lp_ctx, "ReadRaw", "True");
    2785       12357 :         lpcfg_do_global_parameter(lp_ctx, "WriteRaw", "True");
    2786       12357 :         lpcfg_do_global_parameter(lp_ctx, "NullPasswords", "False");
    2787       12357 :         lpcfg_do_global_parameter(lp_ctx, "old password allowed period", "60");
    2788       12357 :         lpcfg_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
    2789             : 
    2790       12357 :         lpcfg_do_global_parameter(lp_ctx, "TimeServer", "False");
    2791       12357 :         lpcfg_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False");
    2792       12357 :         lpcfg_do_global_parameter(lp_ctx, "Unicode", "True");
    2793       12357 :         lpcfg_do_global_parameter(lp_ctx, "ClientLanManAuth", "False");
    2794       12357 :         lpcfg_do_global_parameter(lp_ctx, "ClientNTLMv2Auth", "True");
    2795       12357 :         lpcfg_do_global_parameter(lp_ctx, "LanmanAuth", "False");
    2796       12357 :         lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "ntlmv2-only");
    2797       12357 :         lpcfg_do_global_parameter(lp_ctx, "NT hash store", "always");
    2798       12357 :         lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False");
    2799       12357 :         lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False");
    2800             : 
    2801       12357 :         lpcfg_do_global_parameter(lp_ctx, "allow dcerpc auth level connect", "False");
    2802             : 
    2803       12357 :         lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True");
    2804             : 
    2805       12357 :         lpcfg_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
    2806       12357 :         lpcfg_do_global_parameter(lp_ctx, "LocalMaster", "True");
    2807             : 
    2808       12357 :         lpcfg_do_global_parameter(lp_ctx, "wins support", "False");
    2809       12357 :         lpcfg_do_global_parameter(lp_ctx, "dns proxy", "True");
    2810             : 
    2811       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind separator", "\\");
    2812       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
    2813       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind scan trusted domains", "False");
    2814       12357 :         lpcfg_do_global_parameter(lp_ctx, "require strong key", "True");
    2815       12357 :         lpcfg_do_global_parameter(lp_ctx, "reject md5 servers", "True");
    2816       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
    2817       12357 :         lpcfg_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR);
    2818       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "gpo update command", "%s/samba-gpupdate", dyn_SCRIPTSBINDIR);
    2819       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "apply group policies", "False");
    2820       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "dns update command", "%s/samba_dnsupdate", dyn_SCRIPTSBINDIR);
    2821       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "spn update command", "%s/samba_spnupdate", dyn_SCRIPTSBINDIR);
    2822       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "samba kcc command",
    2823             :                                         "%s/samba_kcc", dyn_SCRIPTSBINDIR);
    2824             : #ifdef MIT_KDC_PATH
    2825        2278 :         lpcfg_do_global_parameter_var(lp_ctx,
    2826             :                                       "mit kdc command",
    2827             :                                       MIT_KDC_PATH);
    2828             : #endif
    2829       12357 :         lpcfg_do_global_parameter(lp_ctx, "template shell", "/bin/false");
    2830       12357 :         lpcfg_do_global_parameter(lp_ctx, "template homedir", "/home/%D/%U");
    2831             : 
    2832       12357 :         lpcfg_do_global_parameter(lp_ctx, "client signing", "default");
    2833       12357 :         lpcfg_do_global_parameter(lp_ctx, "client ipc signing", "default");
    2834       12357 :         lpcfg_do_global_parameter(lp_ctx, "server signing", "default");
    2835             : 
    2836       12357 :         lpcfg_do_global_parameter(lp_ctx, "use mmap", "True");
    2837             : 
    2838       12357 :         lpcfg_do_global_parameter(lp_ctx, "smb ports", "445 139");
    2839       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "nbt port", "%d", NBT_NAME_SERVICE_PORT);
    2840       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "dgram port", "%d", NBT_DGRAM_SERVICE_PORT);
    2841       12357 :         lpcfg_do_global_parameter(lp_ctx, "cldap port", "389");
    2842       12357 :         lpcfg_do_global_parameter(lp_ctx, "krb5 port", "88");
    2843       12357 :         lpcfg_do_global_parameter(lp_ctx, "kpasswd port", "464");
    2844       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "dns port", "%d", DNS_SERVICE_PORT);
    2845             : 
    2846       12357 :         lpcfg_do_global_parameter(lp_ctx, "kdc enable fast", "True");
    2847             : 
    2848       12357 :         lpcfg_do_global_parameter(lp_ctx, "nt status support", "True");
    2849             : 
    2850       12357 :         lpcfg_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */
    2851       12357 :         lpcfg_do_global_parameter(lp_ctx, "min wins ttl", "21600");
    2852             : 
    2853       12357 :         lpcfg_do_global_parameter(lp_ctx, "tls enabled", "True");
    2854       12357 :         lpcfg_do_global_parameter(lp_ctx, "tls verify peer", "as_strict_as_possible");
    2855       12357 :         lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
    2856       12357 :         lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
    2857       12357 :         lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
    2858       12357 :         lpcfg_do_global_parameter(lp_ctx,
    2859             :                                   "tls priority",
    2860             :                                   "NORMAL:-VERS-SSL3.0");
    2861             : 
    2862       12357 :         lpcfg_do_global_parameter(lp_ctx, "nsupdate command", "/usr/bin/nsupdate -g");
    2863             : 
    2864       12357 :         lpcfg_do_global_parameter(lp_ctx, "allow dns updates", "secure only");
    2865       12357 :         lpcfg_do_global_parameter(lp_ctx, "dns zone scavenging", "False");
    2866       12357 :         lpcfg_do_global_parameter(lp_ctx, "dns forwarder", "");
    2867             : 
    2868       12357 :         lpcfg_do_global_parameter(lp_ctx, "algorithmic rid base", "1000");
    2869             : 
    2870       12357 :         lpcfg_do_global_parameter(lp_ctx, "enhanced browsing", "True");
    2871             : 
    2872       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind nss info", "template");
    2873             : 
    2874       12357 :         lpcfg_do_global_parameter(lp_ctx, "server schannel", "True");
    2875       12357 :         lpcfg_do_global_parameter(lp_ctx, "server schannel require seal", "True");
    2876       12357 :         lpcfg_do_global_parameter(lp_ctx, "reject md5 clients", "True");
    2877             : 
    2878       12357 :         lpcfg_do_global_parameter(lp_ctx, "short preserve case", "True");
    2879             : 
    2880       12357 :         lpcfg_do_global_parameter(lp_ctx, "max open files", "16384");
    2881             : 
    2882       12357 :         lpcfg_do_global_parameter(lp_ctx, "cups connection timeout", "30");
    2883             : 
    2884       12357 :         lpcfg_do_global_parameter(lp_ctx, "locking", "True");
    2885             : 
    2886       12357 :         lpcfg_do_global_parameter(lp_ctx, "block size", "1024");
    2887             : 
    2888       12357 :         lpcfg_do_global_parameter(lp_ctx, "client use spnego", "True");
    2889             : 
    2890       12357 :         lpcfg_do_global_parameter(lp_ctx, "change notify", "True");
    2891             : 
    2892       12357 :         lpcfg_do_global_parameter(lp_ctx, "name cache timeout", "660");
    2893             : 
    2894       12357 :         lpcfg_do_global_parameter(lp_ctx, "defer sharing violations", "True");
    2895             : 
    2896       12357 :         lpcfg_do_global_parameter(lp_ctx, "ldap replication sleep", "1000");
    2897             : 
    2898       12357 :         lpcfg_do_global_parameter(lp_ctx, "idmap backend", "tdb");
    2899             : 
    2900       12357 :         lpcfg_do_global_parameter(lp_ctx, "enable privileges", "True");
    2901             : 
    2902       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max write", "%u", DEFAULT_SMB2_MAX_WRITE);
    2903             : 
    2904       12357 :         lpcfg_do_global_parameter(lp_ctx, "passdb backend", "tdbsam");
    2905             : 
    2906       12357 :         lpcfg_do_global_parameter(lp_ctx, "deadtime", "10080");
    2907             : 
    2908       12357 :         lpcfg_do_global_parameter(lp_ctx, "getwd cache", "True");
    2909             : 
    2910       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind nested groups", "True");
    2911             : 
    2912       12357 :         lpcfg_do_global_parameter(lp_ctx, "mangled names", "illegal");
    2913             : 
    2914       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max credits", "%u", DEFAULT_SMB2_MAX_CREDITS);
    2915             : 
    2916       12357 :         lpcfg_do_global_parameter(lp_ctx, "ldap ssl", "start tls");
    2917             : 
    2918       12357 :         lpcfg_do_global_parameter(lp_ctx, "ldap deref", "auto");
    2919             : 
    2920       12357 :         lpcfg_do_global_parameter(lp_ctx, "lm interval", "60");
    2921             : 
    2922       12357 :         lpcfg_do_global_parameter(lp_ctx, "mangling method", "hash2");
    2923             : 
    2924       12357 :         lpcfg_do_global_parameter(lp_ctx, "hide dot files", "True");
    2925             : 
    2926       12357 :         lpcfg_do_global_parameter(lp_ctx, "browse list", "True");
    2927             : 
    2928       12357 :         lpcfg_do_global_parameter(lp_ctx, "passwd chat timeout", "2");
    2929             : 
    2930       12357 :         lpcfg_do_global_parameter(lp_ctx, "guest account", GUEST_ACCOUNT);
    2931             : 
    2932       12357 :         lpcfg_do_global_parameter(lp_ctx, "client schannel", "True");
    2933             : 
    2934       12357 :         lpcfg_do_global_parameter(lp_ctx, "smb encrypt", "default");
    2935             : 
    2936       12357 :         lpcfg_do_global_parameter(lp_ctx, "max log size", "5000");
    2937             : 
    2938       12357 :         lpcfg_do_global_parameter(lp_ctx, "idmap negative cache time", "120");
    2939             : 
    2940       12357 :         lpcfg_do_global_parameter(lp_ctx, "ldap follow referral", "auto");
    2941             : 
    2942       12357 :         lpcfg_do_global_parameter(lp_ctx, "multicast dns register", "yes");
    2943             : 
    2944       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind reconnect delay", "30");
    2945             : 
    2946       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind request timeout", "60");
    2947             : 
    2948       12357 :         lpcfg_do_global_parameter(lp_ctx, "nt acl support", "yes");
    2949             : 
    2950       12357 :         lpcfg_do_global_parameter(lp_ctx, "acl check permissions", "yes");
    2951             : 
    2952       12357 :         lpcfg_do_global_parameter(lp_ctx, "keepalive", "300");
    2953             : 
    2954       12357 :         lpcfg_do_global_parameter(lp_ctx, "smbd profiling level", "off");
    2955             : 
    2956       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind cache time", "300");
    2957             : 
    2958       12357 :         lpcfg_do_global_parameter(lp_ctx, "level2 oplocks", "yes");
    2959             : 
    2960       12357 :         lpcfg_do_global_parameter(lp_ctx, "show add printer wizard", "yes");
    2961             : 
    2962       12357 :         lpcfg_do_global_parameter(lp_ctx, "ldap page size", "1000");
    2963             : 
    2964       12357 :         lpcfg_do_global_parameter(lp_ctx, "kernel share modes", "no");
    2965             : 
    2966       12357 :         lpcfg_do_global_parameter(lp_ctx, "strict locking", "Auto");
    2967             : 
    2968       12357 :         lpcfg_do_global_parameter(lp_ctx, "strict sync", "yes");
    2969             : 
    2970       12357 :         lpcfg_do_global_parameter(lp_ctx, "map readonly", "no");
    2971             : 
    2972       12357 :         lpcfg_do_global_parameter(lp_ctx, "allow trusted domains", "yes");
    2973             : 
    2974       12357 :         lpcfg_do_global_parameter(lp_ctx, "default devmode", "yes");
    2975             : 
    2976       12357 :         lpcfg_do_global_parameter(lp_ctx, "os level", "20");
    2977             : 
    2978       12357 :         lpcfg_do_global_parameter(lp_ctx, "dos filetimes", "yes");
    2979             : 
    2980       12357 :         lpcfg_do_global_parameter(lp_ctx, "mangling char", "~");
    2981             : 
    2982       12357 :         lpcfg_do_global_parameter(lp_ctx, "printcap cache time", "750");
    2983             : 
    2984       12357 :         lpcfg_do_global_parameter(lp_ctx, "create krb5 conf", "yes");
    2985             : 
    2986       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind max clients", "200");
    2987             : 
    2988       12357 :         lpcfg_do_global_parameter(lp_ctx, "acl map full control", "yes");
    2989             : 
    2990       12357 :         lpcfg_do_global_parameter(lp_ctx, "nt pipe support", "yes");
    2991             : 
    2992       12357 :         lpcfg_do_global_parameter(lp_ctx, "ldap debug threshold", "10");
    2993             : 
    2994       12357 :         lpcfg_do_global_parameter(lp_ctx, "client ldap sasl wrapping", "seal");
    2995             : 
    2996       12357 :         lpcfg_do_global_parameter(lp_ctx, "mdns name", "netbios");
    2997             : 
    2998       12357 :         lpcfg_do_global_parameter(lp_ctx, "ldap server require strong auth", "yes");
    2999             : 
    3000       12357 :         lpcfg_do_global_parameter(lp_ctx, "follow symlinks", "yes");
    3001             : 
    3002       12357 :         lpcfg_do_global_parameter(lp_ctx, "machine password timeout", "604800");
    3003             : 
    3004       12357 :         lpcfg_do_global_parameter(lp_ctx, "ldap connection timeout", "2");
    3005             : 
    3006       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind expand groups", "0");
    3007             : 
    3008       12357 :         lpcfg_do_global_parameter(lp_ctx, "stat cache", "yes");
    3009             : 
    3010       12357 :         lpcfg_do_global_parameter(lp_ctx, "lpq cache time", "30");
    3011             : 
    3012       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max trans", "%u", DEFAULT_SMB2_MAX_TRANSACT);
    3013             : 
    3014       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max read", "%u", DEFAULT_SMB2_MAX_READ);
    3015             : 
    3016       12357 :         lpcfg_do_global_parameter(lp_ctx, "durable handles", "yes");
    3017             : 
    3018       12357 :         lpcfg_do_global_parameter(lp_ctx, "max stat cache size", "512");
    3019             : 
    3020       12357 :         lpcfg_do_global_parameter(lp_ctx, "ldap passwd sync", "no");
    3021             : 
    3022       12357 :         lpcfg_do_global_parameter(lp_ctx, "kernel change notify", "yes");
    3023             : 
    3024       12357 :         lpcfg_do_global_parameter(lp_ctx, "max ttl", "259200");
    3025             : 
    3026       12357 :         lpcfg_do_global_parameter(lp_ctx, "blocking locks", "yes");
    3027             : 
    3028       12357 :         lpcfg_do_global_parameter(lp_ctx, "load printers", "yes");
    3029             : 
    3030       12357 :         lpcfg_do_global_parameter(lp_ctx, "idmap cache time", "604800");
    3031             : 
    3032       12357 :         lpcfg_do_global_parameter(lp_ctx, "preserve case", "yes");
    3033             : 
    3034       12357 :         lpcfg_do_global_parameter(lp_ctx, "lm announce", "auto");
    3035             : 
    3036       12357 :         lpcfg_do_global_parameter(lp_ctx, "afs token lifetime", "604800");
    3037             : 
    3038       12357 :         lpcfg_do_global_parameter(lp_ctx, "enable core files", "yes");
    3039             : 
    3040       12357 :         lpcfg_do_global_parameter(lp_ctx, "winbind max domain connections", "1");
    3041             : 
    3042       12357 :         lpcfg_do_global_parameter(lp_ctx, "case sensitive", "auto");
    3043             : 
    3044       12357 :         lpcfg_do_global_parameter(lp_ctx, "ldap timeout", "15");
    3045             : 
    3046       12357 :         lpcfg_do_global_parameter(lp_ctx, "mangle prefix", "1");
    3047             : 
    3048       12357 :         lpcfg_do_global_parameter(lp_ctx, "posix locking", "yes");
    3049             : 
    3050       12357 :         lpcfg_do_global_parameter(lp_ctx, "lock spin time", "200");
    3051             : 
    3052       12357 :         lpcfg_do_global_parameter(lp_ctx, "nmbd bind explicit broadcast", "yes");
    3053             : 
    3054       12357 :         lpcfg_do_global_parameter(lp_ctx, "init logon delay", "100");
    3055             : 
    3056       12357 :         lpcfg_do_global_parameter(lp_ctx, "usershare owner only", "yes");
    3057             : 
    3058       12357 :         lpcfg_do_global_parameter(lp_ctx, "-valid", "yes");
    3059             : 
    3060       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "usershare path", "%s/usershares", get_dyn_STATEDIR());
    3061             : 
    3062             : #ifdef DEVELOPER
    3063       12357 :         lpcfg_do_global_parameter_var(lp_ctx, "panic action", "/bin/sleep 999999999");
    3064             : #endif
    3065             : 
    3066       12357 :         lpcfg_do_global_parameter(lp_ctx, "smb passwd file", get_dyn_SMB_PASSWD_FILE());
    3067             : 
    3068       12357 :         lpcfg_do_global_parameter(lp_ctx, "logon home", "\\\\%N\\%U");
    3069             : 
    3070       12357 :         lpcfg_do_global_parameter(lp_ctx, "logon path", "\\\\%N\\%U\\profile");
    3071             : 
    3072       12357 :         lpcfg_do_global_parameter(lp_ctx, "printjob username", "%U");
    3073             : 
    3074       12357 :         lpcfg_do_global_parameter(lp_ctx, "aio max threads", "100");
    3075             : 
    3076       12357 :         lpcfg_do_global_parameter(lp_ctx, "smb2 leases", "yes");
    3077             : 
    3078       12357 :         lpcfg_do_global_parameter(lp_ctx, "server multi channel support", "yes");
    3079             : 
    3080       12357 :         lpcfg_do_global_parameter(lp_ctx, "kerberos encryption types", "all");
    3081             : 
    3082       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3083             :                                   "rpc server dynamic port range",
    3084             :                                   "49152-65535");
    3085             : 
    3086       12357 :         lpcfg_do_global_parameter(lp_ctx, "prefork children", "4");
    3087       12357 :         lpcfg_do_global_parameter(lp_ctx, "prefork backoff increment", "10");
    3088       12357 :         lpcfg_do_global_parameter(lp_ctx, "prefork maximum backoff", "120");
    3089             : 
    3090       12357 :         lpcfg_do_global_parameter(lp_ctx, "check parent directory delete on close", "no");
    3091             : 
    3092       12357 :         lpcfg_do_global_parameter(lp_ctx, "ea support", "yes");
    3093             : 
    3094       12357 :         lpcfg_do_global_parameter(lp_ctx, "store dos attributes", "yes");
    3095             : 
    3096       12357 :         lpcfg_do_global_parameter(lp_ctx, "debug encryption", "no");
    3097             : 
    3098       12357 :         lpcfg_do_global_parameter(lp_ctx, "spotlight backend", "noindex");
    3099             : 
    3100       12357 :         lpcfg_do_global_parameter(
    3101             :                 lp_ctx, "ldap max anonymous request size", "256000");
    3102       12357 :         lpcfg_do_global_parameter(
    3103             :                 lp_ctx, "ldap max authenticated request size", "16777216");
    3104       12357 :         lpcfg_do_global_parameter(
    3105             :                 lp_ctx, "ldap max search request size", "256000");
    3106             : 
    3107             :         /* Async DNS query timeout in seconds. */
    3108       12357 :         lpcfg_do_global_parameter(lp_ctx, "async dns timeout", "10");
    3109             : 
    3110       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3111             :                                   "client smb encrypt",
    3112             :                                   "default");
    3113             : 
    3114       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3115             :                                   "client use kerberos",
    3116             :                                   "desired");
    3117             : 
    3118       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3119             :                                   "client protection",
    3120             :                                   "default");
    3121             : 
    3122       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3123             :                                   "smbd max xattr size",
    3124             :                                   "65536");
    3125             : 
    3126       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3127             :                                   "acl flag inherited canonicalization",
    3128             :                                   "yes");
    3129             : 
    3130       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3131             :                                   "winbind use krb5 enterprise principals",
    3132             :                                   "yes");
    3133             : 
    3134       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3135             :                                   "client smb3 signing algorithms",
    3136             :                                   DEFAULT_SMB3_SIGNING_ALGORITHMS);
    3137       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3138             :                                   "server smb3 signing algorithms",
    3139             :                                   DEFAULT_SMB3_SIGNING_ALGORITHMS);
    3140             : 
    3141       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3142             :                                   "client smb3 encryption algorithms",
    3143             :                                   DEFAULT_SMB3_ENCRYPTION_ALGORITHMS);
    3144       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3145             :                                   "server smb3 encryption algorithms",
    3146             :                                   DEFAULT_SMB3_ENCRYPTION_ALGORITHMS);
    3147             : 
    3148       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3149             :                                   "min domain uid",
    3150             :                                   "1000");
    3151             : 
    3152       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3153             :                                   "rpc start on demand helpers",
    3154             :                                   "yes");
    3155             : 
    3156       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3157             :                                   "ad dc functional level",
    3158             :                                   "2008_R2");
    3159             : 
    3160       12357 :         lpcfg_do_global_parameter(lp_ctx,
    3161             :                                   "acl claims evaluation",
    3162             :                                   "AD DC only");
    3163             : 
    3164     6426256 :         for (i = 0; parm_table[i].label; i++) {
    3165     6413283 :                 if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
    3166     6413283 :                         lp_ctx->flags[i] |= FLAG_DEFAULT;
    3167             :                 }
    3168             :         }
    3169             : 
    3170       49428 :         for (parm=lp_ctx->globals->param_opt; parm; parm=parm->next) {
    3171       37071 :                 if (!(parm->priority & FLAG_CMDLINE)) {
    3172       37071 :                         parm->priority |= FLAG_DEFAULT;
    3173             :                 }
    3174             :         }
    3175             : 
    3176       12357 :         for (parm=lp_ctx->sDefault->param_opt; parm; parm=parm->next) {
    3177           0 :                 if (!(parm->priority & FLAG_CMDLINE)) {
    3178           0 :                         parm->priority |= FLAG_DEFAULT;
    3179             :                 }
    3180             :         }
    3181             : 
    3182       11741 :         return lp_ctx;
    3183             : }
    3184             : 
    3185             : /**
    3186             :  * Initialise the global parameter structure.
    3187             :  */
    3188       80856 : struct loadparm_context *loadparm_init_global(bool load_default)
    3189             : {
    3190       80856 :         if (global_loadparm_context == NULL) {
    3191       12186 :                 global_loadparm_context = loadparm_init(NULL);
    3192             :         }
    3193       80856 :         if (global_loadparm_context == NULL) {
    3194           0 :                 return NULL;
    3195             :         }
    3196       80856 :         global_loadparm_context->global = true;
    3197       80856 :         if (load_default && !global_loadparm_context->loaded) {
    3198         170 :                 lpcfg_load_default(global_loadparm_context);
    3199             :         }
    3200       80856 :         global_loadparm_context->refuse_free = true;
    3201       80856 :         return global_loadparm_context;
    3202             : }
    3203             : 
    3204             : /**
    3205             :  * @brief Initialise the global parameter structure.
    3206             :  *
    3207             :  * This function initialized the globals if needed. Make sure that
    3208             :  * gfree_loadparm() is called before the application exits.
    3209             :  *
    3210             :  * @param mem_ctx   The talloc memory context to allocate lp_ctx on.
    3211             :  *
    3212             :  * @param s3_fns    The loadparm helper functions to use
    3213             :  *
    3214             :  * @return An initialized lp_ctx pointer or NULL on error.
    3215             :  */
    3216      823021 : struct loadparm_context *loadparm_init_s3(TALLOC_CTX *mem_ctx,
    3217             :                                           const struct loadparm_s3_helpers *s3_fns)
    3218             : {
    3219      823021 :         struct loadparm_context *loadparm_context = talloc_zero(mem_ctx, struct loadparm_context);
    3220      823021 :         if (!loadparm_context) {
    3221           0 :                 return NULL;
    3222             :         }
    3223      823021 :         loadparm_context->s3_fns = s3_fns;
    3224      823021 :         loadparm_context->globals = s3_fns->globals;
    3225      823021 :         loadparm_context->flags = s3_fns->flags;
    3226             : 
    3227             :         /* Make sure globals are correctly initialized */
    3228      823021 :         loadparm_context->s3_fns->init_globals(loadparm_context, false);
    3229             : 
    3230      823021 :         return loadparm_context;
    3231             : }
    3232             : 
    3233      430275 : const char *lpcfg_configfile(struct loadparm_context *lp_ctx)
    3234             : {
    3235      430275 :         return lp_ctx->szConfigFile;
    3236             : }
    3237             : 
    3238      101472 : const char *lp_default_path(void)
    3239             : {
    3240      101472 :     if (getenv("SMB_CONF_PATH"))
    3241       85635 :         return getenv("SMB_CONF_PATH");
    3242             :     else
    3243       15837 :         return dyn_CONFIGFILE;
    3244             : }
    3245             : 
    3246             : /**
    3247             :  * Update the internal state of a loadparm context after settings
    3248             :  * have changed.
    3249             :  */
    3250       29622 : static bool lpcfg_update(struct loadparm_context *lp_ctx)
    3251             : {
    3252         681 :         struct debug_settings settings;
    3253         681 :         int max_protocol, min_protocol;
    3254         681 :         TALLOC_CTX *tmp_ctx;
    3255         681 :         const struct loadparm_substitution *lp_sub =
    3256       29622 :                 lpcfg_noop_substitution();
    3257             : 
    3258       29622 :         tmp_ctx = talloc_new(lp_ctx);
    3259       29622 :         if (tmp_ctx == NULL) {
    3260           0 :                 return false;
    3261             :         }
    3262             : 
    3263       29622 :         lpcfg_add_auto_services(lp_ctx, lpcfg_auto_services(lp_ctx, lp_sub, tmp_ctx));
    3264             : 
    3265       29622 :         if (!lp_ctx->globals->wins_server_list && lp_ctx->globals->we_are_a_wins_server) {
    3266        4496 :                 lpcfg_do_global_parameter(lp_ctx, "wins server", "127.0.0.1");
    3267             :         }
    3268             : 
    3269       29622 :         if (!lp_ctx->global) {
    3270         134 :                 TALLOC_FREE(tmp_ctx);
    3271         134 :                 return true;
    3272             :         }
    3273             : 
    3274       29488 :         panic_action = lp_ctx->globals->panic_action;
    3275             : 
    3276       29488 :         reload_charcnv(lp_ctx);
    3277             : 
    3278       29488 :         ZERO_STRUCT(settings);
    3279             :         /* Add any more debug-related smb.conf parameters created in
    3280             :          * future here */
    3281       29488 :         settings.timestamp_logs = lp_ctx->globals->timestamp_logs;
    3282       29488 :         settings.debug_prefix_timestamp = lp_ctx->globals->debug_prefix_timestamp;
    3283       29488 :         settings.debug_hires_timestamp = lp_ctx->globals->debug_hires_timestamp;
    3284       29488 :         settings.debug_syslog_format = lp_ctx->globals->debug_syslog_format;
    3285       29488 :         settings.debug_pid = lp_ctx->globals->debug_pid;
    3286       29488 :         settings.debug_uid = lp_ctx->globals->debug_uid;
    3287       29488 :         settings.debug_class = lp_ctx->globals->debug_class;
    3288       29488 :         settings.max_log_size = lp_ctx->globals->max_log_size;
    3289       29488 :         debug_set_settings(&settings, lp_ctx->globals->logging,
    3290       28815 :                            lp_ctx->globals->syslog,
    3291       29488 :                            lp_ctx->globals->syslog_only);
    3292             : 
    3293             :         /* FIXME: This is a bit of a hack, but we can't use a global, since
    3294             :          * not everything that uses lp also uses the socket library */
    3295       29488 :         if (lpcfg_parm_bool(lp_ctx, NULL, "socket", "testnonblock", false)) {
    3296         176 :                 setenv("SOCKET_TESTNONBLOCK", "1", 1);
    3297             :         } else {
    3298       29312 :                 unsetenv("SOCKET_TESTNONBLOCK");
    3299             :         }
    3300             : 
    3301             :         /* Check if command line max protocol < min protocol, if so
    3302             :          * report a warning to the user.
    3303             :          */
    3304       29488 :         max_protocol = lpcfg_client_max_protocol(lp_ctx);
    3305       29488 :         min_protocol = lpcfg_client_min_protocol(lp_ctx);
    3306       29488 :         if (lpcfg_client_max_protocol(lp_ctx) < lpcfg_client_min_protocol(lp_ctx)) {
    3307           0 :                 const char *max_protocolp, *min_protocolp;
    3308           0 :                 max_protocolp = lpcfg_get_smb_protocol(max_protocol);
    3309           0 :                 min_protocolp = lpcfg_get_smb_protocol(min_protocol);
    3310           0 :                 DBG_ERR("Max protocol %s is less than min protocol %s.\n",
    3311             :                         max_protocolp, min_protocolp);
    3312             :         }
    3313             : 
    3314       29488 :         TALLOC_FREE(tmp_ctx);
    3315       29488 :         return true;
    3316             : }
    3317             : 
    3318         277 : bool lpcfg_load_default(struct loadparm_context *lp_ctx)
    3319             : {
    3320          11 :     const char *path;
    3321             : 
    3322         277 :     path = lp_default_path();
    3323             : 
    3324         277 :     if (!file_exist(path)) {
    3325             :             /* We allow the default smb.conf file to not exist,
    3326             :              * basically the equivalent of an empty file. */
    3327           2 :             return lpcfg_update(lp_ctx);
    3328             :     }
    3329             : 
    3330         275 :     return lpcfg_load(lp_ctx, path);
    3331             : }
    3332             : 
    3333             : /**
    3334             :  * Load the services array from the services file.
    3335             :  *
    3336             :  * Return True on success, False on failure.
    3337             :  */
    3338       32017 : static bool lpcfg_load_internal(struct loadparm_context *lp_ctx,
    3339             :                                 const char *filename, bool set_global)
    3340             : {
    3341         739 :         char *n2;
    3342         739 :         bool bRetval;
    3343             : 
    3344       32017 :         if (lp_ctx->szConfigFile != NULL) {
    3345       18529 :                 talloc_free(discard_const_p(char, lp_ctx->szConfigFile));
    3346       18529 :                 lp_ctx->szConfigFile = NULL;
    3347             :         }
    3348             : 
    3349       32017 :         lp_ctx->szConfigFile = talloc_strdup(lp_ctx, filename);
    3350             : 
    3351       32017 :         if (lp_ctx->s3_fns) {
    3352        2270 :                 return lp_ctx->s3_fns->load(filename);
    3353             :         }
    3354             : 
    3355       29747 :         lp_ctx->bInGlobalSection = true;
    3356       29747 :         n2 = standard_sub_basic(lp_ctx, lp_ctx->szConfigFile);
    3357       29747 :         DEBUG(2, ("lpcfg_load: refreshing parameters from %s\n", n2));
    3358             : 
    3359       29747 :         add_to_file_list(lp_ctx, &lp_ctx->file_lists, lp_ctx->szConfigFile, n2);
    3360             : 
    3361             :         /* We get sections first, so have to start 'behind' to make up */
    3362       29747 :         lp_ctx->currentService = NULL;
    3363       29747 :         bRetval = pm_process(n2, do_section, lpcfg_do_parameter, lp_ctx);
    3364             : 
    3365             :         /* finish up the last section */
    3366       29747 :         DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
    3367       29747 :         if (bRetval)
    3368       29620 :                 if (lp_ctx->currentService != NULL)
    3369       18340 :                         bRetval = lpcfg_service_ok(lp_ctx->currentService);
    3370             : 
    3371       29747 :         bRetval = bRetval && lpcfg_update(lp_ctx);
    3372             : 
    3373             :         /* we do this unconditionally, so that it happens even
    3374             :            for a missing smb.conf */
    3375       29747 :         reload_charcnv(lp_ctx);
    3376             : 
    3377       29747 :         if (bRetval == true && set_global) {
    3378             :                 /* set this up so that any child python tasks will
    3379             :                    find the right smb.conf */
    3380       29514 :                 setenv("SMB_CONF_PATH", filename, 1);
    3381             : 
    3382             :                 /* set the context used by the lp_*() function
    3383             :                    variants */
    3384       29514 :                 global_loadparm_context = lp_ctx;
    3385       29514 :                 lp_ctx->loaded = true;
    3386             :         }
    3387             : 
    3388       29059 :         return bRetval;
    3389             : }
    3390             : 
    3391         108 : bool lpcfg_load_no_global(struct loadparm_context *lp_ctx, const char *filename)
    3392             : {
    3393         108 :     return lpcfg_load_internal(lp_ctx, filename, false);
    3394             : }
    3395             : 
    3396       31909 : bool lpcfg_load(struct loadparm_context *lp_ctx, const char *filename)
    3397             : {
    3398       31909 :     return lpcfg_load_internal(lp_ctx, filename, true);
    3399             : }
    3400             : 
    3401             : /**
    3402             :  * Return the max number of services.
    3403             :  */
    3404             : 
    3405        5351 : int lpcfg_numservices(struct loadparm_context *lp_ctx)
    3406             : {
    3407        5351 :         if (lp_ctx->s3_fns) {
    3408           6 :                 return lp_ctx->s3_fns->get_numservices();
    3409             :         }
    3410             : 
    3411        5345 :         return lp_ctx->iNumServices;
    3412             : }
    3413             : 
    3414             : /**
    3415             :  * Display the contents of the services array in human-readable form.
    3416             :  */
    3417             : 
    3418         769 : void lpcfg_dump(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults,
    3419             :              int maxtoprint)
    3420             : {
    3421          25 :         int iService;
    3422             : 
    3423         769 :         if (lp_ctx->s3_fns) {
    3424           0 :                 lp_ctx->s3_fns->dump(f, show_defaults, maxtoprint);
    3425           0 :                 return;
    3426             :         }
    3427             : 
    3428         769 :         lpcfg_dump_globals(lp_ctx, f, show_defaults);
    3429             : 
    3430         769 :         lpcfg_dump_a_service(lp_ctx->sDefault, lp_ctx->sDefault, f, lp_ctx->flags, show_defaults);
    3431             : 
    3432        3873 :         for (iService = 0; iService < maxtoprint; iService++)
    3433        3079 :                 lpcfg_dump_one(f, show_defaults, lp_ctx->services[iService], lp_ctx->sDefault);
    3434             : }
    3435             : 
    3436             : /**
    3437             :  * Display the contents of one service in human-readable form.
    3438             :  */
    3439        3080 : void lpcfg_dump_one(FILE *f, bool show_defaults, struct loadparm_service *service, struct loadparm_service *sDefault)
    3440             : {
    3441        3080 :         if (service != NULL) {
    3442        3080 :                 if (service->szService[0] == '\0')
    3443           0 :                         return;
    3444        3080 :                 lpcfg_dump_a_service(service, sDefault, f, NULL, show_defaults);
    3445             :         }
    3446             : }
    3447             : 
    3448        5206 : struct loadparm_service *lpcfg_servicebynum(struct loadparm_context *lp_ctx,
    3449             :                                             int snum)
    3450             : {
    3451        5206 :         if (lp_ctx->s3_fns) {
    3452           0 :                 return lp_ctx->s3_fns->get_servicebynum(snum);
    3453             :         }
    3454             : 
    3455        5206 :         return lp_ctx->services[snum];
    3456             : }
    3457             : 
    3458        8904 : struct loadparm_service *lpcfg_service(struct loadparm_context *lp_ctx,
    3459             :                                     const char *service_name)
    3460             : {
    3461         260 :         int iService;
    3462         260 :         char *serviceName;
    3463             : 
    3464        8904 :         if (lp_ctx->s3_fns) {
    3465           3 :                 return lp_ctx->s3_fns->get_service(service_name);
    3466             :         }
    3467             : 
    3468       71572 :         for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--) {
    3469       71473 :                 if (lp_ctx->services[iService] &&
    3470       71473 :                     lp_ctx->services[iService]->szService) {
    3471             :                         /*
    3472             :                          * The substitution here is used to support %U is
    3473             :                          * service names
    3474             :                          */
    3475       71473 :                         serviceName = standard_sub_basic(
    3476       69067 :                                         lp_ctx->services[iService],
    3477       69067 :                                         lp_ctx->services[iService]->szService);
    3478       71473 :                         if (strequal(serviceName, service_name)) {
    3479        8802 :                                 talloc_free(serviceName);
    3480        8802 :                                 return lp_ctx->services[iService];
    3481             :                         }
    3482       62671 :                         talloc_free(serviceName);
    3483             :                 }
    3484             :         }
    3485             : 
    3486          99 :         DEBUG(7,("lpcfg_servicenumber: couldn't find %s\n", service_name));
    3487          89 :         return NULL;
    3488             : }
    3489             : 
    3490        8701 : const char *lpcfg_servicename(const struct loadparm_service *service)
    3491             : {
    3492        8701 :         return service ? lpcfg_string((const char *)service->szService) : NULL;
    3493             : }
    3494             : 
    3495     2095240 : struct smb_iconv_handle *lpcfg_iconv_handle(struct loadparm_context *lp_ctx)
    3496             : {
    3497     2095240 :         if (lp_ctx == NULL) {
    3498           0 :                 return get_iconv_handle();
    3499             :         }
    3500     2095240 :         return lp_ctx->iconv_handle;
    3501             : }
    3502             : 
    3503       77110 : _PUBLIC_ void reload_charcnv(struct loadparm_context *lp_ctx)
    3504             : {
    3505       77110 :         if (!lp_ctx->global) {
    3506         126 :                 return;
    3507             :         }
    3508             : 
    3509       78454 :         lp_ctx->iconv_handle =
    3510       76974 :                 reinit_iconv_handle(lp_ctx,
    3511             :                                     lpcfg_dos_charset(lp_ctx),
    3512             :                                     lpcfg_unix_charset(lp_ctx));
    3513       76974 :         if (lp_ctx->iconv_handle == NULL) {
    3514           0 :                 smb_panic("reinit_iconv_handle failed");
    3515             :         }
    3516             : }
    3517             : 
    3518          62 : _PUBLIC_ char *lpcfg_tls_keyfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3519             : {
    3520          62 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_keyfile(lp_ctx));
    3521             : }
    3522             : 
    3523          62 : _PUBLIC_ char *lpcfg_tls_certfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3524             : {
    3525          62 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_certfile(lp_ctx));
    3526             : }
    3527             : 
    3528         539 : _PUBLIC_ char *lpcfg_tls_cafile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3529             : {
    3530         539 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_cafile(lp_ctx));
    3531             : }
    3532             : 
    3533         539 : _PUBLIC_ char *lpcfg_tls_crlfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3534             : {
    3535         539 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_crlfile(lp_ctx));
    3536             : }
    3537             : 
    3538          62 : _PUBLIC_ char *lpcfg_tls_dhpfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3539             : {
    3540          62 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_dhpfile(lp_ctx));
    3541             : }
    3542             : 
    3543      294687 : struct gensec_settings *lpcfg_gensec_settings(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3544             : {
    3545      294687 :         struct gensec_settings *settings = talloc_zero(mem_ctx, struct gensec_settings);
    3546      294687 :         if (settings == NULL)
    3547           0 :                 return NULL;
    3548      294687 :         SMB_ASSERT(lp_ctx != NULL);
    3549      294687 :         settings->lp_ctx = talloc_reference(settings, lp_ctx);
    3550      294687 :         settings->target_hostname = lpcfg_parm_string(lp_ctx, NULL, "gensec", "target_hostname");
    3551      294687 :         return settings;
    3552             : }
    3553             : 
    3554      686825 : int lpcfg_server_role(struct loadparm_context *lp_ctx)
    3555             : {
    3556      686825 :         int domain_master = lpcfg__domain_master(lp_ctx);
    3557             : 
    3558     1353514 :         return lp_find_server_role(lpcfg__server_role(lp_ctx),
    3559             :                                    lpcfg__security(lp_ctx),
    3560      686825 :                                    lpcfg__domain_logons(lp_ctx),
    3561       20136 :                                    (domain_master == true) ||
    3562             :                                    (domain_master == Auto));
    3563             : }
    3564             : 
    3565       68518 : int lpcfg_security(struct loadparm_context *lp_ctx)
    3566             : {
    3567       68518 :         return lp_find_security(lpcfg__server_role(lp_ctx),
    3568             :                                 lpcfg__security(lp_ctx));
    3569             : }
    3570             : 
    3571       58976 : int lpcfg_client_max_protocol(struct loadparm_context *lp_ctx)
    3572             : {
    3573       58976 :         int client_max_protocol = lpcfg__client_max_protocol(lp_ctx);
    3574       58976 :         if (client_max_protocol == PROTOCOL_DEFAULT) {
    3575       58956 :                 return PROTOCOL_LATEST;
    3576             :         }
    3577          20 :         return client_max_protocol;
    3578             : }
    3579             : 
    3580        6677 : int lpcfg_client_ipc_min_protocol(struct loadparm_context *lp_ctx)
    3581             : {
    3582        6677 :         int client_ipc_min_protocol = lpcfg__client_ipc_min_protocol(lp_ctx);
    3583        6677 :         if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
    3584        6669 :                 client_ipc_min_protocol = lpcfg_client_min_protocol(lp_ctx);
    3585             :         }
    3586        6677 :         if (client_ipc_min_protocol < PROTOCOL_NT1) {
    3587        5942 :                 return PROTOCOL_NT1;
    3588             :         }
    3589         345 :         return client_ipc_min_protocol;
    3590             : }
    3591             : 
    3592        6677 : int lpcfg_client_ipc_max_protocol(struct loadparm_context *lp_ctx)
    3593             : {
    3594        6677 :         int client_ipc_max_protocol = lpcfg__client_ipc_max_protocol(lp_ctx);
    3595        6677 :         if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
    3596        6275 :                 return PROTOCOL_LATEST;
    3597             :         }
    3598          12 :         if (client_ipc_max_protocol < PROTOCOL_NT1) {
    3599           0 :                 return PROTOCOL_NT1;
    3600             :         }
    3601          12 :         return client_ipc_max_protocol;
    3602             : }
    3603             : 
    3604      283337 : int lpcfg_client_ipc_signing(struct loadparm_context *lp_ctx)
    3605             : {
    3606      283337 :         int client_ipc_signing = lpcfg__client_ipc_signing(lp_ctx);
    3607      283337 :         if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
    3608      283337 :                 return SMB_SIGNING_REQUIRED;
    3609             :         }
    3610           0 :         return client_ipc_signing;
    3611             : }
    3612             : 
    3613      213861 : enum credentials_use_kerberos lpcfg_client_use_kerberos(struct loadparm_context *lp_ctx)
    3614             : {
    3615      213861 :         if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
    3616           6 :                 return CRED_USE_KERBEROS_REQUIRED;
    3617             :         }
    3618             : 
    3619      213855 :         return lpcfg__client_use_kerberos(lp_ctx);
    3620             : }
    3621             : 
    3622       67503 : bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandatory)
    3623             : {
    3624       67503 :         bool allowed = true;
    3625       67503 :         enum smb_signing_setting signing_setting = lpcfg_server_signing(lp_ctx);
    3626             : 
    3627       67503 :         *mandatory = false;
    3628             : 
    3629       67503 :         if (signing_setting == SMB_SIGNING_DEFAULT) {
    3630             :                 /*
    3631             :                  * If we are a domain controller, SMB signing is
    3632             :                  * really important, as it can prevent a number of
    3633             :                  * attacks on communications between us and the
    3634             :                  * clients
    3635             :                  *
    3636             :                  * However, it really sucks (no sendfile, CPU
    3637             :                  * overhead) performance-wise when used on a
    3638             :                  * file server, so disable it by default
    3639             :                  * on non-DCs
    3640             :                  */
    3641             : 
    3642       66439 :                 if (lpcfg_server_role(lp_ctx) >= ROLE_ACTIVE_DIRECTORY_DC) {
    3643       20603 :                         signing_setting = SMB_SIGNING_REQUIRED;
    3644             :                 } else {
    3645       44048 :                         signing_setting = SMB_SIGNING_OFF;
    3646             :                 }
    3647             :         }
    3648             : 
    3649       65715 :         switch (signing_setting) {
    3650       23321 :         case SMB_SIGNING_REQUIRED:
    3651       23321 :                 *mandatory = true;
    3652       23321 :                 break;
    3653         134 :         case SMB_SIGNING_DESIRED:
    3654             :         case SMB_SIGNING_IF_REQUIRED:
    3655         134 :                 break;
    3656       44048 :         case SMB_SIGNING_OFF:
    3657       44048 :                 allowed = false;
    3658       44048 :                 break;
    3659           0 :         case SMB_SIGNING_DEFAULT:
    3660             :         case SMB_SIGNING_IPC_DEFAULT:
    3661           0 :                 smb_panic(__location__);
    3662        1788 :                 break;
    3663             :         }
    3664             : 
    3665       67503 :         return allowed;
    3666             : }
    3667             : 
    3668      330141 : int lpcfg_tdb_hash_size(struct loadparm_context *lp_ctx, const char *name)
    3669             : {
    3670       11753 :         const char *base;
    3671             : 
    3672      330141 :         if (name == NULL) {
    3673           0 :                 return 0;
    3674             :         }
    3675             : 
    3676      330141 :         base = strrchr_m(name, '/');
    3677      330141 :         if (base != NULL) {
    3678      330135 :                 base += 1;
    3679             :         } else {
    3680           0 :                 base = name;
    3681             :         }
    3682      330141 :         return lpcfg_parm_int(lp_ctx, NULL, "tdb_hashsize", base, 0);
    3683             : 
    3684             : }
    3685             : 
    3686     1110985 : int lpcfg_tdb_flags(struct loadparm_context *lp_ctx, int tdb_flags)
    3687             : {
    3688     1110985 :         if (!lpcfg_use_mmap(lp_ctx)) {
    3689           0 :                 tdb_flags |= TDB_NOMMAP;
    3690             :         }
    3691     1110985 :         return tdb_flags;
    3692             : }
    3693             : 
    3694             : /*
    3695             :  * Do not allow LanMan auth if unless NTLMv1 is also allowed
    3696             :  *
    3697             :  * This also ensures it is disabled if NTLM is totally disabled
    3698             :  */
    3699       68816 : bool lpcfg_lanman_auth(struct loadparm_context *lp_ctx)
    3700             : {
    3701       68816 :         enum ntlm_auth_level ntlm_auth_level = lpcfg_ntlm_auth(lp_ctx);
    3702             : 
    3703       68816 :         if (ntlm_auth_level == NTLM_AUTH_ON) {
    3704       35723 :                 return lpcfg__lanman_auth(lp_ctx);
    3705             :         } else {
    3706       33093 :                 return false;
    3707             :         }
    3708             : }
    3709             : 
    3710       47565 : static char *lpcfg_noop_substitution_fn(
    3711             :                         TALLOC_CTX *mem_ctx,
    3712             :                         const struct loadparm_substitution *lp_sub,
    3713             :                         const char *raw_value,
    3714             :                         void *private_data)
    3715             : {
    3716       47565 :         return talloc_strdup(mem_ctx, raw_value);
    3717             : }
    3718             : 
    3719             : static const struct loadparm_substitution global_noop_substitution = {
    3720             :         .substituted_string_fn = lpcfg_noop_substitution_fn,
    3721             : };
    3722             : 
    3723       47841 : const struct loadparm_substitution *lpcfg_noop_substitution(void)
    3724             : {
    3725       47841 :         return &global_noop_substitution;
    3726             : }
    3727             : 
    3728     2538672 : char *lpcfg_substituted_string(TALLOC_CTX *mem_ctx,
    3729             :                                const struct loadparm_substitution *lp_sub,
    3730             :                                const char *raw_value)
    3731             : {
    3732     5077344 :         return lp_sub->substituted_string_fn(mem_ctx,
    3733             :                                              lp_sub,
    3734             :                                              raw_value,
    3735     2538672 :                                              lp_sub->private_data);
    3736             : }
    3737             : 
    3738             : /**
    3739             :  * @brief Parse a string value of a given parameter to its integer enum value.
    3740             :  *
    3741             :  * @param[in]  param_name    The parameter name (e.g. 'client smb encrypt')
    3742             :  *
    3743             :  * @param[in]  param_value   The parameter value (e.g. 'required').
    3744             :  *
    3745             :  * @return The integer value of the enum the param_value matches or INT32_MIN
    3746             :  * on error.
    3747             :  */
    3748         214 : int32_t lpcfg_parse_enum_vals(const char *param_name,
    3749             :                               const char *param_value)
    3750             : {
    3751         214 :         struct parm_struct *parm = NULL;
    3752         214 :         int32_t ret = INT32_MIN;
    3753           8 :         bool ok;
    3754             : 
    3755         214 :         parm = lpcfg_parm_struct(NULL, param_name);
    3756         214 :         if (parm == NULL) {
    3757           0 :                 return INT32_MIN;
    3758             :         }
    3759             : 
    3760         214 :         ok = lp_set_enum_parm(parm, param_value, &ret);
    3761         214 :         if (!ok) {
    3762           0 :                 return INT32_MIN;
    3763             :         }
    3764             : 
    3765         212 :         return ret;
    3766             : }

Generated by: LCOV version 1.14