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