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