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