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