d4ee8a22f2b879a2f22ea8f2389909c76cd4f364
[samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14    Copyright (C) Andrew Bartlett 2011
15
16    This program is free software; you can redistribute it and/or modify
17    it under the terms of the GNU General Public License as published by
18    the Free Software Foundation; either version 3 of the License, or
19    (at your option) any later version.
20
21    This program is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24    GNU General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with this program.  If not, see <http://www.gnu.org/licenses/>.
28 */
29
30 /*
31  *  Load parameters.
32  *
33  *  This module provides suitable callback functions for the params
34  *  module. It builds the internal table of service details which is
35  *  then used by the rest of the server.
36  *
37  * To add a parameter:
38  *
39  * 1) add it to the global or service structure definition
40  * 2) add it to the parm_table
41  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42  * 4) If it's a global then initialise it in init_globals. If a local
43  *    (ie. service) parameter then initialise it in the sDefault structure
44  *  
45  *
46  * Notes:
47  *   The configuration file is processed sequentially for speed. It is NOT
48  *   accessed randomly as happens in 'real' Windows. For this reason, there
49  *   is a fair bit of sequence-dependent code here - ie., code which assumes
50  *   that certain things happen before others. In particular, the code which
51  *   happens at the boundary between sections is delicately poised, so be
52  *   careful!
53  *
54  */
55
56 #include "includes.h"
57 #include "system/filesys.h"
58 #include "util_tdb.h"
59 #include "lib/param/loadparm.h"
60 #include "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 = Auto,
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) || defined(ENABLE_BUILD_FARM_HACKS)
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 **)(&Globals.ptr) ? *(const char **)(&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         strlower_m(result);
1657         return result;
1658 }
1659
1660 /***************************************************************************
1661   Add a name/index pair for the services array to the hash table.
1662 ***************************************************************************/
1663
1664 static bool hash_a_service(const char *name, int idx)
1665 {
1666         char *canon_name;
1667
1668         if ( !ServiceHash ) {
1669                 DEBUG(10,("hash_a_service: creating servicehash\n"));
1670                 ServiceHash = db_open_rbt(NULL);
1671                 if ( !ServiceHash ) {
1672                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1673                         return false;
1674                 }
1675         }
1676
1677         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1678                 idx, name));
1679
1680         canon_name = canonicalize_servicename(talloc_tos(), name );
1681
1682         dbwrap_store_bystring(ServiceHash, canon_name,
1683                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
1684                               TDB_REPLACE);
1685
1686         TALLOC_FREE(canon_name);
1687
1688         return true;
1689 }
1690
1691 /***************************************************************************
1692  Add a new home service, with the specified home directory, defaults coming
1693  from service ifrom.
1694 ***************************************************************************/
1695
1696 bool lp_add_home(const char *pszHomename, int iDefaultService,
1697                  const char *user, const char *pszHomedir)
1698 {
1699         int i;
1700
1701         if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1702                         pszHomedir[0] == '\0') {
1703                 return false;
1704         }
1705
1706         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1707
1708         if (i < 0)
1709                 return false;
1710
1711         if (!(*(ServicePtrs[iDefaultService]->szPath))
1712             || strequal(ServicePtrs[iDefaultService]->szPath,
1713                         lp_pathname(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1714                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
1715         }
1716
1717         if (!(*(ServicePtrs[i]->comment))) {
1718                 char *comment = NULL;
1719                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
1720                         return false;
1721                 }
1722                 string_set(&ServicePtrs[i]->comment, comment);
1723                 SAFE_FREE(comment);
1724         }
1725
1726         /* set the browseable flag from the global default */
1727
1728         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1729         ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
1730
1731         ServicePtrs[i]->autoloaded = true;
1732
1733         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
1734                user, ServicePtrs[i]->szPath ));
1735
1736         return true;
1737 }
1738
1739 /***************************************************************************
1740  Add a new service, based on an old one.
1741 ***************************************************************************/
1742
1743 int lp_add_service(const char *pszService, int iDefaultService)
1744 {
1745         if (iDefaultService < 0) {
1746                 return add_a_service(&sDefault, pszService);
1747         }
1748
1749         return (add_a_service(ServicePtrs[iDefaultService], pszService));
1750 }
1751
1752 /***************************************************************************
1753  Add the IPC service.
1754 ***************************************************************************/
1755
1756 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1757 {
1758         char *comment = NULL;
1759         int i = add_a_service(&sDefault, ipc_name);
1760
1761         if (i < 0)
1762                 return false;
1763
1764         if (asprintf(&comment, "IPC Service (%s)",
1765                                 Globals.szServerString) < 0) {
1766                 return false;
1767         }
1768
1769         string_set(&ServicePtrs[i]->szPath, tmpdir());
1770         string_set(&ServicePtrs[i]->szUsername, "");
1771         string_set(&ServicePtrs[i]->comment, comment);
1772         string_set(&ServicePtrs[i]->fstype, "IPC");
1773         ServicePtrs[i]->iMaxConnections = 0;
1774         ServicePtrs[i]->bAvailable = true;
1775         ServicePtrs[i]->bRead_only = true;
1776         ServicePtrs[i]->bGuest_only = false;
1777         ServicePtrs[i]->bAdministrative_share = true;
1778         ServicePtrs[i]->bGuest_ok = guest_ok;
1779         ServicePtrs[i]->bPrint_ok = false;
1780         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1781
1782         DEBUG(3, ("adding IPC service\n"));
1783
1784         SAFE_FREE(comment);
1785         return true;
1786 }
1787
1788 /***************************************************************************
1789  Add a new printer service, with defaults coming from service iFrom.
1790 ***************************************************************************/
1791
1792 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1793 {
1794         const char *comment = "From Printcap";
1795         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1796
1797         if (i < 0)
1798                 return false;
1799
1800         /* note that we do NOT default the availability flag to true - */
1801         /* we take it from the default service passed. This allows all */
1802         /* dynamic printers to be disabled by disabling the [printers] */
1803         /* entry (if/when the 'available' keyword is implemented!).    */
1804
1805         /* the printer name is set to the service name. */
1806         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1807         string_set(&ServicePtrs[i]->comment, comment);
1808
1809         /* set the browseable flag from the gloabl default */
1810         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1811
1812         /* Printers cannot be read_only. */
1813         ServicePtrs[i]->bRead_only = false;
1814         /* No share modes on printer services. */
1815         ServicePtrs[i]->bShareModes = false;
1816         /* No oplocks on printer services. */
1817         ServicePtrs[i]->bOpLocks = false;
1818         /* Printer services must be printable. */
1819         ServicePtrs[i]->bPrint_ok = true;
1820
1821         DEBUG(3, ("adding printer service %s\n", pszPrintername));
1822
1823         return true;
1824 }
1825
1826
1827 /***************************************************************************
1828  Check whether the given parameter name is valid.
1829  Parametric options (names containing a colon) are considered valid.
1830 ***************************************************************************/
1831
1832 bool lp_parameter_is_valid(const char *pszParmName)
1833 {
1834         return ((map_parameter(pszParmName) != -1) ||
1835                 (strchr(pszParmName, ':') != NULL));
1836 }
1837
1838 /***************************************************************************
1839  Check whether the given name is the name of a global parameter.
1840  Returns true for strings belonging to parameters of class
1841  P_GLOBAL, false for all other strings, also for parametric options
1842  and strings not belonging to any option.
1843 ***************************************************************************/
1844
1845 bool lp_parameter_is_global(const char *pszParmName)
1846 {
1847         int num = map_parameter(pszParmName);
1848
1849         if (num >= 0) {
1850                 return (parm_table[num].p_class == P_GLOBAL);
1851         }
1852
1853         return false;
1854 }
1855
1856 /**************************************************************************
1857  Check whether the given name is the canonical name of a parameter.
1858  Returns false if it is not a valid parameter Name.
1859  For parametric options, true is returned.
1860 **************************************************************************/
1861
1862 bool lp_parameter_is_canonical(const char *parm_name)
1863 {
1864         if (!lp_parameter_is_valid(parm_name)) {
1865                 return false;
1866         }
1867
1868         return (map_parameter(parm_name) ==
1869                 map_parameter_canonical(parm_name, NULL));
1870 }
1871
1872 /**************************************************************************
1873  Determine the canonical name for a parameter.
1874  Indicate when it is an inverse (boolean) synonym instead of a
1875  "usual" synonym.
1876 **************************************************************************/
1877
1878 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1879                                bool *inverse)
1880 {
1881         int num;
1882
1883         if (!lp_parameter_is_valid(parm_name)) {
1884                 *canon_parm = NULL;
1885                 return false;
1886         }
1887
1888         num = map_parameter_canonical(parm_name, inverse);
1889         if (num < 0) {
1890                 /* parametric option */
1891                 *canon_parm = parm_name;
1892         } else {
1893                 *canon_parm = parm_table[num].label;
1894         }
1895
1896         return true;
1897
1898 }
1899
1900 /**************************************************************************
1901  Determine the canonical name for a parameter.
1902  Turn the value given into the inverse boolean expression when
1903  the synonym is an invers boolean synonym.
1904
1905  Return true if parm_name is a valid parameter name and
1906  in case it is an invers boolean synonym, if the val string could
1907  successfully be converted to the reverse bool.
1908  Return false in all other cases.
1909 **************************************************************************/
1910
1911 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1912                                           const char *val,
1913                                           const char **canon_parm,
1914                                           const char **canon_val)
1915 {
1916         int num;
1917         bool inverse;
1918
1919         if (!lp_parameter_is_valid(parm_name)) {
1920                 *canon_parm = NULL;
1921                 *canon_val = NULL;
1922                 return false;
1923         }
1924
1925         num = map_parameter_canonical(parm_name, &inverse);
1926         if (num < 0) {
1927                 /* parametric option */
1928                 *canon_parm = parm_name;
1929                 *canon_val = val;
1930         } else {
1931                 *canon_parm = parm_table[num].label;
1932                 if (inverse) {
1933                         if (!lp_invert_boolean(val, canon_val)) {
1934                                 *canon_val = NULL;
1935                                 return false;
1936                         }
1937                 } else {
1938                         *canon_val = val;
1939                 }
1940         }
1941
1942         return true;
1943 }
1944
1945 /***************************************************************************
1946  Map a parameter's string representation to something we can use. 
1947  Returns false if the parameter string is not recognised, else TRUE.
1948 ***************************************************************************/
1949
1950 static int map_parameter(const char *pszParmName)
1951 {
1952         int iIndex;
1953
1954         if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
1955                 return (-1);
1956
1957         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1958                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1959                         return (iIndex);
1960
1961         /* Warn only if it isn't parametric option */
1962         if (strchr(pszParmName, ':') == NULL)
1963                 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1964         /* We do return 'fail' for parametric options as well because they are
1965            stored in different storage
1966          */
1967         return (-1);
1968 }
1969
1970 /***************************************************************************
1971  Map a parameter's string representation to the index of the canonical
1972  form of the parameter (it might be a synonym).
1973  Returns -1 if the parameter string is not recognised.
1974 ***************************************************************************/
1975
1976 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1977 {
1978         int parm_num, canon_num;
1979         bool loc_inverse = false;
1980
1981         parm_num = map_parameter(pszParmName);
1982         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
1983                 /* invalid, parametric or no canidate for synonyms ... */
1984                 goto done;
1985         }
1986
1987         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1988                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1989                         parm_num = canon_num;
1990                         goto done;
1991                 }
1992         }
1993
1994 done:
1995         if (inverse != NULL) {
1996                 *inverse = loc_inverse;
1997         }
1998         return parm_num;
1999 }
2000
2001 /***************************************************************************
2002  return true if parameter number parm1 is a synonym of parameter
2003  number parm2 (parm2 being the principal name).
2004  set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
2005  false otherwise.
2006 ***************************************************************************/
2007
2008 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
2009 {
2010         if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
2011             (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
2012             (parm_table[parm1].flags & FLAG_HIDE) &&
2013             !(parm_table[parm2].flags & FLAG_HIDE))
2014         {
2015                 if (inverse != NULL) {
2016                         if ((parm_table[parm1].type == P_BOOLREV) &&
2017                             (parm_table[parm2].type == P_BOOL))
2018                         {
2019                                 *inverse = true;
2020                         } else {
2021                                 *inverse = false;
2022                         }
2023                 }
2024                 return true;
2025         }
2026         return false;
2027 }
2028
2029 /***************************************************************************
2030  Show one parameter's name, type, [values,] and flags.
2031  (helper functions for show_parameter_list)
2032 ***************************************************************************/
2033
2034 static void show_parameter(int parmIndex)
2035 {
2036         int enumIndex, flagIndex;
2037         int parmIndex2;
2038         bool hadFlag;
2039         bool hadSyn;
2040         bool inverse;
2041         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2042                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
2043                 "P_ENUM", "P_SEP"};
2044         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2045                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2046                 FLAG_HIDE};
2047         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2048                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2049                 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
2050
2051         printf("%s=%s", parm_table[parmIndex].label,
2052                type[parm_table[parmIndex].type]);
2053         if (parm_table[parmIndex].type == P_ENUM) {
2054                 printf(",");
2055                 for (enumIndex=0;
2056                      parm_table[parmIndex].enum_list[enumIndex].name;
2057                      enumIndex++)
2058                 {
2059                         printf("%s%s",
2060                                enumIndex ? "|" : "",
2061                                parm_table[parmIndex].enum_list[enumIndex].name);
2062                 }
2063         }
2064         printf(",");
2065         hadFlag = false;
2066         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
2067                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2068                         printf("%s%s",
2069                                 hadFlag ? "|" : "",
2070                                 flag_names[flagIndex]);
2071                         hadFlag = true;
2072                 }
2073         }
2074
2075         /* output synonyms */
2076         hadSyn = false;
2077         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
2078                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
2079                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
2080                                parm_table[parmIndex2].label);
2081                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
2082                         if (!hadSyn) {
2083                                 printf(" (synonyms: ");
2084                                 hadSyn = true;
2085                         } else {
2086                                 printf(", ");
2087                         }
2088                         printf("%s%s", parm_table[parmIndex2].label,
2089                                inverse ? "[i]" : "");
2090                 }
2091         }
2092         if (hadSyn) {
2093                 printf(")");
2094         }
2095
2096         printf("\n");
2097 }
2098
2099 /***************************************************************************
2100  Show all parameter's name, type, [values,] and flags.
2101 ***************************************************************************/
2102
2103 void show_parameter_list(void)
2104 {
2105         int classIndex, parmIndex;
2106         const char *section_names[] = { "local", "global", NULL};
2107
2108         for (classIndex=0; section_names[classIndex]; classIndex++) {
2109                 printf("[%s]\n", section_names[classIndex]);
2110                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2111                         if (parm_table[parmIndex].p_class == classIndex) {
2112                                 show_parameter(parmIndex);
2113                         }
2114                 }
2115         }
2116 }
2117
2118 /***************************************************************************
2119  Check if a given string correctly represents a boolean value.
2120 ***************************************************************************/
2121
2122 bool lp_string_is_valid_boolean(const char *parm_value)
2123 {
2124         return set_boolean(parm_value, NULL);
2125 }
2126
2127 /***************************************************************************
2128  Get the standard string representation of a boolean value ("yes" or "no")
2129 ***************************************************************************/
2130
2131 static const char *get_boolean(bool bool_value)
2132 {
2133         static const char *yes_str = "yes";
2134         static const char *no_str = "no";
2135
2136         return (bool_value ? yes_str : no_str);
2137 }
2138
2139 /***************************************************************************
2140  Provide the string of the negated boolean value associated to the boolean
2141  given as a string. Returns false if the passed string does not correctly
2142  represent a boolean.
2143 ***************************************************************************/
2144
2145 bool lp_invert_boolean(const char *str, const char **inverse_str)
2146 {
2147         bool val;
2148
2149         if (!set_boolean(str, &val)) {
2150                 return false;
2151         }
2152
2153         *inverse_str = get_boolean(!val);
2154         return true;
2155 }
2156
2157 /***************************************************************************
2158  Provide the canonical string representation of a boolean value given
2159  as a string. Return true on success, false if the string given does
2160  not correctly represent a boolean.
2161 ***************************************************************************/
2162
2163 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2164 {
2165         bool val;
2166
2167         if (!set_boolean(str, &val)) {
2168                 return false;
2169         }
2170
2171         *canon_str = get_boolean(val);
2172         return true;
2173 }
2174
2175 /***************************************************************************
2176 Find a service by name. Otherwise works like get_service.
2177 ***************************************************************************/
2178
2179 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2180 {
2181         int iService = -1;
2182         char *canon_name;
2183         TDB_DATA data;
2184         NTSTATUS status;
2185
2186         if (ServiceHash == NULL) {
2187                 return -1;
2188         }
2189
2190         canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2191
2192         status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2193                                        &data);
2194
2195         if (NT_STATUS_IS_OK(status) &&
2196             (data.dptr != NULL) &&
2197             (data.dsize == sizeof(iService)))
2198         {
2199                 iService = *(int *)data.dptr;
2200         }
2201
2202         TALLOC_FREE(canon_name);
2203
2204         if ((iService != -1) && (LP_SNUM_OK(iService))
2205             && (pserviceDest != NULL)) {
2206                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2207         }
2208
2209         return (iService);
2210 }
2211
2212 /* Return a pointer to a service by name.  Unlike getservicebyname, it does not copy the service */
2213 struct loadparm_service *lp_service(const char *pszServiceName)
2214 {
2215         int iService = getservicebyname(pszServiceName, NULL);
2216         if (iService == -1 || !LP_SNUM_OK(iService)) {
2217                 return NULL;
2218         }
2219         return ServicePtrs[iService];
2220 }
2221
2222 struct loadparm_service *lp_servicebynum(int snum)
2223 {
2224         if ((snum == -1) || !LP_SNUM_OK(snum)) {
2225                 return NULL;
2226         }
2227         return ServicePtrs[snum];
2228 }
2229
2230 struct loadparm_service *lp_default_loadparm_service()
2231 {
2232         return &sDefault;
2233 }
2234
2235
2236 /***************************************************************************
2237  Copy a service structure to another.
2238  If pcopymapDest is NULL then copy all fields
2239 ***************************************************************************/
2240
2241 /**
2242  * Add a parametric option to a parmlist_entry,
2243  * replacing old value, if already present.
2244  */
2245 static void set_param_opt(struct parmlist_entry **opt_list,
2246                           const char *opt_name,
2247                           const char *opt_value,
2248                           unsigned priority)
2249 {
2250         struct parmlist_entry *new_opt, *opt;
2251         bool not_added;
2252
2253         opt = *opt_list;
2254         not_added = true;
2255
2256         /* Traverse destination */
2257         while (opt) {
2258                 /* If we already have same option, override it */
2259                 if (strwicmp(opt->key, opt_name) == 0) {
2260                         if ((opt->priority & FLAG_CMDLINE) &&
2261                             !(priority & FLAG_CMDLINE)) {
2262                                 /* it's been marked as not to be
2263                                    overridden */
2264                                 return;
2265                         }
2266                         string_free(&opt->value);
2267                         TALLOC_FREE(opt->list);
2268                         opt->value = SMB_STRDUP(opt_value);
2269                         opt->priority = priority;
2270                         not_added = false;
2271                         break;
2272                 }
2273                 opt = opt->next;
2274         }
2275         if (not_added) {
2276             new_opt = SMB_XMALLOC_P(struct parmlist_entry);
2277             new_opt->key = SMB_STRDUP(opt_name);
2278             new_opt->value = SMB_STRDUP(opt_value);
2279             new_opt->list = NULL;
2280             new_opt->priority = priority;
2281             DLIST_ADD(*opt_list, new_opt);
2282         }
2283 }
2284
2285 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
2286                          struct bitmap *pcopymapDest)
2287 {
2288         int i;
2289         bool bcopyall = (pcopymapDest == NULL);
2290         struct parmlist_entry *data;
2291
2292         for (i = 0; parm_table[i].label; i++)
2293                 if (parm_table[i].p_class == P_LOCAL &&
2294                     (bcopyall || bitmap_query(pcopymapDest,i))) {
2295                         void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
2296                         void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
2297
2298                         switch (parm_table[i].type) {
2299                                 case P_BOOL:
2300                                 case P_BOOLREV:
2301                                         *(bool *)dest_ptr = *(bool *)src_ptr;
2302                                         break;
2303
2304                                 case P_INTEGER:
2305                                 case P_ENUM:
2306                                 case P_OCTAL:
2307                                 case P_BYTES:
2308                                         *(int *)dest_ptr = *(int *)src_ptr;
2309                                         break;
2310
2311                                 case P_CHAR:
2312                                         *(char *)dest_ptr = *(char *)src_ptr;
2313                                         break;
2314
2315                                 case P_STRING:
2316                                         string_set((char **)dest_ptr,
2317                                                    *(char **)src_ptr);
2318                                         break;
2319
2320                                 case P_USTRING:
2321                                 {
2322                                         char *upper_string = strupper_talloc(talloc_tos(), 
2323                                                                              *(char **)src_ptr);
2324                                         string_set((char **)dest_ptr,
2325                                                    upper_string);
2326                                         TALLOC_FREE(upper_string);
2327                                         break;
2328                                 }
2329                                 case P_LIST:
2330                                         TALLOC_FREE(*((char ***)dest_ptr));
2331                                         *((char ***)dest_ptr) = str_list_copy(NULL, 
2332                                                       *(const char ***)src_ptr);
2333                                         break;
2334                                 default:
2335                                         break;
2336                         }
2337                 }
2338
2339         if (bcopyall) {
2340                 init_copymap(pserviceDest);
2341                 if (pserviceSource->copymap)
2342                         bitmap_copy(pserviceDest->copymap,
2343                                     pserviceSource->copymap);
2344         }
2345
2346         data = pserviceSource->param_opt;
2347         while (data) {
2348                 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
2349                 data = data->next;
2350         }
2351 }
2352
2353 /***************************************************************************
2354 Check a service for consistency. Return false if the service is in any way
2355 incomplete or faulty, else true.
2356 ***************************************************************************/
2357
2358 bool service_ok(int iService)
2359 {
2360         bool bRetval;
2361
2362         bRetval = true;
2363         if (ServicePtrs[iService]->szService[0] == '\0') {
2364                 DEBUG(0, ("The following message indicates an internal error:\n"));
2365                 DEBUG(0, ("No service name in service entry.\n"));
2366                 bRetval = false;
2367         }
2368
2369         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2370         /* I can't see why you'd want a non-printable printer service...        */
2371         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2372                 if (!ServicePtrs[iService]->bPrint_ok) {
2373                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2374                                ServicePtrs[iService]->szService));
2375                         ServicePtrs[iService]->bPrint_ok = true;
2376                 }
2377                 /* [printers] service must also be non-browsable. */
2378                 if (ServicePtrs[iService]->bBrowseable)
2379                         ServicePtrs[iService]->bBrowseable = false;
2380         }
2381
2382         if (ServicePtrs[iService]->szPath[0] == '\0' &&
2383             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2384             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
2385             ) {
2386                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2387                         ServicePtrs[iService]->szService));
2388                 ServicePtrs[iService]->bAvailable = false;
2389         }
2390
2391         /* If a service is flagged unavailable, log the fact at level 1. */
2392         if (!ServicePtrs[iService]->bAvailable)
2393                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2394                           ServicePtrs[iService]->szService));
2395
2396         return (bRetval);
2397 }
2398
2399 static struct smbconf_ctx *lp_smbconf_ctx(void)
2400 {
2401         sbcErr err;
2402         static struct smbconf_ctx *conf_ctx = NULL;
2403
2404         if (conf_ctx == NULL) {
2405                 err = smbconf_init(NULL, &conf_ctx, "registry:");
2406                 if (!SBC_ERROR_IS_OK(err)) {
2407                         DEBUG(1, ("error initializing registry configuration: "
2408                                   "%s\n", sbcErrorString(err)));
2409                         conf_ctx = NULL;
2410                 }
2411         }
2412
2413         return conf_ctx;
2414 }
2415
2416 static bool process_smbconf_service(struct smbconf_service *service)
2417 {
2418         uint32_t count;
2419         bool ret;
2420
2421         if (service == NULL) {
2422                 return false;
2423         }
2424
2425         ret = do_section(service->name, NULL);
2426         if (ret != true) {
2427                 return false;
2428         }
2429         for (count = 0; count < service->num_params; count++) {
2430                 ret = do_parameter(service->param_names[count],
2431                                    service->param_values[count],
2432                                    NULL);
2433                 if (ret != true) {
2434                         return false;
2435                 }
2436         }
2437         if (iServiceIndex >= 0) {
2438                 return service_ok(iServiceIndex);
2439         }
2440         return true;
2441 }
2442
2443 /**
2444  * load a service from registry and activate it
2445  */
2446 bool process_registry_service(const char *service_name)
2447 {
2448         sbcErr err;
2449         struct smbconf_service *service = NULL;
2450         TALLOC_CTX *mem_ctx = talloc_stackframe();
2451         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2452         bool ret = false;
2453
2454         if (conf_ctx == NULL) {
2455                 goto done;
2456         }
2457
2458         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2459
2460         if (!smbconf_share_exists(conf_ctx, service_name)) {
2461                 /*
2462                  * Registry does not contain data for this service (yet),
2463                  * but make sure lp_load doesn't return false.
2464                  */
2465                 ret = true;
2466                 goto done;
2467         }
2468
2469         err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2470         if (!SBC_ERROR_IS_OK(err)) {
2471                 goto done;
2472         }
2473
2474         ret = process_smbconf_service(service);
2475         if (!ret) {
2476                 goto done;
2477         }
2478
2479         /* store the csn */
2480         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2481
2482 done:
2483         TALLOC_FREE(mem_ctx);
2484         return ret;
2485 }
2486
2487 /*
2488  * process_registry_globals
2489  */
2490 static bool process_registry_globals(void)
2491 {
2492         bool ret;
2493
2494         add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2495
2496         ret = do_parameter("registry shares", "yes", NULL);
2497         if (!ret) {
2498                 return ret;
2499         }
2500
2501         return process_registry_service(GLOBAL_NAME);
2502 }
2503
2504 bool process_registry_shares(void)
2505 {
2506         sbcErr err;
2507         uint32_t count;
2508         struct smbconf_service **service = NULL;
2509         uint32_t num_shares = 0;
2510         TALLOC_CTX *mem_ctx = talloc_stackframe();
2511         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2512         bool ret = false;
2513
2514         if (conf_ctx == NULL) {
2515                 goto done;
2516         }
2517
2518         err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2519         if (!SBC_ERROR_IS_OK(err)) {
2520                 goto done;
2521         }
2522
2523         ret = true;
2524
2525         for (count = 0; count < num_shares; count++) {
2526                 if (strequal(service[count]->name, GLOBAL_NAME)) {
2527                         continue;
2528                 }
2529                 ret = process_smbconf_service(service[count]);
2530                 if (!ret) {
2531                         goto done;
2532                 }
2533         }
2534
2535         /* store the csn */
2536         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2537
2538 done:
2539         TALLOC_FREE(mem_ctx);
2540         return ret;
2541 }
2542
2543 /**
2544  * reload those shares from registry that are already
2545  * activated in the services array.
2546  */
2547 static bool reload_registry_shares(void)
2548 {
2549         int i;
2550         bool ret = true;
2551
2552         for (i = 0; i < iNumServices; i++) {
2553                 if (!VALID(i)) {
2554                         continue;
2555                 }
2556
2557                 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2558                         continue;
2559                 }
2560
2561                 ret = process_registry_service(ServicePtrs[i]->szService);
2562                 if (!ret) {
2563                         goto done;
2564                 }
2565         }
2566
2567 done:
2568         return ret;
2569 }
2570
2571
2572 #define MAX_INCLUDE_DEPTH 100
2573
2574 static uint8_t include_depth;
2575
2576 static struct file_lists {
2577         struct file_lists *next;
2578         char *name;
2579         char *subfname;
2580         time_t modtime;
2581 } *file_lists = NULL;
2582
2583 /*******************************************************************
2584  Keep a linked list of all config files so we know when one has changed 
2585  it's date and needs to be reloaded.
2586 ********************************************************************/
2587
2588 static void add_to_file_list(const char *fname, const char *subfname)
2589 {
2590         struct file_lists *f = file_lists;
2591
2592         while (f) {
2593                 if (f->name && !strcmp(f->name, fname))
2594                         break;
2595                 f = f->next;
2596         }
2597
2598         if (!f) {
2599                 f = SMB_MALLOC_P(struct file_lists);
2600                 if (!f)
2601                         return;
2602                 f->next = file_lists;
2603                 f->name = SMB_STRDUP(fname);
2604                 if (!f->name) {
2605                         SAFE_FREE(f);
2606                         return;
2607                 }
2608                 f->subfname = SMB_STRDUP(subfname);
2609                 if (!f->subfname) {
2610                         SAFE_FREE(f->name);
2611                         SAFE_FREE(f);
2612                         return;
2613                 }
2614                 file_lists = f;
2615                 f->modtime = file_modtime(subfname);
2616         } else {
2617                 time_t t = file_modtime(subfname);
2618                 if (t)
2619                         f->modtime = t;
2620         }
2621         return;
2622 }
2623
2624 /**
2625  * Free the file lists
2626  */
2627 static void free_file_list(void)
2628 {
2629         struct file_lists *f;
2630         struct file_lists *next;
2631
2632         f = file_lists;
2633         while( f ) {
2634                 next = f->next;
2635                 SAFE_FREE( f->name );
2636                 SAFE_FREE( f->subfname );
2637                 SAFE_FREE( f );
2638                 f = next;
2639         }
2640         file_lists = NULL;
2641 }
2642
2643
2644 /**
2645  * Utility function for outsiders to check if we're running on registry.
2646  */
2647 bool lp_config_backend_is_registry(void)
2648 {
2649         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2650 }
2651
2652 /**
2653  * Utility function to check if the config backend is FILE.
2654  */
2655 bool lp_config_backend_is_file(void)
2656 {
2657         return (lp_config_backend() == CONFIG_BACKEND_FILE);
2658 }
2659
2660 /*******************************************************************
2661  Check if a config file has changed date.
2662 ********************************************************************/
2663
2664 bool lp_file_list_changed(void)
2665 {
2666         struct file_lists *f = file_lists;
2667
2668         DEBUG(6, ("lp_file_list_changed()\n"));
2669
2670         while (f) {
2671                 time_t mod_time;
2672
2673                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2674                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2675
2676                         if (conf_ctx == NULL) {
2677                                 return false;
2678                         }
2679                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2680                                             NULL))
2681                         {
2682                                 DEBUGADD(6, ("registry config changed\n"));
2683                                 return true;
2684                         }
2685                 } else {
2686                         char *n2 = NULL;
2687                         n2 = talloc_sub_basic(talloc_tos(),
2688                                               get_current_username(),
2689                                               current_user_info.domain,
2690                                               f->name);
2691                         if (!n2) {
2692                                 return false;
2693                         }
2694                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2695                                      f->name, n2, ctime(&f->modtime)));
2696
2697                         mod_time = file_modtime(n2);
2698
2699                         if (mod_time &&
2700                             ((f->modtime != mod_time) ||
2701                              (f->subfname == NULL) ||
2702                              (strcmp(n2, f->subfname) != 0)))
2703                         {
2704                                 DEBUGADD(6,
2705                                          ("file %s modified: %s\n", n2,
2706                                           ctime(&mod_time)));
2707                                 f->modtime = mod_time;
2708                                 SAFE_FREE(f->subfname);
2709                                 f->subfname = SMB_STRDUP(n2);
2710                                 TALLOC_FREE(n2);
2711                                 return true;
2712                         }
2713                         TALLOC_FREE(n2);
2714                 }
2715                 f = f->next;
2716         }
2717         return false;
2718 }
2719
2720
2721 /**
2722  * Initialize iconv conversion descriptors.
2723  *
2724  * This is called the first time it is needed, and also called again
2725  * every time the configuration is reloaded, because the charset or
2726  * codepage might have changed.
2727  **/
2728 static void init_iconv(void)
2729 {
2730         global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2731                                                       lp_unix_charset(),
2732                                                       true, global_iconv_handle);
2733 }
2734
2735 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2736 {
2737         if (strcmp(*ptr, pszParmValue) != 0) {
2738                 string_set(ptr, pszParmValue);
2739                 init_iconv();
2740         }
2741         return true;
2742 }
2743
2744 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2745 {
2746         bool is_utf8 = false;
2747         size_t len = strlen(pszParmValue);
2748
2749         if (len == 4 || len == 5) {
2750                 /* Don't use StrCaseCmp here as we don't want to
2751                    initialize iconv. */
2752                 if ((toupper_m(pszParmValue[0]) == 'U') &&
2753                     (toupper_m(pszParmValue[1]) == 'T') &&
2754                     (toupper_m(pszParmValue[2]) == 'F')) {
2755                         if (len == 4) {
2756                                 if (pszParmValue[3] == '8') {
2757                                         is_utf8 = true;
2758                                 }
2759                         } else {
2760                                 if (pszParmValue[3] == '-' &&
2761                                     pszParmValue[4] == '8') {
2762                                         is_utf8 = true;
2763                                 }
2764                         }
2765                 }
2766         }
2767
2768         if (strcmp(*ptr, pszParmValue) != 0) {
2769                 if (is_utf8) {
2770                         DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2771                                 "be UTF8, using (default value) %s instead.\n",
2772                                 DEFAULT_DOS_CHARSET));
2773                         pszParmValue = DEFAULT_DOS_CHARSET;
2774                 }
2775                 string_set(ptr, pszParmValue);
2776                 init_iconv();
2777         }
2778         return true;
2779 }
2780
2781 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2782 {
2783         bool ret = true;
2784         char *realm = strupper_talloc(talloc_tos(), pszParmValue);
2785         char *dnsdomain = strlower_talloc(realm, pszParmValue);
2786
2787         ret &= string_set(&Globals.szRealm, pszParmValue);
2788         ret &= string_set(&Globals.szRealm_upper, realm);
2789         ret &= string_set(&Globals.szRealm_lower, dnsdomain);
2790         TALLOC_FREE(realm);
2791
2792         return ret;
2793 }
2794
2795 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2796 {
2797         TALLOC_FREE(Globals.szNetbiosAliases);
2798         Globals.szNetbiosAliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
2799         return set_netbios_aliases(Globals.szNetbiosAliases);
2800 }
2801
2802 /***************************************************************************
2803  Handle the include operation.
2804 ***************************************************************************/
2805 static bool bAllowIncludeRegistry = true;
2806
2807 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2808 {
2809         char *fname;
2810
2811         if (include_depth >= MAX_INCLUDE_DEPTH) {
2812                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2813                           include_depth));
2814                 return false;
2815         }
2816
2817         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2818                 if (!bAllowIncludeRegistry) {
2819                         return true;
2820                 }
2821                 if (bInGlobalSection) {
2822                         bool ret;
2823                         include_depth++;
2824                         ret = process_registry_globals();
2825                         include_depth--;
2826                         return ret;
2827                 } else {
2828                         DEBUG(1, ("\"include = registry\" only effective "
2829                                   "in %s section\n", GLOBAL_NAME));
2830                         return false;
2831                 }
2832         }
2833
2834         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2835                                  current_user_info.domain,
2836                                  pszParmValue);
2837
2838         add_to_file_list(pszParmValue, fname);
2839
2840         string_set(ptr, fname);
2841
2842         if (file_exist(fname)) {
2843                 bool ret;
2844                 include_depth++;
2845                 ret = pm_process(fname, do_section, do_parameter, NULL);
2846                 include_depth--;
2847                 TALLOC_FREE(fname);
2848                 return ret;
2849         }
2850
2851         DEBUG(2, ("Can't find include file %s\n", fname));
2852         TALLOC_FREE(fname);
2853         return true;
2854 }
2855
2856 /***************************************************************************
2857  Handle the interpretation of the copy parameter.
2858 ***************************************************************************/
2859
2860 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2861 {
2862         bool bRetval;
2863         int iTemp;
2864         struct loadparm_service serviceTemp;
2865
2866         string_set(ptr, pszParmValue);
2867
2868         init_service(&serviceTemp);
2869
2870         bRetval = false;
2871
2872         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2873
2874         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2875                 if (iTemp == iServiceIndex) {
2876                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2877                 } else {
2878                         copy_service(ServicePtrs[iServiceIndex],
2879                                      &serviceTemp,
2880                                      ServicePtrs[iServiceIndex]->copymap);
2881                         bRetval = true;
2882                 }
2883         } else {
2884                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2885                 bRetval = false;
2886         }
2887
2888         free_service(&serviceTemp);
2889         return (bRetval);
2890 }
2891
2892 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2893 {
2894         Globals.ldap_debug_level = lp_int(pszParmValue);
2895         init_ldap_debugging();
2896         return true;
2897 }
2898
2899 /***************************************************************************
2900  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
2901  parameters is:
2902
2903  [global]
2904
2905         idmap uid = 1000-1999
2906         idmap gid = 700-899
2907
2908  We only do simple parsing checks here.  The strings are parsed into useful
2909  structures in the idmap daemon code.
2910
2911 ***************************************************************************/
2912
2913 /* Some lp_ routines to return idmap [ug]id information */
2914
2915 static uid_t idmap_uid_low, idmap_uid_high;
2916 static gid_t idmap_gid_low, idmap_gid_high;
2917
2918 bool lp_idmap_uid(uid_t *low, uid_t *high)
2919 {
2920         if (idmap_uid_low == 0 || idmap_uid_high == 0)
2921                 return false;
2922
2923         if (low)
2924                 *low = idmap_uid_low;
2925
2926         if (high)
2927                 *high = idmap_uid_high;
2928
2929         return true;
2930 }
2931
2932 bool lp_idmap_gid(gid_t *low, gid_t *high)
2933 {
2934         if (idmap_gid_low == 0 || idmap_gid_high == 0)
2935                 return false;
2936
2937         if (low)
2938                 *low = idmap_gid_low;
2939
2940         if (high)
2941                 *high = idmap_gid_high;
2942
2943         return true;
2944 }
2945
2946 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2947 {
2948         lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
2949
2950         return true;
2951 }
2952
2953 /* Do some simple checks on "idmap [ug]id" parameter values */
2954
2955 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2956 {
2957         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2958
2959         return true;
2960 }
2961
2962 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2963 {
2964         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2965
2966         return true;
2967 }
2968
2969 /***************************************************************************
2970  Handle the DEBUG level list.
2971 ***************************************************************************/
2972
2973 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
2974 {
2975         string_set(ptr, pszParmValueIn);
2976         return debug_parse_levels(pszParmValueIn);
2977 }
2978
2979 /***************************************************************************
2980  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2981 ***************************************************************************/
2982
2983 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2984 {
2985         const char *suffix_string;
2986
2987         suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2988                                         Globals.szLdapSuffix );
2989         if ( !suffix_string ) {
2990                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2991                 return "";
2992         }
2993
2994         return suffix_string;
2995 }
2996
2997 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2998 {
2999         if (Globals.szLdapMachineSuffix[0])
3000                 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
3001
3002         return lp_string(ctx, Globals.szLdapSuffix);
3003 }
3004
3005 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
3006 {
3007         if (Globals.szLdapUserSuffix[0])
3008                 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
3009
3010         return lp_string(ctx, Globals.szLdapSuffix);
3011 }
3012
3013 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
3014 {
3015         if (Globals.szLdapGroupSuffix[0])
3016                 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
3017
3018         return lp_string(ctx, Globals.szLdapSuffix);
3019 }
3020
3021 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
3022 {
3023         if (Globals.szLdapIdmapSuffix[0])
3024                 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
3025
3026         return lp_string(ctx, Globals.szLdapSuffix);
3027 }
3028
3029 /****************************************************************************
3030  set the value for a P_ENUM
3031  ***************************************************************************/
3032
3033 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3034                               int *ptr )
3035 {
3036         int i;
3037
3038         for (i = 0; parm->enum_list[i].name; i++) {
3039                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3040                         *ptr = parm->enum_list[i].value;
3041                         return;
3042                 }
3043         }
3044         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
3045                   pszParmValue, parm->label));
3046 }
3047
3048 /***************************************************************************
3049 ***************************************************************************/
3050
3051 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
3052 {
3053         static int parm_num = -1;
3054         struct loadparm_service *s;
3055
3056         if ( parm_num == -1 )
3057                 parm_num = map_parameter( "printing" );
3058
3059         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3060
3061         if ( snum < 0 )
3062                 s = &sDefault;
3063         else
3064                 s = ServicePtrs[snum];
3065
3066         init_printer_values( s );
3067
3068         return true;
3069 }
3070
3071
3072 /***************************************************************************
3073  Initialise a copymap.
3074 ***************************************************************************/
3075
3076 static void init_copymap(struct loadparm_service *pservice)
3077 {
3078         int i;
3079
3080         TALLOC_FREE(pservice->copymap);
3081
3082         pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
3083         if (!pservice->copymap)
3084                 DEBUG(0,
3085                       ("Couldn't allocate copymap!! (size %d)\n",
3086                        (int)NUMPARAMETERS));
3087         else
3088                 for (i = 0; i < NUMPARAMETERS; i++)
3089                         bitmap_set(pservice->copymap, i);
3090 }
3091
3092 /**
3093   return the parameter pointer for a parameter
3094 */
3095 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
3096 {
3097         if (service == NULL) {
3098                 if (parm->p_class == P_LOCAL)
3099                         return (void *)(((char *)&sDefault)+parm->offset);
3100                 else if (parm->p_class == P_GLOBAL)
3101                         return (void *)(((char *)&Globals)+parm->offset);
3102                 else return NULL;
3103         } else {
3104                 return (void *)(((char *)service) + parm->offset);
3105         }
3106 }
3107
3108 /***************************************************************************
3109  Return the local pointer to a parameter given the service number and parameter
3110 ***************************************************************************/
3111
3112 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
3113 {
3114         return lp_parm_ptr(ServicePtrs[snum], parm);
3115 }
3116
3117 /***************************************************************************
3118  Process a parameter for a particular service number. If snum < 0
3119  then assume we are in the globals.
3120 ***************************************************************************/
3121
3122 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3123 {
3124         int parmnum, i;
3125         void *parm_ptr = NULL;  /* where we are going to store the result */
3126         struct parmlist_entry **opt_list;
3127
3128         parmnum = map_parameter(pszParmName);
3129
3130         if (parmnum < 0) {
3131                 if (strchr(pszParmName, ':') == NULL) {
3132                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
3133                                   pszParmName));
3134                         return true;
3135                 }
3136
3137                 /*
3138                  * We've got a parametric option
3139                  */
3140
3141                 opt_list = (snum < 0)
3142                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
3143                 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
3144
3145                 return true;
3146         }
3147
3148         /* if it's already been set by the command line, then we don't
3149            override here */
3150         if (parm_table[parmnum].flags & FLAG_CMDLINE) {
3151                 return true;
3152         }
3153
3154         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3155                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3156                           pszParmName));
3157         }
3158
3159         /* we might point at a service, the default service or a global */
3160         if (snum < 0) {
3161                 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
3162         } else {
3163                 if (parm_table[parmnum].p_class == P_GLOBAL) {
3164                         DEBUG(0,
3165                               ("Global parameter %s found in service section!\n",
3166                                pszParmName));
3167                         return true;
3168                 }
3169                 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
3170         }
3171
3172         if (snum >= 0) {
3173                 if (!ServicePtrs[snum]->copymap)
3174                         init_copymap(ServicePtrs[snum]);
3175
3176                 /* this handles the aliases - set the copymap for other entries with
3177                    the same data pointer */
3178                 for (i = 0; parm_table[i].label; i++) {
3179                         if ((parm_table[i].offset == parm_table[parmnum].offset)
3180                             && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
3181                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
3182                         }
3183                 }
3184         }
3185
3186         /* if it is a special case then go ahead */
3187         if (parm_table[parmnum].special) {
3188                 return parm_table[parmnum].special(NULL, snum, pszParmValue,
3189                                                    (char **)parm_ptr);
3190         }
3191
3192         /* now switch on the type of variable it is */
3193         switch (parm_table[parmnum].type)
3194         {
3195                 case P_BOOL:
3196                         *(bool *)parm_ptr = lp_bool(pszParmValue);
3197                         break;
3198
3199                 case P_BOOLREV:
3200                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
3201                         break;
3202
3203                 case P_INTEGER:
3204                         *(int *)parm_ptr = lp_int(pszParmValue);
3205                         break;
3206
3207                 case P_CHAR:
3208                         *(char *)parm_ptr = *pszParmValue;
3209                         break;
3210
3211                 case P_OCTAL:
3212                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3213                         if ( i != 1 ) {
3214                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3215                         }
3216                         break;
3217
3218                 case P_BYTES:
3219                 {
3220                         uint64_t val;
3221                         if (conv_str_size_error(pszParmValue, &val)) {
3222                                 if (val <= INT_MAX) {
3223                                         *(int *)parm_ptr = (int)val;
3224                                         break;
3225                                 }
3226                         }
3227
3228                         DEBUG(0,("lp_do_parameter(%s): value is not "
3229                             "a valid size specifier!\n", pszParmValue));
3230                         return false;
3231                 }
3232
3233                 case P_LIST:
3234                 case P_CMDLIST:
3235                         TALLOC_FREE(*((char ***)parm_ptr));
3236                         *(char ***)parm_ptr = str_list_make_v3(
3237                                 NULL, pszParmValue, NULL);
3238                         break;
3239
3240                 case P_STRING:
3241                         string_set((char **)parm_ptr, pszParmValue);
3242                         break;
3243
3244                 case P_USTRING:
3245                 {
3246                         char *upper_string = strupper_talloc(talloc_tos(), 
3247                                                              pszParmValue);
3248                         string_set((char **)parm_ptr, upper_string);
3249                         TALLOC_FREE(upper_string);
3250                         break;
3251                 }
3252                 case P_ENUM:
3253                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3254                         break;
3255                 case P_SEP:
3256                         break;
3257         }
3258
3259         return true;
3260 }
3261
3262 /***************************************************************************
3263 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
3264 FLAG_CMDLINE won't be overridden by loads from smb.conf.
3265 ***************************************************************************/
3266
3267 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
3268 {
3269         int parmnum, i;
3270         parmnum = map_parameter(pszParmName);
3271         if (parmnum >= 0) {
3272                 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
3273                 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
3274                         return false;
3275                 }
3276                 parm_table[parmnum].flags |= FLAG_CMDLINE;
3277
3278                 /* we have to also set FLAG_CMDLINE on aliases.  Aliases must
3279                  * be grouped in the table, so we don't have to search the
3280                  * whole table */
3281                 for (i=parmnum-1;
3282                      i>=0 && parm_table[i].offset == parm_table[parmnum].offset
3283                              && parm_table[i].p_class == parm_table[parmnum].p_class;
3284                      i--) {
3285                         parm_table[i].flags |= FLAG_CMDLINE;
3286                 }
3287                 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
3288                              && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
3289                         parm_table[i].flags |= FLAG_CMDLINE;
3290                 }
3291
3292                 if (store_values) {
3293                         store_lp_set_cmdline(pszParmName, pszParmValue);
3294                 }
3295                 return true;
3296         }
3297
3298         /* it might be parametric */
3299         if (strchr(pszParmName, ':') != NULL) {
3300                 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
3301                 if (store_values) {
3302                         store_lp_set_cmdline(pszParmName, pszParmValue);
3303                 }
3304                 return true;
3305         }
3306
3307         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
3308         return true;
3309 }
3310
3311 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
3312 {
3313         return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
3314 }
3315
3316 /***************************************************************************
3317  Process a parameter.
3318 ***************************************************************************/
3319
3320 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
3321                          void *userdata)
3322 {
3323         if (!bInGlobalSection && bGlobalOnly)
3324                 return true;
3325
3326         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3327
3328         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3329                                 pszParmName, pszParmValue));
3330 }
3331
3332 /*
3333   set a option from the commandline in 'a=b' format. Use to support --option
3334 */
3335 bool lp_set_option(const char *option)
3336 {
3337         char *p, *s;
3338         bool ret;
3339
3340         s = talloc_strdup(NULL, option);
3341         if (!s) {
3342                 return false;
3343         }
3344
3345         p = strchr(s, '=');
3346         if (!p) {
3347                 talloc_free(s);
3348                 return false;
3349         }
3350
3351         *p = 0;
3352
3353         /* skip white spaces after the = sign */
3354         do {
3355                 p++;
3356         } while (*p == ' ');
3357
3358         ret = lp_set_cmdline(s, p);
3359         talloc_free(s);
3360         return ret;
3361 }
3362
3363 /**************************************************************************
3364  Print a parameter of the specified type.
3365 ***************************************************************************/
3366
3367 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3368 {
3369         /* For the seperation of lists values that we print below */
3370         const char *list_sep = ", ";
3371         int i;
3372         switch (p->type)
3373         {
3374                 case P_ENUM:
3375                         for (i = 0; p->enum_list[i].name; i++) {
3376                                 if (*(int *)ptr == p->enum_list[i].value) {
3377                                         fprintf(f, "%s",
3378                                                 p->enum_list[i].name);
3379                                         break;
3380                                 }
3381                         }
3382                         break;
3383
3384                 case P_BOOL:
3385                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
3386                         break;
3387
3388                 case P_BOOLREV:
3389                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
3390                         break;
3391
3392                 case P_INTEGER:
3393                 case P_BYTES:
3394                         fprintf(f, "%d", *(int *)ptr);
3395                         break;
3396
3397                 case P_CHAR:
3398                         fprintf(f, "%c", *(char *)ptr);
3399                         break;
3400
3401                 case P_OCTAL: {
3402                         int val = *(int *)ptr; 
3403                         if (val == -1) {
3404                                 fprintf(f, "-1");
3405                         } else {
3406                                 fprintf(f, "0%o", val);
3407                         }
3408                         break;
3409                 }
3410
3411                 case P_CMDLIST:
3412                         list_sep = " ";
3413                         /* fall through */
3414                 case P_LIST:
3415                         if ((char ***)ptr && *(char ***)ptr) {
3416                                 char **list = *(char ***)ptr;
3417                                 for (; *list; list++) {
3418                                         /* surround strings with whitespace in double quotes */
3419                                         if (*(list+1) == NULL) {
3420                                                 /* last item, no extra separator */
3421                                                 list_sep = "";
3422                                         }
3423                                         if ( strchr_m( *list, ' ' ) ) {
3424                                                 fprintf(f, "\"%s\"%s", *list, list_sep);
3425                                         } else {
3426                                                 fprintf(f, "%s%s", *list, list_sep);
3427                                         }
3428                                 }
3429                         }
3430                         break;
3431
3432                 case P_STRING:
3433                 case P_USTRING:
3434                         if (*(char **)ptr) {
3435                                 fprintf(f, "%s", *(char **)ptr);
3436                         }
3437                         break;
3438                 case P_SEP:
3439                         break;
3440         }
3441 }
3442
3443 /***************************************************************************
3444  Check if two parameters are equal.
3445 ***************************************************************************/
3446
3447 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
3448 {
3449         switch (type) {
3450                 case P_BOOL:
3451                 case P_BOOLREV:
3452                         return (*((bool *)ptr1) == *((bool *)ptr2));
3453
3454                 case P_INTEGER:
3455                 case P_ENUM:
3456                 case P_OCTAL:
3457                 case P_BYTES:
3458                         return (*((int *)ptr1) == *((int *)ptr2));
3459
3460                 case P_CHAR:
3461                         return (*((char *)ptr1) == *((char *)ptr2));
3462
3463                 case P_LIST:
3464                 case P_CMDLIST:
3465                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
3466
3467                 case P_STRING:
3468                 case P_USTRING:
3469                 {
3470                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3471                         if (p1 && !*p1)
3472                                 p1 = NULL;
3473                         if (p2 && !*p2)
3474                                 p2 = NULL;
3475                         return (p1 == p2 || strequal(p1, p2));
3476                 }
3477                 case P_SEP:
3478                         break;
3479         }
3480         return false;
3481 }
3482
3483 /***************************************************************************
3484  Initialize any local varients in the sDefault table.
3485 ***************************************************************************/
3486
3487 void init_locals(void)
3488 {
3489         /* None as yet. */
3490 }
3491
3492 /***************************************************************************
3493  Process a new section (service). At this stage all sections are services.
3494  Later we'll have special sections that permit server parameters to be set.
3495  Returns true on success, false on failure.
3496 ***************************************************************************/
3497
3498 static bool do_section(const char *pszSectionName, void *userdata)
3499 {
3500         bool bRetval;
3501         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3502                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3503         bRetval = false;
3504
3505         /* if we were in a global section then do the local inits */
3506         if (bInGlobalSection && !isglobal)
3507                 init_locals();
3508
3509         /* if we've just struck a global section, note the fact. */
3510         bInGlobalSection = isglobal;
3511
3512         /* check for multiple global sections */
3513         if (bInGlobalSection) {
3514                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3515                 return true;
3516         }
3517
3518         if (!bInGlobalSection && bGlobalOnly)
3519                 return true;
3520
3521         /* if we have a current service, tidy it up before moving on */
3522         bRetval = true;
3523
3524         if (iServiceIndex >= 0)
3525                 bRetval = service_ok(iServiceIndex);
3526
3527         /* if all is still well, move to the next record in the services array */
3528         if (bRetval) {
3529                 /* We put this here to avoid an odd message order if messages are */
3530                 /* issued by the post-processing of a previous section. */
3531                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3532
3533                 iServiceIndex = add_a_service(&sDefault, pszSectionName);
3534                 if (iServiceIndex < 0) {
3535                         DEBUG(0, ("Failed to add a new service\n"));
3536                         return false;
3537                 }
3538                 /* Clean all parametric options for service */
3539                 /* They will be added during parsing again */
3540                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
3541         }
3542
3543         return bRetval;
3544 }
3545
3546
3547 /***************************************************************************
3548  Determine if a partcular base parameter is currentl set to the default value.
3549 ***************************************************************************/
3550
3551 static bool is_default(int i)
3552 {
3553         if (!defaults_saved)
3554                 return false;
3555         switch (parm_table[i].type) {
3556                 case P_LIST:
3557                 case P_CMDLIST:
3558                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
3559                                               *(const char ***)lp_parm_ptr(NULL, 
3560                                                                            &parm_table[i]));
3561                 case P_STRING:
3562                 case P_USTRING:
3563                         return strequal(parm_table[i].def.svalue,
3564                                         *(char **)lp_parm_ptr(NULL, 
3565                                                               &parm_table[i]));
3566                 case P_BOOL:
3567                 case P_BOOLREV:
3568                         return parm_table[i].def.bvalue ==
3569                                 *(bool *)lp_parm_ptr(NULL, 
3570                                                      &parm_table[i]);
3571                 case P_CHAR:
3572                         return parm_table[i].def.cvalue ==
3573                                 *(char *)lp_parm_ptr(NULL, 
3574                                                      &parm_table[i]);
3575                 case P_INTEGER:
3576                 case P_OCTAL:
3577                 case P_ENUM:
3578                 case P_BYTES:
3579                         return parm_table[i].def.ivalue ==
3580                                 *(int *)lp_parm_ptr(NULL, 
3581                                                     &parm_table[i]);
3582                 case P_SEP:
3583                         break;
3584         }
3585         return false;
3586 }
3587
3588 /***************************************************************************
3589 Display the contents of the global structure.
3590 ***************************************************************************/
3591
3592 static void dump_globals(FILE *f)
3593 {
3594         int i;
3595         struct parmlist_entry *data;
3596
3597         fprintf(f, "[global]\n");
3598
3599         for (i = 0; parm_table[i].label; i++)
3600                 if (parm_table[i].p_class == P_GLOBAL &&
3601                     !(parm_table[i].flags & FLAG_META) &&
3602                     (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
3603                         if (defaults_saved && is_default(i))
3604                                 continue;
3605                         fprintf(f, "\t%s = ", parm_table[i].label);
3606                         print_parameter(&parm_table[i], lp_parm_ptr(NULL, 
3607                                                                     &parm_table[i]),
3608                                         f);
3609                         fprintf(f, "\n");
3610         }
3611         if (Globals.param_opt != NULL) {
3612                 data = Globals.param_opt;
3613                 while(data) {
3614                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3615                         data = data->next;
3616                 }
3617         }
3618
3619 }
3620
3621 /***************************************************************************
3622  Return true if a local parameter is currently set to the global default.
3623 ***************************************************************************/
3624
3625 bool lp_is_default(int snum, struct parm_struct *parm)
3626 {
3627         return equal_parameter(parm->type,
3628                                lp_parm_ptr(ServicePtrs[snum], parm),
3629                                lp_parm_ptr(NULL, parm));
3630 }
3631
3632 /***************************************************************************
3633  Display the contents of a single services record.
3634 ***************************************************************************/
3635
3636 static void dump_a_service(struct loadparm_service *pService, FILE * f)
3637 {
3638         int i;
3639         struct parmlist_entry *data;
3640
3641         if (pService != &sDefault)
3642                 fprintf(f, "[%s]\n", pService->szService);
3643
3644         for (i = 0; parm_table[i].label; i++) {
3645
3646                 if (parm_table[i].p_class == P_LOCAL &&
3647                     !(parm_table[i].flags & FLAG_META) &&
3648                     (*parm_table[i].label != '-') &&
3649                     (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) 
3650                 {
3651                         if (pService == &sDefault) {
3652                                 if (defaults_saved && is_default(i))
3653                                         continue;
3654                         } else {
3655                                 if (equal_parameter(parm_table[i].type,
3656                                                     lp_parm_ptr(pService, &parm_table[i]),
3657                                                     lp_parm_ptr(NULL, &parm_table[i])))
3658                                         continue;
3659                         }
3660
3661                         fprintf(f, "\t%s = ", parm_table[i].label);
3662                         print_parameter(&parm_table[i],
3663                                         lp_parm_ptr(pService, &parm_table[i]),
3664                                         f);
3665                         fprintf(f, "\n");
3666                 }
3667         }
3668
3669                 if (pService->param_opt != NULL) {
3670                         data = pService->param_opt;
3671                         while(data) {
3672                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
3673                                 data = data->next;
3674                         }
3675                 }
3676 }
3677
3678 /***************************************************************************
3679  Display the contents of a parameter of a single services record.
3680 ***************************************************************************/
3681
3682 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
3683 {
3684         int i;
3685         bool result = false;
3686         parm_class p_class;
3687         unsigned flag = 0;
3688         fstring local_parm_name;
3689         char *parm_opt;
3690         const char *parm_opt_value;
3691
3692         /* check for parametrical option */
3693         fstrcpy( local_parm_name, parm_name);
3694         parm_opt = strchr( local_parm_name, ':');
3695
3696         if (parm_opt) {
3697                 *parm_opt = '\0';
3698                 parm_opt++;
3699                 if (strlen(parm_opt)) {
3700                         parm_opt_value = lp_parm_const_string( snum,
3701                                 local_parm_name, parm_opt, NULL);
3702                         if (parm_opt_value) {
3703                                 printf( "%s\n", parm_opt_value);
3704                                 result = true;
3705                         }
3706                 }
3707                 return result;
3708         }
3709
3710         /* check for a key and print the value */
3711         if (isGlobal) {
3712                 p_class = P_GLOBAL;
3713                 flag = FLAG_GLOBAL;
3714         } else
3715                 p_class = P_LOCAL;
3716
3717         for (i = 0; parm_table[i].label; i++) {
3718                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
3719                     !(parm_table[i].flags & FLAG_META) &&
3720                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
3721                     (*parm_table[i].label != '-') &&
3722                     (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) 
3723                 {
3724                         void *ptr;
3725
3726                         if (isGlobal) {
3727                                 ptr = lp_parm_ptr(NULL, 
3728                                                   &parm_table[i]);
3729                         } else {
3730                                 ptr = lp_parm_ptr(ServicePtrs[snum], 
3731                                                   &parm_table[i]);
3732                         }
3733
3734                         print_parameter(&parm_table[i],
3735                                         ptr, f);
3736                         fprintf(f, "\n");
3737                         result = true;
3738                         break;
3739                 }
3740         }
3741
3742         return result;
3743 }
3744
3745 /***************************************************************************
3746  Return info about the requested parameter (given as a string).
3747  Return NULL when the string is not a valid parameter name.
3748 ***************************************************************************/
3749
3750 struct parm_struct *lp_get_parameter(const char *param_name)
3751 {
3752         int num = map_parameter(param_name);
3753
3754         if (num < 0) {
3755                 return NULL;
3756         }
3757
3758         return &parm_table[num];
3759 }
3760
3761 /***************************************************************************
3762  Return info about the next parameter in a service.
3763  snum==GLOBAL_SECTION_SNUM gives the globals.
3764  Return NULL when out of parameters.
3765 ***************************************************************************/
3766
3767 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3768 {
3769         if (snum < 0) {
3770                 /* do the globals */
3771                 for (; parm_table[*i].label; (*i)++) {
3772                         if (parm_table[*i].p_class == P_SEPARATOR)
3773                                 return &parm_table[(*i)++];
3774
3775                         if ((*parm_table[*i].label == '-'))
3776                                 continue;
3777
3778                         if ((*i) > 0
3779                             && (parm_table[*i].offset ==
3780                                 parm_table[(*i) - 1].offset)
3781                             && (parm_table[*i].p_class ==
3782                                 parm_table[(*i) - 1].p_class))
3783                                 continue;
3784
3785                         if (is_default(*i) && !allparameters)
3786                                 continue;
3787
3788                         return &parm_table[(*i)++];
3789                 }
3790         } else {
3791                 struct loadparm_service *pService = ServicePtrs[snum];
3792
3793                 for (; parm_table[*i].label; (*i)++) {
3794                         if (parm_table[*i].p_class == P_SEPARATOR)
3795                                 return &parm_table[(*i)++];
3796
3797                         if (parm_table[*i].p_class == P_LOCAL &&
3798                             (*parm_table[*i].label != '-') &&
3799                             ((*i) == 0 ||
3800                              (parm_table[*i].offset !=
3801                               parm_table[(*i) - 1].offset)))
3802                         {
3803                                 if (allparameters ||
3804                                     !equal_parameter(parm_table[*i].type,
3805                                                      lp_parm_ptr(pService, 
3806                                                                  &parm_table[*i]),
3807                                                      lp_parm_ptr(NULL, 
3808                                                                  &parm_table[*i])))
3809                                 {
3810                                         return &parm_table[(*i)++];
3811                                 }
3812                         }
3813                 }
3814         }
3815
3816         return NULL;
3817 }
3818
3819
3820 #if 0
3821 /***************************************************************************
3822  Display the contents of a single copy structure.
3823 ***************************************************************************/
3824 static void dump_copy_map(bool *pcopymap)
3825 {
3826         int i;
3827         if (!pcopymap)
3828                 return;
3829
3830         printf("\n\tNon-Copied parameters:\n");
3831
3832         for (i = 0; parm_table[i].label; i++)
3833                 if (parm_table[i].p_class == P_LOCAL &&
3834                     parm_table[i].ptr && !pcopymap[i] &&
3835                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3836                 {
3837                         printf("\t\t%s\n", parm_table[i].label);
3838                 }
3839 }
3840 #endif
3841
3842 /***************************************************************************
3843  Return TRUE if the passed service number is within range.
3844 ***************************************************************************/
3845
3846 bool lp_snum_ok(int iService)
3847 {
3848         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3849 }
3850
3851 /***************************************************************************
3852  Auto-load some home services.
3853 ***************************************************************************/
3854
3855 static void lp_add_auto_services(char *str)
3856 {
3857         char *s;
3858         char *p;
3859         int homes;
3860         char *saveptr;
3861
3862         if (!str)
3863                 return;
3864
3865         s = SMB_STRDUP(str);
3866         if (!s)
3867                 return;
3868
3869         homes = lp_servicenumber(HOMES_NAME);
3870
3871         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3872              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3873                 char *home;
3874
3875                 if (lp_servicenumber(p) >= 0)
3876                         continue;
3877
3878                 home = get_user_home_dir(talloc_tos(), p);
3879
3880                 if (home && home[0] && homes >= 0)
3881                         lp_add_home(p, homes, p, home);
3882
3883                 TALLOC_FREE(home);
3884         }
3885         SAFE_FREE(s);
3886 }
3887
3888 /***************************************************************************
3889  Auto-load one printer.
3890 ***************************************************************************/
3891
3892 void lp_add_one_printer(const char *name, const char *comment,
3893                         const char *location, void *pdata)
3894 {
3895         int printers = lp_servicenumber(PRINTERS_NAME);
3896         int i;
3897
3898         if (lp_servicenumber(name) < 0) {
3899                 lp_add_printer(name, printers);
3900                 if ((i = lp_servicenumber(name)) >= 0) {
3901                         string_set(&ServicePtrs[i]->comment, comment);
3902                         ServicePtrs[i]->autoloaded = true;
3903                 }
3904         }
3905 }
3906
3907 /***************************************************************************
3908  Have we loaded a services file yet?
3909 ***************************************************************************/
3910
3911 bool lp_loaded(void)
3912 {
3913         return (bLoaded);
3914 }
3915
3916 /***************************************************************************
3917  Unload unused services.
3918 ***************************************************************************/
3919
3920 void lp_killunused(struct smbd_server_connection *sconn,
3921                    bool (*snumused) (struct smbd_server_connection *, int))
3922 {
3923         int i;
3924         for (i = 0; i < iNumServices; i++) {
3925                 if (!VALID(i))
3926                         continue;
3927
3928                 /* don't kill autoloaded or usershare services */
3929                 if ( ServicePtrs[i]->autoloaded ||
3930                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3931                         continue;
3932                 }
3933
3934                 if (!snumused || !snumused(sconn, i)) {
3935                         free_service_byindex(i);
3936                 }
3937         }
3938 }
3939
3940 /**
3941  * Kill all except autoloaded and usershare services - convenience wrapper
3942  */
3943 void lp_kill_all_services(void)
3944 {
3945         lp_killunused(NULL, NULL);
3946 }
3947
3948 /***************************************************************************
3949  Unload a service.
3950 ***************************************************************************/
3951
3952 void lp_killservice(int iServiceIn)
3953 {
3954         if (VALID(iServiceIn)) {
3955                 free_service_byindex(iServiceIn);
3956         }
3957 }
3958
3959 /***************************************************************************
3960  Save the curent values of all global and sDefault parameters into the 
3961  defaults union. This allows swat and testparm to show only the
3962  changed (ie. non-default) parameters.
3963 ***************************************************************************/
3964
3965 static void lp_save_defaults(void)
3966 {
3967         int i;
3968         for (i = 0; parm_table[i].label; i++) {
3969                 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3970                     && parm_table[i].p_class == parm_table[i - 1].p_class)
3971                         continue;
3972                 switch (parm_table[i].type) {
3973                         case P_LIST:
3974                         case P_CMDLIST:
3975                                 parm_table[i].def.lvalue = str_list_copy(
3976                                         NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3977                                 break;
3978                         case P_STRING:
3979                         case P_USTRING:
3980                                 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
3981                                 break;
3982                         case P_BOOL:
3983                         case P_BOOLREV:
3984                                 parm_table[i].def.bvalue =
3985                                         *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3986                                 break;
3987                         case P_CHAR:
3988                                 parm_table[i].def.cvalue =
3989                                         *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3990                                 break;
3991                         case P_INTEGER:
3992                         case P_OCTAL:
3993                         case P_ENUM:
3994                         case P_BYTES:
3995                                 parm_table[i].def.ivalue =
3996                                         *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3997                                 break;
3998                         case P_SEP:
3999                                 break;
4000                 }
4001         }
4002         defaults_saved = true;
4003 }
4004
4005 /***********************************************************
4006  If we should send plaintext/LANMAN passwords in the clinet
4007 ************************************************************/
4008
4009 static void set_allowed_client_auth(void)
4010 {
4011         if (Globals.bClientNTLMv2Auth) {
4012                 Globals.bClientLanManAuth = false;
4013         }
4014         if (!Globals.bClientLanManAuth) {
4015                 Globals.bClientPlaintextAuth = false;
4016         }
4017 }
4018
4019 /***************************************************************************
4020  JRA.
4021  The following code allows smbd to read a user defined share file.
4022  Yes, this is my intent. Yes, I'm comfortable with that...
4023
4024  THE FOLLOWING IS SECURITY CRITICAL CODE.
4025
4026  It washes your clothes, it cleans your house, it guards you while you sleep...
4027  Do not f%^k with it....
4028 ***************************************************************************/
4029
4030 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4031
4032 /***************************************************************************
4033  Check allowed stat state of a usershare file.
4034  Ensure we print out who is dicking with us so the admin can
4035  get their sorry ass fired.
4036 ***************************************************************************/
4037
4038 static bool check_usershare_stat(const char *fname,
4039                                  const SMB_STRUCT_STAT *psbuf)
4040 {
4041      &