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