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