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