s3-param: Remove never-reached condition for popts == NULL
[metze/samba/wip.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         if (!S_ISREG(psbuf->st_ex_mode)) {
4042                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4043                         "not a regular file\n",
4044                         fname, (unsigned int)psbuf->st_ex_uid ));
4045                 return false;
4046         }
4047
4048         /* Ensure this doesn't have the other write bit set. */
4049         if (psbuf->st_ex_mode & S_IWOTH) {
4050                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4051                         "public write. Refusing to allow as a usershare file.\n",
4052                         fname, (unsigned int)psbuf->st_ex_uid ));
4053                 return false;
4054         }
4055
4056         /* Should be 10k or less. */
4057         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
4058                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4059                         "too large (%u) to be a user share file.\n",
4060                         fname, (unsigned int)psbuf->st_ex_uid,
4061                         (unsigned int)psbuf->st_ex_size ));
4062                 return false;
4063         }
4064
4065         return true;
4066 }
4067
4068 /***************************************************************************
4069  Parse the contents of a usershare file.
4070 ***************************************************************************/
4071
4072 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4073                         SMB_STRUCT_STAT *psbuf,
4074                         const char *servicename,
4075                         int snum,
4076                         char **lines,
4077                         int numlines,
4078                         char **pp_sharepath,
4079                         char **pp_comment,
4080                         char **pp_cp_servicename,
4081                         struct security_descriptor **ppsd,
4082                         bool *pallow_guest)
4083 {
4084         const char **prefixallowlist = lp_usershare_prefix_allow_list();
4085         const char **prefixdenylist = lp_usershare_prefix_deny_list();
4086         int us_vers;
4087         DIR *dp;
4088         SMB_STRUCT_STAT sbuf;
4089         char *sharepath = NULL;
4090         char *comment = NULL;
4091
4092         *pp_sharepath = NULL;
4093         *pp_comment = NULL;
4094
4095         *pallow_guest = false;
4096
4097         if (numlines < 4) {
4098                 return USERSHARE_MALFORMED_FILE;
4099         }
4100
4101         if (strcmp(lines[0], "#VERSION 1") == 0) {
4102                 us_vers = 1;
4103         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4104                 us_vers = 2;
4105                 if (numlines < 5) {
4106                         return USERSHARE_MALFORMED_FILE;
4107                 }
4108         } else {
4109                 return USERSHARE_BAD_VERSION;
4110         }
4111
4112         if (strncmp(lines[1], "path=", 5) != 0) {
4113                 return USERSHARE_MALFORMED_PATH;
4114         }
4115
4116         sharepath = talloc_strdup(ctx, &lines[1][5]);
4117         if (!sharepath) {
4118                 return USERSHARE_POSIX_ERR;
4119         }
4120         trim_string(sharepath, " ", " ");
4121
4122         if (strncmp(lines[2], "comment=", 8) != 0) {
4123                 return USERSHARE_MALFORMED_COMMENT_DEF;
4124         }
4125
4126         comment = talloc_strdup(ctx, &lines[2][8]);
4127         if (!comment) {
4128                 return USERSHARE_POSIX_ERR;
4129         }
4130         trim_string(comment, " ", " ");
4131         trim_char(comment, '"', '"');
4132
4133         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4134                 return USERSHARE_MALFORMED_ACL_DEF;
4135         }
4136
4137         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4138                 return USERSHARE_ACL_ERR;
4139         }
4140
4141         if (us_vers == 2) {
4142                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4143                         return USERSHARE_MALFORMED_ACL_DEF;
4144                 }
4145                 if (lines[4][9] == 'y') {
4146                         *pallow_guest = true;
4147                 }
4148
4149                 /* Backwards compatible extension to file version #2. */
4150                 if (numlines > 5) {
4151                         if (strncmp(lines[5], "sharename=", 10) != 0) {
4152                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
4153                         }
4154                         if (!strequal(&lines[5][10], servicename)) {
4155                                 return USERSHARE_BAD_SHARENAME;
4156                         }
4157                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
4158                         if (!*pp_cp_servicename) {
4159                                 return USERSHARE_POSIX_ERR;
4160                         }
4161                 }
4162         }
4163
4164         if (*pp_cp_servicename == NULL) {
4165                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
4166                 if (!*pp_cp_servicename) {
4167                         return USERSHARE_POSIX_ERR;
4168                 }
4169         }
4170
4171         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4172                 /* Path didn't change, no checks needed. */
4173                 *pp_sharepath = sharepath;
4174                 *pp_comment = comment;
4175                 return USERSHARE_OK;
4176         }
4177
4178         /* The path *must* be absolute. */
4179         if (sharepath[0] != '/') {
4180                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4181                         servicename, sharepath));
4182                 return USERSHARE_PATH_NOT_ABSOLUTE;
4183         }
4184
4185         /* If there is a usershare prefix deny list ensure one of these paths
4186            doesn't match the start of the user given path. */
4187         if (prefixdenylist) {
4188                 int i;
4189                 for ( i=0; prefixdenylist[i]; i++ ) {
4190                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4191                                 servicename, i, prefixdenylist[i], sharepath ));
4192                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4193                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4194                                         "usershare prefix deny list entries.\n",
4195                                         servicename, sharepath));
4196                                 return USERSHARE_PATH_IS_DENIED;
4197                         }
4198                 }
4199         }
4200
4201         /* If there is a usershare prefix allow list ensure one of these paths
4202            does match the start of the user given path. */
4203
4204         if (prefixallowlist) {
4205                 int i;
4206                 for ( i=0; prefixallowlist[i]; i++ ) {
4207                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4208                                 servicename, i, prefixallowlist[i], sharepath ));
4209                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4210                                 break;
4211                         }
4212                 }
4213                 if (prefixallowlist[i] == NULL) {
4214                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4215                                 "usershare prefix allow list entries.\n",
4216                                 servicename, sharepath));
4217                         return USERSHARE_PATH_NOT_ALLOWED;
4218                 }
4219         }
4220
4221         /* Ensure this is pointing to a directory. */
4222         dp = opendir(sharepath);
4223
4224         if (!dp) {
4225                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4226                         servicename, sharepath));
4227                 return USERSHARE_PATH_NOT_DIRECTORY;
4228         }
4229
4230         /* Ensure the owner of the usershare file has permission to share
4231            this directory. */
4232
4233         if (sys_stat(sharepath, &sbuf, false) == -1) {
4234                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4235                         servicename, sharepath, strerror(errno) ));
4236                 closedir(dp);
4237                 return USERSHARE_POSIX_ERR;
4238         }
4239
4240         closedir(dp);
4241
4242         if (!S_ISDIR(sbuf.st_ex_mode)) {
4243                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4244                         servicename, sharepath ));
4245                 return USERSHARE_PATH_NOT_DIRECTORY;
4246         }
4247
4248         /* Check if sharing is restricted to owner-only. */
4249         /* psbuf is the stat of the usershare definition file,
4250            sbuf is the stat of the target directory to be shared. */
4251
4252         if (lp_usershare_owner_only()) {
4253                 /* root can share anything. */
4254                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
4255                         return USERSHARE_PATH_NOT_ALLOWED;
4256                 }
4257         }
4258
4259         *pp_sharepath = sharepath;
4260         *pp_comment = comment;
4261         return USERSHARE_OK;
4262 }
4263
4264 /***************************************************************************
4265  Deal with a usershare file.
4266  Returns:
4267         >= 0 - snum
4268         -1 - Bad name, invalid contents.
4269            - service name already existed and not a usershare, problem
4270             with permissions to share directory etc.
4271 ***************************************************************************/
4272
4273 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4274 {
4275         SMB_STRUCT_STAT sbuf;
4276         SMB_STRUCT_STAT lsbuf;
4277         char *fname = NULL;
4278         char *sharepath = NULL;
4279         char *comment = NULL;
4280         char *cp_service_name = NULL;
4281         char **lines = NULL;
4282         int numlines = 0;
4283         int fd = -1;
4284         int iService = -1;
4285         TALLOC_CTX *ctx = talloc_stackframe();
4286         struct security_descriptor *psd = NULL;
4287         bool guest_ok = false;
4288         char *canon_name = NULL;
4289         bool added_service = false;
4290         int ret = -1;
4291
4292         /* Ensure share name doesn't contain invalid characters. */
4293         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4294                 DEBUG(0,("process_usershare_file: share name %s contains "
4295                         "invalid characters (any of %s)\n",
4296                         file_name, INVALID_SHARENAME_CHARS ));
4297                 goto out;
4298         }
4299
4300         canon_name = canonicalize_servicename(ctx, file_name);
4301         if (!canon_name) {
4302                 goto out;
4303         }
4304
4305         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
4306         if (!fname) {
4307                 goto out;
4308         }
4309
4310         /* Minimize the race condition by doing an lstat before we
4311            open and fstat. Ensure this isn't a symlink link. */
4312
4313         if (sys_lstat(fname, &lsbuf, false) != 0) {
4314                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4315                         fname, strerror(errno) ));
4316                 goto out;
4317         }
4318
4319         /* This must be a regular file, not a symlink, directory or
4320            other strange filetype. */
4321         if (!check_usershare_stat(fname, &lsbuf)) {
4322                 goto out;
4323         }
4324
4325         {
4326                 TDB_DATA data;
4327                 NTSTATUS status;
4328
4329                 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
4330                                                canon_name, &data);
4331
4332                 iService = -1;
4333
4334                 if (NT_STATUS_IS_OK(status) &&
4335                     (data.dptr != NULL) &&
4336                     (data.dsize == sizeof(iService))) {
4337                         memcpy(&iService, data.dptr, sizeof(iService));
4338                 }
4339         }
4340
4341         if (iService != -1 &&
4342             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4343                              &lsbuf.st_ex_mtime) == 0) {
4344                 /* Nothing changed - Mark valid and return. */
4345                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4346                         canon_name ));
4347                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4348                 ret = iService;
4349                 goto out;
4350         }
4351
4352         /* Try and open the file read only - no symlinks allowed. */
4353 #ifdef O_NOFOLLOW
4354         fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
4355 #else
4356         fd = open(fname, O_RDONLY, 0);
4357 #endif
4358
4359         if (fd == -1) {
4360                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4361                         fname, strerror(errno) ));
4362                 goto out;
4363         }
4364
4365         /* Now fstat to be *SURE* it's a regular file. */
4366         if (sys_fstat(fd, &sbuf, false) != 0) {
4367                 close(fd);
4368                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4369                         fname, strerror(errno) ));
4370                 goto out;
4371         }
4372
4373         /* Is it the same dev/inode as was lstated ? */
4374         if (!check_same_stat(&lsbuf, &sbuf)) {
4375                 close(fd);
4376                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4377                         "Symlink spoofing going on ?\n", fname ));
4378                 goto out;
4379         }
4380
4381         /* This must be a regular file, not a symlink, directory or
4382            other strange filetype. */
4383         if (!check_usershare_stat(fname, &sbuf)) {
4384                 goto out;
4385         }
4386
4387         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
4388
4389         close(fd);
4390         if (lines == NULL) {
4391                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4392                         fname, (unsigned int)sbuf.st_ex_uid ));
4393                 goto out;
4394         }
4395
4396         if (parse_usershare_file(ctx, &sbuf, file_name,
4397                         iService, lines, numlines, &sharepath,
4398                         &comment, &cp_service_name,
4399                         &psd, &guest_ok) != USERSHARE_OK) {
4400                 goto out;
4401         }
4402
4403         /* Everything ok - add the service possibly using a template. */
4404         if (iService < 0) {
4405                 const struct loadparm_service *sp = &sDefault;
4406                 if (snum_template != -1) {
4407                         sp = ServicePtrs[snum_template];
4408                 }
4409
4410                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
4411                         DEBUG(0, ("process_usershare_file: Failed to add "
4412                                 "new service %s\n", cp_service_name));
4413                         goto out;
4414                 }
4415
4416                 added_service = true;
4417
4418                 /* Read only is controlled by usershare ACL below. */
4419                 ServicePtrs[iService]->bRead_only = false;
4420         }
4421
4422         /* Write the ACL of the new/modified share. */
4423         if (!set_share_security(canon_name, psd)) {
4424                  DEBUG(0, ("process_usershare_file: Failed to set share "
4425                         "security for user share %s\n",
4426                         canon_name ));
4427                 goto out;
4428         }
4429
4430         /* If from a template it may be marked invalid. */
4431         ServicePtrs[iService]->valid = true;
4432
4433         /* Set the service as a valid usershare. */
4434         ServicePtrs[iService]->usershare = USERSHARE_VALID;
4435
4436         /* Set guest access. */
4437         if (lp_usershare_allow_guests()) {
4438                 ServicePtrs[iService]->bGuest_ok = guest_ok;
4439         }
4440
4441         /* And note when it was loaded. */
4442         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
4443         string_set(&ServicePtrs[iService]->szPath, sharepath);
4444         string_set(&ServicePtrs[iService]->comment, comment);
4445
4446         ret = iService;
4447
4448   out:
4449
4450         if (ret == -1 && iService != -1 && added_service) {
4451                 lp_remove_service(iService);
4452         }
4453
4454         TALLOC_FREE(lines);
4455         TALLOC_FREE(ctx);
4456         return ret;
4457 }
4458
4459 /***************************************************************************
4460  Checks if a usershare entry has been modified since last load.
4461 ***************************************************************************/
4462
4463 static bool usershare_exists(int iService, struct timespec *last_mod)
4464 {
4465         SMB_STRUCT_STAT lsbuf;
4466         const char *usersharepath = Globals.szUsersharePath;
4467         char *fname;
4468
4469         if (asprintf(&fname, "%s/%s",
4470                                 usersharepath,
4471                                 ServicePtrs[iService]->szService) < 0) {
4472                 return false;
4473         }
4474
4475         if (sys_lstat(fname, &lsbuf, false) != 0) {
4476                 SAFE_FREE(fname);
4477                 return false;
4478         }
4479
4480         if (!S_ISREG(lsbuf.st_ex_mode)) {
4481                 SAFE_FREE(fname);
4482                 return false;
4483         }
4484
4485         SAFE_FREE(fname);
4486         *last_mod = lsbuf.st_ex_mtime;
4487         return true;
4488 }
4489
4490 /***************************************************************************
4491  Load a usershare service by name. Returns a valid servicenumber or -1.
4492 ***************************************************************************/
4493
4494 int load_usershare_service(const char *servicename)
4495 {
4496         SMB_STRUCT_STAT sbuf;
4497         const char *usersharepath = Globals.szUsersharePath;
4498         int max_user_shares = Globals.iUsershareMaxShares;
4499         int snum_template = -1;
4500
4501         if (*usersharepath == 0 ||  max_user_shares == 0) {
4502                 return -1;
4503         }
4504
4505         if (sys_stat(usersharepath, &sbuf, false) != 0) {
4506                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4507                         usersharepath, strerror(errno) ));
4508                 return -1;
4509         }
4510
4511         if (!S_ISDIR(sbuf.st_ex_mode)) {
4512                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4513                         usersharepath ));
4514                 return -1;
4515         }
4516
4517         /*
4518          * This directory must be owned by root, and have the 't' bit set.
4519          * It also must not be writable by "other".
4520          */
4521
4522 #ifdef S_ISVTX
4523         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4524 #else
4525         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4526 #endif
4527                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4528                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
4529                         usersharepath ));
4530                 return -1;
4531         }
4532
4533         /* Ensure the template share exists if it's set. */
4534         if (Globals.szUsershareTemplateShare[0]) {
4535                 /* We can't use lp_servicenumber here as we are recommending that
4536                    template shares have -valid=false set. */
4537                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4538                         if (ServicePtrs[snum_template]->szService &&
4539                                         strequal(ServicePtrs[snum_template]->szService,
4540                                                 Globals.szUsershareTemplateShare)) {
4541                                 break;
4542                         }
4543                 }
4544
4545                 if (snum_template == -1) {
4546                         DEBUG(0,("load_usershare_service: usershare template share %s "
4547                                 "does not exist.\n",
4548                                 Globals.szUsershareTemplateShare ));
4549                         return -1;
4550                 }
4551         }
4552
4553         return process_usershare_file(usersharepath, servicename, snum_template);
4554 }
4555
4556 /***************************************************************************
4557  Load all user defined shares from the user share directory.
4558  We only do this if we're enumerating the share list.
4559  This is the function that can delete usershares that have
4560  been removed.
4561 ***************************************************************************/
4562
4563 int load_usershare_shares(struct smbd_server_connection *sconn,
4564                           bool (*snumused) (struct smbd_server_connection *, int))
4565 {
4566         DIR *dp;
4567         SMB_STRUCT_STAT sbuf;
4568         struct dirent *de;
4569         int num_usershares = 0;
4570         int max_user_shares = Globals.iUsershareMaxShares;
4571         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4572         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4573         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4574         int iService;
4575         int snum_template = -1;
4576         const char *usersharepath = Globals.szUsersharePath;
4577         int ret = lp_numservices();
4578         TALLOC_CTX *tmp_ctx;
4579
4580         if (max_user_shares == 0 || *usersharepath == '\0') {
4581                 return lp_numservices();
4582         }
4583
4584         if (sys_stat(usersharepath, &sbuf, false) != 0) {
4585                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4586                         usersharepath, strerror(errno) ));
4587                 return ret;
4588         }
4589
4590         /*
4591          * This directory must be owned by root, and have the 't' bit set.
4592          * It also must not be writable by "other".
4593          */
4594
4595 #ifdef S_ISVTX
4596         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4597 #else
4598         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4599 #endif
4600                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4601                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
4602                         usersharepath ));
4603                 return ret;
4604         }
4605
4606         /* Ensure the template share exists if it's set. */
4607         if (Globals.szUsershareTemplateShare[0]) {
4608                 /* We can't use lp_servicenumber here as we are recommending that
4609                    template shares have -valid=false set. */
4610                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4611                         if (ServicePtrs[snum_template]->szService &&
4612                                         strequal(ServicePtrs[snum_template]->szService,
4613                                                 Globals.szUsershareTemplateShare)) {
4614                                 break;
4615                         }
4616                 }
4617
4618                 if (snum_template == -1) {
4619                         DEBUG(0,("load_usershare_shares: usershare template share %s "
4620                                 "does not exist.\n",
4621                                 Globals.szUsershareTemplateShare ));
4622                         return ret;
4623                 }
4624         }
4625
4626         /* Mark all existing usershares as pending delete. */
4627         for (iService = iNumServices - 1; iService >= 0; iService--) {
4628                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4629                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4630                 }
4631         }
4632
4633         dp = opendir(usersharepath);
4634         if (!dp) {
4635                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4636                         usersharepath, strerror(errno) ));
4637                 return ret;
4638         }
4639
4640         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4641                         (de = readdir(dp));
4642                         num_dir_entries++ ) {
4643                 int r;
4644                 const char *n = de->d_name;
4645
4646                 /* Ignore . and .. */
4647                 if (*n == '.') {
4648                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4649                                 continue;
4650                         }
4651                 }
4652
4653                 if (n[0] == ':') {
4654                         /* Temporary file used when creating a share. */
4655                         num_tmp_dir_entries++;
4656                 }
4657
4658                 /* Allow 20% tmp entries. */
4659                 if (num_tmp_dir_entries > allowed_tmp_entries) {
4660                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4661                                 "in directory %s\n",
4662                                 num_tmp_dir_entries, usersharepath));
4663                         break;
4664                 }
4665
4666                 r = process_usershare_file(usersharepath, n, snum_template);
4667                 if (r == 0) {
4668                         /* Update the services count. */
4669                         num_usershares++;
4670                         if (num_usershares >= max_user_shares) {
4671                                 DEBUG(0,("load_usershare_shares: max user shares reached "
4672                                         "on file %s in directory %s\n",
4673                                         n, usersharepath ));
4674                                 break;
4675                         }
4676                 } else if (r == -1) {
4677                         num_bad_dir_entries++;
4678                 }
4679
4680                 /* Allow 20% bad entries. */
4681                 if (num_bad_dir_entries > allowed_bad_entries) {
4682                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4683                                 "in directory %s\n",
4684                                 num_bad_dir_entries, usersharepath));
4685                         break;
4686                 }
4687
4688                 /* Allow 20% bad entries. */
4689                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4690                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4691                         "in directory %s\n",
4692                         num_dir_entries, usersharepath));
4693                         break;
4694                 }
4695         }
4696
4697         closedir(dp);
4698
4699         /* Sweep through and delete any non-refreshed usershares that are
4700            not currently in use. */
4701         tmp_ctx = talloc_stackframe();
4702         for (iService = iNumServices - 1; iService >= 0; iService--) {
4703                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4704                         char *servname;
4705
4706                         if (snumused && snumused(sconn, iService)) {
4707                                 continue;
4708                         }
4709
4710                         servname = lp_servicename(tmp_ctx, iService);
4711
4712                         /* Remove from the share ACL db. */
4713                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4714                                   servname ));
4715                         delete_share_security(servname);
4716                         free_service_byindex(iService);
4717                 }
4718         }
4719         talloc_free(tmp_ctx);
4720
4721         return lp_numservices();
4722 }
4723
4724 /********************************************************
4725  Destroy global resources allocated in this file
4726 ********************************************************/
4727
4728 void gfree_loadparm(void)
4729 {
4730         int i;
4731
4732         free_file_list();
4733
4734         /* Free resources allocated to services */
4735
4736         for ( i = 0; i < iNumServices; i++ ) {
4737                 if ( VALID(i) ) {
4738                         free_service_byindex(i);
4739                 }
4740         }
4741
4742         SAFE_FREE( ServicePtrs );
4743         iNumServices = 0;
4744
4745         /* Now release all resources allocated to global
4746            parameters and the default service */
4747
4748         free_global_parameters();
4749 }
4750
4751
4752 /***************************************************************************
4753  Allow client apps to specify that they are a client
4754 ***************************************************************************/
4755 static void lp_set_in_client(bool b)
4756 {
4757     in_client = b;
4758 }
4759
4760
4761 /***************************************************************************
4762  Determine if we're running in a client app
4763 ***************************************************************************/
4764 static bool lp_is_in_client(void)
4765 {
4766     return in_client;
4767 }
4768
4769 /***************************************************************************
4770  Load the services array from the services file. Return true on success,
4771  false on failure.
4772 ***************************************************************************/
4773
4774 static bool lp_load_ex(const char *pszFname,
4775                        bool global_only,
4776                        bool save_defaults,
4777                        bool add_ipc,
4778                        bool initialize_globals,
4779                        bool allow_include_registry,
4780                        bool load_all_shares)
4781 {
4782         char *n2 = NULL;
4783         bool bRetval;
4784
4785         bRetval = false;
4786
4787         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4788
4789         bInGlobalSection = true;
4790         bGlobalOnly = global_only;
4791         bAllowIncludeRegistry = allow_include_registry;
4792
4793         init_globals(initialize_globals);
4794
4795         free_file_list();
4796
4797         if (save_defaults) {
4798                 init_locals();
4799                 lp_save_defaults();
4800         }
4801
4802         if (!initialize_globals) {
4803                 free_param_opts(&Globals.param_opt);
4804                 apply_lp_set_cmdline();
4805         }
4806
4807         lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
4808
4809         /* We get sections first, so have to start 'behind' to make up */
4810         iServiceIndex = -1;
4811
4812         if (lp_config_backend_is_file()) {
4813                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4814                                         current_user_info.domain,
4815                                         pszFname);
4816                 if (!n2) {
4817                         smb_panic("lp_load_ex: out of memory");
4818                 }
4819
4820                 add_to_file_list(pszFname, n2);
4821
4822                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
4823                 TALLOC_FREE(n2);
4824
4825                 /* finish up the last section */
4826                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4827                 if (bRetval) {
4828                         if (iServiceIndex >= 0) {
4829                                 bRetval = service_ok(iServiceIndex);
4830                         }
4831                 }
4832
4833                 if (lp_config_backend_is_registry()) {
4834                         /* config backend changed to registry in config file */
4835                         /*
4836                          * We need to use this extra global variable here to
4837                          * survive restart: init_globals uses this as a default
4838                          * for ConfigBackend. Otherwise, init_globals would
4839                          *  send us into an endless loop here.
4840                          */
4841                         config_backend = CONFIG_BACKEND_REGISTRY;
4842                         /* start over */
4843                         DEBUG(1, ("lp_load_ex: changing to config backend "
4844                                   "registry\n"));
4845                         init_globals(true);
4846                         lp_kill_all_services();
4847                         return lp_load_ex(pszFname, global_only, save_defaults,
4848                                           add_ipc, initialize_globals,
4849                                           allow_include_registry,
4850                                           load_all_shares);
4851                 }
4852         } else if (lp_config_backend_is_registry()) {
4853                 bRetval = process_registry_globals();
4854         } else {
4855                 DEBUG(0, ("Illegal config  backend given: %d\n",
4856                           lp_config_backend()));
4857                 bRetval = false;
4858         }
4859
4860         if (bRetval && lp_registry_shares()) {
4861                 if (load_all_shares) {
4862                         bRetval = process_registry_shares();
4863                 } else {
4864                         bRetval = reload_registry_shares();
4865                 }
4866         }
4867
4868         {
4869                 char *serv = lp_auto_services(talloc_tos());
4870                 lp_add_auto_services(serv);
4871                 TALLOC_FREE(serv);
4872         }
4873
4874         if (add_ipc) {
4875                 /* When 'restrict anonymous = 2' guest connections to ipc$
4876                    are denied */
4877                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4878                 if ( lp_enable_asu_support() ) {
4879                         lp_add_ipc("ADMIN$", false);
4880                 }
4881         }
4882
4883         set_allowed_client_auth();
4884
4885         if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
4886                 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4887                           lp_passwordserver()));
4888         }
4889
4890         bLoaded = true;
4891
4892         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
4893         /* if bWINSsupport is true and we are in the client            */
4894         if (lp_is_in_client() && Globals.bWINSsupport) {
4895                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4896         }
4897
4898         init_iconv();
4899
4900         fault_configure(smb_panic_s3);
4901
4902         bAllowIncludeRegistry = true;
4903
4904         return (bRetval);
4905 }
4906
4907 bool lp_load(const char *pszFname,
4908              bool global_only,
4909              bool save_defaults,
4910              bool add_ipc,
4911              bool initialize_globals)
4912 {
4913         return lp_load_ex(pszFname,
4914                           global_only,
4915                           save_defaults,
4916                           add_ipc,
4917                           initialize_globals,
4918                           true,   /* allow_include_registry */
4919                           false); /* load_all_shares*/
4920 }
4921
4922 bool lp_load_initial_only(const char *pszFname)
4923 {
4924         return lp_load_ex(pszFname,
4925                           true,   /* global only */
4926                           false,  /* save_defaults */
4927                           false,  /* add_ipc */
4928                           true,   /* initialize_globals */
4929                           false,  /* allow_include_registry */
4930                           false); /* load_all_shares*/
4931 }
4932
4933 /**
4934  * most common lp_load wrapper, loading only the globals
4935  */
4936 bool lp_load_global(const char *file_name)
4937 {
4938         return lp_load_ex(file_name,
4939                           true,   /* global_only */
4940                           false,  /* save_defaults */
4941                           false,  /* add_ipc */
4942                           true,   /* initialize_globals */
4943                           true,   /* allow_include_registry */
4944                           false); /* load_all_shares*/
4945 }
4946
4947 /**
4948  * lp_load wrapper, especially for clients
4949  */
4950 bool lp_load_client(const char *file_name)
4951 {
4952         lp_set_in_client(true);
4953
4954         return lp_load_global(file_name);
4955 }
4956
4957 /**
4958  * lp_load wrapper, loading only globals, but intended
4959  * for subsequent calls, not reinitializing the globals
4960  * to default values
4961  */
4962 bool lp_load_global_no_reinit(const char *file_name)
4963 {
4964         return lp_load_ex(file_name,
4965                           true,   /* global_only */
4966                           false,  /* save_defaults */
4967                           false,  /* add_ipc */
4968                           false,  /* initialize_globals */
4969                           true,   /* allow_include_registry */
4970                           false); /* load_all_shares*/
4971 }
4972
4973 /**
4974  * lp_load wrapper, especially for clients, no reinitialization
4975  */
4976 bool lp_load_client_no_reinit(const char *file_name)
4977 {
4978         lp_set_in_client(true);
4979
4980         return lp_load_global_no_reinit(file_name);
4981 }
4982
4983 bool lp_load_with_registry_shares(const char *pszFname,
4984                                   bool global_only,
4985                                   bool save_defaults,
4986                                   bool add_ipc,
4987                                   bool initialize_globals)
4988 {
4989         return lp_load_ex(pszFname,
4990                           global_only,
4991                           save_defaults,
4992                           add_ipc,
4993                           initialize_globals,
4994                           true,  /* allow_include_registry */
4995                           true); /* load_all_shares*/
4996 }
4997
4998 /***************************************************************************
4999  Return the max number of services.
5000 ***************************************************************************/
5001
5002 int lp_numservices(void)
5003 {
5004         return (iNumServices);
5005 }
5006
5007 /***************************************************************************
5008 Display the contents of the services array in human-readable form.
5009 ***************************************************************************/
5010
5011 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
5012 {
5013         int iService;
5014
5015         if (show_defaults)
5016                 defaults_saved = false;
5017
5018         dump_globals(f);
5019
5020         dump_a_service(&sDefault, f);
5021
5022         for (iService = 0; iService < maxtoprint; iService++) {
5023                 fprintf(f,"\n");
5024                 lp_dump_one(f, show_defaults, iService);
5025         }
5026 }
5027
5028 /***************************************************************************
5029 Display the contents of one service in human-readable form.
5030 ***************************************************************************/
5031
5032 void lp_dump_one(FILE * f, bool show_defaults, int snum)
5033 {
5034         if (VALID(snum)) {
5035                 if (ServicePtrs[snum]->szService[0] == '\0')
5036                         return;
5037                 dump_a_service(ServicePtrs[snum], f);
5038         }
5039 }
5040
5041 /***************************************************************************
5042 Return the number of the service with the given name, or -1 if it doesn't
5043 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5044 getservicebyname()! This works ONLY if all services have been loaded, and
5045 does not copy the found service.
5046 ***************************************************************************/
5047
5048 int lp_servicenumber(const char *pszServiceName)
5049 {
5050         int iService;
5051         fstring serviceName;
5052
5053         if (!pszServiceName) {
5054                 return GLOBAL_SECTION_SNUM;
5055         }
5056
5057         for (iService = iNumServices - 1; iService >= 0; iService--) {
5058                 if (VALID(iService) && ServicePtrs[iService]->szService) {
5059                         /*
5060                          * The substitution here is used to support %U is
5061                          * service names
5062                          */
5063                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
5064                         standard_sub_basic(get_current_username(),
5065                                            current_user_info.domain,
5066                                            serviceName,sizeof(serviceName));
5067                         if (strequal(serviceName, pszServiceName)) {
5068                                 break;
5069                         }
5070                 }
5071         }
5072
5073         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5074                 struct timespec last_mod;
5075
5076                 if (!usershare_exists(iService, &last_mod)) {
5077                         /* Remove the share security tdb entry for it. */
5078                         delete_share_security(lp_servicename(talloc_tos(), iService));
5079                         /* Remove it from the array. */
5080                         free_service_byindex(iService);
5081                         /* Doesn't exist anymore. */
5082                         return GLOBAL_SECTION_SNUM;
5083                 }
5084
5085                 /* Has it been modified ? If so delete and reload. */
5086                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
5087                                      &last_mod) < 0) {
5088                         /* Remove it from the array. */
5089                         free_service_byindex(iService);
5090                         /* and now reload it. */
5091                         iService = load_usershare_service(pszServiceName);
5092                 }
5093         }
5094
5095         if (iService < 0) {
5096                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5097                 return GLOBAL_SECTION_SNUM;
5098         }
5099
5100         return (iService);
5101 }
5102
5103 /*******************************************************************
5104  A useful volume label function. 
5105 ********************************************************************/
5106
5107 const char *volume_label(TALLOC_CTX *ctx, int snum)
5108 {
5109         char *ret;
5110         const char *label = lp_volume(ctx, snum);
5111         if (!*label) {
5112                 label = lp_servicename(ctx, snum);
5113         }
5114
5115         /* This returns a 33 byte guarenteed null terminated string. */
5116         ret = talloc_strndup(ctx, label, 32);
5117         if (!ret) {
5118                 return "";
5119         }               
5120         return ret;
5121 }
5122
5123 /*******************************************************************
5124  Get the default server type we will announce as via nmbd.
5125 ********************************************************************/
5126
5127 int lp_default_server_announce(void)
5128 {
5129         int default_server_announce = 0;
5130         default_server_announce |= SV_TYPE_WORKSTATION;
5131         default_server_announce |= SV_TYPE_SERVER;
5132         default_server_announce |= SV_TYPE_SERVER_UNIX;
5133
5134         /* note that the flag should be set only if we have a 
5135            printer service but nmbd doesn't actually load the 
5136            services so we can't tell   --jerry */
5137
5138         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5139
5140         default_server_announce |= SV_TYPE_SERVER_NT;
5141         default_server_announce |= SV_TYPE_NT;
5142
5143         switch (lp_server_role()) {
5144                 case ROLE_DOMAIN_MEMBER:
5145                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5146                         break;
5147                 case ROLE_DOMAIN_PDC:
5148                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5149                         break;
5150                 case ROLE_DOMAIN_BDC:
5151                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5152                         break;
5153                 case ROLE_STANDALONE:
5154                 default:
5155                         break;
5156         }
5157         if (lp_time_server())
5158                 default_server_announce |= SV_TYPE_TIME_SOURCE;
5159
5160         if (lp_host_msdfs())
5161                 default_server_announce |= SV_TYPE_DFS_SERVER;
5162
5163         return default_server_announce;
5164 }
5165
5166 /***********************************************************
5167  If we are PDC then prefer us as DMB
5168 ************************************************************/
5169
5170 bool lp_domain_master(void)
5171 {
5172         if (Globals.domain_master == Auto)
5173                 return (lp_server_role() == ROLE_DOMAIN_PDC);
5174
5175         return (bool)Globals.domain_master;
5176 }
5177
5178 /***********************************************************
5179  If we are PDC then prefer us as DMB
5180 ************************************************************/
5181
5182 static bool lp_domain_master_true_or_auto(void)
5183 {
5184         if (Globals.domain_master) /* auto or yes */
5185                 return true;
5186
5187         return false;
5188 }
5189
5190 /***********************************************************
5191  If we are DMB then prefer us as LMB
5192 ************************************************************/
5193
5194 bool lp_preferred_master(void)
5195 {
5196         if (Globals.iPreferredMaster == Auto)
5197                 return (lp_local_master() && lp_domain_master());
5198
5199         return (bool)Globals.iPreferredMaster;
5200 }
5201
5202 /*******************************************************************
5203  Remove a service.
5204 ********************************************************************/
5205
5206 void lp_remove_service(int snum)
5207 {
5208         ServicePtrs[snum]->valid = false;
5209         invalid_services[num_invalid_services++] = snum;
5210 }
5211
5212 /*******************************************************************
5213  Copy a service.
5214 ********************************************************************/
5215
5216 void lp_copy_service(int snum, const char *new_name)
5217 {
5218         do_section(new_name, NULL);
5219         if (snum >= 0) {
5220                 snum = lp_servicenumber(new_name);
5221                 if (snum >= 0) {
5222                         char *name = lp_servicename(talloc_tos(), snum);
5223                         lp_do_parameter(snum, "copy", name);
5224                 }
5225         }
5226 }
5227
5228 const char *lp_printername(TALLOC_CTX *ctx, int snum)
5229 {
5230         const char *ret = lp__printername(talloc_tos(), snum);
5231         if (ret == NULL || *ret == '\0') {
5232                 ret = lp_const_servicename(snum);
5233         }
5234
5235         return ret;
5236 }
5237
5238
5239 /***********************************************************
5240  Allow daemons such as winbindd to fix their logfile name.
5241 ************************************************************/
5242
5243 void lp_set_logfile(const char *name)
5244 {
5245         string_set(&Globals.logfile, name);
5246         debug_set_logfile(name);
5247 }
5248
5249 /*******************************************************************
5250  Return the max print jobs per queue.
5251 ********************************************************************/
5252
5253 int lp_maxprintjobs(int snum)
5254 {
5255         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5256         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5257                 maxjobs = PRINT_MAX_JOBID - 1;
5258
5259         return maxjobs;
5260 }
5261
5262 const char *lp_printcapname(void)
5263 {
5264         if ((Globals.szPrintcapname != NULL) &&
5265             (Globals.szPrintcapname[0] != '\0'))
5266                 return Globals.szPrintcapname;
5267
5268         if (sDefault.iPrinting == PRINT_CUPS) {
5269 #ifdef HAVE_CUPS
5270                 return "cups";
5271 #else
5272                 return "lpstat";
5273 #endif
5274         }
5275
5276         if (sDefault.iPrinting == PRINT_BSD)
5277                 return "/etc/printcap";
5278
5279         return PRINTCAP_NAME;
5280 }
5281
5282 static uint32 spoolss_state;
5283
5284 bool lp_disable_spoolss( void )
5285 {
5286         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5287                 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5288
5289         return spoolss_state == SVCCTL_STOPPED ? true : false;
5290 }
5291
5292 void lp_set_spoolss_state( uint32 state )
5293 {
5294         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5295
5296         spoolss_state = state;
5297 }
5298
5299 uint32 lp_get_spoolss_state( void )
5300 {
5301         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5302 }
5303
5304 /*******************************************************************
5305  Ensure we don't use sendfile if server smb signing is active.
5306 ********************************************************************/
5307
5308 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
5309 {
5310         bool sign_active = false;
5311
5312         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5313         if (get_Protocol() < PROTOCOL_NT1) {
5314                 return false;
5315         }
5316         if (signing_state) {
5317                 sign_active = smb_signing_is_active(signing_state);
5318         }
5319         return (lp__use_sendfile(snum) &&
5320                         (get_remote_arch() != RA_WIN95) &&
5321                         !sign_active);
5322 }
5323
5324 /*******************************************************************
5325  Turn off sendfile if we find the underlying OS doesn't support it.
5326 ********************************************************************/
5327
5328 void set_use_sendfile(int snum, bool val)
5329 {
5330         if (LP_SNUM_OK(snum))
5331                 ServicePtrs[snum]->bUseSendfile = val;
5332         else
5333                 sDefault.bUseSendfile = val;
5334 }
5335
5336 /*******************************************************************
5337  Turn off storing DOS attributes if this share doesn't support it.
5338 ********************************************************************/
5339
5340 void set_store_dos_attributes(int snum, bool val)
5341 {
5342         if (!LP_SNUM_OK(snum))
5343                 return;
5344         ServicePtrs[(snum)]->bStoreDosAttributes = val;
5345 }
5346
5347 void lp_set_mangling_method(const char *new_method)
5348 {
5349         string_set(&Globals.szManglingMethod, new_method);
5350 }
5351
5352 /*******************************************************************
5353  Global state for POSIX pathname processing.
5354 ********************************************************************/
5355
5356 static bool posix_pathnames;
5357
5358 bool lp_posix_pathnames(void)
5359 {
5360         return posix_pathnames;
5361 }
5362
5363 /*******************************************************************
5364  Change everything needed to ensure POSIX pathname processing (currently
5365  not much).
5366 ********************************************************************/
5367
5368 void lp_set_posix_pathnames(void)
5369 {
5370         posix_pathnames = true;
5371 }
5372
5373 /*******************************************************************
5374  Global state for POSIX lock processing - CIFS unix extensions.
5375 ********************************************************************/
5376
5377 bool posix_default_lock_was_set;
5378 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5379
5380 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5381 {
5382         if (posix_default_lock_was_set) {
5383                 return posix_cifsx_locktype;
5384         } else {
5385                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5386         }
5387 }
5388
5389 /*******************************************************************
5390 ********************************************************************/
5391
5392 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5393 {
5394         posix_default_lock_was_set = true;
5395         posix_cifsx_locktype = val;
5396 }
5397
5398 int lp_min_receive_file_size(void)
5399 {
5400         if (Globals.iminreceivefile < 0) {
5401                 return 0;
5402         }
5403         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
5404 }
5405
5406 /*******************************************************************
5407  Safe wide links checks.
5408  This helper function always verify the validity of wide links,
5409  even after a configuration file reload.
5410 ********************************************************************/
5411
5412 static bool lp_widelinks_internal(int snum)
5413 {
5414         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
5415                         sDefault.bWidelinks);
5416 }
5417
5418 void widelinks_warning(int snum)
5419 {
5420         if (lp_allow_insecure_widelinks()) {
5421                 return;
5422         }
5423
5424         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
5425                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
5426                         "These parameters are incompatible. "
5427                         "Wide links will be disabled for this share.\n",
5428                          lp_servicename(talloc_tos(), snum) ));
5429         }
5430 }
5431
5432 bool lp_widelinks(int snum)
5433 {
5434         /* wide links is always incompatible with unix extensions */
5435         if (lp_unix_extensions()) {
5436                 /*
5437                  * Unless we have "allow insecure widelinks"
5438                  * turned on.
5439                  */
5440                 if (!lp_allow_insecure_widelinks()) {
5441                         return false;
5442                 }
5443         }
5444
5445         return lp_widelinks_internal(snum);
5446 }
5447
5448 bool lp_writeraw(void)
5449 {
5450         if (lp_async_smb_echo_handler()) {
5451                 return false;
5452         }
5453         return lp__writeraw();
5454 }
5455
5456 bool lp_readraw(void)
5457 {
5458         if (lp_async_smb_echo_handler()) {
5459                 return false;
5460         }
5461         return lp__readraw();
5462 }
5463
5464 int lp_server_role(void)
5465 {
5466         return lp_find_server_role(lp__server_role(),
5467                                    lp__security(),
5468                                    lp__domain_logons(),
5469                                    lp_domain_master_true_or_auto());
5470 }
5471
5472 int lp_security(void)
5473 {
5474         return lp_find_security(lp__server_role(),
5475                                 lp__security());
5476 }