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