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