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