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