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