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