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