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