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