36bd4890bf4febad1b17b0444942fbbe5bf23c16
[mat/samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14    Copyright (C) Andrew Bartlett 2011
15
16    This program is free software; you can redistribute it and/or modify
17    it under the terms of the GNU General Public License as published by
18    the Free Software Foundation; either version 3 of the License, or
19    (at your option) any later version.
20
21    This program is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24    GNU General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with this program.  If not, see <http://www.gnu.org/licenses/>.
28 */
29
30 /*
31  *  Load parameters.
32  *
33  *  This module provides suitable callback functions for the params
34  *  module. It builds the internal table of service details which is
35  *  then used by the rest of the server.
36  *
37  * To add a parameter:
38  *
39  * 1) add it to the global or service structure definition
40  * 2) add it to the parm_table
41  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42  * 4) If it's a global then initialise it in init_globals. If a local
43  *    (ie. service) parameter then initialise it in the sDefault structure
44  *  
45  *
46  * Notes:
47  *   The configuration file is processed sequentially for speed. It is NOT
48  *   accessed randomly as happens in 'real' Windows. For this reason, there
49  *   is a fair bit of sequence-dependent code here - ie., code which assumes
50  *   that certain things happen before others. In particular, the code which
51  *   happens at the boundary between sections is delicately poised, so be
52  *   careful!
53  *
54  */
55
56 #include "includes.h"
57 #include "system/filesys.h"
58 #include "util_tdb.h"
59 #include "lib/param/loadparm.h"
60 #include "lib/param/param.h"
61 #include "printing.h"
62 #include "lib/smbconf/smbconf.h"
63 #include "lib/smbconf/smbconf_init.h"
64
65 #include "ads.h"
66 #include "../librpc/gen_ndr/svcctl.h"
67 #include "intl.h"
68 #include "../libcli/smb/smb_signing.h"
69 #include "dbwrap/dbwrap.h"
70 #include "dbwrap/dbwrap_rbt.h"
71 #include "../lib/util/bitmap.h"
72
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, bool store_values);
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, false)) {
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, bool store_values)
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                 if (store_values) {
2806                         store_lp_set_cmdline(pszParmName, pszParmValue);
2807                 }
2808                 return true;
2809         }
2810
2811         /* it might be parametric */
2812         if (strchr(pszParmName, ':') != NULL) {
2813                 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2814                 if (store_values) {
2815                         store_lp_set_cmdline(pszParmName, pszParmValue);
2816                 }
2817                 return true;
2818         }
2819
2820         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
2821         return false;
2822 }
2823
2824 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2825 {
2826         return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
2827 }
2828
2829 /***************************************************************************
2830  Process a parameter.
2831 ***************************************************************************/
2832
2833 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2834                          void *userdata)
2835 {
2836         if (!bInGlobalSection && bGlobalOnly)
2837                 return true;
2838
2839         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2840
2841         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2842                                 pszParmName, pszParmValue));
2843 }
2844
2845 /***************************************************************************
2846  Initialize any local variables in the sDefault table, after parsing a
2847  [globals] section.
2848 ***************************************************************************/
2849
2850 static void init_locals(void)
2851 {
2852         /*
2853          * We run this check once the [globals] is parsed, to force
2854          * the VFS objects and other per-share settings we need for
2855          * the standard way a AD DC is operated.  We may change these
2856          * as our code evolves, which is why we force these settings.
2857          *
2858          * We can't do this at the end of lp_load_ex(), as by that
2859          * point the services have been loaded and they will already
2860          * have "" as their vfs objects.
2861          */
2862         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2863                 const char **vfs_objects = lp_vfs_objects(-1);
2864                 if (!vfs_objects || !vfs_objects[0]) {
2865                         if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2866                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2867                         } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2868                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2869                         } else {
2870                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2871                         }
2872                 }
2873
2874                 lp_do_parameter(-1, "map hidden", "no");
2875                 lp_do_parameter(-1, "map system", "no");
2876                 lp_do_parameter(-1, "map readonly", "no");
2877                 lp_do_parameter(-1, "map archive", "no");
2878                 lp_do_parameter(-1, "store dos attributes", "yes");
2879         }
2880 }
2881
2882 /***************************************************************************
2883  Process a new section (service). At this stage all sections are services.
2884  Later we'll have special sections that permit server parameters to be set.
2885  Returns true on success, false on failure.
2886 ***************************************************************************/
2887
2888 static bool do_section(const char *pszSectionName, void *userdata)
2889 {
2890         bool bRetval;
2891         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2892                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2893         bRetval = false;
2894
2895         /* if we were in a global section then do the local inits */
2896         if (bInGlobalSection && !isglobal)
2897                 init_locals();
2898
2899         /* if we've just struck a global section, note the fact. */
2900         bInGlobalSection = isglobal;
2901
2902         /* check for multiple global sections */
2903         if (bInGlobalSection) {
2904                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2905                 return true;
2906         }
2907
2908         if (!bInGlobalSection && bGlobalOnly)
2909                 return true;
2910
2911         /* if we have a current service, tidy it up before moving on */
2912         bRetval = true;
2913
2914         if (iServiceIndex >= 0)
2915                 bRetval = service_ok(iServiceIndex);
2916
2917         /* if all is still well, move to the next record in the services array */
2918         if (bRetval) {
2919                 /* We put this here to avoid an odd message order if messages are */
2920                 /* issued by the post-processing of a previous section. */
2921                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2922
2923                 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2924                 if (iServiceIndex < 0) {
2925                         DEBUG(0, ("Failed to add a new service\n"));
2926                         return false;
2927                 }
2928                 /* Clean all parametric options for service */
2929                 /* They will be added during parsing again */
2930                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2931         }
2932
2933         return bRetval;
2934 }
2935
2936
2937 /***************************************************************************
2938  Determine if a partcular base parameter is currentl set to the default value.
2939 ***************************************************************************/
2940
2941 static bool is_default(int i)
2942 {
2943         switch (parm_table[i].type) {
2944                 case P_LIST:
2945                 case P_CMDLIST:
2946                         return str_list_equal((const char * const *)parm_table[i].def.lvalue,
2947                                               *(const char ***)lp_parm_ptr(NULL, 
2948                                                                            &parm_table[i]));
2949                 case P_STRING:
2950                 case P_USTRING:
2951                         return strequal(parm_table[i].def.svalue,
2952                                         *(char **)lp_parm_ptr(NULL, 
2953                                                               &parm_table[i]));
2954                 case P_BOOL:
2955                 case P_BOOLREV:
2956                         return parm_table[i].def.bvalue ==
2957                                 *(bool *)lp_parm_ptr(NULL, 
2958                                                      &parm_table[i]);
2959                 case P_CHAR:
2960                         return parm_table[i].def.cvalue ==
2961                                 *(char *)lp_parm_ptr(NULL, 
2962                                                      &parm_table[i]);
2963                 case P_INTEGER:
2964                 case P_OCTAL:
2965                 case P_ENUM:
2966                 case P_BYTES:
2967                         return parm_table[i].def.ivalue ==
2968                                 *(int *)lp_parm_ptr(NULL, 
2969                                                     &parm_table[i]);
2970                 case P_SEP:
2971                         break;
2972         }
2973         return false;
2974 }
2975
2976 /***************************************************************************
2977 Display the contents of the global structure.
2978 ***************************************************************************/
2979
2980 static void dump_globals(FILE *f)
2981 {
2982         int i;
2983         struct parmlist_entry *data;
2984
2985         fprintf(f, "[global]\n");
2986
2987         for (i = 0; parm_table[i].label; i++)
2988                 if (parm_table[i].p_class == P_GLOBAL &&
2989                     !(parm_table[i].flags & FLAG_META) &&
2990                     (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
2991                         if (defaults_saved && is_default(i))
2992                                 continue;
2993                         fprintf(f, "\t%s = ", parm_table[i].label);
2994                         lpcfg_print_parameter(&parm_table[i], lp_parm_ptr(NULL,
2995                                                                           &parm_table[i]),
2996                                         f);
2997                         fprintf(f, "\n");
2998         }
2999         if (Globals.param_opt != NULL) {
3000                 data = Globals.param_opt;
3001                 while(data) {
3002                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3003                         data = data->next;
3004                 }
3005         }
3006
3007 }
3008
3009 /***************************************************************************
3010  Display the contents of a single services record.
3011 ***************************************************************************/
3012
3013 static void dump_a_service(struct loadparm_service *pService, FILE * f, bool show_defaults)
3014 {
3015         return lpcfg_dump_a_service(pService, &sDefault, f, NULL, show_defaults);
3016 }
3017
3018 /***************************************************************************
3019  Display the contents of a parameter of a single services record.
3020 ***************************************************************************/
3021
3022 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
3023 {
3024         bool result = false;
3025
3026         struct loadparm_context *lp_ctx;
3027
3028         lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3029         if (lp_ctx == NULL) {
3030                 return false;
3031         }
3032
3033         if (isGlobal) {
3034                 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
3035         } else {
3036                 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
3037         }
3038         TALLOC_FREE(lp_ctx);
3039         return result;
3040 }
3041
3042 /***************************************************************************
3043  Return info about the requested parameter (given as a string).
3044  Return NULL when the string is not a valid parameter name.
3045 ***************************************************************************/
3046
3047 struct parm_struct *lp_get_parameter(const char *param_name)
3048 {
3049         int num = lpcfg_map_parameter(param_name);
3050
3051         if (num < 0) {
3052                 return NULL;
3053         }
3054
3055         return &parm_table[num];
3056 }
3057
3058 #if 0
3059 /***************************************************************************
3060  Display the contents of a single copy structure.
3061 ***************************************************************************/
3062 static void dump_copy_map(bool *pcopymap)
3063 {
3064         int i;
3065         if (!pcopymap)
3066                 return;
3067
3068         printf("\n\tNon-Copied parameters:\n");
3069
3070         for (i = 0; parm_table[i].label; i++)
3071                 if (parm_table[i].p_class == P_LOCAL &&
3072                     parm_table[i].ptr && !pcopymap[i] &&
3073                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3074                 {
3075                         printf("\t\t%s\n", parm_table[i].label);
3076                 }
3077 }
3078 #endif
3079
3080 /***************************************************************************
3081  Return TRUE if the passed service number is within range.
3082 ***************************************************************************/
3083
3084 bool lp_snum_ok(int iService)
3085 {
3086         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3087 }
3088
3089 /***************************************************************************
3090  Auto-load some home services.
3091 ***************************************************************************/
3092
3093 static void lp_add_auto_services(char *str)
3094 {
3095         char *s;
3096         char *p;
3097         int homes;
3098         char *saveptr;
3099
3100         if (!str)
3101                 return;
3102
3103         s = talloc_strdup(talloc_tos(), str);
3104         if (!s) {
3105                 smb_panic("talloc_strdup failed");
3106                 return;
3107         }
3108
3109         homes = lp_servicenumber(HOMES_NAME);
3110
3111         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3112              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3113                 char *home;
3114
3115                 if (lp_servicenumber(p) >= 0)
3116                         continue;
3117
3118                 home = get_user_home_dir(talloc_tos(), p);
3119
3120                 if (home && home[0] && homes >= 0)
3121                         lp_add_home(p, homes, p, home);
3122
3123                 TALLOC_FREE(home);
3124         }
3125         TALLOC_FREE(s);
3126 }
3127
3128 /***************************************************************************
3129  Auto-load one printer.
3130 ***************************************************************************/
3131
3132 void lp_add_one_printer(const char *name, const char *comment,
3133                         const char *location, void *pdata)
3134 {
3135         int printers = lp_servicenumber(PRINTERS_NAME);
3136         int i;
3137
3138         if (lp_servicenumber(name) < 0) {
3139                 lp_add_printer(name, printers);
3140                 if ((i = lp_servicenumber(name)) >= 0) {
3141                         string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
3142                         ServicePtrs[i]->autoloaded = true;
3143                 }
3144         }
3145 }
3146
3147 /***************************************************************************
3148  Have we loaded a services file yet?
3149 ***************************************************************************/
3150
3151 bool lp_loaded(void)
3152 {
3153         return (bLoaded);
3154 }
3155
3156 /***************************************************************************
3157  Unload unused services.
3158 ***************************************************************************/
3159
3160 void lp_killunused(struct smbd_server_connection *sconn,
3161                    bool (*snumused) (struct smbd_server_connection *, int))
3162 {
3163         int i;
3164         for (i = 0; i < iNumServices; i++) {
3165                 if (!VALID(i))
3166                         continue;
3167
3168                 /* don't kill autoloaded or usershare services */
3169                 if ( ServicePtrs[i]->autoloaded ||
3170                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3171                         continue;
3172                 }
3173
3174                 if (!snumused || !snumused(sconn, i)) {
3175                         free_service_byindex(i);
3176                 }
3177         }
3178 }
3179
3180 /**
3181  * Kill all except autoloaded and usershare services - convenience wrapper
3182  */
3183 void lp_kill_all_services(void)
3184 {
3185         lp_killunused(NULL, NULL);
3186 }
3187
3188 /***************************************************************************
3189  Unload a service.
3190 ***************************************************************************/
3191
3192 void lp_killservice(int iServiceIn)
3193 {
3194         if (VALID(iServiceIn)) {
3195                 free_service_byindex(iServiceIn);
3196         }
3197 }
3198
3199 /***************************************************************************
3200  Save the curent values of all global and sDefault parameters into the 
3201  defaults union. This allows testparm to show only the
3202  changed (ie. non-default) parameters.
3203 ***************************************************************************/
3204
3205 static void lp_save_defaults(void)
3206 {
3207         int i;
3208         for (i = 0; parm_table[i].label; i++) {
3209                 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3210                     && parm_table[i].p_class == parm_table[i - 1].p_class)
3211                         continue;
3212                 switch (parm_table[i].type) {
3213                         case P_LIST:
3214                         case P_CMDLIST:
3215                                 parm_table[i].def.lvalue = str_list_copy(
3216                                         NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3217                                 break;
3218                         case P_STRING:
3219                         case P_USTRING:
3220                                 parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i]));
3221                                 if (parm_table[i].def.svalue == NULL) {
3222                                         smb_panic("talloc_strdup failed");
3223                                 }
3224                                 break;
3225                         case P_BOOL:
3226                         case P_BOOLREV:
3227                                 parm_table[i].def.bvalue =
3228                                         *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3229                                 break;
3230                         case P_CHAR:
3231                                 parm_table[i].def.cvalue =
3232                                         *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3233                                 break;
3234                         case P_INTEGER:
3235                         case P_OCTAL:
3236                         case P_ENUM:
3237                         case P_BYTES:
3238                                 parm_table[i].def.ivalue =
3239                                         *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3240                                 break;
3241                         case P_SEP:
3242                                 break;
3243                 }
3244         }
3245         defaults_saved = true;
3246 }
3247
3248 /***********************************************************
3249  If we should send plaintext/LANMAN passwords in the clinet
3250 ************************************************************/
3251
3252 static void set_allowed_client_auth(void)
3253 {
3254         if (Globals.client_ntlmv2_auth) {
3255                 Globals.client_lanman_auth = false;
3256         }
3257         if (!Globals.client_lanman_auth) {
3258                 Globals.client_plaintext_auth = false;
3259         }
3260 }
3261
3262 /***************************************************************************
3263  JRA.
3264  The following code allows smbd to read a user defined share file.
3265  Yes, this is my intent. Yes, I'm comfortable with that...
3266
3267  THE FOLLOWING IS SECURITY CRITICAL CODE.
3268
3269  It washes your clothes, it cleans your house, it guards you while you sleep...
3270  Do not f%^k with it....
3271 ***************************************************************************/
3272
3273 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3274
3275 /***************************************************************************
3276  Check allowed stat state of a usershare file.
3277  Ensure we print out who is dicking with us so the admin can
3278  get their sorry ass fired.
3279 ***************************************************************************/
3280
3281 static bool check_usershare_stat(const char *fname,
3282                                  const SMB_STRUCT_STAT *psbuf)
3283 {
3284         if (!S_ISREG(psbuf->st_ex_mode)) {
3285                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3286                         "not a regular file\n",
3287                         fname, (unsigned int)psbuf->st_ex_uid ));
3288                 return false;
3289         }
3290
3291         /* Ensure this doesn't have the other write bit set. */
3292         if (psbuf->st_ex_mode & S_IWOTH) {
3293                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3294                         "public write. Refusing to allow as a usershare file.\n",
3295                         fname, (unsigned int)psbuf->st_ex_uid ));
3296                 return false;
3297         }
3298
3299         /* Should be 10k or less. */
3300         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3301                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3302                         "too large (%u) to be a user share file.\n",
3303                         fname, (unsigned int)psbuf->st_ex_uid,
3304                         (unsigned int)psbuf->st_ex_size ));
3305                 return false;
3306         }
3307
3308         return true;
3309 }
3310
3311 /***************************************************************************
3312  Parse the contents of a usershare file.
3313 ***************************************************************************/
3314
3315 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3316                         SMB_STRUCT_STAT *psbuf,
3317                         const char *servicename,
3318                         int snum,
3319                         char **lines,
3320                         int numlines,
3321                         char **pp_sharepath,
3322                         char **pp_comment,
3323                         char **pp_cp_servicename,
3324                         struct security_descriptor **ppsd,
3325                         bool *pallow_guest)
3326 {
3327         const char **prefixallowlist = lp_usershare_prefix_allow_list();
3328         const char **prefixdenylist = lp_usershare_prefix_deny_list();
3329         int us_vers;
3330         DIR *dp;
3331         SMB_STRUCT_STAT sbuf;
3332         char *sharepath = NULL;
3333         char *comment = NULL;
3334
3335         *pp_sharepath = NULL;
3336         *pp_comment = NULL;
3337
3338         *pallow_guest = false;
3339
3340         if (numlines < 4) {
3341                 return USERSHARE_MALFORMED_FILE;
3342         }
3343
3344         if (strcmp(lines[0], "#VERSION 1") == 0) {
3345                 us_vers = 1;
3346         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3347                 us_vers = 2;
3348                 if (numlines < 5) {
3349                         return USERSHARE_MALFORMED_FILE;
3350                 }
3351         } else {
3352                 return USERSHARE_BAD_VERSION;
3353         }
3354
3355         if (strncmp(lines[1], "path=", 5) != 0) {
3356                 return USERSHARE_MALFORMED_PATH;
3357         }
3358
3359         sharepath = talloc_strdup(ctx, &lines[1][5]);
3360         if (!sharepath) {
3361                 return USERSHARE_POSIX_ERR;
3362         }
3363         trim_string(sharepath, " ", " ");
3364
3365         if (strncmp(lines[2], "comment=", 8) != 0) {
3366                 return USERSHARE_MALFORMED_COMMENT_DEF;
3367         }
3368
3369         comment = talloc_strdup(ctx, &lines[2][8]);
3370         if (!comment) {
3371                 return USERSHARE_POSIX_ERR;
3372         }
3373         trim_string(comment, " ", " ");
3374         trim_char(comment, '"', '"');
3375
3376         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3377                 return USERSHARE_MALFORMED_ACL_DEF;
3378         }
3379
3380         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3381                 return USERSHARE_ACL_ERR;
3382         }
3383
3384         if (us_vers == 2) {
3385                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3386                         return USERSHARE_MALFORMED_ACL_DEF;
3387                 }
3388                 if (lines[4][9] == 'y') {
3389                         *pallow_guest = true;
3390                 }
3391
3392                 /* Backwards compatible extension to file version #2. */
3393                 if (numlines > 5) {
3394                         if (strncmp(lines[5], "sharename=", 10) != 0) {
3395                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
3396                         }
3397                         if (!strequal(&lines[5][10], servicename)) {
3398                                 return USERSHARE_BAD_SHARENAME;
3399                         }
3400                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3401                         if (!*pp_cp_servicename) {
3402                                 return USERSHARE_POSIX_ERR;
3403                         }
3404                 }
3405         }
3406
3407         if (*pp_cp_servicename == NULL) {
3408                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3409                 if (!*pp_cp_servicename) {
3410                         return USERSHARE_POSIX_ERR;
3411                 }
3412         }
3413
3414         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3415                 /* Path didn't change, no checks needed. */
3416                 *pp_sharepath = sharepath;
3417                 *pp_comment = comment;
3418                 return USERSHARE_OK;
3419         }
3420
3421         /* The path *must* be absolute. */
3422         if (sharepath[0] != '/') {
3423                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3424                         servicename, sharepath));
3425                 return USERSHARE_PATH_NOT_ABSOLUTE;
3426         }
3427
3428         /* If there is a usershare prefix deny list ensure one of these paths
3429            doesn't match the start of the user given path. */
3430         if (prefixdenylist) {
3431                 int i;
3432                 for ( i=0; prefixdenylist[i]; i++ ) {
3433                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3434                                 servicename, i, prefixdenylist[i], sharepath ));
3435                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3436                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3437                                         "usershare prefix deny list entries.\n",
3438                                         servicename, sharepath));
3439                                 return USERSHARE_PATH_IS_DENIED;
3440                         }
3441                 }
3442         }
3443
3444         /* If there is a usershare prefix allow list ensure one of these paths
3445            does match the start of the user given path. */
3446
3447         if (prefixallowlist) {
3448                 int i;
3449                 for ( i=0; prefixallowlist[i]; i++ ) {
3450                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3451                                 servicename, i, prefixallowlist[i], sharepath ));
3452                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3453                                 break;
3454                         }
3455                 }
3456                 if (prefixallowlist[i] == NULL) {
3457                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3458                                 "usershare prefix allow list entries.\n",
3459                                 servicename, sharepath));
3460                         return USERSHARE_PATH_NOT_ALLOWED;
3461                 }
3462         }
3463
3464         /* Ensure this is pointing to a directory. */
3465         dp = opendir(sharepath);
3466
3467         if (!dp) {
3468                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3469                         servicename, sharepath));
3470                 return USERSHARE_PATH_NOT_DIRECTORY;
3471         }
3472
3473         /* Ensure the owner of the usershare file has permission to share
3474            this directory. */
3475
3476         if (sys_stat(sharepath, &sbuf, false) == -1) {
3477                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3478                         servicename, sharepath, strerror(errno) ));
3479                 closedir(dp);
3480                 return USERSHARE_POSIX_ERR;
3481         }
3482
3483         closedir(dp);
3484
3485         if (!S_ISDIR(sbuf.st_ex_mode)) {
3486                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3487                         servicename, sharepath ));
3488                 return USERSHARE_PATH_NOT_DIRECTORY;
3489         }
3490
3491         /* Check if sharing is restricted to owner-only. */
3492         /* psbuf is the stat of the usershare definition file,
3493            sbuf is the stat of the target directory to be shared. */
3494
3495         if (lp_usershare_owner_only()) {
3496                 /* root can share anything. */
3497                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3498                         return USERSHARE_PATH_NOT_ALLOWED;
3499                 }
3500         }
3501
3502         *pp_sharepath = sharepath;
3503         *pp_comment = comment;
3504         return USERSHARE_OK;
3505 }
3506
3507 /***************************************************************************
3508  Deal with a usershare file.
3509  Returns:
3510         >= 0 - snum
3511         -1 - Bad name, invalid contents.
3512            - service name already existed and not a usershare, problem
3513             with permissions to share directory etc.
3514 ***************************************************************************/
3515
3516 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3517 {
3518         SMB_STRUCT_STAT sbuf;
3519         SMB_STRUCT_STAT lsbuf;
3520         char *fname = NULL;
3521         char *sharepath = NULL;
3522         char *comment = NULL;
3523         char *cp_service_name = NULL;
3524         char **lines = NULL;
3525         int numlines = 0;
3526         int fd = -1;
3527         int iService = -1;
3528         TALLOC_CTX *ctx = talloc_stackframe();
3529         struct security_descriptor *psd = NULL;
3530         bool guest_ok = false;
3531         char *canon_name = NULL;
3532         bool added_service = false;
3533         int ret = -1;
3534
3535         /* Ensure share name doesn't contain invalid characters. */
3536         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3537                 DEBUG(0,("process_usershare_file: share name %s contains "
3538                         "invalid characters (any of %s)\n",
3539                         file_name, INVALID_SHARENAME_CHARS ));
3540                 goto out;
3541         }
3542
3543         canon_name = canonicalize_servicename(ctx, file_name);
3544         if (!canon_name) {
3545                 goto out;
3546         }
3547
3548         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3549         if (!fname) {
3550                 goto out;
3551         }
3552
3553         /* Minimize the race condition by doing an lstat before we
3554            open and fstat. Ensure this isn't a symlink link. */
3555
3556         if (sys_lstat(fname, &lsbuf, false) != 0) {
3557                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3558                         fname, strerror(errno) ));
3559                 goto out;
3560         }
3561
3562         /* This must be a regular file, not a symlink, directory or
3563            other strange filetype. */
3564         if (!check_usershare_stat(fname, &lsbuf)) {
3565                 goto out;
3566         }
3567
3568         {
3569                 TDB_DATA data;
3570                 NTSTATUS status;
3571
3572                 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3573                                                canon_name, &data);
3574
3575                 iService = -1;
3576
3577                 if (NT_STATUS_IS_OK(status) &&
3578                     (data.dptr != NULL) &&
3579                     (data.dsize == sizeof(iService))) {
3580                         memcpy(&iService, data.dptr, sizeof(iService));
3581                 }
3582         }
3583
3584         if (iService != -1 &&
3585             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3586                              &lsbuf.st_ex_mtime) == 0) {
3587                 /* Nothing changed - Mark valid and return. */
3588                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3589                         canon_name ));
3590                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3591                 ret = iService;
3592                 goto out;
3593         }
3594
3595         /* Try and open the file read only - no symlinks allowed. */
3596 #ifdef O_NOFOLLOW
3597         fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3598 #else
3599         fd = open(fname, O_RDONLY, 0);
3600 #endif
3601
3602         if (fd == -1) {
3603                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3604                         fname, strerror(errno) ));
3605                 goto out;
3606         }
3607
3608         /* Now fstat to be *SURE* it's a regular file. */
3609         if (sys_fstat(fd, &sbuf, false) != 0) {
3610                 close(fd);
3611                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3612                         fname, strerror(errno) ));
3613                 goto out;
3614         }
3615
3616         /* Is it the same dev/inode as was lstated ? */
3617         if (!check_same_stat(&lsbuf, &sbuf)) {
3618                 close(fd);
3619                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3620                         "Symlink spoofing going on ?\n", fname ));
3621                 goto out;
3622         }
3623
3624         /* This must be a regular file, not a symlink, directory or
3625            other strange filetype. */
3626         if (!check_usershare_stat(fname, &sbuf)) {
3627                 close(fd);
3628                 goto out;
3629         }
3630
3631         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3632
3633         close(fd);
3634         if (lines == NULL) {
3635                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3636                         fname, (unsigned int)sbuf.st_ex_uid ));
3637                 goto out;
3638         }
3639
3640         if (parse_usershare_file(ctx, &sbuf, file_name,
3641                         iService, lines, numlines, &sharepath,
3642                         &comment, &cp_service_name,
3643                         &psd, &guest_ok) != USERSHARE_OK) {
3644                 goto out;
3645         }
3646
3647         /* Everything ok - add the service possibly using a template. */
3648         if (iService < 0) {
3649                 const struct loadparm_service *sp = &sDefault;
3650                 if (snum_template != -1) {
3651                         sp = ServicePtrs[snum_template];
3652                 }
3653
3654                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3655                         DEBUG(0, ("process_usershare_file: Failed to add "
3656                                 "new service %s\n", cp_service_name));
3657                         goto out;
3658                 }
3659
3660                 added_service = true;
3661
3662                 /* Read only is controlled by usershare ACL below. */
3663                 ServicePtrs[iService]->read_only = false;
3664         }
3665
3666         /* Write the ACL of the new/modified share. */
3667         if (!set_share_security(canon_name, psd)) {
3668                  DEBUG(0, ("process_usershare_file: Failed to set share "
3669                         "security for user share %s\n",
3670                         canon_name ));
3671                 goto out;
3672         }
3673
3674         /* If from a template it may be marked invalid. */
3675         ServicePtrs[iService]->valid = true;
3676
3677         /* Set the service as a valid usershare. */
3678         ServicePtrs[iService]->usershare = USERSHARE_VALID;
3679
3680         /* Set guest access. */
3681         if (lp_usershare_allow_guests()) {
3682                 ServicePtrs[iService]->guest_ok = guest_ok;
3683         }
3684
3685         /* And note when it was loaded. */
3686         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3687         string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath);
3688         string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment);
3689
3690         ret = iService;
3691
3692   out:
3693
3694         if (ret == -1 && iService != -1 && added_service) {
3695                 lp_remove_service(iService);
3696         }
3697
3698         TALLOC_FREE(lines);
3699         TALLOC_FREE(ctx);
3700         return ret;
3701 }
3702
3703 /***************************************************************************
3704  Checks if a usershare entry has been modified since last load.
3705 ***************************************************************************/
3706
3707 static bool usershare_exists(int iService, struct timespec *last_mod)
3708 {
3709         SMB_STRUCT_STAT lsbuf;
3710         const char *usersharepath = Globals.usershare_path;
3711         char *fname;
3712
3713         fname = talloc_asprintf(talloc_tos(),
3714                                 "%s/%s",
3715                                 usersharepath,
3716                                 ServicePtrs[iService]->szService);
3717         if (fname == NULL) {
3718                 return false;
3719         }
3720
3721         if (sys_lstat(fname, &lsbuf, false) != 0) {
3722                 TALLOC_FREE(fname);
3723                 return false;
3724         }
3725
3726         if (!S_ISREG(lsbuf.st_ex_mode)) {
3727                 TALLOC_FREE(fname);
3728                 return false;
3729         }
3730
3731         TALLOC_FREE(fname);
3732         *last_mod = lsbuf.st_ex_mtime;
3733         return true;
3734 }
3735
3736 /***************************************************************************
3737  Load a usershare service by name. Returns a valid servicenumber or -1.
3738 ***************************************************************************/
3739
3740 int load_usershare_service(const char *servicename)
3741 {
3742         SMB_STRUCT_STAT sbuf;
3743         const char *usersharepath = Globals.usershare_path;
3744         int max_user_shares = Globals.usershare_max_shares;
3745         int snum_template = -1;
3746
3747         if (*usersharepath == 0 ||  max_user_shares == 0) {
3748                 return -1;
3749         }
3750
3751         if (sys_stat(usersharepath, &sbuf, false) != 0) {
3752                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3753                         usersharepath, strerror(errno) ));
3754                 return -1;
3755         }
3756
3757         if (!S_ISDIR(sbuf.st_ex_mode)) {
3758                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3759                         usersharepath ));
3760                 return -1;
3761         }
3762
3763         /*
3764          * This directory must be owned by root, and have the 't' bit set.
3765          * It also must not be writable by "other".
3766          */
3767
3768 #ifdef S_ISVTX
3769         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3770 #else
3771         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3772 #endif
3773                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3774                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
3775                         usersharepath ));
3776                 return -1;
3777         }
3778
3779         /* Ensure the template share exists if it's set. */
3780         if (Globals.usershare_template_share[0]) {
3781                 /* We can't use lp_servicenumber here as we are recommending that
3782                    template shares have -valid=false set. */
3783                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3784                         if (ServicePtrs[snum_template]->szService &&
3785                                         strequal(ServicePtrs[snum_template]->szService,
3786                                                 Globals.usershare_template_share)) {
3787                                 break;
3788                         }
3789                 }
3790
3791                 if (snum_template == -1) {
3792                         DEBUG(0,("load_usershare_service: usershare template share %s "
3793                                 "does not exist.\n",
3794                                 Globals.usershare_template_share ));
3795                         return -1;
3796                 }
3797         }
3798
3799         return process_usershare_file(usersharepath, servicename, snum_template);
3800 }
3801
3802 /***************************************************************************
3803  Load all user defined shares from the user share directory.
3804  We only do this if we're enumerating the share list.
3805  This is the function that can delete usershares that have
3806  been removed.
3807 ***************************************************************************/
3808
3809 int load_usershare_shares(struct smbd_server_connection *sconn,
3810                           bool (*snumused) (struct smbd_server_connection *, int))
3811 {
3812         DIR *dp;
3813         SMB_STRUCT_STAT sbuf;
3814         struct dirent *de;
3815         int num_usershares = 0;
3816         int max_user_shares = Globals.usershare_max_shares;
3817         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3818         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3819         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3820         int iService;
3821         int snum_template = -1;
3822         const char *usersharepath = Globals.usershare_path;
3823         int ret = lp_numservices();
3824         TALLOC_CTX *tmp_ctx;
3825
3826         if (max_user_shares == 0 || *usersharepath == '\0') {
3827                 return lp_numservices();
3828         }
3829
3830         if (sys_stat(usersharepath, &sbuf, false) != 0) {
3831                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3832                         usersharepath, strerror(errno) ));
3833                 return ret;
3834         }
3835
3836         /*
3837          * This directory must be owned by root, and have the 't' bit set.
3838          * It also must not be writable by "other".
3839          */
3840
3841 #ifdef S_ISVTX
3842         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3843 #else
3844         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3845 #endif
3846                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3847                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
3848                         usersharepath ));
3849                 return ret;
3850         }
3851
3852         /* Ensure the template share exists if it's set. */
3853         if (Globals.usershare_template_share[0]) {
3854                 /* We can't use lp_servicenumber here as we are recommending that
3855                    template shares have -valid=false set. */
3856                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3857                         if (ServicePtrs[snum_template]->szService &&
3858                                         strequal(ServicePtrs[snum_template]->szService,
3859                                                 Globals.usershare_template_share)) {
3860                                 break;
3861                         }
3862                 }
3863
3864                 if (snum_template == -1) {
3865                         DEBUG(0,("load_usershare_shares: usershare template share %s "
3866                                 "does not exist.\n",
3867                                 Globals.usershare_template_share ));
3868                         return ret;
3869                 }
3870         }
3871
3872         /* Mark all existing usershares as pending delete. */
3873         for (iService = iNumServices - 1; iService >= 0; iService--) {
3874                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3875                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3876                 }
3877         }
3878
3879         dp = opendir(usersharepath);
3880         if (!dp) {
3881                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3882                         usersharepath, strerror(errno) ));
3883                 return ret;
3884         }
3885
3886         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3887                         (de = readdir(dp));
3888                         num_dir_entries++ ) {
3889                 int r;
3890                 const char *n = de->d_name;
3891
3892                 /* Ignore . and .. */
3893                 if (*n == '.') {
3894                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3895                                 continue;
3896                         }
3897                 }
3898
3899                 if (n[0] == ':') {
3900                         /* Temporary file used when creating a share. */
3901                         num_tmp_dir_entries++;
3902                 }
3903
3904                 /* Allow 20% tmp entries. */
3905                 if (num_tmp_dir_entries > allowed_tmp_entries) {
3906                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3907                                 "in directory %s\n",
3908                                 num_tmp_dir_entries, usersharepath));
3909                         break;
3910                 }
3911
3912                 r = process_usershare_file(usersharepath, n, snum_template);
3913                 if (r == 0) {
3914                         /* Update the services count. */
3915                         num_usershares++;
3916                         if (num_usershares >= max_user_shares) {
3917                                 DEBUG(0,("load_usershare_shares: max user shares reached "
3918                                         "on file %s in directory %s\n",
3919                                         n, usersharepath ));
3920                                 break;
3921                         }
3922                 } else if (r == -1) {
3923                         num_bad_dir_entries++;
3924                 }
3925
3926                 /* Allow 20% bad entries. */
3927                 if (num_bad_dir_entries > allowed_bad_entries) {
3928                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3929                                 "in directory %s\n",
3930                                 num_bad_dir_entries, usersharepath));
3931                         break;
3932                 }
3933
3934                 /* Allow 20% bad entries. */
3935                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3936                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3937                         "in directory %s\n",
3938                         num_dir_entries, usersharepath));
3939                         break;
3940                 }
3941         }
3942
3943         closedir(dp);
3944
3945         /* Sweep through and delete any non-refreshed usershares that are
3946            not currently in use. */
3947         tmp_ctx = talloc_stackframe();
3948         for (iService = iNumServices - 1; iService >= 0; iService--) {
3949                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3950                         char *servname;
3951
3952                         if (snumused && snumused(sconn, iService)) {
3953                                 continue;
3954                         }
3955
3956                         servname = lp_servicename(tmp_ctx, iService);
3957
3958                         /* Remove from the share ACL db. */
3959                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3960                                   servname ));
3961                         delete_share_security(servname);
3962                         free_service_byindex(iService);
3963                 }
3964         }
3965         talloc_free(tmp_ctx);
3966
3967         return lp_numservices();
3968 }
3969
3970 /********************************************************
3971  Destroy global resources allocated in this file
3972 ********************************************************/
3973
3974 void gfree_loadparm(void)
3975 {
3976         int i;
3977
3978         free_file_list();
3979
3980         /* Free resources allocated to services */
3981
3982         for ( i = 0; i < iNumServices; i++ ) {
3983                 if ( VALID(i) ) {
3984                         free_service_byindex(i);
3985                 }
3986         }
3987
3988         TALLOC_FREE( ServicePtrs );
3989         iNumServices = 0;
3990
3991         /* Now release all resources allocated to global
3992            parameters and the default service */
3993
3994         free_global_parameters();
3995 }
3996
3997
3998 /***************************************************************************
3999  Allow client apps to specify that they are a client
4000 ***************************************************************************/
4001 static void lp_set_in_client(bool b)
4002 {
4003     in_client = b;
4004 }
4005
4006
4007 /***************************************************************************
4008  Determine if we're running in a client app
4009 ***************************************************************************/
4010 static bool lp_is_in_client(void)
4011 {
4012     return in_client;
4013 }
4014
4015 /***************************************************************************
4016  Load the services array from the services file. Return true on success,
4017  false on failure.
4018 ***************************************************************************/
4019
4020 static bool lp_load_ex(const char *pszFname,
4021                        bool global_only,
4022                        bool save_defaults,
4023                        bool add_ipc,
4024                        bool initialize_globals,
4025                        bool allow_include_registry,
4026                        bool load_all_shares)
4027 {
4028         char *n2 = NULL;
4029         bool bRetval;
4030
4031         bRetval = false;
4032
4033         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4034
4035         bInGlobalSection = true;
4036         bGlobalOnly = global_only;
4037         bAllowIncludeRegistry = allow_include_registry;
4038
4039         init_globals(initialize_globals);
4040
4041         free_file_list();
4042
4043         if (save_defaults) {
4044                 init_locals();
4045                 lp_save_defaults();
4046         }
4047
4048         if (!initialize_globals) {
4049                 free_param_opts(&Globals.param_opt);
4050                 apply_lp_set_cmdline();
4051         }
4052
4053         lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
4054
4055         /* We get sections first, so have to start 'behind' to make up */
4056         iServiceIndex = -1;
4057
4058         if (lp_config_backend_is_file()) {
4059                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4060                                         current_user_info.domain,
4061                                         pszFname);
4062                 if (!n2) {
4063                         smb_panic("lp_load_ex: out of memory");
4064                 }
4065
4066                 add_to_file_list(NULL, &file_lists, pszFname, n2);
4067
4068                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
4069                 TALLOC_FREE(n2);
4070
4071                 /* finish up the last section */
4072                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4073                 if (bRetval) {
4074                         if (iServiceIndex >= 0) {
4075                                 bRetval = service_ok(iServiceIndex);
4076                         }
4077                 }
4078
4079                 if (lp_config_backend_is_registry()) {
4080                         /* config backend changed to registry in config file */
4081                         /*
4082                          * We need to use this extra global variable here to
4083                          * survive restart: init_globals uses this as a default
4084                          * for config_backend. Otherwise, init_globals would
4085                          *  send us into an endless loop here.
4086                          */
4087                         config_backend = CONFIG_BACKEND_REGISTRY;
4088                         /* start over */
4089                         DEBUG(1, ("lp_load_ex: changing to config backend "
4090                                   "registry\n"));
4091                         init_globals(true);
4092                         lp_kill_all_services();
4093                         return lp_load_ex(pszFname, global_only, save_defaults,
4094                                           add_ipc, initialize_globals,
4095                                           allow_include_registry,
4096                                           load_all_shares);
4097                 }
4098         } else if (lp_config_backend_is_registry()) {
4099                 bRetval = process_registry_globals();
4100         } else {
4101                 DEBUG(0, ("Illegal config  backend given: %d\n",
4102                           lp_config_backend()));
4103                 bRetval = false;
4104         }
4105
4106         if (bRetval && lp_registry_shares()) {
4107                 if (load_all_shares) {
4108                         bRetval = process_registry_shares();
4109                 } else {
4110                         bRetval = reload_registry_shares();
4111                 }
4112         }
4113
4114         {
4115                 char *serv = lp_auto_services(talloc_tos());
4116                 lp_add_auto_services(serv);
4117                 TALLOC_FREE(serv);
4118         }
4119
4120         if (add_ipc) {
4121                 /* When 'restrict anonymous = 2' guest connections to ipc$
4122                    are denied */
4123                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4124                 if ( lp_enable_asu_support() ) {
4125                         lp_add_ipc("ADMIN$", false);
4126                 }
4127         }
4128
4129         set_allowed_client_auth();
4130
4131         if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4132                 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4133                           lp_password_server()));
4134         }
4135
4136         bLoaded = true;
4137
4138         /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4139         /* if we_are_a_wins_server is true and we are in the client            */
4140         if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4141                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4142         }
4143
4144         init_iconv();
4145
4146         fault_configure(smb_panic_s3);
4147
4148         /*
4149          * We run this check once the whole smb.conf is parsed, to
4150          * force some settings for the standard way a AD DC is
4151          * operated.  We may changed these as our code evolves, which
4152          * is why we force these settings.
4153          */
4154         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4155                 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4156
4157                 lp_do_parameter(-1, "rpc_server:default", "external");
4158                 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4159                 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4160                 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4161                 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4162                 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4163                 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4164                 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4165                 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4166         }
4167
4168         bAllowIncludeRegistry = true;
4169
4170         return (bRetval);
4171 }
4172
4173 bool lp_load(const char *pszFname,
4174              bool global_only,
4175              bool save_defaults,
4176              bool add_ipc,
4177              bool initialize_globals)
4178 {
4179         return lp_load_ex(pszFname,
4180                           global_only,
4181                           save_defaults,
4182                           add_ipc,
4183                           initialize_globals,
4184                           true,   /* allow_include_registry */
4185                           false); /* load_all_shares*/
4186 }
4187
4188 bool lp_load_initial_only(const char *pszFname)
4189 {
4190         return lp_load_ex(pszFname,
4191                           true,   /* global only */
4192                           false,  /* save_defaults */
4193                           false,  /* add_ipc */
4194                           true,   /* initialize_globals */
4195                           false,  /* allow_include_registry */
4196                           false); /* load_all_shares*/
4197 }
4198
4199 /**
4200  * most common lp_load wrapper, loading only the globals
4201  */
4202 bool lp_load_global(const char *file_name)
4203 {
4204         return lp_load_ex(file_name,
4205                           true,   /* global_only */
4206                           false,  /* save_defaults */
4207                           false,  /* add_ipc */
4208                           true,   /* initialize_globals */
4209                           true,   /* allow_include_registry */
4210                           false); /* load_all_shares*/
4211 }
4212
4213 /**
4214  * lp_load wrapper, especially for clients
4215  */
4216 bool lp_load_client(const char *file_name)
4217 {
4218         lp_set_in_client(true);
4219
4220         return lp_load_global(file_name);
4221 }
4222
4223 /**
4224  * lp_load wrapper, loading only globals, but intended
4225  * for subsequent calls, not reinitializing the globals
4226  * to default values
4227  */
4228 bool lp_load_global_no_reinit(const char *file_name)
4229 {
4230         return lp_load_ex(file_name,
4231                           true,   /* global_only */
4232                           false,  /* save_defaults */
4233                           false,  /* add_ipc */
4234                           false,  /* initialize_globals */
4235                           true,   /* allow_include_registry */
4236                           false); /* load_all_shares*/
4237 }
4238
4239 /**
4240  * lp_load wrapper, especially for clients, no reinitialization
4241  */
4242 bool lp_load_client_no_reinit(const char *file_name)
4243 {
4244         lp_set_in_client(true);
4245
4246         return lp_load_global_no_reinit(file_name);
4247 }
4248
4249 bool lp_load_with_registry_shares(const char *pszFname,
4250                                   bool global_only,
4251                                   bool save_defaults,
4252                                   bool add_ipc,
4253                                   bool initialize_globals)
4254 {
4255         return lp_load_ex(pszFname,
4256                           global_only,
4257                           save_defaults,
4258                           add_ipc,
4259                           initialize_globals,
4260                           true,  /* allow_include_registry */
4261                           true); /* load_all_shares*/
4262 }
4263
4264 /***************************************************************************
4265  Return the max number of services.
4266 ***************************************************************************/
4267
4268 int lp_numservices(void)
4269 {
4270         return (iNumServices);
4271 }
4272
4273 /***************************************************************************
4274 Display the contents of the services array in human-readable form.
4275 ***************************************************************************/
4276
4277 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4278 {
4279         int iService;
4280
4281         if (show_defaults)
4282                 defaults_saved = false;
4283
4284         dump_globals(f);
4285
4286         dump_a_service(&sDefault, f, show_defaults);
4287
4288         for (iService = 0; iService < maxtoprint; iService++) {
4289                 fprintf(f,"\n");
4290                 lp_dump_one(f, show_defaults, iService);
4291         }
4292 }
4293
4294 /***************************************************************************
4295 Display the contents of one service in human-readable form.
4296 ***************************************************************************/
4297
4298 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4299 {
4300         if (VALID(snum)) {
4301                 if (ServicePtrs[snum]->szService[0] == '\0')
4302                         return;
4303                 dump_a_service(ServicePtrs[snum], f, show_defaults);
4304         }
4305 }
4306
4307 /***************************************************************************
4308 Return the number of the service with the given name, or -1 if it doesn't
4309 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4310 getservicebyname()! This works ONLY if all services have been loaded, and
4311 does not copy the found service.
4312 ***************************************************************************/
4313
4314 int lp_servicenumber(const char *pszServiceName)
4315 {
4316         int iService;
4317         fstring serviceName;
4318
4319         if (!pszServiceName) {
4320                 return GLOBAL_SECTION_SNUM;
4321         }
4322
4323         for (iService = iNumServices - 1; iService >= 0; iService--) {
4324                 if (VALID(iService) && ServicePtrs[iService]->szService) {
4325                         /*
4326                          * The substitution here is used to support %U is
4327                          * service names
4328                          */
4329                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
4330                         standard_sub_basic(get_current_username(),
4331                                            current_user_info.domain,
4332                                            serviceName,sizeof(serviceName));
4333                         if (strequal(serviceName, pszServiceName)) {
4334                                 break;
4335                         }
4336                 }
4337         }
4338
4339         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4340                 struct timespec last_mod;
4341
4342                 if (!usershare_exists(iService, &last_mod)) {
4343                         /* Remove the share security tdb entry for it. */
4344                         delete_share_security(lp_servicename(talloc_tos(), iService));
4345                         /* Remove it from the array. */
4346                         free_service_byindex(iService);
4347                         /* Doesn't exist anymore. */
4348                         return GLOBAL_SECTION_SNUM;
4349                 }
4350
4351                 /* Has it been modified ? If so delete and reload. */
4352                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4353                                      &last_mod) < 0) {
4354                         /* Remove it from the array. */
4355                         free_service_byindex(iService);
4356                         /* and now reload it. */
4357                         iService = load_usershare_service(pszServiceName);
4358                 }
4359         }
4360
4361         if (iService < 0) {
4362                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4363                 return GLOBAL_SECTION_SNUM;
4364         }
4365
4366         return (iService);
4367 }
4368
4369 /*******************************************************************
4370  A useful volume label function. 
4371 ********************************************************************/
4372
4373 const char *volume_label(TALLOC_CTX *ctx, int snum)
4374 {
4375         char *ret;
4376         const char *label = lp_volume(ctx, snum);
4377         if (!*label) {
4378                 label = lp_servicename(ctx, snum);
4379         }
4380
4381         /* This returns a 33 byte guarenteed null terminated string. */
4382         ret = talloc_strndup(ctx, label, 32);
4383         if (!ret) {
4384                 return "";
4385         }               
4386         return ret;
4387 }
4388
4389 /*******************************************************************
4390  Get the default server type we will announce as via nmbd.
4391 ********************************************************************/
4392
4393 int lp_default_server_announce(void)
4394 {
4395         int default_server_announce = 0;
4396         default_server_announce |= SV_TYPE_WORKSTATION;
4397         default_server_announce |= SV_TYPE_SERVER;
4398         default_server_announce |= SV_TYPE_SERVER_UNIX;
4399
4400         /* note that the flag should be set only if we have a 
4401            printer service but nmbd doesn't actually load the 
4402            services so we can't tell   --jerry */
4403
4404         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4405
4406         default_server_announce |= SV_TYPE_SERVER_NT;
4407         default_server_announce |= SV_TYPE_NT;
4408
4409         switch (lp_server_role()) {
4410                 case ROLE_DOMAIN_MEMBER:
4411                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4412                         break;
4413                 case ROLE_DOMAIN_PDC:
4414                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4415                         break;
4416                 case ROLE_DOMAIN_BDC:
4417                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4418                         break;
4419                 case ROLE_STANDALONE:
4420                 default:
4421                         break;
4422         }
4423         if (lp_time_server())
4424                 default_server_announce |= SV_TYPE_TIME_SOURCE;
4425
4426         if (lp_host_msdfs())
4427                 default_server_announce |= SV_TYPE_DFS_SERVER;
4428
4429         return default_server_announce;
4430 }
4431
4432 /***********************************************************
4433  If we are PDC then prefer us as DMB
4434 ************************************************************/
4435
4436 bool lp_domain_master(void)
4437 {
4438         if (Globals._domain_master == Auto)
4439                 return (lp_server_role() == ROLE_DOMAIN_PDC);
4440
4441         return (bool)Globals._domain_master;
4442 }
4443
4444 /***********************************************************
4445  If we are PDC then prefer us as DMB
4446 ************************************************************/
4447
4448 static bool lp_domain_master_true_or_auto(void)
4449 {
4450         if (Globals._domain_master) /* auto or yes */
4451                 return true;
4452
4453         return false;
4454 }
4455
4456 /***********************************************************
4457  If we are DMB then prefer us as LMB
4458 ************************************************************/
4459
4460 bool lp_preferred_master(void)
4461 {
4462         if (Globals.iPreferredMaster == Auto)
4463                 return (lp_local_master() && lp_domain_master());
4464
4465         return (bool)Globals.iPreferredMaster;
4466 }
4467
4468 /*******************************************************************
4469  Remove a service.
4470 ********************************************************************/
4471
4472 void lp_remove_service(int snum)
4473 {
4474         ServicePtrs[snum]->valid = false;
4475 }
4476
4477 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4478 {
4479         const char *ret = lp__printername(ctx, snum);
4480         if (ret == NULL || *ret == '\0') {
4481                 ret = lp_const_servicename(snum);
4482         }
4483
4484         return ret;
4485 }
4486
4487
4488 /***********************************************************
4489  Allow daemons such as winbindd to fix their logfile name.
4490 ************************************************************/
4491
4492 void lp_set_logfile(const char *name)
4493 {
4494         string_set(Globals.ctx, &Globals.logfile, name);
4495         debug_set_logfile(name);
4496 }
4497
4498 /*******************************************************************
4499  Return the max print jobs per queue.
4500 ********************************************************************/
4501
4502 int lp_maxprintjobs(int snum)
4503 {
4504         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4505         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4506                 maxjobs = PRINT_MAX_JOBID - 1;
4507
4508         return maxjobs;
4509 }
4510
4511 const char *lp_printcapname(void)
4512 {
4513         if ((Globals.szPrintcapname != NULL) &&
4514             (Globals.szPrintcapname[0] != '\0'))
4515                 return Globals.szPrintcapname;
4516
4517         if (sDefault.printing == PRINT_CUPS) {
4518                 return "cups";
4519         }
4520
4521         if (sDefault.printing == PRINT_BSD)
4522                 return "/etc/printcap";
4523
4524         return PRINTCAP_NAME;
4525 }
4526
4527 static uint32 spoolss_state;
4528
4529 bool lp_disable_spoolss( void )
4530 {
4531         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4532                 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4533
4534         return spoolss_state == SVCCTL_STOPPED ? true : false;
4535 }
4536
4537 void lp_set_spoolss_state( uint32 state )
4538 {
4539         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4540
4541         spoolss_state = state;
4542 }
4543
4544 uint32 lp_get_spoolss_state( void )
4545 {
4546         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4547 }
4548
4549 /*******************************************************************
4550  Ensure we don't use sendfile if server smb signing is active.
4551 ********************************************************************/
4552
4553 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4554 {
4555         bool sign_active = false;
4556
4557         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4558         if (get_Protocol() < PROTOCOL_NT1) {
4559                 return false;
4560         }
4561         if (signing_state) {
4562                 sign_active = smb_signing_is_active(signing_state);
4563         }
4564         return (lp__use_sendfile(snum) &&
4565                         (get_remote_arch() != RA_WIN95) &&
4566                         !sign_active);
4567 }
4568
4569 /*******************************************************************
4570  Turn off sendfile if we find the underlying OS doesn't support it.
4571 ********************************************************************/
4572
4573 void set_use_sendfile(int snum, bool val)
4574 {
4575         if (LP_SNUM_OK(snum))
4576                 ServicePtrs[snum]->_use_sendfile = val;
4577         else
4578                 sDefault._use_sendfile = val;
4579 }
4580
4581 /*******************************************************************
4582  Turn off storing DOS attributes if this share doesn't support it.
4583 ********************************************************************/
4584
4585 void set_store_dos_attributes(int snum, bool val)
4586 {
4587         if (!LP_SNUM_OK(snum))
4588                 return;
4589         ServicePtrs[(snum)]->store_dos_attributes = val;
4590 }
4591
4592 void lp_set_mangling_method(const char *new_method)
4593 {
4594         string_set(Globals.ctx, &Globals.mangling_method, new_method);
4595 }
4596
4597 /*******************************************************************
4598  Global state for POSIX pathname processing.
4599 ********************************************************************/
4600
4601 static bool posix_pathnames;
4602
4603 bool lp_posix_pathnames(void)
4604 {
4605         return posix_pathnames;
4606 }
4607
4608 /*******************************************************************
4609  Change everything needed to ensure POSIX pathname processing (currently
4610  not much).
4611 ********************************************************************/
4612
4613 void lp_set_posix_pathnames(void)
4614 {
4615         posix_pathnames = true;
4616 }
4617
4618 /*******************************************************************
4619  Global state for POSIX lock processing - CIFS unix extensions.
4620 ********************************************************************/
4621
4622 bool posix_default_lock_was_set;
4623 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4624
4625 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4626 {
4627         if (posix_default_lock_was_set) {
4628                 return posix_cifsx_locktype;
4629         } else {
4630                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
4631         }
4632 }
4633
4634 /*******************************************************************
4635 ********************************************************************/
4636
4637 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4638 {
4639         posix_default_lock_was_set = true;
4640         posix_cifsx_locktype = val;
4641 }
4642
4643 int lp_min_receive_file_size(void)
4644 {
4645         if (Globals.iminreceivefile < 0) {
4646                 return 0;
4647         }
4648         return Globals.iminreceivefile;
4649 }
4650
4651 /*******************************************************************
4652  Safe wide links checks.
4653  This helper function always verify the validity of wide links,
4654  even after a configuration file reload.
4655 ********************************************************************/
4656
4657 static bool lp_widelinks_internal(int snum)
4658 {
4659         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
4660                         sDefault.bWidelinks);
4661 }
4662
4663 void widelinks_warning(int snum)
4664 {
4665         if (lp_allow_insecure_wide_links()) {
4666                 return;
4667         }
4668
4669         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
4670                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4671                         "These parameters are incompatible. "
4672                         "Wide links will be disabled for this share.\n",
4673                          lp_servicename(talloc_tos(), snum) ));
4674         }
4675 }
4676
4677 bool lp_widelinks(int snum)
4678 {
4679         /* wide links is always incompatible with unix extensions */
4680         if (lp_unix_extensions()) {
4681                 /*
4682                  * Unless we have "allow insecure widelinks"
4683                  * turned on.
4684                  */
4685                 if (!lp_allow_insecure_wide_links()) {
4686                         return false;
4687                 }
4688         }
4689
4690         return lp_widelinks_internal(snum);
4691 }
4692
4693 int lp_server_role(void)
4694 {
4695         return lp_find_server_role(lp__server_role(),
4696                                    lp__security(),
4697                                    lp__domain_logons(),
4698                                    lp_domain_master_true_or_auto());
4699 }
4700
4701 int lp_security(void)
4702 {
4703         return lp_find_security(lp__server_role(),
4704                                 lp__security());
4705 }
4706
4707 struct loadparm_global * get_globals(void)
4708 {
4709         return &Globals;
4710 }