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