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