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