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