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