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