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