0fce5399685f2214c482aa1d77722f5feac2337f
[amitay/samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14    Copyright (C) Andrew Bartlett 2011
15
16    This program is free software; you can redistribute it and/or modify
17    it under the terms of the GNU General Public License as published by
18    the Free Software Foundation; either version 3 of the License, or
19    (at your option) any later version.
20
21    This program is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24    GNU General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with this program.  If not, see <http://www.gnu.org/licenses/>.
28 */
29
30 /*
31  *  Load parameters.
32  *
33  *  This module provides suitable callback functions for the params
34  *  module. It builds the internal table of service details which is
35  *  then used by the rest of the server.
36  *
37  * To add a parameter:
38  *
39  * 1) add it to the global or service structure definition
40  * 2) add it to the parm_table
41  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42  * 4) If it's a global then initialise it in init_globals. If a local
43  *    (ie. service) parameter then initialise it in the sDefault structure
44  *  
45  *
46  * Notes:
47  *   The configuration file is processed sequentially for speed. It is NOT
48  *   accessed randomly as happens in 'real' Windows. For this reason, there
49  *   is a fair bit of sequence-dependent code here - ie., code which assumes
50  *   that certain things happen before others. In particular, the code which
51  *   happens at the boundary between sections is delicately poised, so be
52  *   careful!
53  *
54  */
55
56 #include "includes.h"
57 #include "system/filesys.h"
58 #include "util_tdb.h"
59 #include "lib/param/loadparm.h"
60 #include "lib/param/param.h"
61 #include "printing.h"
62 #include "lib/smbconf/smbconf.h"
63 #include "lib/smbconf/smbconf_init.h"
64
65 #include "ads.h"
66 #include "../librpc/gen_ndr/svcctl.h"
67 #include "intl.h"
68 #include "../libcli/smb/smb_signing.h"
69 #include "dbwrap/dbwrap.h"
70 #include "dbwrap/dbwrap_rbt.h"
71 #include "../lib/util/bitmap.h"
72
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
75 #endif
76
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
79 #endif
80
81 #ifdef CLUSTER_SUPPORT
82 #include "ctdb_private.h"
83 #endif
84
85 bool bLoaded = false;
86
87 extern userdom_struct current_user_info;
88
89 /* the special value for the include parameter
90  * to be interpreted not as a file name but to
91  * trigger loading of the global smb.conf options
92  * from registry. */
93 #ifndef INCLUDE_REGISTRY_NAME
94 #define INCLUDE_REGISTRY_NAME "registry"
95 #endif
96
97 static bool in_client = false;          /* Not in the client by default */
98 static struct smbconf_csn conf_last_csn;
99
100 static int config_backend = CONFIG_BACKEND_FILE;
101
102 /* some helpful bits */
103 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
104 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
105
106 #define USERSHARE_VALID 1
107 #define USERSHARE_PENDING_DELETE 2
108
109 static bool defaults_saved = false;
110
111 #define LOADPARM_EXTRA_GLOBALS \
112         struct parmlist_entry *param_opt;                               \
113         char *realm_original;                                           \
114         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 *szIdmapUID;                                               \
125         char *szIdmapGID;                                               \
126         char *szIdmapBackend;                                           \
127         int winbindMaxDomainConnections;                                \
128         int ismb2_max_credits;                                          \
129         char *tls_keyfile;                                              \
130         char *tls_certfile;                                             \
131         char *tls_cafile;                                               \
132         char *tls_crlfile;                                              \
133         char *tls_dhpfile;
134
135 #include "param/param_global.h"
136
137 static struct loadparm_global Globals;
138
139 /* This is a default service used to prime a services structure */
140 static struct loadparm_service sDefault =
141 {
142         .valid = true,
143         .autoloaded = false,
144         .usershare = 0,
145         .usershare_last_mod = {0, 0},
146         .szService = NULL,
147         .path = NULL,
148         .username = NULL,
149         .invalid_users = NULL,
150         .valid_users = NULL,
151         .admin_users = NULL,
152         .szCopy = NULL,
153         .szInclude = NULL,
154         .preexec = NULL,
155         .postexec = NULL,
156         .root_preexec = NULL,
157         .root_postexec = NULL,
158         .cups_options = NULL,
159         .print_command = NULL,
160         .lpq_command = NULL,
161         .lprm_command = NULL,
162         .lppause_command = NULL,
163         .lpresume_command = NULL,
164         .queuepause_command = NULL,
165         .queueresume_command = NULL,
166         ._printername = NULL,
167         .printjob_username = NULL,
168         .dont_descend = NULL,
169         .hosts_allow = NULL,
170         .hosts_deny = NULL,
171         .magic_script = NULL,
172         .magic_output = NULL,
173         .veto_files = NULL,
174         .hide_files = NULL,
175         .veto_oplock_files = NULL,
176         .comment = NULL,
177         .force_user = NULL,
178         .force_group = NULL,
179         .read_list = NULL,
180         .write_list = NULL,
181         .volume = NULL,
182         .fstype = NULL,
183         .vfs_objects = NULL,
184         .msdfs_proxy = NULL,
185         .aio_write_behind = NULL,
186         .dfree_command = NULL,
187         .min_print_space = 0,
188         .iMaxPrintJobs = 1000,
189         .max_reported_print_jobs = 0,
190         .write_cache_size = 0,
191         .create_mask = 0744,
192         .force_create_mode = 0,
193         .directory_mask = 0755,
194         .force_directory_mode = 0,
195         .max_connections = 0,
196         .default_case = CASE_LOWER,
197         .printing = DEFAULT_PRINTING,
198         .oplock_contention_limit = 2,
199         .csc_policy = 0,
200         .block_size = 1024,
201         .dfree_cache_time = 0,
202         .preexec_close = false,
203         .root_preexec_close = false,
204         .case_sensitive = Auto,
205         .preserve_case = true,
206         .short_preserve_case = true,
207         .hide_dot_files = true,
208         .hide_special_files = false,
209         .hide_unreadable = false,
210         .hide_unwriteable_files = false,
211         .browseable = true,
212         .access_based_share_enum = false,
213         .bAvailable = true,
214         .read_only = true,
215         .guest_only = false,
216         .administrative_share = false,
217         .guest_ok = false,
218         .printable = false,
219         .print_notify_backchannel = false,
220         .map_system = false,
221         .map_hidden = false,
222         .map_archive = true,
223         .store_dos_attributes = false,
224         .dmapi_support = false,
225         .locking = true,
226         .strict_locking = Auto,
227         .posix_locking = true,
228         .oplocks = true,
229         .kernel_oplocks = false,
230         .level2_oplocks = true,
231         .only_user = false,
232         .mangled_names = true,
233         .bWidelinks = false,
234         .follow_symlinks = true,
235         .sync_always = false,
236         .strict_allocate = false,
237         .strict_sync = false,
238         .mangling_char = '~',
239         .copymap = NULL,
240         .delete_readonly = false,
241         .fake_oplocks = false,
242         .delete_veto_files = false,
243         .dos_filemode = false,
244         .dos_filetimes = true,
245         .dos_filetime_resolution = false,
246         .fake_directory_create_times = false,
247         .blocking_locks = true,
248         .inherit_permissions = false,
249         .inherit_acls = false,
250         .inherit_owner = false,
251         .msdfs_root = false,
252         .use_client_driver = false,
253         .default_devmode = true,
254         .force_printername = false,
255         .nt_acl_support = true,
256         .force_unknown_acl_user = false,
257         ._use_sendfile = false,
258         .profile_acls = false,
259         .map_acl_inherit = false,
260         .afs_share = false,
261         .ea_support = false,
262         .acl_check_permissions = true,
263         .acl_map_full_control = true,
264         .acl_group_control = false,
265         .acl_allow_execute_always = false,
266         .change_notify = true,
267         .kernel_change_notify = true,
268         .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
269         .aio_read_size = 0,
270         .aio_write_size = 0,
271         .map_readonly = MAP_READONLY_YES,
272         .directory_name_cache_size = 100,
273         .smb_encrypt = SMB_SIGNING_DEFAULT,
274         .kernel_share_modes = true,
275         .durable_handles = true,
276         .param_opt = NULL,
277         .dummy = ""
278 };
279
280 /* local variables */
281 static struct loadparm_service **ServicePtrs = NULL;
282 static int iNumServices = 0;
283 static int iServiceIndex = 0;
284 static struct db_context *ServiceHash;
285 static bool bInGlobalSection = true;
286 static bool bGlobalOnly = false;
287
288 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
289
290 /* prototypes for the special type handlers */
291 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
292 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
293 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
294 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
295 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
296 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
297 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
298 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
299 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
300 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
301 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
302 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
303
304 /* these are parameter handlers which are not needed in the
305  * source3 code
306  */
307
308 #define handle_logfile NULL
309
310 static void set_allowed_client_auth(void);
311
312 static void add_to_file_list(const char *fname, const char *subfname);
313 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
314 static void free_param_opts(struct parmlist_entry **popts);
315
316 #include "lib/param/param_table.c"
317
318 /* this is used to prevent lots of mallocs of size 1 */
319 static const char null_string[] = "";
320
321 /**
322  Set a string value, allocing the space for the string
323 **/
324
325 static bool string_init(char **dest,const char *src)
326 {
327         size_t l;
328
329         if (!src)
330                 src = "";
331
332         l = strlen(src);
333
334         if (l == 0) {
335                 *dest = discard_const_p(char, null_string);
336         } else {
337                 (*dest) = SMB_STRDUP(src);
338                 if ((*dest) == NULL) {
339                         DEBUG(0,("Out of memory in string_init\n"));
340                         return false;
341                 }
342         }
343         return(true);
344 }
345
346 /**
347  Free a string value.
348 **/
349
350 static void string_free(char **s)
351 {
352         if (!s || !(*s))
353                 return;
354         if (*s == null_string)
355                 *s = NULL;
356         SAFE_FREE(*s);
357 }
358
359 /**
360  Set a string value, deallocating any existing space, and allocing the space
361  for the string
362 **/
363
364 static bool string_set(char **dest,const char *src)
365 {
366         string_free(dest);
367         return(string_init(dest,src));
368 }
369
370 /***************************************************************************
371  Initialise the sDefault parameter structure for the printer values.
372 ***************************************************************************/
373
374 static void init_printer_values(struct loadparm_service *pService)
375 {
376         /* choose defaults depending on the type of printing */
377         switch (pService->printing) {
378                 case PRINT_BSD:
379                 case PRINT_AIX:
380                 case PRINT_LPRNT:
381                 case PRINT_LPROS2:
382                         string_set(&pService->lpq_command, "lpq -P'%p'");
383                         string_set(&pService->lprm_command, "lprm -P'%p' %j");
384                         string_set(&pService->print_command, "lpr -r -P'%p' %s");
385                         break;
386
387                 case PRINT_LPRNG:
388                 case PRINT_PLP:
389                         string_set(&pService->lpq_command, "lpq -P'%p'");
390                         string_set(&pService->lprm_command, "lprm -P'%p' %j");
391                         string_set(&pService->print_command, "lpr -r -P'%p' %s");
392                         string_set(&pService->queuepause_command, "lpc stop '%p'");
393                         string_set(&pService->queueresume_command, "lpc start '%p'");
394                         string_set(&pService->lppause_command, "lpc hold '%p' %j");
395                         string_set(&pService->lpresume_command, "lpc release '%p' %j");
396                         break;
397
398                 case PRINT_CUPS:
399                 case PRINT_IPRINT:
400                         /* set the lpq command to contain the destination printer
401                            name only.  This is used by cups_queue_get() */
402                         string_set(&pService->lpq_command, "%p");
403                         string_set(&pService->lprm_command, "");
404                         string_set(&pService->print_command, "");
405                         string_set(&pService->lppause_command, "");
406                         string_set(&pService->lpresume_command, "");
407                         string_set(&pService->queuepause_command, "");
408                         string_set(&pService->queueresume_command, "");
409                         break;
410
411                 case PRINT_SYSV:
412                 case PRINT_HPUX:
413                         string_set(&pService->lpq_command, "lpstat -o%p");
414                         string_set(&pService->lprm_command, "cancel %p-%j");
415                         string_set(&pService->print_command, "lp -c -d%p %s; rm %s");
416                         string_set(&pService->queuepause_command, "disable %p");
417                         string_set(&pService->queueresume_command, "enable %p");
418 #ifndef HPUX
419                         string_set(&pService->lppause_command, "lp -i %p-%j -H hold");
420                         string_set(&pService->lpresume_command, "lp -i %p-%j -H resume");
421 #endif /* HPUX */
422                         break;
423
424                 case PRINT_QNX:
425                         string_set(&pService->lpq_command, "lpq -P%p");
426                         string_set(&pService->lprm_command, "lprm -P%p %j");
427                         string_set(&pService->print_command, "lp -r -P%p %s");
428                         break;
429
430 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
431
432         case PRINT_TEST:
433         case PRINT_VLP: {
434                 const char *tdbfile;
435                 TALLOC_CTX *tmp_ctx = talloc_stackframe();
436                 char *tmp;
437
438                 tdbfile = talloc_asprintf(
439                         tmp_ctx, "tdbfile=%s",
440                         lp_parm_const_string(-1, "vlp", "tdbfile",
441                                              "/tmp/vlp.tdb"));
442                 if (tdbfile == NULL) {
443                         tdbfile="tdbfile=/tmp/vlp.tdb";
444                 }
445
446                 tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
447                                       tdbfile);
448                 string_set(&pService->print_command,
449                            tmp ? tmp : "vlp print %p %s");
450
451                 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
452                                       tdbfile);
453                 string_set(&pService->lpq_command,
454                            tmp ? tmp : "vlp lpq %p");
455
456                 tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
457                                       tdbfile);
458                 string_set(&pService->lprm_command,
459                            tmp ? tmp : "vlp lprm %p %j");
460
461                 tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
462                                       tdbfile);
463                 string_set(&pService->lppause_command,
464                            tmp ? tmp : "vlp lppause %p %j");
465
466                 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
467                                       tdbfile);
468                 string_set(&pService->lpresume_command,
469                            tmp ? tmp : "vlp lpresume %p %j");
470
471                 tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
472                                       tdbfile);
473                 string_set(&pService->queuepause_command,
474                            tmp ? tmp : "vlp queuepause %p");
475
476                 tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
477                                       tdbfile);
478                 string_set(&pService->queueresume_command,
479                            tmp ? tmp : "vlp queueresume %p");
480                 TALLOC_FREE(tmp_ctx);
481
482                 break;
483         }
484 #endif /* DEVELOPER */
485
486         }
487 }
488 /**
489  *  Function to return the default value for the maximum number of open
490  *  file descriptors permitted.  This function tries to consult the
491  *  kernel-level (sysctl) and ulimit (getrlimit()) values and goes
492  *  the smaller of those.
493  */
494 static int max_open_files(void)
495 {
496         int sysctl_max = MAX_OPEN_FILES;
497         int rlimit_max = MAX_OPEN_FILES;
498
499 #ifdef HAVE_SYSCTLBYNAME
500         {
501                 size_t size = sizeof(sysctl_max);
502                 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
503                              0);
504         }
505 #endif
506
507 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
508         {
509                 struct rlimit rl;
510
511                 ZERO_STRUCT(rl);
512
513                 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
514                         rlimit_max = rl.rlim_cur;
515
516 #if defined(RLIM_INFINITY)
517                 if(rl.rlim_cur == RLIM_INFINITY)
518                         rlimit_max = MAX_OPEN_FILES;
519 #endif
520         }
521 #endif
522
523         if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
524                 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
525                         "minimum Windows limit (%d)\n",
526                         sysctl_max,
527                         MIN_OPEN_FILES_WINDOWS));
528                 sysctl_max = MIN_OPEN_FILES_WINDOWS;
529         }
530
531         if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
532                 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
533                         "minimum Windows limit (%d)\n",
534                         rlimit_max,
535                         MIN_OPEN_FILES_WINDOWS));
536                 rlimit_max = MIN_OPEN_FILES_WINDOWS;
537         }
538
539         return MIN(sysctl_max, rlimit_max);
540 }
541
542 /**
543  * Common part of freeing allocated data for one parameter.
544  */
545 static void free_one_parameter_common(void *parm_ptr,
546                                       struct parm_struct parm)
547 {
548         if ((parm.type == P_STRING) ||
549             (parm.type == P_USTRING))
550         {
551                 string_free((char**)parm_ptr);
552         } else if (parm.type == P_LIST) {
553                 TALLOC_FREE(*((char***)parm_ptr));
554         }
555 }
556
557 /**
558  * Free the allocated data for one parameter for a share
559  * given as a service struct.
560  */
561 static void free_one_parameter(struct loadparm_service *service,
562                                struct parm_struct parm)
563 {
564         void *parm_ptr;
565
566         if (parm.p_class != P_LOCAL) {
567                 return;
568         }
569
570         parm_ptr = lp_parm_ptr(service, &parm);
571
572         free_one_parameter_common(parm_ptr, parm);
573 }
574
575 /**
576  * Free the allocated parameter data of a share given
577  * as a service struct.
578  */
579 static void free_parameters(struct loadparm_service *service)
580 {
581         uint32_t i;
582
583         for (i=0; parm_table[i].label; i++) {
584                 free_one_parameter(service, parm_table[i]);
585         }
586 }
587
588 /**
589  * Free the allocated data for one parameter for a given share
590  * specified by an snum.
591  */
592 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
593 {
594         void *parm_ptr;
595
596         if (snum < 0) {
597                 parm_ptr = lp_parm_ptr(NULL, &parm);
598         } else if (parm.p_class != P_LOCAL) {
599                 return;
600         } else {
601                 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
602         }
603
604         free_one_parameter_common(parm_ptr, parm);
605 }
606
607 /**
608  * Free the allocated parameter data for a share specified
609  * by an snum.
610  */
611 static void free_parameters_by_snum(int snum)
612 {
613         uint32_t i;
614
615         for (i=0; parm_table[i].label; i++) {
616                 free_one_parameter_by_snum(snum, parm_table[i]);
617         }
618 }
619
620 /**
621  * Free the allocated global parameters.
622  */
623 static void free_global_parameters(void)
624 {
625         free_param_opts(&Globals.param_opt);
626         free_parameters_by_snum(GLOBAL_SECTION_SNUM);
627         TALLOC_FREE(Globals.ctx);
628 }
629
630 struct lp_stored_option {
631         struct lp_stored_option *prev, *next;
632         const char *label;
633         const char *value;
634 };
635
636 static struct lp_stored_option *stored_options;
637
638 /*
639   save options set by lp_set_cmdline() into a list. This list is
640   re-applied when we do a globals reset, so that cmdline set options
641   are sticky across reloads of smb.conf
642  */
643 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
644 {
645         struct lp_stored_option *entry, *entry_next;
646         for (entry = stored_options; entry != NULL; entry = entry_next) {
647                 entry_next = entry->next;
648                 if (strcmp(pszParmName, entry->label) == 0) {
649                         DLIST_REMOVE(stored_options, entry);
650                         talloc_free(entry);
651                         break;
652                 }
653         }
654
655         entry = talloc(NULL, struct lp_stored_option);
656         if (!entry) {
657                 return false;
658         }
659
660         entry->label = talloc_strdup(entry, pszParmName);
661         if (!entry->label) {
662                 talloc_free(entry);
663                 return false;
664         }
665
666         entry->value = talloc_strdup(entry, pszParmValue);
667         if (!entry->value) {
668                 talloc_free(entry);
669                 return false;
670         }
671
672         DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
673
674         return true;
675 }
676
677 static bool apply_lp_set_cmdline(void)
678 {
679         struct lp_stored_option *entry = NULL;
680         for (entry = stored_options; entry != NULL; entry = entry->next) {
681                 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
682                         DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
683                                   entry->label, entry->value));
684                         return false;
685                 }
686         }
687         return true;
688 }
689
690 /***************************************************************************
691  Initialise the global parameter structure.
692 ***************************************************************************/
693
694 static void init_globals(bool reinit_globals)
695 {
696         static bool done_init = false;
697         char *s = NULL;
698         int i;
699
700         /* If requested to initialize only once and we've already done it... */
701         if (!reinit_globals && done_init) {
702                 /* ... then we have nothing more to do */
703                 return;
704         }
705
706         if (!done_init) {
707                 /* The logfile can be set before this is invoked. Free it if so. */
708                 if (Globals.logfile != NULL) {
709                         string_free(&Globals.logfile);
710                         Globals.logfile = NULL;
711                 }
712                 done_init = true;
713         } else {
714                 free_global_parameters();
715         }
716
717         /* This memset and the free_global_parameters() above will
718          * wipe out smb.conf options set with lp_set_cmdline().  The
719          * apply_lp_set_cmdline() call puts these values back in the
720          * table once the defaults are set */
721         ZERO_STRUCT(Globals);
722
723         Globals.ctx = talloc_new(NULL);
724
725         for (i = 0; parm_table[i].label; i++) {
726                 if ((parm_table[i].type == P_STRING ||
727                      parm_table[i].type == P_USTRING))
728                 {
729                         string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
730                 }
731         }
732
733
734         string_set(&sDefault.fstype, FSTYPE_STRING);
735         string_set(&sDefault.printjob_username, "%U");
736
737         init_printer_values(&sDefault);
738
739         sDefault.ntvfs_handler = (const char **)str_list_make_v3(NULL, "unixuid default", NULL);
740
741         DEBUG(3, ("Initialising global parameters\n"));
742
743         /* Must manually force to upper case here, as this does not go via the handler */
744         string_set(&Globals.netbios_name, myhostname_upper());
745
746         string_set(&Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
747         string_set(&Globals.private_dir, get_dyn_PRIVATE_DIR());
748
749         /* use the new 'hash2' method by default, with a prefix of 1 */
750         string_set(&Globals.mangling_method, "hash2");
751         Globals.mangle_prefix = 1;
752
753         string_set(&Globals.guest_account, GUEST_ACCOUNT);
754
755         /* using UTF8 by default allows us to support all chars */
756         string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
757
758         /* Use codepage 850 as a default for the dos character set */
759         string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
760
761         /*
762          * Allow the default PASSWD_CHAT to be overridden in local.h.
763          */
764         string_set(&Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
765
766         string_set(&Globals.workgroup, DEFAULT_WORKGROUP);
767
768         string_set(&Globals.passwd_program, "");
769         string_set(&Globals.lock_directory, get_dyn_LOCKDIR());
770         string_set(&Globals.szStateDir, get_dyn_STATEDIR());
771         string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
772         string_set(&Globals.pid_directory, get_dyn_PIDDIR());
773         string_set(&Globals.nbt_client_socket_address, "0.0.0.0");
774         /*
775          * By default support explicit binding to broadcast
776          * addresses.
777          */
778         Globals.nmbd_bind_explicit_broadcast = true;
779
780         if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
781                 smb_panic("init_globals: ENOMEM");
782         }
783         string_set(&Globals.server_string, s);
784         SAFE_FREE(s);
785 #ifdef DEVELOPER
786         string_set(&Globals.panic_action, "/bin/sleep 999999999");
787 #endif
788
789         string_set(&Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
790
791         string_set(&Globals.logon_drive, "");
792         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
793         string_set(&Globals.logon_home, "\\\\%N\\%U");
794         string_set(&Globals.logon_path, "\\\\%N\\%U\\profile");
795
796         Globals.name_resolve_order = (const char **)str_list_make_v3(NULL, "lmhosts wins host bcast", NULL);
797         string_set(&Globals.password_server, "*");
798
799         Globals.algorithmic_rid_base = BASE_RID;
800
801         Globals.load_printers = true;
802         Globals.printcap_cache_time = 750;      /* 12.5 minutes */
803
804         Globals.config_backend = config_backend;
805         Globals._server_role = ROLE_AUTO;
806
807         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
808         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
809         Globals.max_xmit = 0x4104;
810         Globals.max_mux = 50;   /* This is *needed* for profile support. */
811         Globals.lpq_cache_time = 30;    /* changed to handle large print servers better -- jerry */
812         Globals._disable_spoolss = false;
813         Globals.max_smbd_processes = 0;/* no limit specified */
814         Globals.username_level = 0;
815         Globals.deadtime = 0;
816         Globals.getwd_cache = true;
817         Globals.large_readwrite = true;
818         Globals.max_log_size = 5000;
819         Globals.max_open_files = max_open_files();
820         Globals.server_max_protocol = PROTOCOL_SMB3_00;
821         Globals.server_min_protocol = PROTOCOL_LANMAN1;
822         Globals.client_max_protocol = PROTOCOL_NT1;
823         Globals.client_min_protocol = PROTOCOL_CORE;
824         Globals._security = SEC_AUTO;
825         Globals.encrypt_passwords = true;
826         Globals.client_schannel = Auto;
827         Globals.winbind_sealed_pipes = true;
828         Globals.require_strong_key = true;
829         Globals.server_schannel = Auto;
830         Globals.read_raw = true;
831         Globals.write_raw = true;
832         Globals.null_passwords = false;
833         Globals.obey_pam_restrictions = false;
834         Globals.syslog = 1;
835         Globals.syslog_only = false;
836         Globals.timestamp_logs = true;
837         string_set(&Globals.log_level, "0");
838         Globals.debug_prefix_timestamp = false;
839         Globals.debug_hires_timestamp = true;
840         Globals.debug_pid = false;
841         Globals.debug_uid = false;
842         Globals.debug_class = false;
843         Globals.enable_core_files = true;
844         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
845         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
846         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
847         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
848         Globals.lm_announce = Auto;     /* = Auto: send only if LM clients found */
849         Globals.lm_interval = 60;
850 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
851         Globals.nis_homedir = false;
852 #ifdef WITH_NISPLUS_HOME
853         string_set(&Globals.homedir_map, "auto_home.org_dir");
854 #else
855         string_set(&Globals.homedir_map, "auto.home");
856 #endif
857 #endif
858         Globals.time_server = false;
859         Globals.bind_interfaces_only = false;
860         Globals.unix_password_sync = false;
861         Globals.pam_password_change = false;
862         Globals.passwd_chat_debug = false;
863         Globals.passwd_chat_timeout = 2; /* 2 second default. */
864         Globals.nt_pipe_support = true; /* Do NT pipes by default. */
865         Globals.nt_status_support = true; /* Use NT status by default. */
866         Globals.stat_cache = true;      /* use stat cache by default */
867         Globals.max_stat_cache_size = 256; /* 256k by default */
868         Globals.restrict_anonymous = 0;
869         Globals.client_lanman_auth = false;     /* Do NOT use the LanMan hash if it is available */
870         Globals.client_plaintext_auth = false;  /* Do NOT use a plaintext password even if is requested by the server */
871         Globals.lanman_auth = false;    /* Do NOT use the LanMan hash, even if it is supplied */
872         Globals.ntlm_auth = true;       /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
873         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 */
874         /* Note, that we will also use NTLM2 session security (which is different), if it is available */
875
876         Globals.map_to_guest = 0;       /* By Default, "Never" */
877         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
878         Globals.enhanced_browsing = true;
879         Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
880 #ifdef MMAP_BLACKLIST
881         Globals.use_mmap = false;
882 #else
883         Globals.use_mmap = true;
884 #endif
885         Globals.unicode = true;
886         Globals.unix_extensions = true;
887         Globals.reset_on_zero_vc = false;
888         Globals.log_writeable_files_on_exit = false;
889         Globals.create_krb5_conf = true;
890         Globals.winbindMaxDomainConnections = 1;
891
892         /* hostname lookups can be very expensive and are broken on
893            a large number of sites (tridge) */
894         Globals.hostname_lookups = false;
895
896         string_set(&Globals.passdb_backend, "tdbsam");
897         string_set(&Globals.ldap_suffix, "");
898         string_set(&Globals.szLdapMachineSuffix, "");
899         string_set(&Globals.szLdapUserSuffix, "");
900         string_set(&Globals.szLdapGroupSuffix, "");
901         string_set(&Globals.szLdapIdmapSuffix, "");
902
903         string_set(&Globals.ldap_admin_dn, "");
904         Globals.ldap_ssl = LDAP_SSL_START_TLS;
905         Globals.ldap_ssl_ads = false;
906         Globals.ldap_deref = -1;
907         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
908         Globals.ldap_delete_dn = false;
909         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
910         Globals.ldap_follow_referral = Auto;
911         Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
912         Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
913         Globals.ldap_page_size = LDAP_PAGE_SIZE;
914
915         Globals.ldap_debug_level = 0;
916         Globals.ldap_debug_threshold = 10;
917
918         /* This is what we tell the afs client. in reality we set the token 
919          * to never expire, though, when this runs out the afs client will 
920          * forget the token. Set to 0 to get NEVERDATE.*/
921         Globals.afs_token_lifetime = 604800;
922         Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
923
924 /* these parameters are set to defaults that are more appropriate
925    for the increasing samba install base:
926
927    as a member of the workgroup, that will possibly become a
928    _local_ master browser (lm = true).  this is opposed to a forced
929    local master browser startup (pm = true).
930
931    doesn't provide WINS server service by default (wsupp = false),
932    and doesn't provide domain master browser services by default, either.
933
934 */
935
936         Globals.show_add_printer_wizard = true;
937         Globals.os_level = 20;
938         Globals.local_master = true;
939         Globals._domain_master = Auto;  /* depending on _domain_logons */
940         Globals._domain_logons = false;
941         Globals.browse_list = true;
942         Globals.we_are_a_wins_server = false;
943         Globals.wins_proxy = false;
944
945         TALLOC_FREE(Globals.init_logon_delayed_hosts);
946         Globals.init_logon_delay = 100; /* 100 ms default delay */
947
948         Globals.wins_dns_proxy = true;
949
950         Globals.allow_trusted_domains = true;
951         string_set(&Globals.szIdmapBackend, "tdb");
952
953         string_set(&Globals.template_shell, "/bin/false");
954         string_set(&Globals.template_homedir, "/home/%D/%U");
955         string_set(&Globals.winbind_separator, "\\");
956         string_set(&Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
957
958         string_set(&Globals.cups_server, "");
959         string_set(&Globals.iprint_server, "");
960
961 #ifdef CLUSTER_SUPPORT
962         string_set(&Globals.ctdbd_socket, CTDB_PATH);
963 #else
964         string_set(&Globals.ctdbd_socket, "");
965 #endif
966
967         Globals.cluster_addresses = NULL;
968         Globals.clustering = false;
969         Globals.ctdb_timeout = 0;
970         Globals.ctdb_locktime_warn_threshold = 0;
971
972         Globals.winbind_cache_time = 300;       /* 5 minutes */
973         Globals.winbind_reconnect_delay = 30;   /* 30 seconds */
974         Globals.winbind_max_clients = 200;
975         Globals.winbind_enum_users = false;
976         Globals.winbind_enum_groups = false;
977         Globals.winbind_use_default_domain = false;
978         Globals.winbind_trusted_domains_only = false;
979         Globals.winbind_nested_groups = true;
980         Globals.winbind_expand_groups = 1;
981         Globals.winbind_nss_info = (const char **)str_list_make_v3(NULL, "template", NULL);
982         Globals.winbind_refresh_tickets = false;
983         Globals.winbind_offline_logon = false;
984
985         Globals.idmap_cache_time = 86400 * 7; /* a week by default */
986         Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
987
988         Globals.passdb_expand_explicit = false;
989
990         Globals.name_cache_timeout = 660; /* In seconds */
991
992         Globals.use_spnego = true;
993         Globals.client_use_spnego = true;
994
995         Globals.client_signing = SMB_SIGNING_DEFAULT;
996         Globals.server_signing = SMB_SIGNING_DEFAULT;
997
998         Globals.defer_sharing_violations = true;
999         Globals.smb_ports = (const char **)str_list_make_v3(NULL, SMB_PORTS, NULL);
1000
1001         Globals.enable_privileges = true;
1002         Globals.host_msdfs        = true;
1003         Globals.enable_asu_support       = false;
1004
1005         /* User defined shares. */
1006         if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
1007                 smb_panic("init_globals: ENOMEM");
1008         }
1009         string_set(&Globals.usershare_path, s);
1010         SAFE_FREE(s);
1011         string_set(&Globals.usershare_template_share, "");
1012         Globals.usershare_max_shares = 0;
1013         /* By default disallow sharing of directories not owned by the sharer. */
1014         Globals.usershare_owner_only = true;
1015         /* By default disallow guest access to usershares. */
1016         Globals.usershare_allow_guests = false;
1017
1018         Globals.keepalive = DEFAULT_KEEPALIVE;
1019
1020         /* By default no shares out of the registry */
1021         Globals.registry_shares = false;
1022
1023         Globals.iminreceivefile = 0;
1024
1025         Globals.map_untrusted_to_domain = false;
1026         Globals.multicast_dns_register = true;
1027
1028         Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
1029         Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
1030         Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
1031         Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1032
1033         string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
1034
1035         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);
1036
1037         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);
1038
1039         Globals.tls_enabled = true;
1040
1041         string_set(&Globals.tls_keyfile, "tls/key.pem");
1042         string_set(&Globals.tls_certfile, "tls/cert.pem");
1043         string_set(&Globals.tls_cafile, "tls/ca.pem");
1044
1045         string_set(&Globals.share_backend, "classic");
1046
1047         Globals.iPreferredMaster = Auto;
1048
1049         Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
1050
1051         string_set(&Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
1052
1053         string_set(&Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
1054
1055         if (asprintf(&s, "%s/samba_kcc", get_dyn_SCRIPTSBINDIR()) < 0) {
1056                 smb_panic("init_globals: ENOMEM");
1057         }
1058         Globals.samba_kcc_command = (const char **)str_list_make_v3(NULL, s, NULL);
1059         SAFE_FREE(s);
1060
1061         if (asprintf(&s, "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1062                 smb_panic("init_globals: ENOMEM");
1063         }
1064         Globals.dns_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1065         SAFE_FREE(s);
1066
1067         if (asprintf(&s, "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1068                 smb_panic("init_globals: ENOMEM");
1069         }
1070         Globals.spn_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1071         SAFE_FREE(s);
1072
1073         Globals.nsupdate_command = (const char **)str_list_make_v3(NULL, "/usr/bin/nsupdate -g", NULL);
1074
1075         Globals.rndc_command = (const char **)str_list_make_v3(NULL, "/usr/sbin/rndc", NULL);
1076
1077         Globals.cldap_port = 389;
1078
1079         Globals.dgram_port = 138;
1080
1081         Globals.nbt_port = 137;
1082
1083         Globals.krb5_port = 88;
1084
1085         Globals.kpasswd_port = 464;
1086
1087         Globals.web_port = 901;
1088
1089         /* Now put back the settings that were set with lp_set_cmdline() */
1090         apply_lp_set_cmdline();
1091 }
1092
1093 /*******************************************************************
1094  Convenience routine to grab string parameters into talloced memory
1095  and run standard_sub_basic on them. The buffers can be written to by
1096  callers without affecting the source string.
1097 ********************************************************************/
1098
1099 static char *lp_string(TALLOC_CTX *ctx, const char *s)
1100 {
1101         char *ret;
1102
1103         /* The follow debug is useful for tracking down memory problems
1104            especially if you have an inner loop that is calling a lp_*()
1105            function that returns a string.  Perhaps this debug should be
1106            present all the time? */
1107
1108 #if 0
1109         DEBUG(10, ("lp_string(%s)\n", s));
1110 #endif
1111         if (!s) {
1112                 return NULL;
1113         }
1114
1115         ret = talloc_sub_basic(ctx,
1116                         get_current_username(),
1117                         current_user_info.domain,
1118                         s);
1119         if (trim_char(ret, '\"', '\"')) {
1120                 if (strchr(ret,'\"') != NULL) {
1121                         TALLOC_FREE(ret);
1122                         ret = talloc_sub_basic(ctx,
1123                                         get_current_username(),
1124                                         current_user_info.domain,
1125                                         s);
1126                 }
1127         }
1128         return ret;
1129 }
1130
1131 /*
1132    In this section all the functions that are used to access the
1133    parameters from the rest of the program are defined
1134 */
1135
1136 #define FN_GLOBAL_STRING(fn_name,ptr) \
1137 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1138 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1139  const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1140 #define FN_GLOBAL_LIST(fn_name,ptr) \
1141  const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1142 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1143  bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1144 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1145  char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1146 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1147  int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1148
1149 #define FN_LOCAL_STRING(fn_name,val) \
1150 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));}
1151 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1152  const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1153 #define FN_LOCAL_LIST(fn_name,val) \
1154  const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1155 #define FN_LOCAL_BOOL(fn_name,val) \
1156  bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1157 #define FN_LOCAL_INTEGER(fn_name,val) \
1158  int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1159
1160 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1161  bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1162 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1163  int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1164 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1165  char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1166
1167
1168 /* If lp_statedir() and lp_cachedir() are explicitely set during the
1169  * build process or in smb.conf, we use that value.  Otherwise they
1170  * default to the value of lp_lock_directory(). */
1171 const char *lp_statedir(void) {
1172         if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
1173             (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
1174                 return(*(char **)(&Globals.szStateDir) ?
1175                        *(char **)(&Globals.szStateDir) : "");
1176         else
1177                 return(*(char **)(&Globals.lock_directory) ?
1178                        *(char **)(&Globals.lock_directory) : "");
1179 }
1180 const char *lp_cachedir(void) {
1181         if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
1182             (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
1183                 return(*(char **)(&Globals.szCacheDir) ?
1184                        *(char **)(&Globals.szCacheDir) : "");
1185         else
1186                 return(*(char **)(&Globals.lock_directory) ?
1187                        *(char **)(&Globals.lock_directory) : "");
1188 }
1189 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
1190                   winbindMaxDomainConnections)
1191
1192 int lp_winbind_max_domain_connections(void)
1193 {
1194         if (lp_winbind_offline_logon() &&
1195             lp_winbind_max_domain_connections_int() > 1) {
1196                 DEBUG(1, ("offline logons active, restricting max domain "
1197                           "connections to 1\n"));
1198                 return 1;
1199         }
1200         return MAX(1, lp_winbind_max_domain_connections_int());
1201 }
1202
1203 int lp_smb2_max_credits(void)
1204 {
1205         if (Globals.ismb2_max_credits == 0) {
1206                 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1207         }
1208         return Globals.ismb2_max_credits;
1209 }
1210 int lp_cups_encrypt(void)
1211 {
1212         int result = 0;
1213 #ifdef HAVE_HTTPCONNECTENCRYPT
1214         switch (Globals.CupsEncrypt) {
1215                 case Auto:
1216                         result = HTTP_ENCRYPT_REQUIRED;
1217                         break;
1218                 case true:
1219                         result = HTTP_ENCRYPT_ALWAYS;
1220                         break;
1221                 case false:
1222                         result = HTTP_ENCRYPT_NEVER;
1223                         break;
1224         }
1225 #endif
1226         return result;
1227 }
1228
1229 /* These functions remain in source3/param for now */
1230
1231 FN_GLOBAL_STRING(configfile, szConfigFile)
1232
1233 #include "lib/param/param_functions.c"
1234
1235 FN_LOCAL_STRING(servicename, szService)
1236 FN_LOCAL_CONST_STRING(const_servicename, szService)
1237
1238 /* These functions cannot be auto-generated */
1239 FN_LOCAL_BOOL(autoloaded, autoloaded)
1240 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1241
1242 /* local prototypes */
1243
1244 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1245 static const char *get_boolean(bool bool_value);
1246 static int getservicebyname(const char *pszServiceName,
1247                             struct loadparm_service *pserviceDest);
1248 static void copy_service(struct loadparm_service *pserviceDest,
1249                          struct loadparm_service *pserviceSource,
1250                          struct bitmap *pcopymapDest);
1251 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1252                          void *userdata);
1253 static bool do_section(const char *pszSectionName, void *userdata);
1254 static void init_copymap(struct loadparm_service *pservice);
1255 static bool hash_a_service(const char *name, int number);
1256 static void free_service_byindex(int iService);
1257 static void show_parameter(int parmIndex);
1258 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1259
1260 /*
1261  * This is a helper function for parametrical options support.  It returns a
1262  * pointer to parametrical option value if it exists or NULL otherwise. Actual
1263  * parametrical functions are quite simple
1264  */
1265 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
1266                                                            const char *option)
1267 {
1268         bool global_section = false;
1269         char* param_key;
1270         struct parmlist_entry *data;
1271
1272         if (service == NULL) {
1273                 data = Globals.param_opt;
1274                 global_section = true;
1275         } else {
1276                 data = service->param_opt;
1277         }
1278
1279         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
1280                 DEBUG(0,("asprintf failed!\n"));
1281                 return NULL;
1282         }
1283
1284         while (data) {
1285                 if (strwicmp(data->key, param_key) == 0) {
1286                         string_free(&param_key);
1287                         return data;
1288                 }
1289                 data = data->next;
1290         }
1291
1292         if (!global_section) {
1293                 /* Try to fetch the same option but from globals */
1294                 /* but only if we are not already working with Globals */
1295                 data = Globals.param_opt;
1296                 while (data) {
1297                         if (strwicmp(data->key, param_key) == 0) {
1298                                 string_free(&param_key);
1299                                 return data;
1300                         }
1301                         data = data->next;
1302                 }
1303         }
1304
1305         string_free(&param_key);
1306
1307         return NULL;
1308 }
1309
1310 /*
1311  * This is a helper function for parametrical options support.  It returns a
1312  * pointer to parametrical option value if it exists or NULL otherwise. Actual
1313  * parametrical functions are quite simple
1314  */
1315 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1316                                                 const char *option)
1317 {
1318         if (snum >= iNumServices) return NULL;
1319
1320         if (snum < 0) {
1321                 return get_parametrics_by_service(NULL, type, option);
1322         } else {
1323                 return get_parametrics_by_service(ServicePtrs[snum], type, option);
1324         }
1325 }
1326
1327
1328 #define MISSING_PARAMETER(name) \
1329     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1330
1331 /*******************************************************************
1332 convenience routine to return int parameters.
1333 ********************************************************************/
1334 static int lp_int(const char *s)
1335 {
1336
1337         if (!s || !*s) {
1338                 MISSING_PARAMETER(lp_int);
1339                 return (-1);
1340         }
1341
1342         return (int)strtol(s, NULL, 0);
1343 }
1344
1345 /*******************************************************************
1346 convenience routine to return unsigned long parameters.
1347 ********************************************************************/
1348 static unsigned long lp_ulong(const char *s)
1349 {
1350
1351         if (!s || !*s) {
1352                 MISSING_PARAMETER(lp_ulong);
1353                 return (0);
1354         }
1355
1356         return strtoul(s, NULL, 0);
1357 }
1358
1359 /*******************************************************************
1360 convenience routine to return boolean parameters.
1361 ********************************************************************/
1362 static bool lp_bool(const char *s)
1363 {
1364         bool ret = false;
1365
1366         if (!s || !*s) {
1367                 MISSING_PARAMETER(lp_bool);
1368                 return false;
1369         }
1370
1371         if (!set_boolean(s, &ret)) {
1372                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1373                 return false;
1374         }
1375
1376         return ret;
1377 }
1378
1379 /*******************************************************************
1380 convenience routine to return enum parameters.
1381 ********************************************************************/
1382 static int lp_enum(const char *s,const struct enum_list *_enum)
1383 {
1384         int i;
1385
1386         if (!s || !*s || !_enum) {
1387                 MISSING_PARAMETER(lp_enum);
1388                 return (-1);
1389         }
1390
1391         for (i=0; _enum[i].name; i++) {
1392                 if (strequal(_enum[i].name,s))
1393                         return _enum[i].value;
1394         }
1395
1396         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1397         return (-1);
1398 }
1399
1400 #undef MISSING_PARAMETER
1401
1402 /* Return parametric option from a given service. Type is a part of option before ':' */
1403 /* Parametric option has following syntax: 'Type: option = value' */
1404 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1405 {
1406         struct parmlist_entry *data = get_parametrics(snum, type, option);
1407
1408         if (data == NULL||data->value==NULL) {
1409                 if (def) {
1410                         return lp_string(ctx, def);
1411                 } else {
1412                         return NULL;
1413                 }
1414         }
1415
1416         return lp_string(ctx, data->value);
1417 }
1418
1419 /* Return parametric option from a given service. Type is a part of option before ':' */
1420 /* Parametric option has following syntax: 'Type: option = value' */
1421 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1422 {
1423         struct parmlist_entry *data = get_parametrics(snum, type, option);
1424
1425         if (data == NULL||data->value==NULL)
1426                 return def;
1427
1428         return data->value;
1429 }
1430
1431 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
1432 {
1433         struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
1434
1435         if (data == NULL||data->value==NULL)
1436                 return NULL;
1437
1438         return data->value;
1439 }
1440
1441
1442 /* Return parametric option from a given service. Type is a part of option before ':' */
1443 /* Parametric option has following syntax: 'Type: option = value' */
1444
1445 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1446 {
1447         struct parmlist_entry *data = get_parametrics(snum, type, option);
1448
1449         if (data == NULL||data->value==NULL)
1450                 return (const char **)def;
1451
1452         if (data->list==NULL) {
1453                 data->list = str_list_make_v3(NULL, data->value, NULL);
1454         }
1455
1456         return (const char **)data->list;
1457 }
1458
1459 /* Return parametric option from a given service. Type is a part of option before ':' */
1460 /* Parametric option has following syntax: 'Type: option = value' */
1461
1462 int lp_parm_int(int snum, const char *type, const char *option, int def)
1463 {
1464         struct parmlist_entry *data = get_parametrics(snum, type, option);
1465
1466         if (data && data->value && *data->value)
1467                 return lp_int(data->value);
1468
1469         return def;
1470 }
1471
1472 /* Return parametric option from a given service. Type is a part of option before ':' */
1473 /* Parametric option has following syntax: 'Type: option = value' */
1474
1475 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1476 {
1477         struct parmlist_entry *data = get_parametrics(snum, type, option);
1478
1479         if (data && data->value && *data->value)
1480                 return lp_ulong(data->value);
1481
1482         return def;
1483 }
1484
1485 /* Return parametric option from a given service. Type is a part of option before ':' */
1486 /* Parametric option has following syntax: 'Type: option = value' */
1487
1488 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1489 {
1490         struct parmlist_entry *data = get_parametrics(snum, type, option);
1491
1492         if (data && data->value && *data->value)
1493                 return lp_bool(data->value);
1494
1495         return def;
1496 }
1497
1498 /* Return parametric option from a given service. Type is a part of option before ':' */
1499 /* Parametric option has following syntax: 'Type: option = value' */
1500
1501 int lp_parm_enum(int snum, const char *type, const char *option,
1502                  const struct enum_list *_enum, int def)
1503 {
1504         struct parmlist_entry *data = get_parametrics(snum, type, option);
1505
1506         if (data && data->value && *data->value && _enum)
1507                 return lp_enum(data->value, _enum);
1508
1509         return def;
1510 }
1511
1512
1513 /***************************************************************************
1514  Initialise a service to the defaults.
1515 ***************************************************************************/
1516
1517 static void init_service(struct loadparm_service *pservice)
1518 {
1519         memset((char *)pservice, '\0', sizeof(struct loadparm_service));
1520         copy_service(pservice, &sDefault, NULL);
1521 }
1522
1523
1524 /**
1525  * free a param_opts structure.
1526  * param_opts handling should be moved to talloc;
1527  * then this whole functions reduces to a TALLOC_FREE().
1528  */
1529
1530 static void free_param_opts(struct parmlist_entry **popts)
1531 {
1532         struct parmlist_entry *opt, *next_opt;
1533
1534         if (*popts != NULL) {
1535                 DEBUG(5, ("Freeing parametrics:\n"));
1536         }
1537         opt = *popts;
1538         while (opt != NULL) {
1539                 string_free(&opt->key);
1540                 string_free(&opt->value);
1541                 TALLOC_FREE(opt->list);
1542                 next_opt = opt->next;
1543                 SAFE_FREE(opt);
1544                 opt = next_opt;
1545         }
1546         *popts = NULL;
1547 }
1548
1549 /***************************************************************************
1550  Free the dynamically allocated parts of a service struct.
1551 ***************************************************************************/
1552
1553 static void free_service(struct loadparm_service *pservice)
1554 {
1555         if (!pservice)
1556                 return;
1557
1558         if (pservice->szService)
1559                 DEBUG(5, ("free_service: Freeing service %s\n",
1560                        pservice->szService));
1561
1562         free_parameters(pservice);
1563
1564         string_free(&pservice->szService);
1565         TALLOC_FREE(pservice->copymap);
1566
1567         free_param_opts(&pservice->param_opt);
1568
1569         ZERO_STRUCTP(pservice);
1570 }
1571
1572
1573 /***************************************************************************
1574  remove a service indexed in the ServicePtrs array from the ServiceHash
1575  and free the dynamically allocated parts
1576 ***************************************************************************/
1577
1578 static void free_service_byindex(int idx)
1579 {
1580         if ( !LP_SNUM_OK(idx) ) 
1581                 return;
1582
1583         ServicePtrs[idx]->valid = false;
1584
1585         /* we have to cleanup the hash record */
1586
1587         if (ServicePtrs[idx]->szService) {
1588                 char *canon_name = canonicalize_servicename(
1589                         talloc_tos(),
1590                         ServicePtrs[idx]->szService );
1591
1592                 dbwrap_delete_bystring(ServiceHash, canon_name );
1593                 TALLOC_FREE(canon_name);
1594         }
1595
1596         free_service(ServicePtrs[idx]);
1597         talloc_free_children(ServicePtrs[idx]);
1598 }
1599
1600 /***************************************************************************
1601  Add a new service to the services array initialising it with the given 
1602  service. 
1603 ***************************************************************************/
1604
1605 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1606 {
1607         int i;
1608         struct loadparm_service tservice;
1609         int num_to_alloc = iNumServices + 1;
1610         struct loadparm_service **tsp = NULL;
1611
1612         tservice = *pservice;
1613
1614         /* it might already exist */
1615         if (name) {
1616                 i = getservicebyname(name, NULL);
1617                 if (i >= 0) {
1618                         return (i);
1619                 }
1620         }
1621
1622         /* if not, then create one */
1623         i = iNumServices;
1624         tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
1625         if (tsp == NULL) {
1626                 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1627                 return (-1);
1628         }
1629         ServicePtrs = tsp;
1630         ServicePtrs[iNumServices] = talloc(NULL, struct loadparm_service);
1631         if (!ServicePtrs[iNumServices]) {
1632                 DEBUG(0,("add_a_service: out of memory!\n"));
1633                 return (-1);
1634         }
1635         iNumServices++;
1636
1637         ServicePtrs[i]->valid = true;
1638
1639         init_service(ServicePtrs[i]);
1640         copy_service(ServicePtrs[i], &tservice, NULL);
1641         if (name)
1642                 string_set(&ServicePtrs[i]->szService, name);
1643
1644         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
1645                 i, ServicePtrs[i]->szService));
1646
1647         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1648                 return (-1);
1649         }
1650
1651         return (i);
1652 }
1653
1654 /***************************************************************************
1655   Convert a string to uppercase and remove whitespaces.
1656 ***************************************************************************/
1657
1658 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1659 {
1660         char *result;
1661
1662         if ( !src ) {
1663                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1664                 return NULL;
1665         }
1666
1667         result = talloc_strdup(ctx, src);
1668         SMB_ASSERT(result != NULL);
1669
1670         if (!strlower_m(result)) {
1671                 TALLOC_FREE(result);
1672                 return NULL;
1673         }
1674         return result;
1675 }
1676
1677 /***************************************************************************
1678   Add a name/index pair for the services array to the hash table.
1679 ***************************************************************************/
1680
1681 static bool hash_a_service(const char *name, int idx)
1682 {
1683         char *canon_name;
1684
1685         if ( !ServiceHash ) {
1686                 DEBUG(10,("hash_a_service: creating servicehash\n"));
1687                 ServiceHash = db_open_rbt(NULL);
1688                 if ( !ServiceHash ) {
1689                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1690                         return false;
1691                 }
1692         }
1693
1694         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1695                 idx, name));
1696
1697         canon_name = canonicalize_servicename(talloc_tos(), name );
1698
1699         dbwrap_store_bystring(ServiceHash, canon_name,
1700                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
1701                               TDB_REPLACE);
1702
1703         TALLOC_FREE(canon_name);
1704
1705         return true;
1706 }
1707
1708 /***************************************************************************
1709  Add a new home service, with the specified home directory, defaults coming
1710  from service ifrom.
1711 ***************************************************************************/
1712
1713 bool lp_add_home(const char *pszHomename, int iDefaultService,
1714                  const char *user, const char *pszHomedir)
1715 {
1716         int i;
1717
1718         if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1719                         pszHomedir[0] == '\0') {
1720                 return false;
1721         }
1722
1723         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1724
1725         if (i < 0)
1726                 return false;
1727
1728         if (!(*(ServicePtrs[iDefaultService]->path))
1729             || strequal(ServicePtrs[iDefaultService]->path,
1730                         lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1731                 string_set(&ServicePtrs[i]->path, pszHomedir);
1732         }
1733
1734         if (!(*(ServicePtrs[i]->comment))) {
1735                 char *comment = NULL;
1736                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
1737                         return false;
1738                 }
1739                 string_set(&ServicePtrs[i]->comment, comment);
1740                 SAFE_FREE(comment);
1741         }
1742
1743         /* set the browseable flag from the global default */
1744
1745         ServicePtrs[i]->browseable = sDefault.browseable;
1746         ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1747
1748         ServicePtrs[i]->autoloaded = true;
1749
1750         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
1751                user, ServicePtrs[i]->path ));
1752
1753         return true;
1754 }
1755
1756 /***************************************************************************
1757  Add a new service, based on an old one.
1758 ***************************************************************************/
1759
1760 int lp_add_service(const char *pszService, int iDefaultService)
1761 {
1762         if (iDefaultService < 0) {
1763                 return add_a_service(&sDefault, pszService);
1764         }
1765
1766         return (add_a_service(ServicePtrs[iDefaultService], pszService));
1767 }
1768
1769 /***************************************************************************
1770  Add the IPC service.
1771 ***************************************************************************/
1772
1773 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1774 {
1775         char *comment = NULL;
1776         int i = add_a_service(&sDefault, ipc_name);
1777
1778         if (i < 0)
1779                 return false;
1780
1781         if (asprintf(&comment, "IPC Service (%s)",
1782                                 Globals.server_string) < 0) {
1783                 return false;
1784         }
1785
1786         string_set(&ServicePtrs[i]->path, tmpdir());
1787         string_set(&ServicePtrs[i]->username, "");
1788         string_set(&ServicePtrs[i]->comment, comment);
1789         string_set(&ServicePtrs[i]->fstype, "IPC");
1790         ServicePtrs[i]->max_connections = 0;
1791         ServicePtrs[i]->bAvailable = true;
1792         ServicePtrs[i]->read_only = true;
1793         ServicePtrs[i]->guest_only = false;
1794         ServicePtrs[i]->administrative_share = true;
1795         ServicePtrs[i]->guest_ok = guest_ok;
1796         ServicePtrs[i]->printable = false;
1797         ServicePtrs[i]->browseable = sDefault.browseable;
1798
1799         DEBUG(3, ("adding IPC service\n"));
1800
1801         SAFE_FREE(comment);
1802         return true;
1803 }
1804
1805 /***************************************************************************
1806  Add a new printer service, with defaults coming from service iFrom.
1807 ***************************************************************************/
1808
1809 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1810 {
1811         const char *comment = "From Printcap";
1812         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1813
1814         if (i < 0)
1815                 return false;
1816
1817         /* note that we do NOT default the availability flag to true - */
1818         /* we take it from the default service passed. This allows all */
1819         /* dynamic printers to be disabled by disabling the [printers] */
1820         /* entry (if/when the 'available' keyword is implemented!).    */
1821
1822         /* the printer name is set to the service name. */
1823         string_set(&ServicePtrs[i]->_printername, pszPrintername);
1824         string_set(&ServicePtrs[i]->comment, comment);
1825
1826         /* set the browseable flag from the gloabl default */
1827         ServicePtrs[i]->browseable = sDefault.browseable;
1828
1829         /* Printers cannot be read_only. */
1830         ServicePtrs[i]->read_only = false;
1831         /* No oplocks on printer services. */
1832         ServicePtrs[i]->oplocks = false;
1833         /* Printer services must be printable. */
1834         ServicePtrs[i]->printable = true;
1835
1836         DEBUG(3, ("adding printer service %s\n", pszPrintername));
1837
1838         return true;
1839 }
1840
1841
1842 /***************************************************************************
1843  Check whether the given parameter name is valid.
1844  Parametric options (names containing a colon) are considered valid.
1845 ***************************************************************************/
1846
1847 bool lp_parameter_is_valid(const char *pszParmName)
1848 {
1849         return ((lpcfg_map_parameter(pszParmName) != -1) ||
1850                 (strchr(pszParmName, ':') != NULL));
1851 }
1852
1853 /***************************************************************************
1854  Check whether the given name is the name of a global parameter.
1855  Returns true for strings belonging to parameters of class
1856  P_GLOBAL, false for all other strings, also for parametric options
1857  and strings not belonging to any option.
1858 ***************************************************************************/
1859
1860 bool lp_parameter_is_global(const char *pszParmName)
1861 {
1862         int num = lpcfg_map_parameter(pszParmName);
1863
1864         if (num >= 0) {
1865                 return (parm_table[num].p_class == P_GLOBAL);
1866         }
1867
1868         return false;
1869 }
1870
1871 /**************************************************************************
1872  Check whether the given name is the canonical name of a parameter.
1873  Returns false if it is not a valid parameter Name.
1874  For parametric options, true is returned.
1875 **************************************************************************/
1876
1877 bool lp_parameter_is_canonical(const char *parm_name)
1878 {
1879         if (!lp_parameter_is_valid(parm_name)) {
1880                 return false;
1881         }
1882
1883         return (lpcfg_map_parameter(parm_name) ==
1884                 map_parameter_canonical(parm_name, NULL));
1885 }
1886
1887 /**************************************************************************
1888  Determine the canonical name for a parameter.
1889  Indicate when it is an inverse (boolean) synonym instead of a
1890  "usual" synonym.
1891 **************************************************************************/
1892
1893 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1894                                bool *inverse)
1895 {
1896         int num;
1897
1898         if (!lp_parameter_is_valid(parm_name)) {
1899                 *canon_parm = NULL;
1900                 return false;
1901         }
1902
1903         num = map_parameter_canonical(parm_name, inverse);
1904         if (num < 0) {
1905                 /* parametric option */
1906                 *canon_parm = parm_name;
1907         } else {
1908                 *canon_parm = parm_table[num].label;
1909         }
1910
1911         return true;
1912
1913 }
1914
1915 /**************************************************************************
1916  Determine the canonical name for a parameter.
1917  Turn the value given into the inverse boolean expression when
1918  the synonym is an invers boolean synonym.
1919
1920  Return true if parm_name is a valid parameter name and
1921  in case it is an invers boolean synonym, if the val string could
1922  successfully be converted to the reverse bool.
1923  Return false in all other cases.
1924 **************************************************************************/
1925
1926 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1927                                           const char *val,
1928                                           const char **canon_parm,
1929                                           const char **canon_val)
1930 {
1931         int num;
1932         bool inverse;
1933
1934         if (!lp_parameter_is_valid(parm_name)) {
1935                 *canon_parm = NULL;
1936                 *canon_val = NULL;
1937                 return false;
1938         }
1939
1940         num = map_parameter_canonical(parm_name, &inverse);
1941         if (num < 0) {
1942                 /* parametric option */
1943                 *canon_parm = parm_name;
1944                 *canon_val = val;
1945         } else {
1946                 *canon_parm = parm_table[num].label;
1947                 if (inverse) {
1948                         if (!lp_invert_boolean(val, canon_val)) {
1949                                 *canon_val = NULL;
1950                                 return false;
1951                         }
1952                 } else {
1953                         *canon_val = val;
1954                 }
1955         }
1956
1957         return true;
1958 }
1959
1960 /***************************************************************************
1961  Map a parameter's string representation to the index of the canonical
1962  form of the parameter (it might be a synonym).
1963  Returns -1 if the parameter string is not recognised.
1964 ***************************************************************************/
1965
1966 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1967 {
1968         int parm_num, canon_num;
1969         bool loc_inverse = false;
1970
1971         parm_num = lpcfg_map_parameter(pszParmName);
1972         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
1973                 /* invalid, parametric or no canidate for synonyms ... */
1974                 goto done;
1975         }
1976
1977         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1978                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1979                         parm_num = canon_num;
1980                         goto done;
1981                 }
1982         }
1983
1984 done:
1985         if (inverse != NULL) {
1986                 *inverse = loc_inverse;
1987         }
1988         return parm_num;
1989 }
1990
1991 /***************************************************************************
1992  return true if parameter number parm1 is a synonym of parameter
1993  number parm2 (parm2 being the principal name).
1994  set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1995  false otherwise.
1996 ***************************************************************************/
1997
1998 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1999 {
2000         if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
2001             (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
2002             (parm_table[parm1].flags & FLAG_HIDE) &&
2003             !(parm_table[parm2].flags & FLAG_HIDE))
2004         {
2005                 if (inverse != NULL) {
2006                         if ((parm_table[parm1].type == P_BOOLREV) &&
2007                             (parm_table[parm2].type == P_BOOL))
2008                         {
2009                                 *inverse = true;
2010                         } else {
2011                                 *inverse = false;
2012                         }
2013                 }
2014                 return true;
2015         }
2016         return false;
2017 }
2018
2019 /***************************************************************************
2020  Show one parameter's name, type, [values,] and flags.
2021  (helper functions for show_parameter_list)
2022 ***************************************************************************/
2023
2024 static void show_parameter(int parmIndex)
2025 {
2026         int enumIndex, flagIndex;
2027         int parmIndex2;
2028         bool hadFlag;
2029         bool hadSyn;
2030         bool inverse;
2031         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2032                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
2033                 "P_ENUM", "P_SEP"};
2034         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2035                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2036                 FLAG_HIDE};
2037         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2038                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2039                 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
2040
2041         printf("%s=%s", parm_table[parmIndex].label,
2042                type[parm_table[parmIndex].type]);
2043         if (parm_table[parmIndex].type == P_ENUM) {
2044                 printf(",");
2045                 for (enumIndex=0;
2046                      parm_table[parmIndex].enum_list[enumIndex].name;
2047                      enumIndex++)
2048                 {
2049                         printf("%s%s",
2050                                enumIndex ? "|" : "",
2051                                parm_table[parmIndex].enum_list[enumIndex].name);
2052                 }
2053         }
2054         printf(",");
2055         hadFlag = false;
2056         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
2057                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2058                         printf("%s%s",
2059                                 hadFlag ? "|" : "",
2060                                 flag_names[flagIndex]);
2061                         hadFlag = true;
2062                 }
2063         }
2064
2065         /* output synonyms */
2066         hadSyn = false;
2067         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
2068                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
2069                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
2070                                parm_table[parmIndex2].label);
2071                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
2072                         if (!hadSyn) {
2073                                 printf(" (synonyms: ");
2074                                 hadSyn = true;
2075                         } else {
2076                                 printf(", ");
2077                         }
2078                         printf("%s%s", parm_table[parmIndex2].label,
2079                                inverse ? "[i]" : "");
2080                 }
2081         }
2082         if (hadSyn) {
2083                 printf(")");
2084         }
2085
2086         printf("\n");
2087 }
2088
2089 /***************************************************************************
2090  Show all parameter's name, type, [values,] and flags.
2091 ***************************************************************************/
2092
2093 void show_parameter_list(void)
2094 {
2095         int classIndex, parmIndex;
2096         const char *section_names[] = { "local", "global", NULL};
2097
2098         for (classIndex=0; section_names[classIndex]; classIndex++) {
2099                 printf("[%s]\n", section_names[classIndex]);
2100                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2101                         if (parm_table[parmIndex].p_class == classIndex) {
2102                                 show_parameter(parmIndex);
2103                         }
2104                 }
2105         }
2106 }
2107
2108 /***************************************************************************
2109  Check if a given string correctly represents a boolean value.
2110 ***************************************************************************/
2111
2112 bool lp_string_is_valid_boolean(const char *parm_value)
2113 {
2114         return set_boolean(parm_value, NULL);
2115 }
2116
2117 /***************************************************************************
2118  Get the standard string representation of a boolean value ("yes" or "no")
2119 ***************************************************************************/
2120
2121 static const char *get_boolean(bool bool_value)
2122 {
2123         static const char *yes_str = "yes";
2124         static const char *no_str = "no";
2125
2126         return (bool_value ? yes_str : no_str);
2127 }
2128
2129 /***************************************************************************
2130  Provide the string of the negated boolean value associated to the boolean
2131  given as a string. Returns false if the passed string does not correctly
2132  represent a boolean.
2133 ***************************************************************************/
2134
2135 bool lp_invert_boolean(const char *str, const char **inverse_str)
2136 {
2137         bool val;
2138
2139         if (!set_boolean(str, &val)) {
2140                 return false;
2141         }
2142
2143         *inverse_str = get_boolean(!val);
2144         return true;
2145 }
2146
2147 /***************************************************************************
2148  Provide the canonical string representation of a boolean value given
2149  as a string. Return true on success, false if the string given does
2150  not correctly represent a boolean.
2151 ***************************************************************************/
2152
2153 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2154 {
2155         bool val;
2156
2157         if (!set_boolean(str, &val)) {
2158                 return false;
2159         }
2160
2161         *canon_str = get_boolean(val);
2162         return true;
2163 }
2164
2165 /***************************************************************************
2166 Find a service by name. Otherwise works like get_service.
2167 ***************************************************************************/
2168
2169 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2170 {
2171         int iService = -1;
2172         char *canon_name;
2173         TDB_DATA data;
2174         NTSTATUS status;
2175
2176         if (ServiceHash == NULL) {
2177                 return -1;
2178         }
2179
2180         canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2181
2182         status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2183                                        &data);
2184
2185         if (NT_STATUS_IS_OK(status) &&
2186             (data.dptr != NULL) &&
2187             (data.dsize == sizeof(iService)))
2188         {
2189                 iService = *(int *)data.dptr;
2190         }
2191
2192         TALLOC_FREE(canon_name);
2193
2194         if ((iService != -1) && (LP_SNUM_OK(iService))
2195             && (pserviceDest != NULL)) {
2196                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2197         }
2198
2199         return (iService);
2200 }
2201
2202 /* Return a pointer to a service by name.  Unlike getservicebyname, it does not copy the service */
2203 struct loadparm_service *lp_service(const char *pszServiceName)
2204 {
2205         int iService = getservicebyname(pszServiceName, NULL);
2206         if (iService == -1 || !LP_SNUM_OK(iService)) {
2207                 return NULL;
2208         }
2209         return ServicePtrs[iService];
2210 }
2211
2212 struct loadparm_service *lp_servicebynum(int snum)
2213 {
2214         if ((snum == -1) || !LP_SNUM_OK(snum)) {
2215                 return NULL;
2216         }
2217         return ServicePtrs[snum];
2218 }
2219
2220 struct loadparm_service *lp_default_loadparm_service()
2221 {
2222         return &sDefault;
2223 }
2224
2225
2226 /***************************************************************************
2227  Copy a service structure to another.
2228  If pcopymapDest is NULL then copy all fields
2229 ***************************************************************************/
2230
2231 /**
2232  * Add a parametric option to a parmlist_entry,
2233  * replacing old value, if already present.
2234  */
2235 static void set_param_opt(struct parmlist_entry **opt_list,
2236                           const char *opt_name,
2237                           const char *opt_value,
2238                           unsigned priority)
2239 {
2240         struct parmlist_entry *new_opt, *opt;
2241         bool not_added;
2242
2243         opt = *opt_list;
2244         not_added = true;
2245
2246         /* Traverse destination */
2247         while (opt) {
2248                 /* If we already have same option, override it */
2249                 if (strwicmp(opt->key, opt_name) == 0) {
2250                         if ((opt->priority & FLAG_CMDLINE) &&
2251                             !(priority & FLAG_CMDLINE)) {
2252                                 /* it's been marked as not to be
2253                                    overridden */
2254                                 return;
2255                         }
2256                         string_free(&opt->value);
2257                         TALLOC_FREE(opt->list);
2258                         opt->value = SMB_STRDUP(opt_value);
2259                         opt->priority = priority;
2260                         not_added = false;
2261                         break;
2262                 }
2263                 opt = opt->next;
2264         }
2265         if (not_added) {
2266             new_opt = SMB_XMALLOC_P(struct parmlist_entry);
2267             new_opt->key = SMB_STRDUP(opt_name);
2268             new_opt->value = SMB_STRDUP(opt_value);
2269             new_opt->list = NULL;
2270             new_opt->priority = priority;
2271             DLIST_ADD(*opt_list, new_opt);
2272         }
2273 }
2274
2275 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
2276                          struct bitmap *pcopymapDest)
2277 {
2278         int i;
2279         bool bcopyall = (pcopymapDest == NULL);
2280         struct parmlist_entry *data;
2281
2282         for (i = 0; parm_table[i].label; i++)
2283                 if (parm_table[i].p_class == P_LOCAL &&
2284                     (bcopyall || bitmap_query(pcopymapDest,i))) {
2285                         void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
2286                         void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
2287
2288                         switch (parm_table[i].type) {
2289                                 case P_BOOL:
2290                                 case P_BOOLREV:
2291                                         *(bool *)dest_ptr = *(bool *)src_ptr;
2292                                         break;
2293
2294                                 case P_INTEGER:
2295                                 case P_ENUM:
2296                                 case P_OCTAL:
2297                                 case P_BYTES:
2298                                         *(int *)dest_ptr = *(int *)src_ptr;
2299                                         break;
2300
2301                                 case P_CHAR:
2302                                         *(char *)dest_ptr = *(char *)src_ptr;
2303                                         break;
2304
2305                                 case P_STRING:
2306                                         string_set((char **)dest_ptr,
2307                                                    *(char **)src_ptr);
2308                                         break;
2309
2310                                 case P_USTRING:
2311                                 {
2312                                         char *upper_string = strupper_talloc(talloc_tos(), 
2313                                                                              *(char **)src_ptr);
2314                                         string_set((char **)dest_ptr,
2315                                                    upper_string);
2316                                         TALLOC_FREE(upper_string);
2317                                         break;
2318                                 }
2319                                 case P_LIST:
2320                                         TALLOC_FREE(*((char ***)dest_ptr));
2321                                         *((char ***)dest_ptr) = str_list_copy(NULL, 
2322                                                       *(const char ***)src_ptr);
2323                                         break;
2324                                 default:
2325                                         break;
2326                         }
2327                 }
2328
2329         if (bcopyall) {
2330                 init_copymap(pserviceDest);
2331                 if (pserviceSource->copymap)
2332                         bitmap_copy(pserviceDest->copymap,
2333                                     pserviceSource->copymap);
2334         }
2335
2336         data = pserviceSource->param_opt;
2337         while (data) {
2338                 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
2339                 data = data->next;
2340         }
2341 }
2342
2343 /***************************************************************************
2344 Check a service for consistency. Return false if the service is in any way
2345 incomplete or faulty, else true.
2346 ***************************************************************************/
2347
2348 bool service_ok(int iService)
2349 {
2350         bool bRetval;
2351
2352         bRetval = true;
2353         if (ServicePtrs[iService]->szService[0] == '\0') {
2354                 DEBUG(0, ("The following message indicates an internal error:\n"));
2355                 DEBUG(0, ("No service name in service entry.\n"));
2356                 bRetval = false;
2357         }
2358
2359         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2360         /* I can't see why you'd want a non-printable printer service...        */
2361         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2362                 if (!ServicePtrs[iService]->printable) {
2363                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2364                                ServicePtrs[iService]->szService));
2365                         ServicePtrs[iService]->printable = true;
2366                 }
2367                 /* [printers] service must also be non-browsable. */
2368                 if (ServicePtrs[iService]->browseable)
2369                         ServicePtrs[iService]->browseable = false;
2370         }
2371
2372         if (ServicePtrs[iService]->path[0] == '\0' &&
2373             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2374             ServicePtrs[iService]->msdfs_proxy[0] == '\0'
2375             ) {
2376                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2377                         ServicePtrs[iService]->szService));
2378                 ServicePtrs[iService]->bAvailable = false;
2379         }
2380
2381         /* If a service is flagged unavailable, log the fact at level 1. */
2382         if (!ServicePtrs[iService]->bAvailable)
2383                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2384                           ServicePtrs[iService]->szService));
2385
2386         return (bRetval);
2387 }
2388
2389 static struct smbconf_ctx *lp_smbconf_ctx(void)
2390 {
2391         sbcErr err;
2392         static struct smbconf_ctx *conf_ctx = NULL;
2393
2394         if (conf_ctx == NULL) {
2395                 err = smbconf_init(NULL, &conf_ctx, "registry:");
2396                 if (!SBC_ERROR_IS_OK(err)) {
2397                         DEBUG(1, ("error initializing registry configuration: "
2398                                   "%s\n", sbcErrorString(err)));
2399                         conf_ctx = NULL;
2400                 }
2401         }
2402
2403         return conf_ctx;
2404 }
2405
2406 static bool process_smbconf_service(struct smbconf_service *service)
2407 {
2408         uint32_t count;
2409         bool ret;
2410
2411         if (service == NULL) {
2412                 return false;
2413         }
2414
2415         ret = do_section(service->name, NULL);
2416         if (ret != true) {
2417                 return false;
2418         }
2419         for (count = 0; count < service->num_params; count++) {
2420                 ret = do_parameter(service->param_names[count],
2421                                    service->param_values[count],
2422                                    NULL);
2423                 if (ret != true) {
2424                         return false;
2425                 }
2426         }
2427         if (iServiceIndex >= 0) {
2428                 return service_ok(iServiceIndex);
2429         }
2430         return true;
2431 }
2432
2433 /**
2434  * load a service from registry and activate it
2435  */
2436 bool process_registry_service(const char *service_name)
2437 {
2438         sbcErr err;
2439         struct smbconf_service *service = NULL;
2440         TALLOC_CTX *mem_ctx = talloc_stackframe();
2441         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2442         bool ret = false;
2443
2444         if (conf_ctx == NULL) {
2445                 goto done;
2446         }
2447
2448         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2449
2450         if (!smbconf_share_exists(conf_ctx, service_name)) {
2451                 /*
2452                  * Registry does not contain data for this service (yet),
2453                  * but make sure lp_load doesn't return false.
2454                  */
2455                 ret = true;
2456                 goto done;
2457         }
2458
2459         err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2460         if (!SBC_ERROR_IS_OK(err)) {
2461                 goto done;
2462         }
2463
2464         ret = process_smbconf_service(service);
2465         if (!ret) {
2466                 goto done;
2467         }
2468
2469         /* store the csn */
2470         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2471
2472 done:
2473         TALLOC_FREE(mem_ctx);
2474         return ret;
2475 }
2476
2477 /*
2478  * process_registry_globals
2479  */
2480 static bool process_registry_globals(void)
2481 {
2482         bool ret;
2483
2484         add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2485
2486         ret = do_parameter("registry shares", "yes", NULL);
2487         if (!ret) {
2488                 return ret;
2489         }
2490
2491         return process_registry_service(GLOBAL_NAME);
2492 }
2493
2494 bool process_registry_shares(void)
2495 {
2496         sbcErr err;
2497         uint32_t count;
2498         struct smbconf_service **service = NULL;
2499         uint32_t num_shares = 0;
2500         TALLOC_CTX *mem_ctx = talloc_stackframe();
2501         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2502         bool ret = false;
2503
2504         if (conf_ctx == NULL) {
2505                 goto done;
2506         }
2507
2508         err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2509         if (!SBC_ERROR_IS_OK(err)) {
2510                 goto done;
2511         }
2512
2513         ret = true;
2514
2515         for (count = 0; count < num_shares; count++) {
2516                 if (strequal(service[count]->name, GLOBAL_NAME)) {
2517                         continue;
2518                 }
2519                 ret = process_smbconf_service(service[count]);
2520                 if (!ret) {
2521                         goto done;
2522                 }
2523         }
2524
2525         /* store the csn */
2526         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2527
2528 done:
2529         TALLOC_FREE(mem_ctx);
2530         return ret;
2531 }
2532
2533 /**
2534  * reload those shares from registry that are already
2535  * activated in the services array.
2536  */
2537 static bool reload_registry_shares(void)
2538 {
2539         int i;
2540         bool ret = true;
2541
2542         for (i = 0; i < iNumServices; i++) {
2543                 if (!VALID(i)) {
2544                         continue;
2545                 }
2546
2547                 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2548                         continue;
2549                 }
2550
2551                 ret = process_registry_service(ServicePtrs[i]->szService);
2552                 if (!ret) {
2553                         goto done;
2554                 }
2555         }
2556
2557 done:
2558         return ret;
2559 }
2560
2561
2562 #define MAX_INCLUDE_DEPTH 100
2563
2564 static uint8_t include_depth;
2565
2566 static struct file_lists {
2567         struct file_lists *next;
2568         char *name;
2569         char *subfname;
2570         time_t modtime;
2571 } *file_lists = NULL;
2572
2573 /*******************************************************************
2574  Keep a linked list of all config files so we know when one has changed 
2575  it's date and needs to be reloaded.
2576 ********************************************************************/
2577
2578 static void add_to_file_list(const char *fname, const char *subfname)
2579 {
2580         struct file_lists *f = file_lists;
2581
2582         while (f) {
2583                 if (f->name && !strcmp(f->name, fname))
2584                         break;
2585                 f = f->next;
2586         }
2587
2588         if (!f) {
2589                 f = SMB_MALLOC_P(struct file_lists);
2590                 if (!f)
2591                         return;
2592                 f->next = file_lists;
2593                 f->name = SMB_STRDUP(fname);
2594                 if (!f->name) {
2595                         SAFE_FREE(f);
2596                         return;
2597                 }
2598                 f->subfname = SMB_STRDUP(subfname);
2599                 if (!f->subfname) {
2600                         SAFE_FREE(f->name);
2601                         SAFE_FREE(f);
2602                         return;
2603                 }
2604                 file_lists = f;
2605                 f->modtime = file_modtime(subfname);
2606         } else {
2607                 time_t t = file_modtime(subfname);
2608                 if (t)
2609                         f->modtime = t;
2610         }
2611         return;
2612 }
2613
2614 /**
2615  * Free the file lists
2616  */
2617 static void free_file_list(void)
2618 {
2619         struct file_lists *f;
2620         struct file_lists *next;
2621
2622         f = file_lists;
2623         while( f ) {
2624                 next = f->next;
2625                 SAFE_FREE( f->name );
2626                 SAFE_FREE( f->subfname );
2627                 SAFE_FREE( f );
2628                 f = next;
2629         }
2630         file_lists = NULL;
2631 }
2632
2633
2634 /**
2635  * Utility function for outsiders to check if we're running on registry.
2636  */
2637 bool lp_config_backend_is_registry(void)
2638 {
2639         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2640 }
2641
2642 /**
2643  * Utility function to check if the config backend is FILE.
2644  */
2645 bool lp_config_backend_is_file(void)
2646 {
2647         return (lp_config_backend() == CONFIG_BACKEND_FILE);
2648 }
2649
2650 /*******************************************************************
2651  Check if a config file has changed date.
2652 ********************************************************************/
2653
2654 bool lp_file_list_changed(void)
2655 {
2656         struct file_lists *f = file_lists;
2657
2658         DEBUG(6, ("lp_file_list_changed()\n"));
2659
2660         while (f) {
2661                 time_t mod_time;
2662
2663                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2664                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2665
2666                         if (conf_ctx == NULL) {
2667                                 return false;
2668                         }
2669                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2670                                             NULL))
2671                         {
2672                                 DEBUGADD(6, ("registry config changed\n"));
2673                                 return true;
2674                         }
2675                 } else {
2676                         char *n2 = NULL;
2677                         n2 = talloc_sub_basic(talloc_tos(),
2678                                               get_current_username(),
2679                                               current_user_info.domain,
2680                                               f->name);
2681                         if (!n2) {
2682                                 return false;
2683                         }
2684                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2685                                      f->name, n2, ctime(&f->modtime)));
2686
2687                         mod_time = file_modtime(n2);
2688
2689                         if (mod_time &&
2690                             ((f->modtime != mod_time) ||
2691                              (f->subfname == NULL) ||
2692                              (strcmp(n2, f->subfname) != 0)))
2693                         {
2694                                 DEBUGADD(6,
2695                                          ("file %s modified: %s\n", n2,
2696                                           ctime(&mod_time)));
2697                                 f->modtime = mod_time;
2698                                 SAFE_FREE(f->subfname);
2699                                 f->subfname = SMB_STRDUP(n2);
2700                                 TALLOC_FREE(n2);
2701                                 return true;
2702                         }
2703                         TALLOC_FREE(n2);
2704                 }
2705                 f = f->next;
2706         }
2707         return false;
2708 }
2709
2710
2711 /**
2712  * Initialize iconv conversion descriptors.
2713  *
2714  * This is called the first time it is needed, and also called again
2715  * every time the configuration is reloaded, because the charset or
2716  * codepage might have changed.
2717  **/
2718 static void init_iconv(void)
2719 {
2720         global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2721                                                       lp_unix_charset(),
2722                                                       true, global_iconv_handle);
2723 }
2724
2725 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2726 {
2727         if (strcmp(*ptr, pszParmValue) != 0) {
2728                 string_set(ptr, pszParmValue);
2729                 init_iconv();
2730         }
2731         return true;
2732 }
2733
2734 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2735 {
2736         bool is_utf8 = false;
2737         size_t len = strlen(pszParmValue);
2738
2739         if (len == 4 || len == 5) {
2740                 /* Don't use StrCaseCmp here as we don't want to
2741                    initialize iconv. */
2742                 if ((toupper_m(pszParmValue[0]) == 'U') &&
2743                     (toupper_m(pszParmValue[1]) == 'T') &&
2744                     (toupper_m(pszParmValue[2]) == 'F')) {
2745                         if (len == 4) {
2746                                 if (pszParmValue[3] == '8') {
2747                                         is_utf8 = true;
2748                                 }
2749                         } else {
2750                                 if (pszParmValue[3] == '-' &&
2751                                     pszParmValue[4] == '8') {
2752                                         is_utf8 = true;
2753                                 }
2754                         }
2755                 }
2756         }
2757
2758         if (strcmp(*ptr, pszParmValue) != 0) {
2759                 if (is_utf8) {
2760                         DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2761                                 "be UTF8, using (default value) %s instead.\n",
2762                                 DEFAULT_DOS_CHARSET));
2763                         pszParmValue = DEFAULT_DOS_CHARSET;
2764                 }
2765                 string_set(ptr, pszParmValue);
2766                 init_iconv();
2767         }
2768         return true;
2769 }
2770
2771 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2772 {
2773         bool ret = true;
2774         TALLOC_CTX *frame = talloc_stackframe();
2775         char *realm = strupper_talloc(frame, pszParmValue);
2776         char *dnsdomain = strlower_talloc(realm, pszParmValue);
2777
2778         ret &= string_set(&Globals.realm_original, pszParmValue);
2779         ret &= string_set(&Globals.realm, realm);
2780         ret &= string_set(&Globals.dnsdomain, dnsdomain);
2781         TALLOC_FREE(frame);
2782
2783         return ret;
2784 }
2785
2786 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2787 {
2788         TALLOC_FREE(Globals.netbios_aliases);
2789         Globals.netbios_aliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
2790         return set_netbios_aliases(Globals.netbios_aliases);
2791 }
2792
2793 /***************************************************************************
2794  Handle the include operation.
2795 ***************************************************************************/
2796 static bool bAllowIncludeRegistry = true;
2797
2798 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2799 {
2800         char *fname;
2801
2802         if (include_depth >= MAX_INCLUDE_DEPTH) {
2803                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2804                           include_depth));
2805                 return false;
2806         }
2807
2808         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2809                 if (!bAllowIncludeRegistry) {
2810                         return true;
2811                 }
2812                 if (bInGlobalSection) {
2813                         bool ret;
2814                         include_depth++;
2815                         ret = process_registry_globals();
2816                         include_depth--;
2817                         return ret;
2818                 } else {
2819                         DEBUG(1, ("\"include = registry\" only effective "
2820                                   "in %s section\n", GLOBAL_NAME));
2821                         return false;
2822                 }
2823         }
2824
2825         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2826                                  current_user_info.domain,
2827                                  pszParmValue);
2828
2829         add_to_file_list(pszParmValue, fname);
2830
2831         string_set(ptr, fname);
2832
2833         if (file_exist(fname)) {
2834                 bool ret;
2835                 include_depth++;
2836                 ret = pm_process(fname, do_section, do_parameter, NULL);
2837                 include_depth--;
2838                 TALLOC_FREE(fname);
2839                 return ret;
2840         }
2841
2842         DEBUG(2, ("Can't find include file %s\n", fname));
2843         TALLOC_FREE(fname);
2844         return true;
2845 }
2846
2847 /***************************************************************************
2848  Handle the interpretation of the copy parameter.
2849 ***************************************************************************/
2850
2851 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2852 {
2853         bool bRetval;
2854         int iTemp;
2855         struct loadparm_service serviceTemp;
2856
2857         string_set(ptr, pszParmValue);
2858
2859         init_service(&serviceTemp);
2860
2861         bRetval = false;
2862
2863         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2864
2865         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2866                 if (iTemp == iServiceIndex) {
2867                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2868                 } else {
2869                         copy_service(ServicePtrs[iServiceIndex],
2870                                      &serviceTemp,
2871                                      ServicePtrs[iServiceIndex]->copymap);
2872                         bRetval = true;
2873                 }
2874         } else {
2875                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2876                 bRetval = false;
2877         }
2878
2879         free_service(&serviceTemp);
2880         return (bRetval);
2881 }
2882
2883 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2884 {
2885         Globals.ldap_debug_level = lp_int(pszParmValue);
2886         init_ldap_debugging();
2887         return true;
2888 }
2889
2890 /*
2891  * idmap related parameters
2892  */
2893
2894 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2895 {
2896         lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
2897
2898         return true;
2899 }
2900
2901 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2902 {
2903         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2904
2905         return true;
2906 }
2907
2908 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2909 {
2910         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2911
2912         return true;
2913 }
2914
2915 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2916 {
2917         char *config_option = NULL;
2918         const char *range = NULL;
2919         bool ret = false;
2920
2921         SMB_ASSERT(low != NULL);
2922         SMB_ASSERT(high != NULL);
2923
2924         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2925                 domain_name = "*";
2926         }
2927
2928         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2929                                         domain_name);
2930         if (config_option == NULL) {
2931                 DEBUG(0, ("out of memory\n"));
2932                 return false;
2933         }
2934
2935         range = lp_parm_const_string(-1, config_option, "range", NULL);
2936         if (range == NULL) {
2937                 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2938                 goto done;
2939         }
2940
2941         if (sscanf(range, "%u - %u", low, high) != 2) {
2942                 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2943                           range, domain_name));
2944                 goto done;
2945         }
2946
2947         ret = true;
2948
2949 done:
2950         talloc_free(config_option);
2951         return ret;
2952
2953 }
2954
2955 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2956 {
2957         return lp_idmap_range("*", low, high);
2958 }
2959
2960 const char *lp_idmap_backend(const char *domain_name)
2961 {
2962         char *config_option = NULL;
2963         const char *backend = NULL;
2964
2965         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2966                 domain_name = "*";
2967         }
2968
2969         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2970                                         domain_name);
2971         if (config_option == NULL) {
2972                 DEBUG(0, ("out of memory\n"));
2973                 return false;
2974         }
2975
2976         backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2977         if (backend == NULL) {
2978                 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2979                 goto done;
2980         }
2981
2982 done:
2983         talloc_free(config_option);
2984         return backend;
2985 }
2986
2987 const char *lp_idmap_default_backend(void)
2988 {
2989         return lp_idmap_backend("*");
2990 }
2991
2992 /***************************************************************************
2993  Handle the DEBUG level list.
2994 ***************************************************************************/
2995
2996 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
2997 {
2998         string_set(ptr, pszParmValueIn);
2999         return debug_parse_levels(pszParmValueIn);
3000 }
3001
3002 /***************************************************************************
3003  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3004 ***************************************************************************/
3005
3006 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
3007 {
3008         const char *suffix_string;
3009
3010         suffix_string = talloc_asprintf(ctx, "%s,%s", str,
3011                                         Globals.ldap_suffix );
3012         if ( !suffix_string ) {
3013                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3014                 return "";
3015         }
3016
3017         return suffix_string;
3018 }
3019
3020 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
3021 {
3022         if (Globals.szLdapMachineSuffix[0])
3023                 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
3024
3025         return lp_string(ctx, Globals.ldap_suffix);
3026 }
3027
3028 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
3029 {
3030         if (Globals.szLdapUserSuffix[0])
3031                 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
3032
3033         return lp_string(ctx, Globals.ldap_suffix);
3034 }
3035
3036 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
3037 {
3038         if (Globals.szLdapGroupSuffix[0])
3039                 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
3040
3041         return lp_string(ctx, Globals.ldap_suffix);
3042 }
3043
3044 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
3045 {
3046         if (Globals.szLdapIdmapSuffix[0])
3047                 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
3048
3049         return lp_string(ctx, Globals.ldap_suffix);
3050 }
3051
3052 /****************************************************************************
3053  set the value for a P_ENUM
3054  ***************************************************************************/
3055
3056 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3057                               int *ptr )
3058 {
3059         int i;
3060
3061         for (i = 0; parm->enum_list[i].name; i++) {
3062                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3063                         *ptr = parm->enum_list[i].value;
3064                         return;
3065                 }
3066         }
3067         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
3068                   pszParmValue, parm->label));
3069 }
3070
3071 /***************************************************************************
3072 ***************************************************************************/
3073
3074 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
3075 {
3076         static int parm_num = -1;
3077         struct loadparm_service *s;
3078
3079         if ( parm_num == -1 )
3080                 parm_num = lpcfg_map_parameter( "printing" );
3081
3082         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3083
3084         if ( snum < 0 )
3085                 s = &sDefault;
3086         else
3087                 s = ServicePtrs[snum];
3088
3089         init_printer_values( s );
3090
3091         return true;
3092 }
3093
3094
3095 /***************************************************************************
3096  Initialise a copymap.
3097 ***************************************************************************/
3098
3099 static void init_copymap(struct loadparm_service *pservice)
3100 {
3101         int i;
3102
3103         TALLOC_FREE(pservice->copymap);
3104
3105         pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
3106         if (!pservice->copymap)
3107                 DEBUG(0,
3108                       ("Couldn't allocate copymap!! (size %d)\n",
3109                        (int)NUMPARAMETERS));
3110         else
3111                 for (i = 0; i < NUMPARAMETERS; i++)
3112                         bitmap_set(pservice->copymap, i);
3113 }
3114
3115 /**
3116   return the parameter pointer for a parameter
3117 */
3118 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
3119 {
3120         if (service == NULL) {
3121                 if (parm->p_class == P_LOCAL)
3122                         return (void *)(((char *)&sDefault)+parm->offset);
3123                 else if (parm->p_class == P_GLOBAL)
3124                         return (void *)(((char *)&Globals)+parm->offset);
3125                 else return NULL;
3126         } else {
3127                 return (void *)(((char *)service) + parm->offset);
3128         }
3129 }
3130
3131 /***************************************************************************
3132  Return the local pointer to a parameter given the service number and parameter
3133 ***************************************************************************/
3134
3135 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
3136 {
3137         return lp_parm_ptr(ServicePtrs[snum], parm);
3138 }
3139
3140 /***************************************************************************
3141  Process a parameter for a particular service number. If snum < 0
3142  then assume we are in the globals.
3143 ***************************************************************************/
3144
3145 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3146 {
3147         int parmnum, i;
3148         void *parm_ptr = NULL;  /* where we are going to store the result */
3149         struct parmlist_entry **opt_list;
3150
3151         parmnum = lpcfg_map_parameter(pszParmName);
3152
3153         if (parmnum < 0) {
3154                 if (strchr(pszParmName, ':') == NULL) {
3155                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
3156                                   pszParmName));
3157                         return true;
3158                 }
3159
3160                 /*
3161                  * We've got a parametric option
3162                  */
3163
3164                 opt_list = (snum < 0)
3165                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
3166                 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
3167
3168                 return true;
3169         }
3170
3171         /* if it's already been set by the command line, then we don't
3172            override here */
3173         if (parm_table[parmnum].flags & FLAG_CMDLINE) {
3174                 return true;
3175         }
3176
3177         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3178                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3179                           pszParmName));
3180         }
3181
3182         /* we might point at a service, the default service or a global */
3183         if (snum < 0) {
3184                 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
3185         } else {
3186                 if (parm_table[parmnum].p_class == P_GLOBAL) {
3187                         DEBUG(0,
3188                               ("Global parameter %s found in service section!\n",
3189                                pszParmName));
3190                         return true;
3191                 }
3192                 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
3193         }
3194
3195         if (snum >= 0) {
3196                 if (!ServicePtrs[snum]->copymap)
3197                         init_copymap(ServicePtrs[snum]);
3198
3199                 /* this handles the aliases - set the copymap for other entries with
3200                    the same data pointer */
3201                 for (i = 0; parm_table[i].label; i++) {
3202                         if ((parm_table[i].offset == parm_table[parmnum].offset)
3203                             && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
3204                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
3205                         }
3206                 }
3207         }
3208
3209         /* if it is a special case then go ahead */
3210         if (parm_table[parmnum].special) {
3211                 return parm_table[parmnum].special(NULL, snum, pszParmValue,
3212                                                    (char **)parm_ptr);
3213         }
3214
3215         /* now switch on the type of variable it is */
3216         switch (parm_table[parmnum].type)
3217         {
3218                 case P_BOOL:
3219                         *(bool *)parm_ptr = lp_bool(pszParmValue);
3220                         break;
3221
3222                 case P_BOOLREV:
3223                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
3224                         break;
3225
3226                 case P_INTEGER:
3227                         *(int *)parm_ptr = lp_int(pszParmValue);
3228                         break;
3229
3230                 case P_CHAR:
3231                         *(char *)parm_ptr = *pszParmValue;
3232                         break;
3233
3234                 case P_OCTAL:
3235                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3236                         if ( i != 1 ) {
3237                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3238                         }
3239                         break;
3240
3241                 case P_BYTES:
3242                 {
3243                         uint64_t val;
3244                         if (conv_str_size_error(pszParmValue, &val)) {
3245                                 if (val <= INT_MAX) {
3246                                         *(int *)parm_ptr = (int)val;
3247                                         break;
3248                                 }
3249                         }
3250
3251                         DEBUG(0,("lp_do_parameter(%s): value is not "
3252                             "a valid size specifier!\n", pszParmValue));
3253                         return false;
3254                 }
3255
3256                 case P_LIST:
3257                 case P_CMDLIST:
3258                         TALLOC_FREE(*((char ***)parm_ptr));
3259                         *(char ***)parm_ptr = str_list_make_v3(
3260                                 NULL, pszParmValue, NULL);
3261                         break;
3262
3263                 case P_STRING:
3264                         string_set((char **)parm_ptr, pszParmValue);
3265                         break;
3266
3267                 case P_USTRING:
3268                 {
3269                         char *upper_string = strupper_talloc(talloc_tos(), 
3270                                                              pszParmValue);
3271                         string_set((char **)parm_ptr, upper_string);
3272                         TALLOC_FREE(upper_string);
3273                         break;
3274                 }
3275                 case P_ENUM:
3276                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3277                         break;
3278                 case P_SEP:
3279                         break;
3280         }
3281
3282         return true;
3283 }
3284
3285 /***************************************************************************
3286 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
3287 FLAG_CMDLINE won't be overridden by loads from smb.conf.
3288 ***************************************************************************/
3289
3290 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
3291 {
3292         int parmnum, i;
3293         parmnum = lpcfg_map_parameter(pszParmName);
3294         if (parmnum >= 0) {
3295                 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
3296                 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
3297                         return false;
3298                 }
3299                 parm_table[parmnum].flags |= FLAG_CMDLINE;
3300
3301                 /* we have to also set FLAG_CMDLINE on aliases.  Aliases must
3302                  * be grouped in the table, so we don't have to search the
3303                  * whole table */
3304                 for (i=parmnum-1;
3305                      i>=0 && parm_table[i].offset == parm_table[parmnum].offset
3306                              && parm_table[i].p_class == parm_table[parmnum].p_class;
3307                      i--) {
3308                         parm_table[i].flags |= FLAG_CMDLINE;
3309                 }
3310                 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
3311                              && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
3312                         parm_table[i].flags |= FLAG_CMDLINE;
3313                 }
3314
3315                 if (store_values) {
3316                         store_lp_set_cmdline(pszParmName, pszParmValue);
3317                 }
3318                 return true;
3319         }
3320
3321         /* it might be parametric */
3322         if (strchr(pszParmName, ':') != NULL) {
3323                 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
3324                 if (store_values) {
3325                         store_lp_set_cmdline(pszParmName, pszParmValue);
3326                 }
3327                 return true;
3328         }
3329
3330         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
3331         return true;
3332 }
3333
3334 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
3335 {
3336         return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
3337 }
3338
3339 /***************************************************************************
3340  Process a parameter.
3341 ***************************************************************************/
3342
3343 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
3344                          void *userdata)
3345 {
3346         if (!bInGlobalSection && bGlobalOnly)
3347                 return true;
3348
3349         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3350
3351         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3352                                 pszParmName, pszParmValue));
3353 }
3354
3355 /*
3356   set a option from the commandline in 'a=b' format. Use to support --option
3357 */
3358 bool lp_set_option(const char *option)
3359 {
3360         char *p, *s;
3361         bool ret;
3362
3363         s = talloc_strdup(NULL, option);
3364         if (!s) {
3365                 return false;
3366         }
3367
3368         p = strchr(s, '=');
3369         if (!p) {
3370                 talloc_free(s);
3371                 return false;
3372         }
3373
3374         *p = 0;
3375
3376         /* skip white spaces after the = sign */
3377         do {
3378                 p++;
3379         } while (*p == ' ');
3380
3381         ret = lp_set_cmdline(s, p);
3382         talloc_free(s);
3383         return ret;
3384 }
3385
3386 /***************************************************************************
3387  Initialize any local variables in the sDefault table, after parsing a
3388  [globals] section.
3389 ***************************************************************************/
3390
3391 static void init_locals(void)
3392 {
3393         /*
3394          * We run this check once the [globals] is parsed, to force
3395          * the VFS objects and other per-share settings we need for
3396          * the standard way a AD DC is operated.  We may change these
3397          * as our code evolves, which is why we force these settings.
3398          *
3399          * We can't do this at the end of lp_load_ex(), as by that
3400          * point the services have been loaded and they will already
3401          * have "" as their vfs objects.
3402          */
3403         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3404                 const char **vfs_objects = lp_vfs_objects(-1);
3405                 if (!vfs_objects || !vfs_objects[0]) {
3406                         if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
3407                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3408                         } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
3409                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3410                         } else {
3411                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3412                         }
3413                 }
3414
3415                 lp_do_parameter(-1, "map hidden", "no");
3416                 lp_do_parameter(-1, "map system", "no");
3417                 lp_do_parameter(-1, "map readonly", "no");
3418                 lp_do_parameter(-1, "map archive", "no");
3419                 lp_do_parameter(-1, "store dos attributes", "yes");
3420         }
3421 }
3422
3423 /***************************************************************************
3424  Process a new section (service). At this stage all sections are services.
3425  Later we'll have special sections that permit server parameters to be set.
3426  Returns true on success, false on failure.
3427 ***************************************************************************/
3428
3429 static bool do_section(const char *pszSectionName, void *userdata)
3430 {
3431         bool bRetval;
3432         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3433                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3434         bRetval = false;
3435
3436         /* if we were in a global section then do the local inits */
3437         if (bInGlobalSection && !isglobal)
3438                 init_locals();
3439
3440         /* if we've just struck a global section, note the fact. */
3441         bInGlobalSection = isglobal;
3442
3443         /* check for multiple global sections */
3444         if (bInGlobalSection) {
3445                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3446                 return true;
3447         }
3448
3449         if (!bInGlobalSection && bGlobalOnly)
3450                 return true;
3451
3452         /* if we have a current service, tidy it up before moving on */
3453         bRetval = true;
3454
3455         if (iServiceIndex >= 0)
3456                 bRetval = service_ok(iServiceIndex);
3457
3458         /* if all is still well, move to the next record in the services array */
3459         if (bRetval) {
3460                 /* We put this here to avoid an odd message order if messages are */
3461                 /* issued by the post-processing of a previous section. */
3462                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3463
3464                 iServiceIndex = add_a_service(&sDefault, pszSectionName);
3465                 if (iServiceIndex < 0) {
3466                         DEBUG(0, ("Failed to add a new service\n"));
3467                         return false;
3468                 }
3469                 /* Clean all parametric options for service */
3470                 /* They will be added during parsing again */
3471                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
3472         }
3473
3474         return bRetval;
3475 }
3476
3477
3478 /***************************************************************************
3479  Determine if a partcular base parameter is currentl set to the default value.
3480 ***************************************************************************/
3481
3482 static bool is_default(int i)
3483 {
3484         switch (parm_table[i].type) {
3485                 case P_LIST:
3486                 case P_CMDLIST:
3487                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
3488                                               *(const char ***)lp_parm_ptr(NULL, 
3489                                                                            &parm_table[i]));
3490                 case P_STRING:
3491                 case P_USTRING:
3492                         return strequal(parm_table[i].def.svalue,
3493                                         *(char **)lp_parm_ptr(NULL, 
3494                                                               &parm_table[i]));
3495                 case P_BOOL:
3496                 case P_BOOLREV:
3497                         return parm_table[i].def.bvalue ==
3498                                 *(bool *)lp_parm_ptr(NULL, 
3499                                                      &parm_table[i]);
3500                 case P_CHAR:
3501                         return parm_table[i].def.cvalue ==
3502                                 *(char *)lp_parm_ptr(NULL, 
3503                                                      &parm_table[i]);
3504                 case P_INTEGER:
3505                 case P_OCTAL:
3506                 case P_ENUM:
3507                 case P_BYTES:
3508                         return parm_table[i].def.ivalue ==
3509                                 *(int *)lp_parm_ptr(NULL, 
3510                                                     &parm_table[i]);
3511                 case P_SEP:
3512                         break;
3513         }
3514         return false;
3515 }
3516
3517 /***************************************************************************
3518 Display the contents of the global structure.
3519 ***************************************************************************/
3520
3521 static void dump_globals(FILE *f)
3522 {
3523         int i;
3524         struct parmlist_entry *data;
3525
3526         fprintf(f, "[global]\n");
3527
3528         for (i = 0; parm_table[i].label; i++)
3529                 if (parm_table[i].p_class == P_GLOBAL &&
3530                     !(parm_table[i].flags & FLAG_META) &&
3531                     (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
3532                         if (defaults_saved && is_default(i))
3533                                 continue;
3534                         fprintf(f, "\t%s = ", parm_table[i].label);
3535                         lpcfg_print_parameter(&parm_table[i], lp_parm_ptr(NULL,
3536                                                                           &parm_table[i]),
3537                                         f);
3538                         fprintf(f, "\n");
3539         }
3540         if (Globals.param_opt != NULL) {
3541                 data = Globals.param_opt;
3542                 while(data) {
3543                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3544                         data = data->next;
3545                 }
3546         }
3547
3548 }
3549
3550 /***************************************************************************
3551  Display the contents of a single services record.
3552 ***************************************************************************/
3553
3554 static void dump_a_service(struct loadparm_service *pService, FILE * f)
3555 {
3556         int i;
3557         struct parmlist_entry *data;
3558
3559         if (pService != &sDefault)
3560                 fprintf(f, "[%s]\n", pService->szService);
3561
3562         for (i = 0; parm_table[i].label; i++) {
3563
3564                 if (parm_table[i].p_class == P_LOCAL &&
3565                     !(parm_table[i].flags & FLAG_META) &&
3566                     (*parm_table[i].label != '-') &&
3567                     (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) 
3568                 {
3569                         if (pService == &sDefault) {
3570                                 if (defaults_saved && is_default(i))
3571                                         continue;
3572                         } else {
3573                                 if (lpcfg_equal_parameter(parm_table[i].type,
3574                                                           lp_parm_ptr(pService, &parm_table[i]),
3575                                                           lp_parm_ptr(NULL, &parm_table[i])))
3576                                         continue;
3577                         }
3578
3579                         fprintf(f, "\t%s = ", parm_table[i].label);
3580                         lpcfg_print_parameter(&parm_table[i],
3581                                         lp_parm_ptr(pService, &parm_table[i]),
3582                                         f);
3583                         fprintf(f, "\n");
3584                 }
3585         }
3586
3587                 if (pService->param_opt != NULL) {
3588                         data = pService->param_opt;
3589                         while(data) {
3590                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
3591                                 data = data->next;
3592                         }
3593                 }
3594 }
3595
3596 /***************************************************************************
3597  Display the contents of a parameter of a single services record.
3598 ***************************************************************************/
3599
3600 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
3601 {
3602         bool result = false;
3603         fstring local_parm_name;
3604         char *parm_opt;
3605         const char *parm_opt_value;
3606
3607         struct loadparm_context *lp_ctx;
3608
3609         /* check for parametrical option */
3610         fstrcpy( local_parm_name, parm_name);
3611         parm_opt = strchr( local_parm_name, ':');
3612
3613         if (parm_opt) {
3614                 *parm_opt = '\0';
3615                 parm_opt++;
3616                 if (strlen(parm_opt)) {
3617                         parm_opt_value = lp_parm_const_string( snum,
3618                                 local_parm_name, parm_opt, NULL);
3619                         if (parm_opt_value) {
3620                                 printf( "%s\n", parm_opt_value);
3621                                 result = true;
3622                         }
3623                 }
3624                 return result;
3625         }
3626
3627         lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3628         if (lp_ctx == NULL) {
3629                 return false;
3630         }
3631
3632         if (isGlobal) {
3633                 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
3634         } else {
3635                 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
3636         }
3637         TALLOC_FREE(lp_ctx);
3638         return result;
3639 }
3640
3641 /***************************************************************************
3642  Return info about the requested parameter (given as a string).
3643  Return NULL when the string is not a valid parameter name.
3644 ***************************************************************************/
3645
3646 struct parm_struct *lp_get_parameter(const char *param_name)
3647 {
3648         int num = lpcfg_map_parameter(param_name);
3649
3650         if (num < 0) {
3651                 return NULL;
3652         }
3653
3654         return &parm_table[num];
3655 }
3656
3657 #if 0
3658 /***************************************************************************
3659  Display the contents of a single copy structure.
3660 ***************************************************************************/
3661 static void dump_copy_map(bool *pcopymap)
3662 {
3663         int i;
3664         if (!pcopymap)
3665                 return;
3666
3667         printf("\n\tNon-Copied parameters:\n");
3668
3669         for (i = 0; parm_table[i].label; i++)
3670                 if (parm_table[i].p_class == P_LOCAL &&
3671                     parm_table[i].ptr && !pcopymap[i] &&
3672                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3673                 {
3674                         printf("\t\t%s\n", parm_table[i].label);
3675                 }
3676 }
3677 #endif
3678
3679 /***************************************************************************
3680  Return TRUE if the passed service number is within range.
3681 ***************************************************************************/
3682
3683 bool lp_snum_ok(int iService)
3684 {
3685         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3686 }
3687
3688 /***************************************************************************
3689  Auto-load some home services.
3690 ***************************************************************************/
3691
3692 static void lp_add_auto_services(char *str)
3693 {
3694         char *s;
3695         char *p;
3696         int homes;
3697         char *saveptr;
3698
3699         if (!str)
3700                 return;
3701
3702         s = SMB_STRDUP(str);
3703         if (!s)
3704                 return;
3705
3706         homes = lp_servicenumber(HOMES_NAME);
3707
3708         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3709              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3710                 char *home;
3711
3712                 if (lp_servicenumber(p) >= 0)
3713                         continue;
3714
3715                 home = get_user_home_dir(talloc_tos(), p);
3716
3717                 if (home && home[0] && homes >= 0)
3718                         lp_add_home(p, homes, p, home);
3719
3720                 TALLOC_FREE(home);
3721         }
3722         SAFE_FREE(s);
3723 }
3724
3725 /***************************************************************************
3726  Auto-load one printer.
3727 ***************************************************************************/
3728
3729 void lp_add_one_printer(const char *name, const char *comment,
3730                         const char *location, void *pdata)
3731 {
3732         int printers = lp_servicenumber(PRINTERS_NAME);
3733         int i;
3734
3735         if (lp_servicenumber(name) < 0) {
3736                 lp_add_printer(name, printers);
3737                 if ((i = lp_servicenumber(name)) >= 0) {
3738                         string_set(&ServicePtrs[i]->comment, comment);
3739                         ServicePtrs[i]->autoloaded = true;
3740                 }
3741         }
3742 }
3743
3744 /***************************************************************************
3745  Have we loaded a services file yet?
3746 ***************************************************************************/
3747
3748 bool lp_loaded(void)
3749 {
3750         return (bLoaded);
3751 }
3752
3753 /***************************************************************************
3754  Unload unused services.
3755 ***************************************************************************/
3756
3757 void lp_killunused(struct smbd_server_connection *sconn,
3758                    bool (*snumused) (struct smbd_server_connection *, int))
3759 {
3760         int i;
3761         for (i = 0; i < iNumServices; i++) {
3762                 if (!VALID(i))
3763                         continue;
3764
3765                 /* don't kill autoloaded or usershare services */
3766                 if ( ServicePtrs[i]->autoloaded ||
3767                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3768                         continue;
3769                 }
3770
3771                 if (!snumused || !snumused(sconn, i)) {
3772                         free_service_byindex(i);
3773                 }
3774         }
3775 }
3776
3777 /**
3778  * Kill all except autoloaded and usershare services - convenience wrapper
3779  */
3780 void lp_kill_all_services(void)
3781 {
3782         lp_killunused(NULL, NULL);
3783 }
3784
3785 /***************************************************************************
3786  Unload a service.
3787 ***************************************************************************/
3788
3789 void lp_killservice(int iServiceIn)
3790 {
3791         if (VALID(iServiceIn)) {
3792                 free_service_byindex(iServiceIn);
3793         }
3794 }
3795
3796 /***************************************************************************
3797  Save the curent values of all global and sDefault parameters into the 
3798  defaults union. This allows testparm to show only the
3799  changed (ie. non-default) parameters.
3800 ***************************************************************************/
3801
3802 static void lp_save_defaults(void)
3803 {
3804         int i;
3805         for (i = 0; parm_table[i].label; i++) {
3806                 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3807                     && parm_table[i].p_class == parm_table[i - 1].p_class)
3808                         continue;
3809                 switch (parm_table[i].type) {
3810                         case P_LIST:
3811                         case P_CMDLIST:
3812                                 parm_table[i].def.lvalue = str_list_copy(
3813                                         NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3814                                 break;
3815                         case P_STRING:
3816                         case P_USTRING:
3817                                 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
3818                                 break;
3819                         case P_BOOL:
3820                         case P_BOOLREV:
3821                                 parm_table[i].def.bvalue =
3822                                         *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3823                                 break;
3824                         case P_CHAR:
3825                                 parm_table[i].def.cvalue =
3826                                         *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3827                                 break;
3828                         case P_INTEGER: