LCOV - code coverage report
Current view: top level - source3/param - loadparm.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 1517 2071 73.2 %
Date: 2024-05-31 13:13:24 Functions: 136 157 86.6 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Parameter loading functions
       4             :    Copyright (C) Karl Auer 1993-1998
       5             : 
       6             :    Largely re-written by Andrew Tridgell, September 1994
       7             : 
       8             :    Copyright (C) Simo Sorce 2001
       9             :    Copyright (C) Alexander Bokovoy 2002
      10             :    Copyright (C) Stefan (metze) Metzmacher 2002
      11             :    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
      12             :    Copyright (C) Michael Adam 2008
      13             :    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
      14             :    Copyright (C) Andrew Bartlett 2011
      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             : #define LOADPARM_SUBSTITUTION_INTERNALS 1
      57             : #include "includes.h"
      58             : #include "lib/util/util_file.h"
      59             : #include "system/filesys.h"
      60             : #include "util_tdb.h"
      61             : #include "lib/param/loadparm.h"
      62             : #include "lib/param/param.h"
      63             : #include "printing.h"
      64             : #include "lib/smbconf/smbconf.h"
      65             : #include "lib/smbconf/smbconf_init.h"
      66             : 
      67             : #include "include/smb_ldap.h"
      68             : #include "../librpc/gen_ndr/svcctl.h"
      69             : #include "intl.h"
      70             : #include "../libcli/smb/smb_signing.h"
      71             : #include "dbwrap/dbwrap.h"
      72             : #include "dbwrap/dbwrap_rbt.h"
      73             : #include "../lib/util/bitmap.h"
      74             : #include "librpc/gen_ndr/nbt.h"
      75             : #include "librpc/gen_ndr/dns.h"
      76             : #include "source4/lib/tls/tls.h"
      77             : #include "libcli/auth/ntlm_check.h"
      78             : #include "lib/crypto/gnutls_helpers.h"
      79             : #include "lib/util/string_wrappers.h"
      80             : #include "auth/credentials/credentials.h"
      81             : #include "source3/lib/substitute.h"
      82             : #include "source3/librpc/gen_ndr/ads.h"
      83             : #include "lib/util/time_basic.h"
      84             : #include "libds/common/flags.h"
      85             : 
      86             : #ifdef HAVE_SYS_SYSCTL_H
      87             : #include <sys/sysctl.h>
      88             : #endif
      89             : 
      90             : bool b_loaded = false;
      91             : 
      92             : /* the special value for the include parameter
      93             :  * to be interpreted not as a file name but to
      94             :  * trigger loading of the global smb.conf options
      95             :  * from registry. */
      96             : #ifndef INCLUDE_REGISTRY_NAME
      97             : #define INCLUDE_REGISTRY_NAME "registry"
      98             : #endif
      99             : 
     100             : static bool in_client = false;          /* Not in the client by default */
     101             : static struct smbconf_csn conf_last_csn;
     102             : 
     103             : static int config_backend = CONFIG_BACKEND_FILE;
     104             : 
     105             : /* some helpful bits */
     106             : #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && \
     107             :                        (ServicePtrs != NULL) && \
     108             :                        (ServicePtrs[(i)] != NULL) && ServicePtrs[(i)]->valid)
     109             : #define VALID(i) ((ServicePtrs != NULL) && (ServicePtrs[i]!= NULL) && \
     110             :                   ServicePtrs[i]->valid)
     111             : 
     112             : #define USERSHARE_VALID 1
     113             : #define USERSHARE_PENDING_DELETE 2
     114             : 
     115             : static bool defaults_saved = false;
     116             : 
     117             : #include "lib/param/param_global.h"
     118             : 
     119             : static struct loadparm_global Globals;
     120             : 
     121             : /* This is a default service used to prime a services structure */
     122             : static const struct loadparm_service _sDefault =
     123             : {
     124             :         .valid = true,
     125             :         .autoloaded = false,
     126             :         .usershare = 0,
     127             :         .usershare_last_mod = {0, 0},
     128             :         .szService = NULL,
     129             :         .path = NULL,
     130             :         .invalid_users = NULL,
     131             :         .valid_users = NULL,
     132             :         .admin_users = NULL,
     133             :         .copy = NULL,
     134             :         .include = NULL,
     135             :         .preexec = NULL,
     136             :         .postexec = NULL,
     137             :         .root_preexec = NULL,
     138             :         .root_postexec = NULL,
     139             :         .cups_options = NULL,
     140             :         .print_command = NULL,
     141             :         .lpq_command = NULL,
     142             :         .lprm_command = NULL,
     143             :         .lppause_command = NULL,
     144             :         .lpresume_command = NULL,
     145             :         .queuepause_command = NULL,
     146             :         .queueresume_command = NULL,
     147             :         ._printername = NULL,
     148             :         .printjob_username = NULL,
     149             :         .dont_descend = NULL,
     150             :         .hosts_allow = NULL,
     151             :         .hosts_deny = NULL,
     152             :         .magic_script = NULL,
     153             :         .magic_output = NULL,
     154             :         .veto_files = NULL,
     155             :         .hide_files = NULL,
     156             :         .veto_oplock_files = NULL,
     157             :         .comment = NULL,
     158             :         .force_user = NULL,
     159             :         .force_group = NULL,
     160             :         .read_list = NULL,
     161             :         .write_list = NULL,
     162             :         .volume = NULL,
     163             :         .fstype = NULL,
     164             :         .vfs_objects = NULL,
     165             :         .msdfs_proxy = NULL,
     166             :         .aio_write_behind = NULL,
     167             :         .dfree_command = NULL,
     168             :         .min_print_space = 0,
     169             :         .max_print_jobs = 1000,
     170             :         .max_reported_print_jobs = 0,
     171             :         .create_mask = 0744,
     172             :         .force_create_mode = 0,
     173             :         .directory_mask = 0755,
     174             :         .force_directory_mode = 0,
     175             :         .max_connections = 0,
     176             :         .default_case = CASE_LOWER,
     177             :         .printing = DEFAULT_PRINTING,
     178             :         .csc_policy = 0,
     179             :         .block_size = 1024,
     180             :         .dfree_cache_time = 0,
     181             :         .preexec_close = false,
     182             :         .root_preexec_close = false,
     183             :         .case_sensitive = Auto,
     184             :         .preserve_case = true,
     185             :         .short_preserve_case = true,
     186             :         .hide_dot_files = true,
     187             :         .hide_special_files = false,
     188             :         .hide_unreadable = false,
     189             :         .hide_unwriteable_files = false,
     190             :         .browseable = true,
     191             :         .access_based_share_enum = false,
     192             :         .available = true,
     193             :         .read_only = true,
     194             :         .spotlight = false,
     195             :         .guest_only = false,
     196             :         .administrative_share = false,
     197             :         .guest_ok = false,
     198             :         .printable = false,
     199             :         .print_notify_backchannel = false,
     200             :         .map_system = false,
     201             :         .map_hidden = false,
     202             :         .map_archive = true,
     203             :         .store_dos_attributes = true,
     204             :         .smbd_max_xattr_size = 65536,
     205             :         .dmapi_support = false,
     206             :         .locking = true,
     207             :         .strict_locking = Auto,
     208             :         .posix_locking = true,
     209             :         .oplocks = true,
     210             :         .kernel_oplocks = false,
     211             :         .level2_oplocks = true,
     212             :         .mangled_names = MANGLED_NAMES_ILLEGAL,
     213             :         .wide_links = false,
     214             :         .follow_symlinks = true,
     215             :         .sync_always = false,
     216             :         .strict_allocate = false,
     217             :         .strict_rename = false,
     218             :         .strict_sync = true,
     219             :         .mangling_char = '~',
     220             :         .copymap = NULL,
     221             :         .delete_readonly = false,
     222             :         .fake_oplocks = false,
     223             :         .delete_veto_files = false,
     224             :         .dos_filemode = false,
     225             :         .dos_filetimes = true,
     226             :         .dos_filetime_resolution = false,
     227             :         .fake_directory_create_times = false,
     228             :         .blocking_locks = true,
     229             :         .inherit_permissions = false,
     230             :         .inherit_acls = false,
     231             :         .inherit_owner = false,
     232             :         .msdfs_root = false,
     233             :         .msdfs_shuffle_referrals = false,
     234             :         .use_client_driver = false,
     235             :         .default_devmode = true,
     236             :         .force_printername = false,
     237             :         .nt_acl_support = true,
     238             :         .force_unknown_acl_user = false,
     239             :         ._use_sendfile = false,
     240             :         .map_acl_inherit = false,
     241             :         .afs_share = false,
     242             :         .ea_support = true,
     243             :         .acl_check_permissions = true,
     244             :         .acl_map_full_control = true,
     245             :         .acl_group_control = false,
     246             :         .acl_allow_execute_always = false,
     247             :         .acl_flag_inherited_canonicalization = true,
     248             :         .aio_read_size = 1,
     249             :         .aio_write_size = 1,
     250             :         .map_readonly = MAP_READONLY_NO,
     251             :         .server_smb_encrypt = SMB_ENCRYPTION_DEFAULT,
     252             :         .kernel_share_modes = false,
     253             :         .durable_handles = true,
     254             :         .check_parent_directory_delete_on_close = false,
     255             :         .param_opt = NULL,
     256             :         .smbd_search_ask_sharemode = true,
     257             :         .smbd_getinfo_ask_sharemode = true,
     258             :         .spotlight_backend = SPOTLIGHT_BACKEND_NOINDEX,
     259             :         .honor_change_notify_privilege = false,
     260             :         .volume_serial_number = -1,
     261             :         .dummy = ""
     262             : };
     263             : 
     264             : /*
     265             :  * This is a copy of the default service structure. Service options in the
     266             :  * global section would otherwise overwrite the initial default values.
     267             :  */
     268             : static struct loadparm_service sDefault;
     269             : 
     270             : /* local variables */
     271             : static struct loadparm_service **ServicePtrs = NULL;
     272             : static int iNumServices = 0;
     273             : static int iServiceIndex = 0;
     274             : static struct db_context *ServiceHash;
     275             : static bool bInGlobalSection = true;
     276             : static bool bGlobalOnly = false;
     277             : static struct file_lists *file_lists = NULL;
     278             : static unsigned int *flags_list = NULL;
     279             : 
     280             : static void set_allowed_client_auth(void);
     281             : 
     282             : static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
     283             : static void free_param_opts(struct parmlist_entry **popts);
     284             : 
     285             : /**
     286             :  *  Function to return the default value for the maximum number of open
     287             :  *  file descriptors permitted.  This function tries to consult the
     288             :  *  kernel-level (sysctl) and ulimit (getrlimit()) values and goes
     289             :  *  the smaller of those.
     290             :  */
     291       88683 : static int max_open_files(void)
     292             : {
     293       88683 :         int sysctl_max = MAX_OPEN_FILES;
     294       88683 :         int rlimit_max = MAX_OPEN_FILES;
     295             : 
     296             : #ifdef HAVE_SYSCTLBYNAME
     297             :         {
     298             :                 size_t size = sizeof(sysctl_max);
     299             :                 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
     300             :                              0);
     301             :         }
     302             : #endif
     303             : 
     304             : #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
     305             :         {
     306         213 :                 struct rlimit rl;
     307             : 
     308       88683 :                 ZERO_STRUCT(rl);
     309             : 
     310       88683 :                 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
     311       88683 :                         rlimit_max = rl.rlim_cur;
     312             : 
     313             : #if defined(RLIM_INFINITY)
     314       88683 :                 if(rl.rlim_cur == RLIM_INFINITY)
     315           0 :                         rlimit_max = MAX_OPEN_FILES;
     316             : #endif
     317             :         }
     318             : #endif
     319             : 
     320       88683 :         if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
     321           0 :                 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
     322             :                         "minimum Windows limit (%d)\n",
     323             :                         sysctl_max,
     324             :                         MIN_OPEN_FILES_WINDOWS));
     325           0 :                 sysctl_max = MIN_OPEN_FILES_WINDOWS;
     326             :         }
     327             : 
     328       88683 :         if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
     329         733 :                 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
     330             :                         "minimum Windows limit (%d)\n",
     331             :                         rlimit_max,
     332             :                         MIN_OPEN_FILES_WINDOWS));
     333         733 :                 rlimit_max = MIN_OPEN_FILES_WINDOWS;
     334             :         }
     335             : 
     336       88683 :         return MIN(sysctl_max, rlimit_max);
     337             : }
     338             : 
     339             : /**
     340             :  * Common part of freeing allocated data for one parameter.
     341             :  */
     342    56618767 : static void free_one_parameter_common(void *parm_ptr,
     343             :                                       struct parm_struct parm)
     344             : {
     345    56618767 :         if ((parm.type == P_STRING) ||
     346    42252549 :             (parm.type == P_USTRING))
     347             :         {
     348    14533505 :                 lpcfg_string_free((char**)parm_ptr);
     349    42085262 :         } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
     350     4811391 :                 TALLOC_FREE(*((char***)parm_ptr));
     351             :         }
     352    56618767 : }
     353             : 
     354             : /**
     355             :  * Free the allocated data for one parameter for a share
     356             :  * given as a service struct.
     357             :  */
     358    73350027 : static void free_one_parameter(struct loadparm_service *service,
     359             :                                struct parm_struct parm)
     360             : {
     361           0 :         void *parm_ptr;
     362             : 
     363    73350027 :         if (parm.p_class != P_LOCAL) {
     364    51246468 :                 return;
     365             :         }
     366             : 
     367    22103559 :         parm_ptr = lp_parm_ptr(service, &parm);
     368             : 
     369    22103559 :         free_one_parameter_common(parm_ptr, parm);
     370             : }
     371             : 
     372             : /**
     373             :  * Free the allocated parameter data of a share given
     374             :  * as a service struct.
     375             :  */
     376      140787 : static void free_parameters(struct loadparm_service *service)
     377             : {
     378           0 :         uint32_t i;
     379             : 
     380    73490814 :         for (i=0; parm_table[i].label; i++) {
     381    73350027 :                 free_one_parameter(service, parm_table[i]);
     382             :         }
     383      140787 : }
     384             : 
     385             : /**
     386             :  * Free the allocated data for one parameter for a given share
     387             :  * specified by an snum.
     388             :  */
     389    34515208 : static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
     390             : {
     391       43243 :         void *parm_ptr;
     392             : 
     393    34515208 :         if (snum < 0) {
     394    34515208 :                 parm_ptr = lp_parm_ptr(NULL, &parm);
     395           0 :         } else if (parm.p_class != P_LOCAL) {
     396           0 :                 return;
     397             :         } else {
     398           0 :                 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
     399             :         }
     400             : 
     401    34515208 :         free_one_parameter_common(parm_ptr, parm);
     402             : }
     403             : 
     404             : /**
     405             :  * Free the allocated parameter data for a share specified
     406             :  * by an snum.
     407             :  */
     408       66248 : static void free_parameters_by_snum(int snum)
     409             : {
     410          83 :         uint32_t i;
     411             : 
     412    34581456 :         for (i=0; parm_table[i].label; i++) {
     413    34515208 :                 free_one_parameter_by_snum(snum, parm_table[i]);
     414             :         }
     415       66248 : }
     416             : 
     417             : /**
     418             :  * Free the allocated global parameters.
     419             :  */
     420       66248 : static void free_global_parameters(void)
     421             : {
     422          83 :         uint32_t i;
     423          83 :         struct parm_struct *parm;
     424             : 
     425       66248 :         free_param_opts(&Globals.param_opt);
     426       66248 :         free_parameters_by_snum(GLOBAL_SECTION_SNUM);
     427             : 
     428             :         /* Reset references in the defaults because the context is going to be freed */
     429    34581539 :         for (i=0; parm_table[i].label; i++) {
     430    34515208 :                 parm = &parm_table[i];
     431    34515208 :                 if ((parm->type == P_STRING) ||
     432    25076535 :                     (parm->type == P_USTRING)) {
     433     9605960 :                         if ((parm->def.svalue != NULL) &&
     434      264321 :                             (*(parm->def.svalue) != '\0')) {
     435       80090 :                                 if (talloc_parent(parm->def.svalue) == Globals.ctx) {
     436       80090 :                                         parm->def.svalue = NULL;
     437             :                                 }
     438             :                         }
     439             :                 }
     440             :         }
     441       66248 :         TALLOC_FREE(Globals.ctx);
     442       66248 : }
     443             : 
     444             : struct lp_stored_option {
     445             :         struct lp_stored_option *prev, *next;
     446             :         const char *label;
     447             :         const char *value;
     448             : };
     449             : 
     450             : static struct lp_stored_option *stored_options;
     451             : 
     452             : /*
     453             :   save options set by lp_set_cmdline() into a list. This list is
     454             :   re-applied when we do a globals reset, so that cmdline set options
     455             :   are sticky across reloads of smb.conf
     456             :  */
     457       32012 : bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
     458             : {
     459          82 :         struct lp_stored_option *entry, *entry_next;
     460       43792 :         for (entry = stored_options; entry != NULL; entry = entry_next) {
     461       12552 :                 entry_next = entry->next;
     462       12552 :                 if (strcmp(pszParmName, entry->label) == 0) {
     463         772 :                         DLIST_REMOVE(stored_options, entry);
     464         772 :                         talloc_free(entry);
     465         772 :                         break;
     466             :                 }
     467             :         }
     468             : 
     469       32012 :         entry = talloc(NULL, struct lp_stored_option);
     470       32012 :         if (!entry) {
     471           0 :                 return false;
     472             :         }
     473             : 
     474       32012 :         entry->label = talloc_strdup(entry, pszParmName);
     475       32012 :         if (!entry->label) {
     476           0 :                 talloc_free(entry);
     477           0 :                 return false;
     478             :         }
     479             : 
     480       32012 :         entry->value = talloc_strdup(entry, pszParmValue);
     481       32012 :         if (!entry->value) {
     482           0 :                 talloc_free(entry);
     483           0 :                 return false;
     484             :         }
     485             : 
     486       32012 :         DLIST_ADD_END(stored_options, entry);
     487             : 
     488       31930 :         return true;
     489             : }
     490             : 
     491       91133 : static bool apply_lp_set_cmdline(void)
     492             : {
     493       91133 :         struct lp_stored_option *entry = NULL;
     494      147866 :         for (entry = stored_options; entry != NULL; entry = entry->next) {
     495       56733 :                 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
     496           0 :                         DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
     497             :                                   entry->label, entry->value));
     498           0 :                         return false;
     499             :                 }
     500             :         }
     501       90869 :         return true;
     502             : }
     503             : 
     504             : /***************************************************************************
     505             :  Initialise the global parameter structure.
     506             : ***************************************************************************/
     507             : 
     508      887319 : void loadparm_s3_init_globals(struct loadparm_context *lp_ctx,
     509             :                               bool reinit_globals)
     510             : {
     511       10361 :         static bool done_init = false;
     512      887319 :         char *s = NULL;
     513       10361 :         int i;
     514             : 
     515             :         /* If requested to initialize only once and we've already done it... */
     516      887319 :         if (!reinit_globals && done_init) {
     517             :                 /* ... then we have nothing more to do */
     518      788488 :                 return;
     519             :         }
     520             : 
     521       88683 :         if (!done_init) {
     522             :                 /* The logfile can be set before this is invoked. Free it if so. */
     523       40209 :                 lpcfg_string_free(&Globals.logfile);
     524       40209 :                 done_init = true;
     525             :         } else {
     526       48474 :                 free_global_parameters();
     527             :         }
     528             : 
     529             :         /* This memset and the free_global_parameters() above will
     530             :          * wipe out smb.conf options set with lp_set_cmdline().  The
     531             :          * apply_lp_set_cmdline() call puts these values back in the
     532             :          * table once the defaults are set */
     533       88683 :         ZERO_STRUCT(Globals);
     534             : 
     535       88683 :         Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
     536             : 
     537             :         /* Initialize the flags list if necessary */
     538       88683 :         if (flags_list == NULL) {
     539           0 :                 get_flags();
     540             :         }
     541             : 
     542    46292526 :         for (i = 0; parm_table[i].label; i++) {
     543    46203843 :                 if ((parm_table[i].type == P_STRING ||
     544    33530130 :                      parm_table[i].type == P_USTRING))
     545             :                 {
     546    12859035 :                         lpcfg_string_set(
     547             :                                 Globals.ctx,
     548    12859035 :                                 (char **)lp_parm_ptr(NULL, &parm_table[i]),
     549             :                                 "");
     550             :                 }
     551             :         }
     552             : 
     553             : 
     554       88683 :         lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
     555       88683 :         lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U");
     556             : 
     557       88683 :         init_printer_values(lp_ctx, Globals.ctx, &sDefault);
     558             : 
     559       88683 :         sDefault.ntvfs_handler = str_list_make_v3_const(Globals.ctx, "unixuid default", NULL);
     560             : 
     561       88683 :         DEBUG(3, ("Initialising global parameters\n"));
     562             : 
     563             :         /* Must manually force to upper case here, as this does not go via the handler */
     564       88683 :         lpcfg_string_set(Globals.ctx, &Globals.netbios_name,
     565       88683 :                          myhostname_upper());
     566             : 
     567       88683 :         lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file,
     568             :                          get_dyn_SMB_PASSWD_FILE());
     569       88683 :         lpcfg_string_set(Globals.ctx, &Globals.private_dir,
     570             :                          get_dyn_PRIVATE_DIR());
     571       88683 :         lpcfg_string_set(Globals.ctx, &Globals.binddns_dir,
     572             :                          get_dyn_BINDDNS_DIR());
     573             : 
     574             :         /* use the new 'hash2' method by default, with a prefix of 1 */
     575       88683 :         lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
     576       88683 :         Globals.mangle_prefix = 1;
     577             : 
     578       88683 :         lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
     579             : 
     580             :         /* using UTF8 by default allows us to support all chars */
     581       88683 :         lpcfg_string_set(Globals.ctx, &Globals.unix_charset,
     582             :                          DEFAULT_UNIX_CHARSET);
     583             : 
     584             :         /* Use codepage 850 as a default for the dos character set */
     585       88683 :         lpcfg_string_set(Globals.ctx, &Globals.dos_charset,
     586             :                          DEFAULT_DOS_CHARSET);
     587             : 
     588             :         /*
     589             :          * Allow the default PASSWD_CHAT to be overridden in local.h.
     590             :          */
     591       88683 :         lpcfg_string_set(Globals.ctx, &Globals.passwd_chat,
     592             :                          DEFAULT_PASSWD_CHAT);
     593             : 
     594       88683 :         lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
     595             : 
     596       88683 :         lpcfg_string_set(Globals.ctx, &Globals.passwd_program, "");
     597       88683 :         lpcfg_string_set(Globals.ctx, &Globals.lock_directory,
     598             :                          get_dyn_LOCKDIR());
     599       88683 :         lpcfg_string_set(Globals.ctx, &Globals.state_directory,
     600             :                          get_dyn_STATEDIR());
     601       88683 :         lpcfg_string_set(Globals.ctx, &Globals.cache_directory,
     602             :                          get_dyn_CACHEDIR());
     603       88683 :         lpcfg_string_set(Globals.ctx, &Globals.pid_directory,
     604             :                          get_dyn_PIDDIR());
     605       88683 :         lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address,
     606             :                          "0.0.0.0");
     607             :         /*
     608             :          * By default support explicit binding to broadcast
     609             :          * addresses.
     610             :          */
     611       88683 :         Globals.nmbd_bind_explicit_broadcast = true;
     612             : 
     613       88683 :         s = talloc_asprintf(Globals.ctx, "Samba %s", samba_version_string());
     614       88683 :         if (s == NULL) {
     615           0 :                 smb_panic("init_globals: ENOMEM");
     616             :         }
     617       88683 :         lpcfg_string_set(Globals.ctx, &Globals.server_string, s);
     618       88683 :         TALLOC_FREE(s);
     619             : #ifdef DEVELOPER
     620       88683 :         lpcfg_string_set(Globals.ctx, &Globals.panic_action,
     621             :                          "/bin/sleep 999999999");
     622             : #endif
     623             : 
     624       88683 :         lpcfg_string_set(Globals.ctx, &Globals.socket_options,
     625             :                          DEFAULT_SOCKET_OPTIONS);
     626             : 
     627       88683 :         lpcfg_string_set(Globals.ctx, &Globals.logon_drive, "");
     628             :         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
     629       88683 :         lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
     630       88683 :         lpcfg_string_set(Globals.ctx, &Globals.logon_path,
     631             :                          "\\\\%N\\%U\\profile");
     632             : 
     633       88896 :         Globals.name_resolve_order =
     634       88683 :                         str_list_make_v3_const(Globals.ctx,
     635             :                                                DEFAULT_NAME_RESOLVE_ORDER,
     636             :                                                NULL);
     637       88683 :         lpcfg_string_set(Globals.ctx, &Globals.password_server, "*");
     638             : 
     639       88683 :         Globals.algorithmic_rid_base = BASE_RID;
     640             : 
     641       88683 :         Globals.load_printers = true;
     642       88683 :         Globals.printcap_cache_time = 750;      /* 12.5 minutes */
     643             : 
     644       88683 :         Globals.config_backend = config_backend;
     645       88683 :         Globals._server_role = ROLE_AUTO;
     646             : 
     647             :         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
     648             :         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
     649       88683 :         Globals.max_xmit = 0x4104;
     650       88683 :         Globals.max_mux = 50;   /* This is *needed* for profile support. */
     651       88683 :         Globals.lpq_cache_time = 30;    /* changed to handle large print servers better -- jerry */
     652       88683 :         Globals._disable_spoolss = false;
     653       88683 :         Globals.max_smbd_processes = 0;/* no limit specified */
     654       88683 :         Globals.username_level = 0;
     655       88683 :         Globals.deadtime = 10080;
     656       88683 :         Globals.getwd_cache = true;
     657       88683 :         Globals.large_readwrite = true;
     658       88683 :         Globals.max_log_size = 5000;
     659       88683 :         Globals.max_open_files = max_open_files();
     660       88683 :         Globals.server_max_protocol = PROTOCOL_SMB3_11;
     661       88683 :         Globals.server_min_protocol = PROTOCOL_SMB2_02;
     662       88683 :         Globals._client_max_protocol = PROTOCOL_DEFAULT;
     663       88683 :         Globals.client_min_protocol = PROTOCOL_SMB2_02;
     664       88683 :         Globals._client_ipc_max_protocol = PROTOCOL_DEFAULT;
     665       88683 :         Globals._client_ipc_min_protocol = PROTOCOL_DEFAULT;
     666       88683 :         Globals._security = SEC_AUTO;
     667       88683 :         Globals.encrypt_passwords = true;
     668       88683 :         Globals.client_schannel = true;
     669       88683 :         Globals.winbind_sealed_pipes = true;
     670       88683 :         Globals.require_strong_key = true;
     671       88683 :         Globals.reject_md5_servers = true;
     672       88683 :         Globals.server_schannel = true;
     673       88683 :         Globals.server_schannel_require_seal = true;
     674       88683 :         Globals.reject_md5_clients = true;
     675       88683 :         Globals.read_raw = true;
     676       88683 :         Globals.write_raw = true;
     677       88683 :         Globals.null_passwords = false;
     678       88683 :         Globals.old_password_allowed_period = 60;
     679       88683 :         Globals.obey_pam_restrictions = false;
     680       88683 :         Globals.syslog = 1;
     681       88683 :         Globals.syslog_only = false;
     682       88683 :         Globals.timestamp_logs = true;
     683       88683 :         lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
     684       88683 :         Globals.debug_prefix_timestamp = false;
     685       88683 :         Globals.debug_hires_timestamp = true;
     686       88683 :         Globals.debug_syslog_format = false;
     687       88683 :         Globals.debug_pid = false;
     688       88683 :         Globals.debug_uid = false;
     689       88683 :         Globals.debug_class = false;
     690       88683 :         Globals.enable_core_files = true;
     691       88683 :         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
     692       88683 :         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
     693       88683 :         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
     694       88683 :         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
     695       88683 :         Globals.lm_announce = Auto;     /* = Auto: send only if LM clients found */
     696       88683 :         Globals.lm_interval = 60;
     697       88683 :         Globals.time_server = false;
     698       88683 :         Globals.bind_interfaces_only = false;
     699       88683 :         Globals.unix_password_sync = false;
     700       88683 :         Globals.pam_password_change = false;
     701       88683 :         Globals.passwd_chat_debug = false;
     702       88683 :         Globals.passwd_chat_timeout = 2; /* 2 second default. */
     703       88683 :         Globals.nt_pipe_support = true; /* Do NT pipes by default. */
     704       88683 :         Globals.nt_status_support = true; /* Use NT status by default. */
     705       88683 :         Globals.smbd_profiling_level = 0;
     706       88683 :         Globals.stat_cache = true;      /* use stat cache by default */
     707       88683 :         Globals.max_stat_cache_size = 512; /* 512k by default */
     708       88683 :         Globals.restrict_anonymous = 0;
     709       88683 :         Globals.client_lanman_auth = false;     /* Do NOT use the LanMan hash if it is available */
     710       88683 :         Globals.client_plaintext_auth = false;  /* Do NOT use a plaintext password even if is requested by the server */
     711       88683 :         Globals._lanman_auth = false;   /* Do NOT use the LanMan hash, even if it is supplied */
     712       88683 :         Globals.ntlm_auth = NTLM_AUTH_NTLMV2_ONLY;      /* Do NOT use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
     713       88683 :         Globals.nt_hash_store = NT_HASH_STORE_ALWAYS;   /* Fill in NT hash when setting password */
     714       88683 :         Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */
     715       88683 :         Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
     716             :         /* Note, that we will also use NTLM2 session security (which is different), if it is available */
     717             : 
     718       88683 :         Globals.allow_dcerpc_auth_level_connect = false; /* we don't allow this by default */
     719             : 
     720       88683 :         Globals.map_to_guest = 0;       /* By Default, "Never" */
     721       88683 :         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
     722       88683 :         Globals.enhanced_browsing = true;
     723       88683 :         Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
     724       88683 :         Globals.use_mmap = true;
     725       88683 :         Globals.unicode = true;
     726       88683 :         Globals.smb1_unix_extensions = true;
     727       88683 :         Globals.reset_on_zero_vc = false;
     728       88683 :         Globals.log_writeable_files_on_exit = false;
     729       88683 :         Globals.create_krb5_conf = true;
     730       88683 :         Globals.include_system_krb5_conf = true;
     731       88683 :         Globals._winbind_max_domain_connections = 1;
     732             : 
     733             :         /* hostname lookups can be very expensive and are broken on
     734             :            a large number of sites (tridge) */
     735       88683 :         Globals.hostname_lookups = false;
     736             : 
     737       88683 :         Globals.change_notify = true,
     738       88683 :         Globals.kernel_change_notify = true,
     739             : 
     740       88683 :         lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
     741       88683 :         lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, "");
     742       88683 :         lpcfg_string_set(Globals.ctx, &Globals._ldap_machine_suffix, "");
     743       88683 :         lpcfg_string_set(Globals.ctx, &Globals._ldap_user_suffix, "");
     744       88683 :         lpcfg_string_set(Globals.ctx, &Globals._ldap_group_suffix, "");
     745       88683 :         lpcfg_string_set(Globals.ctx, &Globals._ldap_idmap_suffix, "");
     746             : 
     747       88683 :         lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
     748       88683 :         Globals.ldap_ssl = LDAP_SSL_START_TLS;
     749       88683 :         Globals.ldap_deref = -1;
     750       88683 :         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
     751       88683 :         Globals.ldap_delete_dn = false;
     752       88683 :         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
     753       88683 :         Globals.ldap_follow_referral = Auto;
     754       88683 :         Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
     755       88683 :         Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
     756       88683 :         Globals.ldap_page_size = LDAP_PAGE_SIZE;
     757             : 
     758       88683 :         Globals.ldap_debug_level = 0;
     759       88683 :         Globals.ldap_debug_threshold = 10;
     760             : 
     761       88683 :         Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SEAL;
     762             : 
     763       88683 :         Globals.ldap_server_require_strong_auth =
     764             :                 LDAP_SERVER_REQUIRE_STRONG_AUTH_YES;
     765             : 
     766             :         /* This is what we tell the afs client. in reality we set the token
     767             :          * to never expire, though, when this runs out the afs client will
     768             :          * forget the token. Set to 0 to get NEVERDATE.*/
     769       88683 :         Globals.afs_token_lifetime = 604800;
     770       88683 :         Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
     771             : 
     772             : /* these parameters are set to defaults that are more appropriate
     773             :    for the increasing samba install base:
     774             : 
     775             :    as a member of the workgroup, that will possibly become a
     776             :    _local_ master browser (lm = true).  this is opposed to a forced
     777             :    local master browser startup (pm = true).
     778             : 
     779             :    doesn't provide WINS server service by default (wsupp = false),
     780             :    and doesn't provide domain master browser services by default, either.
     781             : 
     782             : */
     783             : 
     784       88683 :         Globals.show_add_printer_wizard = true;
     785       88683 :         Globals.os_level = 20;
     786       88683 :         Globals.local_master = true;
     787       88683 :         Globals._domain_master = Auto;  /* depending on _domain_logons */
     788       88683 :         Globals._domain_logons = false;
     789       88683 :         Globals.browse_list = true;
     790       88683 :         Globals.we_are_a_wins_server = false;
     791       88683 :         Globals.wins_proxy = false;
     792             : 
     793       88683 :         TALLOC_FREE(Globals.init_logon_delayed_hosts);
     794       88683 :         Globals.init_logon_delay = 100; /* 100 ms default delay */
     795             : 
     796       88683 :         Globals.wins_dns_proxy = true;
     797       88683 :         Globals.dns_port = DNS_SERVICE_PORT;
     798             : 
     799       88683 :         Globals.allow_trusted_domains = true;
     800       88683 :         lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb");
     801             : 
     802       88683 :         lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
     803       88683 :         lpcfg_string_set(Globals.ctx, &Globals.template_homedir,
     804             :                          "/home/%D/%U");
     805       88683 :         lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\");
     806       88683 :         lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory,
     807             :                          dyn_WINBINDD_SOCKET_DIR);
     808             : 
     809       88683 :         lpcfg_string_set(Globals.ctx, &Globals.cups_server, "");
     810       88683 :         lpcfg_string_set(Globals.ctx, &Globals.iprint_server, "");
     811             : 
     812       88683 :         lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, "");
     813             : 
     814       88683 :         Globals.cluster_addresses = NULL;
     815       88683 :         Globals.clustering = false;
     816       88683 :         Globals.ctdb_timeout = 0;
     817       88683 :         Globals.ctdb_locktime_warn_threshold = 0;
     818             : 
     819       88683 :         Globals.winbind_cache_time = 300;       /* 5 minutes */
     820       88683 :         Globals.winbind_reconnect_delay = 30;   /* 30 seconds */
     821       88683 :         Globals.winbind_request_timeout = 60;   /* 60 seconds */
     822       88683 :         Globals.winbind_max_clients = 200;
     823       88683 :         Globals.winbind_enum_users = false;
     824       88683 :         Globals.winbind_enum_groups = false;
     825       88683 :         Globals.winbind_use_default_domain = false;
     826       88683 :         Globals.winbind_nested_groups = true;
     827       88683 :         Globals.winbind_expand_groups = 0;
     828       88683 :         Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
     829       88683 :         Globals.winbind_refresh_tickets = false;
     830       88683 :         Globals.winbind_offline_logon = false;
     831       88683 :         Globals.winbind_scan_trusted_domains = false;
     832             : 
     833       88683 :         Globals.idmap_cache_time = 86400 * 7; /* a week by default */
     834       88683 :         Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
     835             : 
     836       88683 :         Globals.passdb_expand_explicit = false;
     837             : 
     838       88683 :         Globals.name_cache_timeout = 660; /* In seconds */
     839             : 
     840       88683 :         Globals.client_use_spnego = true;
     841             : 
     842       88683 :         Globals.client_signing = SMB_SIGNING_DEFAULT;
     843       88683 :         Globals._client_ipc_signing = SMB_SIGNING_DEFAULT;
     844       88683 :         Globals.server_signing = SMB_SIGNING_DEFAULT;
     845             : 
     846       88683 :         Globals.defer_sharing_violations = true;
     847       88683 :         Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
     848             : 
     849       88683 :         Globals.enable_privileges = true;
     850       88683 :         Globals.host_msdfs        = true;
     851       88683 :         Globals.enable_asu_support       = false;
     852             : 
     853             :         /* User defined shares. */
     854       88683 :         s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
     855       88683 :         if (s == NULL) {
     856           0 :                 smb_panic("init_globals: ENOMEM");
     857             :         }
     858       88683 :         lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s);
     859       88683 :         TALLOC_FREE(s);
     860       88683 :         lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, "");
     861       88683 :         Globals.usershare_max_shares = 0;
     862             :         /* By default disallow sharing of directories not owned by the sharer. */
     863       88683 :         Globals.usershare_owner_only = true;
     864             :         /* By default disallow guest access to usershares. */
     865       88683 :         Globals.usershare_allow_guests = false;
     866             : 
     867       88683 :         Globals.keepalive = DEFAULT_KEEPALIVE;
     868             : 
     869             :         /* By default no shares out of the registry */
     870       88683 :         Globals.registry_shares = false;
     871             : 
     872       88683 :         Globals.min_receivefile_size = 0;
     873             : 
     874       88683 :         Globals.multicast_dns_register = true;
     875             : 
     876       88683 :         Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
     877       88683 :         Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
     878       88683 :         Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
     879       88683 :         Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
     880       88683 :         Globals.smb2_leases = true;
     881       88683 :         Globals.server_multi_channel_support = true;
     882             : 
     883       88683 :         lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir,
     884             :                          get_dyn_NCALRPCDIR());
     885             : 
     886       88683 :         Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
     887             : 
     888       88683 :         Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
     889             : 
     890       88683 :         Globals.tls_enabled = true;
     891       88683 :         Globals.tls_verify_peer = TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE;
     892             : 
     893       88683 :         lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
     894       88683 :         lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
     895       88683 :         lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
     896       88683 :         lpcfg_string_set(Globals.ctx,
     897             :                          &Globals.tls_priority,
     898             :                          "NORMAL:-VERS-SSL3.0");
     899             : 
     900       88683 :         Globals._preferred_master = Auto;
     901             : 
     902       88683 :         Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
     903       88683 :         Globals.dns_zone_scavenging = false;
     904             : 
     905       88683 :         lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
     906             :                          get_dyn_NTP_SIGND_SOCKET_DIR());
     907             : 
     908       88683 :         s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
     909       88683 :         if (s == NULL) {
     910           0 :                 smb_panic("init_globals: ENOMEM");
     911             :         }
     912       88683 :         Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
     913       88683 :         TALLOC_FREE(s);
     914             : 
     915             : #ifdef MIT_KDC_PATH
     916       12153 :         Globals.mit_kdc_command = str_list_make_v3_const(NULL, MIT_KDC_PATH, NULL);
     917             : #endif
     918             : 
     919       88683 :         s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
     920       88683 :         if (s == NULL) {
     921           0 :                 smb_panic("init_globals: ENOMEM");
     922             :         }
     923       88683 :         Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
     924       88683 :         TALLOC_FREE(s);
     925             : 
     926       88683 :         s = talloc_asprintf(talloc_tos(), "%s/samba-gpupdate", get_dyn_SCRIPTSBINDIR());
     927       88683 :         if (s == NULL) {
     928           0 :                 smb_panic("init_globals: ENOMEM");
     929             :         }
     930       88683 :         Globals.gpo_update_command = str_list_make_v3_const(NULL, s, NULL);
     931       88683 :         TALLOC_FREE(s);
     932             : 
     933       88683 :         Globals.apply_group_policies = false;
     934             : 
     935       88683 :         s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
     936       88683 :         if (s == NULL) {
     937           0 :                 smb_panic("init_globals: ENOMEM");
     938             :         }
     939       88683 :         Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
     940       88683 :         TALLOC_FREE(s);
     941             : 
     942       88683 :         Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
     943             : 
     944       88683 :         Globals.cldap_port = 389;
     945             : 
     946       88683 :         Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
     947             : 
     948       88683 :         Globals.nbt_port = NBT_NAME_SERVICE_PORT;
     949             : 
     950       88683 :         Globals.krb5_port = 88;
     951             : 
     952       88683 :         Globals.kpasswd_port = 464;
     953             : 
     954       88683 :         Globals.kdc_enable_fast = true;
     955             : 
     956       88683 :         Globals.winbind_debug_traceid = true;
     957             : 
     958       88683 :         Globals.aio_max_threads = 100;
     959             : 
     960       88683 :         lpcfg_string_set(Globals.ctx,
     961             :                          &Globals.rpc_server_dynamic_port_range,
     962             :                          "49152-65535");
     963       88683 :         Globals.rpc_low_port = SERVER_TCP_LOW_PORT;
     964       88683 :         Globals.rpc_high_port = SERVER_TCP_HIGH_PORT;
     965       88683 :         Globals.prefork_children = 4;
     966       88683 :         Globals.prefork_backoff_increment = 10;
     967       88683 :         Globals.prefork_maximum_backoff = 120;
     968             : 
     969       88683 :         Globals.ldap_max_anonymous_request_size = 256000;
     970       88683 :         Globals.ldap_max_authenticated_request_size = 16777216;
     971       88683 :         Globals.ldap_max_search_request_size = 256000;
     972             : 
     973             :         /* Async DNS query timeout (in seconds). */
     974       88683 :         Globals.async_dns_timeout = 10;
     975             : 
     976       88683 :         Globals.client_smb_encrypt = SMB_ENCRYPTION_DEFAULT;
     977             : 
     978       88683 :         Globals._client_use_kerberos = CRED_USE_KERBEROS_DESIRED;
     979             : 
     980       88683 :         Globals.client_protection = CRED_CLIENT_PROTECTION_DEFAULT;
     981             : 
     982       88683 :         Globals.winbind_use_krb5_enterprise_principals = true;
     983             : 
     984       88896 :         Globals.client_smb3_signing_algorithms =
     985       88683 :                 str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
     986       88896 :         Globals.server_smb3_signing_algorithms =
     987       88683 :                 str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
     988             : 
     989       88896 :         Globals.client_smb3_encryption_algorithms =
     990       88683 :                 str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
     991       88896 :         Globals.server_smb3_encryption_algorithms =
     992       88683 :                 str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
     993             : 
     994       88683 :         Globals.min_domain_uid = 1000;
     995             : 
     996             :         /*
     997             :          * By default allow smbd and winbindd to start samba-dcerpcd as
     998             :          * a named-pipe helper.
     999             :          */
    1000       88683 :         Globals.rpc_start_on_demand_helpers = true;
    1001             : 
    1002       88683 :         Globals.ad_dc_functional_level = DS_DOMAIN_FUNCTION_2008_R2,
    1003             : 
    1004       88683 :         Globals.acl_claims_evaluation = ACL_CLAIMS_EVALUATION_AD_DC_ONLY;
    1005             : 
    1006             :         /* Now put back the settings that were set with lp_set_cmdline() */
    1007       88683 :         apply_lp_set_cmdline();
    1008             : }
    1009             : 
    1010             : /* Convenience routine to setup an lp_context with additional s3 variables */
    1011      471598 : static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
    1012             : {
    1013        4228 :         struct loadparm_context *lp_ctx;
    1014             : 
    1015      471598 :         lp_ctx = loadparm_init_s3(mem_ctx,
    1016             :                                   loadparm_s3_helpers());
    1017      471598 :         if (lp_ctx == NULL) {
    1018           0 :                 DEBUG(0, ("loadparm_init_s3 failed\n"));
    1019           0 :                 return NULL;
    1020             :         }
    1021             : 
    1022      471598 :         lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
    1023      471598 :         if (lp_ctx->sDefault == NULL) {
    1024           0 :                 DBG_ERR("talloc_zero failed\n");
    1025           0 :                 TALLOC_FREE(lp_ctx);
    1026           0 :                 return NULL;
    1027             :         }
    1028             : 
    1029      471598 :         *lp_ctx->sDefault = _sDefault;
    1030      471598 :         lp_ctx->services = NULL; /* We do not want to access this directly */
    1031      471598 :         lp_ctx->bInGlobalSection = bInGlobalSection;
    1032      471598 :         lp_ctx->flags = flags_list;
    1033             : 
    1034      471598 :         return lp_ctx;
    1035             : }
    1036             : 
    1037             : /*******************************************************************
    1038             :  Convenience routine to grab string parameters into talloced memory
    1039             :  and run standard_sub_basic on them. The buffers can be written to by
    1040             :  callers without affecting the source string.
    1041             : ********************************************************************/
    1042             : 
    1043     2523894 : static char *loadparm_s3_global_substitution_fn(
    1044             :                         TALLOC_CTX *mem_ctx,
    1045             :                         const struct loadparm_substitution *lp_sub,
    1046             :                         const char *s,
    1047             :                         void *private_data)
    1048             : {
    1049       28668 :         char *ret;
    1050             : 
    1051             :         /* The follow debug is useful for tracking down memory problems
    1052             :            especially if you have an inner loop that is calling a lp_*()
    1053             :            function that returns a string.  Perhaps this debug should be
    1054             :            present all the time? */
    1055             : 
    1056             : #if 0
    1057             :         DEBUG(10, ("lp_string(%s)\n", s));
    1058             : #endif
    1059     2523894 :         if (!s) {
    1060          46 :                 return NULL;
    1061             :         }
    1062             : 
    1063     2523848 :         ret = talloc_sub_basic(mem_ctx,
    1064             :                         get_current_username(),
    1065             :                         get_current_user_info_domain(),
    1066             :                         s);
    1067     2523848 :         if (trim_char(ret, '\"', '\"')) {
    1068          34 :                 if (strchr(ret,'\"') != NULL) {
    1069          34 :                         TALLOC_FREE(ret);
    1070          34 :                         ret = talloc_sub_basic(mem_ctx,
    1071             :                                         get_current_username(),
    1072             :                                         get_current_user_info_domain(),
    1073             :                                         s);
    1074             :                 }
    1075             :         }
    1076     2495180 :         return ret;
    1077             : }
    1078             : 
    1079             : static const struct loadparm_substitution s3_global_substitution = {
    1080             :         .substituted_string_fn = loadparm_s3_global_substitution_fn,
    1081             : };
    1082             : 
    1083     4935959 : const struct loadparm_substitution *loadparm_s3_global_substitution(void)
    1084             : {
    1085     4935959 :         return &s3_global_substitution;
    1086             : }
    1087             : 
    1088             : /*
    1089             :    In this section all the functions that are used to access the
    1090             :    parameters from the rest of the program are defined
    1091             : */
    1092             : 
    1093             : #define FN_GLOBAL_SUBSTITUTED_STRING(fn_name,ptr) \
    1094             : char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub) \
    1095             :  {return lpcfg_substituted_string(ctx, lp_sub, *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : "");}
    1096             : #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
    1097             :  const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
    1098             : #define FN_GLOBAL_LIST(fn_name,ptr) \
    1099             :  const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
    1100             : #define FN_GLOBAL_BOOL(fn_name,ptr) \
    1101             :  bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
    1102             : #define FN_GLOBAL_CHAR(fn_name,ptr) \
    1103             :  char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
    1104             : #define FN_GLOBAL_INTEGER(fn_name,ptr) \
    1105             :  int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
    1106             : 
    1107             : #define FN_LOCAL_SUBSTITUTED_STRING(fn_name,val) \
    1108             : char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub, int i) \
    1109             :  {return lpcfg_substituted_string((ctx), lp_sub, (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
    1110             : #define FN_LOCAL_CONST_STRING(fn_name,val) \
    1111             :  const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
    1112             : #define FN_LOCAL_LIST(fn_name,val) \
    1113             :  const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
    1114             : #define FN_LOCAL_BOOL(fn_name,val) \
    1115             :  bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
    1116             : #define FN_LOCAL_INTEGER(fn_name,val) \
    1117             :  int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
    1118             : 
    1119             : #define FN_LOCAL_PARM_BOOL(fn_name,val) \
    1120             :  bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
    1121             : #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
    1122             :  int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
    1123             : #define FN_LOCAL_PARM_CHAR(fn_name,val) \
    1124             :  char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
    1125             : 
    1126         266 : int lp_winbind_max_domain_connections(void)
    1127             : {
    1128         298 :         if (lp_winbind_offline_logon() &&
    1129          32 :             lp__winbind_max_domain_connections() > 1) {
    1130           0 :                 DEBUG(1, ("offline logons active, restricting max domain "
    1131             :                           "connections to 1\n"));
    1132           0 :                 return 1;
    1133             :         }
    1134         266 :         return MAX(1, lp__winbind_max_domain_connections());
    1135             : }
    1136             : 
    1137             : /* These functions remain in source3/param for now */
    1138             : 
    1139             : #include "lib/param/param_functions.c"
    1140             : 
    1141      170425 : FN_LOCAL_SUBSTITUTED_STRING(servicename, szService)
    1142      280018 : FN_LOCAL_CONST_STRING(const_servicename, szService)
    1143             : 
    1144             : /* These functions cannot be auto-generated */
    1145        1219 : FN_LOCAL_BOOL(autoloaded, autoloaded)
    1146        4803 : FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
    1147             : 
    1148             : /* local prototypes */
    1149             : 
    1150             : static int map_parameter_canonical(const char *pszParmName, bool *inverse);
    1151             : static const char *get_boolean(bool bool_value);
    1152             : static bool do_parameter(const char *pszParmName, const char *pszParmValue,
    1153             :                          void *userdata);
    1154             : static bool hash_a_service(const char *name, int number);
    1155             : static void free_service_byindex(int iService);
    1156             : static void show_parameter(int parmIndex);
    1157             : static bool is_synonym_of(int parm1, int parm2, bool *inverse);
    1158             : static bool lp_parameter_value_is_valid(const char *parm_name, const char *val);
    1159             : 
    1160             : /*
    1161             :  * This is a helper function for parametrical options support.  It returns a
    1162             :  * pointer to parametrical option value if it exists or NULL otherwise. Actual
    1163             :  * parametrical functions are quite simple
    1164             :  */
    1165     2888903 : static struct parmlist_entry *get_parametrics(int snum, const char *type,
    1166             :                                                 const char *option)
    1167             : {
    1168     2888903 :         if (snum >= iNumServices) return NULL;
    1169             : 
    1170     2888903 :         if (snum < 0) {
    1171      832385 :                 return get_parametric_helper(NULL, type, option, Globals.param_opt);
    1172             :         } else {
    1173     2056518 :                 return get_parametric_helper(ServicePtrs[snum],
    1174             :                                              type, option, Globals.param_opt);
    1175             :         }
    1176             : }
    1177             : 
    1178         985 : static void discard_whitespace(char *str)
    1179             : {
    1180         985 :         size_t len = strlen(str);
    1181         985 :         size_t i = 0;
    1182             : 
    1183       26124 :         while (i < len) {
    1184       25139 :                 if (isspace(str[i])) {
    1185        1453 :                         memmove(&str[i], &str[i+1], len-i);
    1186        1453 :                         len -= 1;
    1187        1453 :                         continue;
    1188             :                 }
    1189       23686 :                 i += 1;
    1190             :         }
    1191         985 : }
    1192             : 
    1193             : /**
    1194             :  * @brief Go through all global parametric parameters
    1195             :  *
    1196             :  * @param regex_str     A regular expression to scan param for
    1197             :  * @param max_matches   Max number of submatches the regexp expects
    1198             :  * @param cb            Function to call on match. Should return true
    1199             :  *                      when it wants wi_scan_global_parametrics to stop
    1200             :  *                      scanning
    1201             :  * @param private_data  Anonymous pointer passed to cb
    1202             :  *
    1203             :  * @return              0: success, regcomp/regexec return value on error.
    1204             :  *                      See "man regexec" for possible errors
    1205             :  */
    1206             : 
    1207          49 : int lp_wi_scan_global_parametrics(
    1208             :         const char *regex_str, size_t max_matches,
    1209             :         bool (*cb)(const char *string, regmatch_t matches[],
    1210             :                    void *private_data),
    1211             :         void *private_data)
    1212             : {
    1213           0 :         struct parmlist_entry *data;
    1214           0 :         regex_t regex;
    1215           0 :         int ret;
    1216             : 
    1217          49 :         ret = regcomp(&regex, regex_str, REG_ICASE);
    1218          49 :         if (ret != 0) {
    1219           0 :                 return ret;
    1220             :         }
    1221             : 
    1222        1034 :         for (data = Globals.param_opt; data != NULL; data = data->next) {
    1223         985 :                 size_t keylen = strlen(data->key);
    1224         985 :                 char key[keylen+1];
    1225         985 :                 regmatch_t matches[max_matches];
    1226           0 :                 bool stop;
    1227             : 
    1228         985 :                 memcpy(key, data->key, sizeof(key));
    1229         985 :                 discard_whitespace(key);
    1230             : 
    1231         985 :                 ret = regexec(&regex, key, max_matches, matches, 0);
    1232         985 :                 if (ret == REG_NOMATCH) {
    1233         926 :                         continue;
    1234             :                 }
    1235          59 :                 if (ret != 0) {
    1236           0 :                         goto fail;
    1237             :                 }
    1238             : 
    1239          59 :                 stop = cb(key, matches, private_data);
    1240          59 :                 if (stop) {
    1241           0 :                         break;
    1242             :                 }
    1243             :         }
    1244             : 
    1245          49 :         ret = 0;
    1246          49 : fail:
    1247          49 :         regfree(&regex);
    1248          49 :         return ret;
    1249             : }
    1250             : 
    1251             : 
    1252             : #define MISSING_PARAMETER(name) \
    1253             :     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
    1254             : 
    1255             : /*******************************************************************
    1256             : convenience routine to return enum parameters.
    1257             : ********************************************************************/
    1258       10064 : static int lp_enum(const char *s,const struct enum_list *_enum)
    1259             : {
    1260           0 :         int i;
    1261             : 
    1262       10064 :         if (!s || !*s || !_enum) {
    1263           0 :                 MISSING_PARAMETER(lp_enum);
    1264           0 :                 return (-1);
    1265             :         }
    1266             : 
    1267       11942 :         for (i=0; _enum[i].name; i++) {
    1268       11942 :                 if (strequal(_enum[i].name,s))
    1269       10064 :                         return _enum[i].value;
    1270             :         }
    1271             : 
    1272           0 :         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
    1273           0 :         return (-1);
    1274             : }
    1275             : 
    1276             : #undef MISSING_PARAMETER
    1277             : 
    1278             : /* Return parametric option from a given service. Type is a part of option before ':' */
    1279             : /* Parametric option has following syntax: 'Type: option = value' */
    1280      465907 : char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx,
    1281             :                                  const struct loadparm_substitution *lp_sub,
    1282             :                                  int snum,
    1283             :                                  const char *type,
    1284             :                                  const char *option,
    1285             :                                  const char *def)
    1286             : {
    1287      465907 :         struct parmlist_entry *data = get_parametrics(snum, type, option);
    1288             : 
    1289      465907 :         SMB_ASSERT(lp_sub != NULL);
    1290             : 
    1291      465907 :         if (data == NULL||data->value==NULL) {
    1292      464568 :                 if (def) {
    1293      464568 :                         return lpcfg_substituted_string(mem_ctx, lp_sub, def);
    1294             :                 } else {
    1295           0 :                         return NULL;
    1296             :                 }
    1297             :         }
    1298             : 
    1299        1339 :         return lpcfg_substituted_string(mem_ctx, lp_sub, data->value);
    1300             : }
    1301             : 
    1302             : /* Return parametric option from a given service. Type is a part of option before ':' */
    1303             : /* Parametric option has following syntax: 'Type: option = value' */
    1304      206566 : const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
    1305             : {
    1306      206566 :         struct parmlist_entry *data = get_parametrics(snum, type, option);
    1307             : 
    1308      206566 :         if (data == NULL||data->value==NULL)
    1309      189197 :                 return def;
    1310             : 
    1311       16542 :         return data->value;
    1312             : }
    1313             : 
    1314             : 
    1315             : /* Return parametric option from a given service. Type is a part of option before ':' */
    1316             : /* Parametric option has following syntax: 'Type: option = value' */
    1317             : 
    1318      108624 : const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
    1319             : {
    1320      108624 :         struct parmlist_entry *data = get_parametrics(snum, type, option);
    1321             : 
    1322      108624 :         if (data == NULL||data->value==NULL)
    1323       25482 :                 return (const char **)def;
    1324             : 
    1325       83142 :         if (data->list==NULL) {
    1326       40224 :                 data->list = str_list_make_v3(NULL, data->value, NULL);
    1327             :         }
    1328             : 
    1329       83142 :         return discard_const_p(const char *, data->list);
    1330             : }
    1331             : 
    1332             : /* Return parametric option from a given service. Type is a part of option before ':' */
    1333             : /* Parametric option has following syntax: 'Type: option = value' */
    1334             : 
    1335      256877 : int lp_parm_int(int snum, const char *type, const char *option, int def)
    1336             : {
    1337      256877 :         struct parmlist_entry *data = get_parametrics(snum, type, option);
    1338             : 
    1339      256877 :         if (data && data->value && *data->value)
    1340       13859 :                 return lp_int(data->value);
    1341             : 
    1342      243003 :         return def;
    1343             : }
    1344             : 
    1345             : /* Return parametric option from a given service. Type is a part of option before ':' */
    1346             : /* Parametric option has following syntax: 'Type: option = value' */
    1347             : 
    1348       20772 : unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
    1349             : {
    1350       20772 :         struct parmlist_entry *data = get_parametrics(snum, type, option);
    1351             : 
    1352       20772 :         if (data && data->value && *data->value)
    1353          26 :                 return lp_ulong(data->value);
    1354             : 
    1355       20744 :         return def;
    1356             : }
    1357             : 
    1358             : /* Return parametric option from a given service. Type is a part of option before ':' */
    1359             : /* Parametric option has following syntax: 'Type: option = value' */
    1360             : 
    1361        8699 : unsigned long long lp_parm_ulonglong(int snum, const char *type,
    1362             :                                      const char *option, unsigned long long def)
    1363             : {
    1364        8699 :         struct parmlist_entry *data = get_parametrics(snum, type, option);
    1365             : 
    1366        8699 :         if (data && data->value && *data->value) {
    1367         411 :                 return lp_ulonglong(data->value);
    1368             :         }
    1369             : 
    1370        8288 :         return def;
    1371             : }
    1372             : 
    1373             : /* Return parametric option from a given service. Type is a part of option
    1374             :  * before ':' */
    1375             : /* Parametric option has following syntax: 'Type: option = value' */
    1376             : 
    1377     1663829 : bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
    1378             : {
    1379     1663829 :         struct parmlist_entry *data = get_parametrics(snum, type, option);
    1380             : 
    1381     1663829 :         if (data && data->value && *data->value)
    1382      721195 :                 return lp_bool(data->value);
    1383             : 
    1384      937192 :         return def;
    1385             : }
    1386             : 
    1387             : /* Return parametric option from a given service. Type is a part of option before ':' */
    1388             : /* Parametric option has following syntax: 'Type: option = value' */
    1389             : 
    1390      157629 : int lp_parm_enum(int snum, const char *type, const char *option,
    1391             :                  const struct enum_list *_enum, int def)
    1392             : {
    1393      157629 :         struct parmlist_entry *data = get_parametrics(snum, type, option);
    1394             : 
    1395      157629 :         if (data && data->value && *data->value && _enum)
    1396       10064 :                 return lp_enum(data->value, _enum);
    1397             : 
    1398      146694 :         return def;
    1399             : }
    1400             : 
    1401             : /**
    1402             :  * free a param_opts structure.
    1403             :  * param_opts handling should be moved to talloc;
    1404             :  * then this whole functions reduces to a TALLOC_FREE().
    1405             :  */
    1406             : 
    1407     3212280 : static void free_param_opts(struct parmlist_entry **popts)
    1408             : {
    1409         282 :         struct parmlist_entry *opt, *next_opt;
    1410             : 
    1411     3212280 :         if (*popts != NULL) {
    1412     1197102 :                 DEBUG(5, ("Freeing parametrics:\n"));
    1413             :         }
    1414     3212280 :         opt = *popts;
    1415     7378737 :         while (opt != NULL) {
    1416     4166457 :                 lpcfg_string_free(&opt->key);
    1417     4166457 :                 lpcfg_string_free(&opt->value);
    1418     4166457 :                 TALLOC_FREE(opt->list);
    1419     4166457 :                 next_opt = opt->next;
    1420     4166457 :                 TALLOC_FREE(opt);
    1421     4166457 :                 opt = next_opt;
    1422             :         }
    1423     3212280 :         *popts = NULL;
    1424     3212280 : }
    1425             : 
    1426             : /***************************************************************************
    1427             :  Free the dynamically allocated parts of a service struct.
    1428             : ***************************************************************************/
    1429             : 
    1430      140787 : static void free_service(struct loadparm_service *pservice)
    1431             : {
    1432      140787 :         if (!pservice)
    1433           0 :                 return;
    1434             : 
    1435      140787 :         if (pservice->szService)
    1436      140787 :                 DEBUG(5, ("free_service: Freeing service %s\n",
    1437             :                        pservice->szService));
    1438             : 
    1439      140787 :         free_parameters(pservice);
    1440             : 
    1441      140787 :         lpcfg_string_free(&pservice->szService);
    1442      140787 :         TALLOC_FREE(pservice->copymap);
    1443             : 
    1444      140787 :         free_param_opts(&pservice->param_opt);
    1445             : 
    1446      140787 :         ZERO_STRUCTP(pservice);
    1447             : }
    1448             : 
    1449             : 
    1450             : /***************************************************************************
    1451             :  remove a service indexed in the ServicePtrs array from the ServiceHash
    1452             :  and free the dynamically allocated parts
    1453             : ***************************************************************************/
    1454             : 
    1455      140787 : static void free_service_byindex(int idx)
    1456             : {
    1457      140787 :         if ( !LP_SNUM_OK(idx) )
    1458           0 :                 return;
    1459             : 
    1460      140787 :         ServicePtrs[idx]->valid = false;
    1461             : 
    1462             :         /* we have to cleanup the hash record */
    1463             : 
    1464      140787 :         if (ServicePtrs[idx]->szService) {
    1465      140787 :                 char *canon_name = canonicalize_servicename(
    1466             :                         talloc_tos(),
    1467      140787 :                         ServicePtrs[idx]->szService );
    1468             : 
    1469      140787 :                 dbwrap_delete_bystring(ServiceHash, canon_name );
    1470      140787 :                 TALLOC_FREE(canon_name);
    1471             :         }
    1472             : 
    1473      140787 :         free_service(ServicePtrs[idx]);
    1474      140787 :         TALLOC_FREE(ServicePtrs[idx]);
    1475             : }
    1476             : 
    1477             : /***************************************************************************
    1478             :  Add a new service to the services array initialising it with the given
    1479             :  service.
    1480             : ***************************************************************************/
    1481             : 
    1482     3038460 : static int add_a_service(const struct loadparm_service *pservice, const char *name)
    1483             : {
    1484         148 :         int i;
    1485     3038460 :         struct loadparm_service **tsp = NULL;
    1486             : 
    1487             :         /* it might already exist */
    1488     3038460 :         if (name) {
    1489     3038460 :                 i = getservicebyname(name, NULL);
    1490     3038460 :                 if (i >= 0) {
    1491     2839983 :                         return (i);
    1492             :                 }
    1493             :         }
    1494             : 
    1495             :         /* Re use empty slots if any before allocating new one.*/
    1496    12112095 :         for (i=0; i < iNumServices; i++) {
    1497    12042473 :                 if (ServicePtrs[i] == NULL) {
    1498      128775 :                         break;
    1499             :                 }
    1500             :         }
    1501      198397 :         if (i == iNumServices) {
    1502             :                 /* if not, then create one */
    1503       69622 :                 tsp = talloc_realloc(NULL, ServicePtrs,
    1504             :                                      struct loadparm_service *,
    1505             :                                      iNumServices + 1);
    1506       69622 :                 if (tsp == NULL) {
    1507           0 :                         DEBUG(0, ("add_a_service: failed to enlarge "
    1508             :                                   "ServicePtrs!\n"));
    1509           0 :                         return (-1);
    1510             :                 }
    1511       69622 :                 ServicePtrs = tsp;
    1512       69622 :                 iNumServices++;
    1513             :         }
    1514      198397 :         ServicePtrs[i] = talloc_zero(ServicePtrs, struct loadparm_service);
    1515      198397 :         if (!ServicePtrs[i]) {
    1516           0 :                 DEBUG(0,("add_a_service: out of memory!\n"));
    1517           0 :                 return (-1);
    1518             :         }
    1519             : 
    1520      198397 :         ServicePtrs[i]->valid = true;
    1521             : 
    1522      198397 :         copy_service(ServicePtrs[i], pservice, NULL);
    1523      198397 :         if (name)
    1524      198397 :                 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
    1525             :                                  name);
    1526             : 
    1527      198397 :         DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
    1528             :                 i, ServicePtrs[i]->szService));
    1529             : 
    1530      198397 :         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
    1531           0 :                 return (-1);
    1532             :         }
    1533             : 
    1534      198329 :         return (i);
    1535             : }
    1536             : 
    1537             : /***************************************************************************
    1538             :   Convert a string to uppercase and remove whitespaces.
    1539             : ***************************************************************************/
    1540             : 
    1541     4363701 : char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
    1542             : {
    1543        1952 :         char *result;
    1544             : 
    1545     4363701 :         if ( !src ) {
    1546           0 :                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
    1547           0 :                 return NULL;
    1548             :         }
    1549             : 
    1550     4363701 :         result = talloc_strdup(ctx, src);
    1551     4363701 :         SMB_ASSERT(result != NULL);
    1552             : 
    1553     4363701 :         if (!strlower_m(result)) {
    1554           0 :                 TALLOC_FREE(result);
    1555           0 :                 return NULL;
    1556             :         }
    1557     4361749 :         return result;
    1558             : }
    1559             : 
    1560             : /***************************************************************************
    1561             :   Add a name/index pair for the services array to the hash table.
    1562             : ***************************************************************************/
    1563             : 
    1564      198397 : static bool hash_a_service(const char *name, int idx)
    1565             : {
    1566          68 :         char *canon_name;
    1567             : 
    1568      198397 :         if ( !ServiceHash ) {
    1569        2241 :                 DEBUG(10,("hash_a_service: creating servicehash\n"));
    1570        2241 :                 ServiceHash = db_open_rbt(NULL);
    1571        2241 :                 if ( !ServiceHash ) {
    1572           0 :                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
    1573           0 :                         return false;
    1574             :                 }
    1575             :         }
    1576             : 
    1577      198397 :         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
    1578             :                 idx, name));
    1579             : 
    1580      198397 :         canon_name = canonicalize_servicename(talloc_tos(), name );
    1581             : 
    1582      198397 :         dbwrap_store_bystring(ServiceHash, canon_name,
    1583             :                               make_tdb_data((uint8_t *)&idx, sizeof(idx)),
    1584             :                               TDB_REPLACE);
    1585             : 
    1586      198397 :         TALLOC_FREE(canon_name);
    1587             : 
    1588      198329 :         return true;
    1589             : }
    1590             : 
    1591             : /***************************************************************************
    1592             :  Add a new home service, with the specified home directory, defaults coming
    1593             :  from service ifrom.
    1594             : ***************************************************************************/
    1595             : 
    1596       11530 : bool lp_add_home(const char *pszHomename, int iDefaultService,
    1597             :                  const char *user, const char *pszHomedir)
    1598             : {
    1599           0 :         const struct loadparm_substitution *lp_sub =
    1600       11530 :                 loadparm_s3_global_substitution();
    1601           0 :         int i;
    1602           0 :         char *global_path;
    1603             : 
    1604       11530 :         if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
    1605       11530 :                         pszHomedir[0] == '\0') {
    1606           0 :                 return false;
    1607             :         }
    1608             : 
    1609       11530 :         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
    1610             : 
    1611       11530 :         if (i < 0)
    1612           0 :                 return false;
    1613             : 
    1614       11530 :         global_path = lp_path(talloc_tos(), lp_sub, GLOBAL_SECTION_SNUM);
    1615       11530 :         if (!(*(ServicePtrs[iDefaultService]->path))
    1616           0 :             || strequal(ServicePtrs[iDefaultService]->path, global_path)) {
    1617       11530 :                 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
    1618             :                                  pszHomedir);
    1619             :         }
    1620       11530 :         TALLOC_FREE(global_path);
    1621             : 
    1622       11530 :         if (!(*(ServicePtrs[i]->comment))) {
    1623           0 :                 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
    1624           0 :                 if (comment == NULL) {
    1625           0 :                         return false;
    1626             :                 }
    1627           0 :                 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment,
    1628             :                                  comment);
    1629           0 :                 TALLOC_FREE(comment);
    1630             :         }
    1631             : 
    1632             :         /* set the browseable flag from the global default */
    1633             : 
    1634       11530 :         ServicePtrs[i]->browseable = sDefault.browseable;
    1635       11530 :         ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
    1636             : 
    1637       11530 :         ServicePtrs[i]->autoloaded = true;
    1638             : 
    1639       11530 :         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
    1640             :                user, ServicePtrs[i]->path ));
    1641             : 
    1642       11530 :         return true;
    1643             : }
    1644             : 
    1645             : /***************************************************************************
    1646             :  Add a new service, based on an old one.
    1647             : ***************************************************************************/
    1648             : 
    1649           0 : int lp_add_service(const char *pszService, int iDefaultService)
    1650             : {
    1651           0 :         if (iDefaultService < 0) {
    1652           0 :                 return add_a_service(&sDefault, pszService);
    1653             :         }
    1654             : 
    1655           0 :         return (add_a_service(ServicePtrs[iDefaultService], pszService));
    1656             : }
    1657             : 
    1658             : /***************************************************************************
    1659             :  Add the IPC service.
    1660             : ***************************************************************************/
    1661             : 
    1662       24133 : static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
    1663             : {
    1664       24133 :         char *comment = NULL;
    1665       24133 :         int i = add_a_service(&sDefault, ipc_name);
    1666             : 
    1667       24133 :         if (i < 0)
    1668           0 :                 return false;
    1669             : 
    1670       24133 :         comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
    1671             :                                   Globals.server_string);
    1672       24133 :         if (comment == NULL) {
    1673           0 :                 return false;
    1674             :         }
    1675             : 
    1676       24133 :         lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
    1677       24133 :         lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
    1678       24133 :         lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
    1679       24133 :         ServicePtrs[i]->max_connections = 0;
    1680       24133 :         ServicePtrs[i]->available = true;
    1681       24133 :         ServicePtrs[i]->read_only = true;
    1682       24133 :         ServicePtrs[i]->guest_only = false;
    1683       24133 :         ServicePtrs[i]->administrative_share = true;
    1684       24133 :         ServicePtrs[i]->guest_ok = guest_ok;
    1685       24133 :         ServicePtrs[i]->printable = false;
    1686       24133 :         ServicePtrs[i]->browseable = sDefault.browseable;
    1687       24133 :         ServicePtrs[i]->autoloaded = false;
    1688             : 
    1689       24133 :         DEBUG(3, ("adding IPC service\n"));
    1690             : 
    1691       24133 :         TALLOC_FREE(comment);
    1692       24133 :         return true;
    1693             : }
    1694             : 
    1695             : /***************************************************************************
    1696             :  Add a new printer service, with defaults coming from service iFrom.
    1697             : ***************************************************************************/
    1698             : 
    1699           0 : bool lp_add_printer(const char *pszPrintername, int iDefaultService)
    1700             : {
    1701           0 :         const char *comment = "From Printcap";
    1702           0 :         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
    1703             : 
    1704           0 :         if (i < 0)
    1705           0 :                 return false;
    1706             : 
    1707             :         /* note that we do NOT default the availability flag to true - */
    1708             :         /* we take it from the default service passed. This allows all */
    1709             :         /* dynamic printers to be disabled by disabling the [printers] */
    1710             :         /* entry (if/when the 'available' keyword is implemented!).    */
    1711             : 
    1712             :         /* the printer name is set to the service name. */
    1713           0 :         lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername,
    1714             :                          pszPrintername);
    1715           0 :         lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
    1716             : 
    1717             :         /* set the browseable flag from the global default */
    1718           0 :         ServicePtrs[i]->browseable = sDefault.browseable;
    1719             : 
    1720             :         /* Printers cannot be read_only. */
    1721           0 :         ServicePtrs[i]->read_only = false;
    1722             :         /* No oplocks on printer services. */
    1723           0 :         ServicePtrs[i]->oplocks = false;
    1724             :         /* Printer services must be printable. */
    1725           0 :         ServicePtrs[i]->printable = true;
    1726             : 
    1727           0 :         DEBUG(3, ("adding printer service %s\n", pszPrintername));
    1728             : 
    1729           0 :         return true;
    1730             : }
    1731             : 
    1732             : 
    1733             : /***************************************************************************
    1734             :  Check whether the given parameter name is valid.
    1735             :  Parametric options (names containing a colon) are considered valid.
    1736             : ***************************************************************************/
    1737             : 
    1738       26473 : bool lp_parameter_is_valid(const char *pszParmName)
    1739             : {
    1740       28573 :         return ((lpcfg_map_parameter(pszParmName) != -1) ||
    1741        2104 :                 (strchr(pszParmName, ':') != NULL));
    1742             : }
    1743             : 
    1744             : /***************************************************************************
    1745             :  Check whether the given name is the name of a global parameter.
    1746             :  Returns true for strings belonging to parameters of class
    1747             :  P_GLOBAL, false for all other strings, also for parametric options
    1748             :  and strings not belonging to any option.
    1749             : ***************************************************************************/
    1750             : 
    1751        2711 : bool lp_parameter_is_global(const char *pszParmName)
    1752             : {
    1753        2711 :         int num = lpcfg_map_parameter(pszParmName);
    1754             : 
    1755        2711 :         if (num >= 0) {
    1756        2403 :                 return (parm_table[num].p_class == P_GLOBAL);
    1757             :         }
    1758             : 
    1759         308 :         return false;
    1760             : }
    1761             : 
    1762             : /**************************************************************************
    1763             :  Determine the canonical name for a parameter.
    1764             :  Indicate when it is an inverse (boolean) synonym instead of a
    1765             :  "usual" synonym.
    1766             : **************************************************************************/
    1767             : 
    1768           0 : bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
    1769             :                                bool *inverse)
    1770             : {
    1771           0 :         int num;
    1772             : 
    1773           0 :         if (!lp_parameter_is_valid(parm_name)) {
    1774           0 :                 *canon_parm = NULL;
    1775           0 :                 return false;
    1776             :         }
    1777             : 
    1778           0 :         num = map_parameter_canonical(parm_name, inverse);
    1779           0 :         if (num < 0) {
    1780             :                 /* parametric option */
    1781           0 :                 *canon_parm = parm_name;
    1782             :         } else {
    1783           0 :                 *canon_parm = parm_table[num].label;
    1784             :         }
    1785             : 
    1786           0 :         return true;
    1787             : 
    1788             : }
    1789             : 
    1790             : /**************************************************************************
    1791             :  Determine the canonical name for a parameter.
    1792             :  Turn the value given into the inverse boolean expression when
    1793             :  the synonym is an inverse boolean synonym.
    1794             : 
    1795             :  Return true if
    1796             :  - parm_name is a valid parameter name and
    1797             :  - val is a valid value for this parameter and
    1798             :  - in case the parameter is an inverse boolean synonym, if the val
    1799             :    string could successfully be converted to the reverse bool.
    1800             :  Return false in all other cases.
    1801             : **************************************************************************/
    1802             : 
    1803        2953 : bool lp_canonicalize_parameter_with_value(const char *parm_name,
    1804             :                                           const char *val,
    1805             :                                           const char **canon_parm,
    1806             :                                           const char **canon_val)
    1807             : {
    1808          21 :         int num;
    1809          21 :         bool inverse;
    1810          21 :         bool ret;
    1811             : 
    1812        2953 :         if (!lp_parameter_is_valid(parm_name)) {
    1813           0 :                 *canon_parm = NULL;
    1814           0 :                 *canon_val = NULL;
    1815           0 :                 return false;
    1816             :         }
    1817             : 
    1818        2953 :         num = map_parameter_canonical(parm_name, &inverse);
    1819        2953 :         if (num < 0) {
    1820             :                 /* parametric option */
    1821         391 :                 *canon_parm = parm_name;
    1822         391 :                 *canon_val = val;
    1823         391 :                 return true;
    1824             :         }
    1825             : 
    1826        2562 :         *canon_parm = parm_table[num].label;
    1827        2562 :         if (inverse) {
    1828         217 :                 if (!lp_invert_boolean(val, canon_val)) {
    1829           0 :                         *canon_val = NULL;
    1830           0 :                         return false;
    1831             :                 }
    1832             :         } else {
    1833        2345 :                 *canon_val = val;
    1834             :         }
    1835             : 
    1836        2562 :         ret = lp_parameter_value_is_valid(*canon_parm, *canon_val);
    1837             : 
    1838        2562 :         return ret;
    1839             : }
    1840             : 
    1841             : /***************************************************************************
    1842             :  Map a parameter's string representation to the index of the canonical
    1843             :  form of the parameter (it might be a synonym).
    1844             :  Returns -1 if the parameter string is not recognised.
    1845             : ***************************************************************************/
    1846             : 
    1847        2953 : static int map_parameter_canonical(const char *pszParmName, bool *inverse)
    1848             : {
    1849          21 :         int parm_num, canon_num;
    1850        2953 :         bool loc_inverse = false;
    1851             : 
    1852        2953 :         parm_num = lpcfg_map_parameter(pszParmName);
    1853        2953 :         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
    1854             :                 /* invalid, parametric or no candidate for synonyms ... */
    1855        2724 :                 goto done;
    1856             :         }
    1857             : 
    1858       85676 :         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
    1859       85676 :                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
    1860         229 :                         parm_num = canon_num;
    1861         229 :                         goto done;
    1862             :                 }
    1863             :         }
    1864             : 
    1865           0 : done:
    1866        2953 :         if (inverse != NULL) {
    1867        2953 :                 *inverse = loc_inverse;
    1868             :         }
    1869        2953 :         return parm_num;
    1870             : }
    1871             : 
    1872             : /***************************************************************************
    1873             :  return true if parameter number parm1 is a synonym of parameter
    1874             :  number parm2 (parm2 being the principal name).
    1875             :  set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
    1876             :  false otherwise.
    1877             : ***************************************************************************/
    1878             : 
    1879       85676 : static bool is_synonym_of(int parm1, int parm2, bool *inverse)
    1880             : {
    1881       85676 :         if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
    1882         470 :             (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
    1883         229 :             (parm_table[parm1].flags & FLAG_SYNONYM) &&
    1884         229 :             !(parm_table[parm2].flags & FLAG_SYNONYM))
    1885             :         {
    1886         229 :                 if (inverse != NULL) {
    1887         229 :                         if ((parm_table[parm1].type == P_BOOLREV) &&
    1888         217 :                             (parm_table[parm2].type == P_BOOL))
    1889             :                         {
    1890         217 :                                 *inverse = true;
    1891             :                         } else {
    1892          12 :                                 *inverse = false;
    1893             :                         }
    1894             :                 }
    1895         229 :                 return true;
    1896             :         }
    1897       85447 :         return false;
    1898             : }
    1899             : 
    1900             : /***************************************************************************
    1901             :  Show one parameter's name, type, [values,] and flags.
    1902             :  (helper functions for show_parameter_list)
    1903             : ***************************************************************************/
    1904             : 
    1905           0 : static void show_parameter(int parmIndex)
    1906             : {
    1907           0 :         size_t enumIndex, flagIndex;
    1908           0 :         size_t parmIndex2;
    1909           0 :         bool hadFlag;
    1910           0 :         bool hadSyn;
    1911           0 :         bool inverse;
    1912           0 :         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
    1913             :                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
    1914             :                 "P_ENUM", "P_BYTES", "P_CMDLIST" };
    1915           0 :         unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
    1916           0 :         const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
    1917             : 
    1918           0 :         printf("%s=%s", parm_table[parmIndex].label,
    1919           0 :                type[parm_table[parmIndex].type]);
    1920           0 :         if (parm_table[parmIndex].type == P_ENUM) {
    1921           0 :                 printf(",");
    1922           0 :                 for (enumIndex=0;
    1923           0 :                      parm_table[parmIndex].enum_list[enumIndex].name;
    1924           0 :                      enumIndex++)
    1925             :                 {
    1926           0 :                         printf("%s%s",
    1927             :                                enumIndex ? "|" : "",
    1928           0 :                                parm_table[parmIndex].enum_list[enumIndex].name);
    1929             :                 }
    1930             :         }
    1931           0 :         printf(",");
    1932           0 :         hadFlag = false;
    1933           0 :         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
    1934           0 :                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
    1935           0 :                         printf("%s%s",
    1936             :                                 hadFlag ? "|" : "",
    1937             :                                 flag_names[flagIndex]);
    1938           0 :                         hadFlag = true;
    1939             :                 }
    1940             :         }
    1941             : 
    1942             :         /* output synonyms */
    1943           0 :         hadSyn = false;
    1944           0 :         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
    1945           0 :                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
    1946           0 :                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
    1947             :                                parm_table[parmIndex2].label);
    1948           0 :                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
    1949           0 :                         if (!hadSyn) {
    1950           0 :                                 printf(" (synonyms: ");
    1951           0 :                                 hadSyn = true;
    1952             :                         } else {
    1953           0 :                                 printf(", ");
    1954             :                         }
    1955           0 :                         printf("%s%s", parm_table[parmIndex2].label,
    1956           0 :                                inverse ? "[i]" : "");
    1957             :                 }
    1958             :         }
    1959           0 :         if (hadSyn) {
    1960           0 :                 printf(")");
    1961             :         }
    1962             : 
    1963           0 :         printf("\n");
    1964           0 : }
    1965             : 
    1966             : /*
    1967             :  * Check the value for a P_ENUM
    1968             :  */
    1969          44 : static bool check_enum_parameter(struct parm_struct *parm, const char *value)
    1970             : {
    1971           6 :         int i;
    1972             : 
    1973         265 :         for (i = 0; parm->enum_list[i].name; i++) {
    1974         265 :                 if (strwicmp(value, parm->enum_list[i].name) == 0) {
    1975          38 :                         return true;
    1976             :                 }
    1977             :         }
    1978           0 :         return false;
    1979             : }
    1980             : 
    1981             : /**************************************************************************
    1982             :  Check whether the given value is valid for the given parameter name.
    1983             : **************************************************************************/
    1984             : 
    1985        2562 : static bool lp_parameter_value_is_valid(const char *parm_name, const char *val)
    1986             : {
    1987        2562 :         bool ret = false, tmp_bool;
    1988        2562 :         int num = lpcfg_map_parameter(parm_name), tmp_int;
    1989        2562 :         uint64_t tmp_int64 = 0;
    1990          20 :         struct parm_struct *parm;
    1991             : 
    1992             :         /* parametric options (parameter names containing a colon) cannot
    1993             :            be checked and are therefore considered valid. */
    1994        2562 :         if (strchr(parm_name, ':') != NULL) {
    1995           0 :                 return true;
    1996             :         }
    1997             : 
    1998        2562 :         if (num >= 0) {
    1999        2562 :                 parm = &parm_table[num];
    2000        2562 :                 switch (parm->type) {
    2001        1045 :                         case P_BOOL:
    2002             :                         case P_BOOLREV:
    2003        1045 :                                 ret = set_boolean(val, &tmp_bool);
    2004        1045 :                                 break;
    2005             : 
    2006          16 :                         case P_INTEGER:
    2007          16 :                                 ret = (sscanf(val, "%d", &tmp_int) == 1);
    2008          16 :                                 break;
    2009             : 
    2010          18 :                         case P_OCTAL:
    2011          18 :                                 ret = (sscanf(val, "%o", &tmp_int) == 1);
    2012          18 :                                 break;
    2013             : 
    2014          44 :                         case P_ENUM:
    2015          44 :                                 ret = check_enum_parameter(parm, val);
    2016          44 :                                 break;
    2017             : 
    2018           6 :                         case P_BYTES:
    2019           6 :                                 if (conv_str_size_error(val, &tmp_int64) &&
    2020           6 :                                     tmp_int64 <= INT_MAX) {
    2021           6 :                                         ret = true;
    2022             :                                 }
    2023           6 :                                 break;
    2024             : 
    2025        1433 :                         case P_CHAR:
    2026             :                         case P_LIST:
    2027             :                         case P_STRING:
    2028             :                         case P_USTRING:
    2029             :                         case P_CMDLIST:
    2030        1433 :                                 ret = true;
    2031        1433 :                                 break;
    2032             :                 }
    2033             :         }
    2034        2542 :         return ret;
    2035             : }
    2036             : 
    2037             : /***************************************************************************
    2038             :  Show all parameter's name, type, [values,] and flags.
    2039             : ***************************************************************************/
    2040             : 
    2041           0 : void show_parameter_list(void)
    2042             : {
    2043           0 :         int classIndex, parmIndex;
    2044           0 :         const char *section_names[] = { "local", "global", NULL};
    2045             : 
    2046           0 :         for (classIndex=0; section_names[classIndex]; classIndex++) {
    2047           0 :                 printf("[%s]\n", section_names[classIndex]);
    2048           0 :                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
    2049           0 :                         if (parm_table[parmIndex].p_class == classIndex) {
    2050           0 :                                 show_parameter(parmIndex);
    2051             :                         }
    2052             :                 }
    2053             :         }
    2054           0 : }
    2055             : 
    2056             : /***************************************************************************
    2057             :  Get the standard string representation of a boolean value ("yes" or "no")
    2058             : ***************************************************************************/
    2059             : 
    2060         217 : static const char *get_boolean(bool bool_value)
    2061             : {
    2062           0 :         static const char *yes_str = "yes";
    2063           0 :         static const char *no_str = "no";
    2064             : 
    2065         217 :         return (bool_value ? yes_str : no_str);
    2066             : }
    2067             : 
    2068             : /***************************************************************************
    2069             :  Provide the string of the negated boolean value associated to the boolean
    2070             :  given as a string. Returns false if the passed string does not correctly
    2071             :  represent a boolean.
    2072             : ***************************************************************************/
    2073             : 
    2074         217 : bool lp_invert_boolean(const char *str, const char **inverse_str)
    2075             : {
    2076           0 :         bool val;
    2077             : 
    2078         217 :         if (!set_boolean(str, &val)) {
    2079           0 :                 return false;
    2080             :         }
    2081             : 
    2082         217 :         *inverse_str = get_boolean(!val);
    2083         217 :         return true;
    2084             : }
    2085             : 
    2086             : /***************************************************************************
    2087             :  Provide the canonical string representation of a boolean value given
    2088             :  as a string. Return true on success, false if the string given does
    2089             :  not correctly represent a boolean.
    2090             : ***************************************************************************/
    2091             : 
    2092           0 : bool lp_canonicalize_boolean(const char *str, const char**canon_str)
    2093             : {
    2094           0 :         bool val;
    2095             : 
    2096           0 :         if (!set_boolean(str, &val)) {
    2097           0 :                 return false;
    2098             :         }
    2099             : 
    2100           0 :         *canon_str = get_boolean(val);
    2101           0 :         return true;
    2102             : }
    2103             : 
    2104             : /***************************************************************************
    2105             : Find a service by name. Otherwise works like get_service.
    2106             : ***************************************************************************/
    2107             : 
    2108     3917121 : int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
    2109             : {
    2110     3917121 :         int iService = -1;
    2111         197 :         char *canon_name;
    2112         197 :         TDB_DATA data;
    2113         197 :         NTSTATUS status;
    2114             : 
    2115     3917121 :         if (ServiceHash == NULL) {
    2116        2232 :                 return -1;
    2117             :         }
    2118             : 
    2119     3914879 :         canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
    2120             : 
    2121     3914879 :         status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
    2122             :                                        &data);
    2123             : 
    2124     3914879 :         if (NT_STATUS_IS_OK(status) &&
    2125     3718723 :             (data.dptr != NULL) &&
    2126     3718723 :             (data.dsize == sizeof(iService)))
    2127             :         {
    2128     3718723 :                 memcpy(&iService, data.dptr, sizeof(iService));
    2129             :         }
    2130             : 
    2131     3914879 :         TALLOC_FREE(canon_name);
    2132             : 
    2133     3914879 :         if ((iService != -1) && (LP_SNUM_OK(iService))
    2134     3718723 :             && (pserviceDest != NULL)) {
    2135           0 :                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
    2136             :         }
    2137             : 
    2138     3914692 :         return (iService);
    2139             : }
    2140             : 
    2141             : /* Return a pointer to a service by name.  Unlike getservicebyname, it does not copy the service */
    2142      878661 : struct loadparm_service *lp_service(const char *pszServiceName)
    2143             : {
    2144      878661 :         int iService = getservicebyname(pszServiceName, NULL);
    2145      878661 :         if (iService == -1 || !LP_SNUM_OK(iService)) {
    2146           1 :                 return NULL;
    2147             :         }
    2148      878611 :         return ServicePtrs[iService];
    2149             : }
    2150             : 
    2151           0 : struct loadparm_service *lp_servicebynum(int snum)
    2152             : {
    2153           0 :         if ((snum == -1) || !LP_SNUM_OK(snum)) {
    2154           0 :                 return NULL;
    2155             :         }
    2156           0 :         return ServicePtrs[snum];
    2157             : }
    2158             : 
    2159           0 : struct loadparm_service *lp_default_loadparm_service(void)
    2160             : {
    2161           0 :         return &sDefault;
    2162             : }
    2163             : 
    2164     2980082 : static struct smbconf_ctx *lp_smbconf_ctx(void)
    2165             : {
    2166           0 :         sbcErr err;
    2167           0 :         static struct smbconf_ctx *conf_ctx = NULL;
    2168             : 
    2169     2980082 :         if (conf_ctx == NULL) {
    2170         441 :                 err = smbconf_init(NULL, &conf_ctx, "registry:");
    2171         441 :                 if (!SBC_ERROR_IS_OK(err)) {
    2172           0 :                         DEBUG(1, ("error initializing registry configuration: "
    2173             :                                   "%s\n", sbcErrorString(err)));
    2174           0 :                         conf_ctx = NULL;
    2175             :                 }
    2176             :         }
    2177             : 
    2178     2980082 :         return conf_ctx;
    2179             : }
    2180             : 
    2181        3232 : static bool process_smbconf_service(struct smbconf_service *service)
    2182             : {
    2183           0 :         uint32_t count;
    2184           0 :         bool ret;
    2185             : 
    2186        3232 :         if (service == NULL) {
    2187           0 :                 return false;
    2188             :         }
    2189             : 
    2190        3232 :         ret = lp_do_section(service->name, NULL);
    2191        3232 :         if (ret != true) {
    2192           0 :                 return false;
    2193             :         }
    2194       16159 :         for (count = 0; count < service->num_params; count++) {
    2195             : 
    2196       12927 :                 if (!bInGlobalSection && bGlobalOnly) {
    2197           0 :                         ret = true;
    2198             :                 } else {
    2199       12927 :                         const char *pszParmName = service->param_names[count];
    2200       12927 :                         const char *pszParmValue = service->param_values[count];
    2201             : 
    2202       12927 :                         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
    2203             : 
    2204       12927 :                         ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
    2205             :                                               pszParmName, pszParmValue);
    2206             :                 }
    2207             : 
    2208       12927 :                 if (ret != true) {
    2209           0 :                         return false;
    2210             :                 }
    2211             :         }
    2212        3232 :         if (iServiceIndex >= 0) {
    2213        3232 :                 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
    2214             :         }
    2215           0 :         return true;
    2216             : }
    2217             : 
    2218             : /**
    2219             :  * load a service from registry and activate it
    2220             :  */
    2221     2979846 : bool process_registry_service(const char *service_name)
    2222             : {
    2223           0 :         sbcErr err;
    2224     2979846 :         struct smbconf_service *service = NULL;
    2225     2979846 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
    2226     2979846 :         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
    2227     2979846 :         bool ret = false;
    2228             : 
    2229     2979846 :         if (conf_ctx == NULL) {
    2230           0 :                 goto done;
    2231             :         }
    2232             : 
    2233     2979846 :         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
    2234             : 
    2235     2979846 :         if (!smbconf_share_exists(conf_ctx, service_name)) {
    2236             :                 /*
    2237             :                  * Registry does not contain data for this service (yet),
    2238             :                  * but make sure lp_load doesn't return false.
    2239             :                  */
    2240     2979022 :                 ret = true;
    2241     2979022 :                 goto done;
    2242             :         }
    2243             : 
    2244         824 :         err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
    2245         824 :         if (!SBC_ERROR_IS_OK(err)) {
    2246           0 :                 goto done;
    2247             :         }
    2248             : 
    2249         824 :         ret = process_smbconf_service(service);
    2250         824 :         if (!ret) {
    2251           0 :                 goto done;
    2252             :         }
    2253             : 
    2254             :         /* store the csn */
    2255         824 :         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
    2256             : 
    2257     2979846 : done:
    2258     2979846 :         TALLOC_FREE(mem_ctx);
    2259     2979846 :         return ret;
    2260             : }
    2261             : 
    2262             : /*
    2263             :  * process_registry_globals
    2264             :  */
    2265           0 : static bool process_registry_globals(void)
    2266             : {
    2267           0 :         bool ret;
    2268             : 
    2269           0 :         add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
    2270             : 
    2271           0 :         if (!bInGlobalSection && bGlobalOnly) {
    2272           0 :                 ret = true;
    2273             :         } else {
    2274           0 :                 const char *pszParmName = "registry shares";
    2275           0 :                 const char *pszParmValue = "yes";
    2276             : 
    2277           0 :                 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
    2278             : 
    2279           0 :                 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
    2280             :                                       pszParmName, pszParmValue);
    2281             :         }
    2282             : 
    2283           0 :         if (!ret) {
    2284           0 :                 return ret;
    2285             :         }
    2286             : 
    2287           0 :         return process_registry_service(GLOBAL_NAME);
    2288             : }
    2289             : 
    2290         236 : bool process_registry_shares(void)
    2291             : {
    2292           0 :         sbcErr err;
    2293           0 :         uint32_t count;
    2294         236 :         struct smbconf_service **service = NULL;
    2295         236 :         uint32_t num_shares = 0;
    2296         236 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
    2297         236 :         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
    2298         236 :         bool ret = false;
    2299             : 
    2300         236 :         if (conf_ctx == NULL) {
    2301           0 :                 goto done;
    2302             :         }
    2303             : 
    2304         236 :         err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
    2305         236 :         if (!SBC_ERROR_IS_OK(err)) {
    2306           0 :                 goto done;
    2307             :         }
    2308             : 
    2309         236 :         ret = true;
    2310             : 
    2311        2656 :         for (count = 0; count < num_shares; count++) {
    2312        2420 :                 if (strequal(service[count]->name, GLOBAL_NAME)) {
    2313          12 :                         continue;
    2314             :                 }
    2315        2408 :                 ret = process_smbconf_service(service[count]);
    2316        2408 :                 if (!ret) {
    2317           0 :                         goto done;
    2318             :                 }
    2319             :         }
    2320             : 
    2321             :         /* store the csn */
    2322         236 :         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
    2323             : 
    2324         236 : done:
    2325         236 :         TALLOC_FREE(mem_ctx);
    2326         236 :         return ret;
    2327             : }
    2328             : 
    2329             : /**
    2330             :  * reload those shares from registry that are already
    2331             :  * activated in the services array.
    2332             :  */
    2333       29240 : static bool reload_registry_shares(void)
    2334             : {
    2335           0 :         int i;
    2336       29240 :         bool ret = true;
    2337             : 
    2338     3005081 :         for (i = 0; i < iNumServices; i++) {
    2339     2975841 :                 if (!VALID(i)) {
    2340        6090 :                         continue;
    2341             :                 }
    2342             : 
    2343     2969751 :                 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
    2344           0 :                         continue;
    2345             :                 }
    2346             : 
    2347     2969751 :                 ret = process_registry_service(ServicePtrs[i]->szService);
    2348     2969751 :                 if (!ret) {
    2349           0 :                         goto done;
    2350             :                 }
    2351             :         }
    2352             : 
    2353       29240 : done:
    2354       29240 :         return ret;
    2355             : }
    2356             : 
    2357             : 
    2358             : #define MAX_INCLUDE_DEPTH 100
    2359             : 
    2360             : static uint8_t include_depth;
    2361             : 
    2362             : /**
    2363             :  * Free the file lists
    2364             :  */
    2365       68698 : static void free_file_list(void)
    2366             : {
    2367         134 :         struct file_lists *f;
    2368         134 :         struct file_lists *next;
    2369             : 
    2370       68698 :         f = file_lists;
    2371      233865 :         while( f ) {
    2372      165167 :                 next = f->next;
    2373      165167 :                 TALLOC_FREE( f );
    2374      165167 :                 f = next;
    2375             :         }
    2376       68698 :         file_lists = NULL;
    2377       68564 : }
    2378             : 
    2379             : 
    2380             : /**
    2381             :  * Utility function for outsiders to check if we're running on registry.
    2382             :  */
    2383       51026 : bool lp_config_backend_is_registry(void)
    2384             : {
    2385       51026 :         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
    2386             : }
    2387             : 
    2388             : /**
    2389             :  * Utility function to check if the config backend is FILE.
    2390             :  */
    2391       50924 : bool lp_config_backend_is_file(void)
    2392             : {
    2393       50924 :         return (lp_config_backend() == CONFIG_BACKEND_FILE);
    2394             : }
    2395             : 
    2396             : /*******************************************************************
    2397             :  Check if a config file has changed date.
    2398             : ********************************************************************/
    2399             : 
    2400      152919 : bool lp_file_list_changed(void)
    2401             : {
    2402      152919 :         struct file_lists *f = file_lists;
    2403             : 
    2404      152919 :         DEBUG(6, ("lp_file_list_changed()\n"));
    2405             : 
    2406      856631 :         while (f) {
    2407      704135 :                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
    2408           0 :                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
    2409             : 
    2410           0 :                         if (conf_ctx == NULL) {
    2411           0 :                                 return false;
    2412             :                         }
    2413           0 :                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
    2414             :                                             NULL))
    2415             :                         {
    2416           0 :                                 DEBUGADD(6, ("registry config changed\n"));
    2417           0 :                                 return true;
    2418             :                         }
    2419             :                 } else {
    2420      704135 :                         struct timespec mod_time = {
    2421             :                                 .tv_sec = 0,
    2422             :                         };
    2423      704135 :                         struct timeval_buf tbuf = {
    2424             :                                 .buf = {0},
    2425             :                         };
    2426      704135 :                         char *n2 = NULL;
    2427      704135 :                         struct stat sb = {0};
    2428        3885 :                         int rc;
    2429             : 
    2430      704135 :                         n2 = talloc_sub_basic(talloc_tos(),
    2431             :                                               get_current_username(),
    2432             :                                               get_current_user_info_domain(),
    2433      704135 :                                               f->name);
    2434      704135 :                         if (!n2) {
    2435         423 :                                 return false;
    2436             :                         }
    2437      704135 :                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
    2438             :                                      f->name, n2,
    2439             :                                      timespec_string_buf(&f->modtime,
    2440             :                                                          true,
    2441             :                                                          &tbuf)));
    2442             : 
    2443      704135 :                         rc = stat(n2, &sb);
    2444      704135 :                         if (rc == 0) {
    2445      592468 :                                 mod_time = get_mtimespec(&sb);
    2446             :                         }
    2447             : 
    2448     1296603 :                         if (mod_time.tv_sec > 0 &&
    2449      592468 :                             ((timespec_compare(&mod_time, &f->modtime) != 0) ||
    2450      592045 :                              (f->subfname == NULL) ||
    2451      592045 :                              (strcmp(n2, f->subfname) != 0)))
    2452             :                         {
    2453         423 :                                 f->modtime = mod_time;
    2454             : 
    2455         423 :                                 DEBUGADD(6,
    2456             :                                          ("file %s modified: %s\n", n2,
    2457             :                                           timespec_string_buf(&f->modtime,
    2458             :                                                               true,
    2459             :                                                               &tbuf)));
    2460             : 
    2461         423 :                                 TALLOC_FREE(f->subfname);
    2462         423 :                                 f->subfname = talloc_strdup(f, n2);
    2463         423 :                                 if (f->subfname == NULL) {
    2464           0 :                                         smb_panic("talloc_strdup failed");
    2465             :                                 }
    2466         423 :                                 TALLOC_FREE(n2);
    2467         423 :                                 return true;
    2468             :                         }
    2469      703712 :                         TALLOC_FREE(n2);
    2470             :                 }
    2471      703712 :                 f = f->next;
    2472             :         }
    2473      148611 :         return false;
    2474             : }
    2475             : 
    2476             : 
    2477             : /**
    2478             :  * Initialize iconv conversion descriptors.
    2479             :  *
    2480             :  * This is called the first time it is needed, and also called again
    2481             :  * every time the configuration is reloaded, because the charset or
    2482             :  * codepage might have changed.
    2483             :  **/
    2484       50924 : static void init_iconv(void)
    2485             : {
    2486       50924 :         struct smb_iconv_handle *ret = NULL;
    2487             : 
    2488       50924 :         ret = reinit_iconv_handle(NULL,
    2489             :                                   lp_dos_charset(),
    2490             :                                   lp_unix_charset());
    2491       50924 :         if (ret == NULL) {
    2492           0 :                 smb_panic("reinit_iconv_handle failed");
    2493             :         }
    2494       50924 : }
    2495             : 
    2496             : /***************************************************************************
    2497             :  Handle the include operation.
    2498             : ***************************************************************************/
    2499             : static bool bAllowIncludeRegistry = true;
    2500             : 
    2501      172728 : bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
    2502             :                 const char *pszParmValue, char **ptr)
    2503             : {
    2504           0 :         char *fname;
    2505             : 
    2506      172728 :         if (include_depth >= MAX_INCLUDE_DEPTH) {
    2507           0 :                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
    2508             :                           include_depth));
    2509           0 :                 return false;
    2510             :         }
    2511             : 
    2512      172728 :         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
    2513           0 :                 if (!bAllowIncludeRegistry) {
    2514           0 :                         return true;
    2515             :                 }
    2516           0 :                 if (lp_ctx->bInGlobalSection) {
    2517           0 :                         bool ret;
    2518           0 :                         include_depth++;
    2519           0 :                         ret = process_registry_globals();
    2520           0 :                         include_depth--;
    2521           0 :                         return ret;
    2522             :                 } else {
    2523           0 :                         DEBUG(1, ("\"include = registry\" only effective "
    2524             :                                   "in %s section\n", GLOBAL_NAME));
    2525           0 :                         return false;
    2526             :                 }
    2527             :         }
    2528             : 
    2529      172728 :         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
    2530             :                                  get_current_user_info_domain(),
    2531             :                                  pszParmValue);
    2532             : 
    2533      172728 :         add_to_file_list(NULL, &file_lists, pszParmValue, fname);
    2534             : 
    2535      172728 :         if (service == NULL) {
    2536       29382 :                 lpcfg_string_set(Globals.ctx, ptr, fname);
    2537             :         } else {
    2538      143346 :                 lpcfg_string_set(service, ptr, fname);
    2539             :         }
    2540             : 
    2541      172728 :         if (file_exist(fname)) {
    2542           0 :                 bool ret;
    2543      148497 :                 include_depth++;
    2544      148497 :                 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
    2545      148497 :                 include_depth--;
    2546      148497 :                 TALLOC_FREE(fname);
    2547      148497 :                 return ret;
    2548             :         }
    2549             : 
    2550       24231 :         DEBUG(2, ("Can't find include file %s\n", fname));
    2551       24231 :         TALLOC_FREE(fname);
    2552       24231 :         return true;
    2553             : }
    2554             : 
    2555        2506 : bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
    2556             : {
    2557        2506 :         char *config_option = NULL;
    2558        2506 :         const char *range = NULL;
    2559        2506 :         bool ret = false;
    2560             : 
    2561        2506 :         SMB_ASSERT(low != NULL);
    2562        2506 :         SMB_ASSERT(high != NULL);
    2563             : 
    2564        2506 :         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
    2565           0 :                 domain_name = "*";
    2566             :         }
    2567             : 
    2568        2506 :         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
    2569             :                                         domain_name);
    2570        2506 :         if (config_option == NULL) {
    2571           0 :                 DEBUG(0, ("out of memory\n"));
    2572           0 :                 return false;
    2573             :         }
    2574             : 
    2575        2506 :         range = lp_parm_const_string(-1, config_option, "range", NULL);
    2576        2506 :         if (range == NULL) {
    2577        2200 :                 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
    2578        2200 :                 goto done;
    2579             :         }
    2580             : 
    2581         306 :         if (sscanf(range, "%u - %u", low, high) != 2) {
    2582           0 :                 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
    2583             :                           range, domain_name));
    2584           0 :                 goto done;
    2585             :         }
    2586             : 
    2587         306 :         ret = true;
    2588             : 
    2589        2506 : done:
    2590        2506 :         talloc_free(config_option);
    2591        2506 :         return ret;
    2592             : 
    2593             : }
    2594             : 
    2595        2502 : bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
    2596             : {
    2597        2502 :         return lp_idmap_range("*", low, high);
    2598             : }
    2599             : 
    2600          57 : const char *lp_idmap_backend(const char *domain_name)
    2601             : {
    2602          57 :         char *config_option = NULL;
    2603          57 :         const char *backend = NULL;
    2604             : 
    2605          57 :         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
    2606           0 :                 domain_name = "*";
    2607             :         }
    2608             : 
    2609          57 :         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
    2610             :                                         domain_name);
    2611          57 :         if (config_option == NULL) {
    2612           0 :                 DEBUG(0, ("out of memory\n"));
    2613           0 :                 return false;
    2614             :         }
    2615             : 
    2616          57 :         backend = lp_parm_const_string(-1, config_option, "backend", NULL);
    2617          57 :         if (backend == NULL) {
    2618           0 :                 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
    2619           0 :                 goto done;
    2620             :         }
    2621             : 
    2622          57 : done:
    2623          57 :         talloc_free(config_option);
    2624          57 :         return backend;
    2625             : }
    2626             : 
    2627          53 : const char *lp_idmap_default_backend(void)
    2628             : {
    2629          53 :         return lp_idmap_backend("*");
    2630             : }
    2631             : 
    2632             : /***************************************************************************
    2633             :  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
    2634             : ***************************************************************************/
    2635             : 
    2636           0 : static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
    2637             : {
    2638           0 :         const char *suffix_string;
    2639             : 
    2640           0 :         suffix_string = talloc_asprintf(ctx, "%s,%s", str,
    2641             :                                         Globals.ldap_suffix );
    2642           0 :         if ( !suffix_string ) {
    2643           0 :                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
    2644           0 :                 return "";
    2645             :         }
    2646             : 
    2647           0 :         return suffix_string;
    2648             : }
    2649             : 
    2650           0 : const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
    2651             : {
    2652           0 :         if (Globals._ldap_machine_suffix[0])
    2653           0 :                 return append_ldap_suffix(ctx, Globals._ldap_machine_suffix);
    2654             : 
    2655           0 :         return talloc_strdup(ctx, Globals.ldap_suffix);
    2656             : }
    2657             : 
    2658           0 : const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
    2659             : {
    2660           0 :         if (Globals._ldap_user_suffix[0])
    2661           0 :                 return append_ldap_suffix(ctx, Globals._ldap_user_suffix);
    2662             : 
    2663           0 :         return talloc_strdup(ctx, Globals.ldap_suffix);
    2664             : }
    2665             : 
    2666           0 : const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
    2667             : {
    2668           0 :         if (Globals._ldap_group_suffix[0])
    2669           0 :                 return append_ldap_suffix(ctx, Globals._ldap_group_suffix);
    2670             : 
    2671           0 :         return talloc_strdup(ctx, Globals.ldap_suffix);
    2672             : }
    2673             : 
    2674           0 : const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
    2675             : {
    2676           0 :         if (Globals._ldap_idmap_suffix[0])
    2677           0 :                 return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix);
    2678             : 
    2679           0 :         return talloc_strdup(ctx, Globals.ldap_suffix);
    2680             : }
    2681             : 
    2682             : /**
    2683             :   return the parameter pointer for a parameter
    2684             : */
    2685    73511490 : void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
    2686             : {
    2687    73511490 :         if (service == NULL) {
    2688    51407538 :                 if (parm->p_class == P_LOCAL)
    2689    14578102 :                         return (void *)(((char *)&sDefault)+parm->offset);
    2690    36829436 :                 else if (parm->p_class == P_GLOBAL)
    2691    36829436 :                         return (void *)(((char *)&Globals)+parm->offset);
    2692           0 :                 else return NULL;
    2693             :         } else {
    2694    22103952 :                 return (void *)(((char *)service) + parm->offset);
    2695             :         }
    2696             : }
    2697             : 
    2698             : /***************************************************************************
    2699             :  Process a parameter for a particular service number. If snum < 0
    2700             :  then assume we are in the globals.
    2701             : ***************************************************************************/
    2702             : 
    2703      418717 : bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
    2704             : {
    2705      418717 :         TALLOC_CTX *frame = talloc_stackframe();
    2706        4099 :         struct loadparm_context *lp_ctx;
    2707        4099 :         bool ok;
    2708             : 
    2709      418717 :         lp_ctx = setup_lp_context(frame);
    2710      418717 :         if (lp_ctx == NULL) {
    2711           0 :                 TALLOC_FREE(frame);
    2712           0 :                 return false;
    2713             :         }
    2714             : 
    2715      418717 :         if (snum < 0) {
    2716      188358 :                 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
    2717             :         } else {
    2718      230359 :                 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
    2719             :                                                 pszParmName, pszParmValue);
    2720             :         }
    2721             : 
    2722      418717 :         TALLOC_FREE(frame);
    2723             : 
    2724      414618 :         return ok;
    2725             : }
    2726             : 
    2727             : /***************************************************************************
    2728             : set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
    2729             : FLAG_CMDLINE won't be overridden by loads from smb.conf.
    2730             : ***************************************************************************/
    2731             : 
    2732       56733 : static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
    2733             : {
    2734          88 :         int parmnum, i;
    2735       56733 :         parmnum = lpcfg_map_parameter(pszParmName);
    2736       56733 :         if (parmnum >= 0) {
    2737       56094 :                 flags_list[parmnum] &= ~FLAG_CMDLINE;
    2738       56094 :                 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
    2739           0 :                         return false;
    2740             :                 }
    2741       56094 :                 flags_list[parmnum] |= FLAG_CMDLINE;
    2742             : 
    2743             :                 /* we have to also set FLAG_CMDLINE on aliases.  Aliases must
    2744             :                  * be grouped in the table, so we don't have to search the
    2745             :                  * whole table */
    2746       56094 :                 for (i=parmnum-1;
    2747       56091 :                      i>=0 && parm_table[i].offset == parm_table[parmnum].offset
    2748       56094 :                              && parm_table[i].p_class == parm_table[parmnum].p_class;
    2749           0 :                      i--) {
    2750           0 :                         flags_list[i] |= FLAG_CMDLINE;
    2751             :                 }
    2752      155823 :                 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
    2753       99778 :                              && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
    2754       21842 :                         flags_list[i] |= FLAG_CMDLINE;
    2755             :                 }
    2756             : 
    2757       56012 :                 return true;
    2758             :         }
    2759             : 
    2760             :         /* it might be parametric */
    2761         639 :         if (strchr(pszParmName, ':') != NULL) {
    2762         639 :                 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
    2763         639 :                 return true;
    2764             :         }
    2765             : 
    2766           0 :         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
    2767           0 :         return false;
    2768             : }
    2769             : 
    2770             : /***************************************************************************
    2771             :  Process a parameter.
    2772             : ***************************************************************************/
    2773             : 
    2774    18329006 : static bool do_parameter(const char *pszParmName, const char *pszParmValue,
    2775             :                          void *userdata)
    2776             : {
    2777    18329006 :         if (!bInGlobalSection && bGlobalOnly)
    2778     2540385 :                 return true;
    2779             : 
    2780    15788605 :         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
    2781             : 
    2782    15788605 :         if (bInGlobalSection) {
    2783     3913630 :                 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
    2784             :         } else {
    2785    11874975 :                 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
    2786             :                                                   pszParmName, pszParmValue);
    2787             :         }
    2788             : }
    2789             : 
    2790             : 
    2791             : static const char *ad_dc_req_vfs_mods[] = {"dfs_samba4", "acl_xattr", NULL};
    2792             : 
    2793             : /*
    2794             :  * check that @vfs_objects includes all vfs modules required by an AD DC.
    2795             :  */
    2796        4047 : static bool check_ad_dc_required_mods(const char **vfs_objects)
    2797             : {
    2798          10 :         int i;
    2799          10 :         int j;
    2800          10 :         int got_req;
    2801             : 
    2802       12137 :         for (i = 0; ad_dc_req_vfs_mods[i] != NULL; i++) {
    2803        8104 :                 got_req = false;
    2804       12141 :                 for (j = 0; vfs_objects[j] != NULL; j++) {
    2805       12139 :                         if (!strwicmp(ad_dc_req_vfs_mods[i], vfs_objects[j])) {
    2806        8074 :                                 got_req = true;
    2807        8074 :                                 break;
    2808             :                         }
    2809             :                 }
    2810        8092 :                 if (!got_req) {
    2811           2 :                         DEBUG(0, ("vfs objects specified without required AD "
    2812             :                                   "DC module: %s\n", ad_dc_req_vfs_mods[i]));
    2813           2 :                         return false;
    2814             :                 }
    2815             :         }
    2816             : 
    2817        4045 :         DEBUG(6, ("vfs objects specified with all required AD DC modules\n"));
    2818        4037 :         return true;
    2819             : }
    2820             : 
    2821             : 
    2822             : /***************************************************************************
    2823             :  Initialize any local variables in the sDefault table, after parsing a
    2824             :  [globals] section.
    2825             : ***************************************************************************/
    2826             : 
    2827       40165 : static void init_locals(void)
    2828             : {
    2829             :         /*
    2830             :          * We run this check once the [globals] is parsed, to force
    2831             :          * the VFS objects and other per-share settings we need for
    2832             :          * the standard way a AD DC is operated.  We may change these
    2833             :          * as our code evolves, which is why we force these settings.
    2834             :          *
    2835             :          * We can't do this at the end of lp_load_ex(), as by that
    2836             :          * point the services have been loaded and they will already
    2837             :          * have "" as their vfs objects.
    2838             :          */
    2839       40165 :         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
    2840        4053 :                 const char **vfs_objects = lp_vfs_objects(-1);
    2841        4053 :                 if (vfs_objects != NULL) {
    2842             :                         /* ignore return, only warn if modules are missing */
    2843        4047 :                         check_ad_dc_required_mods(vfs_objects);
    2844             :                 } else {
    2845           6 :                         if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
    2846           0 :                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
    2847           6 :                         } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
    2848           0 :                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
    2849             :                         } else {
    2850           6 :                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
    2851             :                         }
    2852             :                 }
    2853             : 
    2854        4053 :                 lp_do_parameter(-1, "map hidden", "no");
    2855        4053 :                 lp_do_parameter(-1, "map system", "no");
    2856        4053 :                 lp_do_parameter(-1, "map readonly", "no");
    2857        4053 :                 lp_do_parameter(-1, "map archive", "no");
    2858        4053 :                 lp_do_parameter(-1, "store dos attributes", "yes");
    2859             :         }
    2860       40165 : }
    2861             : 
    2862             : /***************************************************************************
    2863             :  Process a new section (service). At this stage all sections are services.
    2864             :  Later we'll have special sections that permit server parameters to be set.
    2865             :  Returns true on success, false on failure.
    2866             : ***************************************************************************/
    2867             : 
    2868     3703587 : bool lp_do_section(const char *pszSectionName, void *userdata)
    2869             : {
    2870     3703587 :         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
    2871         287 :         bool bRetval;
    2872     7349751 :         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
    2873     3646164 :                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
    2874             : 
    2875             :         /* if we were in a global section then do the local inits */
    2876     3703587 :         if (bInGlobalSection && !isglobal)
    2877       38113 :                 init_locals();
    2878             : 
    2879             :         /* if we've just struck a global section, note the fact. */
    2880     3703587 :         bInGlobalSection = isglobal;
    2881     3703587 :         if (lp_ctx != NULL) {
    2882     3700355 :                 lp_ctx->bInGlobalSection = isglobal;
    2883             :         }
    2884             : 
    2885             :         /* check for multiple global sections */
    2886     3703587 :         if (bInGlobalSection) {
    2887       57423 :                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
    2888       57423 :                 return true;
    2889             :         }
    2890             : 
    2891     3646164 :         if (!bInGlobalSection && bGlobalOnly)
    2892      643361 :                 return true;
    2893             : 
    2894             :         /* if we have a current service, tidy it up before moving on */
    2895     3002795 :         bRetval = true;
    2896             : 
    2897     3002795 :         if ((iServiceIndex >= 0) && (ServicePtrs[iServiceIndex] != NULL))
    2898     2975046 :                 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
    2899             : 
    2900             :         /* if all is still well, move to the next record in the services array */
    2901     3002773 :         if (bRetval) {
    2902             :                 /* We put this here to avoid an odd message order if messages are */
    2903             :                 /* issued by the post-processing of a previous section. */
    2904     3002795 :                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
    2905             : 
    2906     3002795 :                 iServiceIndex = add_a_service(&sDefault, pszSectionName);
    2907     3002795 :                 if (iServiceIndex < 0) {
    2908           0 :                         DEBUG(0, ("Failed to add a new service\n"));
    2909           0 :                         return false;
    2910             :                 }
    2911             :                 /* Clean all parametric options for service */
    2912             :                 /* They will be added during parsing again */
    2913     3002795 :                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
    2914             :         }
    2915             : 
    2916     3002647 :         return bRetval;
    2917             : }
    2918             : 
    2919             : /***************************************************************************
    2920             :  Display the contents of a parameter of a single services record.
    2921             : ***************************************************************************/
    2922             : 
    2923        1430 : bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
    2924             : {
    2925        1430 :         bool result = false;
    2926           4 :         struct loadparm_context *lp_ctx;
    2927             : 
    2928        1430 :         lp_ctx = setup_lp_context(talloc_tos());
    2929        1430 :         if (lp_ctx == NULL) {
    2930           0 :                 return false;
    2931             :         }
    2932             : 
    2933        1430 :         if (isGlobal) {
    2934        1026 :                 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
    2935             :         } else {
    2936         404 :                 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
    2937             :         }
    2938        1430 :         TALLOC_FREE(lp_ctx);
    2939        1430 :         return result;
    2940             : }
    2941             : 
    2942             : #if 0
    2943             : /***************************************************************************
    2944             :  Display the contents of a single copy structure.
    2945             : ***************************************************************************/
    2946             : static void dump_copy_map(bool *pcopymap)
    2947             : {
    2948             :         int i;
    2949             :         if (!pcopymap)
    2950             :                 return;
    2951             : 
    2952             :         printf("\n\tNon-Copied parameters:\n");
    2953             : 
    2954             :         for (i = 0; parm_table[i].label; i++)
    2955             :                 if (parm_table[i].p_class == P_LOCAL &&
    2956             :                     parm_table[i].ptr && !pcopymap[i] &&
    2957             :                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
    2958             :                 {
    2959             :                         printf("\t\t%s\n", parm_table[i].label);
    2960             :                 }
    2961             : }
    2962             : #endif
    2963             : 
    2964             : /***************************************************************************
    2965             :  Return TRUE if the passed service number is within range.
    2966             : ***************************************************************************/
    2967             : 
    2968     2176388 : bool lp_snum_ok(int iService)
    2969             : {
    2970     2176388 :         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->available);
    2971             : }
    2972             : 
    2973             : /***************************************************************************
    2974             :  Auto-load some home services.
    2975             : ***************************************************************************/
    2976             : 
    2977       50924 : static void lp_add_auto_services(const char *str)
    2978             : {
    2979         125 :         char *s;
    2980         125 :         char *p;
    2981         125 :         int homes;
    2982         125 :         char *saveptr;
    2983             : 
    2984       50924 :         if (!str)
    2985           0 :                 return;
    2986             : 
    2987       50924 :         s = talloc_strdup(talloc_tos(), str);
    2988       50924 :         if (!s) {
    2989           0 :                 smb_panic("talloc_strdup failed");
    2990             :                 return;
    2991             :         }
    2992             : 
    2993       50924 :         homes = lp_servicenumber(HOMES_NAME);
    2994             : 
    2995       50926 :         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
    2996           2 :              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
    2997           0 :                 char *home;
    2998             : 
    2999           2 :                 if (lp_servicenumber(p) >= 0)
    3000           0 :                         continue;
    3001             : 
    3002           2 :                 home = get_user_home_dir(talloc_tos(), p);
    3003             : 
    3004           2 :                 if (home && home[0] && homes >= 0)
    3005           0 :                         lp_add_home(p, homes, p, home);
    3006             : 
    3007           2 :                 TALLOC_FREE(home);
    3008             :         }
    3009       50924 :         TALLOC_FREE(s);
    3010             : }
    3011             : 
    3012             : /***************************************************************************
    3013             :  Auto-load one printer.
    3014             : ***************************************************************************/
    3015             : 
    3016           0 : void lp_add_one_printer(const char *name, const char *comment,
    3017             :                         const char *location, void *pdata)
    3018             : {
    3019           0 :         int printers = lp_servicenumber(PRINTERS_NAME);
    3020           0 :         int i;
    3021             : 
    3022           0 :         if (lp_servicenumber(name) < 0) {
    3023           0 :                 lp_add_printer(name, printers);
    3024           0 :                 if ((i = lp_servicenumber(name)) >= 0) {
    3025           0 :                         lpcfg_string_set(ServicePtrs[i],
    3026           0 :                                          &ServicePtrs[i]->comment, comment);
    3027           0 :                         ServicePtrs[i]->autoloaded = true;
    3028             :                 }
    3029             :         }
    3030           0 : }
    3031             : 
    3032             : /***************************************************************************
    3033             :  Have we loaded a services file yet?
    3034             : ***************************************************************************/
    3035             : 
    3036      315443 : bool lp_loaded(void)
    3037             : {
    3038      315443 :         return (b_loaded);
    3039             : }
    3040             : 
    3041             : /***************************************************************************
    3042             :  Unload unused services.
    3043             : ***************************************************************************/
    3044             : 
    3045        1407 : void lp_killunused(struct smbd_server_connection *sconn,
    3046             :                    bool (*snumused) (struct smbd_server_connection *, int))
    3047             : {
    3048           0 :         int i;
    3049      136586 :         for (i = 0; i < iNumServices; i++) {
    3050      135179 :                 if (!VALID(i))
    3051         804 :                         continue;
    3052             : 
    3053             :                 /* don't kill autoloaded or usershare services */
    3054      134375 :                 if ( ServicePtrs[i]->autoloaded ||
    3055      134367 :                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
    3056           8 :                         continue;
    3057             :                 }
    3058             : 
    3059      134367 :                 if (!snumused || !snumused(sconn, i)) {
    3060      128781 :                         free_service_byindex(i);
    3061             :                 }
    3062             :         }
    3063        1407 : }
    3064             : 
    3065             : /**
    3066             :  * Kill all except autoloaded and usershare services - convenience wrapper
    3067             :  */
    3068         203 : void lp_kill_all_services(void)
    3069             : {
    3070         203 :         lp_killunused(NULL, NULL);
    3071         203 : }
    3072             : 
    3073             : /***************************************************************************
    3074             :  Unload a service.
    3075             : ***************************************************************************/
    3076             : 
    3077          22 : void lp_killservice(int iServiceIn)
    3078             : {
    3079          22 :         if (VALID(iServiceIn)) {
    3080          22 :                 free_service_byindex(iServiceIn);
    3081             :         }
    3082          22 : }
    3083             : 
    3084             : /***************************************************************************
    3085             :  Save the current values of all global and sDefault parameters into the
    3086             :  defaults union. This allows testparm to show only the
    3087             :  changed (ie. non-default) parameters.
    3088             : ***************************************************************************/
    3089             : 
    3090        2052 : static void lp_save_defaults(void)
    3091             : {
    3092           5 :         int i;
    3093           5 :         struct parmlist_entry * parm;
    3094     1071144 :         for (i = 0; parm_table[i].label; i++) {
    3095     1069092 :                 if (!(flags_list[i] & FLAG_CMDLINE)) {
    3096     1063577 :                         flags_list[i] |= FLAG_DEFAULT;
    3097             :                 }
    3098             : 
    3099     1069092 :                 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
    3100       71820 :                     && parm_table[i].p_class == parm_table[i - 1].p_class)
    3101       71820 :                         continue;
    3102      997272 :                 switch (parm_table[i].type) {
    3103       86184 :                         case P_LIST:
    3104             :                         case P_CMDLIST:
    3105       86184 :                                 parm_table[i].def.lvalue = str_list_copy(
    3106       86184 :                                         NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
    3107       86184 :                                 break;
    3108      264708 :                         case P_STRING:
    3109             :                         case P_USTRING:
    3110      264708 :                                 lpcfg_string_set(
    3111             :                                         Globals.ctx,
    3112             :                                         &parm_table[i].def.svalue,
    3113      264708 :                                         *(char **)lp_parm_ptr(
    3114             :                                                 NULL, &parm_table[i]));
    3115      264708 :                                 if (parm_table[i].def.svalue == NULL) {
    3116           0 :                                         smb_panic("lpcfg_string_set() failed");
    3117             :                                 }
    3118      264063 :                                 break;
    3119      361152 :                         case P_BOOL:
    3120             :                         case P_BOOLREV:
    3121      362032 :                                 parm_table[i].def.bvalue =
    3122      361152 :                                         *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
    3123      361152 :                                 break;
    3124        2052 :                         case P_CHAR:
    3125        2057 :                                 parm_table[i].def.cvalue =
    3126        2052 :                                         *(char *)lp_parm_ptr(NULL, &parm_table[i]);
    3127        2052 :                                 break;
    3128      283176 :                         case P_INTEGER:
    3129             :                         case P_OCTAL:
    3130             :                         case P_ENUM:
    3131             :                         case P_BYTES:
    3132      283866 :                                 parm_table[i].def.ivalue =
    3133      283176 :                                         *(int *)lp_parm_ptr(NULL, &parm_table[i]);
    3134      283176 :                                 break;
    3135             :                 }
    3136             :         }
    3137             : 
    3138        2176 :         for (parm=Globals.param_opt; parm; parm=parm->next) {
    3139         124 :                 if (!(parm->priority & FLAG_CMDLINE)) {
    3140           9 :                         parm->priority |= FLAG_DEFAULT;
    3141             :                 }
    3142             :         }
    3143             : 
    3144        2052 :         for (parm=sDefault.param_opt; parm; parm=parm->next) {
    3145           0 :                 if (!(parm->priority & FLAG_CMDLINE)) {
    3146           0 :                         parm->priority |= FLAG_DEFAULT;
    3147             :                 }
    3148             :         }
    3149             : 
    3150        2052 :         defaults_saved = true;
    3151        2052 : }
    3152             : 
    3153             : /***********************************************************
    3154             :  If we should send plaintext/LANMAN passwords in the client
    3155             : ************************************************************/
    3156             : 
    3157       50924 : static void set_allowed_client_auth(void)
    3158             : {
    3159       50924 :         if (Globals.client_ntlmv2_auth) {
    3160       50528 :                 Globals.client_lanman_auth = false;
    3161             :         }
    3162       50924 :         if (!Globals.client_lanman_auth) {
    3163       50534 :                 Globals.client_plaintext_auth = false;
    3164             :         }
    3165       50799 : }
    3166             : 
    3167             : /***************************************************************************
    3168             :  JRA.
    3169             :  The following code allows smbd to read a user defined share file.
    3170             :  Yes, this is my intent. Yes, I'm comfortable with that...
    3171             : 
    3172             :  THE FOLLOWING IS SECURITY CRITICAL CODE.
    3173             : 
    3174             :  It washes your clothes, it cleans your house, it guards you while you sleep...
    3175             :  Do not f%^k with it....
    3176             : ***************************************************************************/
    3177             : 
    3178             : #define MAX_USERSHARE_FILE_SIZE (10*1024)
    3179             : 
    3180             : /***************************************************************************
    3181             :  Check allowed stat state of a usershare file.
    3182             :  Ensure we print out who is dicking with us so the admin can
    3183             :  get their sorry ass fired.
    3184             : ***************************************************************************/
    3185             : 
    3186           4 : static bool check_usershare_stat(const char *fname,
    3187             :                                  const SMB_STRUCT_STAT *psbuf)
    3188             : {
    3189           4 :         if (!S_ISREG(psbuf->st_ex_mode)) {
    3190           0 :                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
    3191             :                         "not a regular file\n",
    3192             :                         fname, (unsigned int)psbuf->st_ex_uid ));
    3193           0 :                 return false;
    3194             :         }
    3195             : 
    3196             :         /* Ensure this doesn't have the other write bit set. */
    3197           4 :         if (psbuf->st_ex_mode & S_IWOTH) {
    3198           0 :                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
    3199             :                         "public write. Refusing to allow as a usershare file.\n",
    3200             :                         fname, (unsigned int)psbuf->st_ex_uid ));
    3201           0 :                 return false;
    3202             :         }
    3203             : 
    3204             :         /* Should be 10k or less. */
    3205           4 :         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
    3206           0 :                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
    3207             :                         "too large (%u) to be a user share file.\n",
    3208             :                         fname, (unsigned int)psbuf->st_ex_uid,
    3209             :                         (unsigned int)psbuf->st_ex_size ));
    3210           0 :                 return false;
    3211             :         }
    3212             : 
    3213           4 :         return true;
    3214             : }
    3215             : 
    3216             : /***************************************************************************
    3217             :  Parse the contents of a usershare file.
    3218             : ***************************************************************************/
    3219             : 
    3220           4 : enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
    3221             :                         SMB_STRUCT_STAT *psbuf,
    3222             :                         const char *servicename,
    3223             :                         int snum,
    3224             :                         char **lines,
    3225             :                         int numlines,
    3226             :                         char **pp_sharepath,
    3227             :                         char **pp_comment,
    3228             :                         char **pp_cp_servicename,
    3229             :                         struct security_descriptor **ppsd,
    3230             :                         bool *pallow_guest)
    3231             : {
    3232           4 :         const char **prefixallowlist = lp_usershare_prefix_allow_list();
    3233           4 :         const char **prefixdenylist = lp_usershare_prefix_deny_list();
    3234           0 :         int us_vers;
    3235           0 :         DIR *dp;
    3236           0 :         SMB_STRUCT_STAT sbuf;
    3237           4 :         char *sharepath = NULL;
    3238           4 :         char *comment = NULL;
    3239             : 
    3240           4 :         *pp_sharepath = NULL;
    3241           4 :         *pp_comment = NULL;
    3242             : 
    3243           4 :         *pallow_guest = false;
    3244             : 
    3245           4 :         if (numlines < 4) {
    3246           0 :                 return USERSHARE_MALFORMED_FILE;
    3247             :         }
    3248             : 
    3249           4 :         if (strcmp(lines[0], "#VERSION 1") == 0) {
    3250           0 :                 us_vers = 1;
    3251           4 :         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
    3252           4 :                 us_vers = 2;
    3253           4 :                 if (numlines < 5) {
    3254           0 :                         return USERSHARE_MALFORMED_FILE;
    3255             :                 }
    3256             :         } else {
    3257           0 :                 return USERSHARE_BAD_VERSION;
    3258             :         }
    3259             : 
    3260           4 :         if (strncmp(lines[1], "path=", 5) != 0) {
    3261           0 :                 return USERSHARE_MALFORMED_PATH;
    3262             :         }
    3263             : 
    3264           4 :         sharepath = talloc_strdup(ctx, &lines[1][5]);
    3265           4 :         if (!sharepath) {
    3266           0 :                 return USERSHARE_POSIX_ERR;
    3267             :         }
    3268           4 :         trim_string(sharepath, " ", " ");
    3269             : 
    3270           4 :         if (strncmp(lines[2], "comment=", 8) != 0) {
    3271           0 :                 return USERSHARE_MALFORMED_COMMENT_DEF;
    3272             :         }
    3273             : 
    3274           4 :         comment = talloc_strdup(ctx, &lines[2][8]);
    3275           4 :         if (!comment) {
    3276           0 :                 return USERSHARE_POSIX_ERR;
    3277             :         }
    3278           4 :         trim_string(comment, " ", " ");
    3279           4 :         trim_char(comment, '"', '"');
    3280             : 
    3281           4 :         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
    3282           0 :                 return USERSHARE_MALFORMED_ACL_DEF;
    3283             :         }
    3284             : 
    3285           4 :         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
    3286           0 :                 return USERSHARE_ACL_ERR;
    3287             :         }
    3288             : 
    3289           4 :         if (us_vers == 2) {
    3290           4 :                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
    3291           0 :                         return USERSHARE_MALFORMED_ACL_DEF;
    3292             :                 }
    3293           4 :                 if (lines[4][9] == 'y') {
    3294           0 :                         *pallow_guest = true;
    3295             :                 }
    3296             : 
    3297             :                 /* Backwards compatible extension to file version #2. */
    3298           4 :                 if (numlines > 5) {
    3299           4 :                         if (strncmp(lines[5], "sharename=", 10) != 0) {
    3300           0 :                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
    3301             :                         }
    3302           4 :                         if (!strequal(&lines[5][10], servicename)) {
    3303           0 :                                 return USERSHARE_BAD_SHARENAME;
    3304             :                         }
    3305           4 :                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
    3306           4 :                         if (!*pp_cp_servicename) {
    3307           0 :                                 return USERSHARE_POSIX_ERR;
    3308             :                         }
    3309             :                 }
    3310             :         }
    3311             : 
    3312           4 :         if (*pp_cp_servicename == NULL) {
    3313           0 :                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
    3314           0 :                 if (!*pp_cp_servicename) {
    3315           0 :                         return USERSHARE_POSIX_ERR;
    3316             :                 }
    3317             :         }
    3318             : 
    3319           4 :         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
    3320             :                 /* Path didn't change, no checks needed. */
    3321           0 :                 *pp_sharepath = sharepath;
    3322           0 :                 *pp_comment = comment;
    3323           0 :                 return USERSHARE_OK;
    3324             :         }
    3325             : 
    3326             :         /* The path *must* be absolute. */
    3327           4 :         if (sharepath[0] != '/') {
    3328           0 :                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
    3329             :                         servicename, sharepath));
    3330           0 :                 return USERSHARE_PATH_NOT_ABSOLUTE;
    3331             :         }
    3332             : 
    3333             :         /* If there is a usershare prefix deny list ensure one of these paths
    3334             :            doesn't match the start of the user given path. */
    3335           4 :         if (prefixdenylist) {
    3336             :                 int i;
    3337           0 :                 for ( i=0; prefixdenylist[i]; i++ ) {
    3338           0 :                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
    3339             :                                 servicename, i, prefixdenylist[i], sharepath ));
    3340           0 :                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
    3341           0 :                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
    3342             :                                         "usershare prefix deny list entries.\n",
    3343             :                                         servicename, sharepath));
    3344           0 :                                 return USERSHARE_PATH_IS_DENIED;
    3345             :                         }
    3346             :                 }
    3347             :         }
    3348             : 
    3349             :         /* If there is a usershare prefix allow list ensure one of these paths
    3350             :            does match the start of the user given path. */
    3351             : 
    3352           4 :         if (prefixallowlist) {
    3353             :                 int i;
    3354           4 :                 for ( i=0; prefixallowlist[i]; i++ ) {
    3355           4 :                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
    3356             :                                 servicename, i, prefixallowlist[i], sharepath ));
    3357           4 :                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
    3358           4 :                                 break;
    3359             :                         }
    3360             :                 }
    3361           4 :                 if (prefixallowlist[i] == NULL) {
    3362           0 :                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
    3363             :                                 "usershare prefix allow list entries.\n",
    3364             :                                 servicename, sharepath));
    3365           0 :                         return USERSHARE_PATH_NOT_ALLOWED;
    3366             :                 }
    3367             :         }
    3368             : 
    3369             :         /* Ensure this is pointing to a directory. */
    3370           4 :         dp = opendir(sharepath);
    3371             : 
    3372           4 :         if (!dp) {
    3373           0 :                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
    3374             :                         servicename, sharepath));
    3375           0 :                 return USERSHARE_PATH_NOT_DIRECTORY;
    3376             :         }
    3377             : 
    3378             :         /* Ensure the owner of the usershare file has permission to share
    3379             :            this directory. */
    3380             : 
    3381           4 :         if (sys_stat(sharepath, &sbuf, false) == -1) {
    3382           0 :                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
    3383             :                         servicename, sharepath, strerror(errno) ));
    3384           0 :                 closedir(dp);
    3385           0 :                 return USERSHARE_POSIX_ERR;
    3386             :         }
    3387             : 
    3388           4 :         closedir(dp);
    3389             : 
    3390           4 :         if (!S_ISDIR(sbuf.st_ex_mode)) {
    3391           0 :                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
    3392             :                         servicename, sharepath ));
    3393           0 :                 return USERSHARE_PATH_NOT_DIRECTORY;
    3394             :         }
    3395             : 
    3396             :         /* Check if sharing is restricted to owner-only. */
    3397             :         /* psbuf is the stat of the usershare definition file,
    3398             :            sbuf is the stat of the target directory to be shared. */
    3399             : 
    3400           4 :         if (lp_usershare_owner_only()) {
    3401             :                 /* root can share anything. */
    3402           4 :                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
    3403           0 :                         return USERSHARE_PATH_NOT_ALLOWED;
    3404             :                 }
    3405             :         }
    3406             : 
    3407           4 :         *pp_sharepath = sharepath;
    3408           4 :         *pp_comment = comment;
    3409           4 :         return USERSHARE_OK;
    3410             : }
    3411             : 
    3412             : /***************************************************************************
    3413             :  Deal with a usershare file.
    3414             :  Returns:
    3415             :         >= 0 - snum
    3416             :         -1 - Bad name, invalid contents.
    3417             :            - service name already existed and not a usershare, problem
    3418             :             with permissions to share directory etc.
    3419             : ***************************************************************************/
    3420             : 
    3421          10 : static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
    3422             : {
    3423           0 :         SMB_STRUCT_STAT sbuf;
    3424           0 :         SMB_STRUCT_STAT lsbuf;
    3425          10 :         char *fname = NULL;
    3426          10 :         char *sharepath = NULL;
    3427          10 :         char *comment = NULL;
    3428          10 :         char *cp_service_name = NULL;
    3429          10 :         char **lines = NULL;
    3430          10 :         int numlines = 0;
    3431          10 :         int fd = -1;
    3432          10 :         int iService = -1;
    3433          10 :         TALLOC_CTX *ctx = talloc_stackframe();
    3434          10 :         struct security_descriptor *psd = NULL;
    3435          10 :         bool guest_ok = false;
    3436          10 :         char *canon_name = NULL;
    3437          10 :         bool added_service = false;
    3438          10 :         int ret = -1;
    3439           0 :         NTSTATUS status;
    3440             : 
    3441             :         /* Ensure share name doesn't contain invalid characters. */
    3442          10 :         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
    3443           0 :                 DEBUG(0,("process_usershare_file: share name %s contains "
    3444             :                         "invalid characters (any of %s)\n",
    3445             :                         file_name, INVALID_SHARENAME_CHARS ));
    3446           0 :                 goto out;
    3447             :         }
    3448             : 
    3449          10 :         canon_name = canonicalize_servicename(ctx, file_name);
    3450          10 :         if (!canon_name) {
    3451           0 :                 goto out;
    3452             :         }
    3453             : 
    3454          10 :         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
    3455          10 :         if (!fname) {
    3456           0 :                 goto out;
    3457             :         }
    3458             : 
    3459             :         /* Minimize the race condition by doing an lstat before we
    3460             :            open and fstat. Ensure this isn't a symlink link. */
    3461             : 
    3462          10 :         if (sys_lstat(fname, &lsbuf, false) != 0) {
    3463           8 :                 if (errno == ENOENT) {
    3464             :                         /* Unknown share requested. Just ignore. */
    3465           8 :                         goto out;
    3466             :                 }
    3467             :                 /* Only log messages for meaningful problems. */
    3468           0 :                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
    3469             :                         fname, strerror(errno) ));
    3470           0 :                 goto out;
    3471             :         }
    3472             : 
    3473             :         /* This must be a regular file, not a symlink, directory or
    3474             :            other strange filetype. */
    3475           2 :         if (!check_usershare_stat(fname, &lsbuf)) {
    3476           0 :                 goto out;
    3477             :         }
    3478             : 
    3479             :         {
    3480           0 :                 TDB_DATA data;
    3481             : 
    3482           2 :                 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
    3483             :                                                canon_name, &data);
    3484             : 
    3485           2 :                 iService = -1;
    3486             : 
    3487           2 :                 if (NT_STATUS_IS_OK(status) &&
    3488           0 :                     (data.dptr != NULL) &&
    3489           0 :                     (data.dsize == sizeof(iService))) {
    3490           0 :                         memcpy(&iService, data.dptr, sizeof(iService));
    3491             :                 }
    3492             :         }
    3493             : 
    3494           2 :         if (iService != -1 &&
    3495           0 :             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
    3496             :                              &lsbuf.st_ex_mtime) == 0) {
    3497             :                 /* Nothing changed - Mark valid and return. */
    3498           0 :                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
    3499             :                         canon_name ));
    3500           0 :                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
    3501           0 :                 ret = iService;
    3502           0 :                 goto out;
    3503             :         }
    3504             : 
    3505             :         /* Try and open the file read only - no symlinks allowed. */
    3506             : #ifdef O_NOFOLLOW
    3507           2 :         fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
    3508             : #else
    3509             :         fd = open(fname, O_RDONLY, 0);
    3510             : #endif
    3511             : 
    3512           2 :         if (fd == -1) {
    3513           0 :                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
    3514             :                         fname, strerror(errno) ));
    3515           0 :                 goto out;
    3516             :         }
    3517             : 
    3518             :         /* Now fstat to be *SURE* it's a regular file. */
    3519           2 :         if (sys_fstat(fd, &sbuf, false) != 0) {
    3520           0 :                 close(fd);
    3521           0 :                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
    3522             :                         fname, strerror(errno) ));
    3523           0 :                 goto out;
    3524             :         }
    3525             : 
    3526             :         /* Is it the same dev/inode as was lstated ? */
    3527           2 :         if (!check_same_stat(&lsbuf, &sbuf)) {
    3528           0 :                 close(fd);
    3529           0 :                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
    3530             :                         "Symlink spoofing going on ?\n", fname ));
    3531           0 :                 goto out;
    3532             :         }
    3533             : 
    3534             :         /* This must be a regular file, not a symlink, directory or
    3535             :            other strange filetype. */
    3536           2 :         if (!check_usershare_stat(fname, &sbuf)) {
    3537           0 :                 close(fd);
    3538           0 :                 goto out;
    3539             :         }
    3540             : 
    3541           2 :         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
    3542             : 
    3543           2 :         close(fd);
    3544           2 :         if (lines == NULL) {
    3545           0 :                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
    3546             :                         fname, (unsigned int)sbuf.st_ex_uid ));
    3547           0 :                 goto out;
    3548             :         }
    3549             : 
    3550           2 :         if (parse_usershare_file(ctx, &sbuf, file_name,
    3551             :                         iService, lines, numlines, &sharepath,
    3552             :                         &comment, &cp_service_name,
    3553             :                         &psd, &guest_ok) != USERSHARE_OK) {
    3554           0 :                 goto out;
    3555             :         }
    3556             : 
    3557             :         /* Everything ok - add the service possibly using a template. */
    3558           2 :         if (iService < 0) {
    3559           2 :                 const struct loadparm_service *sp = &sDefault;
    3560           2 :                 if (snum_template != -1) {
    3561           0 :                         sp = ServicePtrs[snum_template];
    3562             :                 }
    3563             : 
    3564           2 :                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
    3565           0 :                         DEBUG(0, ("process_usershare_file: Failed to add "
    3566             :                                 "new service %s\n", cp_service_name));
    3567           0 :                         goto out;
    3568             :                 }
    3569             : 
    3570           2 :                 added_service = true;
    3571             : 
    3572             :                 /* Read only is controlled by usershare ACL below. */
    3573           2 :                 ServicePtrs[iService]->read_only = false;
    3574             :         }
    3575             : 
    3576             :         /* Write the ACL of the new/modified share. */
    3577           2 :         status = set_share_security(canon_name, psd);
    3578           2 :         if (!NT_STATUS_IS_OK(status)) {
    3579           0 :                  DEBUG(0, ("process_usershare_file: Failed to set share "
    3580             :                         "security for user share %s\n",
    3581             :                         canon_name ));
    3582           0 :                 goto out;
    3583             :         }
    3584             : 
    3585             :         /* If from a template it may be marked invalid. */
    3586           2 :         ServicePtrs[iService]->valid = true;
    3587             : 
    3588             :         /* Set the service as a valid usershare. */
    3589           2 :         ServicePtrs[iService]->usershare = USERSHARE_VALID;
    3590             : 
    3591             :         /* Set guest access. */
    3592           2 :         if (lp_usershare_allow_guests()) {
    3593           2 :                 ServicePtrs[iService]->guest_ok = guest_ok;
    3594             :         }
    3595             : 
    3596             :         /* And note when it was loaded. */
    3597           2 :         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
    3598           2 :         lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path,
    3599             :                          sharepath);
    3600           2 :         lpcfg_string_set(ServicePtrs[iService],
    3601           2 :                          &ServicePtrs[iService]->comment, comment);
    3602             : 
    3603           2 :         ret = iService;
    3604             : 
    3605          10 :   out:
    3606             : 
    3607          10 :         if (ret == -1 && iService != -1 && added_service) {
    3608           0 :                 lp_remove_service(iService);
    3609             :         }
    3610             : 
    3611          10 :         TALLOC_FREE(lines);
    3612          10 :         TALLOC_FREE(ctx);
    3613          10 :         return ret;
    3614             : }
    3615             : 
    3616             : /***************************************************************************
    3617             :  Checks if a usershare entry has been modified since last load.
    3618             : ***************************************************************************/
    3619             : 
    3620           4 : static bool usershare_exists(int iService, struct timespec *last_mod)
    3621             : {
    3622           0 :         SMB_STRUCT_STAT lsbuf;
    3623           4 :         const char *usersharepath = Globals.usershare_path;
    3624           0 :         char *fname;
    3625             : 
    3626           4 :         fname = talloc_asprintf(talloc_tos(),
    3627             :                                 "%s/%s",
    3628             :                                 usersharepath,
    3629           4 :                                 ServicePtrs[iService]->szService);
    3630           4 :         if (fname == NULL) {
    3631           0 :                 return false;
    3632             :         }
    3633             : 
    3634           4 :         if (sys_lstat(fname, &lsbuf, false) != 0) {
    3635           0 :                 TALLOC_FREE(fname);
    3636           0 :                 return false;
    3637             :         }
    3638             : 
    3639           4 :         if (!S_ISREG(lsbuf.st_ex_mode)) {
    3640           0 :                 TALLOC_FREE(fname);
    3641           0 :                 return false;
    3642             :         }
    3643             : 
    3644           4 :         TALLOC_FREE(fname);
    3645           4 :         *last_mod = lsbuf.st_ex_mtime;
    3646           4 :         return true;
    3647             : }
    3648             : 
    3649          10 : static bool usershare_directory_is_root(uid_t uid)
    3650             : {
    3651          10 :         if (uid == 0) {
    3652           0 :                 return true;
    3653             :         }
    3654             : 
    3655          10 :         if (uid_wrapper_enabled()) {
    3656          10 :                 return true;
    3657             :         }
    3658             : 
    3659           0 :         return false;
    3660             : }
    3661             : 
    3662             : /***************************************************************************
    3663             :  Load a usershare service by name. Returns a valid servicenumber or -1.
    3664             : ***************************************************************************/
    3665             : 
    3666        1435 : int load_usershare_service(const char *servicename)
    3667             : {
    3668          10 :         SMB_STRUCT_STAT sbuf;
    3669        1435 :         const char *usersharepath = Globals.usershare_path;
    3670        1435 :         int max_user_shares = Globals.usershare_max_shares;
    3671        1435 :         int snum_template = -1;
    3672             : 
    3673        1435 :         if (servicename[0] == '\0') {
    3674             :                 /* Invalid service name. */
    3675           0 :                 return -1;
    3676             :         }
    3677             : 
    3678        1435 :         if (*usersharepath == 0 ||  max_user_shares == 0) {
    3679        1415 :                 return -1;
    3680             :         }
    3681             : 
    3682          10 :         if (sys_stat(usersharepath, &sbuf, false) != 0) {
    3683           0 :                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
    3684             :                         usersharepath, strerror(errno) ));
    3685           0 :                 return -1;
    3686             :         }
    3687             : 
    3688          10 :         if (!S_ISDIR(sbuf.st_ex_mode)) {
    3689           0 :                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
    3690             :                         usersharepath ));
    3691           0 :                 return -1;
    3692             :         }
    3693             : 
    3694             :         /*
    3695             :          * This directory must be owned by root, and have the 't' bit set.
    3696             :          * It also must not be writable by "other".
    3697             :          */
    3698             : 
    3699             : #ifdef S_ISVTX
    3700          10 :         if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
    3701          10 :             !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
    3702             : #else
    3703             :         if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
    3704             :             (sbuf.st_ex_mode & S_IWOTH)) {
    3705             : #endif
    3706           0 :                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
    3707             :                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
    3708             :                         usersharepath ));
    3709           0 :                 return -1;
    3710             :         }
    3711             : 
    3712             :         /* Ensure the template share exists if it's set. */
    3713          10 :         if (Globals.usershare_template_share[0]) {
    3714             :                 /* We can't use lp_servicenumber here as we are recommending that
    3715             :                    template shares have -valid=false set. */
    3716           0 :                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
    3717           0 :                         if (ServicePtrs[snum_template]->szService &&
    3718           0 :                                         strequal(ServicePtrs[snum_template]->szService,
    3719           0 :                                                 Globals.usershare_template_share)) {
    3720           0 :                                 break;
    3721             :                         }
    3722             :                 }
    3723             : 
    3724           0 :                 if (snum_template == -1) {
    3725           0 :                         DEBUG(0,("load_usershare_service: usershare template share %s "
    3726             :                                 "does not exist.\n",
    3727             :                                 Globals.usershare_template_share ));
    3728           0 :                         return -1;
    3729             :                 }
    3730             :         }
    3731             : 
    3732          10 :         return process_usershare_file(usersharepath, servicename, snum_template);
    3733             : }
    3734             : 
    3735             : /***************************************************************************
    3736             :  Load all user defined shares from the user share directory.
    3737             :  We only do this if we're enumerating the share list.
    3738             :  This is the function that can delete usershares that have
    3739             :  been removed.
    3740             : ***************************************************************************/
    3741             : 
    3742         207 : int load_usershare_shares(struct smbd_server_connection *sconn,
    3743             :                           bool (*snumused) (struct smbd_server_connection *, int))
    3744             : {
    3745           0 :         DIR *dp;
    3746           0 :         SMB_STRUCT_STAT sbuf;
    3747           0 :         struct dirent *de;
    3748         207 :         int num_usershares = 0;
    3749         207 :         int max_user_shares = Globals.usershare_max_shares;
    3750           0 :         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
    3751         207 :         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
    3752         207 :         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
    3753           0 :         int iService;
    3754         207 :         int snum_template = -1;
    3755         207 :         const char *usersharepath = Globals.usershare_path;
    3756         207 :         int ret = lp_numservices();
    3757           0 :         TALLOC_CTX *tmp_ctx;
    3758             : 
    3759         207 :         if (max_user_shares == 0 || *usersharepath == '\0') {
    3760         188 :                 return lp_numservices();
    3761             :         }
    3762             : 
    3763          19 :         if (sys_stat(usersharepath, &sbuf, false) != 0) {
    3764           0 :                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
    3765             :                         usersharepath, strerror(errno) ));
    3766           0 :                 return ret;
    3767             :         }
    3768             : 
    3769             :         /*
    3770             :          * This directory must be owned by root, and have the 't' bit set.
    3771             :          * It also must not be writable by "other".
    3772             :          */
    3773             : 
    3774             : #ifdef S_ISVTX
    3775          19 :         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
    3776             : #else
    3777             :         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
    3778             : #endif
    3779          19 :                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
    3780             :                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
    3781             :                         usersharepath ));
    3782          19 :                 return ret;
    3783             :         }
    3784             : 
    3785             :         /* Ensure the template share exists if it's set. */
    3786           0 :         if (Globals.usershare_template_share[0]) {
    3787             :                 /* We can't use lp_servicenumber here as we are recommending that
    3788             :                    template shares have -valid=false set. */
    3789           0 :                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
    3790           0 :                         if (ServicePtrs[snum_template]->szService &&
    3791           0 :                                         strequal(ServicePtrs[snum_template]->szService,
    3792           0 :                                                 Globals.usershare_template_share)) {
    3793           0 :                                 break;
    3794             :                         }
    3795             :                 }
    3796             : 
    3797           0 :                 if (snum_template == -1) {
    3798           0 :                         DEBUG(0,("load_usershare_shares: usershare template share %s "
    3799             :                                 "does not exist.\n",
    3800             :                                 Globals.usershare_template_share ));
    3801           0 :                         return ret;
    3802             :                 }
    3803             :         }
    3804             : 
    3805             :         /* Mark all existing usershares as pending delete. */
    3806           0 :         for (iService = iNumServices - 1; iService >= 0; iService--) {
    3807           0 :                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
    3808           0 :                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
    3809             :                 }
    3810             :         }
    3811             : 
    3812           0 :         dp = opendir(usersharepath);
    3813           0 :         if (!dp) {
    3814           0 :                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
    3815             :                         usersharepath, strerror(errno) ));
    3816           0 :                 return ret;
    3817             :         }
    3818             : 
    3819           0 :         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
    3820           0 :                         (de = readdir(dp));
    3821           0 :                         num_dir_entries++ ) {
    3822           0 :                 int r;
    3823           0 :                 const char *n = de->d_name;
    3824             : 
    3825             :                 /* Ignore . and .. */
    3826           0 :                 if (*n == '.') {
    3827           0 :                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
    3828           0 :                                 continue;
    3829             :                         }
    3830             :                 }
    3831             : 
    3832           0 :                 if (n[0] == ':') {
    3833             :                         /* Temporary file used when creating a share. */
    3834           0 :                         num_tmp_dir_entries++;
    3835             :                 }
    3836             : 
    3837             :                 /* Allow 20% tmp entries. */
    3838           0 :                 if (num_tmp_dir_entries > allowed_tmp_entries) {
    3839           0 :                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
    3840             :                                 "in directory %s\n",
    3841             :                                 num_tmp_dir_entries, usersharepath));
    3842           0 :                         break;
    3843             :                 }
    3844             : 
    3845           0 :                 r = process_usershare_file(usersharepath, n, snum_template);
    3846           0 :                 if (r == 0) {
    3847             :                         /* Update the services count. */
    3848           0 :                         num_usershares++;
    3849           0 :                         if (num_usershares >= max_user_shares) {
    3850           0 :                                 DEBUG(0,("load_usershare_shares: max user shares reached "
    3851             :                                         "on file %s in directory %s\n",
    3852             :                                         n, usersharepath ));
    3853           0 :                                 break;
    3854             :                         }
    3855           0 :                 } else if (r == -1) {
    3856           0 :                         num_bad_dir_entries++;
    3857             :                 }
    3858             : 
    3859             :                 /* Allow 20% bad entries. */
    3860           0 :                 if (num_bad_dir_entries > allowed_bad_entries) {
    3861           0 :                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
    3862             :                                 "in directory %s\n",
    3863             :                                 num_bad_dir_entries, usersharepath));
    3864           0 :                         break;
    3865             :                 }
    3866             : 
    3867             :                 /* Allow 20% bad entries. */
    3868           0 :                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
    3869           0 :                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
    3870             :                         "in directory %s\n",
    3871             :                         num_dir_entries, usersharepath));
    3872           0 :                         break;
    3873             :                 }
    3874             :         }
    3875             : 
    3876           0 :         closedir(dp);
    3877             : 
    3878             :         /* Sweep through and delete any non-refreshed usershares that are
    3879             :            not currently in use. */
    3880           0 :         tmp_ctx = talloc_stackframe();
    3881           0 :         for (iService = iNumServices - 1; iService >= 0; iService--) {
    3882           0 :                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
    3883           0 :                         const struct loadparm_substitution *lp_sub =
    3884           0 :                                 loadparm_s3_global_substitution();
    3885           0 :                         char *servname;
    3886             : 
    3887           0 :                         if (snumused && snumused(sconn, iService)) {
    3888           0 :                                 continue;
    3889             :                         }
    3890             : 
    3891           0 :                         servname = lp_servicename(tmp_ctx, lp_sub, iService);
    3892             : 
    3893             :                         /* Remove from the share ACL db. */
    3894           0 :                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
    3895             :                                   servname ));
    3896           0 :                         delete_share_security(servname);
    3897           0 :                         free_service_byindex(iService);
    3898             :                 }
    3899             :         }
    3900           0 :         talloc_free(tmp_ctx);
    3901             : 
    3902           0 :         return lp_numservices();
    3903             : }
    3904             : 
    3905             : /********************************************************
    3906             :  Destroy global resources allocated in this file
    3907             : ********************************************************/
    3908             : 
    3909       17774 : void gfree_loadparm(void)
    3910             : {
    3911           9 :         int i;
    3912             : 
    3913       17774 :         free_file_list();
    3914             : 
    3915             :         /* Free resources allocated to services */
    3916             : 
    3917       29758 :         for ( i = 0; i < iNumServices; i++ ) {
    3918       11984 :                 if ( VALID(i) ) {
    3919       11984 :                         free_service_byindex(i);
    3920             :                 }
    3921             :         }
    3922             : 
    3923       17774 :         TALLOC_FREE( ServicePtrs );
    3924       17774 :         iNumServices = 0;
    3925             : 
    3926             :         /* Now release all resources allocated to global
    3927             :            parameters and the default service */
    3928             : 
    3929       17774 :         free_global_parameters();
    3930       17774 : }
    3931             : 
    3932             : 
    3933             : /***************************************************************************
    3934             :  Allow client apps to specify that they are a client
    3935             : ***************************************************************************/
    3936       19647 : static void lp_set_in_client(bool b)
    3937             : {
    3938       19647 :     in_client = b;
    3939       19639 : }
    3940             : 
    3941             : 
    3942             : /***************************************************************************
    3943             :  Determine if we're running in a client app
    3944             : ***************************************************************************/
    3945       50924 : static bool lp_is_in_client(void)
    3946             : {
    3947       50924 :     return in_client;
    3948             : }
    3949             : 
    3950        4053 : static void lp_enforce_ad_dc_settings(void)
    3951             : {
    3952        4053 :         lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
    3953        4053 :         lp_do_parameter(GLOBAL_SECTION_SNUM,
    3954             :                         "winbindd:use external pipes", "true");
    3955        4053 :         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
    3956        4053 :         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
    3957        4053 :         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
    3958        4053 :         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
    3959        4053 :         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
    3960        4053 :         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
    3961        4053 :         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
    3962        4053 :         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
    3963        4053 :         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
    3964        4053 : }
    3965             : 
    3966             : /***************************************************************************
    3967             :  Load the services array from the services file. Return true on success,
    3968             :  false on failure.
    3969             : ***************************************************************************/
    3970             : 
    3971       50924 : static bool lp_load_ex(const char *pszFname,
    3972             :                        bool global_only,
    3973             :                        bool save_defaults,
    3974             :                        bool add_ipc,
    3975             :                        bool reinit_globals,
    3976             :                        bool allow_include_registry,
    3977             :                        bool load_all_shares)
    3978             : {
    3979       50924 :         char *n2 = NULL;
    3980         125 :         bool bRetval;
    3981       50924 :         TALLOC_CTX *frame = talloc_stackframe();
    3982         125 :         struct loadparm_context *lp_ctx;
    3983         125 :         int max_protocol, min_protocol;
    3984             : 
    3985       50924 :         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
    3986             : 
    3987       50924 :         bInGlobalSection = true;
    3988       50924 :         bGlobalOnly = global_only;
    3989       50924 :         bAllowIncludeRegistry = allow_include_registry;
    3990       50924 :         sDefault = _sDefault;
    3991             : 
    3992       50924 :         lp_ctx = setup_lp_context(talloc_tos());
    3993             : 
    3994       50924 :         loadparm_s3_init_globals(lp_ctx, reinit_globals);
    3995             : 
    3996       50924 :         free_file_list();
    3997             : 
    3998       50924 :         if (save_defaults) {
    3999        2052 :                 init_locals();
    4000        2052 :                 lp_save_defaults();
    4001             :         }
    4002             : 
    4003       50924 :         if (!reinit_globals) {
    4004        2450 :                 free_param_opts(&Globals.param_opt);
    4005        2450 :                 apply_lp_set_cmdline();
    4006             :         }
    4007             : 
    4008       50924 :         lp_do_parameter(-1, "idmap config * : backend", Globals.idmap_backend);
    4009             : 
    4010             :         /* We get sections first, so have to start 'behind' to make up */
    4011       50924 :         iServiceIndex = -1;
    4012             : 
    4013       50924 :         if (lp_config_backend_is_file()) {
    4014       50924 :                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
    4015             :                                         get_current_user_info_domain(),
    4016             :                                         pszFname);
    4017       50924 :                 if (!n2) {
    4018           0 :                         smb_panic("lp_load_ex: out of memory");
    4019             :                 }
    4020             : 
    4021       50924 :                 add_to_file_list(NULL, &file_lists, pszFname, n2);
    4022             : 
    4023       50924 :                 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
    4024       50924 :                 TALLOC_FREE(n2);
    4025             : 
    4026             :                 /* finish up the last section */
    4027       50924 :                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
    4028       50924 :                 if (bRetval) {
    4029       50704 :                         if (iServiceIndex >= 0) {
    4030       27749 :                                 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
    4031             :                         }
    4032             :                 }
    4033             : 
    4034       50924 :                 if (lp_config_backend_is_registry()) {
    4035           0 :                         bool ok;
    4036             :                         /* config backend changed to registry in config file */
    4037             :                         /*
    4038             :                          * We need to use this extra global variable here to
    4039             :                          * survive restart: init_globals uses this as a default
    4040             :                          * for config_backend. Otherwise, init_globals would
    4041             :                          *  send us into an endless loop here.
    4042             :                          */
    4043             : 
    4044           0 :                         config_backend = CONFIG_BACKEND_REGISTRY;
    4045             :                         /* start over */
    4046           0 :                         DEBUG(1, ("lp_load_ex: changing to config backend "
    4047             :                                   "registry\n"));
    4048           0 :                         loadparm_s3_init_globals(lp_ctx, true);
    4049             : 
    4050           0 :                         TALLOC_FREE(lp_ctx);
    4051             : 
    4052           0 :                         lp_kill_all_services();
    4053           0 :                         ok = lp_load_ex(pszFname, global_only, save_defaults,
    4054             :                                         add_ipc, reinit_globals,
    4055             :                                         allow_include_registry,
    4056             :                                         load_all_shares);
    4057           0 :                         TALLOC_FREE(frame);
    4058           0 :                         return ok;
    4059             :                 }
    4060           0 :         } else if (lp_config_backend_is_registry()) {
    4061           0 :                 bRetval = process_registry_globals();
    4062             :         } else {
    4063           0 :                 DEBUG(0, ("Illegal config  backend given: %d\n",
    4064             :                           lp_config_backend()));
    4065           0 :                 bRetval = false;
    4066             :         }
    4067             : 
    4068       50924 :         if (bRetval && lp_registry_shares()) {
    4069       29326 :                 if (load_all_shares) {
    4070          86 :                         bRetval = process_registry_shares();
    4071             :                 } else {
    4072       29240 :                         bRetval = reload_registry_shares();
    4073             :                 }
    4074             :         }
    4075             : 
    4076             :         {
    4077         125 :                 const struct loadparm_substitution *lp_sub =
    4078       50924 :                         loadparm_s3_global_substitution();
    4079       50924 :                 char *serv = lp_auto_services(talloc_tos(), lp_sub);
    4080       50924 :                 lp_add_auto_services(serv);
    4081       50924 :                 TALLOC_FREE(serv);
    4082             :         }
    4083             : 
    4084       50924 :         if (add_ipc) {
    4085             :                 /* When 'restrict anonymous = 2' guest connections to ipc$
    4086             :                    are denied */
    4087       24133 :                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
    4088       24133 :                 if ( lp_enable_asu_support() ) {
    4089           0 :                         lp_add_ipc("ADMIN$", false);
    4090             :                 }
    4091             :         }
    4092             : 
    4093       50924 :         set_allowed_client_auth();
    4094             : 
    4095       50924 :         if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
    4096           0 :                 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
    4097             :                           lp_password_server()));
    4098             :         }
    4099             : 
    4100       50924 :         b_loaded = true;
    4101             : 
    4102             :         /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
    4103             :         /* if we_are_a_wins_server is true and we are in the client            */
    4104       50924 :         if (lp_is_in_client() && Globals.we_are_a_wins_server) {
    4105        1329 :                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
    4106             :         }
    4107             : 
    4108       50924 :         init_iconv();
    4109             : 
    4110       50924 :         fault_configure(smb_panic_s3);
    4111             : 
    4112             :         /*
    4113             :          * We run this check once the whole smb.conf is parsed, to
    4114             :          * force some settings for the standard way a AD DC is
    4115             :          * operated.  We may change these as our code evolves, which
    4116             :          * is why we force these settings.
    4117             :          */
    4118       50924 :         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
    4119        4053 :                 lp_enforce_ad_dc_settings();
    4120             :         }
    4121             : 
    4122       50924 :         bAllowIncludeRegistry = true;
    4123             : 
    4124             :         /* Check if command line max protocol < min protocol, if so
    4125             :          * report a warning to the user.
    4126             :          */
    4127       50924 :         max_protocol = lp_client_max_protocol();
    4128       50924 :         min_protocol = lp_client_min_protocol();
    4129       50924 :         if (max_protocol < min_protocol) {
    4130           0 :                 const char *max_protocolp, *min_protocolp;
    4131           0 :                 max_protocolp = lpcfg_get_smb_protocol(max_protocol);
    4132           0 :                 min_protocolp = lpcfg_get_smb_protocol(min_protocol);
    4133           0 :                 DBG_ERR("Max protocol %s is less than min protocol %s.\n",
    4134             :                         max_protocolp, min_protocolp);
    4135             :         }
    4136             : 
    4137       50924 :         TALLOC_FREE(frame);
    4138       50799 :         return (bRetval);
    4139             : }
    4140             : 
    4141       48872 : static bool lp_load(const char *pszFname,
    4142             :                     bool global_only,
    4143             :                     bool save_defaults,
    4144             :                     bool add_ipc,
    4145             :                     bool reinit_globals)
    4146             : {
    4147       48872 :         return lp_load_ex(pszFname,
    4148             :                           global_only,
    4149             :                           save_defaults,
    4150             :                           add_ipc,
    4151             :                           reinit_globals,
    4152             :                           true,   /* allow_include_registry */
    4153             :                           false); /* load_all_shares*/
    4154             : }
    4155             : 
    4156           3 : bool lp_load_initial_only(const char *pszFname)
    4157             : {
    4158           3 :         return lp_load_ex(pszFname,
    4159             :                           true,   /* global only */
    4160             :                           true,   /* save_defaults */
    4161             :                           false,  /* add_ipc */
    4162             :                           true,   /* reinit_globals */
    4163             :                           false,  /* allow_include_registry */
    4164             :                           false); /* load_all_shares*/
    4165             : }
    4166             : 
    4167             : /**
    4168             :  * most common lp_load wrapper, loading only the globals
    4169             :  *
    4170             :  * If this is used in a daemon or client utility it should be called
    4171             :  * after processing popt.
    4172             :  */
    4173       22289 : bool lp_load_global(const char *file_name)
    4174             : {
    4175       22289 :         return lp_load(file_name,
    4176             :                        true,   /* global_only */
    4177             :                        false,  /* save_defaults */
    4178             :                        false,  /* add_ipc */
    4179             :                        true);  /* reinit_globals */
    4180             : }
    4181             : 
    4182             : /**
    4183             :  * The typical lp_load wrapper with shares, loads global and
    4184             :  * shares, including IPC, but does not force immediate
    4185             :  * loading of all shares from registry.
    4186             :  */
    4187       24133 : bool lp_load_with_shares(const char *file_name)
    4188             : {
    4189       24133 :         return lp_load(file_name,
    4190             :                        false,  /* global_only */
    4191             :                        false,  /* save_defaults */
    4192             :                        true,   /* add_ipc */
    4193             :                        true);  /* reinit_globals */
    4194             : }
    4195             : 
    4196             : /**
    4197             :  * lp_load wrapper, especially for clients
    4198             :  */
    4199       19485 : bool lp_load_client(const char *file_name)
    4200             : {
    4201       19485 :         lp_set_in_client(true);
    4202             : 
    4203       19485 :         return lp_load_global(file_name);
    4204             : }
    4205             : 
    4206             : /**
    4207             :  * lp_load wrapper, loading only globals, but intended
    4208             :  * for subsequent calls, not reinitializing the globals
    4209             :  * to default values
    4210             :  */
    4211         162 : bool lp_load_global_no_reinit(const char *file_name)
    4212             : {
    4213         162 :         return lp_load(file_name,
    4214             :                        true,   /* global_only */
    4215             :                        false,  /* save_defaults */
    4216             :                        false,  /* add_ipc */
    4217             :                        false); /* reinit_globals */
    4218             : }
    4219             : 
    4220             : /**
    4221             :  * lp_load wrapper, loading globals and shares,
    4222             :  * intended for subsequent calls, i.e. not reinitializing
    4223             :  * the globals to default values.
    4224             :  */
    4225        2288 : bool lp_load_no_reinit(const char *file_name)
    4226             : {
    4227        2288 :         return lp_load(file_name,
    4228             :                        false,  /* global_only */
    4229             :                        false,  /* save_defaults */
    4230             :                        false,  /* add_ipc */
    4231             :                        false); /* reinit_globals */
    4232             : }
    4233             : 
    4234             : 
    4235             : /**
    4236             :  * lp_load wrapper, especially for clients, no reinitialization
    4237             :  */
    4238         162 : bool lp_load_client_no_reinit(const char *file_name)
    4239             : {
    4240         162 :         lp_set_in_client(true);
    4241             : 
    4242         162 :         return lp_load_global_no_reinit(file_name);
    4243             : }
    4244             : 
    4245        2049 : bool lp_load_with_registry_shares(const char *pszFname)
    4246             : {
    4247        2049 :         return lp_load_ex(pszFname,
    4248             :                           false, /* global_only */
    4249             :                           true,  /* save_defaults */
    4250             :                           false, /* add_ipc */
    4251             :                           true, /* reinit_globals */
    4252             :                           true,  /* allow_include_registry */
    4253             :                           true); /* load_all_shares*/
    4254             : }
    4255             : 
    4256             : /***************************************************************************
    4257             :  Return the max number of services.
    4258             : ***************************************************************************/
    4259             : 
    4260        2484 : int lp_numservices(void)
    4261             : {
    4262        2484 :         return (iNumServices);
    4263             : }
    4264             : 
    4265             : /***************************************************************************
    4266             : Display the contents of the services array in human-readable form.
    4267             : ***************************************************************************/
    4268             : 
    4269         527 : void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
    4270             : {
    4271           0 :         int iService;
    4272           0 :         struct loadparm_context *lp_ctx;
    4273             : 
    4274         527 :         if (show_defaults)
    4275           0 :                 defaults_saved = false;
    4276             : 
    4277         527 :         lp_ctx = setup_lp_context(talloc_tos());
    4278         527 :         if (lp_ctx == NULL) {
    4279           0 :                 return;
    4280             :         }
    4281             : 
    4282         527 :         lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
    4283             : 
    4284         527 :         lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
    4285             : 
    4286         781 :         for (iService = 0; iService < maxtoprint; iService++) {
    4287         254 :                 fprintf(f,"\n");
    4288         254 :                 lp_dump_one(f, show_defaults, iService);
    4289             :         }
    4290         527 :         TALLOC_FREE(lp_ctx);
    4291             : }
    4292             : 
    4293             : /***************************************************************************
    4294             : Display the contents of one service in human-readable form.
    4295             : ***************************************************************************/
    4296             : 
    4297         254 : void lp_dump_one(FILE * f, bool show_defaults, int snum)
    4298             : {
    4299         254 :         if (VALID(snum)) {
    4300         254 :                 if (ServicePtrs[snum]->szService[0] == '\0')
    4301           0 :                         return;
    4302         254 :                 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
    4303             :                                      flags_list, show_defaults);
    4304             :         }
    4305             : }
    4306             : 
    4307             : /***************************************************************************
    4308             : Return the number of the service with the given name, or -1 if it doesn't
    4309             : exist. Note that this is a DIFFERENT ANIMAL from the internal function
    4310             : getservicebyname()! This works ONLY if all services have been loaded, and
    4311             : does not copy the found service.
    4312             : ***************************************************************************/
    4313             : 
    4314      293264 : int lp_servicenumber(const char *pszServiceName)
    4315             : {
    4316        3499 :         int iService;
    4317        3499 :         fstring serviceName;
    4318             : 
    4319      293264 :         if (!pszServiceName) {
    4320          32 :                 return GLOBAL_SECTION_SNUM;
    4321             :         }
    4322             : 
    4323    15390049 :         for (iService = iNumServices - 1; iService >= 0; iService--) {
    4324    15290450 :                 if (VALID(iService) && ServicePtrs[iService]->szService) {
    4325             :                         /*
    4326             :                          * The substitution here is used to support %U in
    4327             :                          * service names
    4328             :                          */
    4329    15250796 :                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
    4330    15250796 :                         standard_sub_basic(get_current_username(),
    4331             :                                            get_current_user_info_domain(),
    4332             :                                            serviceName,sizeof(serviceName));
    4333    15250796 :                         if (strequal(serviceName, pszServiceName)) {
    4334      191859 :                                 break;
    4335             :                         }
    4336             :                 }
    4337             :         }
    4338             : 
    4339      293232 :         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
    4340           0 :                 struct timespec last_mod;
    4341             : 
    4342           4 :                 if (!usershare_exists(iService, &last_mod)) {
    4343             :                         /* Remove the share security tdb entry for it. */
    4344           0 :                         delete_share_security(lp_const_servicename(iService));
    4345             :                         /* Remove it from the array. */
    4346           0 :                         free_service_byindex(iService);
    4347             :                         /* Doesn't exist anymore. */
    4348           0 :                         return GLOBAL_SECTION_SNUM;
    4349             :                 }
    4350             : 
    4351             :                 /* Has it been modified ? If so delete and reload. */
    4352           4 :                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
    4353             :                                      &last_mod) < 0) {
    4354             :                         /* Remove it from the array. */
    4355           0 :                         free_service_byindex(iService);
    4356             :                         /* and now reload it. */
    4357           0 :                         iService = load_usershare_service(pszServiceName);
    4358             :                 }
    4359             :         }
    4360             : 
    4361      293232 :         if (iService < 0) {
    4362       99599 :                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
    4363       99599 :                 return GLOBAL_SECTION_SNUM;
    4364             :         }
    4365             : 
    4366      191859 :         return (iService);
    4367             : }
    4368             : 
    4369             : /*******************************************************************
    4370             :  A useful volume label function.
    4371             : ********************************************************************/
    4372             : 
    4373        3429 : const char *volume_label(TALLOC_CTX *ctx, int snum)
    4374             : {
    4375           0 :         const struct loadparm_substitution *lp_sub =
    4376        3429 :                 loadparm_s3_global_substitution();
    4377           0 :         char *ret;
    4378        3429 :         const char *label = lp_volume(ctx, lp_sub, snum);
    4379        3429 :         size_t end = 32;
    4380             : 
    4381        3429 :         if (!*label) {
    4382        3429 :                 label = lp_servicename(ctx, lp_sub, snum);
    4383             :         }
    4384             : 
    4385             :         /*
    4386             :          * Volume label can be a max of 32 bytes. Make sure to truncate
    4387             :          * it at a codepoint boundary if it's longer than 32 and contains
    4388             :          * multibyte characters. Windows insists on a volume label being
    4389             :          * a valid mb sequence, and errors out if not.
    4390             :          */
    4391        3429 :         if (strlen(label) > 32) {
    4392             :                 /*
    4393             :                  * A MB char can be a max of 5 bytes, thus
    4394             :                  * we should have a valid mb character at a
    4395             :                  * minimum position of (32-5) = 27.
    4396             :                  */
    4397           0 :                 while (end >= 27) {
    4398             :                         /*
    4399             :                          * Check if a codepoint starting from next byte
    4400             :                          * is valid. If yes, then the current byte is the
    4401             :                          * end of a MB or ascii sequence and the label can
    4402             :                          * be safely truncated here. If not, keep going
    4403             :                          * backwards till a valid codepoint is found.
    4404             :                          */
    4405           0 :                         size_t len = 0;
    4406           0 :                         const char *s = &label[end];
    4407           0 :                         codepoint_t c = next_codepoint(s, &len);
    4408           0 :                         if (c != INVALID_CODEPOINT) {
    4409           0 :                                 break;
    4410             :                         }
    4411           0 :                         end--;
    4412             :                 }
    4413             :         }
    4414             : 
    4415             :         /* This returns a max of 33 byte guaranteed null terminated string. */
    4416        3429 :         ret = talloc_strndup(ctx, label, end);
    4417        3429 :         if (!ret) {
    4418           0 :                 return "";
    4419             :         }
    4420        3429 :         return ret;
    4421             : }
    4422             : 
    4423             : /*******************************************************************
    4424             :  Get the default server type we will announce as via nmbd.
    4425             : ********************************************************************/
    4426             : 
    4427       18104 : int lp_default_server_announce(void)
    4428             : {
    4429       18104 :         int default_server_announce = 0;
    4430       18104 :         default_server_announce |= SV_TYPE_WORKSTATION;
    4431       18104 :         default_server_announce |= SV_TYPE_SERVER;
    4432       18104 :         default_server_announce |= SV_TYPE_SERVER_UNIX;
    4433             : 
    4434             :         /* note that the flag should be set only if we have a
    4435             :            printer service but nmbd doesn't actually load the
    4436             :            services so we can't tell   --jerry */
    4437             : 
    4438       18104 :         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
    4439             : 
    4440       18104 :         default_server_announce |= SV_TYPE_SERVER_NT;
    4441       18104 :         default_server_announce |= SV_TYPE_NT;
    4442             : 
    4443       18104 :         switch (lp_server_role()) {
    4444        7404 :                 case ROLE_DOMAIN_MEMBER:
    4445        7404 :                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
    4446        7404 :                         break;
    4447        7174 :                 case ROLE_DOMAIN_PDC:
    4448             :                 case ROLE_IPA_DC:
    4449        7174 :                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
    4450        7174 :                         break;
    4451           0 :                 case ROLE_DOMAIN_BDC:
    4452           0 :                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
    4453           0 :                         break;
    4454        3526 :                 case ROLE_STANDALONE:
    4455             :                 default:
    4456        3526 :                         break;
    4457             :         }
    4458       18104 :         if (lp_time_server())
    4459       18086 :                 default_server_announce |= SV_TYPE_TIME_SOURCE;
    4460             : 
    4461       18104 :         if (lp_host_msdfs())
    4462       18104 :                 default_server_announce |= SV_TYPE_DFS_SERVER;
    4463             : 
    4464       18104 :         return default_server_announce;
    4465             : }
    4466             : 
    4467             : /***********************************************************
    4468             :  If we are PDC then prefer us as DMB
    4469             : ************************************************************/
    4470             : 
    4471         293 : bool lp_domain_master(void)
    4472             : {
    4473         293 :         if (Globals._domain_master == Auto)
    4474         338 :                 return (lp_server_role() == ROLE_DOMAIN_PDC ||
    4475         164 :                         lp_server_role() == ROLE_IPA_DC);
    4476             : 
    4477         119 :         return (bool)Globals._domain_master;
    4478             : }
    4479             : 
    4480             : /***********************************************************
    4481             :  If we are PDC then prefer us as DMB
    4482             : ************************************************************/
    4483             : 
    4484     2550905 : static bool lp_domain_master_true_or_auto(void)
    4485             : {
    4486     2550905 :         if (Globals._domain_master) /* auto or yes */
    4487     2550905 :                 return true;
    4488             : 
    4489           0 :         return false;
    4490             : }
    4491             : 
    4492             : /***********************************************************
    4493             :  If we are DMB then prefer us as LMB
    4494             : ************************************************************/
    4495             : 
    4496          43 : bool lp_preferred_master(void)
    4497             : {
    4498          43 :         int preferred_master = lp__preferred_master();
    4499             : 
    4500          43 :         if (preferred_master == Auto)
    4501          43 :                 return (lp_local_master() && lp_domain_master());
    4502             : 
    4503           0 :         return (bool)preferred_master;
    4504             : }
    4505             : 
    4506             : /*******************************************************************
    4507             :  Remove a service.
    4508             : ********************************************************************/
    4509             : 
    4510           0 : void lp_remove_service(int snum)
    4511             : {
    4512           0 :         ServicePtrs[snum]->valid = false;
    4513           0 : }
    4514             : 
    4515        6003 : const char *lp_printername(TALLOC_CTX *ctx,
    4516             :                            const struct loadparm_substitution *lp_sub,
    4517             :                            int snum)
    4518             : {
    4519        6003 :         const char *ret = lp__printername(ctx, lp_sub, snum);
    4520             : 
    4521        6003 :         if (ret == NULL || *ret == '\0') {
    4522        6003 :                 ret = lp_const_servicename(snum);
    4523             :         }
    4524             : 
    4525        6003 :         return ret;
    4526             : }
    4527             : 
    4528             : 
    4529             : /***********************************************************
    4530             :  Allow daemons such as winbindd to fix their logfile name.
    4531             : ************************************************************/
    4532             : 
    4533           0 : void lp_set_logfile(const char *name)
    4534             : {
    4535           0 :         lpcfg_string_set(Globals.ctx, &Globals.logfile, name);
    4536           0 :         debug_set_logfile(name);
    4537           0 : }
    4538             : 
    4539             : /*******************************************************************
    4540             :  Return the max print jobs per queue.
    4541             : ********************************************************************/
    4542             : 
    4543         668 : int lp_maxprintjobs(int snum)
    4544             : {
    4545         668 :         int maxjobs = lp_max_print_jobs(snum);
    4546             : 
    4547         668 :         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
    4548           0 :                 maxjobs = PRINT_MAX_JOBID - 1;
    4549             : 
    4550         668 :         return maxjobs;
    4551             : }
    4552             : 
    4553          42 : const char *lp_printcapname(void)
    4554             : {
    4555          42 :         const char *printcap_name = lp_printcap_name();
    4556             : 
    4557          42 :         if ((printcap_name != NULL) &&
    4558          42 :             (printcap_name[0] != '\0'))
    4559          42 :                 return printcap_name;
    4560             : 
    4561           0 :         if (sDefault.printing == PRINT_CUPS) {
    4562           0 :                 return "cups";
    4563             :         }
    4564             : 
    4565           0 :         if (sDefault.printing == PRINT_BSD)
    4566           0 :                 return "/etc/printcap";
    4567             : 
    4568           0 :         return PRINTCAP_NAME;
    4569             : }
    4570             : 
    4571             : static uint32_t spoolss_state;
    4572             : 
    4573        9698 : bool lp_disable_spoolss( void )
    4574             : {
    4575        9698 :         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
    4576          28 :                 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
    4577             : 
    4578        9698 :         return spoolss_state == SVCCTL_STOPPED ? true : false;
    4579             : }
    4580             : 
    4581           0 : void lp_set_spoolss_state( uint32_t state )
    4582             : {
    4583           0 :         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
    4584             : 
    4585           0 :         spoolss_state = state;
    4586           0 : }
    4587             : 
    4588          24 : uint32_t lp_get_spoolss_state( void )
    4589             : {
    4590          24 :         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
    4591             : }
    4592             : 
    4593             : /*******************************************************************
    4594             :  Turn off sendfile if we find the underlying OS doesn't support it.
    4595             : ********************************************************************/
    4596             : 
    4597           0 : void set_use_sendfile(int snum, bool val)
    4598             : {
    4599           0 :         if (LP_SNUM_OK(snum))
    4600           0 :                 ServicePtrs[snum]->_use_sendfile = val;
    4601             :         else
    4602           0 :                 sDefault._use_sendfile = val;
    4603           0 : }
    4604             : 
    4605         478 : void lp_set_mangling_method(const char *new_method)
    4606             : {
    4607         478 :         lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method);
    4608         478 : }
    4609             : 
    4610             : /*******************************************************************
    4611             :  Global state for POSIX pathname processing.
    4612             : ********************************************************************/
    4613             : 
    4614             : static bool posix_pathnames;
    4615             : 
    4616      680248 : bool lp_posix_pathnames(void)
    4617             : {
    4618      680248 :         return posix_pathnames;
    4619             : }
    4620             : 
    4621             : /*******************************************************************
    4622             :  Change everything needed to ensure POSIX pathname processing (currently
    4623             :  not much).
    4624             : ********************************************************************/
    4625             : 
    4626         478 : void lp_set_posix_pathnames(void)
    4627             : {
    4628         478 :         posix_pathnames = true;
    4629         478 : }
    4630             : 
    4631             : /*******************************************************************
    4632             :  Global state for POSIX lock processing - CIFS unix extensions.
    4633             : ********************************************************************/
    4634             : 
    4635             : bool posix_default_lock_was_set;
    4636             : static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
    4637             : 
    4638      409004 : enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
    4639             : {
    4640      409004 :         if (posix_default_lock_was_set) {
    4641           0 :                 return posix_cifsx_locktype;
    4642             :         } else {
    4643      409004 :                 return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
    4644      409004 :                         POSIX_LOCK : WINDOWS_LOCK;
    4645             :         }
    4646             : }
    4647             : 
    4648             : /*******************************************************************
    4649             : ********************************************************************/
    4650             : 
    4651           0 : void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
    4652             : {
    4653           0 :         posix_default_lock_was_set = true;
    4654           0 :         posix_cifsx_locktype = val;
    4655           0 : }
    4656             : 
    4657     2146780 : int lp_min_receive_file_size(void)
    4658             : {
    4659     2146780 :         int min_receivefile_size = lp_min_receivefile_size();
    4660             : 
    4661     2146780 :         if (min_receivefile_size < 0) {
    4662           0 :                 return 0;
    4663             :         }
    4664     2126795 :         return min_receivefile_size;
    4665             : }
    4666             : 
    4667             : /*******************************************************************
    4668             :  Safe wide links checks.
    4669             :  This helper function always verify the validity of wide links,
    4670             :  even after a configuration file reload.
    4671             : ********************************************************************/
    4672             : 
    4673       50022 : void widelinks_warning(int snum)
    4674             : {
    4675       50022 :         if (lp_allow_insecure_wide_links()) {
    4676       40950 :                 return;
    4677             :         }
    4678             : 
    4679        9072 :         if (lp_wide_links(snum)) {
    4680           0 :                 if (lp_smb1_unix_extensions()) {
    4681           0 :                         DBG_ERR("Share '%s' has wide links and SMB1 unix "
    4682             :                         "extensions enabled. "
    4683             :                         "These parameters are incompatible. "
    4684             :                         "Wide links will be disabled for this share.\n",
    4685             :                          lp_const_servicename(snum));
    4686           0 :                 } else if (lp_smb3_unix_extensions(snum)) {
    4687           0 :                         DBG_ERR("Share '%s' has wide links and SMB3 Unix "
    4688             :                                 "extensions enabled. "
    4689             :                                 "These parameters are incompatible. "
    4690             :                                 "Wide links will be disabled for this share.\n",
    4691             :                                 lp_const_servicename(snum));
    4692             :                 }
    4693             :         }
    4694             : }
    4695             : 
    4696       58836 : bool lp_widelinks(int snum)
    4697             : {
    4698             :         /* wide links is always incompatible with unix extensions */
    4699       58836 :         if (lp_smb1_unix_extensions() || lp_smb3_unix_extensions(snum)) {
    4700             :                 /*
    4701             :                  * Unless we have "allow insecure widelinks"
    4702             :                  * turned on.
    4703             :                  */
    4704       58836 :                 if (!lp_allow_insecure_wide_links()) {
    4705       11890 :                         return false;
    4706             :                 }
    4707             :         }
    4708             : 
    4709       46052 :         return lp_wide_links(snum);
    4710             : }
    4711             : 
    4712     2550905 : int lp_server_role(void)
    4713             : {
    4714     2554096 :         return lp_find_server_role(lp__server_role(),
    4715             :                                    lp__security(),
    4716     2550905 :                                    lp__domain_logons(),
    4717     2547714 :                                    lp_domain_master_true_or_auto());
    4718             : }
    4719             : 
    4720      123538 : int lp_security(void)
    4721             : {
    4722      123538 :         return lp_find_security(lp__server_role(),
    4723             :                                 lp__security());
    4724             : }
    4725             : 
    4726       68025 : int lp_client_max_protocol(void)
    4727             : {
    4728       68025 :         int client_max_protocol = lp__client_max_protocol();
    4729       68025 :         if (client_max_protocol == PROTOCOL_DEFAULT) {
    4730       53002 :                 return PROTOCOL_LATEST;
    4731             :         }
    4732       15023 :         return client_max_protocol;
    4733             : }
    4734             : 
    4735        1590 : int lp_client_ipc_min_protocol(void)
    4736             : {
    4737        1590 :         int client_ipc_min_protocol = lp__client_ipc_min_protocol();
    4738        1590 :         if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
    4739        1590 :                 client_ipc_min_protocol = lp_client_min_protocol();
    4740             :         }
    4741        1590 :         if (client_ipc_min_protocol < PROTOCOL_NT1) {
    4742        1126 :                 return PROTOCOL_NT1;
    4743             :         }
    4744         464 :         return client_ipc_min_protocol;
    4745             : }
    4746             : 
    4747        1590 : int lp_client_ipc_max_protocol(void)
    4748             : {
    4749        1590 :         int client_ipc_max_protocol = lp__client_ipc_max_protocol();
    4750        1590 :         if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
    4751        1590 :                 return PROTOCOL_LATEST;
    4752             :         }
    4753           0 :         if (client_ipc_max_protocol < PROTOCOL_NT1) {
    4754           0 :                 return PROTOCOL_NT1;
    4755             :         }
    4756           0 :         return client_ipc_max_protocol;
    4757             : }
    4758             : 
    4759        3808 : int lp_client_ipc_signing(void)
    4760             : {
    4761        3808 :         int client_ipc_signing = lp__client_ipc_signing();
    4762        3808 :         if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
    4763        3808 :                 return SMB_SIGNING_REQUIRED;
    4764             :         }
    4765           0 :         return client_ipc_signing;
    4766             : }
    4767             : 
    4768           0 : enum credentials_use_kerberos lp_client_use_kerberos(void)
    4769             : {
    4770           0 :         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
    4771           0 :                 return CRED_USE_KERBEROS_REQUIRED;
    4772             :         }
    4773             : 
    4774           0 :         return lp__client_use_kerberos();
    4775             : }
    4776             : 
    4777             : 
    4778          16 : int lp_rpc_low_port(void)
    4779             : {
    4780          16 :         return Globals.rpc_low_port;
    4781             : }
    4782             : 
    4783          64 : int lp_rpc_high_port(void)
    4784             : {
    4785          64 :         return Globals.rpc_high_port;
    4786             : }
    4787             : 
    4788         156 : const char *lp_dns_hostname(void)
    4789             : {
    4790         156 :         const char *dns_hostname = lp__dns_hostname();
    4791         156 :         const char *dns_domain = lp_dnsdomain();
    4792         156 :         char *netbios_name = NULL;
    4793             : 
    4794         156 :         if (dns_hostname != NULL && dns_hostname[0] != '\0') {
    4795          96 :                 return dns_hostname;
    4796             :         }
    4797             : 
    4798          60 :         netbios_name = talloc_strdup(talloc_tos(), lp_netbios_name());
    4799          60 :         if (netbios_name == NULL) {
    4800           0 :                 return NULL;
    4801             :         }
    4802          60 :         strlower_m(netbios_name);
    4803             : 
    4804             :         /* If it isn't set, try to initialize with [netbios name].[realm] */
    4805          60 :         if (dns_domain != NULL && dns_domain[0] != '\0') {
    4806          60 :                 Globals._dns_hostname = talloc_asprintf(Globals.ctx,
    4807             :                                                         "%s.%s",
    4808             :                                                         netbios_name,
    4809             :                                                         dns_domain);
    4810             :         } else {
    4811           0 :                 Globals._dns_hostname = talloc_strdup(Globals.ctx,
    4812             :                                                       netbios_name);
    4813             :         }
    4814          60 :         TALLOC_FREE(netbios_name);
    4815          60 :         if (Globals._dns_hostname == NULL) {
    4816           0 :                 return NULL;
    4817             :         }
    4818          60 :         dns_hostname = Globals._dns_hostname;
    4819             : 
    4820          60 :         return dns_hostname;
    4821             : }
    4822             : 
    4823             : /*
    4824             :  * Do not allow LanMan auth if unless NTLMv1 is also allowed
    4825             :  *
    4826             :  * This also ensures it is disabled if NTLM is totally disabled
    4827             :  */
    4828       56777 : bool lp_lanman_auth(void)
    4829             : {
    4830       56777 :         enum ntlm_auth_level ntlm_auth_level = lp_ntlm_auth();
    4831             : 
    4832       56777 :         if (ntlm_auth_level == NTLM_AUTH_ON) {
    4833       44172 :                 return lp__lanman_auth();
    4834             :         } else {
    4835       12599 :                 return false;
    4836             :         }
    4837             : }
    4838             : 
    4839      836399 : struct loadparm_global * get_globals(void)
    4840             : {
    4841      836399 :         return &Globals;
    4842             : }
    4843             : 
    4844      836395 : unsigned int * get_flags(void)
    4845             : {
    4846      836395 :         if (flags_list == NULL) {
    4847       40209 :                 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
    4848             :         }
    4849             : 
    4850      836395 :         return flags_list;
    4851             : }
    4852             : 
    4853         262 : enum samba_weak_crypto lp_weak_crypto(void)
    4854             : {
    4855         262 :         if (Globals.weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) {
    4856          51 :                 Globals.weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED;
    4857             : 
    4858          51 :                 if (samba_gnutls_weak_crypto_allowed()) {
    4859          50 :                         Globals.weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED;
    4860             :                 }
    4861             :         }
    4862             : 
    4863         262 :         return Globals.weak_crypto;
    4864             : }
    4865             : 
    4866         502 : uint32_t lp_get_async_dns_timeout(void)
    4867             : {
    4868             :         /*
    4869             :          * Clamp minimum async dns timeout to 1 second
    4870             :          * as per the man page.
    4871             :          */
    4872         502 :         return MAX(Globals.async_dns_timeout, 1);
    4873             : }

Generated by: LCOV version 1.14