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