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