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