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