LCOV - code coverage report
Current view: top level - lib/param - loadparm.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 1443 1721 83.8 %
Date: 2024-02-28 12:06:22 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      290234 : struct loadparm_service *lpcfg_default_service(struct loadparm_context *lp_ctx)
      90             : {
      91      290234 :         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     1004874 : enum samba_weak_crypto lpcfg_weak_crypto(struct loadparm_context *lp_ctx)
     105             : {
     106     1004874 :         if (lp_ctx->globals->weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) {
     107       58636 :                 lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED;
     108             : 
     109       58636 :                 if (samba_gnutls_weak_crypto_allowed()) {
     110       58634 :                         lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED;
     111             :                 }
     112             :         }
     113             : 
     114     1004874 :         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    12290131 : 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    12290131 :         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     5722560 : 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    17657080 : struct parmlist_entry *get_parametric_helper(struct loadparm_service *service,
     277             :                                              const char *type, const char *option,
     278             :                                              struct parmlist_entry *global_opts)
     279    17657080 : {
     280    17657080 :         size_t type_len = strlen(type);
     281    17657080 :         size_t option_len = strlen(option);
     282    17657080 :         char param_key[type_len + option_len + 2];
     283    17657080 :         struct parmlist_entry *data = NULL;
     284             : 
     285    17657080 :         snprintf(param_key, sizeof(param_key), "%s:%s", type, option);
     286             : 
     287             :         /*
     288             :          * Try to fetch the option from the data.
     289             :          */
     290    17657080 :         if (service != NULL) {
     291     2281182 :                 data = service->param_opt;
     292     4176380 :                 while (data != NULL) {
     293     2134462 :                         if (strwicmp(data->key, param_key) == 0) {
     294      239264 :                                 return data;
     295             :                         }
     296     1895198 :                         data = data->next;
     297             :                 }
     298             :         }
     299             : 
     300             :         /*
     301             :          * Fall back to fetching from the globals.
     302             :          */
     303    13090912 :         data = global_opts;
     304   536566181 :         while (data != NULL) {
     305   521134877 :                 if (strwicmp(data->key, param_key) == 0) {
     306     1986512 :                         return data;
     307             :                 }
     308   519148365 :                 data = data->next;
     309             :         }
     310             : 
     311    11127359 :         return NULL;
     312             : }
     313             : 
     314    14470649 : const char *lpcfg_get_parametric(struct loadparm_context *lp_ctx,
     315             :                               struct loadparm_service *service,
     316             :                               const char *type, const char *option)
     317             : {
     318     4315983 :         struct parmlist_entry *data;
     319             : 
     320    14470649 :         if (lp_ctx == NULL)
     321           0 :                 return NULL;
     322             : 
     323    18786632 :         data = get_parametric_helper(service,
     324    14470649 :                                      type, option, lp_ctx->globals->param_opt);
     325             : 
     326    14470649 :         if (data == NULL) {
     327     8856884 :                 return NULL;
     328             :         } else {
     329     1318762 :                 return data->value;
     330             :         }
     331             : }
     332             : 
     333             : 
     334             : /**
     335             :  * convenience routine to return int parameters.
     336             :  */
     337      862653 : int lp_int(const char *s)
     338             : {
     339             : 
     340      862653 :         if (!s || !*s) {
     341           0 :                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
     342           0 :                 return -1;
     343             :         }
     344             : 
     345      862653 :         return strtol(s, NULL, 0);
     346             : }
     347             : 
     348             : /**
     349             :  * convenience routine to return unsigned long parameters.
     350             :  */
     351        3983 : unsigned long lp_ulong(const char *s)
     352             : {
     353        3983 :         int error = 0;
     354           0 :         unsigned long int ret;
     355             : 
     356        3983 :         if (!s || !*s) {
     357           0 :                 DBG_DEBUG("lp_ulong(%s): is called with NULL!\n",s);
     358           0 :                 return -1;
     359             :         }
     360             : 
     361        3983 :         ret = smb_strtoul(s, NULL, 0, &error, SMB_STR_STANDARD);
     362        3983 :         if (error != 0) {
     363           0 :                 DBG_DEBUG("lp_ulong(%s): conversion failed\n",s);
     364           0 :                 return -1;
     365             :         }
     366             : 
     367        3983 :         return ret;
     368             : }
     369             : 
     370             : /**
     371             :  * convenience routine to return unsigned long long parameters.
     372             :  */
     373         611 : unsigned long long lp_ulonglong(const char *s)
     374             : {
     375         611 :         int error = 0;
     376           0 :         unsigned long long int ret;
     377             : 
     378         611 :         if (!s || !*s) {
     379           0 :                 DBG_DEBUG("lp_ulonglong(%s): is called with NULL!\n", s);
     380           0 :                 return -1;
     381             :         }
     382             : 
     383         611 :         ret = smb_strtoull(s, NULL, 0, &error, SMB_STR_STANDARD);
     384         611 :         if (error != 0) {
     385           0 :                 DBG_DEBUG("lp_ulonglong(%s): conversion failed\n",s);
     386           0 :                 return -1;
     387             :         }
     388             : 
     389         611 :         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     1191773 : bool lp_bool(const char *s)
     424             : {
     425     1191773 :         bool ret = false;
     426             : 
     427     1191773 :         if (!s || !*s) {
     428          28 :                 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
     429          28 :                 return false;
     430             :         }
     431             : 
     432     1191745 :         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     1191745 :         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     2135283 : const char *lpcfg_parm_string(struct loadparm_context *lp_ctx,
     447             :                               struct loadparm_service *service, const char *type,
     448             :                               const char *option)
     449             : {
     450     2135283 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     451             : 
     452     2135283 :         if (value)
     453      788674 :                 return lpcfg_string(value);
     454             : 
     455     1326138 :         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      780784 : 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      780784 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     490             : 
     491      780784 :         if (value)
     492       58615 :                 return lp_int(value);
     493             : 
     494      700242 :         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       66951 : 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       66951 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     530             : 
     531       66951 :         if (value)
     532        3942 :                 return lp_ulong(value);
     533             : 
     534       62129 :         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         757 : 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         757 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     561             : 
     562         757 :         if (value)
     563           0 :                 return lp_long(value);
     564             : 
     565         733 :         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    11440565 : 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    11440565 :         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
     590             : 
     591    11440565 :         if (value != NULL)
     592      425751 :                 return lp_bool(value);
     593             : 
     594     6763733 :         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   116906799 : void lpcfg_string_free(char **s)
     605             : {
     606   116906799 :         if (s == NULL) {
     607           0 :                 return;
     608             :         }
     609   116906799 :         if (*s == lpcfg_string_empty) {
     610    41801407 :                 *s = NULL;
     611    41801407 :                 return;
     612             :         }
     613    75105392 :         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    91184680 : bool lpcfg_string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
     621             : {
     622    91184680 :         lpcfg_string_free(dest);
     623             : 
     624    91184680 :         if ((src == NULL) || (*src == '\0')) {
     625    49834514 :                 *dest = discard_const_p(char, lpcfg_string_empty);
     626    49834514 :                 return true;
     627             :         }
     628             : 
     629    41350166 :         *dest = talloc_strdup(mem_ctx, src);
     630    41350166 :         if ((*dest) == NULL) {
     631           0 :                 DEBUG(0,("Out of memory in string_set\n"));
     632           0 :                 return false;
     633             :         }
     634             : 
     635    41230728 :         return true;
     636             : }
     637             : 
     638             : /**
     639             :  * Set a string value, deallocating any existing space, and allocing the space
     640             :  * for the string
     641             :  */
     642      193520 : bool lpcfg_string_set_upper(TALLOC_CTX *mem_ctx, char **dest, const char *src)
     643             : {
     644      193520 :         lpcfg_string_free(dest);
     645             : 
     646      193520 :         if ((src == NULL) || (*src == '\0')) {
     647           6 :                 *dest = discard_const_p(char, lpcfg_string_empty);
     648           6 :                 return true;
     649             :         }
     650             : 
     651      193514 :         *dest = strupper_talloc(mem_ctx, src);
     652      193514 :         if ((*dest) == NULL) {
     653           0 :                 DEBUG(0,("Out of memory in string_set_upper\n"));
     654           0 :                 return false;
     655             :         }
     656             : 
     657      191204 :         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      301389 : 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      301389 :         int num_to_alloc = lp_ctx->iNumServices + 1;
     673        2892 :         struct parmlist_entry *data, *pdata;
     674             : 
     675      301389 :         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      301389 :         if (pservice == NULL) {
     680          68 :                 pservice = lp_ctx->sDefault;
     681             :         }
     682             : 
     683             :         /* it might already exist */
     684      301389 :         if (name) {
     685      301389 :                 struct loadparm_service *service = lpcfg_getservicebyname(lp_ctx,
     686             :                                                                     name);
     687      301389 :                 if (service != NULL) {
     688             :                         /* Clean all parametric options for service */
     689             :                         /* They will be added during parsing again */
     690      211292 :                         data = service->param_opt;
     691      648850 :                         while (data) {
     692      437558 :                                 pdata = data->next;
     693      437558 :                                 talloc_free(data);
     694      437558 :                                 data = pdata;
     695             :                         }
     696      211292 :                         service->param_opt = NULL;
     697      211292 :                         return service;
     698             :                 }
     699             :         }
     700             : 
     701             :         /* find an invalid one */
     702     1689701 :         for (i = 0; i < lp_ctx->iNumServices; i++)
     703     1599604 :                 if (lp_ctx->services[i] == NULL)
     704           0 :                         break;
     705             : 
     706             :         /* if not, then create one */
     707       90097 :         if (i == lp_ctx->iNumServices) {
     708        1965 :                 struct loadparm_service **tsp;
     709             : 
     710       90097 :                 tsp = talloc_realloc(lp_ctx, lp_ctx->services, struct loadparm_service *, num_to_alloc);
     711             : 
     712       90097 :                 if (!tsp) {
     713           0 :                         DEBUG(0,("lpcfg_add_service: failed to enlarge services!\n"));
     714           0 :                         return NULL;
     715             :                 } else {
     716       90097 :                         lp_ctx->services = tsp;
     717       90097 :                         lp_ctx->services[lp_ctx->iNumServices] = NULL;
     718             :                 }
     719             : 
     720       90097 :                 lp_ctx->iNumServices++;
     721             :         }
     722             : 
     723       90097 :         lp_ctx->services[i] = talloc_zero(lp_ctx->services, struct loadparm_service);
     724       90097 :         if (lp_ctx->services[i] == NULL) {
     725           0 :                 DEBUG(0,("lpcfg_add_service: out of memory!\n"));
     726           0 :                 return NULL;
     727             :         }
     728       90097 :         copy_service(lp_ctx->services[i], pservice, NULL);
     729       90097 :         if (name != NULL)
     730       90097 :                 lpcfg_string_set(lp_ctx->services[i], &lp_ctx->services[i]->szService, name);
     731       90097 :         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    25788188 : int lpcfg_map_parameter(const char *pszParmName)
     740             : {
     741      211825 :         int iIndex;
     742             : 
     743  8487597888 :         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
     744  8481612858 :                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
     745    19803158 :                         return iIndex;
     746             : 
     747             :         /* Warn only if it isn't parametric option */
     748     5985030 :         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     5968978 :         return -1;
     754             : }
     755             : 
     756             : 
     757             : /**
     758             :   return the parameter structure for a parameter
     759             : */
     760       38483 : struct parm_struct *lpcfg_parm_struct(struct loadparm_context *lp_ctx, const char *name)
     761             : {
     762       38483 :         int num = lpcfg_map_parameter(name);
     763             : 
     764       38483 :         if (num < 0) {
     765           0 :                 return NULL;
     766             :         }
     767             : 
     768       38482 :         return &parm_table[num];
     769             : }
     770             : 
     771             : /**
     772             :   return the parameter pointer for a parameter
     773             : */
     774     7785807 : void *lpcfg_parm_ptr(struct loadparm_context *lp_ctx,
     775             :                   struct loadparm_service *service, struct parm_struct *parm)
     776             : {
     777     7785807 :         if (lp_ctx->s3_fns) {
     778     3389267 :                 return lp_ctx->s3_fns->get_parm_ptr(service, parm);
     779             :         }
     780             : 
     781     4396540 :         if (service == NULL) {
     782     4391252 :                 if (parm->p_class == P_LOCAL)
     783      600075 :                         return ((char *)lp_ctx->sDefault)+parm->offset;
     784     3791177 :                 else if (parm->p_class == P_GLOBAL)
     785     3791177 :                         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      756004 : bool lpcfg_parm_is_cmdline(struct loadparm_context *lp_ctx, const char *name)
     796             : {
     797       11121 :         int parmnum;
     798             : 
     799      756004 :         parmnum = lpcfg_map_parameter(name);
     800      756004 :         if (parmnum == -1) return false;
     801             : 
     802      756004 :         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     1429053 : static struct loadparm_service *lpcfg_getservicebyname(struct loadparm_context *lp_ctx,
     820             :                                         const char *pszServiceName)
     821             : {
     822        4368 :         int iService;
     823             : 
     824     1429053 :         if (lp_ctx->s3_fns) {
     825     1005954 :                 return lp_ctx->s3_fns->get_service(pszServiceName);
     826             :         }
     827             : 
     828     6898267 :         for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--)
     829    13616338 :                 if (lp_ctx->services[iService] != NULL &&
     830     6808169 :                     strwicmp(lp_ctx->services[iService]->szService, pszServiceName) == 0) {
     831      333001 :                         return lp_ctx->services[iService];
     832             :                 }
     833             : 
     834       88133 :         return NULL;
     835             : }
     836             : 
     837             : /**
     838             :  * Add a parametric option to a parmlist_entry,
     839             :  * replacing old value, if already present.
     840             :  */
     841     6331415 : 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       20105 :         struct parmlist_entry *new_opt, *opt;
     848             : 
     849     6331415 :         opt = *opt_list;
     850             : 
     851             :         /* Traverse destination */
     852    48611024 :         while (opt) {
     853             :                 /* If we already have same option, override it */
     854    42842345 :                 if (strwicmp(opt->key, opt_name) == 0) {
     855      562736 :                         if ((opt->priority & FLAG_CMDLINE) &&
     856        7724 :                             !(priority & FLAG_CMDLINE)) {
     857             :                                 /* it's been marked as not to be
     858             :                                    overridden */
     859         440 :                                 return;
     860             :                         }
     861      562274 :                         TALLOC_FREE(opt->list);
     862      562274 :                         lpcfg_string_set(opt, &opt->value, opt_value);
     863      562274 :                         opt->priority = priority;
     864      562274 :                         return;
     865             :                 }
     866    42279609 :                 opt = opt->next;
     867             :         }
     868             : 
     869     5768679 :         new_opt = talloc_pooled_object(
     870             :                 mem_ctx, struct parmlist_entry,
     871             :                 2, strlen(opt_name) + 1 + strlen(opt_value) + 1);
     872     5768679 :         if (new_opt == NULL) {
     873           0 :                 smb_panic("OOM");
     874             :         }
     875     5768679 :         new_opt->key = NULL;
     876     5768679 :         lpcfg_string_set(new_opt, &new_opt->key, opt_name);
     877     5768679 :         new_opt->value = NULL;
     878     5768679 :         lpcfg_string_set(new_opt, &new_opt->value, opt_value);
     879             : 
     880     5768679 :         new_opt->list = NULL;
     881     5768679 :         new_opt->priority = priority;
     882     5768679 :         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     1422211 : void copy_service(struct loadparm_service *pserviceDest,
     891             :                   const struct loadparm_service *pserviceSource,
     892             :                   struct bitmap *pcopymapDest)
     893             : {
     894        3509 :         int i;
     895     1422211 :         bool bcopyall = (pcopymapDest == NULL);
     896        3509 :         struct parmlist_entry *data;
     897             : 
     898   739549720 :         for (i = 0; parm_table[i].label; i++)
     899   738127509 :                 if (parm_table[i].p_class == P_LOCAL &&
     900   177042934 :                     (bcopyall || bitmap_query(pcopymapDest, i))) {
     901   220444084 :                         const void *src_ptr =
     902   220444084 :                                 ((const char *)pserviceSource) + parm_table[i].offset;
     903   220444084 :                         void *dest_ptr =
     904   219895247 :                                 ((char *)pserviceDest) + parm_table[i].offset;
     905             : 
     906   220444084 :                         switch (parm_table[i].type) {
     907   108932937 :                                 case P_BOOL:
     908             :                                 case P_BOOLREV:
     909   108932937 :                                         *(bool *)dest_ptr = *(const bool *)src_ptr;
     910   108932937 :                                         break;
     911             : 
     912    43925603 :                                 case P_INTEGER:
     913             :                                 case P_BYTES:
     914             :                                 case P_OCTAL:
     915             :                                 case P_ENUM:
     916    43925603 :                                         *(int *)dest_ptr = *(const int *)src_ptr;
     917    43925603 :                                         break;
     918             : 
     919     1422211 :                                 case P_CHAR:
     920     1422211 :                                         *(char *)dest_ptr = *(const char *)src_ptr;
     921     1422211 :                                         break;
     922             : 
     923    48284371 :                                 case P_STRING:
     924    48284371 :                                         lpcfg_string_set(pserviceDest,
     925             :                                                    (char **)dest_ptr,
     926             :                                                    *(const char * const *)src_ptr);
     927    48284371 :                                         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    17878962 :                                 case P_CMDLIST:
     935             :                                 case P_LIST:
     936    17878962 :                                         TALLOC_FREE(*((char ***)dest_ptr));
     937    17878962 :                                         *(char ***)dest_ptr = str_list_copy(pserviceDest,
     938             :                                                                             *discard_const_p(const char **, src_ptr));
     939    17878962 :                                         break;
     940           0 :                                 default:
     941           0 :                                         break;
     942             :                         }
     943             :                 }
     944             : 
     945     1422211 :         if (bcopyall) {
     946      294549 :                 init_copymap(pserviceDest);
     947      294549 :                 if (pserviceSource->copymap)
     948       15117 :                         bitmap_copy(pserviceDest->copymap,
     949       15117 :                                     pserviceSource->copymap);
     950             :         }
     951             : 
     952     1771384 :         for (data = pserviceSource->param_opt; data != NULL; data = data->next) {
     953      349173 :                 set_param_opt(pserviceDest, &pserviceDest->param_opt,
     954      349173 :                               data->key, data->value, data->priority);
     955             :         }
     956     1422211 : }
     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     3793906 : bool lpcfg_service_ok(struct loadparm_service *service)
     963             : {
     964        3035 :         bool bRetval;
     965             : 
     966     3793906 :         bRetval = true;
     967     3793906 :         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     3793906 :         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     3809114 :         if (service->path[0] == '\0' &&
     987       15208 :             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     3793906 :         if (!service->available)
     996           2 :                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
     997             :                           service->szService));
     998             : 
     999     3793906 :         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      286404 : void add_to_file_list(TALLOC_CTX *mem_ctx, struct file_lists **list,
    1009             :                              const char *fname, const char *subfname)
    1010             : {
    1011      286404 :         struct file_lists *f = *list;
    1012             : 
    1013      707985 :         while (f) {
    1014      495569 :                 if (f->name && !strcmp(f->name, fname))
    1015       73871 :                         break;
    1016      421581 :                 f = f->next;
    1017             :         }
    1018             : 
    1019      286404 :         if (!f) {
    1020      212416 :                 f = talloc_zero(mem_ctx, struct file_lists);
    1021      212416 :                 if (!f)
    1022           0 :                         goto fail;
    1023      212416 :                 f->next = *list;
    1024      212416 :                 f->name = talloc_strdup(f, fname);
    1025      212416 :                 if (!f->name) {
    1026           0 :                         TALLOC_FREE(f);
    1027           0 :                         goto fail;
    1028             :                 }
    1029      212416 :                 f->subfname = talloc_strdup(f, subfname);
    1030      212416 :                 if (!f->subfname) {
    1031           0 :                         TALLOC_FREE(f);
    1032           0 :                         goto fail;
    1033             :                 }
    1034      212416 :                 *list = f;
    1035             :         }
    1036             : 
    1037             :         /* If file_modtime() fails it leaves f->modtime as zero. */
    1038      286404 :         (void)file_modtime(subfname, &f->modtime);
    1039      286404 :         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     2034890 : bool lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
    1050             :                               int *ptr )
    1051             : {
    1052       41045 :         int i;
    1053             : 
    1054     8601019 :         for (i = 0; parm->enum_list[i].name; i++) {
    1055     8601015 :                 if (strwicmp(pszParmValue, parm->enum_list[i].name) == 0) {
    1056     2034886 :                         *ptr = parm->enum_list[i].value;
    1057     2034886 :                         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       34818 : 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       34818 :         upper = strupper_talloc(lp_ctx, pszParmValue);
    1077       34818 :         if (upper == NULL) {
    1078           0 :                 return false;
    1079             :         }
    1080             : 
    1081       34818 :         lower = strlower_talloc(lp_ctx, pszParmValue);
    1082       34818 :         if (lower == NULL) {
    1083           0 :                 TALLOC_FREE(upper);
    1084           0 :                 return false;
    1085             :         }
    1086             : 
    1087       34818 :         lpcfg_string_set(lp_ctx->globals->ctx, &lp_ctx->globals->realm, upper);
    1088       34818 :         lpcfg_string_set(lp_ctx->globals->ctx, &lp_ctx->globals->dnsdomain, lower);
    1089             : 
    1090       34818 :         return true;
    1091             : }
    1092             : 
    1093             : /***************************************************************************
    1094             :  Handle the include operation.
    1095             : ***************************************************************************/
    1096             : 
    1097      199289 : 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      199289 :         if (lp_ctx->s3_fns) {
    1105      197588 :                 return lp_ctx->s3_fns->lp_include(lp_ctx, service, pszParmValue, ptr);
    1106             :         }
    1107             : 
    1108        1701 :         fname = standard_sub_basic(lp_ctx, pszParmValue);
    1109             : 
    1110        1701 :         add_to_file_list(lp_ctx, &lp_ctx->file_lists, pszParmValue, fname);
    1111             : 
    1112        1701 :         lpcfg_string_set(lp_ctx, ptr, fname);
    1113             : 
    1114        1701 :         if (file_exist(fname))
    1115        1456 :                 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         245 :         substitution_variable_substring = strchr(fname, '%');
    1122             : 
    1123         245 :         if (substitution_variable_substring != NULL) {
    1124         240 :                 next_char = substitution_variable_substring[1];
    1125         240 :                 if ((next_char >= 'a' && next_char <= 'z')
    1126         240 :                     || (next_char >= 'A' && next_char <= 'Z')) {
    1127         240 :                         DEBUG(2, ("Tried to load %s but variable substitution in "
    1128             :                                  "filename, ignoring file.\n", fname));
    1129         240 :                         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     1127664 : bool handle_copy(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1143             :                         const char *pszParmValue, char **ptr)
    1144             : {
    1145        1476 :         bool bRetval;
    1146     1127664 :         struct loadparm_service *serviceTemp = NULL;
    1147             : 
    1148     1127664 :         bRetval = false;
    1149             : 
    1150     1127664 :         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
    1151             : 
    1152     1127664 :         serviceTemp = lpcfg_getservicebyname(lp_ctx, pszParmValue);
    1153             : 
    1154     1127664 :         if (service == NULL) {
    1155           2 :                 DEBUG(0, ("Unable to copy service - invalid service destination.\n"));
    1156           2 :                 return false;
    1157             :         }
    1158             : 
    1159     1127662 :         if (serviceTemp != NULL) {
    1160     1127662 :                 if (serviceTemp == service) {
    1161           0 :                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
    1162             :                 } else {
    1163     1127662 :                         copy_service(service,
    1164             :                                      serviceTemp,
    1165             :                                      service->copymap);
    1166     1127662 :                         lpcfg_string_set(service, ptr, pszParmValue);
    1167             : 
    1168     1127662 :                         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     1126186 :         return bRetval;
    1177             : }
    1178             : 
    1179      121318 : bool handle_debug_list(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1180             :                         const char *pszParmValue, char **ptr)
    1181             : {
    1182      121318 :         lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1183             : 
    1184      121318 :         return debug_parse_levels(pszParmValue);
    1185             : }
    1186             : 
    1187       99548 : bool handle_logfile(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1188             :                     const char *pszParmValue, char **ptr)
    1189             : {
    1190       99548 :         if (lp_ctx->s3_fns == NULL) {
    1191       33809 :                 debug_set_logfile(pszParmValue);
    1192             :         }
    1193             : 
    1194       99548 :         lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1195             : 
    1196       99548 :         return true;
    1197             : }
    1198             : 
    1199             : /*
    1200             :  * These special charset handling methods only run in the source3 code.
    1201             :  */
    1202             : 
    1203       12568 : bool handle_charset(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1204             :                         const char *pszParmValue, char **ptr)
    1205             : {
    1206       12568 :         if (lp_ctx->s3_fns) {
    1207          13 :                 if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
    1208          11 :                         struct smb_iconv_handle *ret = NULL;
    1209             : 
    1210          11 :                         ret = reinit_iconv_handle(NULL,
    1211             :                                                   lpcfg_dos_charset(lp_ctx),
    1212             :                                                   lpcfg_unix_charset(lp_ctx));
    1213          11 :                         if (ret == NULL) {
    1214           0 :                                 smb_panic("reinit_iconv_handle failed");
    1215             :                         }
    1216             :                 }
    1217             : 
    1218             :         }
    1219       12568 :         return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1220             : 
    1221             : }
    1222             : 
    1223       12570 : bool handle_dos_charset(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1224             :                         const char *pszParmValue, char **ptr)
    1225             : {
    1226       12570 :         bool is_utf8 = false;
    1227       12570 :         size_t len = strlen(pszParmValue);
    1228             : 
    1229       12570 :         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       12570 :         return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
    1267             : }
    1268             : 
    1269       89166 : 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       89166 :         if (parm_num == -1) {
    1275        7697 :                 parm_num = lpcfg_map_parameter("printing");
    1276             :         }
    1277             : 
    1278       89166 :         if (!lp_set_enum_parm(&parm_table[parm_num], pszParmValue, (int*)ptr)) {
    1279           0 :                 return false;
    1280             :         }
    1281             : 
    1282       89166 :         if (lp_ctx->s3_fns) {
    1283       70728 :                 if (service == NULL) {
    1284       70728 :                         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       88920 :         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       12561 : bool handle_idmap_backend(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    1309             :                           const char *pszParmValue, char **ptr)
    1310             : {
    1311       12561 :         if (lp_ctx->s3_fns) {
    1312           6 :                 lp_do_parameter_parametric(lp_ctx, service, "idmap config * : backend",
    1313             :                                            pszParmValue, 0);
    1314             :         }
    1315             : 
    1316       12561 :         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       12555 : 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       12555 :         if (!pszParmValue || !*pszParmValue) {
    1349           0 :                 return false;
    1350             :         }
    1351             : 
    1352       12555 :         if (parm_num == -1) {
    1353       12383 :                 parm_num = lpcfg_map_parameter("smb ports");
    1354       12383 :                 if (parm_num == -1) {
    1355           0 :                         return false;
    1356             :                 }
    1357             :         }
    1358             : 
    1359       12555 :         if (!set_variable_helper(lp_ctx->globals->ctx, parm_num, ptr, "smb ports",
    1360             :                                 pszParmValue)) {
    1361           0 :                 return false;
    1362             :         }
    1363             : 
    1364       12555 :         list = lp_ctx->globals->smb_ports;
    1365       12555 :         if (list == NULL) {
    1366           0 :                 return false;
    1367             :         }
    1368             : 
    1369             :         /* Check that each port is a valid integer and within range */
    1370       37665 :         for (i = 0; list[i] != NULL; i++) {
    1371       25110 :                 char *end = NULL;
    1372       25110 :                 int port = 0;
    1373       25110 :                 port = strtol(list[i], &end, 10);
    1374       25110 :                 if (*end != '\0' || port <= 0 || port > 65535) {
    1375           0 :                         TALLOC_FREE(list);
    1376           0 :                         return false;
    1377             :                 }
    1378             :         }
    1379             : 
    1380       11939 :         return true;
    1381             : }
    1382             : 
    1383       12555 : 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       12555 :         int low_port = -1, high_port = -1;
    1390         616 :         int rc;
    1391             : 
    1392       12555 :         if (parm_num == -1) {
    1393       12383 :                 parm_num = lpcfg_map_parameter("rpc server dynamic port range");
    1394       12383 :                 if (parm_num == -1) {
    1395           0 :                         return false;
    1396             :                 }
    1397             :         }
    1398             : 
    1399       12555 :         if (pszParmValue == NULL || pszParmValue[0] == '\0') {
    1400           0 :                 return false;
    1401             :         }
    1402             : 
    1403       12555 :         rc = sscanf(pszParmValue, "%d - %d", &low_port, &high_port);
    1404       12555 :         if (rc != 2) {
    1405           0 :                 return false;
    1406             :         }
    1407             : 
    1408       12555 :         if (low_port > high_port) {
    1409           0 :                 return false;
    1410             :         }
    1411             : 
    1412       12555 :         if (low_port < SERVER_TCP_PORT_MIN|| high_port > SERVER_TCP_PORT_MAX) {
    1413           0 :                 return false;
    1414             :         }
    1415             : 
    1416       12555 :         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       12555 :         lp_ctx->globals->rpc_low_port = low_port;
    1423       12555 :         lp_ctx->globals->rpc_high_port = high_port;
    1424             : 
    1425       12555 :         return true;
    1426             : }
    1427             : 
    1428       12561 : bool handle_smb2_max_credits(struct loadparm_context *lp_ctx,
    1429             :                              struct loadparm_service *service,
    1430             :                              const char *pszParmValue, char **ptr)
    1431             : {
    1432       12561 :         int value = lp_int(pszParmValue);
    1433             : 
    1434       12561 :         if (value <= 0) {
    1435           0 :                 value = DEFAULT_SMB2_MAX_CREDITS;
    1436             :         }
    1437             : 
    1438       12561 :         *(int *)ptr = value;
    1439             : 
    1440       12561 :         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      294549 : void init_copymap(struct loadparm_service *pservice)
    1480             : {
    1481        2033 :         int i;
    1482             : 
    1483      294549 :         TALLOC_FREE(pservice->copymap);
    1484             : 
    1485      294549 :         pservice->copymap = bitmap_talloc(pservice, num_parameters());
    1486      294549 :         if (!pservice->copymap) {
    1487           0 :                 DEBUG(0,
    1488             :                       ("Couldn't allocate copymap!! (size %d)\n",
    1489             :                        (int)num_parameters()));
    1490             :         } else {
    1491   153460029 :                 for (i = 0; i < num_parameters(); i++) {
    1492   153165480 :                         bitmap_set(pservice->copymap, i);
    1493             :                 }
    1494             :         }
    1495      294549 : }
    1496             : 
    1497             : /**
    1498             :  * Process a parametric option
    1499             :  */
    1500     5981602 : 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       16040 :         struct parmlist_entry **data;
    1506       16040 :         char *name;
    1507       16040 :         TALLOC_CTX *mem_ctx;
    1508             : 
    1509     5981602 :         while (isspace((unsigned char)*pszParmName)) {
    1510           0 :                 pszParmName++;
    1511             :         }
    1512             : 
    1513     5981602 :         name = strlower_talloc(lp_ctx, pszParmName);
    1514     5981602 :         if (!name) return false;
    1515             : 
    1516     5981602 :         if (service == NULL) {
    1517     1966892 :                 data = &lp_ctx->globals->param_opt;
    1518             :                 /**
    1519             :                  * s3 code cannot deal with parametric options stored on the globals ctx.
    1520             :                  */
    1521     1966892 :                 if (lp_ctx->s3_fns != NULL) {
    1522     1153320 :                         mem_ctx = NULL;
    1523             :                 } else {
    1524      812527 :                         mem_ctx = lp_ctx->globals->ctx;
    1525             :                 }
    1526             :         } else {
    1527     4014710 :                 data = &service->param_opt;
    1528     4014710 :                 mem_ctx = service;
    1529             :         }
    1530             : 
    1531     5981602 :         set_param_opt(mem_ctx, data, name, pszParmValue, flags);
    1532             : 
    1533     5981602 :         talloc_free(name);
    1534             : 
    1535     5981602 :         return true;
    1536             : }
    1537             : 
    1538    17049099 : static bool set_variable_helper(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
    1539             :                          const char *pszParmName, const char *pszParmValue)
    1540             : {
    1541      174311 :         size_t i;
    1542             : 
    1543             :         /* switch on the type of variable it is */
    1544    17049099 :         switch (parm_table[parmnum].type)
    1545             :         {
    1546     5000445 :                 case P_BOOL: {
    1547       61888 :                         bool b;
    1548     5000445 :                         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     5000445 :                         *(bool *)parm_ptr = b;
    1554             :                         }
    1555     5000445 :                         break;
    1556             : 
    1557       18942 :                 case P_BOOLREV: {
    1558           0 :                         bool b;
    1559       18942 :                         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       18942 :                         *(bool *)parm_ptr = !b;
    1565             :                         }
    1566       18942 :                         break;
    1567             : 
    1568      777195 :                 case P_INTEGER:
    1569      777195 :                         *(int *)parm_ptr = lp_int(pszParmValue);
    1570      777195 :                         break;
    1571             : 
    1572       12561 :                 case P_CHAR:
    1573       12561 :                         *(char *)parm_ptr = *pszParmValue;
    1574       12561 :                         break;
    1575             : 
    1576      389732 :                 case P_OCTAL:
    1577      389732 :                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
    1578      389732 :                         if ( i != 1 ) {
    1579           0 :                                 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
    1580           0 :                                 return false;
    1581             :                         }
    1582      388871 :                         break;
    1583             : 
    1584      213369 :                 case P_BYTES:
    1585             :                 {
    1586        4420 :                         uint64_t val;
    1587      213369 :                         if (conv_str_size_error(pszParmValue, &val)) {
    1588      213369 :                                 if (val <= INT_MAX) {
    1589      213369 :                                         *(int *)parm_ptr = (int)val;
    1590      213369 :                                         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     2293509 :                 case P_CMDLIST:
    1600     2293509 :                         TALLOC_FREE(*(char ***)parm_ptr);
    1601     2293509 :                         *(char ***)parm_ptr = str_list_make_v3(mem_ctx,
    1602             :                                                         pszParmValue, NULL);
    1603     2293509 :                         break;
    1604             : 
    1605      223256 :                 case P_LIST:
    1606             :                 {
    1607      223256 :                         char **new_list = str_list_make_v3(mem_ctx,
    1608             :                                                         pszParmValue, NULL);
    1609      223256 :                         if (new_list == NULL) {
    1610           3 :                                 break;
    1611             :                         }
    1612             : 
    1613      360313 :                         for (i=0; new_list[i]; i++) {
    1614      310082 :                                 if (*(const char ***)parm_ptr != NULL &&
    1615      207000 :                                     new_list[i][0] == '+' &&
    1616       93863 :                                     new_list[i][1])
    1617             :                                 {
    1618      110228 :                                         if (!str_list_check(*(const char ***)parm_ptr,
    1619       93863 :                                                             &new_list[i][1])) {
    1620       44623 :                                                 *(const char ***)parm_ptr = str_list_add(*(const char ***)parm_ptr,
    1621       44623 :                                                                                          &new_list[i][1]);
    1622             :                                         }
    1623      216219 :                                 } else if (*(const char ***)parm_ptr != NULL &&
    1624      113137 :                                            new_list[i][0] == '-' &&
    1625       43197 :                                            new_list[i][1])
    1626             :                                 {
    1627       43197 :                                         str_list_remove(*(const char ***)parm_ptr,
    1628       43197 :                                                         &new_list[i][1]);
    1629             :                                 } else {
    1630      173022 :                                         if (i != 0) {
    1631           0 :                                                 DEBUG(0, ("Unsupported list syntax for: %s = %s\n",
    1632             :                                                           pszParmName, pszParmValue));
    1633           0 :                                                 return false;
    1634             :                                         }
    1635      173022 :                                         *(char ***)parm_ptr = new_list;
    1636      173022 :                                         break;
    1637             :                                 }
    1638             :                         }
    1639      217309 :                         break;
    1640             :                 }
    1641             : 
    1642     6580225 :                 case P_STRING:
    1643     6580225 :                         lpcfg_string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
    1644     6580225 :                         break;
    1645             : 
    1646      193520 :                 case P_USTRING:
    1647      193520 :                         lpcfg_string_set_upper(mem_ctx, (char **)parm_ptr, pszParmValue);
    1648      193520 :                         break;
    1649             : 
    1650     1346345 :                 case P_ENUM:
    1651     1346345 :                         if (!lp_set_enum_parm(&parm_table[parmnum], pszParmValue, (int*)parm_ptr)) {
    1652           2 :                                 return false;
    1653             :                         }
    1654     1318131 :                         break;
    1655             : 
    1656             :         }
    1657             : 
    1658    16874786 :         return true;
    1659             : 
    1660             : }
    1661             : 
    1662       12565 : bool handle_name_resolve_order(struct loadparm_context *lp_ctx,
    1663             :                                struct loadparm_service *service,
    1664             :                                const char *pszParmValue, char **ptr)
    1665             : {
    1666       12565 :         const char **valid_values = NULL;
    1667       12565 :         const char **values_to_set = NULL;
    1668         616 :         int i;
    1669       12565 :         bool value_is_valid = false;
    1670       12565 :         valid_values = str_list_make_v3_const(NULL,
    1671             :                                               DEFAULT_NAME_RESOLVE_ORDER,
    1672             :                                               NULL);
    1673       12565 :         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       12565 :         values_to_set = str_list_make_v3_const(lp_ctx->globals->ctx,
    1679             :                                                pszParmValue,
    1680             :                                                NULL);
    1681       12565 :         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       12565 :         TALLOC_FREE(lp_ctx->globals->name_resolve_order);
    1687       62805 :         for (i = 0; values_to_set[i] != NULL; i++) {
    1688       50248 :                 value_is_valid = str_list_check(valid_values, values_to_set[i]);
    1689       50248 :                 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       12557 : out:
    1697       12565 :         if (value_is_valid) {
    1698       12557 :                 lp_ctx->globals->name_resolve_order = values_to_set;
    1699             :         } else {
    1700           8 :                 TALLOC_FREE(values_to_set);
    1701             :         }
    1702       12565 :         TALLOC_FREE(valid_values);
    1703       12565 :         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    18783774 : 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      181989 :         int i;
    1855      181989 :         bool ok;
    1856             : 
    1857             :         /* if it is a special case then go ahead */
    1858    18783774 :         if (parm_table[parmnum].special) {
    1859     1759785 :                 ok = parm_table[parmnum].special(lp_ctx, service, pszParmValue,
    1860             :                                                   (char **)parm_ptr);
    1861             :         } else {
    1862    17023989 :                 ok = set_variable_helper(mem_ctx, parmnum, parm_ptr,
    1863             :                                          pszParmName, pszParmValue);
    1864             :         }
    1865             : 
    1866    18783774 :         if (!ok) {
    1867          17 :                 return false;
    1868             :         }
    1869             : 
    1870    18783757 :         if (on_globals && (lp_ctx->flags[parmnum] & FLAG_DEFAULT)) {
    1871      379572 :                 lp_ctx->flags[parmnum] &= ~FLAG_DEFAULT;
    1872             :                 /* we have to also unset FLAG_DEFAULT on aliases */
    1873      388159 :                 for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) {
    1874        8587 :                         lp_ctx->flags[i] &= ~FLAG_DEFAULT;
    1875             :                 }
    1876      431475 :                 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset;i++) {
    1877       51903 :                         lp_ctx->flags[i] &= ~FLAG_DEFAULT;
    1878             :                 }
    1879             :         }
    1880    18601768 :         return true;
    1881             : }
    1882             : 
    1883             : 
    1884     9713435 : bool lpcfg_do_global_parameter(struct loadparm_context *lp_ctx,
    1885             :                                const char *pszParmName, const char *pszParmValue)
    1886             : {
    1887     9713435 :         int parmnum = lpcfg_map_parameter(pszParmName);
    1888      184733 :         void *parm_ptr;
    1889             : 
    1890     9713435 :         if (parmnum < 0) {
    1891     1940478 :                 if (strchr(pszParmName, ':')) {
    1892     1940476 :                         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     7772957 :         if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) {
    1901       55488 :                 return true;
    1902             :         }
    1903             : 
    1904     7717163 :         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
    1905      370862 :                 char *suppress_env = getenv("SAMBA_DEPRECATED_SUPPRESS");
    1906      384657 :                 bool print_warning = (suppress_env == NULL
    1907      370862 :                                       || suppress_env[0] == '\0');
    1908      370862 :                 if (print_warning) {
    1909           4 :                         DBG_WARNING("WARNING: The \"%s\" option "
    1910             :                                     "is deprecated\n",
    1911             :                                     pszParmName);
    1912             : 
    1913             :                 }
    1914             :         }
    1915             : 
    1916     7717163 :         parm_ptr = lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[parmnum]);
    1917             : 
    1918     7717163 :         return set_variable(lp_ctx->globals->ctx, NULL, parmnum, parm_ptr,
    1919             :                             pszParmName, pszParmValue, lp_ctx, true);
    1920             : }
    1921             : 
    1922    15081549 : 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    15081549 :         int parmnum = lpcfg_map_parameter(pszParmName);
    1929             : 
    1930    15081549 :         if (parmnum < 0) {
    1931     4014710 :                 if (strchr(pszParmName, ':')) {
    1932     4014710 :                         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    11066839 :         if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) {
    1941         228 :                 return true;
    1942             :         }
    1943             : 
    1944    11066611 :         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    11066611 :         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    11066611 :         parm_ptr = ((char *)service) + parm_table[parmnum].offset;
    1963             : 
    1964    11066611 :         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  5754637720 :         for (i = 0; parm_table[i].label; i++)
    1970  5743571109 :                 if (parm_table[i].offset == parm_table[parmnum].offset &&
    1971    28420972 :                     parm_table[i].p_class == parm_table[parmnum].p_class)
    1972    18345243 :                         bitmap_clear(service->copymap, i);
    1973             : 
    1974    11066611 :         return set_variable(service, service, parmnum, parm_ptr, pszParmName,
    1975             :                             pszParmValue, lp_ctx, false);
    1976             : }
    1977             : 
    1978             : /**
    1979             :  * Process a parameter.
    1980             :  */
    1981             : 
    1982     3061435 : bool lpcfg_do_parameter(const char *pszParmName, const char *pszParmValue,
    1983             :                          void *userdata)
    1984             : {
    1985     3061435 :         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
    1986             : 
    1987     3061435 :         if (lp_ctx->bInGlobalSection)
    1988     2029922 :                 return lpcfg_do_global_parameter(lp_ctx, pszParmName,
    1989             :                                               pszParmValue);
    1990             :         else
    1991     1031513 :                 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      190559 : 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      190559 :         va_start(ap, fmt);
    2007      190559 :         s = talloc_vasprintf(NULL, fmt, ap);
    2008      190559 :         va_end(ap);
    2009      190559 :         ret = lpcfg_do_global_parameter(lp_ctx, pszParmName, s);
    2010      190559 :         talloc_free(s);
    2011      190559 :         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       66996 : 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       69898 :         while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
    2027             : 
    2028       66996 :         parmnum = lpcfg_map_parameter(pszParmName);
    2029             : 
    2030       66996 :         if (parmnum < 0 && strchr(pszParmName, ':')) {
    2031             :                 /* set a parametric option */
    2032         911 :                 bool ok;
    2033       26398 :                 ok = lp_do_parameter_parametric(lp_ctx, NULL, pszParmName,
    2034             :                                                 pszParmValue, FLAG_CMDLINE);
    2035       26398 :                 if (lp_ctx->s3_fns != NULL) {
    2036         412 :                         if (ok) {
    2037         412 :                                 lp_ctx->s3_fns->store_cmdline(pszParmName, pszParmValue);
    2038             :                         }
    2039             :                 }
    2040       26398 :                 return ok;
    2041             :         }
    2042             : 
    2043       40598 :         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       40598 :         lp_ctx->flags[parmnum] &= ~FLAG_CMDLINE;
    2050             : 
    2051       40598 :         if (!lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) {
    2052           5 :                 return false;
    2053             :         }
    2054             : 
    2055       40593 :         lp_ctx->flags[parmnum] |= FLAG_CMDLINE;
    2056             : 
    2057             :         /* we have to also set FLAG_CMDLINE on aliases */
    2058       40593 :         for (i=parmnum-1;
    2059       40874 :              i>=0 && parm_table[i].p_class == parm_table[parmnum].p_class &&
    2060       39861 :              parm_table[i].offset == parm_table[parmnum].offset;
    2061         281 :              i--) {
    2062         281 :                 lp_ctx->flags[i] |= FLAG_CMDLINE;
    2063             :         }
    2064       40593 :         for (i=parmnum+1;
    2065       65634 :              i<num_parameters() &&
    2066       65271 :              parm_table[i].p_class == parm_table[parmnum].p_class &&
    2067       62228 :              parm_table[i].offset == parm_table[parmnum].offset;
    2068       24678 :              i++) {
    2069       24678 :                 lp_ctx->flags[i] |= FLAG_CMDLINE;
    2070             :         }
    2071             : 
    2072       40593 :         if (lp_ctx->s3_fns != NULL) {
    2073       35889 :                 lp_ctx->s3_fns->store_cmdline(pszParmName, pszParmValue);
    2074             :         }
    2075             : 
    2076       40311 :         return true;
    2077             : }
    2078             : 
    2079             : /*
    2080             :   set a option from the commandline in 'a=b' format. Use to support --option
    2081             : */
    2082       11482 : bool lpcfg_set_option(struct loadparm_context *lp_ctx, const char *option)
    2083             : {
    2084         375 :         char *p, *s;
    2085         375 :         bool ret;
    2086             : 
    2087       11482 :         s = talloc_strdup(NULL, option);
    2088       11482 :         if (!s) {
    2089           0 :                 return false;
    2090             :         }
    2091             : 
    2092       11482 :         p = strchr(s, '=');
    2093       11482 :         if (!p) {
    2094           1 :                 talloc_free(s);
    2095           1 :                 return false;
    2096             :         }
    2097             : 
    2098       11481 :         *p = 0;
    2099             : 
    2100       11481 :         ret = lpcfg_set_cmdline(lp_ctx, s, p+1);
    2101       11481 :         talloc_free(s);
    2102       11481 :         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       51678 : 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       51678 :         const char *list_sep = ", ";
    2116        1648 :         int i;
    2117       51678 :         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       15620 :                 case P_BOOL:
    2130       15620 :                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
    2131       15195 :                         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       51678 : }
    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      337829 : static bool do_section(const char *pszSectionName, void *userdata)
    2234             : {
    2235      337829 :         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
    2236        3724 :         bool bRetval;
    2237        3724 :         bool isglobal;
    2238             : 
    2239      337829 :         if (lp_ctx->s3_fns != NULL) {
    2240           0 :                 return lp_ctx->s3_fns->do_section(pszSectionName, lp_ctx);
    2241             :         }
    2242             : 
    2243      639341 :         isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
    2244      301512 :                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
    2245             : 
    2246             :         /* if we've just struck a global section, note the fact. */
    2247      337829 :         lp_ctx->bInGlobalSection = isglobal;
    2248             : 
    2249             :         /* check for multiple global sections */
    2250      337829 :         if (lp_ctx->bInGlobalSection) {
    2251       36510 :                 DEBUG(4, ("Processing section \"[%s]\"\n", pszSectionName));
    2252       36510 :                 bRetval = true;
    2253       36510 :                 goto out;
    2254             :         }
    2255             : 
    2256             :         /* if we have a current service, tidy it up before moving on */
    2257      301319 :         bRetval = true;
    2258             : 
    2259      301319 :         if (lp_ctx->currentService != NULL)
    2260      283183 :                 bRetval = lpcfg_service_ok(lp_ctx->currentService);
    2261             : 
    2262             :         /* if all is still well, move to the next record in the services array */
    2263      301122 :         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      301319 :                 DEBUG(4, ("Processing section \"[%s]\"\n", pszSectionName));
    2267             : 
    2268      301319 :                 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      301319 : out:
    2277      334105 :         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        1383 :                                 continue;
    2340             :                         }
    2341             :                 }
    2342             : 
    2343       30376 :                 fprintf(f, "\t%s = ", parm_table[i].label);
    2344       30376 :                 lpcfg_print_parameter(&parm_table[i], lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[i]), f);
    2345       43219 :                 fprintf(f, "\n");
    2346             :         }
    2347        1296 :         if (lp_ctx->globals->param_opt != NULL) {
    2348       11501 :                 for (data = lp_ctx->globals->param_opt; data;
    2349       10205 :                      data = data->next) {
    2350       10205 :                         if (!show_defaults && (data->priority & FLAG_DEFAULT)) {
    2351        2120 :                                 continue;
    2352             :                         }
    2353        8160 :                         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       28626 : static void lpcfg_add_auto_services(struct loadparm_context *lp_ctx,
    2479             :                                     const char *str)
    2480             : {
    2481       28626 :         return;
    2482             : }
    2483             : 
    2484             : /***************************************************************************
    2485             :  Initialise the sDefault parameter structure for the printer values.
    2486             : ***************************************************************************/
    2487             : 
    2488      169135 : 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      169135 :         switch (pService->printing) {
    2493       43069 :                 case PRINT_BSD:
    2494             :                 case PRINT_AIX:
    2495             :                 case PRINT_LPRNT:
    2496             :                 case PRINT_LPROS2:
    2497       43069 :                         lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
    2498       43069 :                         lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
    2499       43069 :                         lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
    2500       43069 :                         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      126066 :                 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      126066 :                         lpcfg_string_set(ctx, &pService->lpq_command, "%p");
    2518      126066 :                         lpcfg_string_set(ctx, &pService->lprm_command, "");
    2519      126066 :                         lpcfg_string_set(ctx, &pService->print_command, "");
    2520      126066 :                         lpcfg_string_set(ctx, &pService->lppause_command, "");
    2521      126066 :                         lpcfg_string_set(ctx, &pService->lpresume_command, "");
    2522      126066 :                         lpcfg_string_set(ctx, &pService->queuepause_command, "");
    2523      126066 :                         lpcfg_string_set(ctx, &pService->queueresume_command, "");
    2524      126066 :                         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      169135 : }
    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       12552 : 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       12552 :         lp_ctx = talloc_zero(mem_ctx, struct loadparm_context);
    2645       12552 :         if (lp_ctx == NULL)
    2646           0 :                 return NULL;
    2647             : 
    2648       12552 :         talloc_set_destructor(lp_ctx, lpcfg_destructor);
    2649       12552 :         lp_ctx->bInGlobalSection = true;
    2650       12552 :         lp_ctx->globals = talloc_zero(lp_ctx, struct loadparm_global);
    2651             :         /* This appears odd, but globals in s3 isn't a pointer */
    2652       12552 :         lp_ctx->globals->ctx = lp_ctx->globals;
    2653       12552 :         lp_ctx->globals->rpc_low_port = SERVER_TCP_LOW_PORT;
    2654       12552 :         lp_ctx->globals->rpc_high_port = SERVER_TCP_HIGH_PORT;
    2655       12552 :         lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_UNKNOWN;
    2656       12552 :         lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
    2657       12552 :         lp_ctx->flags = talloc_zero_array(lp_ctx, unsigned int, num_parameters());
    2658             : 
    2659       12552 :         lp_ctx->sDefault->max_print_jobs = 1000;
    2660       12552 :         lp_ctx->sDefault->available = true;
    2661       12552 :         lp_ctx->sDefault->browseable = true;
    2662       12552 :         lp_ctx->sDefault->read_only = true;
    2663       12552 :         lp_ctx->sDefault->map_archive = true;
    2664       12552 :         lp_ctx->sDefault->strict_locking = true;
    2665       12552 :         lp_ctx->sDefault->oplocks = true;
    2666       12552 :         lp_ctx->sDefault->create_mask = 0744;
    2667       12552 :         lp_ctx->sDefault->force_create_mode = 0000;
    2668       12552 :         lp_ctx->sDefault->directory_mask = 0755;
    2669       12552 :         lp_ctx->sDefault->force_directory_mode = 0000;
    2670       12552 :         lp_ctx->sDefault->aio_read_size = 1;
    2671       12552 :         lp_ctx->sDefault->aio_write_size = 1;
    2672       12552 :         lp_ctx->sDefault->smbd_search_ask_sharemode = true;
    2673       12552 :         lp_ctx->sDefault->smbd_getinfo_ask_sharemode = true;
    2674       12552 :         lp_ctx->sDefault->volume_serial_number = -1;
    2675             : 
    2676       12552 :         DEBUG(3, ("Initialising global parameters\n"));
    2677             : 
    2678     6527040 :         for (i = 0; parm_table[i].label; i++) {
    2679     6514488 :                 if ((parm_table[i].type == P_STRING ||
    2680     4600512 :                      parm_table[i].type == P_USTRING) &&
    2681     1807488 :                     !(lp_ctx->flags[i] & FLAG_CMDLINE)) {
    2682       88704 :                         TALLOC_CTX *parent_mem;
    2683       88704 :                         char **r;
    2684     1807488 :                         if (parm_table[i].p_class == P_LOCAL) {
    2685      439320 :                                 parent_mem = lp_ctx->sDefault;
    2686      439320 :                                 r = (char **)(((char *)lp_ctx->sDefault) + parm_table[i].offset);
    2687             :                         } else {
    2688     1368168 :                                 parent_mem = lp_ctx->globals;
    2689     1368168 :                                 r = (char **)(((char *)lp_ctx->globals) + parm_table[i].offset);
    2690             :                         }
    2691     1807488 :                         lpcfg_string_set(parent_mem, r, "");
    2692             :                 }
    2693             :         }
    2694             : 
    2695       12552 :         logfile = talloc_asprintf(lp_ctx, "%s/log.samba", dyn_LOGFILEBASE);
    2696       12552 :         lpcfg_do_global_parameter(lp_ctx, "log file", logfile);
    2697       12552 :         talloc_free(logfile);
    2698             : 
    2699       12552 :         lpcfg_do_global_parameter(lp_ctx, "log level", "0");
    2700             : 
    2701       12552 :         lpcfg_do_global_parameter(lp_ctx, "syslog", "1");
    2702       12552 :         lpcfg_do_global_parameter(lp_ctx, "syslog only", "No");
    2703       12552 :         lpcfg_do_global_parameter(lp_ctx, "debug timestamp", "Yes");
    2704       12552 :         lpcfg_do_global_parameter(lp_ctx, "debug prefix timestamp", "No");
    2705       12552 :         lpcfg_do_global_parameter(lp_ctx, "debug hires timestamp", "Yes");
    2706       12552 :         lpcfg_do_global_parameter(lp_ctx, "debug syslog format", "No");
    2707       12552 :         lpcfg_do_global_parameter(lp_ctx, "debug pid", "No");
    2708       12552 :         lpcfg_do_global_parameter(lp_ctx, "debug uid", "No");
    2709       12552 :         lpcfg_do_global_parameter(lp_ctx, "debug class", "No");
    2710             : 
    2711       12552 :         lpcfg_do_global_parameter(lp_ctx, "server role", "auto");
    2712       12552 :         lpcfg_do_global_parameter(lp_ctx, "domain logons", "No");
    2713       12552 :         lpcfg_do_global_parameter(lp_ctx, "domain master", "Auto");
    2714             : 
    2715             :         /* options that can be set on the command line must be initialised via
    2716             :            the slower lpcfg_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */
    2717             : #ifdef TCP_NODELAY
    2718       12552 :         lpcfg_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY");
    2719             : #endif
    2720       12552 :         lpcfg_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP);
    2721       12552 :         myname = get_myname(lp_ctx);
    2722       12552 :         lpcfg_do_global_parameter(lp_ctx, "netbios name", myname);
    2723       12552 :         talloc_free(myname);
    2724       12552 :         lpcfg_do_global_parameter(lp_ctx,
    2725             :                                   "name resolve order",
    2726             :                                   DEFAULT_NAME_RESOLVE_ORDER);
    2727             : 
    2728       12552 :         lpcfg_do_global_parameter(lp_ctx, "fstype", "NTFS");
    2729             : 
    2730       12552 :         lpcfg_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
    2731       12552 :         lpcfg_do_global_parameter(lp_ctx, "max connections", "0");
    2732             : 
    2733       12552 :         lpcfg_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper wkssvc samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver");
    2734       12552 :         lpcfg_do_global_parameter(lp_ctx, "server services", "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns");
    2735       12552 :         lpcfg_do_global_parameter(lp_ctx, "kccsrv:samba_kcc", "true");
    2736             :         /* the winbind method for domain controllers is for both RODC
    2737             :            auth forwarding and for trusted domains */
    2738       12552 :         lpcfg_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
    2739       12552 :         lpcfg_do_global_parameter(lp_ctx, "binddns dir", dyn_BINDDNS_DIR);
    2740       12552 :         lpcfg_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
    2741             : 
    2742             :         /* This hive should be dynamically generated by Samba using
    2743             :            data from the sam, but for the moment leave it in a tdb to
    2744             :            keep regedt32 from popping up an annoying dialog. */
    2745       12552 :         lpcfg_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb");
    2746             : 
    2747             :         /* using UTF8 by default allows us to support all chars */
    2748       12552 :         lpcfg_do_global_parameter(lp_ctx, "unix charset", "UTF-8");
    2749             : 
    2750             :         /* Use codepage 850 as a default for the dos character set */
    2751       12552 :         lpcfg_do_global_parameter(lp_ctx, "dos charset", "CP850");
    2752             : 
    2753             :         /*
    2754             :          * Allow the default PASSWD_CHAT to be overridden in local.h.
    2755             :          */
    2756       12552 :         lpcfg_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT);
    2757             : 
    2758       12552 :         lpcfg_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR);
    2759       12552 :         lpcfg_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR);
    2760       12552 :         lpcfg_do_global_parameter(lp_ctx, "state directory", dyn_STATEDIR);
    2761       12552 :         lpcfg_do_global_parameter(lp_ctx, "cache directory", dyn_CACHEDIR);
    2762       12552 :         lpcfg_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
    2763             : 
    2764       12552 :         lpcfg_do_global_parameter(lp_ctx, "nbt client socket address", "0.0.0.0");
    2765       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "server string",
    2766             :                                    "Samba %s", SAMBA_VERSION_STRING);
    2767             : 
    2768       12552 :         lpcfg_do_global_parameter(lp_ctx, "password server", "*");
    2769             : 
    2770       12552 :         lpcfg_do_global_parameter(lp_ctx, "max mux", "50");
    2771       12552 :         lpcfg_do_global_parameter(lp_ctx, "max xmit", "16644");
    2772       12552 :         lpcfg_do_global_parameter(lp_ctx, "host msdfs", "true");
    2773             : 
    2774       12552 :         lpcfg_do_global_parameter(lp_ctx, "LargeReadwrite", "True");
    2775       12552 :         lpcfg_do_global_parameter(lp_ctx, "server min protocol", "SMB2_02");
    2776       12552 :         lpcfg_do_global_parameter(lp_ctx, "server max protocol", "SMB3");
    2777       12552 :         lpcfg_do_global_parameter(lp_ctx, "client min protocol", "SMB2_02");
    2778       12552 :         lpcfg_do_global_parameter(lp_ctx, "client max protocol", "default");
    2779       12552 :         lpcfg_do_global_parameter(lp_ctx, "client ipc min protocol", "default");
    2780       12552 :         lpcfg_do_global_parameter(lp_ctx, "client ipc max protocol", "default");
    2781       12552 :         lpcfg_do_global_parameter(lp_ctx, "security", "AUTO");
    2782       12552 :         lpcfg_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
    2783       12552 :         lpcfg_do_global_parameter(lp_ctx, "ReadRaw", "True");
    2784       12552 :         lpcfg_do_global_parameter(lp_ctx, "WriteRaw", "True");
    2785       12552 :         lpcfg_do_global_parameter(lp_ctx, "NullPasswords", "False");
    2786       12552 :         lpcfg_do_global_parameter(lp_ctx, "old password allowed period", "60");
    2787       12552 :         lpcfg_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
    2788             : 
    2789       12552 :         lpcfg_do_global_parameter(lp_ctx, "TimeServer", "False");
    2790       12552 :         lpcfg_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False");
    2791       12552 :         lpcfg_do_global_parameter(lp_ctx, "Unicode", "True");
    2792       12552 :         lpcfg_do_global_parameter(lp_ctx, "ClientLanManAuth", "False");
    2793       12552 :         lpcfg_do_global_parameter(lp_ctx, "ClientNTLMv2Auth", "True");
    2794       12552 :         lpcfg_do_global_parameter(lp_ctx, "LanmanAuth", "False");
    2795       12552 :         lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "ntlmv2-only");
    2796       12552 :         lpcfg_do_global_parameter(lp_ctx, "NT hash store", "always");
    2797       12552 :         lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False");
    2798       12552 :         lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False");
    2799             : 
    2800       12552 :         lpcfg_do_global_parameter(lp_ctx, "allow dcerpc auth level connect", "False");
    2801             : 
    2802       12552 :         lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True");
    2803             : 
    2804       12552 :         lpcfg_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
    2805       12552 :         lpcfg_do_global_parameter(lp_ctx, "LocalMaster", "True");
    2806             : 
    2807       12552 :         lpcfg_do_global_parameter(lp_ctx, "wins support", "False");
    2808       12552 :         lpcfg_do_global_parameter(lp_ctx, "dns proxy", "True");
    2809             : 
    2810       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbind separator", "\\");
    2811       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
    2812       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbind scan trusted domains", "False");
    2813       12552 :         lpcfg_do_global_parameter(lp_ctx, "require strong key", "True");
    2814       12552 :         lpcfg_do_global_parameter(lp_ctx, "reject md5 servers", "True");
    2815       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
    2816       12552 :         lpcfg_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR);
    2817       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "gpo update command", "%s/samba-gpupdate", dyn_SCRIPTSBINDIR);
    2818       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "apply group policies", "False");
    2819       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "dns update command", "%s/samba_dnsupdate", dyn_SCRIPTSBINDIR);
    2820       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "spn update command", "%s/samba_spnupdate", dyn_SCRIPTSBINDIR);
    2821       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "samba kcc command",
    2822             :                                         "%s/samba_kcc", dyn_SCRIPTSBINDIR);
    2823             : #ifdef MIT_KDC_PATH
    2824        2278 :         lpcfg_do_global_parameter_var(lp_ctx,
    2825             :                                       "mit kdc command",
    2826             :                                       MIT_KDC_PATH);
    2827             : #endif
    2828       12552 :         lpcfg_do_global_parameter(lp_ctx, "template shell", "/bin/false");
    2829       12552 :         lpcfg_do_global_parameter(lp_ctx, "template homedir", "/home/%D/%U");
    2830             : 
    2831       12552 :         lpcfg_do_global_parameter(lp_ctx, "client signing", "default");
    2832       12552 :         lpcfg_do_global_parameter(lp_ctx, "client ipc signing", "default");
    2833       12552 :         lpcfg_do_global_parameter(lp_ctx, "server signing", "default");
    2834             : 
    2835       12552 :         lpcfg_do_global_parameter(lp_ctx, "use mmap", "True");
    2836             : 
    2837       12552 :         lpcfg_do_global_parameter(lp_ctx, "smb ports", "445 139");
    2838       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "nbt port", "%d", NBT_NAME_SERVICE_PORT);
    2839       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "dgram port", "%d", NBT_DGRAM_SERVICE_PORT);
    2840       12552 :         lpcfg_do_global_parameter(lp_ctx, "cldap port", "389");
    2841       12552 :         lpcfg_do_global_parameter(lp_ctx, "krb5 port", "88");
    2842       12552 :         lpcfg_do_global_parameter(lp_ctx, "kpasswd port", "464");
    2843       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "dns port", "%d", DNS_SERVICE_PORT);
    2844             : 
    2845       12552 :         lpcfg_do_global_parameter(lp_ctx, "kdc enable fast", "True");
    2846             : 
    2847       12552 :         lpcfg_do_global_parameter(lp_ctx, "nt status support", "True");
    2848             : 
    2849       12552 :         lpcfg_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */
    2850       12552 :         lpcfg_do_global_parameter(lp_ctx, "min wins ttl", "21600");
    2851             : 
    2852       12552 :         lpcfg_do_global_parameter(lp_ctx, "tls enabled", "True");
    2853       12552 :         lpcfg_do_global_parameter(lp_ctx, "tls verify peer", "as_strict_as_possible");
    2854       12552 :         lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
    2855       12552 :         lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
    2856       12552 :         lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
    2857       12552 :         lpcfg_do_global_parameter(lp_ctx,
    2858             :                                   "tls priority",
    2859             :                                   "NORMAL:-VERS-SSL3.0");
    2860             : 
    2861       12552 :         lpcfg_do_global_parameter(lp_ctx, "nsupdate command", "/usr/bin/nsupdate -g");
    2862             : 
    2863       12552 :         lpcfg_do_global_parameter(lp_ctx, "allow dns updates", "secure only");
    2864       12552 :         lpcfg_do_global_parameter(lp_ctx, "dns zone scavenging", "False");
    2865       12552 :         lpcfg_do_global_parameter(lp_ctx, "dns forwarder", "");
    2866             : 
    2867       12552 :         lpcfg_do_global_parameter(lp_ctx, "algorithmic rid base", "1000");
    2868             : 
    2869       12552 :         lpcfg_do_global_parameter(lp_ctx, "enhanced browsing", "True");
    2870             : 
    2871       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbind nss info", "template");
    2872             : 
    2873       12552 :         lpcfg_do_global_parameter(lp_ctx, "server schannel", "True");
    2874       12552 :         lpcfg_do_global_parameter(lp_ctx, "server schannel require seal", "True");
    2875       12552 :         lpcfg_do_global_parameter(lp_ctx, "reject md5 clients", "True");
    2876             : 
    2877       12552 :         lpcfg_do_global_parameter(lp_ctx, "short preserve case", "True");
    2878             : 
    2879       12552 :         lpcfg_do_global_parameter(lp_ctx, "max open files", "16384");
    2880             : 
    2881       12552 :         lpcfg_do_global_parameter(lp_ctx, "cups connection timeout", "30");
    2882             : 
    2883       12552 :         lpcfg_do_global_parameter(lp_ctx, "locking", "True");
    2884             : 
    2885       12552 :         lpcfg_do_global_parameter(lp_ctx, "block size", "1024");
    2886             : 
    2887       12552 :         lpcfg_do_global_parameter(lp_ctx, "client use spnego", "True");
    2888             : 
    2889       12552 :         lpcfg_do_global_parameter(lp_ctx, "change notify", "True");
    2890             : 
    2891       12552 :         lpcfg_do_global_parameter(lp_ctx, "name cache timeout", "660");
    2892             : 
    2893       12552 :         lpcfg_do_global_parameter(lp_ctx, "defer sharing violations", "True");
    2894             : 
    2895       12552 :         lpcfg_do_global_parameter(lp_ctx, "ldap replication sleep", "1000");
    2896             : 
    2897       12552 :         lpcfg_do_global_parameter(lp_ctx, "idmap backend", "tdb");
    2898             : 
    2899       12552 :         lpcfg_do_global_parameter(lp_ctx, "enable privileges", "True");
    2900             : 
    2901       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max write", "%u", DEFAULT_SMB2_MAX_WRITE);
    2902             : 
    2903       12552 :         lpcfg_do_global_parameter(lp_ctx, "passdb backend", "tdbsam");
    2904             : 
    2905       12552 :         lpcfg_do_global_parameter(lp_ctx, "deadtime", "10080");
    2906             : 
    2907       12552 :         lpcfg_do_global_parameter(lp_ctx, "getwd cache", "True");
    2908             : 
    2909       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbind nested groups", "True");
    2910             : 
    2911       12552 :         lpcfg_do_global_parameter(lp_ctx, "mangled names", "illegal");
    2912             : 
    2913       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max credits", "%u", DEFAULT_SMB2_MAX_CREDITS);
    2914             : 
    2915       12552 :         lpcfg_do_global_parameter(lp_ctx, "ldap ssl", "start tls");
    2916             : 
    2917       12552 :         lpcfg_do_global_parameter(lp_ctx, "ldap deref", "auto");
    2918             : 
    2919       12552 :         lpcfg_do_global_parameter(lp_ctx, "lm interval", "60");
    2920             : 
    2921       12552 :         lpcfg_do_global_parameter(lp_ctx, "mangling method", "hash2");
    2922             : 
    2923       12552 :         lpcfg_do_global_parameter(lp_ctx, "hide dot files", "True");
    2924             : 
    2925       12552 :         lpcfg_do_global_parameter(lp_ctx, "browse list", "True");
    2926             : 
    2927       12552 :         lpcfg_do_global_parameter(lp_ctx, "passwd chat timeout", "2");
    2928             : 
    2929       12552 :         lpcfg_do_global_parameter(lp_ctx, "guest account", GUEST_ACCOUNT);
    2930             : 
    2931       12552 :         lpcfg_do_global_parameter(lp_ctx, "client schannel", "True");
    2932             : 
    2933       12552 :         lpcfg_do_global_parameter(lp_ctx, "smb encrypt", "default");
    2934             : 
    2935       12552 :         lpcfg_do_global_parameter(lp_ctx, "max log size", "5000");
    2936             : 
    2937       12552 :         lpcfg_do_global_parameter(lp_ctx, "idmap negative cache time", "120");
    2938             : 
    2939       12552 :         lpcfg_do_global_parameter(lp_ctx, "ldap follow referral", "auto");
    2940             : 
    2941       12552 :         lpcfg_do_global_parameter(lp_ctx, "multicast dns register", "yes");
    2942             : 
    2943       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbind reconnect delay", "30");
    2944             : 
    2945       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbind request timeout", "60");
    2946             : 
    2947       12552 :         lpcfg_do_global_parameter(lp_ctx, "nt acl support", "yes");
    2948             : 
    2949       12552 :         lpcfg_do_global_parameter(lp_ctx, "acl check permissions", "yes");
    2950             : 
    2951       12552 :         lpcfg_do_global_parameter(lp_ctx, "keepalive", "300");
    2952             : 
    2953       12552 :         lpcfg_do_global_parameter(lp_ctx, "smbd profiling level", "off");
    2954             : 
    2955       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbind cache time", "300");
    2956             : 
    2957       12552 :         lpcfg_do_global_parameter(lp_ctx, "level2 oplocks", "yes");
    2958             : 
    2959       12552 :         lpcfg_do_global_parameter(lp_ctx, "show add printer wizard", "yes");
    2960             : 
    2961       12552 :         lpcfg_do_global_parameter(lp_ctx, "ldap page size", "1000");
    2962             : 
    2963       12552 :         lpcfg_do_global_parameter(lp_ctx, "kernel share modes", "no");
    2964             : 
    2965       12552 :         lpcfg_do_global_parameter(lp_ctx, "strict locking", "Auto");
    2966             : 
    2967       12552 :         lpcfg_do_global_parameter(lp_ctx, "strict sync", "yes");
    2968             : 
    2969       12552 :         lpcfg_do_global_parameter(lp_ctx, "map readonly", "no");
    2970             : 
    2971       12552 :         lpcfg_do_global_parameter(lp_ctx, "allow trusted domains", "yes");
    2972             : 
    2973       12552 :         lpcfg_do_global_parameter(lp_ctx, "default devmode", "yes");
    2974             : 
    2975       12552 :         lpcfg_do_global_parameter(lp_ctx, "os level", "20");
    2976             : 
    2977       12552 :         lpcfg_do_global_parameter(lp_ctx, "dos filetimes", "yes");
    2978             : 
    2979       12552 :         lpcfg_do_global_parameter(lp_ctx, "mangling char", "~");
    2980             : 
    2981       12552 :         lpcfg_do_global_parameter(lp_ctx, "printcap cache time", "750");
    2982             : 
    2983       12552 :         lpcfg_do_global_parameter(lp_ctx, "create krb5 conf", "yes");
    2984             : 
    2985       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbind max clients", "200");
    2986             : 
    2987       12552 :         lpcfg_do_global_parameter(lp_ctx, "acl map full control", "yes");
    2988             : 
    2989       12552 :         lpcfg_do_global_parameter(lp_ctx, "nt pipe support", "yes");
    2990             : 
    2991       12552 :         lpcfg_do_global_parameter(lp_ctx, "ldap debug threshold", "10");
    2992             : 
    2993       12552 :         lpcfg_do_global_parameter(lp_ctx, "client ldap sasl wrapping", "seal");
    2994             : 
    2995       12552 :         lpcfg_do_global_parameter(lp_ctx, "mdns name", "netbios");
    2996             : 
    2997       12552 :         lpcfg_do_global_parameter(lp_ctx, "ldap server require strong auth", "yes");
    2998             : 
    2999       12552 :         lpcfg_do_global_parameter(lp_ctx, "follow symlinks", "yes");
    3000             : 
    3001       12552 :         lpcfg_do_global_parameter(lp_ctx, "machine password timeout", "604800");
    3002             : 
    3003       12552 :         lpcfg_do_global_parameter(lp_ctx, "ldap connection timeout", "2");
    3004             : 
    3005       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbind expand groups", "0");
    3006             : 
    3007       12552 :         lpcfg_do_global_parameter(lp_ctx, "stat cache", "yes");
    3008             : 
    3009       12552 :         lpcfg_do_global_parameter(lp_ctx, "lpq cache time", "30");
    3010             : 
    3011       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max trans", "%u", DEFAULT_SMB2_MAX_TRANSACT);
    3012             : 
    3013       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max read", "%u", DEFAULT_SMB2_MAX_READ);
    3014             : 
    3015       12552 :         lpcfg_do_global_parameter(lp_ctx, "durable handles", "yes");
    3016             : 
    3017       12552 :         lpcfg_do_global_parameter(lp_ctx, "max stat cache size", "512");
    3018             : 
    3019       12552 :         lpcfg_do_global_parameter(lp_ctx, "ldap passwd sync", "no");
    3020             : 
    3021       12552 :         lpcfg_do_global_parameter(lp_ctx, "kernel change notify", "yes");
    3022             : 
    3023       12552 :         lpcfg_do_global_parameter(lp_ctx, "max ttl", "259200");
    3024             : 
    3025       12552 :         lpcfg_do_global_parameter(lp_ctx, "blocking locks", "yes");
    3026             : 
    3027       12552 :         lpcfg_do_global_parameter(lp_ctx, "load printers", "yes");
    3028             : 
    3029       12552 :         lpcfg_do_global_parameter(lp_ctx, "idmap cache time", "604800");
    3030             : 
    3031       12552 :         lpcfg_do_global_parameter(lp_ctx, "preserve case", "yes");
    3032             : 
    3033       12552 :         lpcfg_do_global_parameter(lp_ctx, "lm announce", "auto");
    3034             : 
    3035       12552 :         lpcfg_do_global_parameter(lp_ctx, "afs token lifetime", "604800");
    3036             : 
    3037       12552 :         lpcfg_do_global_parameter(lp_ctx, "enable core files", "yes");
    3038             : 
    3039       12552 :         lpcfg_do_global_parameter(lp_ctx, "winbind max domain connections", "1");
    3040             : 
    3041       12552 :         lpcfg_do_global_parameter(lp_ctx, "case sensitive", "auto");
    3042             : 
    3043       12552 :         lpcfg_do_global_parameter(lp_ctx, "ldap timeout", "15");
    3044             : 
    3045       12552 :         lpcfg_do_global_parameter(lp_ctx, "mangle prefix", "1");
    3046             : 
    3047       12552 :         lpcfg_do_global_parameter(lp_ctx, "posix locking", "yes");
    3048             : 
    3049       12552 :         lpcfg_do_global_parameter(lp_ctx, "lock spin time", "200");
    3050             : 
    3051       12552 :         lpcfg_do_global_parameter(lp_ctx, "nmbd bind explicit broadcast", "yes");
    3052             : 
    3053       12552 :         lpcfg_do_global_parameter(lp_ctx, "init logon delay", "100");
    3054             : 
    3055       12552 :         lpcfg_do_global_parameter(lp_ctx, "usershare owner only", "yes");
    3056             : 
    3057       12552 :         lpcfg_do_global_parameter(lp_ctx, "-valid", "yes");
    3058             : 
    3059       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "usershare path", "%s/usershares", get_dyn_STATEDIR());
    3060             : 
    3061             : #ifdef DEVELOPER
    3062       12552 :         lpcfg_do_global_parameter_var(lp_ctx, "panic action", "/bin/sleep 999999999");
    3063             : #endif
    3064             : 
    3065       12552 :         lpcfg_do_global_parameter(lp_ctx, "smb passwd file", get_dyn_SMB_PASSWD_FILE());
    3066             : 
    3067       12552 :         lpcfg_do_global_parameter(lp_ctx, "logon home", "\\\\%N\\%U");
    3068             : 
    3069       12552 :         lpcfg_do_global_parameter(lp_ctx, "logon path", "\\\\%N\\%U\\profile");
    3070             : 
    3071       12552 :         lpcfg_do_global_parameter(lp_ctx, "printjob username", "%U");
    3072             : 
    3073       12552 :         lpcfg_do_global_parameter(lp_ctx, "aio max threads", "100");
    3074             : 
    3075       12552 :         lpcfg_do_global_parameter(lp_ctx, "smb2 leases", "yes");
    3076             : 
    3077       12552 :         lpcfg_do_global_parameter(lp_ctx, "server multi channel support", "yes");
    3078             : 
    3079       12552 :         lpcfg_do_global_parameter(lp_ctx, "kerberos encryption types", "all");
    3080             : 
    3081       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3082             :                                   "rpc server dynamic port range",
    3083             :                                   "49152-65535");
    3084             : 
    3085       12552 :         lpcfg_do_global_parameter(lp_ctx, "prefork children", "4");
    3086       12552 :         lpcfg_do_global_parameter(lp_ctx, "prefork backoff increment", "10");
    3087       12552 :         lpcfg_do_global_parameter(lp_ctx, "prefork maximum backoff", "120");
    3088             : 
    3089       12552 :         lpcfg_do_global_parameter(lp_ctx, "check parent directory delete on close", "no");
    3090             : 
    3091       12552 :         lpcfg_do_global_parameter(lp_ctx, "ea support", "yes");
    3092             : 
    3093       12552 :         lpcfg_do_global_parameter(lp_ctx, "store dos attributes", "yes");
    3094             : 
    3095       12552 :         lpcfg_do_global_parameter(lp_ctx, "debug encryption", "no");
    3096             : 
    3097       12552 :         lpcfg_do_global_parameter(lp_ctx, "spotlight backend", "noindex");
    3098             : 
    3099       12552 :         lpcfg_do_global_parameter(
    3100             :                 lp_ctx, "ldap max anonymous request size", "256000");
    3101       12552 :         lpcfg_do_global_parameter(
    3102             :                 lp_ctx, "ldap max authenticated request size", "16777216");
    3103       12552 :         lpcfg_do_global_parameter(
    3104             :                 lp_ctx, "ldap max search request size", "256000");
    3105             : 
    3106             :         /* Async DNS query timeout in seconds. */
    3107       12552 :         lpcfg_do_global_parameter(lp_ctx, "async dns timeout", "10");
    3108             : 
    3109       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3110             :                                   "client smb encrypt",
    3111             :                                   "default");
    3112             : 
    3113       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3114             :                                   "client use kerberos",
    3115             :                                   "desired");
    3116             : 
    3117       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3118             :                                   "client protection",
    3119             :                                   "default");
    3120             : 
    3121       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3122             :                                   "smbd max xattr size",
    3123             :                                   "65536");
    3124             : 
    3125       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3126             :                                   "acl flag inherited canonicalization",
    3127             :                                   "yes");
    3128             : 
    3129       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3130             :                                   "winbind use krb5 enterprise principals",
    3131             :                                   "yes");
    3132             : 
    3133       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3134             :                                   "client smb3 signing algorithms",
    3135             :                                   DEFAULT_SMB3_SIGNING_ALGORITHMS);
    3136       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3137             :                                   "server smb3 signing algorithms",
    3138             :                                   DEFAULT_SMB3_SIGNING_ALGORITHMS);
    3139             : 
    3140       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3141             :                                   "client smb3 encryption algorithms",
    3142             :                                   DEFAULT_SMB3_ENCRYPTION_ALGORITHMS);
    3143       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3144             :                                   "server smb3 encryption algorithms",
    3145             :                                   DEFAULT_SMB3_ENCRYPTION_ALGORITHMS);
    3146             : 
    3147       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3148             :                                   "min domain uid",
    3149             :                                   "1000");
    3150             : 
    3151       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3152             :                                   "rpc start on demand helpers",
    3153             :                                   "yes");
    3154             : 
    3155       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3156             :                                   "ad dc functional level",
    3157             :                                   "2008_R2");
    3158             : 
    3159       12552 :         lpcfg_do_global_parameter(lp_ctx,
    3160             :                                   "acl claims evaluation",
    3161             :                                   "AD DC only");
    3162             : 
    3163     6527656 :         for (i = 0; parm_table[i].label; i++) {
    3164     6514488 :                 if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
    3165     6514488 :                         lp_ctx->flags[i] |= FLAG_DEFAULT;
    3166             :                 }
    3167             :         }
    3168             : 
    3169       50208 :         for (parm=lp_ctx->globals->param_opt; parm; parm=parm->next) {
    3170       37656 :                 if (!(parm->priority & FLAG_CMDLINE)) {
    3171       37656 :                         parm->priority |= FLAG_DEFAULT;
    3172             :                 }
    3173             :         }
    3174             : 
    3175       12552 :         for (parm=lp_ctx->sDefault->param_opt; parm; parm=parm->next) {
    3176           0 :                 if (!(parm->priority & FLAG_CMDLINE)) {
    3177           0 :                         parm->priority |= FLAG_DEFAULT;
    3178             :                 }
    3179             :         }
    3180             : 
    3181       11936 :         return lp_ctx;
    3182             : }
    3183             : 
    3184             : /**
    3185             :  * Initialise the global parameter structure.
    3186             :  */
    3187       80402 : struct loadparm_context *loadparm_init_global(bool load_default)
    3188             : {
    3189       80402 :         if (global_loadparm_context == NULL) {
    3190       12381 :                 global_loadparm_context = loadparm_init(NULL);
    3191             :         }
    3192       80402 :         if (global_loadparm_context == NULL) {
    3193           0 :                 return NULL;
    3194             :         }
    3195       80402 :         global_loadparm_context->global = true;
    3196       80402 :         if (load_default && !global_loadparm_context->loaded) {
    3197         170 :                 lpcfg_load_default(global_loadparm_context);
    3198             :         }
    3199       80402 :         global_loadparm_context->refuse_free = true;
    3200       80402 :         return global_loadparm_context;
    3201             : }
    3202             : 
    3203             : /**
    3204             :  * @brief Initialise the global parameter structure.
    3205             :  *
    3206             :  * This function initialized the globals if needed. Make sure that
    3207             :  * gfree_loadparm() is called before the application exits.
    3208             :  *
    3209             :  * @param mem_ctx   The talloc memory context to allocate lp_ctx on.
    3210             :  *
    3211             :  * @param s3_fns    The loadparm helper functions to use
    3212             :  *
    3213             :  * @return An initialized lp_ctx pointer or NULL on error.
    3214             :  */
    3215      914769 : struct loadparm_context *loadparm_init_s3(TALLOC_CTX *mem_ctx,
    3216             :                                           const struct loadparm_s3_helpers *s3_fns)
    3217             : {
    3218      914769 :         struct loadparm_context *loadparm_context = talloc_zero(mem_ctx, struct loadparm_context);
    3219      914769 :         if (!loadparm_context) {
    3220           0 :                 return NULL;
    3221             :         }
    3222      914769 :         loadparm_context->s3_fns = s3_fns;
    3223      914769 :         loadparm_context->globals = s3_fns->globals;
    3224      914769 :         loadparm_context->flags = s3_fns->flags;
    3225             : 
    3226             :         /* Make sure globals are correctly initialized */
    3227      914769 :         loadparm_context->s3_fns->init_globals(loadparm_context, false);
    3228             : 
    3229      914769 :         return loadparm_context;
    3230             : }
    3231             : 
    3232      437950 : const char *lpcfg_configfile(struct loadparm_context *lp_ctx)
    3233             : {
    3234      437950 :         return lp_ctx->szConfigFile;
    3235             : }
    3236             : 
    3237      111148 : const char *lp_default_path(void)
    3238             : {
    3239      111148 :     if (getenv("SMB_CONF_PATH"))
    3240       95290 :         return getenv("SMB_CONF_PATH");
    3241             :     else
    3242       15858 :         return dyn_CONFIGFILE;
    3243             : }
    3244             : 
    3245             : /**
    3246             :  * Update the internal state of a loadparm context after settings
    3247             :  * have changed.
    3248             :  */
    3249       29307 : static bool lpcfg_update(struct loadparm_context *lp_ctx)
    3250             : {
    3251         681 :         struct debug_settings settings;
    3252         681 :         int max_protocol, min_protocol;
    3253         681 :         TALLOC_CTX *tmp_ctx;
    3254         681 :         const struct loadparm_substitution *lp_sub =
    3255       29307 :                 lpcfg_noop_substitution();
    3256             : 
    3257       29307 :         tmp_ctx = talloc_new(lp_ctx);
    3258       29307 :         if (tmp_ctx == NULL) {
    3259           0 :                 return false;
    3260             :         }
    3261             : 
    3262       29307 :         lpcfg_add_auto_services(lp_ctx, lpcfg_auto_services(lp_ctx, lp_sub, tmp_ctx));
    3263             : 
    3264       29307 :         if (!lp_ctx->globals->wins_server_list && lp_ctx->globals->we_are_a_wins_server) {
    3265        4487 :                 lpcfg_do_global_parameter(lp_ctx, "wins server", "127.0.0.1");
    3266             :         }
    3267             : 
    3268       29307 :         if (!lp_ctx->global) {
    3269         134 :                 TALLOC_FREE(tmp_ctx);
    3270         134 :                 return true;
    3271             :         }
    3272             : 
    3273       29173 :         panic_action = lp_ctx->globals->panic_action;
    3274             : 
    3275       29173 :         reload_charcnv(lp_ctx);
    3276             : 
    3277       29173 :         ZERO_STRUCT(settings);
    3278             :         /* Add any more debug-related smb.conf parameters created in
    3279             :          * future here */
    3280       29173 :         settings.timestamp_logs = lp_ctx->globals->timestamp_logs;
    3281       29173 :         settings.debug_prefix_timestamp = lp_ctx->globals->debug_prefix_timestamp;
    3282       29173 :         settings.debug_hires_timestamp = lp_ctx->globals->debug_hires_timestamp;
    3283       29173 :         settings.debug_syslog_format = lp_ctx->globals->debug_syslog_format;
    3284       29173 :         settings.debug_pid = lp_ctx->globals->debug_pid;
    3285       29173 :         settings.debug_uid = lp_ctx->globals->debug_uid;
    3286       29173 :         settings.debug_class = lp_ctx->globals->debug_class;
    3287       29173 :         settings.max_log_size = lp_ctx->globals->max_log_size;
    3288       29173 :         debug_set_settings(&settings, lp_ctx->globals->logging,
    3289       28500 :                            lp_ctx->globals->syslog,
    3290       29173 :                            lp_ctx->globals->syslog_only);
    3291             : 
    3292             :         /* FIXME: This is a bit of a hack, but we can't use a global, since
    3293             :          * not everything that uses lp also uses the socket library */
    3294       29173 :         if (lpcfg_parm_bool(lp_ctx, NULL, "socket", "testnonblock", false)) {
    3295         176 :                 setenv("SOCKET_TESTNONBLOCK", "1", 1);
    3296             :         } else {
    3297       28997 :                 unsetenv("SOCKET_TESTNONBLOCK");
    3298             :         }
    3299             : 
    3300             :         /* Check if command line max protocol < min protocol, if so
    3301             :          * report a warning to the user.
    3302             :          */
    3303       29173 :         max_protocol = lpcfg_client_max_protocol(lp_ctx);
    3304       29173 :         min_protocol = lpcfg_client_min_protocol(lp_ctx);
    3305       29173 :         if (lpcfg_client_max_protocol(lp_ctx) < lpcfg_client_min_protocol(lp_ctx)) {
    3306           0 :                 const char *max_protocolp, *min_protocolp;
    3307           0 :                 max_protocolp = lpcfg_get_smb_protocol(max_protocol);
    3308           0 :                 min_protocolp = lpcfg_get_smb_protocol(min_protocol);
    3309           0 :                 DBG_ERR("Max protocol %s is less than min protocol %s.\n",
    3310             :                         max_protocolp, min_protocolp);
    3311             :         }
    3312             : 
    3313       29173 :         TALLOC_FREE(tmp_ctx);
    3314       29173 :         return true;
    3315             : }
    3316             : 
    3317         257 : bool lpcfg_load_default(struct loadparm_context *lp_ctx)
    3318             : {
    3319          11 :     const char *path;
    3320             : 
    3321         257 :     path = lp_default_path();
    3322             : 
    3323         257 :     if (!file_exist(path)) {
    3324             :             /* We allow the default smb.conf file to not exist,
    3325             :              * basically the equivalent of an empty file. */
    3326           2 :             return lpcfg_update(lp_ctx);
    3327             :     }
    3328             : 
    3329         255 :     return lpcfg_load(lp_ctx, path);
    3330             : }
    3331             : 
    3332             : /**
    3333             :  * Load the services array from the services file.
    3334             :  *
    3335             :  * Return True on success, False on failure.
    3336             :  */
    3337       31705 : static bool lpcfg_load_internal(struct loadparm_context *lp_ctx,
    3338             :                                 const char *filename, bool set_global)
    3339             : {
    3340         739 :         char *n2;
    3341         739 :         bool bRetval;
    3342             : 
    3343       31705 :         if (lp_ctx->szConfigFile != NULL) {
    3344       18266 :                 talloc_free(discard_const_p(char, lp_ctx->szConfigFile));
    3345       18266 :                 lp_ctx->szConfigFile = NULL;
    3346             :         }
    3347             : 
    3348       31705 :         lp_ctx->szConfigFile = talloc_strdup(lp_ctx, filename);
    3349             : 
    3350       31705 :         if (lp_ctx->s3_fns) {
    3351        2270 :                 return lp_ctx->s3_fns->load(filename);
    3352             :         }
    3353             : 
    3354       29435 :         lp_ctx->bInGlobalSection = true;
    3355       29435 :         n2 = standard_sub_basic(lp_ctx, lp_ctx->szConfigFile);
    3356       29435 :         DEBUG(2, ("lpcfg_load: refreshing parameters from %s\n", n2));
    3357             : 
    3358       29435 :         add_to_file_list(lp_ctx, &lp_ctx->file_lists, lp_ctx->szConfigFile, n2);
    3359             : 
    3360             :         /* We get sections first, so have to start 'behind' to make up */
    3361       29435 :         lp_ctx->currentService = NULL;
    3362       29435 :         bRetval = pm_process(n2, do_section, lpcfg_do_parameter, lp_ctx);
    3363             : 
    3364             :         /* finish up the last section */
    3365       29435 :         DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
    3366       29435 :         if (bRetval)
    3367       29305 :                 if (lp_ctx->currentService != NULL)
    3368       18132 :                         bRetval = lpcfg_service_ok(lp_ctx->currentService);
    3369             : 
    3370       29435 :         bRetval = bRetval && lpcfg_update(lp_ctx);
    3371             : 
    3372             :         /* we do this unconditionally, so that it happens even
    3373             :            for a missing smb.conf */
    3374       29435 :         reload_charcnv(lp_ctx);
    3375             : 
    3376       29435 :         if (bRetval == true && set_global) {
    3377             :                 /* set this up so that any child python tasks will
    3378             :                    find the right smb.conf */
    3379       29199 :                 setenv("SMB_CONF_PATH", filename, 1);
    3380             : 
    3381             :                 /* set the context used by the lp_*() function
    3382             :                    variants */
    3383       29199 :                 global_loadparm_context = lp_ctx;
    3384       29199 :                 lp_ctx->loaded = true;
    3385             :         }
    3386             : 
    3387       28747 :         return bRetval;
    3388             : }
    3389             : 
    3390         108 : bool lpcfg_load_no_global(struct loadparm_context *lp_ctx, const char *filename)
    3391             : {
    3392         108 :     return lpcfg_load_internal(lp_ctx, filename, false);
    3393             : }
    3394             : 
    3395       31597 : bool lpcfg_load(struct loadparm_context *lp_ctx, const char *filename)
    3396             : {
    3397       31597 :     return lpcfg_load_internal(lp_ctx, filename, true);
    3398             : }
    3399             : 
    3400             : /**
    3401             :  * Return the max number of services.
    3402             :  */
    3403             : 
    3404        5351 : int lpcfg_numservices(struct loadparm_context *lp_ctx)
    3405             : {
    3406        5351 :         if (lp_ctx->s3_fns) {
    3407           6 :                 return lp_ctx->s3_fns->get_numservices();
    3408             :         }
    3409             : 
    3410        5345 :         return lp_ctx->iNumServices;
    3411             : }
    3412             : 
    3413             : /**
    3414             :  * Display the contents of the services array in human-readable form.
    3415             :  */
    3416             : 
    3417         769 : void lpcfg_dump(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults,
    3418             :              int maxtoprint)
    3419             : {
    3420          25 :         int iService;
    3421             : 
    3422         769 :         if (lp_ctx->s3_fns) {
    3423           0 :                 lp_ctx->s3_fns->dump(f, show_defaults, maxtoprint);
    3424           0 :                 return;
    3425             :         }
    3426             : 
    3427         769 :         lpcfg_dump_globals(lp_ctx, f, show_defaults);
    3428             : 
    3429         769 :         lpcfg_dump_a_service(lp_ctx->sDefault, lp_ctx->sDefault, f, lp_ctx->flags, show_defaults);
    3430             : 
    3431        3873 :         for (iService = 0; iService < maxtoprint; iService++)
    3432        3079 :                 lpcfg_dump_one(f, show_defaults, lp_ctx->services[iService], lp_ctx->sDefault);
    3433             : }
    3434             : 
    3435             : /**
    3436             :  * Display the contents of one service in human-readable form.
    3437             :  */
    3438        3080 : void lpcfg_dump_one(FILE *f, bool show_defaults, struct loadparm_service *service, struct loadparm_service *sDefault)
    3439             : {
    3440        3080 :         if (service != NULL) {
    3441        3080 :                 if (service->szService[0] == '\0')
    3442           0 :                         return;
    3443        3080 :                 lpcfg_dump_a_service(service, sDefault, f, NULL, show_defaults);
    3444             :         }
    3445             : }
    3446             : 
    3447        5206 : struct loadparm_service *lpcfg_servicebynum(struct loadparm_context *lp_ctx,
    3448             :                                             int snum)
    3449             : {
    3450        5206 :         if (lp_ctx->s3_fns) {
    3451           0 :                 return lp_ctx->s3_fns->get_servicebynum(snum);
    3452             :         }
    3453             : 
    3454        5206 :         return lp_ctx->services[snum];
    3455             : }
    3456             : 
    3457        8907 : struct loadparm_service *lpcfg_service(struct loadparm_context *lp_ctx,
    3458             :                                     const char *service_name)
    3459             : {
    3460         260 :         int iService;
    3461         260 :         char *serviceName;
    3462             : 
    3463        8907 :         if (lp_ctx->s3_fns) {
    3464           3 :                 return lp_ctx->s3_fns->get_service(service_name);
    3465             :         }
    3466             : 
    3467       71575 :         for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--) {
    3468       71476 :                 if (lp_ctx->services[iService] &&
    3469       71476 :                     lp_ctx->services[iService]->szService) {
    3470             :                         /*
    3471             :                          * The substitution here is used to support %U is
    3472             :                          * service names
    3473             :                          */
    3474       71476 :                         serviceName = standard_sub_basic(
    3475       69070 :                                         lp_ctx->services[iService],
    3476       69070 :                                         lp_ctx->services[iService]->szService);
    3477       71476 :                         if (strequal(serviceName, service_name)) {
    3478        8805 :                                 talloc_free(serviceName);
    3479        8805 :                                 return lp_ctx->services[iService];
    3480             :                         }
    3481       62671 :                         talloc_free(serviceName);
    3482             :                 }
    3483             :         }
    3484             : 
    3485          99 :         DEBUG(7,("lpcfg_servicenumber: couldn't find %s\n", service_name));
    3486          89 :         return NULL;
    3487             : }
    3488             : 
    3489        8704 : const char *lpcfg_servicename(const struct loadparm_service *service)
    3490             : {
    3491        8704 :         return service ? lpcfg_string((const char *)service->szService) : NULL;
    3492             : }
    3493             : 
    3494     2095240 : struct smb_iconv_handle *lpcfg_iconv_handle(struct loadparm_context *lp_ctx)
    3495             : {
    3496     2095240 :         if (lp_ctx == NULL) {
    3497           0 :                 return get_iconv_handle();
    3498             :         }
    3499     2095240 :         return lp_ctx->iconv_handle;
    3500             : }
    3501             : 
    3502       76424 : _PUBLIC_ void reload_charcnv(struct loadparm_context *lp_ctx)
    3503             : {
    3504       76424 :         if (!lp_ctx->global) {
    3505         126 :                 return;
    3506             :         }
    3507             : 
    3508       77768 :         lp_ctx->iconv_handle =
    3509       76288 :                 reinit_iconv_handle(lp_ctx,
    3510             :                                     lpcfg_dos_charset(lp_ctx),
    3511             :                                     lpcfg_unix_charset(lp_ctx));
    3512       76288 :         if (lp_ctx->iconv_handle == NULL) {
    3513           0 :                 smb_panic("reinit_iconv_handle failed");
    3514             :         }
    3515             : }
    3516             : 
    3517          62 : _PUBLIC_ char *lpcfg_tls_keyfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3518             : {
    3519          62 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_keyfile(lp_ctx));
    3520             : }
    3521             : 
    3522          62 : _PUBLIC_ char *lpcfg_tls_certfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3523             : {
    3524          62 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_certfile(lp_ctx));
    3525             : }
    3526             : 
    3527         539 : _PUBLIC_ char *lpcfg_tls_cafile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3528             : {
    3529         539 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_cafile(lp_ctx));
    3530             : }
    3531             : 
    3532         539 : _PUBLIC_ char *lpcfg_tls_crlfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3533             : {
    3534         539 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_crlfile(lp_ctx));
    3535             : }
    3536             : 
    3537          62 : _PUBLIC_ char *lpcfg_tls_dhpfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3538             : {
    3539          62 :         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_dhpfile(lp_ctx));
    3540             : }
    3541             : 
    3542      312891 : struct gensec_settings *lpcfg_gensec_settings(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    3543             : {
    3544      312891 :         struct gensec_settings *settings = talloc_zero(mem_ctx, struct gensec_settings);
    3545      312891 :         if (settings == NULL)
    3546           0 :                 return NULL;
    3547      312891 :         SMB_ASSERT(lp_ctx != NULL);
    3548      312891 :         settings->lp_ctx = talloc_reference(settings, lp_ctx);
    3549      312891 :         settings->target_hostname = lpcfg_parm_string(lp_ctx, NULL, "gensec", "target_hostname");
    3550      312891 :         return settings;
    3551             : }
    3552             : 
    3553      693811 : int lpcfg_server_role(struct loadparm_context *lp_ctx)
    3554             : {
    3555      693811 :         int domain_master = lpcfg__domain_master(lp_ctx);
    3556             : 
    3557     1367486 :         return lp_find_server_role(lpcfg__server_role(lp_ctx),
    3558             :                                    lpcfg__security(lp_ctx),
    3559      693811 :                                    lpcfg__domain_logons(lp_ctx),
    3560       20136 :                                    (domain_master == true) ||
    3561             :                                    (domain_master == Auto));
    3562             : }
    3563             : 
    3564       67272 : int lpcfg_security(struct loadparm_context *lp_ctx)
    3565             : {
    3566       67272 :         return lp_find_security(lpcfg__server_role(lp_ctx),
    3567             :                                 lpcfg__security(lp_ctx));
    3568             : }
    3569             : 
    3570       58346 : int lpcfg_client_max_protocol(struct loadparm_context *lp_ctx)
    3571             : {
    3572       58346 :         int client_max_protocol = lpcfg__client_max_protocol(lp_ctx);
    3573       58346 :         if (client_max_protocol == PROTOCOL_DEFAULT) {
    3574       58326 :                 return PROTOCOL_LATEST;
    3575             :         }
    3576          20 :         return client_max_protocol;
    3577             : }
    3578             : 
    3579        6511 : int lpcfg_client_ipc_min_protocol(struct loadparm_context *lp_ctx)
    3580             : {
    3581        6511 :         int client_ipc_min_protocol = lpcfg__client_ipc_min_protocol(lp_ctx);
    3582        6511 :         if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
    3583        6503 :                 client_ipc_min_protocol = lpcfg_client_min_protocol(lp_ctx);
    3584             :         }
    3585        6511 :         if (client_ipc_min_protocol < PROTOCOL_NT1) {
    3586        5776 :                 return PROTOCOL_NT1;
    3587             :         }
    3588         345 :         return client_ipc_min_protocol;
    3589             : }
    3590             : 
    3591        6511 : int lpcfg_client_ipc_max_protocol(struct loadparm_context *lp_ctx)
    3592             : {
    3593        6511 :         int client_ipc_max_protocol = lpcfg__client_ipc_max_protocol(lp_ctx);
    3594        6511 :         if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
    3595        6109 :                 return PROTOCOL_LATEST;
    3596             :         }
    3597          12 :         if (client_ipc_max_protocol < PROTOCOL_NT1) {
    3598           0 :                 return PROTOCOL_NT1;
    3599             :         }
    3600          12 :         return client_ipc_max_protocol;
    3601             : }
    3602             : 
    3603      305275 : int lpcfg_client_ipc_signing(struct loadparm_context *lp_ctx)
    3604             : {
    3605      305275 :         int client_ipc_signing = lpcfg__client_ipc_signing(lp_ctx);
    3606      305275 :         if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
    3607      305275 :                 return SMB_SIGNING_REQUIRED;
    3608             :         }
    3609           0 :         return client_ipc_signing;
    3610             : }
    3611             : 
    3612      223308 : enum credentials_use_kerberos lpcfg_client_use_kerberos(struct loadparm_context *lp_ctx)
    3613             : {
    3614      223308 :         if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
    3615           5 :                 return CRED_USE_KERBEROS_REQUIRED;
    3616             :         }
    3617             : 
    3618      223303 :         return lpcfg__client_use_kerberos(lp_ctx);
    3619             : }
    3620             : 
    3621       71168 : bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandatory)
    3622             : {
    3623       71168 :         bool allowed = true;
    3624       71168 :         enum smb_signing_setting signing_setting = lpcfg_server_signing(lp_ctx);
    3625             : 
    3626       71168 :         *mandatory = false;
    3627             : 
    3628       71168 :         if (signing_setting == SMB_SIGNING_DEFAULT) {
    3629             :                 /*
    3630             :                  * If we are a domain controller, SMB signing is
    3631             :                  * really important, as it can prevent a number of
    3632             :                  * attacks on communications between us and the
    3633             :                  * clients
    3634             :                  *
    3635             :                  * However, it really sucks (no sendfile, CPU
    3636             :                  * overhead) performance-wise when used on a
    3637             :                  * file server, so disable it by default
    3638             :                  * on non-DCs
    3639             :                  */
    3640             : 
    3641       70104 :                 if (lpcfg_server_role(lp_ctx) >= ROLE_ACTIVE_DIRECTORY_DC) {
    3642       20234 :                         signing_setting = SMB_SIGNING_REQUIRED;
    3643             :                 } else {
    3644       48082 :                         signing_setting = SMB_SIGNING_OFF;
    3645             :                 }
    3646             :         }
    3647             : 
    3648       69380 :         switch (signing_setting) {
    3649       22952 :         case SMB_SIGNING_REQUIRED:
    3650       22952 :                 *mandatory = true;
    3651       22952 :                 break;
    3652         134 :         case SMB_SIGNING_DESIRED:
    3653             :         case SMB_SIGNING_IF_REQUIRED:
    3654         134 :                 break;
    3655       48082 :         case SMB_SIGNING_OFF:
    3656       48082 :                 allowed = false;
    3657       48082 :                 break;
    3658           0 :         case SMB_SIGNING_DEFAULT:
    3659             :         case SMB_SIGNING_IPC_DEFAULT:
    3660           0 :                 smb_panic(__location__);
    3661        1788 :                 break;
    3662             :         }
    3663             : 
    3664       71168 :         return allowed;
    3665             : }
    3666             : 
    3667      340349 : int lpcfg_tdb_hash_size(struct loadparm_context *lp_ctx, const char *name)
    3668             : {
    3669       12007 :         const char *base;
    3670             : 
    3671      340349 :         if (name == NULL) {
    3672           0 :                 return 0;
    3673             :         }
    3674             : 
    3675      340349 :         base = strrchr_m(name, '/');
    3676      340349 :         if (base != NULL) {
    3677      340343 :                 base += 1;
    3678             :         } else {
    3679           0 :                 base = name;
    3680             :         }
    3681      340349 :         return lpcfg_parm_int(lp_ctx, NULL, "tdb_hashsize", base, 0);
    3682             : 
    3683             : }
    3684             : 
    3685     1108023 : int lpcfg_tdb_flags(struct loadparm_context *lp_ctx, int tdb_flags)
    3686             : {
    3687     1108023 :         if (!lpcfg_use_mmap(lp_ctx)) {
    3688           0 :                 tdb_flags |= TDB_NOMMAP;
    3689             :         }
    3690     1108023 :         return tdb_flags;
    3691             : }
    3692             : 
    3693             : /*
    3694             :  * Do not allow LanMan auth if unless NTLMv1 is also allowed
    3695             :  *
    3696             :  * This also ensures it is disabled if NTLM is totally disabled
    3697             :  */
    3698       80867 : bool lpcfg_lanman_auth(struct loadparm_context *lp_ctx)
    3699             : {
    3700       80867 :         enum ntlm_auth_level ntlm_auth_level = lpcfg_ntlm_auth(lp_ctx);
    3701             : 
    3702       80867 :         if (ntlm_auth_level == NTLM_AUTH_ON) {
    3703       35928 :                 return lpcfg__lanman_auth(lp_ctx);
    3704             :         } else {
    3705       44939 :                 return false;
    3706             :         }
    3707             : }
    3708             : 
    3709       47095 : static char *lpcfg_noop_substitution_fn(
    3710             :                         TALLOC_CTX *mem_ctx,
    3711             :                         const struct loadparm_substitution *lp_sub,
    3712             :                         const char *raw_value,
    3713             :                         void *private_data)
    3714             : {
    3715       47095 :         return talloc_strdup(mem_ctx, raw_value);
    3716             : }
    3717             : 
    3718             : static const struct loadparm_substitution global_noop_substitution = {
    3719             :         .substituted_string_fn = lpcfg_noop_substitution_fn,
    3720             : };
    3721             : 
    3722       47371 : const struct loadparm_substitution *lpcfg_noop_substitution(void)
    3723             : {
    3724       47371 :         return &global_noop_substitution;
    3725             : }
    3726             : 
    3727     2876686 : char *lpcfg_substituted_string(TALLOC_CTX *mem_ctx,
    3728             :                                const struct loadparm_substitution *lp_sub,
    3729             :                                const char *raw_value)
    3730             : {
    3731     5753372 :         return lp_sub->substituted_string_fn(mem_ctx,
    3732             :                                              lp_sub,
    3733             :                                              raw_value,
    3734     2876686 :                                              lp_sub->private_data);
    3735             : }
    3736             : 
    3737             : /**
    3738             :  * @brief Parse a string value of a given parameter to its integer enum value.
    3739             :  *
    3740             :  * @param[in]  param_name    The parameter name (e.g. 'client smb encrypt')
    3741             :  *
    3742             :  * @param[in]  param_value   The parameter value (e.g. 'required').
    3743             :  *
    3744             :  * @return The integer value of the enum the param_value matches or INT32_MIN
    3745             :  * on error.
    3746             :  */
    3747         214 : int32_t lpcfg_parse_enum_vals(const char *param_name,
    3748             :                               const char *param_value)
    3749             : {
    3750         214 :         struct parm_struct *parm = NULL;
    3751         214 :         int32_t ret = INT32_MIN;
    3752           8 :         bool ok;
    3753             : 
    3754         214 :         parm = lpcfg_parm_struct(NULL, param_name);
    3755         214 :         if (parm == NULL) {
    3756           0 :                 return INT32_MIN;
    3757             :         }
    3758             : 
    3759         214 :         ok = lp_set_enum_parm(parm, param_value, &ret);
    3760         214 :         if (!ok) {
    3761           0 :                 return INT32_MIN;
    3762             :         }
    3763             : 
    3764         212 :         return ret;
    3765             : }

Generated by: LCOV version 1.14