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