s3-param: Make dump_a_parameter use lp_paramater() rather than an open-coded loop
[bbaumbach/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         struct parm_struct *p_struct;
3688         fstring local_parm_name;
3689         char *parm_opt;
3690         const char *parm_opt_value;
3691         void *ptr;
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         p_struct = lp_get_parameter(parm_name);
3712
3713         if (p_struct == NULL) {
3714                 return false;
3715         }
3716
3717         if (isGlobal) {
3718                 ptr = lp_parm_ptr(NULL,
3719                                   p_struct);
3720         } else {
3721                 ptr = lp_parm_ptr(ServicePtrs[snum],
3722                                   p_struct);
3723         }
3724
3725         lpcfg_print_parameter(p_struct,
3726                               ptr, f);
3727         fprintf(f, "\n");
3728         return true;
3729 }
3730
3731 /***************************************************************************
3732  Return info about the requested parameter (given as a string).
3733  Return NULL when the string is not a valid parameter name.
3734 ***************************************************************************/
3735
3736 struct parm_struct *lp_get_parameter(const char *param_name)
3737 {
3738         int num = map_parameter(param_name);
3739
3740         if (num < 0) {
3741                 return NULL;
3742         }
3743
3744         return &parm_table[num];
3745 }
3746
3747 /***************************************************************************
3748  Return info about the next parameter in a service.
3749  snum==GLOBAL_SECTION_SNUM gives the globals.
3750  Return NULL when out of parameters.
3751 ***************************************************************************/
3752
3753 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3754 {
3755         if (snum < 0) {
3756                 /* do the globals */
3757                 for (; parm_table[*i].label; (*i)++) {
3758                         if (parm_table[*i].p_class == P_SEPARATOR)
3759                                 return &parm_table[(*i)++];
3760
3761                         if ((*parm_table[*i].label == '-'))
3762                                 continue;
3763
3764                         if ((*i) > 0
3765                             && (parm_table[*i].offset ==
3766                                 parm_table[(*i) - 1].offset)
3767                             && (parm_table[*i].p_class ==
3768                                 parm_table[(*i) - 1].p_class))
3769                                 continue;
3770
3771                         if (is_default(*i) && !allparameters)
3772                                 continue;
3773
3774                         return &parm_table[(*i)++];
3775                 }
3776         } else {
3777                 struct loadparm_service *pService = ServicePtrs[snum];
3778
3779                 for (; parm_table[*i].label; (*i)++) {
3780                         if (parm_table[*i].p_class == P_SEPARATOR)
3781                                 return &parm_table[(*i)++];
3782
3783                         if (parm_table[*i].p_class == P_LOCAL &&
3784                             (*parm_table[*i].label != '-') &&
3785                             ((*i) == 0 ||
3786                              (parm_table[*i].offset !=
3787                               parm_table[(*i) - 1].offset)))
3788                         {
3789                                 if (allparameters ||
3790                                     !equal_parameter(parm_table[*i].type,
3791                                                      lp_parm_ptr(pService, 
3792                                                                  &parm_table[*i]),
3793                                                      lp_parm_ptr(NULL, 
3794                                                                  &parm_table[*i])))
3795                                 {
3796                                         return &parm_table[(*i)++];
3797                                 }
3798                         }
3799                 }
3800         }
3801
3802         return NULL;
3803 }
3804
3805
3806 #if 0
3807 /***************************************************************************
3808  Display the contents of a single copy structure.
3809 ***************************************************************************/
3810 static void dump_copy_map(bool *pcopymap)
3811 {
3812         int i;
3813         if (!pcopymap)
3814                 return;
3815
3816         printf("\n\tNon-Copied parameters:\n");
3817
3818         for (i = 0; parm_table[i].label; i++)
3819                 if (parm_table[i].p_class == P_LOCAL &&
3820                     parm_table[i].ptr && !pcopymap[i] &&
3821                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3822                 {
3823                         printf("\t\t%s\n", parm_table[i].label);
3824                 }
3825 }
3826 #endif
3827
3828 /***************************************************************************
3829  Return TRUE if the passed service number is within range.
3830 ***************************************************************************/
3831
3832 bool lp_snum_ok(int iService)
3833 {
3834         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3835 }
3836
3837 /***************************************************************************
3838  Auto-load some home services.
3839 ***************************************************************************/
3840
3841 static void lp_add_auto_services(char *str)
3842 {
3843         char *s;
3844         char *p;
3845         int homes;
3846         char *saveptr;
3847
3848         if (!str)
3849                 return;
3850
3851         s = SMB_STRDUP(str);
3852         if (!s)
3853                 return;
3854
3855         homes = lp_servicenumber(HOMES_NAME);
3856
3857         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3858              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3859                 char *home;
3860
3861                 if (lp_servicenumber(p) >= 0)
3862                         continue;
3863
3864                 home = get_user_home_dir(talloc_tos(), p);
3865
3866                 if (home && home[0] && homes >= 0)
3867                         lp_add_home(p, homes, p, home);
3868
3869                 TALLOC_FREE(home);
3870         }
3871         SAFE_FREE(s);
3872 }
3873
3874 /***************************************************************************
3875  Auto-load one printer.
3876 ***************************************************************************/
3877
3878 void lp_add_one_printer(const char *name, const char *comment,
3879                         const char *location, void *pdata)
3880 {
3881         int printers = lp_servicenumber(PRINTERS_NAME);
3882         int i;
3883
3884         if (lp_servicenumber(name) < 0) {
3885                 lp_add_printer(name, printers);
3886                 if ((i = lp_servicenumber(name)) >= 0) {
3887                         string_set(&ServicePtrs[i]->comment, comment);
3888                         ServicePtrs[i]->autoloaded = true;
3889                 }
3890         }
3891 }
3892
3893 /***************************************************************************
3894  Have we loaded a services file yet?
3895 ***************************************************************************/
3896
3897 bool lp_loaded(void)
3898 {
3899         return (bLoaded);
3900 }
3901
3902 /***************************************************************************
3903  Unload unused services.
3904 ***************************************************************************/
3905
3906 void lp_killunused(struct smbd_server_connection *sconn,
3907                    bool (*snumused) (struct smbd_server_connection *, int))
3908 {
3909         int i;
3910         for (i = 0; i < iNumServices; i++) {
3911                 if (!VALID(i))
3912                         continue;
3913
3914                 /* don't kill autoloaded or usershare services */
3915                 if ( ServicePtrs[i]->autoloaded ||
3916                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3917                         continue;
3918                 }
3919
3920                 if (!snumused || !snumused(sconn, i)) {
3921                         free_service_byindex(i);
3922                 }
3923         }
3924 }
3925
3926 /**
3927  * Kill all except autoloaded and usershare services - convenience wrapper
3928  */
3929 void lp_kill_all_services(void)
3930 {
3931         lp_killunused(NULL, NULL);
3932 }
3933
3934 /***************************************************************************
3935  Unload a service.
3936 ***************************************************************************/
3937
3938 void lp_killservice(int iServiceIn)
3939 {
3940         if (VALID(iServiceIn)) {
3941                 free_service_byindex(iServiceIn);
3942         }
3943 }
3944
3945 /***************************************************************************
3946  Save the curent values of all global and sDefault parameters into the 
3947  defaults union. This allows testparm to show only the
3948  changed (ie. non-default) parameters.
3949 ***************************************************************************/
3950
3951 static void lp_save_defaults(void)
3952 {
3953         int i;
3954         for (i = 0; parm_table[i].label; i++) {
3955                 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3956                     && parm_table[i].p_class == parm_table[i - 1].p_class)
3957                         continue;
3958                 switch (parm_table[i].type) {
3959                         case P_LIST:
3960                         case P_CMDLIST:
3961                                 parm_table[i].def.lvalue = str_list_copy(
3962                                         NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3963                                 break;
3964                         case P_STRING:
3965                         case P_USTRING:
3966                                 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
3967                                 break;
3968                         case P_BOOL:
3969                         case P_BOOLREV:
3970                                 parm_table[i].def.bvalue =
3971                                         *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3972                                 break;
3973                         case P_CHAR:
3974                                 parm_table[i].def.cvalue =
3975                                         *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3976                                 break;
3977                         case P_INTEGER:
3978                         case P_OCTAL:
3979                         case P_ENUM:
3980                         case P_BYTES:
3981                                 parm_table[i].def.ivalue =
3982                                         *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3983                                 break;
3984                         case P_SEP:
3985                                 break;
3986                 }
3987         }
3988         defaults_saved = true;
3989 }
3990
3991 /***********************************************************
3992  If we should send plaintext/LANMAN passwords in the clinet
3993 ************************************************************/
3994
3995 static void set_allowed_client_auth(void)
3996 {
3997         if (Globals.client_ntlmv2_auth) {
3998                 Globals.client_lanman_auth = false;
3999         }
4000         if (!Globals.client_lanman_auth) {
4001                 Globals.client_plaintext_auth = false;
4002         }
4003 }
4004
4005 /***************************************************************************
4006  JRA.
4007  The following code allows smbd to read a user defined share file.
4008  Yes, this is my intent. Yes, I'm comfortable with that...
4009
4010  THE FOLLOWING IS SECURITY CRITICAL CODE.
4011
4012  It washes your clothes, it cleans your house, it guards you while you sleep...
4013  Do not f%^k with it....
4014 ***************************************************************************/
4015
4016 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4017
4018 /***************************************************************************
4019  Check allowed stat state of a usershare file.
4020  Ensure we print out who is dicking with us so the admin can
4021  get their sorry ass fired.
4022 ***************************************************************************/
4023
4024 static bool check_usershare_stat(const char *fname,
4025                                  const SMB_STRUCT_STAT *psbuf)
4026 {
4027         if (!S_ISREG(psbuf->st_ex_mode)) {
4028                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4029                         "not a regular file\n",
4030                         fname, (unsigned int)psbuf->st_ex_uid ));
4031                 return false;
4032         }
4033
4034         /* Ensure this doesn't have the other write bit set. */
4035         if (psbuf->st_ex_mode & S_IWOTH) {
4036                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4037                         "public write. Refusing to allow as a usershare file.\n",
4038                         fname, (unsigned int)psbuf->st_ex_uid ));
4039                 return false;
4040         }
4041
4042         /* Should be 10k or less. */
4043         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
4044                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4045                         "too large (%u) to be a user share file.\n",
4046                         fname, (unsigned int)psbuf->st_ex_uid,
4047                         (unsigned int)psbuf->st_ex_size ));
4048                 return false;
4049         }
4050
4051         return true;
4052 }
4053
4054 /***************************************************************************
4055  Parse the contents of a usershare file.
4056 ***************************************************************************/
4057
4058 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4059                         SMB_STRUCT_STAT *psbuf,
4060                         const char *servicename,
4061                         int snum,
4062                         char **lines,
4063                         int numlines,
4064                         char **pp_sharepath,
4065                         char **pp_comment,
4066                         char **pp_cp_servicename,
4067                         struct security_descriptor **ppsd,
4068                         bool *pallow_guest)
4069 {
4070         const char **prefixallowlist = lp_usershare_prefix_allow_list();
4071         const char **prefixdenylist = lp_usershare_prefix_deny_list();
4072         int us_vers;
4073         DIR *dp;
4074         SMB_STRUCT_STAT sbuf;
4075         char *sharepath = NULL;
4076         char *comment = NULL;
4077
4078         *pp_sharepath = NULL;
4079         *pp_comment = NULL;
4080
4081         *pallow_guest = false;
4082
4083         if (numlines < 4) {
4084                 return USERSHARE_MALFORMED_FILE;
4085         }
4086
4087         if (strcmp(lines[0], "#VERSION 1") == 0) {
4088                 us_vers = 1;
4089         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4090                 us_vers = 2;
4091                 if (numlines < 5) {
4092                         return USERSHARE_MALFORMED_FILE;
4093                 }
4094         } else {
4095                 return USERSHARE_BAD_VERSION;
4096         }
4097
4098         if (strncmp(lines[1], "path=", 5) != 0) {
4099                 return USERSHARE_MALFORMED_PATH;
4100         }
4101
4102         sharepath = talloc_strdup(ctx, &lines[1][5]);
4103         if (!sharepath) {
4104                 return USERSHARE_POSIX_ERR;
4105         }
4106         trim_string(sharepath, " ", " ");
4107
4108         if (strncmp(lines[2], "comment=", 8) != 0) {
4109                 return USERSHARE_MALFORMED_COMMENT_DEF;
4110         }
4111
4112         comment = talloc_strdup(ctx, &lines[2][8]);
4113         if (!comment) {
4114                 return USERSHARE_POSIX_ERR;
4115         }
4116         trim_string(comment, " ", " ");
4117         trim_char(comment, '"', '"');
4118
4119         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4120                 return USERSHARE_MALFORMED_ACL_DEF;
4121         }
4122
4123         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4124                 return USERSHARE_ACL_ERR;
4125         }
4126
4127         if (us_vers == 2) {
4128                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4129                         return USERSHARE_MALFORMED_ACL_DEF;
4130                 }
4131                 if (lines[4][9] == 'y') {
4132                         *pallow_guest = true;
4133                 }
4134
4135                 /* Backwards compatible extension to file version #2. */
4136                 if (numlines > 5) {
4137                         if (strncmp(lines[5], "sharename=", 10) != 0) {
4138                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
4139                         }
4140                         if (!strequal(&lines[5][10], servicename)) {
4141                                 return USERSHARE_BAD_SHARENAME;
4142                         }
4143                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
4144                         if (!*pp_cp_servicename) {
4145                                 return USERSHARE_POSIX_ERR;
4146                         }
4147                 }
4148         }
4149
4150         if (*pp_cp_servicename == NULL) {
4151                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
4152                 if (!*pp_cp_servicename) {
4153                         return USERSHARE_POSIX_ERR;
4154                 }
4155         }
4156
4157         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->pathname) == 0)) {
4158                 /* Path didn't change, no checks needed. */
4159                 *pp_sharepath = sharepath;
4160                 *pp_comment = comment;
4161                 return USERSHARE_OK;
4162         }
4163
4164         /* The path *must* be absolute. */
4165         if (sharepath[0] != '/') {
4166                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4167                         servicename, sharepath));
4168                 return USERSHARE_PATH_NOT_ABSOLUTE;
4169         }
4170
4171         /* If there is a usershare prefix deny list ensure one of these paths
4172            doesn't match the start of the user given path. */
4173         if (prefixdenylist) {
4174                 int i;
4175                 for ( i=0; prefixdenylist[i]; i++ ) {
4176                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4177                                 servicename, i, prefixdenylist[i], sharepath ));
4178                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4179                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4180                                         "usershare prefix deny list entries.\n",
4181                                         servicename, sharepath));
4182                                 return USERSHARE_PATH_IS_DENIED;
4183                         }
4184                 }
4185         }
4186
4187         /* If there is a usershare prefix allow list ensure one of these paths
4188            does match the start of the user given path. */
4189
4190         if (prefixallowlist) {
4191                 int i;
4192                 for ( i=0; prefixallowlist[i]; i++ ) {
4193                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4194                                 servicename, i, prefixallowlist[i], sharepath ));
4195                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4196                                 break;
4197                         }
4198                 }
4199                 if (prefixallowlist[i] == NULL) {
4200                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4201                                 "usershare prefix allow list entries.\n",
4202                                 servicename, sharepath));
4203                         return USERSHARE_PATH_NOT_ALLOWED;
4204                 }
4205         }
4206
4207         /* Ensure this is pointing to a directory. */
4208         dp = opendir(sharepath);
4209
4210         if (!dp) {
4211                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4212                         servicename, sharepath));
4213                 return USERSHARE_PATH_NOT_DIRECTORY;
4214         }
4215
4216         /* Ensure the owner of the usershare file has permission to share
4217            this directory. */
4218
4219         if (sys_stat(sharepath, &sbuf, false) == -1) {
4220                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4221                         servicename, sharepath, strerror(errno) ));
4222                 closedir(dp);
4223                 return USERSHARE_POSIX_ERR;
4224         }
4225
4226         closedir(dp);
4227
4228         if (!S_ISDIR(sbuf.st_ex_mode)) {
4229                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4230                         servicename, sharepath ));
4231                 return USERSHARE_PATH_NOT_DIRECTORY;
4232         }
4233
4234         /* Check if sharing is restricted to owner-only. */
4235         /* psbuf is the stat of the usershare definition file,
4236            sbuf is the stat of the target directory to be shared. */
4237
4238         if (lp_usershare_owner_only()) {
4239                 /* root can share anything. */
4240                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
4241                         return USERSHARE_PATH_NOT_ALLOWED;
4242                 }
4243         }
4244
4245         *pp_sharepath = sharepath;
4246         *pp_comment = comment;
4247         return USERSHARE_OK;
4248 }
4249
4250 /***************************************************************************
4251  Deal with a usershare file.
4252  Returns:
4253         >= 0 - snum
4254         -1 - Bad name, invalid contents.
4255            - service name already existed and not a usershare, problem
4256             with permissions to share directory etc.
4257 ***************************************************************************/
4258
4259 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4260 {
4261         SMB_STRUCT_STAT sbuf;
4262         SMB_STRUCT_STAT lsbuf;
4263         char *fname = NULL;
4264         char *sharepath = NULL;
4265         char *comment = NULL;
4266         char *cp_service_name = NULL;
4267         char **lines = NULL;
4268         int numlines = 0;
4269         int fd = -1;
4270         int iService = -1;
4271         TALLOC_CTX *ctx = talloc_stackframe();
4272         struct security_descriptor *psd = NULL;
4273         bool guest_ok = false;
4274         char *canon_name = NULL;
4275         bool added_service = false;
4276         int ret = -1;
4277
4278         /* Ensure share name doesn't contain invalid characters. */
4279         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4280                 DEBUG(0,("process_usershare_file: share name %s contains "
4281                         "invalid characters (any of %s)\n",
4282                         file_name, INVALID_SHARENAME_CHARS ));
4283                 goto out;
4284         }
4285
4286         canon_name = canonicalize_servicename(ctx, file_name);
4287         if (!canon_name) {
4288                 goto out;
4289         }
4290
4291         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
4292         if (!fname) {
4293                 goto out;
4294         }
4295
4296         /* Minimize the race condition by doing an lstat before we
4297            open and fstat. Ensure this isn't a symlink link. */
4298
4299         if (sys_lstat(fname, &lsbuf, false) != 0) {
4300                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4301                         fname, strerror(errno) ));
4302                 goto out;
4303         }
4304
4305         /* This must be a regular file, not a symlink, directory or
4306            other strange filetype. */
4307         if (!check_usershare_stat(fname, &lsbuf)) {
4308                 goto out;
4309         }
4310
4311         {
4312                 TDB_DATA data;
4313                 NTSTATUS status;
4314
4315                 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
4316                                                canon_name, &data);
4317
4318                 iService = -1;
4319
4320                 if (NT_STATUS_IS_OK(status) &&
4321                     (data.dptr != NULL) &&
4322                     (data.dsize == sizeof(iService))) {
4323                         memcpy(&iService, data.dptr, sizeof(iService));
4324                 }
4325         }
4326
4327         if (iService != -1 &&
4328             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4329                              &lsbuf.st_ex_mtime) == 0) {
4330                 /* Nothing changed - Mark valid and return. */
4331                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4332                         canon_name ));
4333                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4334                 ret = iService;
4335                 goto out;
4336         }
4337
4338         /* Try and open the file read only - no symlinks allowed. */
4339 #ifdef O_NOFOLLOW
4340         fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
4341 #else
4342         fd = open(fname, O_RDONLY, 0);
4343 #endif
4344
4345         if (fd == -1) {
4346                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4347                         fname, strerror(errno) ));
4348                 goto out;
4349         }
4350
4351         /* Now fstat to be *SURE* it's a regular file. */
4352         if (sys_fstat(fd, &sbuf, false) != 0) {
4353                 close(fd);
4354                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4355                         fname, strerror(errno) ));
4356                 goto out;
4357         }
4358
4359         /* Is it the same dev/inode as was lstated ? */
4360         if (!check_same_stat(&lsbuf, &sbuf)) {
4361                 close(fd);
4362                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4363                         "Symlink spoofing going on ?\n", fname ));
4364                 goto out;
4365         }
4366
4367         /* This must be a regular file, not a symlink, directory or
4368            other strange filetype. */
4369         if (!check_usershare_stat(fname, &sbuf)) {
4370                 close(fd);
4371                 goto out;
4372         }
4373
4374         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
4375
4376         close(fd);
4377         if (lines == NULL) {
4378                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4379                         fname, (unsigned int)sbuf.st_ex_uid ));
4380                 goto out;
4381         }
4382
4383         if (parse_usershare_file(ctx, &sbuf, file_name,
4384                         iService, lines, numlines, &sharepath,
4385                         &comment, &cp_service_name,
4386                         &psd, &guest_ok) != USERSHARE_OK) {
4387                 goto out;
4388         }
4389
4390         /* Everything ok - add the service possibly using a template. */
4391         if (iService < 0) {
4392                 const struct loadparm_service *sp = &sDefault;
4393                 if (snum_template != -1) {
4394                         sp = ServicePtrs[snum_template];
4395                 }
4396
4397                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
4398                         DEBUG(0, ("process_usershare_file: Failed to add "
4399                                 "new service %s\n", cp_service_name));
4400                         goto out;
4401                 }
4402
4403                 added_service = true;
4404
4405                 /* Read only is controlled by usershare ACL below. */
4406                 ServicePtrs[iService]->readonly = false;
4407         }
4408
4409         /* Write the ACL of the new/modified share. */
4410         if (!set_share_security(canon_name, psd)) {
4411                  DEBUG(0, ("process_usershare_file: Failed to set share "
4412                         "security for user share %s\n",
4413                         canon_name ));
4414                 goto out;
4415         }
4416
4417         /* If from a template it may be marked invalid. */
4418         ServicePtrs[iService]->valid = true;
4419
4420         /* Set the service as a valid usershare. */
4421         ServicePtrs[iService]->usershare = USERSHARE_VALID;
4422
4423         /* Set guest access. */
4424         if (lp_usershare_allow_guests()) {
4425                 ServicePtrs[iService]->guest_ok = guest_ok;
4426         }
4427
4428         /* And note when it was loaded. */
4429         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
4430         string_set(&ServicePtrs[iService]->pathname, sharepath);
4431         string_set(&ServicePtrs[iService]->comment, comment);
4432
4433         ret = iService;
4434
4435   out:
4436
4437         if (ret == -1 && iService != -1 && added_service) {
4438                 lp_remove_service(iService);
4439         }
4440
4441         TALLOC_FREE(lines);
4442         TALLOC_FREE(ctx);
4443         return ret;
4444 }
4445
4446 /***************************************************************************
4447  Checks if a usershare entry has been modified since last load.
4448 ***************************************************************************/
4449
4450 static bool usershare_exists(int iService, struct timespec *last_mod)
4451 {
4452         SMB_STRUCT_STAT lsbuf;
4453         const char *usersharepath = Globals.usershare_path;
4454         char *fname;
4455
4456         if (asprintf(&fname, "%s/%s",
4457                                 usersharepath,
4458                                 ServicePtrs[iService]->szService) < 0) {
4459                 return false;
4460         }
4461
4462         if (sys_lstat(fname, &lsbuf, false) != 0) {
4463                 SAFE_FREE(fname);
4464                 return false;
4465         }
4466
4467         if (!S_ISREG(lsbuf.st_ex_mode)) {
4468                 SAFE_FREE(fname);
4469                 return false;
4470         }
4471
4472         SAFE_FREE(fname);
4473         *last_mod = lsbuf.st_ex_mtime;
4474         return true;
4475 }
4476
4477 /***************************************************************************
4478  Load a usershare service by name. Returns a valid servicenumber or -1.
4479 ***************************************************************************/
4480
4481 int load_usershare_service(const char *servicename)
4482 {
4483         SMB_STRUCT_STAT sbuf;
4484         const char *usersharepath = Globals.usershare_path;
4485         int max_user_shares = Globals.usershare_max_shares;
4486         int snum_template = -1;
4487
4488         if (*usersharepath == 0 ||  max_user_shares == 0) {
4489                 return -1;
4490         }
4491
4492         if (sys_stat(usersharepath, &sbuf, false) != 0) {
4493                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4494                         usersharepath, strerror(errno) ));
4495                 return -1;
4496         }
4497
4498         if (!S_ISDIR(sbuf.st_ex_mode)) {
4499                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4500                         usersharepath ));
4501                 return -1;
4502         }
4503
4504         /*
4505          * This directory must be owned by root, and have the 't' bit set.
4506          * It also must not be writable by "other".
4507          */
4508
4509 #ifdef S_ISVTX
4510         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4511 #else
4512         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4513 #endif
4514                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4515                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
4516                         usersharepath ));
4517                 return -1;
4518         }
4519
4520         /* Ensure the template share exists if it's set. */
4521         if (Globals.szUsershareTemplateShare[0]) {
4522                 /* We can't use lp_servicenumber here as we are recommending that
4523                    template shares have -valid=false set. */
4524                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4525                         if (ServicePtrs[snum_template]->szService &&
4526                                         strequal(ServicePtrs[snum_template]->szService,
4527                                                 Globals.szUsershareTemplateShare)) {
4528                                 break;
4529                         }
4530                 }
4531
4532                 if (snum_template == -1) {
4533                         DEBUG(0,("load_usershare_service: usershare template share %s "
4534                                 "does not exist.\n",
4535                                 Globals.szUsershareTemplateShare ));
4536                         return -1;
4537                 }
4538         }
4539
4540         return process_usershare_file(usersharepath, servicename, snum_template);
4541 }
4542
4543 /***************************************************************************
4544  Load all user defined shares from the user share directory.
4545  We only do this if we're enumerating the share list.
4546  This is the function that can delete usershares that have
4547  been removed.
4548 ***************************************************************************/
4549
4550 int load_usershare_shares(struct smbd_server_connection *sconn,
4551                           bool (*snumused) (struct smbd_server_connection *, int))
4552 {
4553         DIR *dp;
4554         SMB_STRUCT_STAT sbuf;
4555         struct dirent *de;
4556         int num_usershares = 0;
4557         int max_user_shares = Globals.usershare_max_shares;
4558         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4559         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4560         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4561         int iService;
4562         int snum_template = -1;
4563         const char *usersharepath = Globals.usershare_path;
4564         int ret = lp_numservices();
4565         TALLOC_CTX *tmp_ctx;
4566
4567         if (max_user_shares == 0 || *usersharepath == '\0') {
4568                 return lp_numservices();
4569         }
4570
4571         if (sys_stat(usersharepath, &sbuf, false) != 0) {
4572                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4573                         usersharepath, strerror(errno) ));
4574                 return ret;
4575         }
4576
4577         /*
4578          * This directory must be owned by root, and have the 't' bit set.
4579          * It also must not be writable by "other".
4580          */
4581
4582 #ifdef S_ISVTX
4583         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4584 #else
4585         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4586 #endif
4587                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4588                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
4589                         usersharepath ));
4590                 return ret;
4591         }
4592
4593         /* Ensure the template share exists if it's set. */
4594         if (Globals.szUsershareTemplateShare[0]) {
4595                 /* We can't use lp_servicenumber here as we are recommending that
4596                    template shares have -valid=false set. */
4597                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4598                         if (ServicePtrs[snum_template]->szService &&
4599                                         strequal(ServicePtrs[snum_template]->szService,
4600                                                 Globals.szUsershareTemplateShare)) {
4601                                 break;
4602                         }
4603                 }
4604
4605                 if (snum_template == -1) {
4606                         DEBUG(0,("load_usershare_shares: usershare template share %s "
4607                                 "does not exist.\n",
4608                                 Globals.szUsershareTemplateShare ));
4609                         return ret;
4610                 }
4611         }
4612
4613         /* Mark all existing usershares as pending delete. */
4614         for (iService = iNumServices - 1; iService >= 0; iService--) {
4615                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4616                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4617                 }
4618         }
4619
4620         dp = opendir(usersharepath);
4621         if (!dp) {
4622                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4623                         usersharepath, strerror(errno) ));
4624                 return ret;
4625         }
4626
4627         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4628                         (de = readdir(dp));
4629                         num_dir_entries++ ) {
4630                 int r;
4631                 const char *n = de->d_name;
4632
4633                 /* Ignore . and .. */
4634                 if (*n == '.') {
4635                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4636                                 continue;
4637                         }
4638                 }
4639
4640                 if (n[0] == ':') {
4641                         /* Temporary file used when creating a share. */
4642                         num_tmp_dir_entries++;
4643                 }
4644
4645                 /* Allow 20% tmp entries. */
4646                 if (num_tmp_dir_entries > allowed_tmp_entries) {
4647                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4648                                 "in directory %s\n",
4649                                 num_tmp_dir_entries, usersharepath));
4650                         break;
4651                 }
4652
4653                 r = process_usershare_file(usersharepath, n, snum_template);
4654                 if (r == 0) {
4655                         /* Update the services count. */
4656                         num_usershares++;
4657                         if (num_usershares >= max_user_shares) {
4658                                 DEBUG(0,("load_usershare_shares: max user shares reached "
4659                                         "on file %s in directory %s\n",
4660                                         n, usersharepath ));
4661                                 break;
4662                         }
4663                 } else if (r == -1) {
4664                         num_bad_dir_entries++;
4665                 }
4666
4667                 /* Allow 20% bad entries. */
4668                 if (num_bad_dir_entries > allowed_bad_entries) {
4669                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4670                                 "in directory %s\n",
4671                                 num_bad_dir_entries, usersharepath));
4672                         break;
4673                 }
4674
4675                 /* Allow 20% bad entries. */
4676                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4677                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4678                         "in directory %s\n",
4679                         num_dir_entries, usersharepath));
4680                         break;
4681                 }
4682         }
4683
4684         closedir(dp);
4685
4686         /* Sweep through and delete any non-refreshed usershares that are
4687            not currently in use. */
4688         tmp_ctx = talloc_stackframe();
4689         for (iService = iNumServices - 1; iService >= 0; iService--) {
4690                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4691                         char *servname;
4692
4693                         if (snumused && snumused(sconn, iService)) {
4694                                 continue;
4695                         }
4696
4697                         servname = lp_servicename(tmp_ctx, iService);
4698
4699                         /* Remove from the share ACL db. */
4700                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4701                                   servname ));
4702                         delete_share_security(servname);
4703                         free_service_byindex(iService);
4704                 }
4705         }
4706         talloc_free(tmp_ctx);
4707
4708         return lp_numservices();
4709 }
4710
4711 /********************************************************
4712  Destroy global resources allocated in this file
4713 ********************************************************/
4714
4715 void gfree_loadparm(void)
4716 {
4717         int i;
4718
4719         free_file_list();
4720
4721         /* Free resources allocated to services */
4722
4723         for ( i = 0; i < iNumServices; i++ ) {
4724                 if ( VALID(i) ) {
4725                         free_service_byindex(i);
4726                 }
4727         }
4728
4729         SAFE_FREE( ServicePtrs );
4730         iNumServices = 0;
4731
4732         /* Now release all resources allocated to global
4733            parameters and the default service */
4734
4735         free_global_parameters();
4736 }
4737
4738
4739 /***************************************************************************
4740  Allow client apps to specify that they are a client
4741 ***************************************************************************/
4742 static void lp_set_in_client(bool b)
4743 {
4744     in_client = b;
4745 }
4746
4747
4748 /***************************************************************************
4749  Determine if we're running in a client app
4750 ***************************************************************************/
4751 static bool lp_is_in_client(void)
4752 {
4753     return in_client;
4754 }
4755
4756 /***************************************************************************
4757  Load the services array from the services file. Return true on success,
4758  false on failure.
4759 ***************************************************************************/
4760
4761 static bool lp_load_ex(const char *pszFname,
4762                        bool global_only,
4763                        bool save_defaults,
4764                        bool add_ipc,
4765                        bool initialize_globals,
4766                        bool allow_include_registry,
4767                        bool load_all_shares)
4768 {
4769         char *n2 = NULL;
4770         bool bRetval;
4771
4772         bRetval = false;
4773
4774         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4775
4776         bInGlobalSection = true;
4777         bGlobalOnly = global_only;
4778         bAllowIncludeRegistry = allow_include_registry;
4779
4780         init_globals(initialize_globals);
4781
4782         free_file_list();
4783
4784         if (save_defaults) {
4785                 init_locals();
4786                 lp_save_defaults();
4787         }
4788
4789         if (!initialize_globals) {
4790                 free_param_opts(&Globals.param_opt);
4791                 apply_lp_set_cmdline();
4792         }
4793
4794         lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
4795
4796         /* We get sections first, so have to start 'behind' to make up */
4797         iServiceIndex = -1;
4798
4799         if (lp_config_backend_is_file()) {
4800                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4801                                         current_user_info.domain,
4802                                         pszFname);
4803                 if (!n2) {
4804                         smb_panic("lp_load_ex: out of memory");
4805                 }
4806
4807                 add_to_file_list(pszFname, n2);
4808
4809                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
4810                 TALLOC_FREE(n2);
4811
4812                 /* finish up the last section */
4813                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4814                 if (bRetval) {
4815                         if (iServiceIndex >= 0) {
4816                                 bRetval = service_ok(iServiceIndex);
4817                         }
4818                 }
4819
4820                 if (lp_config_backend_is_registry()) {
4821                         /* config backend changed to registry in config file */
4822                         /*
4823                          * We need to use this extra global variable here to
4824                          * survive restart: init_globals uses this as a default
4825                          * for config_backend. Otherwise, init_globals would
4826                          *  send us into an endless loop here.
4827                          */
4828                         config_backend = CONFIG_BACKEND_REGISTRY;
4829                         /* start over */
4830                         DEBUG(1, ("lp_load_ex: changing to config backend "
4831                                   "registry\n"));
4832                         init_globals(true);
4833                         lp_kill_all_services();
4834                         return lp_load_ex(pszFname, global_only, save_defaults,
4835                                           add_ipc, initialize_globals,
4836                                           allow_include_registry,
4837                                           load_all_shares);
4838                 }
4839         } else if (lp_config_backend_is_registry()) {
4840                 bRetval = process_registry_globals();
4841         } else {
4842                 DEBUG(0, ("Illegal config  backend given: %d\n",
4843                           lp_config_backend()));
4844                 bRetval = false;
4845         }
4846
4847         if (bRetval && lp_registry_shares()) {
4848                 if (load_all_shares) {
4849                         bRetval = process_registry_shares();
4850                 } else {
4851                         bRetval = reload_registry_shares();
4852                 }
4853         }
4854
4855         {
4856                 char *serv = lp_auto_services(talloc_tos());
4857                 lp_add_auto_services(serv);
4858                 TALLOC_FREE(serv);
4859         }
4860
4861         if (add_ipc) {
4862                 /* When 'restrict anonymous = 2' guest connections to ipc$
4863                    are denied */
4864                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4865                 if ( lp_enable_asu_support() ) {
4866                         lp_add_ipc("ADMIN$", false);
4867                 }
4868         }
4869
4870         set_allowed_client_auth();
4871
4872         if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
4873                 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4874                           lp_passwordserver()));
4875         }
4876
4877         bLoaded = true;
4878
4879         /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4880         /* if we_are_a_wins_server is true and we are in the client            */
4881         if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4882                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4883         }
4884
4885         init_iconv();
4886
4887         fault_configure(smb_panic_s3);
4888
4889         /*
4890          * We run this check once the whole smb.conf is parsed, to
4891          * force some settings for the standard way a AD DC is
4892          * operated.  We may changed these as our code evolves, which
4893          * is why we force these settings.
4894          */
4895         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4896                 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4897
4898                 lp_do_parameter(-1, "rpc_server:default", "external");
4899                 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4900                 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4901                 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4902                 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4903                 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4904                 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4905                 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4906                 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4907         }
4908
4909         bAllowIncludeRegistry = true;
4910
4911         return (bRetval);
4912 }
4913
4914 bool lp_load(const char *pszFname,
4915              bool global_only,
4916              bool save_defaults,
4917              bool add_ipc,
4918              bool initialize_globals)
4919 {
4920         return lp_load_ex(pszFname,
4921                           global_only,
4922                           save_defaults,
4923                           add_ipc,
4924                           initialize_globals,
4925                           true,   /* allow_include_registry */
4926                           false); /* load_all_shares*/
4927 }
4928
4929 bool lp_load_initial_only(const char *pszFname)
4930 {
4931         return lp_load_ex(pszFname,
4932                           true,   /* global only */
4933                           false,  /* save_defaults */
4934                           false,  /* add_ipc */
4935                           true,   /* initialize_globals */
4936                           false,  /* allow_include_registry */
4937                           false); /* load_all_shares*/
4938 }
4939
4940 /**
4941  * most common lp_load wrapper, loading only the globals
4942  */
4943 bool lp_load_global(const char *file_name)
4944 {
4945         return lp_load_ex(file_name,
4946                           true,   /* global_only */
4947                           false,  /* save_defaults */
4948                           false,  /* add_ipc */
4949                           true,   /* initialize_globals */
4950                           true,   /* allow_include_registry */
4951                           false); /* load_all_shares*/
4952 }
4953
4954 /**
4955  * lp_load wrapper, especially for clients
4956  */
4957 bool lp_load_client(const char *file_name)
4958 {
4959         lp_set_in_client(true);
4960
4961         return lp_load_global(file_name);
4962 }
4963
4964 /**
4965  * lp_load wrapper, loading only globals, but intended
4966  * for subsequent calls, not reinitializing the globals
4967  * to default values
4968  */
4969 bool lp_load_global_no_reinit(const char *file_name)
4970 {
4971         return lp_load_ex(file_name,
4972                           true,   /* global_only */
4973                           false,  /* save_defaults */
4974                           false,  /* add_ipc */
4975                           false,  /* initialize_globals */
4976                           true,   /* allow_include_registry */
4977                           false); /* load_all_shares*/
4978 }
4979
4980 /**
4981  * lp_load wrapper, especially for clients, no reinitialization
4982  */
4983 bool lp_load_client_no_reinit(const char *file_name)
4984 {
4985         lp_set_in_client(true);
4986
4987         return lp_load_global_no_reinit(file_name);
4988 }
4989
4990 bool lp_load_with_registry_shares(const char *pszFname,
4991                                   bool global_only,
4992                                   bool save_defaults,
4993                                   bool add_ipc,
4994                                   bool initialize_globals)
4995 {
4996         return lp_load_ex(pszFname,
4997                           global_only,
4998                           save_defaults,
4999                           add_ipc,
5000                           initialize_globals,
5001                           true,  /* allow_include_registry */
5002                           true); /* load_all_shares*/
5003 }
5004
5005 /***************************************************************************
5006  Return the max number of services.
5007 ***************************************************************************/
5008
5009 int lp_numservices(void)
5010 {
5011         return (iNumServices);
5012 }
5013
5014 /***************************************************************************
5015 Display the contents of the services array in human-readable form.
5016 ***************************************************************************/
5017
5018 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
5019 {
5020         int iService;
5021
5022         if (show_defaults)
5023                 defaults_saved = false;
5024
5025         dump_globals(f);
5026
5027         dump_a_service(&sDefault, f);
5028
5029         for (iService = 0; iService < maxtoprint; iService++) {
5030                 fprintf(f,"\n");
5031                 lp_dump_one(f, show_defaults, iService);
5032         }
5033 }
5034
5035 /***************************************************************************
5036 Display the contents of one service in human-readable form.
5037 ***************************************************************************/
5038
5039 void lp_dump_one(FILE * f, bool show_defaults, int snum)
5040 {
5041         if (VALID(snum)) {
5042                 if (ServicePtrs[snum]->szService[0] == '\0')
5043                         return;
5044                 dump_a_service(ServicePtrs[snum], f);
5045         }
5046 }
5047
5048 /***************************************************************************
5049 Return the number of the service with the given name, or -1 if it doesn't
5050 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5051 getservicebyname()! This works ONLY if all services have been loaded, and
5052 does not copy the found service.
5053 ***************************************************************************/
5054
5055 int lp_servicenumber(const char *pszServiceName)
5056 {
5057         int iService;
5058         fstring serviceName;
5059
5060         if (!pszServiceName) {
5061                 return GLOBAL_SECTION_SNUM;
5062         }
5063
5064         for (iService = iNumServices - 1; iService >= 0; iService--) {
5065                 if (VALID(iService) && ServicePtrs[iService]->szService) {
5066                         /*
5067                          * The substitution here is used to support %U is
5068                          * service names
5069                          */
5070                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
5071                         standard_sub_basic(get_current_username(),
5072                                            current_user_info.domain,
5073                                            serviceName,sizeof(serviceName));
5074                         if (strequal(serviceName, pszServiceName)) {
5075                                 break;
5076                         }
5077                 }
5078         }
5079
5080         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5081                 struct timespec last_mod;
5082
5083                 if (!usershare_exists(iService, &last_mod)) {
5084                         /* Remove the share security tdb entry for it. */
5085                         delete_share_security(lp_servicename(talloc_tos(), iService));
5086                         /* Remove it from the array. */
5087                         free_service_byindex(iService);
5088                         /* Doesn't exist anymore. */
5089                         return GLOBAL_SECTION_SNUM;
5090                 }
5091
5092                 /* Has it been modified ? If so delete and reload. */
5093                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
5094                                      &last_mod) < 0) {
5095                         /* Remove it from the array. */
5096                         free_service_byindex(iService);
5097                         /* and now reload it. */
5098                         iService = load_usershare_service(pszServiceName);
5099                 }
5100         }
5101
5102         if (iService < 0) {
5103                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5104                 return GLOBAL_SECTION_SNUM;
5105         }
5106
5107         return (iService);
5108 }
5109
5110 /*******************************************************************
5111  A useful volume label function. 
5112 ********************************************************************/
5113
5114 const char *volume_label(TALLOC_CTX *ctx, int snum)
5115 {
5116         char *ret;
5117         const char *label = lp_volume(ctx, snum);
5118         if (!*label) {
5119                 label = lp_servicename(ctx, snum);
5120         }
5121
5122         /* This returns a 33 byte guarenteed null terminated string. */
5123         ret = talloc_strndup(ctx, label, 32);
5124         if (!ret) {
5125                 return "";
5126         }               
5127         return ret;
5128 }
5129
5130 /*******************************************************************
5131  Get the default server type we will announce as via nmbd.
5132 ********************************************************************/
5133
5134 int lp_default_server_announce(void)
5135 {
5136         int default_server_announce = 0;
5137         default_server_announce |= SV_TYPE_WORKSTATION;
5138         default_server_announce |= SV_TYPE_SERVER;
5139         default_server_announce |= SV_TYPE_SERVER_UNIX;
5140
5141         /* note that the flag should be set only if we have a 
5142            printer service but nmbd doesn't actually load the 
5143            services so we can't tell   --jerry */
5144
5145         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5146
5147         default_server_announce |= SV_TYPE_SERVER_NT;
5148         default_server_announce |= SV_TYPE_NT;
5149
5150         switch (lp_server_role()) {
5151                 case ROLE_DOMAIN_MEMBER:
5152                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5153                         break;
5154                 case ROLE_DOMAIN_PDC:
5155                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5156                         break;
5157                 case ROLE_DOMAIN_BDC:
5158                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5159                         break;
5160                 case ROLE_STANDALONE:
5161                 default:
5162                         break;
5163         }
5164         if (lp_time_server())
5165                 default_server_announce |= SV_TYPE_TIME_SOURCE;
5166
5167         if (lp_host_msdfs())
5168                 default_server_announce |= SV_TYPE_DFS_SERVER;
5169
5170         return default_server_announce;
5171 }
5172
5173 /***********************************************************
5174  If we are PDC then prefer us as DMB
5175 ************************************************************/
5176
5177 bool lp_domain_master(void)
5178 {
5179         if (Globals._domain_master == Auto)
5180                 return (lp_server_role() == ROLE_DOMAIN_PDC);
5181
5182         return (bool)Globals._domain_master;
5183 }
5184
5185 /***********************************************************
5186  If we are PDC then prefer us as DMB
5187 ************************************************************/
5188
5189 static bool lp_domain_master_true_or_auto(void)
5190 {
5191         if (Globals._domain_master) /* auto or yes */
5192                 return true;
5193
5194         return false;
5195 }
5196
5197 /***********************************************************
5198  If we are DMB then prefer us as LMB
5199 ************************************************************/
5200
5201 bool lp_preferred_master(void)
5202 {
5203         if (Globals.iPreferredMaster == Auto)
5204                 return (lp_local_master() && lp_domain_master());
5205
5206         return (bool)Globals.iPreferredMaster;
5207 }
5208
5209 /*******************************************************************
5210  Remove a service.
5211 ********************************************************************/
5212
5213 void lp_remove_service(int snum)
5214 {
5215         ServicePtrs[snum]->valid = false;
5216 }
5217
5218 /*******************************************************************
5219  Copy a service.
5220 ********************************************************************/
5221
5222 void lp_copy_service(int snum, const char *new_name)
5223 {
5224         do_section(new_name, NULL);
5225         if (snum >= 0) {
5226                 snum = lp_servicenumber(new_name);
5227                 if (snum >= 0) {
5228                         char *name = lp_servicename(talloc_tos(), snum);
5229                         lp_do_parameter(snum, "copy", name);
5230                 }
5231         }
5232 }
5233
5234 const char *lp_printername(TALLOC_CTX *ctx, int snum)
5235 {
5236         const char *ret = lp__printername(ctx, snum);
5237         if (ret == NULL || *ret == '\0') {
5238                 ret = lp_const_servicename(snum);
5239         }
5240
5241         return ret;
5242 }
5243
5244
5245 /***********************************************************
5246  Allow daemons such as winbindd to fix their logfile name.
5247 ************************************************************/
5248
5249 void lp_set_logfile(const char *name)
5250 {
5251         string_set(&Globals.logfile, name);
5252         debug_set_logfile(name);
5253 }
5254
5255 /*******************************************************************
5256  Return the max print jobs per queue.
5257 ********************************************************************/
5258
5259 int lp_maxprintjobs(int snum)
5260 {
5261         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5262         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5263                 maxjobs = PRINT_MAX_JOBID - 1;
5264
5265         return maxjobs;
5266 }
5267
5268 const char *lp_printcapname(void)
5269 {
5270         if ((Globals.szPrintcapname != NULL) &&
5271             (Globals.szPrintcapname[0] != '\0'))
5272                 return Globals.szPrintcapname;
5273
5274         if (sDefault.printing == PRINT_CUPS) {
5275                 return "cups";
5276         }
5277
5278         if (sDefault.printing == PRINT_BSD)
5279                 return "/etc/printcap";
5280
5281         return PRINTCAP_NAME;
5282 }
5283
5284 static uint32 spoolss_state;
5285
5286 bool lp_disable_spoolss( void )
5287 {
5288         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5289                 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5290
5291         return spoolss_state == SVCCTL_STOPPED ? true : false;
5292 }
5293
5294 void lp_set_spoolss_state( uint32 state )
5295 {
5296         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5297
5298         spoolss_state = state;
5299 }
5300
5301 uint32 lp_get_spoolss_state( void )
5302 {
5303         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5304 }
5305
5306 /*******************************************************************
5307  Ensure we don't use sendfile if server smb signing is active.
5308 ********************************************************************/
5309
5310 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
5311 {
5312         bool sign_active = false;
5313
5314         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5315         if (get_Protocol() < PROTOCOL_NT1) {
5316                 return false;
5317         }
5318         if (signing_state) {
5319                 sign_active = smb_signing_is_active(signing_state);
5320         }
5321         return (lp__use_sendfile(snum) &&
5322                         (get_remote_arch() != RA_WIN95) &&
5323                         !sign_active);
5324 }
5325
5326 /*******************************************************************
5327  Turn off sendfile if we find the underlying OS doesn't support it.
5328 ********************************************************************/
5329
5330 void set_use_sendfile(int snum, bool val)
5331 {
5332         if (LP_SNUM_OK(snum))
5333                 ServicePtrs[snum]->_use_sendfile = val;
5334         else
5335                 sDefault._use_sendfile = val;
5336 }
5337
5338 /*******************************************************************
5339  Turn off storing DOS attributes if this share doesn't support it.
5340 ********************************************************************/
5341
5342 void set_store_dos_attributes(int snum, bool val)
5343 {
5344         if (!LP_SNUM_OK(snum))
5345                 return;
5346         ServicePtrs[(snum)]->store_dos_attributes = val;
5347 }
5348
5349 void lp_set_mangling_method(const char *new_method)
5350 {
5351         string_set(&Globals.mangling_method, new_method);
5352 }
5353
5354 /*******************************************************************
5355  Global state for POSIX pathname processing.
5356 ********************************************************************/
5357
5358 static bool posix_pathnames;
5359
5360 bool lp_posix_pathnames(void)
5361 {
5362         return posix_pathnames;
5363 }
5364
5365 /*******************************************************************
5366  Change everything needed to ensure POSIX pathname processing (currently
5367  not much).
5368 ********************************************************************/
5369
5370 void lp_set_posix_pathnames(void)
5371 {
5372         posix_pathnames = true;
5373 }
5374
5375 /*******************************************************************
5376  Global state for POSIX lock processing - CIFS unix extensions.
5377 ********************************************************************/
5378
5379 bool posix_default_lock_was_set;
5380 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5381
5382 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5383 {
5384         if (posix_default_lock_was_set) {
5385                 return posix_cifsx_locktype;
5386         } else {
5387                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5388         }
5389 }
5390
5391 /*******************************************************************
5392 ********************************************************************/
5393
5394 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5395 {
5396         posix_default_lock_was_set = true;
5397         posix_cifsx_locktype = val;
5398 }
5399
5400 int lp_min_receive_file_size(void)
5401 {
5402         if (Globals.iminreceivefile < 0) {
5403                 return 0;
5404         }
5405         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
5406 }
5407
5408 /*******************************************************************
5409  Safe wide links checks.
5410  This helper function always verify the validity of wide links,
5411  even after a configuration file reload.
5412 ********************************************************************/
5413
5414 static bool lp_widelinks_internal(int snum)
5415 {
5416         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
5417                         sDefault.bWidelinks);
5418 }
5419
5420 void widelinks_warning(int snum)
5421 {
5422         if (lp_allow_insecure_widelinks()) {
5423                 return;
5424         }
5425
5426         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
5427                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
5428                         "These parameters are incompatible. "
5429                         "Wide links will be disabled for this share.\n",
5430                          lp_servicename(talloc_tos(), snum) ));
5431         }
5432 }
5433
5434 bool lp_widelinks(int snum)
5435 {
5436         /* wide links is always incompatible with unix extensions */
5437         if (lp_unix_extensions()) {
5438                 /*
5439                  * Unless we have "allow insecure widelinks"
5440                  * turned on.
5441                  */
5442                 if (!lp_allow_insecure_widelinks()) {
5443                         return false;
5444                 }
5445         }
5446
5447         return lp_widelinks_internal(snum);
5448 }
5449
5450 bool lp_writeraw(void)
5451 {
5452         if (lp_async_smb_echo_handler()) {
5453                 return false;
5454         }
5455         return lp__writeraw();
5456 }
5457
5458 bool lp_readraw(void)
5459 {
5460         if (lp_async_smb_echo_handler()) {
5461                 return false;
5462         }
5463         return lp__readraw();
5464 }
5465
5466 int lp_server_role(void)
5467 {
5468         return lp_find_server_role(lp__server_role(),
5469                                    lp__security(),
5470                                    lp__domain_logons(),
5471                                    lp_domain_master_true_or_auto());
5472 }
5473
5474 int lp_security(void)
5475 {
5476         return lp_find_security(lp__server_role(),
5477                                 lp__security());
5478 }