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