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