s3-param use lp_parm_ptr() rather than parm.ptr directly
[ddiss/samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14    Copyright (C) Andrew Bartlett 2011
15
16    This program is free software; you can redistribute it and/or modify
17    it under the terms of the GNU General Public License as published by
18    the Free Software Foundation; either version 3 of the License, or
19    (at your option) any later version.
20
21    This program is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24    GNU General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with this program.  If not, see <http://www.gnu.org/licenses/>.
28 */
29
30 /*
31  *  Load parameters.
32  *
33  *  This module provides suitable callback functions for the params
34  *  module. It builds the internal table of service details which is
35  *  then used by the rest of the server.
36  *
37  * To add a parameter:
38  *
39  * 1) add it to the global or service structure definition
40  * 2) add it to the parm_table
41  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42  * 4) If it's a global then initialise it in init_globals. If a local
43  *    (ie. service) parameter then initialise it in the sDefault structure
44  *  
45  *
46  * Notes:
47  *   The configuration file is processed sequentially for speed. It is NOT
48  *   accessed randomly as happens in 'real' Windows. For this reason, there
49  *   is a fair bit of sequence-dependent code here - ie., code which assumes
50  *   that certain things happen before others. In particular, the code which
51  *   happens at the boundary between sections is delicately poised, so be
52  *   careful!
53  *
54  */
55
56 #include "includes.h"
57 #include "system/filesys.h"
58 #include "util_tdb.h"
59 #include "printing.h"
60 #include "lib/smbconf/smbconf.h"
61 #include "lib/smbconf/smbconf_init.h"
62
63 #include "ads.h"
64 #include "../librpc/gen_ndr/svcctl.h"
65 #include "intl.h"
66 #include "smb_signing.h"
67 #include "dbwrap.h"
68 #include "smbldap.h"
69
70 #ifdef HAVE_SYS_SYSCTL_H
71 #include <sys/sysctl.h>
72 #endif
73
74 #ifdef HAVE_HTTPCONNECTENCRYPT
75 #include <cups/http.h>
76 #endif
77
78 bool bLoaded = False;
79
80 extern userdom_struct current_user_info;
81
82 #ifndef GLOBAL_NAME
83 #define GLOBAL_NAME "global"
84 #endif
85
86 #ifndef PRINTERS_NAME
87 #define PRINTERS_NAME "printers"
88 #endif
89
90 #ifndef HOMES_NAME
91 #define HOMES_NAME "homes"
92 #endif
93
94 /* the special value for the include parameter
95  * to be interpreted not as a file name but to
96  * trigger loading of the global smb.conf options
97  * from registry. */
98 #ifndef INCLUDE_REGISTRY_NAME
99 #define INCLUDE_REGISTRY_NAME "registry"
100 #endif
101
102 static bool in_client = False;          /* Not in the client by default */
103 static struct smbconf_csn conf_last_csn;
104
105 #define CONFIG_BACKEND_FILE 0
106 #define CONFIG_BACKEND_REGISTRY 1
107
108 static int config_backend = CONFIG_BACKEND_FILE;
109
110 /* some helpful bits */
111 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
112 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
113
114 #define USERSHARE_VALID 1
115 #define USERSHARE_PENDING_DELETE 2
116
117 static bool defaults_saved = False;
118
119 struct param_opt_struct {
120         struct param_opt_struct *prev, *next;
121         char *key;
122         char *value;
123         char **list;
124         unsigned flags;
125 };
126
127 /*
128  * This structure describes global (ie., server-wide) parameters.
129  */
130 struct loadparm_global {
131         int ConfigBackend;
132         char *smb_ports;
133         char *dos_charset;
134         char *unix_charset;
135         char *szPrintcapname;
136         char *szAddPortCommand;
137         char *szEnumPortsCommand;
138         char *szAddPrinterCommand;
139         char *szDeletePrinterCommand;
140         char *szOs2DriverMap;
141         char *szLockDir;
142         char *szStateDir;
143         char *szCacheDir;
144         char *szPidDir;
145         char *szRootdir;
146         char *szDefaultService;
147         char *szGetQuota;
148         char *szSetQuota;
149         char *szMsgCommand;
150         char *szServerString;
151         char *szAutoServices;
152         char *szPasswdProgram;
153         char *szPasswdChat;
154         char *szLogFile;
155         char *szConfigFile;
156         char *szSMBPasswdFile;
157         char *szPrivateDir;
158         char *szPassdbBackend;
159         char **szPreloadModules;
160         char *szPasswordServer;
161         char *szSocketOptions;
162         char *szRealm;
163         char *szRealmUpper;
164         char *szDnsDomain;
165         char *szAfsUsernameMap;
166         int iAfsTokenLifetime;
167         char *szLogNtTokenCommand;
168         char *szUsernameMap;
169         char *szLogonScript;
170         char *szLogonPath;
171         char *szLogonDrive;
172         char *szLogonHome;
173         char **szWINSservers;
174         char **szInterfaces;
175         char *szRemoteAnnounce;
176         char *szRemoteBrowseSync;
177         char *szSocketAddress;
178         bool bNmbdBindExplicitBroadcast;
179         char *szNISHomeMapName;
180         char *szWorkgroup;
181         char *szNetbiosName;
182         char **szNetbiosAliases;
183         char *szNetbiosScope;
184         char *szNameResolveOrder;
185         char *szPanicAction;
186         char *szAddUserScript;
187         char *szRenameUserScript;
188         char *szDelUserScript;
189         char *szAddGroupScript;
190         char *szDelGroupScript;
191         char *szAddUserToGroupScript;
192         char *szDelUserFromGroupScript;
193         char *szSetPrimaryGroupScript;
194         char *szAddMachineScript;
195         char *szShutdownScript;
196         char *szAbortShutdownScript;
197         char *szUsernameMapScript;
198         int iUsernameMapCacheTime;
199         char *szCheckPasswordScript;
200         char *szWINSHook;
201         char *szUtmpDir;
202         char *szWtmpDir;
203         bool bUtmp;
204         char *szIdmapUID;
205         char *szIdmapGID;
206         bool bPassdbExpandExplicit;
207         int AlgorithmicRidBase;
208         char *szTemplateHomedir;
209         char *szTemplateShell;
210         char *szWinbindSeparator;
211         bool bWinbindEnumUsers;
212         bool bWinbindEnumGroups;
213         bool bWinbindUseDefaultDomain;
214         bool bWinbindTrustedDomainsOnly;
215         bool bWinbindNestedGroups;
216         int  winbind_expand_groups;
217         bool bWinbindRefreshTickets;
218         bool bWinbindOfflineLogon;
219         bool bWinbindNormalizeNames;
220         bool bWinbindRpcOnly;
221         bool bCreateKrb5Conf;
222         int winbindMaxDomainConnections;
223         char *szIdmapBackend;
224         bool bIdmapReadOnly;
225         char *szAddShareCommand;
226         char *szChangeShareCommand;
227         char *szDeleteShareCommand;
228         char **szEventLogs;
229         char *szGuestaccount;
230         char *szManglingMethod;
231         char **szServicesList;
232         char *szUsersharePath;
233         char *szUsershareTemplateShare;
234         char **szUsersharePrefixAllowList;
235         char **szUsersharePrefixDenyList;
236         int mangle_prefix;
237         int max_log_size;
238         char *szLogLevel;
239         int max_xmit;
240         int max_mux;
241         int max_open_files;
242         int open_files_db_hash_size;
243         int pwordlevel;
244         int unamelevel;
245         int deadtime;
246         bool getwd_cache;
247         int maxprotocol;
248         int minprotocol;
249         int security;
250         char **AuthMethods;
251         bool paranoid_server_security;
252         int maxdisksize;
253         int lpqcachetime;
254         int iMaxSmbdProcesses;
255         bool bDisableSpoolss;
256         int syslog;
257         int os_level;
258         bool enhanced_browsing;
259         int max_ttl;
260         int max_wins_ttl;
261         int min_wins_ttl;
262         int lm_announce;
263         int lm_interval;
264         int machine_password_timeout;
265         int map_to_guest;
266         int oplock_break_wait_time;
267         int winbind_cache_time;
268         int winbind_reconnect_delay;
269         int winbind_max_clients;
270         char **szWinbindNssInfo;
271         int iLockSpinTime;
272         char *szLdapMachineSuffix;
273         char *szLdapUserSuffix;
274         char *szLdapIdmapSuffix;
275         char *szLdapGroupSuffix;
276         int ldap_ssl;
277         bool ldap_ssl_ads;
278         int ldap_deref;
279         int ldap_follow_referral;
280         char *szLdapSuffix;
281         char *szLdapAdminDn;
282         int ldap_debug_level;
283         int ldap_debug_threshold;
284         int iAclCompat;
285         char *szCupsServer;
286         int CupsEncrypt;
287         char *szIPrintServer;
288         char *ctdbdSocket;
289         char **szClusterAddresses;
290         bool clustering;
291         int ctdb_timeout;
292         int ctdb_locktime_warn_threshold;
293         int ldap_passwd_sync;
294         int ldap_replication_sleep;
295         int ldap_timeout; /* This is initialised in init_globals */
296         int ldap_connection_timeout;
297         int ldap_page_size;
298         bool ldap_delete_dn;
299         bool bMsAddPrinterWizard;
300         bool bDNSproxy;
301         bool bWINSsupport;
302         bool bWINSproxy;
303         bool bLocalMaster;
304         int  iPreferredMaster;
305         int iDomainMaster;
306         bool bDomainLogons;
307         char **szInitLogonDelayedHosts;
308         int InitLogonDelay;
309         bool bEncryptPasswords;
310         bool bUpdateEncrypt;
311         int  clientSchannel;
312         int  serverSchannel;
313         bool bNullPasswords;
314         bool bObeyPamRestrictions;
315         bool bLoadPrinters;
316         int PrintcapCacheTime;
317         bool bLargeReadwrite;
318         bool bReadRaw;
319         bool bWriteRaw;
320         bool bSyslogOnly;
321         bool bBrowseList;
322         bool bNISHomeMap;
323         bool bTimeServer;
324         bool bBindInterfacesOnly;
325         bool bPamPasswordChange;
326         bool bUnixPasswdSync;
327         bool bPasswdChatDebug;
328         int iPasswdChatTimeout;
329         bool bTimestampLogs;
330         bool bNTSmbSupport;
331         bool bNTPipeSupport;
332         bool bNTStatusSupport;
333         bool bStatCache;
334         int iMaxStatCacheSize;
335         bool bKernelOplocks;
336         bool bAllowTrustedDomains;
337         bool bLanmanAuth;
338         bool bNTLMAuth;
339         bool bUseSpnego;
340         bool bClientLanManAuth;
341         bool bClientNTLMv2Auth;
342         bool bClientPlaintextAuth;
343         bool bClientUseSpnego;
344         bool client_use_spnego_principal;
345         bool send_spnego_principal;
346         bool bDebugPrefixTimestamp;
347         bool bDebugHiresTimestamp;
348         bool bDebugPid;
349         bool bDebugUid;
350         bool bDebugClass;
351         bool bEnableCoreFiles;
352         bool bHostMSDfs;
353         bool bUseMmap;
354         bool bHostnameLookups;
355         bool bUnixExtensions;
356         bool bDisableNetbios;
357         char * szDedicatedKeytabFile;
358         int  iKerberosMethod;
359         bool bDeferSharingViolations;
360         bool bEnablePrivileges;
361         bool bASUSupport;
362         bool bUsershareOwnerOnly;
363         bool bUsershareAllowGuests;
364         bool bRegistryShares;
365         int restrict_anonymous;
366         int name_cache_timeout;
367         int client_signing;
368         int server_signing;
369         int client_ldap_sasl_wrapping;
370         int iUsershareMaxShares;
371         int iIdmapCacheTime;
372         int iIdmapNegativeCacheTime;
373         bool bResetOnZeroVC;
374         bool bLogWriteableFilesOnExit;
375         int iKeepalive;
376         int iminreceivefile;
377         struct param_opt_struct *param_opt;
378         int cups_connection_timeout;
379         char *szSMBPerfcountModule;
380         bool bMapUntrustedToDomain;
381         bool bAsyncSMBEchoHandler;
382         bool bMulticastDnsRegister;
383         int ismb2_max_read;
384         int ismb2_max_write;
385         int ismb2_max_trans;
386         int ismb2_max_credits;
387         char *ncalrpc_dir;
388 };
389
390 static struct loadparm_global Globals;
391
392 /*
393  * This structure describes a single service.
394  */
395 struct loadparm_service {
396         bool valid;
397         bool autoloaded;
398         int usershare;
399         struct timespec usershare_last_mod;
400         char *szService;
401         char *szPath;
402         char *szUsername;
403         char **szInvalidUsers;
404         char **szValidUsers;
405         char **szAdminUsers;
406         char *szCopy;
407         char *szInclude;
408         char *szPreExec;
409         char *szPostExec;
410         char *szRootPreExec;
411         char *szRootPostExec;
412         char *szCupsOptions;
413         char *szPrintcommand;
414         char *szLpqcommand;
415         char *szLprmcommand;
416         char *szLppausecommand;
417         char *szLpresumecommand;
418         char *szQueuepausecommand;
419         char *szQueueresumecommand;
420         char *szPrintername;
421         char *szPrintjobUsername;
422         char *szDontdescend;
423         char **szHostsallow;
424         char **szHostsdeny;
425         char *szMagicScript;
426         char *szMagicOutput;
427         char *szVetoFiles;
428         char *szHideFiles;
429         char *szVetoOplockFiles;
430         char *comment;
431         char *force_user;
432         char *force_group;
433         char **readlist;
434         char **writelist;
435         char **printer_admin;
436         char *volume;
437         char *fstype;
438         char **szVfsObjects;
439         char *szMSDfsProxy;
440         char *szAioWriteBehind;
441         char *szDfree;
442         int iMinPrintSpace;
443         int iMaxPrintJobs;
444         int iMaxReportedPrintJobs;
445         int iWriteCacheSize;
446         int iCreate_mask;
447         int iCreate_force_mode;
448         int iSecurity_mask;
449         int iSecurity_force_mode;
450         int iDir_mask;
451         int iDir_force_mode;
452         int iDir_Security_mask;
453         int iDir_Security_force_mode;
454         int iMaxConnections;
455         int iDefaultCase;
456         int iPrinting;
457         int iOplockContentionLimit;
458         int iCSCPolicy;
459         int iBlock_size;
460         int iDfreeCacheTime;
461         bool bPreexecClose;
462         bool bRootpreexecClose;
463         int  iCaseSensitive;
464         bool bCasePreserve;
465         bool bShortCasePreserve;
466         bool bHideDotFiles;
467         bool bHideSpecialFiles;
468         bool bHideUnReadable;
469         bool bHideUnWriteableFiles;
470         bool bBrowseable;
471         bool bAccessBasedShareEnum;
472         bool bAvailable;
473         bool bRead_only;
474         bool bNo_set_dir;
475         bool bGuest_only;
476         bool bAdministrative_share;
477         bool bGuest_ok;
478         bool bPrint_ok;
479         bool bPrintNotifyBackchannel;
480         bool bMap_system;
481         bool bMap_hidden;
482         bool bMap_archive;
483         bool bStoreDosAttributes;
484         bool bDmapiSupport;
485         bool bLocking;
486         int iStrictLocking;
487         bool bPosixLocking;
488         bool bShareModes;
489         bool bOpLocks;
490         bool bLevel2OpLocks;
491         bool bOnlyUser;
492         bool bMangledNames;
493         bool bWidelinks;
494         bool bSymlinks;
495         bool bSyncAlways;
496         bool bStrictAllocate;
497         bool bStrictSync;
498         char magic_char;
499         struct bitmap *copymap;
500         bool bDeleteReadonly;
501         bool bFakeOplocks;
502         bool bDeleteVetoFiles;
503         bool bDosFilemode;
504         bool bDosFiletimes;
505         bool bDosFiletimeResolution;
506         bool bFakeDirCreateTimes;
507         bool bBlockingLocks;
508         bool bInheritPerms;
509         bool bInheritACLS;
510         bool bInheritOwner;
511         bool bMSDfsRoot;
512         bool bUseClientDriver;
513         bool bDefaultDevmode;
514         bool bForcePrintername;
515         bool bNTAclSupport;
516         bool bForceUnknownAclUser;
517         bool bUseSendfile;
518         bool bProfileAcls;
519         bool bMap_acl_inherit;
520         bool bAfs_Share;
521         bool bEASupport;
522         bool bAclCheckPermissions;
523         bool bAclMapFullControl;
524         bool bAclGroupControl;
525         bool bChangeNotify;
526         bool bKernelChangeNotify;
527         int iallocation_roundup_size;
528         int iAioReadSize;
529         int iAioWriteSize;
530         int iMap_readonly;
531         int iDirectoryNameCacheSize;
532         int ismb_encrypt;
533         struct param_opt_struct *param_opt;
534
535         char dummy[3];          /* for alignment */
536 };
537
538
539 /* This is a default service used to prime a services structure */
540 static struct loadparm_service sDefault = {
541         True,                   /* valid */
542         False,                  /* not autoloaded */
543         0,                      /* not a usershare */
544         {0, },                  /* No last mod time */
545         NULL,                   /* szService */
546         NULL,                   /* szPath */
547         NULL,                   /* szUsername */
548         NULL,                   /* szInvalidUsers */
549         NULL,                   /* szValidUsers */
550         NULL,                   /* szAdminUsers */
551         NULL,                   /* szCopy */
552         NULL,                   /* szInclude */
553         NULL,                   /* szPreExec */
554         NULL,                   /* szPostExec */
555         NULL,                   /* szRootPreExec */
556         NULL,                   /* szRootPostExec */
557         NULL,                   /* szCupsOptions */
558         NULL,                   /* szPrintcommand */
559         NULL,                   /* szLpqcommand */
560         NULL,                   /* szLprmcommand */
561         NULL,                   /* szLppausecommand */
562         NULL,                   /* szLpresumecommand */
563         NULL,                   /* szQueuepausecommand */
564         NULL,                   /* szQueueresumecommand */
565         NULL,                   /* szPrintername */
566         NULL,                   /* szPrintjobUsername */
567         NULL,                   /* szDontdescend */
568         NULL,                   /* szHostsallow */
569         NULL,                   /* szHostsdeny */
570         NULL,                   /* szMagicScript */
571         NULL,                   /* szMagicOutput */
572         NULL,                   /* szVetoFiles */
573         NULL,                   /* szHideFiles */
574         NULL,                   /* szVetoOplockFiles */
575         NULL,                   /* comment */
576         NULL,                   /* force user */
577         NULL,                   /* force group */
578         NULL,                   /* readlist */
579         NULL,                   /* writelist */
580         NULL,                   /* printer admin */
581         NULL,                   /* volume */
582         NULL,                   /* fstype */
583         NULL,                   /* vfs objects */
584         NULL,                   /* szMSDfsProxy */
585         NULL,                   /* szAioWriteBehind */
586         NULL,                   /* szDfree */
587         0,                      /* iMinPrintSpace */
588         1000,                   /* iMaxPrintJobs */
589         0,                      /* iMaxReportedPrintJobs */
590         0,                      /* iWriteCacheSize */
591         0744,                   /* iCreate_mask */
592         0000,                   /* iCreate_force_mode */
593         0777,                   /* iSecurity_mask */
594         0,                      /* iSecurity_force_mode */
595         0755,                   /* iDir_mask */
596         0000,                   /* iDir_force_mode */
597         0777,                   /* iDir_Security_mask */
598         0,                      /* iDir_Security_force_mode */
599         0,                      /* iMaxConnections */
600         CASE_LOWER,             /* iDefaultCase */
601         DEFAULT_PRINTING,       /* iPrinting */
602         2,                      /* iOplockContentionLimit */
603         0,                      /* iCSCPolicy */
604         1024,                   /* iBlock_size */
605         0,                      /* iDfreeCacheTime */
606         False,                  /* bPreexecClose */
607         False,                  /* bRootpreexecClose */
608         Auto,                   /* case sensitive */
609         True,                   /* case preserve */
610         True,                   /* short case preserve */
611         True,                   /* bHideDotFiles */
612         False,                  /* bHideSpecialFiles */
613         False,                  /* bHideUnReadable */
614         False,                  /* bHideUnWriteableFiles */
615         True,                   /* bBrowseable */
616         False,                  /* bAccessBasedShareEnum */
617         True,                   /* bAvailable */
618         True,                   /* bRead_only */
619         True,                   /* bNo_set_dir */
620         False,                  /* bGuest_only */
621         False,                  /* bAdministrative_share */
622         False,                  /* bGuest_ok */
623         False,                  /* bPrint_ok */
624         True,                   /* bPrintNotifyBackchannel */
625         False,                  /* bMap_system */
626         False,                  /* bMap_hidden */
627         True,                   /* bMap_archive */
628         False,                  /* bStoreDosAttributes */
629         False,                  /* bDmapiSupport */
630         True,                   /* bLocking */
631         Auto,                   /* iStrictLocking */
632         True,                   /* bPosixLocking */
633         True,                   /* bShareModes */
634         True,                   /* bOpLocks */
635         True,                   /* bLevel2OpLocks */
636         False,                  /* bOnlyUser */
637         True,                   /* bMangledNames */
638         false,                  /* bWidelinks */
639         True,                   /* bSymlinks */
640         False,                  /* bSyncAlways */
641         False,                  /* bStrictAllocate */
642         False,                  /* bStrictSync */
643         '~',                    /* magic char */
644         NULL,                   /* copymap */
645         False,                  /* bDeleteReadonly */
646         False,                  /* bFakeOplocks */
647         False,                  /* bDeleteVetoFiles */
648         False,                  /* bDosFilemode */
649         True,                   /* bDosFiletimes */
650         False,                  /* bDosFiletimeResolution */
651         False,                  /* bFakeDirCreateTimes */
652         True,                   /* bBlockingLocks */
653         False,                  /* bInheritPerms */
654         False,                  /* bInheritACLS */
655         False,                  /* bInheritOwner */
656         False,                  /* bMSDfsRoot */
657         False,                  /* bUseClientDriver */
658         True,                   /* bDefaultDevmode */
659         False,                  /* bForcePrintername */
660         True,                   /* bNTAclSupport */
661         False,                  /* bForceUnknownAclUser */
662         False,                  /* bUseSendfile */
663         False,                  /* bProfileAcls */
664         False,                  /* bMap_acl_inherit */
665         False,                  /* bAfs_Share */
666         False,                  /* bEASupport */
667         True,                   /* bAclCheckPermissions */
668         True,                   /* bAclMapFullControl */
669         False,                  /* bAclGroupControl */
670         True,                   /* bChangeNotify */
671         True,                   /* bKernelChangeNotify */
672         SMB_ROUNDUP_ALLOCATION_SIZE,            /* iallocation_roundup_size */
673         0,                      /* iAioReadSize */
674         0,                      /* iAioWriteSize */
675         MAP_READONLY_YES,       /* iMap_readonly */
676 #ifdef BROKEN_DIRECTORY_HANDLING
677         0,                      /* iDirectoryNameCacheSize */
678 #else
679         100,                    /* iDirectoryNameCacheSize */
680 #endif
681         Auto,                   /* ismb_encrypt */
682         NULL,                   /* Parametric options */
683
684         ""                      /* dummy */
685 };
686
687 /* local variables */
688 static struct loadparm_service **ServicePtrs = NULL;
689 static int iNumServices = 0;
690 static int iServiceIndex = 0;
691 static struct db_context *ServiceHash;
692 static int *invalid_services = NULL;
693 static int num_invalid_services = 0;
694 static bool bInGlobalSection = True;
695 static bool bGlobalOnly = False;
696 static int default_server_announce;
697
698 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
699
700 /* prototypes for the special type handlers */
701 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
702 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
703 static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr);
704 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
705 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
706 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
707 static bool handle_realm( int snum, const char *pszParmValue, char **ptr );
708 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
709 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
710 static bool handle_dos_charset( int snum, const char *pszParmValue, char **ptr );
711 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
712 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
713
714 static void set_default_server_announce_type(void);
715 static void set_allowed_client_auth(void);
716
717 static void add_to_file_list(const char *fname, const char *subfname);
718 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
719
720 static const struct enum_list enum_protocol[] = {
721         {PROTOCOL_SMB2, "SMB2"},
722         {PROTOCOL_NT1, "NT1"},
723         {PROTOCOL_LANMAN2, "LANMAN2"},
724         {PROTOCOL_LANMAN1, "LANMAN1"},
725         {PROTOCOL_CORE, "CORE"},
726         {PROTOCOL_COREPLUS, "COREPLUS"},
727         {PROTOCOL_COREPLUS, "CORE+"},
728         {-1, NULL}
729 };
730
731 static const struct enum_list enum_security[] = {
732         {SEC_SHARE, "SHARE"},
733         {SEC_USER, "USER"},
734         {SEC_SERVER, "SERVER"},
735         {SEC_DOMAIN, "DOMAIN"},
736 #ifdef HAVE_ADS
737         {SEC_ADS, "ADS"},
738 #endif
739         {-1, NULL}
740 };
741
742 static const struct enum_list enum_printing[] = {
743         {PRINT_SYSV, "sysv"},
744         {PRINT_AIX, "aix"},
745         {PRINT_HPUX, "hpux"},
746         {PRINT_BSD, "bsd"},
747         {PRINT_QNX, "qnx"},
748         {PRINT_PLP, "plp"},
749         {PRINT_LPRNG, "lprng"},
750         {PRINT_CUPS, "cups"},
751         {PRINT_IPRINT, "iprint"},
752         {PRINT_LPRNT, "nt"},
753         {PRINT_LPROS2, "os2"},
754 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
755         {PRINT_TEST, "test"},
756         {PRINT_VLP, "vlp"},
757 #endif /* DEVELOPER */
758         {-1, NULL}
759 };
760
761 static const struct enum_list enum_ldap_sasl_wrapping[] = {
762         {0, "plain"},
763         {ADS_AUTH_SASL_SIGN, "sign"},
764         {ADS_AUTH_SASL_SEAL, "seal"},
765         {-1, NULL}
766 };
767
768 static const struct enum_list enum_ldap_ssl[] = {
769         {LDAP_SSL_OFF, "no"},
770         {LDAP_SSL_OFF, "off"},
771         {LDAP_SSL_START_TLS, "start tls"},
772         {LDAP_SSL_START_TLS, "start_tls"},
773         {-1, NULL}
774 };
775
776 /* LDAP Dereferencing Alias types */
777 #define SAMBA_LDAP_DEREF_NEVER          0
778 #define SAMBA_LDAP_DEREF_SEARCHING      1
779 #define SAMBA_LDAP_DEREF_FINDING        2
780 #define SAMBA_LDAP_DEREF_ALWAYS         3
781
782 static const struct enum_list enum_ldap_deref[] = {
783         {SAMBA_LDAP_DEREF_NEVER, "never"},
784         {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
785         {SAMBA_LDAP_DEREF_FINDING, "finding"},
786         {SAMBA_LDAP_DEREF_ALWAYS, "always"},
787         {-1, "auto"}
788 };
789
790 static const struct enum_list enum_ldap_passwd_sync[] = {
791         {LDAP_PASSWD_SYNC_OFF, "no"},
792         {LDAP_PASSWD_SYNC_OFF, "off"},
793         {LDAP_PASSWD_SYNC_ON, "yes"},
794         {LDAP_PASSWD_SYNC_ON, "on"},
795         {LDAP_PASSWD_SYNC_ONLY, "only"},
796         {-1, NULL}
797 };
798
799 static const struct enum_list enum_map_readonly[] = {
800         {MAP_READONLY_NO, "no"},
801         {MAP_READONLY_NO, "false"},
802         {MAP_READONLY_NO, "0"},
803         {MAP_READONLY_YES, "yes"},
804         {MAP_READONLY_YES, "true"},
805         {MAP_READONLY_YES, "1"},
806         {MAP_READONLY_PERMISSIONS, "permissions"},
807         {MAP_READONLY_PERMISSIONS, "perms"},
808         {-1, NULL}
809 };
810
811 static const struct enum_list enum_case[] = {
812         {CASE_LOWER, "lower"},
813         {CASE_UPPER, "upper"},
814         {-1, NULL}
815 };
816
817
818
819 static const struct enum_list enum_bool_auto[] = {
820         {False, "No"},
821         {False, "False"},
822         {False, "0"},
823         {True, "Yes"},
824         {True, "True"},
825         {True, "1"},
826         {Auto, "Auto"},
827         {-1, NULL}
828 };
829
830 static const struct enum_list enum_csc_policy[] = {
831         {CSC_POLICY_MANUAL, "manual"},
832         {CSC_POLICY_DOCUMENTS, "documents"},
833         {CSC_POLICY_PROGRAMS, "programs"},
834         {CSC_POLICY_DISABLE, "disable"},
835         {-1, NULL}
836 };
837
838 /* SMB signing types. */
839 static const struct enum_list enum_smb_signing_vals[] = {
840         {False, "No"},
841         {False, "False"},
842         {False, "0"},
843         {False, "Off"},
844         {False, "disabled"},
845         {True, "Yes"},
846         {True, "True"},
847         {True, "1"},
848         {True, "On"},
849         {True, "enabled"},
850         {Auto, "auto"},
851         {Required, "required"},
852         {Required, "mandatory"},
853         {Required, "force"},
854         {Required, "forced"},
855         {Required, "enforced"},
856         {-1, NULL}
857 };
858
859 /* ACL compatibility options. */
860 static const struct enum_list enum_acl_compat_vals[] = {
861     { ACL_COMPAT_AUTO, "auto" },
862     { ACL_COMPAT_WINNT, "winnt" },
863     { ACL_COMPAT_WIN2K, "win2k" },
864     { -1, NULL}
865 };
866
867 /* 
868    Do you want session setups at user level security with a invalid
869    password to be rejected or allowed in as guest? WinNT rejects them
870    but it can be a pain as it means "net view" needs to use a password
871
872    You have 3 choices in the setting of map_to_guest:
873
874    "Never" means session setups with an invalid password
875    are rejected. This is the default.
876
877    "Bad User" means session setups with an invalid password
878    are rejected, unless the username does not exist, in which case it
879    is treated as a guest login
880
881    "Bad Password" means session setups with an invalid password
882    are treated as a guest login
883
884    Note that map_to_guest only has an effect in user or server
885    level security.
886 */
887
888 static const struct enum_list enum_map_to_guest[] = {
889         {NEVER_MAP_TO_GUEST, "Never"},
890         {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
891         {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
892         {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
893         {-1, NULL}
894 };
895
896 /* Config backend options */
897
898 static const struct enum_list enum_config_backend[] = {
899         {CONFIG_BACKEND_FILE, "file"},
900         {CONFIG_BACKEND_REGISTRY, "registry"},
901         {-1, NULL}
902 };
903
904 /* ADS kerberos ticket verification options */
905
906 static const struct enum_list enum_kerberos_method[] = {
907         {KERBEROS_VERIFY_SECRETS, "default"},
908         {KERBEROS_VERIFY_SECRETS, "secrets only"},
909         {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
910         {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
911         {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
912         {-1, NULL}
913 };
914
915 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
916  *
917  * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
918  * screen in SWAT. This is used to exclude parameters as well as to squash all
919  * parameters that have been duplicated by pseudonyms.
920  *
921  * NOTE: To display a parameter in BASIC view set FLAG_BASIC
922  *       Any parameter that does NOT have FLAG_ADVANCED will not disply at all
923  *       Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
924  *        respective views.
925  *
926  * NOTE2: Handling of duplicated (synonym) parameters:
927  *      Only the first occurance of a parameter should be enabled by FLAG_BASIC
928  *      and/or FLAG_ADVANCED. All duplicates following the first mention should be
929  *      set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
930  *      name first, and all synonyms must follow it with the FLAG_HIDE attribute.
931  */
932
933 static struct parm_struct parm_table[] = {
934         {N_("Base Options"), P_SEP, P_SEPARATOR},
935
936         {
937                 .label          = "dos charset",
938                 .type           = P_STRING,
939                 .p_class        = P_GLOBAL,
940                 .ptr            = &Globals.dos_charset,
941                 .special        = handle_dos_charset,
942                 .enum_list      = NULL,
943                 .flags          = FLAG_ADVANCED
944         },
945         {
946                 .label          = "unix charset",
947                 .type           = P_STRING,
948                 .p_class        = P_GLOBAL,
949                 .ptr            = &Globals.unix_charset,
950                 .special        = handle_charset,
951                 .enum_list      = NULL,
952                 .flags          = FLAG_ADVANCED
953         },
954         {
955                 .label          = "comment",
956                 .type           = P_STRING,
957                 .p_class        = P_LOCAL,
958                 .ptr            = &sDefault.comment,
959                 .special        = NULL,
960                 .enum_list      = NULL,
961                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
962         },
963         {
964                 .label          = "path",
965                 .type           = P_STRING,
966                 .p_class        = P_LOCAL,
967                 .ptr            = &sDefault.szPath,
968                 .special        = NULL,
969                 .enum_list      = NULL,
970                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
971         },
972         {
973                 .label          = "directory",
974                 .type           = P_STRING,
975                 .p_class        = P_LOCAL,
976                 .ptr            = &sDefault.szPath,
977                 .special        = NULL,
978                 .enum_list      = NULL,
979                 .flags          = FLAG_HIDE,
980         },
981         {
982                 .label          = "workgroup",
983                 .type           = P_USTRING,
984                 .p_class        = P_GLOBAL,
985                 .ptr            = &Globals.szWorkgroup,
986                 .special        = NULL,
987                 .enum_list      = NULL,
988                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
989         },
990         {
991                 .label          = "realm",
992                 .type           = P_USTRING,
993                 .p_class        = P_GLOBAL,
994                 .ptr            = &Globals.szRealm,
995                 .special        = handle_realm,
996                 .enum_list      = NULL,
997                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
998         },
999         {
1000                 .label          = "netbios name",
1001                 .type           = P_USTRING,
1002                 .p_class        = P_GLOBAL,
1003                 .ptr            = &Globals.szNetbiosName,
1004                 .special        = NULL,
1005                 .enum_list      = NULL,
1006                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1007         },
1008         {
1009                 .label          = "netbios aliases",
1010                 .type           = P_LIST,
1011                 .p_class        = P_GLOBAL,
1012                 .ptr            = &Globals.szNetbiosAliases,
1013                 .special        = handle_netbios_aliases,
1014                 .enum_list      = NULL,
1015                 .flags          = FLAG_ADVANCED,
1016         },
1017         {
1018                 .label          = "netbios scope",
1019                 .type           = P_USTRING,
1020                 .p_class        = P_GLOBAL,
1021                 .ptr            = &Globals.szNetbiosScope,
1022                 .special        = NULL,
1023                 .enum_list      = NULL,
1024                 .flags          = FLAG_ADVANCED,
1025         },
1026         {
1027                 .label          = "server string",
1028                 .type           = P_STRING,
1029                 .p_class        = P_GLOBAL,
1030                 .ptr            = &Globals.szServerString,
1031                 .special        = NULL,
1032                 .enum_list      = NULL,
1033                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
1034         },
1035         {
1036                 .label          = "interfaces",
1037                 .type           = P_LIST,
1038                 .p_class        = P_GLOBAL,
1039                 .ptr            = &Globals.szInterfaces,
1040                 .special        = NULL,
1041                 .enum_list      = NULL,
1042                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1043         },
1044         {
1045                 .label          = "bind interfaces only",
1046                 .type           = P_BOOL,
1047                 .p_class        = P_GLOBAL,
1048                 .ptr            = &Globals.bBindInterfacesOnly,
1049                 .special        = NULL,
1050                 .enum_list      = NULL,
1051                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
1052         },
1053         {
1054                 .label          = "config backend",
1055                 .type           = P_ENUM,
1056                 .p_class        = P_GLOBAL,
1057                 .ptr            = &Globals.ConfigBackend,
1058                 .special        = NULL,
1059                 .enum_list      = enum_config_backend,
1060                 .flags          = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1061         },
1062
1063         {N_("Security Options"), P_SEP, P_SEPARATOR},
1064
1065         {
1066                 .label          = "security",
1067                 .type           = P_ENUM,
1068                 .p_class        = P_GLOBAL,
1069                 .ptr            = &Globals.security,
1070                 .special        = NULL,
1071                 .enum_list      = enum_security,
1072                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1073         },
1074         {
1075                 .label          = "auth methods",
1076                 .type           = P_LIST,
1077                 .p_class        = P_GLOBAL,
1078                 .ptr            = &Globals.AuthMethods,
1079                 .special        = NULL,
1080                 .enum_list      = NULL,
1081                 .flags          = FLAG_ADVANCED,
1082         },
1083         {
1084                 .label          = "encrypt passwords",
1085                 .type           = P_BOOL,
1086                 .p_class        = P_GLOBAL,
1087                 .ptr            = &Globals.bEncryptPasswords,
1088                 .special        = NULL,
1089                 .enum_list      = NULL,
1090                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1091         },
1092         {
1093                 .label          = "client schannel",
1094                 .type           = P_ENUM,
1095                 .p_class        = P_GLOBAL,
1096                 .ptr            = &Globals.clientSchannel,
1097                 .special        = NULL,
1098                 .enum_list      = enum_bool_auto,
1099                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
1100         },
1101         {
1102                 .label          = "server schannel",
1103                 .type           = P_ENUM,
1104                 .p_class        = P_GLOBAL,
1105                 .ptr            = &Globals.serverSchannel,
1106                 .special        = NULL,
1107                 .enum_list      = enum_bool_auto,
1108                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
1109         },
1110         {
1111                 .label          = "allow trusted domains",
1112                 .type           = P_BOOL,
1113                 .p_class        = P_GLOBAL,
1114                 .ptr            = &Globals.bAllowTrustedDomains,
1115                 .special        = NULL,
1116                 .enum_list      = NULL,
1117                 .flags          = FLAG_ADVANCED,
1118         },
1119         {
1120                 .label          = "map to guest",
1121                 .type           = P_ENUM,
1122                 .p_class        = P_GLOBAL,
1123                 .ptr            = &Globals.map_to_guest,
1124                 .special        = NULL,
1125                 .enum_list      = enum_map_to_guest,
1126                 .flags          = FLAG_ADVANCED,
1127         },
1128         {
1129                 .label          = "null passwords",
1130                 .type           = P_BOOL,
1131                 .p_class        = P_GLOBAL,
1132                 .ptr            = &Globals.bNullPasswords,
1133                 .special        = NULL,
1134                 .enum_list      = NULL,
1135                 .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
1136         },
1137         {
1138                 .label          = "obey pam restrictions",
1139                 .type           = P_BOOL,
1140                 .p_class        = P_GLOBAL,
1141                 .ptr            = &Globals.bObeyPamRestrictions,
1142                 .special        = NULL,
1143                 .enum_list      = NULL,
1144                 .flags          = FLAG_ADVANCED,
1145         },
1146         {
1147                 .label          = "password server",
1148                 .type           = P_STRING,
1149                 .p_class        = P_GLOBAL,
1150                 .ptr            = &Globals.szPasswordServer,
1151                 .special        = NULL,
1152                 .enum_list      = NULL,
1153                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
1154         },
1155         {
1156                 .label          = "smb passwd file",
1157                 .type           = P_STRING,
1158                 .p_class        = P_GLOBAL,
1159                 .ptr            = &Globals.szSMBPasswdFile,
1160                 .special        = NULL,
1161                 .enum_list      = NULL,
1162                 .flags          = FLAG_ADVANCED,
1163         },
1164         {
1165                 .label          = "private dir",
1166                 .type           = P_STRING,
1167                 .p_class        = P_GLOBAL,
1168                 .ptr            = &Globals.szPrivateDir,
1169                 .special        = NULL,
1170                 .enum_list      = NULL,
1171                 .flags          = FLAG_ADVANCED,
1172         },
1173         {
1174                 .label          = "passdb backend",
1175                 .type           = P_STRING,
1176                 .p_class        = P_GLOBAL,
1177                 .ptr            = &Globals.szPassdbBackend,
1178                 .special        = NULL,
1179                 .enum_list      = NULL,
1180                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
1181         },
1182         {
1183                 .label          = "algorithmic rid base",
1184                 .type           = P_INTEGER,
1185                 .p_class        = P_GLOBAL,
1186                 .ptr            = &Globals.AlgorithmicRidBase,
1187                 .special        = NULL,
1188                 .enum_list      = NULL,
1189                 .flags          = FLAG_ADVANCED,
1190         },
1191         {
1192                 .label          = "root directory",
1193                 .type           = P_STRING,
1194                 .p_class        = P_GLOBAL,
1195                 .ptr            = &Globals.szRootdir,
1196                 .special        = NULL,
1197                 .enum_list      = NULL,
1198                 .flags          = FLAG_ADVANCED,
1199         },
1200         {
1201                 .label          = "root dir",
1202                 .type           = P_STRING,
1203                 .p_class        = P_GLOBAL,
1204                 .ptr            = &Globals.szRootdir,
1205                 .special        = NULL,
1206                 .enum_list      = NULL,
1207                 .flags          = FLAG_HIDE,
1208         },
1209         {
1210                 .label          = "root",
1211                 .type           = P_STRING,
1212                 .p_class        = P_GLOBAL,
1213                 .ptr            = &Globals.szRootdir,
1214                 .special        = NULL,
1215                 .enum_list      = NULL,
1216                 .flags          = FLAG_HIDE,
1217         },
1218         {
1219                 .label          = "guest account",
1220                 .type           = P_STRING,
1221                 .p_class        = P_GLOBAL,
1222                 .ptr            = &Globals.szGuestaccount,
1223                 .special        = NULL,
1224                 .enum_list      = NULL,
1225                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
1226         },
1227         {
1228                 .label          = "enable privileges",
1229                 .type           = P_BOOL,
1230                 .p_class        = P_GLOBAL,
1231                 .ptr            = &Globals.bEnablePrivileges,
1232                 .special        = NULL,
1233                 .enum_list      = NULL,
1234                 .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
1235         },
1236
1237         {
1238                 .label          = "pam password change",
1239                 .type           = P_BOOL,
1240                 .p_class        = P_GLOBAL,
1241                 .ptr            = &Globals.bPamPasswordChange,
1242                 .special        = NULL,
1243                 .enum_list      = NULL,
1244                 .flags          = FLAG_ADVANCED,
1245         },
1246         {
1247                 .label          = "passwd program",
1248                 .type           = P_STRING,
1249                 .p_class        = P_GLOBAL,
1250                 .ptr            = &Globals.szPasswdProgram,
1251                 .special        = NULL,
1252                 .enum_list      = NULL,
1253                 .flags          = FLAG_ADVANCED,
1254         },
1255         {
1256                 .label          = "passwd chat",
1257                 .type           = P_STRING,
1258                 .p_class        = P_GLOBAL,
1259                 .ptr            = &Globals.szPasswdChat,
1260                 .special        = NULL,
1261                 .enum_list      = NULL,
1262                 .flags          = FLAG_ADVANCED,
1263         },
1264         {
1265                 .label          = "passwd chat debug",
1266                 .type           = P_BOOL,
1267                 .p_class        = P_GLOBAL,
1268                 .ptr            = &Globals.bPasswdChatDebug,
1269                 .special        = NULL,
1270                 .enum_list      = NULL,
1271                 .flags          = FLAG_ADVANCED,
1272         },
1273         {
1274                 .label          = "passwd chat timeout",
1275                 .type           = P_INTEGER,
1276                 .p_class        = P_GLOBAL,
1277                 .ptr            = &Globals.iPasswdChatTimeout,
1278                 .special        = NULL,
1279                 .enum_list      = NULL,
1280                 .flags          = FLAG_ADVANCED,
1281         },
1282         {
1283                 .label          = "check password script",
1284                 .type           = P_STRING,
1285                 .p_class        = P_GLOBAL,
1286                 .ptr            = &Globals.szCheckPasswordScript,
1287                 .special        = NULL,
1288                 .enum_list      = NULL,
1289                 .flags          = FLAG_ADVANCED,
1290         },
1291         {
1292                 .label          = "username map",
1293                 .type           = P_STRING,
1294                 .p_class        = P_GLOBAL,
1295                 .ptr            = &Globals.szUsernameMap,
1296                 .special        = NULL,
1297                 .enum_list      = NULL,
1298                 .flags          = FLAG_ADVANCED,
1299         },
1300         {
1301                 .label          = "password level",
1302                 .type           = P_INTEGER,
1303                 .p_class        = P_GLOBAL,
1304                 .ptr            = &Globals.pwordlevel,
1305                 .special        = NULL,
1306                 .enum_list      = NULL,
1307                 .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
1308         },
1309         {
1310                 .label          = "username level",
1311                 .type           = P_INTEGER,
1312                 .p_class        = P_GLOBAL,
1313                 .ptr            = &Globals.unamelevel,
1314                 .special        = NULL,
1315                 .enum_list      = NULL,
1316                 .flags          = FLAG_ADVANCED,
1317         },
1318         {
1319                 .label          = "unix password sync",
1320                 .type           = P_BOOL,
1321                 .p_class        = P_GLOBAL,
1322                 .ptr            = &Globals.bUnixPasswdSync,
1323                 .special        = NULL,
1324                 .enum_list      = NULL,
1325                 .flags          = FLAG_ADVANCED,
1326         },
1327         {
1328                 .label          = "restrict anonymous",
1329                 .type           = P_INTEGER,
1330                 .p_class        = P_GLOBAL,
1331                 .ptr            = &Globals.restrict_anonymous,
1332                 .special        = NULL,
1333                 .enum_list      = NULL,
1334                 .flags          = FLAG_ADVANCED,
1335         },
1336         {
1337                 .label          = "lanman auth",
1338                 .type           = P_BOOL,
1339                 .p_class        = P_GLOBAL,
1340                 .ptr            = &Globals.bLanmanAuth,
1341                 .special        = NULL,
1342                 .enum_list      = NULL,
1343                 .flags          = FLAG_ADVANCED,
1344         },
1345         {
1346                 .label          = "ntlm auth",
1347                 .type           = P_BOOL,
1348                 .p_class        = P_GLOBAL,
1349                 .ptr            = &Globals.bNTLMAuth,
1350                 .special        = NULL,
1351                 .enum_list      = NULL,
1352                 .flags          = FLAG_ADVANCED,
1353         },
1354         {
1355                 .label          = "client NTLMv2 auth",
1356                 .type           = P_BOOL,
1357                 .p_class        = P_GLOBAL,
1358                 .ptr            = &Globals.bClientNTLMv2Auth,
1359                 .special        = NULL,
1360                 .enum_list      = NULL,
1361                 .flags          = FLAG_ADVANCED,
1362         },
1363         {
1364                 .label          = "client lanman auth",
1365                 .type           = P_BOOL,
1366                 .p_class        = P_GLOBAL,
1367                 .ptr            = &Globals.bClientLanManAuth,
1368                 .special        = NULL,
1369                 .enum_list      = NULL,
1370                 .flags          = FLAG_ADVANCED,
1371         },
1372         {
1373                 .label          = "client plaintext auth",
1374                 .type           = P_BOOL,
1375                 .p_class        = P_GLOBAL,
1376                 .ptr            = &Globals.bClientPlaintextAuth,
1377                 .special        = NULL,
1378                 .enum_list      = NULL,
1379                 .flags          = FLAG_ADVANCED,
1380         },
1381         {
1382                 .label          = "client use spnego principal",
1383                 .type           = P_BOOL,
1384                 .p_class        = P_GLOBAL,
1385                 .ptr            = &Globals.client_use_spnego_principal,
1386                 .special        = NULL,
1387                 .enum_list      = NULL,
1388                 .flags          = FLAG_ADVANCED,
1389         },
1390         {
1391                 .label          = "send spnego principal",
1392                 .type           = P_BOOL,
1393                 .p_class        = P_GLOBAL,
1394                 .ptr            = &Globals.send_spnego_principal,
1395                 .special        = NULL,
1396                 .enum_list      = NULL,
1397                 .flags          = FLAG_ADVANCED,
1398         },
1399         {
1400                 .label          = "username",
1401                 .type           = P_STRING,
1402                 .p_class        = P_LOCAL,
1403                 .ptr            = &sDefault.szUsername,
1404                 .special        = NULL,
1405                 .enum_list      = NULL,
1406                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1407         },
1408         {
1409                 .label          = "user",
1410                 .type           = P_STRING,
1411                 .p_class        = P_LOCAL,
1412                 .ptr            = &sDefault.szUsername,
1413                 .special        = NULL,
1414                 .enum_list      = NULL,
1415                 .flags          = FLAG_HIDE,
1416         },
1417         {
1418                 .label          = "users",
1419                 .type           = P_STRING,
1420                 .p_class        = P_LOCAL,
1421                 .ptr            = &sDefault.szUsername,
1422                 .special        = NULL,
1423                 .enum_list      = NULL,
1424                 .flags          = FLAG_HIDE,
1425         },
1426         {
1427                 .label          = "invalid users",
1428                 .type           = P_LIST,
1429                 .p_class        = P_LOCAL,
1430                 .ptr            = &sDefault.szInvalidUsers,
1431                 .special        = NULL,
1432                 .enum_list      = NULL,
1433                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1434         },
1435         {
1436                 .label          = "valid users",
1437                 .type           = P_LIST,
1438                 .p_class        = P_LOCAL,
1439                 .ptr            = &sDefault.szValidUsers,
1440                 .special        = NULL,
1441                 .enum_list      = NULL,
1442                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1443         },
1444         {
1445                 .label          = "admin users",
1446                 .type           = P_LIST,
1447                 .p_class        = P_LOCAL,
1448                 .ptr            = &sDefault.szAdminUsers,
1449                 .special        = NULL,
1450                 .enum_list      = NULL,
1451                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1452         },
1453         {
1454                 .label          = "read list",
1455                 .type           = P_LIST,
1456                 .p_class        = P_LOCAL,
1457                 .ptr            = &sDefault.readlist,
1458                 .special        = NULL,
1459                 .enum_list      = NULL,
1460                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1461         },
1462         {
1463                 .label          = "write list",
1464                 .type           = P_LIST,
1465                 .p_class        = P_LOCAL,
1466                 .ptr            = &sDefault.writelist,
1467                 .special        = NULL,
1468                 .enum_list      = NULL,
1469                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1470         },
1471         {
1472                 .label          = "printer admin",
1473                 .type           = P_LIST,
1474                 .p_class        = P_LOCAL,
1475                 .ptr            = &sDefault.printer_admin,
1476                 .special        = NULL,
1477                 .enum_list      = NULL,
1478                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1479         },
1480         {
1481                 .label          = "force user",
1482                 .type           = P_STRING,
1483                 .p_class        = P_LOCAL,
1484                 .ptr            = &sDefault.force_user,
1485                 .special        = NULL,
1486                 .enum_list      = NULL,
1487                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1488         },
1489         {
1490                 .label          = "force group",
1491                 .type           = P_STRING,
1492                 .p_class        = P_LOCAL,
1493                 .ptr            = &sDefault.force_group,
1494                 .special        = NULL,
1495                 .enum_list      = NULL,
1496                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1497         },
1498         {
1499                 .label          = "group",
1500                 .type           = P_STRING,
1501                 .p_class        = P_LOCAL,
1502                 .ptr            = &sDefault.force_group,
1503                 .special        = NULL,
1504                 .enum_list      = NULL,
1505                 .flags          = FLAG_ADVANCED,
1506         },
1507         {
1508                 .label          = "read only",
1509                 .type           = P_BOOL,
1510                 .p_class        = P_LOCAL,
1511                 .ptr            = &sDefault.bRead_only,
1512                 .special        = NULL,
1513                 .enum_list      = NULL,
1514                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1515         },
1516         {
1517                 .label          = "write ok",
1518                 .type           = P_BOOLREV,
1519                 .p_class        = P_LOCAL,
1520                 .ptr            = &sDefault.bRead_only,
1521                 .special        = NULL,
1522                 .enum_list      = NULL,
1523                 .flags          = FLAG_HIDE,
1524         },
1525         {
1526                 .label          = "writeable",
1527                 .type           = P_BOOLREV,
1528                 .p_class        = P_LOCAL,
1529                 .ptr            = &sDefault.bRead_only,
1530                 .special        = NULL,
1531                 .enum_list      = NULL,
1532                 .flags          = FLAG_HIDE,
1533         },
1534         {
1535                 .label          = "writable",
1536                 .type           = P_BOOLREV,
1537                 .p_class        = P_LOCAL,
1538                 .ptr            = &sDefault.bRead_only,
1539                 .special        = NULL,
1540                 .enum_list      = NULL,
1541                 .flags          = FLAG_HIDE,
1542         },
1543         {
1544                 .label          = "acl check permissions",
1545                 .type           = P_BOOL,
1546                 .p_class        = P_LOCAL,
1547                 .ptr            = &sDefault.bAclCheckPermissions,
1548                 .special        = NULL,
1549                 .enum_list      = NULL,
1550                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1551         },
1552         {
1553                 .label          = "acl group control",
1554                 .type           = P_BOOL,
1555                 .p_class        = P_LOCAL,
1556                 .ptr            = &sDefault.bAclGroupControl,
1557                 .special        = NULL,
1558                 .enum_list      = NULL,
1559                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1560         },
1561         {
1562                 .label          = "acl map full control",
1563                 .type           = P_BOOL,
1564                 .p_class        = P_LOCAL,
1565                 .ptr            = &sDefault.bAclMapFullControl,
1566                 .special        = NULL,
1567                 .enum_list      = NULL,
1568                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1569         },
1570         {
1571                 .label          = "create mask",
1572                 .type           = P_OCTAL,
1573                 .p_class        = P_LOCAL,
1574                 .ptr            = &sDefault.iCreate_mask,
1575                 .special        = NULL,
1576                 .enum_list      = NULL,
1577                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1578         },
1579         {
1580                 .label          = "create mode",
1581                 .type           = P_OCTAL,
1582                 .p_class        = P_LOCAL,
1583                 .ptr            = &sDefault.iCreate_mask,
1584                 .special        = NULL,
1585                 .enum_list      = NULL,
1586                 .flags          = FLAG_HIDE,
1587         },
1588         {
1589                 .label          = "force create mode",
1590                 .type           = P_OCTAL,
1591                 .p_class        = P_LOCAL,
1592                 .ptr            = &sDefault.iCreate_force_mode,
1593                 .special        = NULL,
1594                 .enum_list      = NULL,
1595                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1596         },
1597         {
1598                 .label          = "security mask",
1599                 .type           = P_OCTAL,
1600                 .p_class        = P_LOCAL,
1601                 .ptr            = &sDefault.iSecurity_mask,
1602                 .special        = NULL,
1603                 .enum_list      = NULL,
1604                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1605         },
1606         {
1607                 .label          = "force security mode",
1608                 .type           = P_OCTAL,
1609                 .p_class        = P_LOCAL,
1610                 .ptr            = &sDefault.iSecurity_force_mode,
1611                 .special        = NULL,
1612                 .enum_list      = NULL,
1613                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1614         },
1615         {
1616                 .label          = "directory mask",
1617                 .type           = P_OCTAL,
1618                 .p_class        = P_LOCAL,
1619                 .ptr            = &sDefault.iDir_mask,
1620                 .special        = NULL,
1621                 .enum_list      = NULL,
1622                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1623         },
1624         {
1625                 .label          = "directory mode",
1626                 .type           = P_OCTAL,
1627                 .p_class        = P_LOCAL,
1628                 .ptr            = &sDefault.iDir_mask,
1629                 .special        = NULL,
1630                 .enum_list      = NULL,
1631                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
1632         },
1633         {
1634                 .label          = "force directory mode",
1635                 .type           = P_OCTAL,
1636                 .p_class        = P_LOCAL,
1637                 .ptr            = &sDefault.iDir_force_mode,
1638                 .special        = NULL,
1639                 .enum_list      = NULL,
1640                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1641         },
1642         {
1643                 .label          = "directory security mask",
1644                 .type           = P_OCTAL,
1645                 .p_class        = P_LOCAL,
1646                 .ptr            = &sDefault.iDir_Security_mask,
1647                 .special        = NULL,
1648                 .enum_list      = NULL,
1649                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1650         },
1651         {
1652                 .label          = "force directory security mode",
1653                 .type           = P_OCTAL,
1654                 .p_class        = P_LOCAL,
1655                 .ptr            = &sDefault.iDir_Security_force_mode,
1656                 .special        = NULL,
1657                 .enum_list      = NULL,
1658                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1659         },
1660         {
1661                 .label          = "force unknown acl user",
1662                 .type           = P_BOOL,
1663                 .p_class        = P_LOCAL,
1664                 .ptr            = &sDefault.bForceUnknownAclUser,
1665                 .special        = NULL,
1666                 .enum_list      = NULL,
1667                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1668         },
1669         {
1670                 .label          = "inherit permissions",
1671                 .type           = P_BOOL,
1672                 .p_class        = P_LOCAL,
1673                 .ptr            = &sDefault.bInheritPerms,
1674                 .special        = NULL,
1675                 .enum_list      = NULL,
1676                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1677         },
1678         {
1679                 .label          = "inherit acls",
1680                 .type           = P_BOOL,
1681                 .p_class        = P_LOCAL,
1682                 .ptr            = &sDefault.bInheritACLS,
1683                 .special        = NULL,
1684                 .enum_list      = NULL,
1685                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1686         },
1687         {
1688                 .label          = "inherit owner",
1689                 .type           = P_BOOL,
1690                 .p_class        = P_LOCAL,
1691                 .ptr            = &sDefault.bInheritOwner,
1692                 .special        = NULL,
1693                 .enum_list      = NULL,
1694                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1695         },
1696         {
1697                 .label          = "guest only",
1698                 .type           = P_BOOL,
1699                 .p_class        = P_LOCAL,
1700                 .ptr            = &sDefault.bGuest_only,
1701                 .special        = NULL,
1702                 .enum_list      = NULL,
1703                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
1704         },
1705         {
1706                 .label          = "only guest",
1707                 .type           = P_BOOL,
1708                 .p_class        = P_LOCAL,
1709                 .ptr            = &sDefault.bGuest_only,
1710                 .special        = NULL,
1711                 .enum_list      = NULL,
1712                 .flags          = FLAG_HIDE,
1713         },
1714         {
1715                 .label          = "administrative share",
1716                 .type           = P_BOOL,
1717                 .p_class        = P_LOCAL,
1718                 .ptr            = &sDefault.bAdministrative_share,
1719                 .special        = NULL,
1720                 .enum_list      = NULL,
1721                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1722         },
1723
1724         {
1725                 .label          = "guest ok",
1726                 .type           = P_BOOL,
1727                 .p_class        = P_LOCAL,
1728                 .ptr            = &sDefault.bGuest_ok,
1729                 .special        = NULL,
1730                 .enum_list      = NULL,
1731                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1732         },
1733         {
1734                 .label          = "public",
1735                 .type           = P_BOOL,
1736                 .p_class        = P_LOCAL,
1737                 .ptr            = &sDefault.bGuest_ok,
1738                 .special        = NULL,
1739                 .enum_list      = NULL,
1740                 .flags          = FLAG_HIDE,
1741         },
1742         {
1743                 .label          = "only user",
1744                 .type           = P_BOOL,
1745                 .p_class        = P_LOCAL,
1746                 .ptr            = &sDefault.bOnlyUser,
1747                 .special        = NULL,
1748                 .enum_list      = NULL,
1749                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1750         },
1751         {
1752                 .label          = "hosts allow",
1753                 .type           = P_LIST,
1754                 .p_class        = P_LOCAL,
1755                 .ptr            = &sDefault.szHostsallow,
1756                 .special        = NULL,
1757                 .enum_list      = NULL,
1758                 .flags          = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1759         },
1760         {
1761                 .label          = "allow hosts",
1762                 .type           = P_LIST,
1763                 .p_class        = P_LOCAL,
1764                 .ptr            = &sDefault.szHostsallow,
1765                 .special        = NULL,
1766                 .enum_list      = NULL,
1767                 .flags          = FLAG_HIDE,
1768         },
1769         {
1770                 .label          = "hosts deny",
1771                 .type           = P_LIST,
1772                 .p_class        = P_LOCAL,
1773                 .ptr            = &sDefault.szHostsdeny,
1774                 .special        = NULL,
1775                 .enum_list      = NULL,
1776                 .flags          = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1777         },
1778         {
1779                 .label          = "deny hosts",
1780                 .type           = P_LIST,
1781                 .p_class        = P_LOCAL,
1782                 .ptr            = &sDefault.szHostsdeny,
1783                 .special        = NULL,
1784                 .enum_list      = NULL,
1785                 .flags          = FLAG_HIDE,
1786         },
1787         {
1788                 .label          = "preload modules",
1789                 .type           = P_LIST,
1790                 .p_class        = P_GLOBAL,
1791                 .ptr            = &Globals.szPreloadModules,
1792                 .special        = NULL,
1793                 .enum_list      = NULL,
1794                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
1795         },
1796         {
1797                 .label          = "dedicated keytab file",
1798                 .type           = P_STRING,
1799                 .p_class        = P_GLOBAL,
1800                 .ptr            = &Globals.szDedicatedKeytabFile,
1801                 .special        = NULL,
1802                 .enum_list      = NULL,
1803                 .flags          = FLAG_ADVANCED,
1804         },
1805         {
1806                 .label          = "kerberos method",
1807                 .type           = P_ENUM,
1808                 .p_class        = P_GLOBAL,
1809                 .ptr            = &Globals.iKerberosMethod,
1810                 .special        = NULL,
1811                 .enum_list      = enum_kerberos_method,
1812                 .flags          = FLAG_ADVANCED,
1813         },
1814         {
1815                 .label          = "map untrusted to domain",
1816                 .type           = P_BOOL,
1817                 .p_class        = P_GLOBAL,
1818                 .ptr            = &Globals.bMapUntrustedToDomain,
1819                 .special        = NULL,
1820                 .enum_list      = NULL,
1821                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
1822         },
1823
1824
1825         {N_("Logging Options"), P_SEP, P_SEPARATOR},
1826
1827         {
1828                 .label          = "log level",
1829                 .type           = P_STRING,
1830                 .p_class        = P_GLOBAL,
1831                 .ptr            = &Globals.szLogLevel,
1832                 .special        = handle_debug_list,
1833                 .enum_list      = NULL,
1834                 .flags          = FLAG_ADVANCED,
1835         },
1836         {
1837                 .label          = "debuglevel",
1838                 .type           = P_STRING,
1839                 .p_class        = P_GLOBAL,
1840                 .ptr            = &Globals.szLogLevel,
1841                 .special        = handle_debug_list,
1842                 .enum_list      = NULL,
1843                 .flags          = FLAG_HIDE,
1844         },
1845         {
1846                 .label          = "syslog",
1847                 .type           = P_INTEGER,
1848                 .p_class        = P_GLOBAL,
1849                 .ptr            = &Globals.syslog,
1850                 .special        = NULL,
1851                 .enum_list      = NULL,
1852                 .flags          = FLAG_ADVANCED,
1853         },
1854         {
1855                 .label          = "syslog only",
1856                 .type           = P_BOOL,
1857                 .p_class        = P_GLOBAL,
1858                 .ptr            = &Globals.bSyslogOnly,
1859                 .special        = NULL,
1860                 .enum_list      = NULL,
1861                 .flags          = FLAG_ADVANCED,
1862         },
1863         {
1864                 .label          = "log file",
1865                 .type           = P_STRING,
1866                 .p_class        = P_GLOBAL,
1867                 .ptr            = &Globals.szLogFile,
1868                 .special        = NULL,
1869                 .enum_list      = NULL,
1870                 .flags          = FLAG_ADVANCED,
1871         },
1872         {
1873                 .label          = "max log size",
1874                 .type           = P_INTEGER,
1875                 .p_class        = P_GLOBAL,
1876                 .ptr            = &Globals.max_log_size,
1877                 .special        = NULL,
1878                 .enum_list      = NULL,
1879                 .flags          = FLAG_ADVANCED,
1880         },
1881         {
1882                 .label          = "debug timestamp",
1883                 .type           = P_BOOL,
1884                 .p_class        = P_GLOBAL,
1885                 .ptr            = &Globals.bTimestampLogs,
1886                 .special        = NULL,
1887                 .enum_list      = NULL,
1888                 .flags          = FLAG_ADVANCED,
1889         },
1890         {
1891                 .label          = "timestamp logs",
1892                 .type           = P_BOOL,
1893                 .p_class        = P_GLOBAL,
1894                 .ptr            = &Globals.bTimestampLogs,
1895                 .special        = NULL,
1896                 .enum_list      = NULL,
1897                 .flags          = FLAG_ADVANCED,
1898         },
1899         {
1900                 .label          = "debug prefix timestamp",
1901                 .type           = P_BOOL,
1902                 .p_class        = P_GLOBAL,
1903                 .ptr            = &Globals.bDebugPrefixTimestamp,
1904                 .special        = NULL,
1905                 .enum_list      = NULL,
1906                 .flags          = FLAG_ADVANCED,
1907         },
1908         {
1909                 .label          = "debug hires timestamp",
1910                 .type           = P_BOOL,
1911                 .p_class        = P_GLOBAL,
1912                 .ptr            = &Globals.bDebugHiresTimestamp,
1913                 .special        = NULL,
1914                 .enum_list      = NULL,
1915                 .flags          = FLAG_ADVANCED,
1916         },
1917         {
1918                 .label          = "debug pid",
1919                 .type           = P_BOOL,
1920                 .p_class        = P_GLOBAL,
1921                 .ptr            = &Globals.bDebugPid,
1922                 .special        = NULL,
1923                 .enum_list      = NULL,
1924                 .flags          = FLAG_ADVANCED,
1925         },
1926         {
1927                 .label          = "debug uid",
1928                 .type           = P_BOOL,
1929                 .p_class        = P_GLOBAL,
1930                 .ptr            = &Globals.bDebugUid,
1931                 .special        = NULL,
1932                 .enum_list      = NULL,
1933                 .flags          = FLAG_ADVANCED,
1934         },
1935         {
1936                 .label          = "debug class",
1937                 .type           = P_BOOL,
1938                 .p_class        = P_GLOBAL,
1939                 .ptr            = &Globals.bDebugClass,
1940                 .special        = NULL,
1941                 .enum_list      = NULL,
1942                 .flags          = FLAG_ADVANCED,
1943         },
1944         {
1945                 .label          = "enable core files",
1946                 .type           = P_BOOL,
1947                 .p_class        = P_GLOBAL,
1948                 .ptr            = &Globals.bEnableCoreFiles,
1949                 .special        = NULL,
1950                 .enum_list      = NULL,
1951                 .flags          = FLAG_ADVANCED,
1952         },
1953
1954         {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1955
1956         {
1957                 .label          = "allocation roundup size",
1958                 .type           = P_INTEGER,
1959                 .p_class        = P_LOCAL,
1960                 .ptr            = &sDefault.iallocation_roundup_size,
1961                 .special        = NULL,
1962                 .enum_list      = NULL,
1963                 .flags          = FLAG_ADVANCED,
1964         },
1965         {
1966                 .label          = "aio read size",
1967                 .type           = P_INTEGER,
1968                 .p_class        = P_LOCAL,
1969                 .ptr            = &sDefault.iAioReadSize,
1970                 .special        = NULL,
1971                 .enum_list      = NULL,
1972                 .flags          = FLAG_ADVANCED,
1973         },
1974         {
1975                 .label          = "aio write size",
1976                 .type           = P_INTEGER,
1977                 .p_class        = P_LOCAL,
1978                 .ptr            = &sDefault.iAioWriteSize,
1979                 .special        = NULL,
1980                 .enum_list      = NULL,
1981                 .flags          = FLAG_ADVANCED,
1982         },
1983         {
1984                 .label          = "aio write behind",
1985                 .type           = P_STRING,
1986                 .p_class        = P_LOCAL,
1987                 .ptr            = &sDefault.szAioWriteBehind,
1988                 .special        = NULL,
1989                 .enum_list      = NULL,
1990                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1991         },
1992         {
1993                 .label          = "smb ports",
1994                 .type           = P_STRING,
1995                 .p_class        = P_GLOBAL,
1996                 .ptr            = &Globals.smb_ports,
1997                 .special        = NULL,
1998                 .enum_list      = NULL,
1999                 .flags          = FLAG_ADVANCED,
2000         },
2001         {
2002                 .label          = "large readwrite",
2003                 .type           = P_BOOL,
2004                 .p_class        = P_GLOBAL,
2005                 .ptr            = &Globals.bLargeReadwrite,
2006                 .special        = NULL,
2007                 .enum_list      = NULL,
2008                 .flags          = FLAG_ADVANCED,
2009         },
2010         {
2011                 .label          = "max protocol",
2012                 .type           = P_ENUM,
2013                 .p_class        = P_GLOBAL,
2014                 .ptr            = &Globals.maxprotocol,
2015                 .special        = NULL,
2016                 .enum_list      = enum_protocol,
2017                 .flags          = FLAG_ADVANCED,
2018         },
2019         {
2020                 .label          = "protocol",
2021                 .type           = P_ENUM,
2022                 .p_class        = P_GLOBAL,
2023                 .ptr            = &Globals.maxprotocol,
2024                 .special        = NULL,
2025                 .enum_list      = enum_protocol,
2026                 .flags          = FLAG_ADVANCED,
2027         },
2028         {
2029                 .label          = "min protocol",
2030                 .type           = P_ENUM,
2031                 .p_class        = P_GLOBAL,
2032                 .ptr            = &Globals.minprotocol,
2033                 .special        = NULL,
2034                 .enum_list      = enum_protocol,
2035                 .flags          = FLAG_ADVANCED,
2036         },
2037         {
2038                 .label          = "min receivefile size",
2039                 .type           = P_INTEGER,
2040                 .p_class        = P_GLOBAL,
2041                 .ptr            = &Globals.iminreceivefile,
2042                 .special        = NULL,
2043                 .enum_list      = NULL,
2044                 .flags          = FLAG_ADVANCED,
2045         },
2046         {
2047                 .label          = "read raw",
2048                 .type           = P_BOOL,
2049                 .p_class        = P_GLOBAL,
2050                 .ptr            = &Globals.bReadRaw,
2051                 .special        = NULL,
2052                 .enum_list      = NULL,
2053                 .flags          = FLAG_ADVANCED,
2054         },
2055         {
2056                 .label          = "write raw",
2057                 .type           = P_BOOL,
2058                 .p_class        = P_GLOBAL,
2059                 .ptr            = &Globals.bWriteRaw,
2060                 .special        = NULL,
2061                 .enum_list      = NULL,
2062                 .flags          = FLAG_ADVANCED,
2063         },
2064         {
2065                 .label          = "disable netbios",
2066                 .type           = P_BOOL,
2067                 .p_class        = P_GLOBAL,
2068                 .ptr            = &Globals.bDisableNetbios,
2069                 .special        = NULL,
2070                 .enum_list      = NULL,
2071                 .flags          = FLAG_ADVANCED,
2072         },
2073         {
2074                 .label          = "reset on zero vc",
2075                 .type           = P_BOOL,
2076                 .p_class        = P_GLOBAL,
2077                 .ptr            = &Globals.bResetOnZeroVC,
2078                 .special        = NULL,
2079                 .enum_list      = NULL,
2080                 .flags          = FLAG_ADVANCED,
2081         },
2082         {
2083                 .label          = "log writeable files on exit",
2084                 .type           = P_BOOL,
2085                 .p_class        = P_GLOBAL,
2086                 .ptr            = &Globals.bLogWriteableFilesOnExit,
2087                 .special        = NULL,
2088                 .enum_list      = NULL,
2089                 .flags          = FLAG_ADVANCED,
2090         },
2091         {
2092                 .label          = "acl compatibility",
2093                 .type           = P_ENUM,
2094                 .p_class        = P_GLOBAL,
2095                 .ptr            = &Globals.iAclCompat,
2096                 .special        = NULL,
2097                 .enum_list      = enum_acl_compat_vals,
2098                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2099         },
2100         {
2101                 .label          = "defer sharing violations",
2102                 .type           = P_BOOL,
2103                 .p_class        = P_GLOBAL,
2104                 .ptr            = &Globals.bDeferSharingViolations,
2105                 .special        = NULL,
2106                 .enum_list      = NULL,
2107                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2108         },
2109         {
2110                 .label          = "ea support",
2111                 .type           = P_BOOL,
2112                 .p_class        = P_LOCAL,
2113                 .ptr            = &sDefault.bEASupport,
2114                 .special        = NULL,
2115                 .enum_list      = NULL,
2116                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2117         },
2118         {
2119                 .label          = "nt acl support",
2120                 .type           = P_BOOL,
2121                 .p_class        = P_LOCAL,
2122                 .ptr            = &sDefault.bNTAclSupport,
2123                 .special        = NULL,
2124                 .enum_list      = NULL,
2125                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2126         },
2127         {
2128                 .label          = "nt pipe support",
2129                 .type           = P_BOOL,
2130                 .p_class        = P_GLOBAL,
2131                 .ptr            = &Globals.bNTPipeSupport,
2132                 .special        = NULL,
2133                 .enum_list      = NULL,
2134                 .flags          = FLAG_ADVANCED,
2135         },
2136         {
2137                 .label          = "nt status support",
2138                 .type           = P_BOOL,
2139                 .p_class        = P_GLOBAL,
2140                 .ptr            = &Globals.bNTStatusSupport,
2141                 .special        = NULL,
2142                 .enum_list      = NULL,
2143                 .flags          = FLAG_ADVANCED,
2144         },
2145         {
2146                 .label          = "profile acls",
2147                 .type           = P_BOOL,
2148                 .p_class        = P_LOCAL,
2149                 .ptr            = &sDefault.bProfileAcls,
2150                 .special        = NULL,
2151                 .enum_list      = NULL,
2152                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2153         },
2154         {
2155                 .label          = "map acl inherit",
2156                 .type           = P_BOOL,
2157                 .p_class        = P_LOCAL,
2158                 .ptr            = &sDefault.bMap_acl_inherit,
2159                 .special        = NULL,
2160                 .enum_list      = NULL,
2161                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2162         },
2163         {
2164                 .label          = "afs share",
2165                 .type           = P_BOOL,
2166                 .p_class        = P_LOCAL,
2167                 .ptr            = &sDefault.bAfs_Share,
2168                 .special        = NULL,
2169                 .enum_list      = NULL,
2170                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2171         },
2172         {
2173                 .label          = "max mux",
2174                 .type           = P_INTEGER,
2175                 .p_class        = P_GLOBAL,
2176                 .ptr            = &Globals.max_mux,
2177                 .special        = NULL,
2178                 .enum_list      = NULL,
2179                 .flags          = FLAG_ADVANCED,
2180         },
2181         {
2182                 .label          = "max xmit",
2183                 .type           = P_INTEGER,
2184                 .p_class        = P_GLOBAL,
2185                 .ptr            = &Globals.max_xmit,
2186                 .special        = NULL,
2187                 .enum_list      = NULL,
2188                 .flags          = FLAG_ADVANCED,
2189         },
2190         {
2191                 .label          = "name resolve order",
2192                 .type           = P_STRING,
2193                 .p_class        = P_GLOBAL,
2194                 .ptr            = &Globals.szNameResolveOrder,
2195                 .special        = NULL,
2196                 .enum_list      = NULL,
2197                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
2198         },
2199         {
2200                 .label          = "max ttl",
2201                 .type           = P_INTEGER,
2202                 .p_class        = P_GLOBAL,
2203                 .ptr            = &Globals.max_ttl,
2204                 .special        = NULL,
2205                 .enum_list      = NULL,
2206                 .flags          = FLAG_ADVANCED,
2207         },
2208         {
2209                 .label          = "max wins ttl",
2210                 .type           = P_INTEGER,
2211                 .p_class        = P_GLOBAL,
2212                 .ptr            = &Globals.max_wins_ttl,
2213                 .special        = NULL,
2214                 .enum_list      = NULL,
2215                 .flags          = FLAG_ADVANCED,
2216         },
2217         {
2218                 .label          = "min wins ttl",
2219                 .type           = P_INTEGER,
2220                 .p_class        = P_GLOBAL,
2221                 .ptr            = &Globals.min_wins_ttl,
2222                 .special        = NULL,
2223                 .enum_list      = NULL,
2224                 .flags          = FLAG_ADVANCED,
2225         },
2226         {
2227                 .label          = "time server",
2228                 .type           = P_BOOL,
2229                 .p_class        = P_GLOBAL,
2230                 .ptr            = &Globals.bTimeServer,
2231                 .special        = NULL,
2232                 .enum_list      = NULL,
2233                 .flags          = FLAG_ADVANCED,
2234         },
2235         {
2236                 .label          = "unix extensions",
2237                 .type           = P_BOOL,
2238                 .p_class        = P_GLOBAL,
2239                 .ptr            = &Globals.bUnixExtensions,
2240                 .special        = NULL,
2241                 .enum_list      = NULL,
2242                 .flags          = FLAG_ADVANCED,
2243         },
2244         {
2245                 .label          = "use spnego",
2246                 .type           = P_BOOL,
2247                 .p_class        = P_GLOBAL,
2248                 .ptr            = &Globals.bUseSpnego,
2249                 .special        = NULL,
2250                 .enum_list      = NULL,
2251                 .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
2252         },
2253         {
2254                 .label          = "client signing",
2255                 .type           = P_ENUM,
2256                 .p_class        = P_GLOBAL,
2257                 .ptr            = &Globals.client_signing,
2258                 .special        = NULL,
2259                 .enum_list      = enum_smb_signing_vals,
2260                 .flags          = FLAG_ADVANCED,
2261         },
2262         {
2263                 .label          = "server signing",
2264                 .type           = P_ENUM,
2265                 .p_class        = P_GLOBAL,
2266                 .ptr            = &Globals.server_signing,
2267                 .special        = NULL,
2268                 .enum_list      = enum_smb_signing_vals,
2269                 .flags          = FLAG_ADVANCED,
2270         },
2271         {
2272                 .label          = "smb encrypt",
2273                 .type           = P_ENUM,
2274                 .p_class        = P_LOCAL,
2275                 .ptr            = &sDefault.ismb_encrypt,
2276                 .special        = NULL,
2277                 .enum_list      = enum_smb_signing_vals,
2278                 .flags          = FLAG_ADVANCED,
2279         },
2280         {
2281                 .label          = "client use spnego",
2282                 .type           = P_BOOL,
2283                 .p_class        = P_GLOBAL,
2284                 .ptr            = &Globals.bClientUseSpnego,
2285                 .special        = NULL,
2286                 .enum_list      = NULL,
2287                 .flags          = FLAG_ADVANCED,
2288         },
2289         {
2290                 .label          = "client ldap sasl wrapping",
2291                 .type           = P_ENUM,
2292                 .p_class        = P_GLOBAL,
2293                 .ptr            = &Globals.client_ldap_sasl_wrapping,
2294                 .special        = NULL,
2295                 .enum_list      = enum_ldap_sasl_wrapping,
2296                 .flags          = FLAG_ADVANCED,
2297         },
2298         {
2299                 .label          = "enable asu support",
2300                 .type           = P_BOOL,
2301                 .p_class        = P_GLOBAL,
2302                 .ptr            = &Globals.bASUSupport,
2303                 .special        = NULL,
2304                 .enum_list      = NULL,
2305                 .flags          = FLAG_ADVANCED,
2306         },
2307         {
2308                 .label          = "svcctl list",
2309                 .type           = P_LIST,
2310                 .p_class        = P_GLOBAL,
2311                 .ptr            = &Globals.szServicesList,
2312                 .special        = NULL,
2313                 .enum_list      = NULL,
2314                 .flags          = FLAG_ADVANCED,
2315         },
2316
2317         {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2318
2319         {
2320                 .label          = "block size",
2321                 .type           = P_INTEGER,
2322                 .p_class        = P_LOCAL,
2323                 .ptr            = &sDefault.iBlock_size,
2324                 .special        = NULL,
2325                 .enum_list      = NULL,
2326                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2327         },
2328         {
2329                 .label          = "deadtime",
2330                 .type           = P_INTEGER,
2331                 .p_class        = P_GLOBAL,
2332                 .ptr            = &Globals.deadtime,
2333                 .special        = NULL,
2334                 .enum_list      = NULL,
2335                 .flags          = FLAG_ADVANCED,
2336         },
2337         {
2338                 .label          = "getwd cache",
2339                 .type           = P_BOOL,
2340                 .p_class        = P_GLOBAL,
2341                 .ptr            = &Globals.getwd_cache,
2342                 .special        = NULL,
2343                 .enum_list      = NULL,
2344                 .flags          = FLAG_ADVANCED,
2345         },
2346         {
2347                 .label          = "keepalive",
2348                 .type           = P_INTEGER,
2349                 .p_class        = P_GLOBAL,
2350                 .ptr            = &Globals.iKeepalive,
2351                 .special        = NULL,
2352                 .enum_list      = NULL,
2353                 .flags          = FLAG_ADVANCED,
2354         },
2355         {
2356                 .label          = "change notify",
2357                 .type           = P_BOOL,
2358                 .p_class        = P_LOCAL,
2359                 .ptr            = &sDefault.bChangeNotify,
2360                 .special        = NULL,
2361                 .enum_list      = NULL,
2362                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2363         },
2364         {
2365                 .label          = "directory name cache size",
2366                 .type           = P_INTEGER,
2367                 .p_class        = P_LOCAL,
2368                 .ptr            = &sDefault.iDirectoryNameCacheSize,
2369                 .special        = NULL,
2370                 .enum_list      = NULL,
2371                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2372         },
2373         {
2374                 .label          = "kernel change notify",
2375                 .type           = P_BOOL,
2376                 .p_class        = P_LOCAL,
2377                 .ptr            = &sDefault.bKernelChangeNotify,
2378                 .special        = NULL,
2379                 .enum_list      = NULL,
2380                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2381         },
2382         {
2383                 .label          = "lpq cache time",
2384                 .type           = P_INTEGER,
2385                 .p_class        = P_GLOBAL,
2386                 .ptr            = &Globals.lpqcachetime,
2387                 .special        = NULL,
2388                 .enum_list      = NULL,
2389                 .flags          = FLAG_ADVANCED,
2390         },
2391         {
2392                 .label          = "max smbd processes",
2393                 .type           = P_INTEGER,
2394                 .p_class        = P_GLOBAL,
2395                 .ptr            = &Globals.iMaxSmbdProcesses,
2396                 .special        = NULL,
2397                 .enum_list      = NULL,
2398                 .flags          = FLAG_ADVANCED,
2399         },
2400         {
2401                 .label          = "max connections",
2402                 .type           = P_INTEGER,
2403                 .p_class        = P_LOCAL,
2404                 .ptr            = &sDefault.iMaxConnections,
2405                 .special        = NULL,
2406                 .enum_list      = NULL,
2407                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2408         },
2409         {
2410                 .label          = "paranoid server security",
2411                 .type           = P_BOOL,
2412                 .p_class        = P_GLOBAL,
2413                 .ptr            = &Globals.paranoid_server_security,
2414                 .special        = NULL,
2415                 .enum_list      = NULL,
2416                 .flags          = FLAG_ADVANCED,
2417         },
2418         {
2419                 .label          = "max disk size",
2420                 .type           = P_INTEGER,
2421                 .p_class        = P_GLOBAL,
2422                 .ptr            = &Globals.maxdisksize,
2423                 .special        = NULL,
2424                 .enum_list      = NULL,
2425                 .flags          = FLAG_ADVANCED,
2426         },
2427         {
2428                 .label          = "max open files",
2429                 .type           = P_INTEGER,
2430                 .p_class        = P_GLOBAL,
2431                 .ptr            = &Globals.max_open_files,
2432                 .special        = NULL,
2433                 .enum_list      = NULL,
2434                 .flags          = FLAG_ADVANCED,
2435         },
2436         {
2437                 .label          = "min print space",
2438                 .type           = P_INTEGER,
2439                 .p_class        = P_LOCAL,
2440                 .ptr            = &sDefault.iMinPrintSpace,
2441                 .special        = NULL,
2442                 .enum_list      = NULL,
2443                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2444         },
2445         {
2446                 .label          = "socket options",
2447                 .type           = P_STRING,
2448                 .p_class        = P_GLOBAL,
2449                 .ptr            = &Globals.szSocketOptions,
2450                 .special        = NULL,
2451                 .enum_list      = NULL,
2452                 .flags          = FLAG_ADVANCED,
2453         },
2454         {
2455                 .label          = "strict allocate",
2456                 .type           = P_BOOL,
2457                 .p_class        = P_LOCAL,
2458                 .ptr            = &sDefault.bStrictAllocate,
2459                 .special        = NULL,
2460                 .enum_list      = NULL,
2461                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2462         },
2463         {
2464                 .label          = "strict sync",
2465                 .type           = P_BOOL,
2466                 .p_class        = P_LOCAL,
2467                 .ptr            = &sDefault.bStrictSync,
2468                 .special        = NULL,
2469                 .enum_list      = NULL,
2470                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2471         },
2472         {
2473                 .label          = "sync always",
2474                 .type           = P_BOOL,
2475                 .p_class        = P_LOCAL,
2476                 .ptr            = &sDefault.bSyncAlways,
2477                 .special        = NULL,
2478                 .enum_list      = NULL,
2479                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2480         },
2481         {
2482                 .label          = "use mmap",
2483                 .type           = P_BOOL,
2484                 .p_class        = P_GLOBAL,
2485                 .ptr            = &Globals.bUseMmap,
2486                 .special        = NULL,
2487                 .enum_list      = NULL,
2488                 .flags          = FLAG_ADVANCED,
2489         },
2490         {
2491                 .label          = "use sendfile",
2492                 .type           = P_BOOL,
2493                 .p_class        = P_LOCAL,
2494                 .ptr            = &sDefault.bUseSendfile,
2495                 .special        = NULL,
2496                 .enum_list      = NULL,
2497                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2498         },
2499         {
2500                 .label          = "hostname lookups",
2501                 .type           = P_BOOL,
2502                 .p_class        = P_GLOBAL,
2503                 .ptr            = &Globals.bHostnameLookups,
2504                 .special        = NULL,
2505                 .enum_list      = NULL,
2506                 .flags          = FLAG_ADVANCED,
2507         },
2508         {
2509                 .label          = "write cache size",
2510                 .type           = P_INTEGER,
2511                 .p_class        = P_LOCAL,
2512                 .ptr            = &sDefault.iWriteCacheSize,
2513                 .special        = NULL,
2514                 .enum_list      = NULL,
2515                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2516         },
2517         {
2518                 .label          = "name cache timeout",
2519                 .type           = P_INTEGER,
2520                 .p_class        = P_GLOBAL,
2521                 .ptr            = &Globals.name_cache_timeout,
2522                 .special        = NULL,
2523                 .enum_list      = NULL,
2524                 .flags          = FLAG_ADVANCED,
2525         },
2526         {
2527                 .label          = "ctdbd socket",
2528                 .type           = P_STRING,
2529                 .p_class        = P_GLOBAL,
2530                 .ptr            = &Globals.ctdbdSocket,
2531                 .special        = NULL,
2532                 .enum_list      = NULL,
2533                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2534         },
2535         {
2536                 .label          = "cluster addresses",
2537                 .type           = P_LIST,
2538                 .p_class        = P_GLOBAL,
2539                 .ptr            = &Globals.szClusterAddresses,
2540                 .special        = NULL,
2541                 .enum_list      = NULL,
2542                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2543         },
2544         {
2545                 .label          = "clustering",
2546                 .type           = P_BOOL,
2547                 .p_class        = P_GLOBAL,
2548                 .ptr            = &Globals.clustering,
2549                 .special        = NULL,
2550                 .enum_list      = NULL,
2551                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2552         },
2553         {
2554                 .label          = "ctdb timeout",
2555                 .type           = P_INTEGER,
2556                 .p_class        = P_GLOBAL,
2557                 .ptr            = &Globals.ctdb_timeout,
2558                 .special        = NULL,
2559                 .enum_list      = NULL,
2560                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2561         },
2562         {
2563                 .label          = "ctdb locktime warn threshold",
2564                 .type           = P_INTEGER,
2565                 .p_class        = P_GLOBAL,
2566                 .ptr            = &Globals.ctdb_locktime_warn_threshold,
2567                 .special        = NULL,
2568                 .enum_list      = NULL,
2569                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2570         },
2571         {
2572                 .label          = "smb2 max read",
2573                 .type           = P_INTEGER,
2574                 .p_class        = P_GLOBAL,
2575                 .ptr            = &Globals.ismb2_max_read,
2576                 .special        = NULL,
2577                 .enum_list      = NULL,
2578                 .flags          = FLAG_ADVANCED,
2579         },
2580         {
2581                 .label          = "smb2 max write",
2582                 .type           = P_INTEGER,
2583                 .p_class        = P_GLOBAL,
2584                 .ptr            = &Globals.ismb2_max_write,
2585                 .special        = NULL,
2586                 .enum_list      = NULL,
2587                 .flags          = FLAG_ADVANCED,
2588         },
2589         {
2590                 .label          = "smb2 max trans",
2591                 .type           = P_INTEGER,
2592                 .p_class        = P_GLOBAL,
2593                 .ptr            = &Globals.ismb2_max_trans,
2594                 .special        = NULL,
2595                 .enum_list      = NULL,
2596                 .flags          = FLAG_ADVANCED,
2597         },
2598         {
2599                 .label          = "smb2 max credits",
2600                 .type           = P_INTEGER,
2601                 .p_class        = P_GLOBAL,
2602                 .ptr            = &Globals.ismb2_max_credits,
2603                 .special        = NULL,
2604                 .enum_list      = NULL,
2605                 .flags          = FLAG_ADVANCED,
2606         },
2607
2608         {N_("Printing Options"), P_SEP, P_SEPARATOR},
2609
2610         {
2611                 .label          = "max reported print jobs",
2612                 .type           = P_INTEGER,
2613                 .p_class        = P_LOCAL,
2614                 .ptr            = &sDefault.iMaxReportedPrintJobs,
2615                 .special        = NULL,
2616                 .enum_list      = NULL,
2617                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2618         },
2619         {
2620                 .label          = "max print jobs",
2621                 .type           = P_INTEGER,
2622                 .p_class        = P_LOCAL,
2623                 .ptr            = &sDefault.iMaxPrintJobs,
2624                 .special        = NULL,
2625                 .enum_list      = NULL,
2626                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2627         },
2628         {
2629                 .label          = "load printers",
2630                 .type           = P_BOOL,
2631                 .p_class        = P_GLOBAL,
2632                 .ptr            = &Globals.bLoadPrinters,
2633                 .special        = NULL,
2634                 .enum_list      = NULL,
2635                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2636         },
2637         {
2638                 .label          = "printcap cache time",
2639                 .type           = P_INTEGER,
2640                 .p_class        = P_GLOBAL,
2641                 .ptr            = &Globals.PrintcapCacheTime,
2642                 .special        = NULL,
2643                 .enum_list      = NULL,
2644                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2645         },
2646         {
2647                 .label          = "printcap name",
2648                 .type           = P_STRING,
2649                 .p_class        = P_GLOBAL,
2650                 .ptr            = &Globals.szPrintcapname,
2651                 .special        = NULL,
2652                 .enum_list      = NULL,
2653                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2654         },
2655         {
2656                 .label          = "printcap",
2657                 .type           = P_STRING,
2658                 .p_class        = P_GLOBAL,
2659                 .ptr            = &Globals.szPrintcapname,
2660                 .special        = NULL,
2661                 .enum_list      = NULL,
2662                 .flags          = FLAG_HIDE,
2663         },
2664         {
2665                 .label          = "printable",
2666                 .type           = P_BOOL,
2667                 .p_class        = P_LOCAL,
2668                 .ptr            = &sDefault.bPrint_ok,
2669                 .special        = NULL,
2670                 .enum_list      = NULL,
2671                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2672         },
2673         {
2674                 .label          = "print notify backchannel",
2675                 .type           = P_BOOL,
2676                 .p_class        = P_LOCAL,
2677                 .ptr            = &sDefault.bPrintNotifyBackchannel,
2678                 .special        = NULL,
2679                 .enum_list      = NULL,
2680                 .flags          = FLAG_ADVANCED,
2681         },
2682         {
2683                 .label          = "print ok",
2684                 .type           = P_BOOL,
2685                 .p_class        = P_LOCAL,
2686                 .ptr            = &sDefault.bPrint_ok,
2687                 .special        = NULL,
2688                 .enum_list      = NULL,
2689                 .flags          = FLAG_HIDE,
2690         },
2691         {
2692                 .label          = "printing",
2693                 .type           = P_ENUM,
2694                 .p_class        = P_LOCAL,
2695                 .ptr            = &sDefault.iPrinting,
2696                 .special        = handle_printing,
2697                 .enum_list      = enum_printing,
2698                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2699         },
2700         {
2701                 .label          = "cups options",
2702                 .type           = P_STRING,
2703                 .p_class        = P_LOCAL,
2704                 .ptr            = &sDefault.szCupsOptions,
2705                 .special        = NULL,
2706                 .enum_list      = NULL,
2707                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2708         },
2709         {
2710                 .label          = "cups server",
2711                 .type           = P_STRING,
2712                 .p_class        = P_GLOBAL,
2713                 .ptr            = &Globals.szCupsServer,
2714                 .special        = NULL,
2715                 .enum_list      = NULL,
2716                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2717         },
2718         {
2719                 .label          = "cups encrypt",
2720                 .type           = P_ENUM,
2721                 .p_class        = P_GLOBAL,
2722                 .ptr            = &Globals.CupsEncrypt,
2723                 .special        = NULL,
2724                 .enum_list      = enum_bool_auto,
2725                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2726         },
2727         {
2728
2729                 .label          = "cups connection timeout",
2730                 .type           = P_INTEGER,
2731                 .p_class        = P_GLOBAL,
2732                 .ptr            = &Globals.cups_connection_timeout,
2733                 .special        = NULL,
2734                 .enum_list      = NULL,
2735                 .flags          = FLAG_ADVANCED,
2736         },
2737         {
2738                 .label          = "iprint server",
2739                 .type           = P_STRING,
2740                 .p_class        = P_GLOBAL,
2741                 .ptr            = &Globals.szIPrintServer,
2742                 .special        = NULL,
2743                 .enum_list      = NULL,
2744                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2745         },
2746         {
2747                 .label          = "print command",
2748                 .type           = P_STRING,
2749                 .p_class        = P_LOCAL,
2750                 .ptr            = &sDefault.szPrintcommand,
2751                 .special        = NULL,
2752                 .enum_list      = NULL,
2753                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2754         },
2755         {
2756                 .label          = "disable spoolss",
2757                 .type           = P_BOOL,
2758                 .p_class        = P_GLOBAL,
2759                 .ptr            = &Globals.bDisableSpoolss,
2760                 .special        = NULL,
2761                 .enum_list      = NULL,
2762                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2763         },
2764         {
2765                 .label          = "enable spoolss",
2766                 .type           = P_BOOLREV,
2767                 .p_class        = P_GLOBAL,
2768                 .ptr            = &Globals.bDisableSpoolss,
2769                 .special        = NULL,
2770                 .enum_list      = NULL,
2771                 .flags          = FLAG_HIDE,
2772         },
2773         {
2774                 .label          = "lpq command",
2775                 .type           = P_STRING,
2776                 .p_class        = P_LOCAL,
2777                 .ptr            = &sDefault.szLpqcommand,
2778                 .special        = NULL,
2779                 .enum_list      = NULL,
2780                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2781         },
2782         {
2783                 .label          = "lprm command",
2784                 .type           = P_STRING,
2785                 .p_class        = P_LOCAL,
2786                 .ptr            = &sDefault.szLprmcommand,
2787                 .special        = NULL,
2788                 .enum_list      = NULL,
2789                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2790         },
2791         {
2792                 .label          = "lppause command",
2793                 .type           = P_STRING,
2794                 .p_class        = P_LOCAL,
2795                 .ptr            = &sDefault.szLppausecommand,
2796                 .special        = NULL,
2797                 .enum_list      = NULL,
2798                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2799         },
2800         {
2801                 .label          = "lpresume command",
2802                 .type           = P_STRING,
2803                 .p_class        = P_LOCAL,
2804                 .ptr            = &sDefault.szLpresumecommand,
2805                 .special        = NULL,
2806                 .enum_list      = NULL,
2807                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2808         },
2809         {
2810                 .label          = "queuepause command",
2811                 .type           = P_STRING,
2812                 .p_class        = P_LOCAL,
2813                 .ptr            = &sDefault.szQueuepausecommand,
2814                 .special        = NULL,
2815                 .enum_list      = NULL,
2816                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2817         },
2818         {
2819                 .label          = "queueresume command",
2820                 .type           = P_STRING,
2821                 .p_class        = P_LOCAL,
2822                 .ptr            = &sDefault.szQueueresumecommand,
2823                 .special        = NULL,
2824                 .enum_list      = NULL,
2825                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2826         },
2827         {
2828                 .label          = "addport command",
2829                 .type           = P_STRING,
2830                 .p_class        = P_GLOBAL,
2831                 .ptr            = &Globals.szAddPortCommand,
2832                 .special        = NULL,
2833                 .enum_list      = NULL,
2834                 .flags          = FLAG_ADVANCED,
2835         },
2836         {
2837                 .label          = "enumports command",
2838                 .type           = P_STRING,
2839                 .p_class        = P_GLOBAL,
2840                 .ptr            = &Globals.szEnumPortsCommand,
2841                 .special        = NULL,
2842                 .enum_list      = NULL,
2843                 .flags          = FLAG_ADVANCED,
2844         },
2845         {
2846                 .label          = "addprinter command",
2847                 .type           = P_STRING,
2848                 .p_class        = P_GLOBAL,
2849                 .ptr            = &Globals.szAddPrinterCommand,
2850                 .special        = NULL,
2851                 .enum_list      = NULL,
2852                 .flags          = FLAG_ADVANCED,
2853         },
2854         {
2855                 .label          = "deleteprinter command",
2856                 .type           = P_STRING,
2857                 .p_class        = P_GLOBAL,
2858                 .ptr            = &Globals.szDeletePrinterCommand,
2859                 .special        = NULL,
2860                 .enum_list      = NULL,
2861                 .flags          = FLAG_ADVANCED,
2862         },
2863         {
2864                 .label          = "show add printer wizard",
2865                 .type           = P_BOOL,
2866                 .p_class        = P_GLOBAL,
2867                 .ptr            = &Globals.bMsAddPrinterWizard,
2868                 .special        = NULL,
2869                 .enum_list      = NULL,
2870                 .flags          = FLAG_ADVANCED,
2871         },
2872         {
2873                 .label          = "os2 driver map",
2874                 .type           = P_STRING,
2875                 .p_class        = P_GLOBAL,
2876                 .ptr            = &Globals.szOs2DriverMap,
2877                 .special        = NULL,
2878                 .enum_list      = NULL,
2879                 .flags          = FLAG_ADVANCED,
2880         },
2881
2882         {
2883                 .label          = "printer name",
2884                 .type           = P_STRING,
2885                 .p_class        = P_LOCAL,
2886                 .ptr            = &sDefault.szPrintername,
2887                 .special        = NULL,
2888                 .enum_list      = NULL,
2889                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2890         },
2891         {
2892                 .label          = "printer",
2893                 .type           = P_STRING,
2894                 .p_class        = P_LOCAL,
2895                 .ptr            = &sDefault.szPrintername,
2896                 .special        = NULL,
2897                 .enum_list      = NULL,
2898                 .flags          = FLAG_HIDE,
2899         },
2900         {
2901                 .label          = "use client driver",
2902                 .type           = P_BOOL,
2903                 .p_class        = P_LOCAL,
2904                 .ptr            = &sDefault.bUseClientDriver,
2905                 .special        = NULL,
2906                 .enum_list      = NULL,
2907                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2908         },
2909         {
2910                 .label          = "default devmode",
2911                 .type           = P_BOOL,
2912                 .p_class        = P_LOCAL,
2913                 .ptr            = &sDefault.bDefaultDevmode,
2914                 .special        = NULL,
2915                 .enum_list      = NULL,
2916                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2917         },
2918         {
2919                 .label          = "force printername",
2920                 .type           = P_BOOL,
2921                 .p_class        = P_LOCAL,
2922                 .ptr            = &sDefault.bForcePrintername,
2923                 .special        = NULL,
2924                 .enum_list      = NULL,
2925                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2926         },
2927         {
2928                 .label          = "printjob username",
2929                 .type           = P_STRING,
2930                 .p_class        = P_LOCAL,
2931                 .ptr            = &sDefault.szPrintjobUsername,
2932                 .special        = NULL,
2933                 .enum_list      = NULL,
2934                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2935         },
2936
2937         {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2938
2939         {
2940                 .label          = "mangling method",
2941                 .type           = P_STRING,
2942                 .p_class        = P_GLOBAL,
2943                 .ptr            = &Globals.szManglingMethod,
2944                 .special        = NULL,
2945                 .enum_list      = NULL,
2946                 .flags          = FLAG_ADVANCED,
2947         },
2948         {
2949                 .label          = "mangle prefix",
2950                 .type           = P_INTEGER,
2951                 .p_class        = P_GLOBAL,
2952                 .ptr            = &Globals.mangle_prefix,
2953                 .special        = NULL,
2954                 .enum_list      = NULL,
2955                 .flags          = FLAG_ADVANCED,
2956         },
2957
2958         {
2959                 .label          = "default case",
2960                 .type           = P_ENUM,
2961                 .p_class        = P_LOCAL,
2962                 .ptr            = &sDefault.iDefaultCase,
2963                 .special        = NULL,
2964                 .enum_list      = enum_case,
2965                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2966         },
2967         {
2968                 .label          = "case sensitive",
2969                 .type           = P_ENUM,
2970                 .p_class        = P_LOCAL,
2971                 .ptr            = &sDefault.iCaseSensitive,
2972                 .special        = NULL,
2973                 .enum_list      = enum_bool_auto,
2974                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2975         },
2976         {
2977                 .label          = "casesignames",
2978                 .type           = P_ENUM,
2979                 .p_class        = P_LOCAL,
2980                 .ptr            = &sDefault.iCaseSensitive,
2981                 .special        = NULL,
2982                 .enum_list      = enum_bool_auto,
2983                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2984         },
2985         {
2986                 .label          = "preserve case",
2987                 .type           = P_BOOL,
2988                 .p_class        = P_LOCAL,
2989                 .ptr            = &sDefault.bCasePreserve,
2990                 .special        = NULL,
2991                 .enum_list      = NULL,
2992                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2993         },
2994         {
2995                 .label          = "short preserve case",
2996                 .type           = P_BOOL,
2997                 .p_class        = P_LOCAL,
2998                 .ptr            = &sDefault.bShortCasePreserve,
2999                 .special        = NULL,
3000                 .enum_list      = NULL,
3001                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3002         },
3003         {
3004                 .label          = "mangling char",
3005                 .type           = P_CHAR,
3006                 .p_class        = P_LOCAL,
3007                 .ptr            = &sDefault.magic_char,
3008                 .special        = NULL,
3009                 .enum_list      = NULL,
3010                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3011         },
3012         {
3013                 .label          = "hide dot files",
3014                 .type           = P_BOOL,
3015                 .p_class        = P_LOCAL,
3016                 .ptr            = &sDefault.bHideDotFiles,
3017                 .special        = NULL,
3018                 .enum_list      = NULL,
3019                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3020         },
3021         {
3022                 .label          = "hide special files",
3023                 .type           = P_BOOL,
3024                 .p_class        = P_LOCAL,
3025                 .ptr            = &sDefault.bHideSpecialFiles,
3026                 .special        = NULL,
3027                 .enum_list      = NULL,
3028                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3029         },
3030         {
3031                 .label          = "hide unreadable",
3032                 .type           = P_BOOL,
3033                 .p_class        = P_LOCAL,
3034                 .ptr            = &sDefault.bHideUnReadable,
3035                 .special        = NULL,
3036                 .enum_list      = NULL,
3037                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3038         },
3039         {
3040                 .label          = "hide unwriteable files",
3041                 .type           = P_BOOL,
3042                 .p_class        = P_LOCAL,
3043                 .ptr            = &sDefault.bHideUnWriteableFiles,
3044                 .special        = NULL,
3045                 .enum_list      = NULL,
3046                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3047         },
3048         {
3049                 .label          = "delete veto files",
3050                 .type           = P_BOOL,
3051                 .p_class        = P_LOCAL,
3052                 .ptr            = &sDefault.bDeleteVetoFiles,
3053                 .special        = NULL,
3054                 .enum_list      = NULL,
3055                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3056         },
3057         {
3058                 .label          = "veto files",
3059                 .type           = P_STRING,
3060                 .p_class        = P_LOCAL,
3061                 .ptr            = &sDefault.szVetoFiles,
3062                 .special        = NULL,
3063                 .enum_list      = NULL,
3064                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3065         },
3066         {
3067                 .label          = "hide files",
3068                 .type           = P_STRING,
3069                 .p_class        = P_LOCAL,
3070                 .ptr            = &sDefault.szHideFiles,
3071                 .special        = NULL,
3072                 .enum_list      = NULL,
3073                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3074         },
3075         {
3076                 .label          = "veto oplock files",
3077                 .type           = P_STRING,
3078                 .p_class        = P_LOCAL,
3079                 .ptr            = &sDefault.szVetoOplockFiles,
3080                 .special        = NULL,
3081                 .enum_list      = NULL,
3082                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3083         },
3084         {
3085                 .label          = "map archive",
3086                 .type           = P_BOOL,
3087                 .p_class        = P_LOCAL,
3088                 .ptr            = &sDefault.bMap_archive,
3089                 .special        = NULL,
3090                 .enum_list      = NULL,
3091                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3092         },
3093         {
3094                 .label          = "map hidden",
3095                 .type           = P_BOOL,
3096                 .p_class        = P_LOCAL,
3097                 .ptr            = &sDefault.bMap_hidden,
3098                 .special        = NULL,
3099                 .enum_list      = NULL,
3100                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3101         },
3102         {
3103                 .label          = "map system",
3104                 .type           = P_BOOL,
3105                 .p_class        = P_LOCAL,
3106                 .ptr            = &sDefault.bMap_system,
3107                 .special        = NULL,
3108                 .enum_list      = NULL,
3109                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3110         },
3111         {
3112                 .label          = "map readonly",
3113                 .type           = P_ENUM,
3114                 .p_class        = P_LOCAL,
3115                 .ptr            = &sDefault.iMap_readonly,
3116                 .special        = NULL,
3117                 .enum_list      = enum_map_readonly,
3118                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3119         },
3120         {
3121                 .label          = "mangled names",
3122                 .type           = P_BOOL,
3123                 .p_class        = P_LOCAL,
3124                 .ptr            = &sDefault.bMangledNames,
3125                 .special        = NULL,
3126                 .enum_list      = NULL,
3127                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3128         },
3129         {
3130                 .label          = "max stat cache size",
3131                 .type           = P_INTEGER,
3132                 .p_class        = P_GLOBAL,
3133                 .ptr            = &Globals.iMaxStatCacheSize,
3134                 .special        = NULL,
3135                 .enum_list      = NULL,
3136                 .flags          = FLAG_ADVANCED,
3137         },
3138         {
3139                 .label          = "stat cache",
3140                 .type           = P_BOOL,
3141                 .p_class        = P_GLOBAL,
3142                 .ptr            = &Globals.bStatCache,
3143                 .special        = NULL,
3144                 .enum_list      = NULL,
3145                 .flags          = FLAG_ADVANCED,
3146         },
3147         {
3148                 .label          = "store dos attributes",
3149                 .type           = P_BOOL,
3150                 .p_class        = P_LOCAL,
3151                 .ptr            = &sDefault.bStoreDosAttributes,
3152                 .special        = NULL,
3153                 .enum_list      = NULL,
3154                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3155         },
3156         {
3157                 .label          = "dmapi support",
3158                 .type           = P_BOOL,
3159                 .p_class        = P_LOCAL,
3160                 .ptr            = &sDefault.bDmapiSupport,
3161                 .special        = NULL,
3162                 .enum_list      = NULL,
3163                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3164         },
3165
3166
3167         {N_("Domain Options"), P_SEP, P_SEPARATOR},
3168
3169         {
3170                 .label          = "machine password timeout",
3171                 .type           = P_INTEGER,
3172                 .p_class        = P_GLOBAL,
3173                 .ptr            = &Globals.machine_password_timeout,
3174                 .special        = NULL,
3175                 .enum_list      = NULL,
3176                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
3177         },
3178
3179         {N_("Logon Options"), P_SEP, P_SEPARATOR},
3180
3181         {
3182                 .label          = "add user script",
3183                 .type           = P_STRING,
3184                 .p_class        = P_GLOBAL,
3185                 .ptr            = &Globals.szAddUserScript,
3186                 .special        = NULL,
3187                 .enum_list      = NULL,
3188                 .flags          = FLAG_ADVANCED,
3189         },
3190         {
3191                 .label          = "rename user script",
3192                 .type           = P_STRING,
3193                 .p_class        = P_GLOBAL,
3194                 .ptr            = &Globals.szRenameUserScript,
3195                 .special        = NULL,
3196                 .enum_list      = NULL,
3197                 .flags          = FLAG_ADVANCED,
3198         },
3199         {
3200                 .label          = "delete user script",
3201                 .type           = P_STRING,
3202                 .p_class        = P_GLOBAL,
3203                 .ptr            = &Globals.szDelUserScript,
3204                 .special        = NULL,
3205                 .enum_list      = NULL,
3206                 .flags          = FLAG_ADVANCED,
3207         },
3208         {
3209                 .label          = "add group script",
3210                 .type           = P_STRING,
3211                 .p_class        = P_GLOBAL,
3212                 .ptr            = &Globals.szAddGroupScript,
3213                 .special        = NULL,
3214                 .enum_list      = NULL,
3215                 .flags          = FLAG_ADVANCED,
3216         },
3217         {
3218                 .label          = "delete group script",
3219                 .type           = P_STRING,
3220                 .p_class        = P_GLOBAL,
3221                 .ptr            = &Globals.szDelGroupScript,
3222                 .special        = NULL,
3223                 .enum_list      = NULL,
3224                 .flags          = FLAG_ADVANCED,
3225         },
3226         {
3227                 .label          = "add user to group script",
3228                 .type           = P_STRING,
3229                 .p_class        = P_GLOBAL,
3230                 .ptr            = &Globals.szAddUserToGroupScript,
3231                 .special        = NULL,
3232                 .enum_list      = NULL,
3233                 .flags          = FLAG_ADVANCED,
3234         },
3235         {
3236                 .label          = "delete user from group script",
3237                 .type           = P_STRING,
3238                 .p_class        = P_GLOBAL,
3239                 .ptr            = &Globals.szDelUserFromGroupScript,
3240                 .special        = NULL,
3241                 .enum_list      = NULL,
3242                 .flags          = FLAG_ADVANCED,
3243         },
3244         {
3245                 .label          = "set primary group script",
3246                 .type           = P_STRING,
3247                 .p_class        = P_GLOBAL,
3248                 .ptr            = &Globals.szSetPrimaryGroupScript,
3249                 .special        = NULL,
3250                 .enum_list      = NULL,
3251                 .flags          = FLAG_ADVANCED,
3252         },
3253         {
3254                 .label          = "add machine script",
3255                 .type           = P_STRING,
3256                 .p_class        = P_GLOBAL,
3257                 .ptr            = &Globals.szAddMachineScript,
3258                 .special        = NULL,
3259                 .enum_list      = NULL,
3260                 .flags          = FLAG_ADVANCED,
3261         },
3262         {
3263                 .label          = "shutdown script",
3264                 .type           = P_STRING,
3265                 .p_class        = P_GLOBAL,
3266                 .ptr            = &Globals.szShutdownScript,
3267                 .special        = NULL,
3268                 .enum_list      = NULL,
3269                 .flags          = FLAG_ADVANCED,
3270         },
3271         {
3272                 .label          = "abort shutdown script",
3273                 .type           = P_STRING,
3274                 .p_class        = P_GLOBAL,
3275                 .ptr            = &Globals.szAbortShutdownScript,
3276                 .special        = NULL,
3277                 .enum_list      = NULL,
3278                 .flags          = FLAG_ADVANCED,
3279         },
3280         {
3281                 .label          = "username map script",
3282                 .type           = P_STRING,
3283                 .p_class        = P_GLOBAL,
3284                 .ptr            = &Globals.szUsernameMapScript,
3285                 .special        = NULL,
3286                 .enum_list      = NULL,
3287                 .flags          = FLAG_ADVANCED,
3288         },
3289         {
3290                 .label          = "username map cache time",
3291                 .type           = P_INTEGER,
3292                 .p_class        = P_GLOBAL,
3293                 .ptr            = &Globals.iUsernameMapCacheTime,
3294                 .special        = NULL,
3295                 .enum_list      = NULL,
3296                 .flags          = FLAG_ADVANCED,
3297         },
3298         {
3299                 .label          = "logon script",
3300                 .type           = P_STRING,
3301                 .p_class        = P_GLOBAL,
3302                 .ptr            = &Globals.szLogonScript,
3303                 .special        = NULL,
3304                 .enum_list      = NULL,
3305                 .flags          = FLAG_ADVANCED,
3306         },
3307         {
3308                 .label          = "logon path",
3309                 .type           = P_STRING,
3310                 .p_class        = P_GLOBAL,
3311                 .ptr            = &Globals.szLogonPath,
3312                 .special        = NULL,
3313                 .enum_list      = NULL,
3314                 .flags          = FLAG_ADVANCED,
3315         },
3316         {
3317                 .label          = "logon drive",
3318                 .type           = P_STRING,
3319                 .p_class        = P_GLOBAL,
3320                 .ptr            = &Globals.szLogonDrive,
3321                 .special        = NULL,
3322                 .enum_list      = NULL,
3323                 .flags          = FLAG_ADVANCED,
3324         },
3325         {
3326                 .label          = "logon home",
3327                 .type           = P_STRING,
3328                 .p_class        = P_GLOBAL,
3329                 .ptr            = &Globals.szLogonHome,
3330                 .special        = NULL,
3331                 .enum_list      = NULL,
3332                 .flags          = FLAG_ADVANCED,
3333         },
3334         {
3335                 .label          = "domain logons",
3336                 .type           = P_BOOL,
3337                 .p_class        = P_GLOBAL,
3338                 .ptr            = &Globals.bDomainLogons,
3339                 .special        = NULL,
3340                 .enum_list      = NULL,
3341                 .flags          = FLAG_ADVANCED,
3342         },
3343
3344         {
3345                 .label          = "init logon delayed hosts",
3346                 .type           = P_LIST,
3347                 .p_class        = P_GLOBAL,
3348                 .ptr            = &Globals.szInitLogonDelayedHosts,
3349                 .special        = NULL,
3350                 .enum_list      = NULL,
3351                 .flags          = FLAG_ADVANCED,
3352         },
3353
3354         {
3355                 .label          = "init logon delay",
3356                 .type           = P_INTEGER,
3357                 .p_class        = P_GLOBAL,
3358                 .ptr            = &Globals.InitLogonDelay,
3359                 .special        = NULL,
3360                 .enum_list      = NULL,
3361                 .flags          = FLAG_ADVANCED,
3362
3363         },
3364
3365         {N_("Browse Options"), P_SEP, P_SEPARATOR},
3366
3367         {
3368                 .label          = "os level",
3369                 .type           = P_INTEGER,
3370                 .p_class        = P_GLOBAL,
3371                 .ptr            = &Globals.os_level,
3372                 .special        = NULL,
3373                 .enum_list      = NULL,
3374                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3375         },
3376         {
3377                 .label          = "lm announce",
3378                 .type           = P_ENUM,
3379                 .p_class        = P_GLOBAL,
3380                 .ptr            = &Globals.lm_announce,
3381                 .special        = NULL,
3382                 .enum_list      = enum_bool_auto,
3383                 .flags          = FLAG_ADVANCED,
3384         },
3385         {
3386                 .label          = "lm interval",
3387                 .type           = P_INTEGER,
3388                 .p_class        = P_GLOBAL,
3389                 .ptr            = &Globals.lm_interval,
3390                 .special        = NULL,
3391                 .enum_list      = NULL,
3392                 .flags          = FLAG_ADVANCED,
3393         },
3394         {
3395                 .label          = "preferred master",
3396                 .type           = P_ENUM,
3397                 .p_class        = P_GLOBAL,
3398                 .ptr            = &Globals.iPreferredMaster,
3399                 .special        = NULL,
3400                 .enum_list      = enum_bool_auto,
3401                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3402         },
3403         {
3404                 .label          = "prefered master",
3405                 .type           = P_ENUM,
3406                 .p_class        = P_GLOBAL,
3407                 .ptr            = &Globals.iPreferredMaster,
3408                 .special        = NULL,
3409                 .enum_list      = enum_bool_auto,
3410                 .flags          = FLAG_HIDE,
3411         },
3412         {
3413                 .label          = "local master",
3414                 .type           = P_BOOL,
3415                 .p_class        = P_GLOBAL,
3416                 .ptr            = &Globals.bLocalMaster,
3417                 .special        = NULL,
3418                 .enum_list      = NULL,
3419                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3420         },
3421         {
3422                 .label          = "domain master",
3423                 .type           = P_ENUM,
3424                 .p_class        = P_GLOBAL,
3425                 .ptr            = &Globals.iDomainMaster,
3426                 .special        = NULL,
3427                 .enum_list      = enum_bool_auto,
3428                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3429         },
3430         {
3431                 .label          = "browse list",
3432                 .type           = P_BOOL,
3433                 .p_class        = P_GLOBAL,
3434                 .ptr            = &Globals.bBrowseList,
3435                 .special        = NULL,
3436                 .enum_list      = NULL,
3437                 .flags          = FLAG_ADVANCED,
3438         },
3439         {
3440                 .label          = "browseable",
3441                 .type           = P_BOOL,
3442                 .p_class        = P_LOCAL,
3443                 .ptr            = &sDefault.bBrowseable,
3444                 .special        = NULL,
3445                 .enum_list      = NULL,
3446                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3447         },
3448         {
3449                 .label          = "browsable",
3450                 .type           = P_BOOL,
3451                 .p_class        = P_LOCAL,
3452                 .ptr            = &sDefault.bBrowseable,
3453                 .special        = NULL,
3454                 .enum_list      = NULL,
3455                 .flags          = FLAG_HIDE,
3456         },
3457         {
3458                 .label          = "access based share enum",
3459                 .type           = P_BOOL,
3460                 .p_class        = P_LOCAL,
3461                 .ptr            = &sDefault.bAccessBasedShareEnum,
3462                 .special        = NULL,
3463                 .enum_list      = NULL,
3464                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3465         },
3466         {
3467                 .label          = "enhanced browsing",
3468                 .type           = P_BOOL,
3469                 .p_class        = P_GLOBAL,
3470                 .ptr            = &Globals.enhanced_browsing,
3471                 .special        = NULL,
3472                 .enum_list      = NULL,
3473                 .flags          = FLAG_ADVANCED,
3474         },
3475
3476         {N_("WINS Options"), P_SEP, P_SEPARATOR},
3477
3478         {
3479                 .label          = "dns proxy",
3480                 .type           = P_BOOL,
3481                 .p_class        = P_GLOBAL,
3482                 .ptr            = &Globals.bDNSproxy,
3483                 .special        = NULL,
3484                 .enum_list      = NULL,
3485                 .flags          = FLAG_ADVANCED,
3486         },
3487         {
3488                 .label          = "wins proxy",
3489                 .type           = P_BOOL,
3490                 .p_class        = P_GLOBAL,
3491                 .ptr            = &Globals.bWINSproxy,
3492                 .special        = NULL,
3493                 .enum_list      = NULL,
3494                 .flags          = FLAG_ADVANCED,
3495         },
3496         {
3497                 .label          = "wins server",
3498                 .type           = P_LIST,
3499                 .p_class        = P_GLOBAL,
3500                 .ptr            = &Globals.szWINSservers,
3501                 .special        = NULL,
3502                 .enum_list      = NULL,
3503                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3504         },
3505         {
3506                 .label          = "wins support",
3507                 .type           = P_BOOL,
3508                 .p_class        = P_GLOBAL,
3509                 .ptr            = &Globals.bWINSsupport,
3510                 .special        = NULL,
3511                 .enum_list      = NULL,
3512                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3513         },
3514         {
3515                 .label          = "wins hook",
3516                 .type           = P_STRING,
3517                 .p_class        = P_GLOBAL,
3518                 .ptr            = &Globals.szWINSHook,
3519                 .special        = NULL,
3520                 .enum_list      = NULL,
3521                 .flags          = FLAG_ADVANCED,
3522         },
3523
3524         {N_("Locking Options"), P_SEP, P_SEPARATOR},
3525
3526         {
3527                 .label          = "blocking locks",
3528                 .type           = P_BOOL,
3529                 .p_class        = P_LOCAL,
3530                 .ptr            = &sDefault.bBlockingLocks,
3531                 .special        = NULL,
3532                 .enum_list      = NULL,
3533                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3534         },
3535         {
3536                 .label          = "csc policy",
3537                 .type           = P_ENUM,
3538                 .p_class        = P_LOCAL,
3539                 .ptr            = &sDefault.iCSCPolicy,
3540                 .special        = NULL,
3541                 .enum_list      = enum_csc_policy,
3542                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3543         },
3544         {
3545                 .label          = "fake oplocks",
3546                 .type           = P_BOOL,
3547                 .p_class        = P_LOCAL,
3548                 .ptr            = &sDefault.bFakeOplocks,
3549                 .special        = NULL,
3550                 .enum_list      = NULL,
3551                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
3552         },
3553         {
3554                 .label          = "kernel oplocks",
3555                 .type           = P_BOOL,
3556                 .p_class        = P_GLOBAL,
3557                 .ptr            = &Globals.bKernelOplocks,
3558                 .special        = NULL,
3559                 .enum_list      = NULL,
3560                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
3561         },
3562         {
3563                 .label          = "locking",
3564                 .type           = P_BOOL,
3565                 .p_class        = P_LOCAL,
3566                 .ptr            = &sDefault.bLocking,
3567                 .special        = NULL,
3568                 .enum_list      = NULL,
3569                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3570         },
3571         {
3572                 .label          = "lock spin time",
3573                 .type           = P_INTEGER,
3574                 .p_class        = P_GLOBAL,
3575                 .ptr            = &Globals.iLockSpinTime,
3576                 .special        = NULL,
3577                 .enum_list      = NULL,
3578                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
3579         },
3580         {
3581                 .label          = "oplocks",
3582                 .type           = P_BOOL,
3583                 .p_class        = P_LOCAL,
3584                 .ptr            = &sDefault.bOpLocks,
3585                 .special        = NULL,
3586                 .enum_list      = NULL,
3587                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3588         },
3589         {
3590                 .label          = "level2 oplocks",
3591                 .type           = P_BOOL,
3592                 .p_class        = P_LOCAL,
3593                 .ptr            = &sDefault.bLevel2OpLocks,
3594                 .special        = NULL,
3595                 .enum_list      = NULL,
3596                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3597         },
3598         {
3599                 .label          = "oplock break wait time",
3600                 .type           = P_INTEGER,
3601                 .p_class        = P_GLOBAL,
3602                 .ptr            = &Globals.oplock_break_wait_time,
3603                 .special        = NULL,
3604                 .enum_list      = NULL,
3605                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
3606         },
3607         {
3608                 .label          = "oplock contention limit",
3609                 .type           = P_INTEGER,
3610                 .p_class        = P_LOCAL,
3611                 .ptr            = &sDefault.iOplockContentionLimit,
3612                 .special        = NULL,
3613                 .enum_list      = NULL,
3614                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3615         },
3616         {
3617                 .label          = "posix locking",
3618                 .type           = P_BOOL,
3619                 .p_class        = P_LOCAL,
3620                 .ptr            = &sDefault.bPosixLocking,
3621                 .special        = NULL,
3622                 .enum_list      = NULL,
3623                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3624         },
3625         {
3626                 .label          = "strict locking",
3627                 .type           = P_ENUM,
3628                 .p_class        = P_LOCAL,
3629                 .ptr            = &sDefault.iStrictLocking,
3630                 .special        = NULL,
3631                 .enum_list      = enum_bool_auto,
3632                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3633         },
3634         {
3635                 .label          = "share modes",
3636                 .type           = P_BOOL,
3637                 .p_class        = P_LOCAL,
3638                 .ptr            = &sDefault.bShareModes,
3639                 .special        = NULL,
3640                 .enum_list      = NULL,
3641                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3642         },
3643
3644         {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3645
3646         {
3647                 .label          = "ldap admin dn",
3648                 .type           = P_STRING,
3649                 .p_class        = P_GLOBAL,
3650                 .ptr            = &Globals.szLdapAdminDn,
3651                 .special        = NULL,
3652                 .enum_list      = NULL,
3653                 .flags          = FLAG_ADVANCED,
3654         },
3655         {
3656                 .label          = "ldap delete dn",
3657                 .type           = P_BOOL,
3658                 .p_class        = P_GLOBAL,
3659                 .ptr            = &Globals.ldap_delete_dn,
3660                 .special        = NULL,
3661                 .enum_list      = NULL,
3662                 .flags          = FLAG_ADVANCED,
3663         },
3664         {
3665                 .label          = "ldap group suffix",
3666                 .type           = P_STRING,
3667                 .p_class        = P_GLOBAL,
3668                 .ptr            = &Globals.szLdapGroupSuffix,
3669                 .special        = NULL,
3670                 .enum_list      = NULL,
3671                 .flags          = FLAG_ADVANCED,
3672         },
3673         {
3674                 .label          = "ldap idmap suffix",
3675                 .type           = P_STRING,
3676                 .p_class        = P_GLOBAL,
3677                 .ptr            = &Globals.szLdapIdmapSuffix,
3678                 .special        = NULL,
3679                 .enum_list      = NULL,
3680                 .flags          = FLAG_ADVANCED,
3681         },
3682         {
3683                 .label          = "ldap machine suffix",
3684                 .type           = P_STRING,
3685                 .p_class        = P_GLOBAL,
3686                 .ptr            = &Globals.szLdapMachineSuffix,
3687                 .special        = NULL,
3688                 .enum_list      = NULL,
3689                 .flags          = FLAG_ADVANCED,
3690         },
3691         {
3692                 .label          = "ldap passwd sync",
3693                 .type           = P_ENUM,
3694                 .p_class        = P_GLOBAL,
3695                 .ptr            = &Globals.ldap_passwd_sync,
3696                 .special        = NULL,
3697                 .enum_list      = enum_ldap_passwd_sync,
3698                 .flags          = FLAG_ADVANCED,
3699         },
3700         {
3701                 .label          = "ldap password sync",
3702                 .type           = P_ENUM,
3703                 .p_class        = P_GLOBAL,
3704                 .ptr            = &Globals.ldap_passwd_sync,
3705                 .special        = NULL,
3706                 .enum_list      = enum_ldap_passwd_sync,
3707                 .flags          = FLAG_HIDE,
3708         },
3709         {
3710                 .label          = "ldap replication sleep",
3711                 .type           = P_INTEGER,
3712                 .p_class        = P_GLOBAL,
3713                 .ptr            = &Globals.ldap_replication_sleep,
3714                 .special        = NULL,
3715                 .enum_list      = NULL,
3716                 .flags          = FLAG_ADVANCED,
3717         },
3718         {
3719                 .label          = "ldap suffix",
3720                 .type           = P_STRING,
3721                 .p_class        = P_GLOBAL,
3722                 .ptr            = &Globals.szLdapSuffix,
3723                 .special        = NULL,
3724                 .enum_list      = NULL,
3725                 .flags          = FLAG_ADVANCED,
3726         },
3727         {
3728                 .label          = "ldap ssl",
3729                 .type           = P_ENUM,
3730                 .p_class        = P_GLOBAL,
3731                 .ptr            = &Globals.ldap_ssl,
3732                 .special        = NULL,
3733                 .enum_list      = enum_ldap_ssl,
3734                 .flags          = FLAG_ADVANCED,
3735         },
3736         {
3737                 .label          = "ldap ssl ads",
3738                 .type           = P_BOOL,
3739                 .p_class        = P_GLOBAL,
3740                 .ptr            = &Globals.ldap_ssl_ads,
3741                 .special        = NULL,
3742                 .enum_list      = NULL,
3743                 .flags          = FLAG_ADVANCED,
3744         },
3745         {
3746                 .label          = "ldap deref",
3747                 .type           = P_ENUM,
3748                 .p_class        = P_GLOBAL,
3749                 .ptr            = &Globals.ldap_deref,
3750                 .special        = NULL,
3751                 .enum_list      = enum_ldap_deref,
3752                 .flags          = FLAG_ADVANCED,
3753         },
3754         {
3755                 .label          = "ldap follow referral",
3756                 .type           = P_ENUM,
3757                 .p_class        = P_GLOBAL,
3758                 .ptr            = &Globals.ldap_follow_referral,
3759                 .special        = NULL,
3760                 .enum_list      = enum_bool_auto,
3761                 .flags          = FLAG_ADVANCED,
3762         },
3763         {
3764                 .label          = "ldap timeout",
3765                 .type           = P_INTEGER,
3766                 .p_class        = P_GLOBAL,
3767                 .ptr            = &Globals.ldap_timeout,
3768                 .special        = NULL,
3769                 .enum_list      = NULL,
3770                 .flags          = FLAG_ADVANCED,
3771         },
3772         {
3773                 .label          = "ldap connection timeout",
3774                 .type           = P_INTEGER,
3775                 .p_class        = P_GLOBAL,
3776                 .ptr            = &Globals.ldap_connection_timeout,
3777                 .special        = NULL,
3778                 .enum_list      = NULL,
3779                 .flags          = FLAG_ADVANCED,
3780         },
3781         {
3782                 .label          = "ldap page size",
3783                 .type           = P_INTEGER,
3784                 .p_class        = P_GLOBAL,
3785                 .ptr            = &Globals.ldap_page_size,
3786                 .special        = NULL,
3787                 .enum_list      = NULL,
3788                 .flags          = FLAG_ADVANCED,
3789         },
3790         {
3791                 .label          = "ldap user suffix",
3792                 .type           = P_STRING,
3793                 .p_class        = P_GLOBAL,
3794                 .ptr            = &Globals.szLdapUserSuffix,
3795                 .special        = NULL,
3796                 .enum_list      = NULL,
3797                 .flags          = FLAG_ADVANCED,
3798         },
3799         {
3800                 .label          = "ldap debug level",
3801                 .type           = P_INTEGER,
3802                 .p_class        = P_GLOBAL,
3803                 .ptr            = &Globals.ldap_debug_level,
3804                 .special        = handle_ldap_debug_level,
3805                 .enum_list      = NULL,
3806                 .flags          = FLAG_ADVANCED,
3807         },
3808         {
3809                 .label          = "ldap debug threshold",
3810                 .type           = P_INTEGER,
3811                 .p_class        = P_GLOBAL,
3812                 .ptr            = &Globals.ldap_debug_threshold,
3813                 .special        = NULL,
3814                 .enum_list      = NULL,
3815                 .flags          = FLAG_ADVANCED,
3816         },
3817
3818         {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3819
3820         {
3821                 .label          = "eventlog list",
3822                 .type           = P_LIST,
3823                 .p_class        = P_GLOBAL,
3824                 .ptr            = &Globals.szEventLogs,
3825                 .special        = NULL,
3826                 .enum_list      = NULL,
3827                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3828         },
3829
3830         {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3831
3832         {
3833                 .label          = "add share command",
3834                 .type           = P_STRING,
3835                 .p_class        = P_GLOBAL,
3836                 .ptr            = &Globals.szAddShareCommand,
3837                 .special        = NULL,
3838                 .enum_list      = NULL,
3839                 .flags          = FLAG_ADVANCED,
3840         },
3841         {
3842                 .label          = "change share command",
3843                 .type           = P_STRING,
3844                 .p_class        = P_GLOBAL,
3845                 .ptr            = &Globals.szChangeShareCommand,
3846                 .special        = NULL,
3847                 .enum_list      = NULL,
3848                 .flags          = FLAG_ADVANCED,
3849         },
3850         {
3851                 .label          = "delete share command",
3852                 .type           = P_STRING,
3853                 .p_class        = P_GLOBAL,
3854                 .ptr            = &Globals.szDeleteShareCommand,
3855                 .special        = NULL,
3856                 .enum_list      = NULL,
3857                 .flags          = FLAG_ADVANCED,
3858         },
3859         {
3860                 .label          = "config file",
3861                 .type           = P_STRING,
3862                 .p_class        = P_GLOBAL,
3863                 .ptr            = &Globals.szConfigFile,
3864                 .special        = NULL,
3865                 .enum_list      = NULL,
3866                 .flags          = FLAG_HIDE|FLAG_META,
3867         },
3868         {
3869                 .label          = "preload",
3870                 .type           = P_STRING,
3871                 .p_class        = P_GLOBAL,
3872                 .ptr            = &Globals.szAutoServices,
3873                 .special        = NULL,
3874                 .enum_list      = NULL,
3875                 .flags          = FLAG_ADVANCED,
3876         },
3877         {
3878                 .label          = "auto services",
3879                 .type           = P_STRING,
3880                 .p_class        = P_GLOBAL,
3881                 .ptr            = &Globals.szAutoServices,
3882                 .special        = NULL,
3883                 .enum_list      = NULL,
3884                 .flags          = FLAG_ADVANCED,
3885         },
3886         {
3887                 .label          = "lock directory",
3888                 .type           = P_STRING,
3889                 .p_class        = P_GLOBAL,
3890                 .ptr            = &Globals.szLockDir,
3891                 .special        = NULL,
3892                 .enum_list      = NULL,
3893                 .flags          = FLAG_ADVANCED,
3894         },
3895         {
3896                 .label          = "lock dir",
3897                 .type           = P_STRING,
3898                 .p_class        = P_GLOBAL,
3899                 .ptr            = &Globals.szLockDir,
3900                 .special        = NULL,
3901                 .enum_list      = NULL,
3902                 .flags          = FLAG_HIDE,
3903         },
3904         {
3905                 .label          = "state directory",
3906                 .type           = P_STRING,
3907                 .p_class        = P_GLOBAL,
3908                 .ptr            = &Globals.szStateDir,
3909                 .special        = NULL,
3910                 .enum_list      = NULL,
3911                 .flags          = FLAG_ADVANCED,
3912         },
3913         {
3914                 .label          = "cache directory",
3915                 .type           = P_STRING,
3916                 .p_class        = P_GLOBAL,
3917                 .ptr            = &Globals.szCacheDir,
3918                 .special        = NULL,
3919                 .enum_list      = NULL,
3920                 .flags          = FLAG_ADVANCED,
3921         },
3922         {
3923                 .label          = "pid directory",
3924                 .type           = P_STRING,
3925                 .p_class        = P_GLOBAL,
3926                 .ptr            = &Globals.szPidDir,
3927                 .special        = NULL,
3928                 .enum_list      = NULL,
3929                 .flags          = FLAG_ADVANCED,
3930         },
3931 #ifdef WITH_UTMP
3932         {
3933                 .label          = "utmp directory",
3934                 .type           = P_STRING,
3935                 .p_class        = P_GLOBAL,
3936                 .ptr            = &Globals.szUtmpDir,
3937                 .special        = NULL,
3938                 .enum_list      = NULL,
3939                 .flags          = FLAG_ADVANCED,
3940         },
3941         {
3942                 .label          = "wtmp directory",
3943                 .type           = P_STRING,
3944                 .p_class        = P_GLOBAL,
3945                 .ptr            = &Globals.szWtmpDir,
3946                 .special        = NULL,
3947                 .enum_list      = NULL,
3948                 .flags          = FLAG_ADVANCED,
3949         },
3950         {
3951                 .label          = "utmp",
3952                 .type           = P_BOOL,
3953                 .p_class        = P_GLOBAL,
3954                 .ptr            = &Globals.bUtmp,
3955                 .special        = NULL,
3956                 .enum_list      = NULL,
3957                 .flags          = FLAG_ADVANCED,
3958         },
3959 #endif
3960         {
3961                 .label          = "default service",
3962                 .type           = P_STRING,
3963                 .p_class        = P_GLOBAL,
3964                 .ptr            = &Globals.szDefaultService,
3965                 .special        = NULL,
3966                 .enum_list      = NULL,
3967                 .flags          = FLAG_ADVANCED,
3968         },
3969         {
3970                 .label          = "default",
3971                 .type           = P_STRING,
3972                 .p_class        = P_GLOBAL,
3973                 .ptr            = &Globals.szDefaultService,
3974                 .special        = NULL,
3975                 .enum_list      = NULL,
3976                 .flags          = FLAG_ADVANCED,
3977         },
3978         {
3979                 .label          = "message command",
3980                 .type           = P_STRING,
3981                 .p_class        = P_GLOBAL,
3982                 .ptr            = &Globals.szMsgCommand,
3983                 .special        = NULL,
3984                 .enum_list      = NULL,
3985                 .flags          = FLAG_ADVANCED,
3986         },
3987         {
3988                 .label          = "dfree cache time",
3989                 .type           = P_INTEGER,
3990                 .p_class        = P_LOCAL,
3991                 .ptr            = &sDefault.iDfreeCacheTime,
3992                 .special        = NULL,
3993                 .enum_list      = NULL,
3994                 .flags          = FLAG_ADVANCED,
3995         },
3996         {
3997                 .label          = "dfree command",
3998                 .type           = P_STRING,
3999                 .p_class        = P_LOCAL,
4000                 .ptr            = &sDefault.szDfree,
4001                 .special        = NULL,
4002                 .enum_list      = NULL,
4003                 .flags          = FLAG_ADVANCED,
4004         },
4005         {
4006                 .label          = "get quota command",
4007                 .type           = P_STRING,
4008                 .p_class        = P_GLOBAL,
4009                 .ptr            = &Globals.szGetQuota,
4010                 .special        = NULL,
4011                 .enum_list      = NULL,
4012                 .flags          = FLAG_ADVANCED,
4013         },
4014         {
4015                 .label          = "set quota command",
4016                 .type           = P_STRING,
4017                 .p_class        = P_GLOBAL,
4018                 .ptr            = &Globals.szSetQuota,
4019                 .special        = NULL,
4020                 .enum_list      = NULL,
4021                 .flags          = FLAG_ADVANCED,
4022         },
4023         {
4024                 .label          = "remote announce",
4025                 .type           = P_STRING,
4026                 .p_class        = P_GLOBAL,
4027                 .ptr            = &Globals.szRemoteAnnounce,
4028                 .special        = NULL,
4029                 .enum_list      = NULL,
4030                 .flags          = FLAG_ADVANCED,
4031         },
4032         {
4033                 .label          = "remote browse sync",
4034                 .type           = P_STRING,
4035                 .p_class        = P_GLOBAL,
4036                 .ptr            = &Globals.szRemoteBrowseSync,
4037                 .special        = NULL,
4038                 .enum_list      = NULL,
4039                 .flags          = FLAG_ADVANCED,
4040         },
4041         {
4042                 .label          = "socket address",
4043                 .type           = P_STRING,
4044                 .p_class        = P_GLOBAL,
4045                 .ptr            = &Globals.szSocketAddress,
4046                 .special        = NULL,
4047                 .enum_list      = NULL,
4048                 .flags          = FLAG_ADVANCED,
4049         },
4050         {
4051                 .label          = "nmbd bind explicit broadcast",
4052                 .type           = P_BOOL,
4053                 .p_class        = P_GLOBAL,
4054                 .ptr            = &Globals.bNmbdBindExplicitBroadcast,
4055                 .special        = NULL,
4056                 .enum_list      = NULL,
4057                 .flags          = FLAG_ADVANCED,
4058         },
4059         {
4060                 .label          = "homedir map",
4061                 .type           = P_STRING,
4062                 .p_class        = P_GLOBAL,
4063                 .ptr            = &Globals.szNISHomeMapName,
4064                 .special        = NULL,
4065                 .enum_list      = NULL,
4066                 .flags          = FLAG_ADVANCED,
4067         },
4068         {
4069                 .label          = "afs username map",
4070                 .type           = P_STRING,
4071                 .p_class        = P_GLOBAL,
4072                 .ptr            = &Globals.szAfsUsernameMap,
4073                 .special        = NULL,
4074                 .enum_list      = NULL,
4075                 .flags          = FLAG_ADVANCED,
4076         },
4077         {
4078                 .label          = "afs token lifetime",
4079                 .type           = P_INTEGER,
4080                 .p_class        = P_GLOBAL,
4081                 .ptr            = &Globals.iAfsTokenLifetime,
4082                 .special        = NULL,
4083                 .enum_list      = NULL,
4084                 .flags          = FLAG_ADVANCED,
4085         },
4086         {
4087                 .label          = "log nt token command",
4088                 .type           = P_STRING,
4089                 .p_class        = P_GLOBAL,
4090                 .ptr            = &Globals.szLogNtTokenCommand,
4091                 .special        = NULL,
4092                 .enum_list      = NULL,
4093                 .flags          = FLAG_ADVANCED,
4094         },
4095         {
4096                 .label          = "NIS homedir",
4097                 .type           = P_BOOL,
4098                 .p_class        = P_GLOBAL,
4099                 .ptr            = &Globals.bNISHomeMap,
4100                 .special        = NULL,
4101                 .enum_list      = NULL,
4102                 .flags          = FLAG_ADVANCED,
4103         },
4104         {
4105                 .label          = "-valid",
4106                 .type           = P_BOOL,
4107                 .p_class        = P_LOCAL,
4108                 .ptr            = &sDefault.valid,
4109                 .special        = NULL,
4110                 .enum_list      = NULL,
4111                 .flags          = FLAG_HIDE,
4112         },
4113         {
4114                 .label          = "copy",
4115                 .type           = P_STRING,
4116                 .p_class        = P_LOCAL,
4117                 .ptr            = &sDefault.szCopy,
4118                 .special        = handle_copy,
4119                 .enum_list      = NULL,
4120                 .flags          = FLAG_HIDE,
4121         },
4122         {
4123                 .label          = "include",
4124                 .type           = P_STRING,
4125                 .p_class        = P_LOCAL,
4126                 .ptr            = &sDefault.szInclude,
4127                 .special        = handle_include,
4128                 .enum_list      = NULL,
4129                 .flags          = FLAG_HIDE|FLAG_META,
4130         },
4131         {
4132                 .label          = "preexec",
4133                 .type           = P_STRING,
4134                 .p_class        = P_LOCAL,
4135                 .ptr            = &sDefault.szPreExec,
4136                 .special        = NULL,
4137                 .enum_list      = NULL,
4138                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4139         },
4140         {
4141                 .label          = "exec",
4142                 .type           = P_STRING,
4143                 .p_class        = P_LOCAL,
4144                 .ptr            = &sDefault.szPreExec,
4145                 .special        = NULL,
4146                 .enum_list      = NULL,
4147                 .flags          = FLAG_ADVANCED,
4148         },
4149         {
4150                 .label          = "preexec close",
4151                 .type           = P_BOOL,
4152                 .p_class        = P_LOCAL,
4153                 .ptr            = &sDefault.bPreexecClose,
4154                 .special        = NULL,
4155                 .enum_list      = NULL,
4156                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4157         },
4158         {
4159                 .label          = "postexec",
4160                 .type           = P_STRING,
4161                 .p_class        = P_LOCAL,
4162                 .ptr            = &sDefault.szPostExec,
4163                 .special        = NULL,
4164                 .enum_list      = NULL,
4165                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4166         },
4167         {
4168                 .label          = "root preexec",
4169                 .type           = P_STRING,
4170                 .p_class        = P_LOCAL,
4171                 .ptr            = &sDefault.szRootPreExec,
4172                 .special        = NULL,
4173                 .enum_list      = NULL,
4174                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4175         },
4176         {
4177                 .label          = "root preexec close",
4178                 .type           = P_BOOL,
4179                 .p_class        = P_LOCAL,
4180                 .ptr            = &sDefault.bRootpreexecClose,
4181                 .special        = NULL,
4182                 .enum_list      = NULL,
4183                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4184         },
4185         {
4186                 .label          = "root postexec",
4187                 .type           = P_STRING,
4188                 .p_class        = P_LOCAL,
4189                 .ptr            = &sDefault.szRootPostExec,
4190                 .special        = NULL,
4191                 .enum_list      = NULL,
4192                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4193         },
4194         {
4195                 .label          = "available",
4196                 .type           = P_BOOL,
4197                 .p_class        = P_LOCAL,
4198                 .ptr            = &sDefault.bAvailable,
4199                 .special        = NULL,
4200                 .enum_list      = NULL,
4201                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4202         },
4203         {
4204                 .label          = "registry shares",
4205                 .type           = P_BOOL,
4206                 .p_class        = P_GLOBAL,
4207                 .ptr            = &Globals.bRegistryShares,
4208                 .special        = NULL,
4209                 .enum_list      = NULL,
4210                 .flags          = FLAG_ADVANCED,
4211         },
4212         {
4213                 .label          = "usershare allow guests",
4214                 .type           = P_BOOL,
4215                 .p_class        = P_GLOBAL,
4216                 .ptr            = &Globals.bUsershareAllowGuests,
4217                 .special        = NULL,
4218                 .enum_list      = NULL,
4219                 .flags          = FLAG_ADVANCED,
4220         },
4221         {
4222                 .label          = "usershare max shares",
4223                 .type           = P_INTEGER,
4224                 .p_class        = P_GLOBAL,
4225                 .ptr            = &Globals.iUsershareMaxShares,
4226                 .special        = NULL,
4227                 .enum_list      = NULL,
4228                 .flags          = FLAG_ADVANCED,
4229         },
4230         {
4231                 .label          = "usershare owner only",
4232                 .type           = P_BOOL,
4233                 .p_class        = P_GLOBAL,
4234                 .ptr            = &Globals.bUsershareOwnerOnly,
4235                 .special        = NULL,
4236                 .enum_list      = NULL,
4237                 .flags          = FLAG_ADVANCED,
4238         },
4239         {
4240                 .label          = "usershare path",
4241                 .type           = P_STRING,
4242                 .p_class        = P_GLOBAL,
4243                 .ptr            = &Globals.szUsersharePath,
4244                 .special        = NULL,
4245                 .enum_list      = NULL,
4246                 .flags          = FLAG_ADVANCED,
4247         },
4248         {
4249                 .label          = "usershare prefix allow list",
4250                 .type           = P_LIST,
4251                 .p_class        = P_GLOBAL,
4252                 .ptr            = &Globals.szUsersharePrefixAllowList,
4253                 .special        = NULL,
4254                 .enum_list      = NULL,
4255                 .flags          = FLAG_ADVANCED,
4256         },
4257         {
4258                 .label          = "usershare prefix deny list",
4259                 .type           = P_LIST,
4260                 .p_class        = P_GLOBAL,
4261                 .ptr            = &Globals.szUsersharePrefixDenyList,
4262                 .special        = NULL,
4263                 .enum_list      = NULL,
4264                 .flags          = FLAG_ADVANCED,
4265         },
4266         {
4267                 .label          = "usershare template share",
4268                 .type           = P_STRING,
4269                 .p_class        = P_GLOBAL,
4270                 .ptr            = &Globals.szUsershareTemplateShare,
4271                 .special        = NULL,
4272                 .enum_list      = NULL,
4273                 .flags          = FLAG_ADVANCED,
4274         },
4275         {
4276                 .label          = "volume",
4277                 .type           = P_STRING,
4278                 .p_class        = P_LOCAL,
4279                 .ptr            = &sDefault.volume,
4280                 .special        = NULL,
4281                 .enum_list      = NULL,
4282                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4283         },
4284         {
4285                 .label          = "fstype",
4286                 .type           = P_STRING,
4287                 .p_class        = P_LOCAL,
4288                 .ptr            = &sDefault.fstype,
4289                 .special        = NULL,
4290                 .enum_list      = NULL,
4291                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4292         },
4293         {
4294                 .label          = "set directory",
4295                 .type           = P_BOOLREV,
4296                 .p_class        = P_LOCAL,
4297                 .ptr            = &sDefault.bNo_set_dir,
4298                 .special        = NULL,
4299                 .enum_list      = NULL,
4300                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4301         },
4302         {
4303                 .label          = "wide links",
4304                 .type           = P_BOOL,
4305                 .p_class        = P_LOCAL,
4306                 .ptr            = &sDefault.bWidelinks,
4307                 .special        = NULL,
4308                 .enum_list      = NULL,
4309                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4310         },
4311         {
4312                 .label          = "follow symlinks",
4313                 .type           = P_BOOL,
4314                 .p_class        = P_LOCAL,
4315                 .ptr            = &sDefault.bSymlinks,
4316                 .special        = NULL,
4317                 .enum_list      = NULL,
4318                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4319         },
4320         {
4321                 .label          = "dont descend",
4322                 .type           = P_STRING,
4323                 .p_class        = P_LOCAL,
4324                 .ptr            = &sDefault.szDontdescend,
4325                 .special        = NULL,
4326                 .enum_list      = NULL,
4327                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4328         },
4329         {
4330                 .label          = "magic script",
4331                 .type           = P_STRING,
4332                 .p_class        = P_LOCAL,
4333                 .ptr            = &sDefault.szMagicScript,
4334                 .special        = NULL,
4335                 .enum_list      = NULL,
4336                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4337         },
4338         {
4339                 .label          = "magic output",
4340                 .type           = P_STRING,
4341                 .p_class        = P_LOCAL,
4342                 .ptr            = &sDefault.szMagicOutput,
4343                 .special        = NULL,
4344                 .enum_list      = NULL,
4345                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4346         },
4347         {
4348                 .label          = "delete readonly",
4349                 .type           = P_BOOL,
4350                 .p_class        = P_LOCAL,
4351                 .ptr            = &sDefault.bDeleteReadonly,
4352                 .special        = NULL,
4353                 .enum_list      = NULL,
4354                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4355         },
4356         {
4357                 .label          = "dos filemode",
4358                 .type           = P_BOOL,
4359                 .p_class        = P_LOCAL,
4360                 .ptr            = &sDefault.bDosFilemode,
4361                 .special        = NULL,
4362                 .enum_list      = NULL,
4363                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4364         },
4365         {
4366                 .label          = "dos filetimes",
4367                 .type           = P_BOOL,
4368                 .p_class        = P_LOCAL,
4369                 .ptr            = &sDefault.bDosFiletimes,
4370                 .special        = NULL,
4371                 .enum_list      = NULL,
4372                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4373         },
4374         {
4375                 .label          = "dos filetime resolution",
4376                 .type           = P_BOOL,
4377                 .p_class        = P_LOCAL,
4378                 .ptr            = &sDefault.bDosFiletimeResolution,
4379                 .special        = NULL,
4380                 .enum_list      = NULL,
4381                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4382         },
4383         {
4384                 .label          = "fake directory create times",
4385                 .type           = P_BOOL,
4386                 .p_class        = P_LOCAL,
4387                 .ptr            = &sDefault.bFakeDirCreateTimes,
4388                 .special        = NULL,
4389                 .enum_list      = NULL,
4390                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
4391         },
4392         {
4393                 .label          = "async smb echo handler",
4394                 .type           = P_BOOL,
4395                 .p_class        = P_GLOBAL,
4396                 .ptr            = &Globals.bAsyncSMBEchoHandler,
4397                 .special        = NULL,
4398                 .enum_list      = NULL,
4399                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
4400         },
4401         {
4402                 .label          = "multicast dns register",
4403                 .type           = P_BOOL,
4404                 .p_class        = P_GLOBAL,
4405                 .ptr            = &Globals.bMulticastDnsRegister,
4406                 .special        = NULL,
4407                 .enum_list      = NULL,
4408                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
4409         },
4410         {
4411                 .label          = "panic action",
4412                 .type           = P_STRING,
4413                 .p_class        = P_GLOBAL,
4414                 .ptr            = &Globals.szPanicAction,
4415                 .special        = NULL,
4416                 .enum_list      = NULL,
4417                 .flags          = FLAG_ADVANCED,
4418         },
4419         {
4420                 .label          = "perfcount module",
4421                 .type           = P_STRING,
4422                 .p_class        = P_GLOBAL,
4423                 .ptr            = &Globals.szSMBPerfcountModule,
4424                 .special        = NULL,
4425                 .enum_list      = NULL,
4426                 .flags          = FLAG_ADVANCED,
4427         },
4428
4429         {N_("VFS module options"), P_SEP, P_SEPARATOR},
4430
4431         {
4432                 .label          = "vfs objects",
4433                 .type           = P_LIST,
4434                 .p_class        = P_LOCAL,
4435                 .ptr            = &sDefault.szVfsObjects,
4436                 .special        = NULL,
4437                 .enum_list      = NULL,
4438                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4439         },
4440         {
4441                 .label          = "vfs object",
4442                 .type           = P_LIST,
4443                 .p_class        = P_LOCAL,
4444                 .ptr            = &sDefault.szVfsObjects,
4445                 .special        = NULL,
4446                 .enum_list      = NULL,
4447                 .flags          = FLAG_HIDE,
4448         },
4449
4450
4451         {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4452
4453         {
4454                 .label          = "msdfs root",
4455                 .type           = P_BOOL,
4456                 .p_class        = P_LOCAL,
4457                 .ptr            = &sDefault.bMSDfsRoot,
4458                 .special        = NULL,
4459                 .enum_list      = NULL,
4460                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4461         },
4462         {
4463                 .label          = "msdfs proxy",
4464                 .type           = P_STRING,
4465                 .p_class        = P_LOCAL,
4466                 .ptr            = &sDefault.szMSDfsProxy,
4467                 .special        = NULL,
4468                 .enum_list      = NULL,
4469                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4470         },
4471         {
4472                 .label          = "host msdfs",
4473                 .type           = P_BOOL,
4474                 .p_class        = P_GLOBAL,
4475                 .ptr            = &Globals.bHostMSDfs,
4476                 .special        = NULL,
4477                 .enum_list      = NULL,
4478                 .flags          = FLAG_ADVANCED,
4479         },
4480
4481         {N_("Winbind options"), P_SEP, P_SEPARATOR},
4482
4483         {
4484                 .label          = "passdb expand explicit",
4485                 .type           = P_BOOL,
4486                 .p_class        = P_GLOBAL,
4487                 .ptr            = &Globals.bPassdbExpandExplicit,
4488                 .special        = NULL,
4489                 .enum_list      = NULL,
4490                 .flags          = FLAG_ADVANCED,
4491         },
4492         {
4493                 .label          = "idmap backend",
4494                 .type           = P_STRING,
4495                 .p_class        = P_GLOBAL,
4496                 .ptr            = &Globals.szIdmapBackend,
4497                 .special        = handle_idmap_backend,
4498                 .enum_list      = NULL,
4499                 .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
4500         },
4501         {
4502                 .label          = "idmap cache time",
4503                 .type           = P_INTEGER,
4504                 .p_class        = P_GLOBAL,
4505                 .ptr            = &Globals.iIdmapCacheTime,
4506                 .special        = NULL,
4507                 .enum_list      = NULL,
4508                 .flags          = FLAG_ADVANCED,
4509         },
4510         {
4511                 .label          = "idmap negative cache time",
4512                 .type           = P_INTEGER,
4513                 .p_class        = P_GLOBAL,
4514                 .ptr            = &Globals.iIdmapNegativeCacheTime,
4515                 .special        = NULL,
4516                 .enum_list      = NULL,
4517                 .flags          = FLAG_ADVANCED,
4518         },
4519         {
4520                 .label          = "idmap uid",
4521                 .type           = P_STRING,
4522                 .p_class        = P_GLOBAL,
4523                 .ptr            = &Globals.szIdmapUID,
4524                 .special        = handle_idmap_uid,
4525                 .enum_list      = NULL,
4526                 .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
4527         },
4528         {
4529                 .label          = "winbind uid",
4530                 .type           = P_STRING,
4531                 .p_class        = P_GLOBAL,
4532                 .ptr            = &Globals.szIdmapUID,
4533                 .special        = handle_idmap_uid,
4534                 .enum_list      = NULL,
4535                 .flags          = FLAG_HIDE,
4536         },
4537         {
4538                 .label          = "idmap gid",
4539                 .type           = P_STRING,
4540                 .p_class        = P_GLOBAL,
4541                 .ptr            = &Globals.szIdmapGID,
4542                 .special        = handle_idmap_gid,
4543                 .enum_list      = NULL,
4544                 .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
4545         },
4546         {
4547                 .label          = "winbind gid",
4548                 .type           = P_STRING,
4549                 .p_class        = P_GLOBAL,
4550                 .ptr            = &Globals.szIdmapGID,
4551                 .special        = handle_idmap_gid,
4552                 .enum_list      = NULL,
4553                 .flags          = FLAG_HIDE,
4554         },
4555         {
4556                 .label          = "template homedir",
4557                 .type           = P_STRING,
4558                 .p_class        = P_GLOBAL,
4559                 .ptr            = &Globals.szTemplateHomedir,
4560                 .special        = NULL,
4561                 .enum_list      = NULL,
4562                 .flags          = FLAG_ADVANCED,
4563         },
4564         {
4565                 .label          = "template shell",
4566                 .type           = P_STRING,
4567                 .p_class        = P_GLOBAL,
4568                 .ptr            = &Globals.szTemplateShell,
4569                 .special        = NULL,
4570                 .enum_list      = NULL,
4571                 .flags          = FLAG_ADVANCED,
4572         },
4573         {
4574                 .label          = "winbind separator",
4575                 .type           = P_STRING,
4576                 .p_class        = P_GLOBAL,
4577                 .ptr            = &Globals.szWinbindSeparator,
4578                 .special        = NULL,
4579                 .enum_list      = NULL,
4580                 .flags          = FLAG_ADVANCED,
4581         },
4582         {
4583                 .label          = "winbind cache time",
4584                 .type           = P_INTEGER,
4585                 .p_class        = P_GLOBAL,
4586                 .ptr            = &Globals.winbind_cache_time,
4587                 .special        = NULL,
4588                 .enum_list      = NULL,
4589                 .flags          = FLAG_ADVANCED,
4590         },
4591         {
4592                 .label          = "winbind reconnect delay",
4593                 .type           = P_INTEGER,
4594                 .p_class        = P_GLOBAL,
4595                 .ptr            = &Globals.winbind_reconnect_delay,
4596                 .special        = NULL,
4597                 .enum_list      = NULL,
4598                 .flags          = FLAG_ADVANCED,
4599         },
4600         {
4601                 .label          = "winbind max clients",
4602                 .type           = P_INTEGER,
4603                 .p_class        = P_GLOBAL,
4604                 .ptr            = &Globals.winbind_max_clients,
4605                 .special        = NULL,
4606                 .enum_list      = NULL,
4607                 .flags          = FLAG_ADVANCED,
4608         },
4609         {
4610                 .label          = "winbind enum users",
4611                 .type           = P_BOOL,
4612                 .p_class        = P_GLOBAL,
4613                 .ptr            = &Globals.bWinbindEnumUsers,
4614                 .special        = NULL,
4615                 .enum_list      = NULL,
4616                 .flags          = FLAG_ADVANCED,
4617         },
4618         {
4619                 .label          = "winbind enum groups",
4620                 .type           = P_BOOL,
4621                 .p_class        = P_GLOBAL,
4622                 .ptr            = &Globals.bWinbindEnumGroups,
4623                 .special        = NULL,
4624                 .enum_list      = NULL,
4625                 .flags          = FLAG_ADVANCED,
4626         },
4627         {
4628                 .label          = "winbind use default domain",
4629                 .type           = P_BOOL,
4630                 .p_class        = P_GLOBAL,
4631                 .ptr            = &Globals.bWinbindUseDefaultDomain,
4632                 .special        = NULL,
4633                 .enum_list      = NULL,
4634                 .flags          = FLAG_ADVANCED,
4635         },
4636         {
4637                 .label          = "winbind trusted domains only",
4638                 .type           = P_BOOL,
4639                 .p_class        = P_GLOBAL,
4640                 .ptr            = &Globals.bWinbindTrustedDomainsOnly,
4641                 .special        = NULL,
4642                 .enum_list      = NULL,
4643                 .flags          = FLAG_ADVANCED,
4644         },
4645         {
4646                 .label          = "winbind nested groups",
4647                 .type           = P_BOOL,
4648                 .p_class        = P_GLOBAL,
4649                 .ptr            = &Globals.bWinbindNestedGroups,
4650                 .special        = NULL,
4651                 .enum_list      = NULL,
4652                 .flags          = FLAG_ADVANCED,
4653         },
4654         {
4655                 .label          = "winbind expand groups",
4656                 .type           = P_INTEGER,
4657                 .p_class        = P_GLOBAL,
4658                 .ptr            = &Globals.winbind_expand_groups,
4659                 .special        = NULL,
4660                 .enum_list      = NULL,
4661                 .flags          = FLAG_ADVANCED,
4662         },
4663         {
4664                 .label          = "winbind nss info",
4665                 .type           = P_LIST,
4666                 .p_class        = P_GLOBAL,
4667                 .ptr            = &Globals.szWinbindNssInfo,
4668                 .special        = NULL,
4669                 .enum_list      = NULL,
4670                 .flags          = FLAG_ADVANCED,
4671         },
4672         {
4673                 .label          = "winbind refresh tickets",
4674                 .type           = P_BOOL,
4675                 .p_class        = P_GLOBAL,
4676                 .ptr            = &Globals.bWinbindRefreshTickets,
4677                 .special        = NULL,
4678                 .enum_list      = NULL,
4679                 .flags          = FLAG_ADVANCED,
4680         },
4681         {
4682                 .label          = "winbind offline logon",
4683                 .type           = P_BOOL,
4684                 .p_class        = P_GLOBAL,
4685                 .ptr            = &Globals.bWinbindOfflineLogon,
4686                 .special        = NULL,
4687                 .enum_list      = NULL,
4688                 .flags          = FLAG_ADVANCED,
4689         },
4690         {
4691                 .label          = "winbind normalize names",
4692                 .type           = P_BOOL,
4693                 .p_class        = P_GLOBAL,
4694                 .ptr            = &Globals.bWinbindNormalizeNames,
4695                 .special        = NULL,
4696                 .enum_list      = NULL,
4697                 .flags          = FLAG_ADVANCED,
4698         },
4699         {
4700                 .label          = "winbind rpc only",
4701                 .type           = P_BOOL,
4702                 .p_class        = P_GLOBAL,
4703                 .ptr            = &Globals.bWinbindRpcOnly,
4704                 .special        = NULL,
4705                 .enum_list      = NULL,
4706                 .flags          = FLAG_ADVANCED,
4707         },
4708         {
4709                 .label          = "create krb5 conf",
4710                 .type           = P_BOOL,
4711                 .p_class        = P_GLOBAL,
4712                 .ptr            = &Globals.bCreateKrb5Conf,
4713                 .special        = NULL,
4714                 .enum_list      = NULL,
4715                 .flags          = FLAG_ADVANCED,
4716         },
4717         {
4718                 .label          = "ncalrpc dir",
4719                 .type           = P_STRING,
4720                 .p_class        = P_GLOBAL,
4721                 .ptr            = &Globals.ncalrpc_dir,
4722                 .special        = NULL,
4723                 .enum_list      = NULL,
4724                 .flags          = FLAG_ADVANCED,
4725         },
4726         {
4727                 .label          = "winbind max domain connections",
4728                 .type           = P_INTEGER,
4729                 .p_class        = P_GLOBAL,
4730                 .ptr            = &Globals.winbindMaxDomainConnections,
4731                 .special        = NULL,
4732                 .enum_list      = NULL,
4733                 .flags          = FLAG_ADVANCED,
4734         },
4735
4736         {NULL,  P_BOOL,  P_NONE,  NULL,  NULL,  NULL,  0}
4737 };
4738
4739 /***************************************************************************
4740  Initialise the sDefault parameter structure for the printer values.
4741 ***************************************************************************/
4742
4743 static void init_printer_values(struct loadparm_service *pService)
4744 {
4745         /* choose defaults depending on the type of printing */
4746         switch (pService->iPrinting) {
4747                 case PRINT_BSD:
4748                 case PRINT_AIX:
4749                 case PRINT_LPRNT:
4750                 case PRINT_LPROS2:
4751                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4752                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4753                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4754                         break;
4755
4756                 case PRINT_LPRNG:
4757                 case PRINT_PLP:
4758                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4759                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4760                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4761                         string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4762                         string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4763                         string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4764                         string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4765                         break;
4766
4767                 case PRINT_CUPS:
4768                 case PRINT_IPRINT:
4769 #ifdef HAVE_CUPS
4770                         /* set the lpq command to contain the destination printer
4771                            name only.  This is used by cups_queue_get() */
4772                         string_set(&pService->szLpqcommand, "%p");
4773                         string_set(&pService->szLprmcommand, "");
4774                         string_set(&pService->szPrintcommand, "");
4775                         string_set(&pService->szLppausecommand, "");
4776                         string_set(&pService->szLpresumecommand, "");
4777                         string_set(&pService->szQueuepausecommand, "");
4778                         string_set(&pService->szQueueresumecommand, "");
4779 #else
4780                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4781                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4782                         string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4783                         string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4784                         string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4785                         string_set(&pService->szQueuepausecommand, "disable '%p'");
4786                         string_set(&pService->szQueueresumecommand, "enable '%p'");
4787 #endif /* HAVE_CUPS */
4788                         break;
4789
4790                 case PRINT_SYSV:
4791                 case PRINT_HPUX:
4792                         string_set(&pService->szLpqcommand, "lpstat -o%p");
4793                         string_set(&pService->szLprmcommand, "cancel %p-%j");
4794                         string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4795                         string_set(&pService->szQueuepausecommand, "disable %p");
4796                         string_set(&pService->szQueueresumecommand, "enable %p");
4797 #ifndef HPUX
4798                         string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4799                         string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4800 #endif /* HPUX */
4801                         break;
4802
4803                 case PRINT_QNX:
4804                         string_set(&pService->szLpqcommand, "lpq -P%p");
4805                         string_set(&pService->szLprmcommand, "lprm -P%p %j");
4806                         string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4807                         break;
4808
4809 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4810
4811         case PRINT_TEST:
4812         case PRINT_VLP: {
4813                 const char *tdbfile;
4814                 char *tmp;
4815
4816                 tdbfile = talloc_asprintf(
4817                         talloc_tos(), "tdbfile=%s",
4818                         lp_parm_const_string(-1, "vlp", "tdbfile",
4819                                              "/tmp/vlp.tdb"));
4820                 if (tdbfile == NULL) {
4821                         tdbfile="tdbfile=/tmp/vlp.tdb";
4822                 }
4823
4824                 tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
4825                                       tdbfile);
4826                 string_set(&pService->szPrintcommand,
4827                            tmp ? tmp : "vlp print %p %s");
4828                 TALLOC_FREE(tmp);
4829
4830                 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
4831                                       tdbfile);
4832                 string_set(&pService->szLpqcommand,
4833                            tmp ? tmp : "vlp lpq %p");
4834                 TALLOC_FREE(tmp);
4835
4836                 tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
4837                                       tdbfile);
4838                 string_set(&pService->szLprmcommand,
4839                            tmp ? tmp : "vlp lprm %p %j");
4840                 TALLOC_FREE(tmp);
4841
4842                 tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
4843                                       tdbfile);
4844                 string_set(&pService->szLppausecommand,
4845                            tmp ? tmp : "vlp lppause %p %j");
4846                 TALLOC_FREE(tmp);
4847
4848                 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
4849                                       tdbfile);
4850                 string_set(&pService->szLpresumecommand,
4851                            tmp ? tmp : "vlp lpresume %p %j");
4852                 TALLOC_FREE(tmp);
4853
4854                 tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
4855                                       tdbfile);
4856                 string_set(&pService->szQueuepausecommand,
4857                            tmp ? tmp : "vlp queuepause %p");
4858                 TALLOC_FREE(tmp);
4859
4860                 tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
4861                                       tdbfile);
4862                 string_set(&pService->szQueueresumecommand,
4863                            tmp ? tmp : "vlp queueresume %p");
4864                 TALLOC_FREE(tmp);
4865
4866                 break;
4867         }
4868 #endif /* DEVELOPER */
4869
4870         }
4871 }
4872 /**
4873  *  Function to return the default value for the maximum number of open
4874  *  file descriptors permitted.  This function tries to consult the
4875  *  kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4876  *  the smaller of those.
4877  */
4878 static int max_open_files(void)
4879 {
4880         int sysctl_max = MAX_OPEN_FILES;
4881         int rlimit_max = MAX_OPEN_FILES;
4882
4883 #ifdef HAVE_SYSCTLBYNAME
4884         {
4885                 size_t size = sizeof(sysctl_max);
4886                 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4887                              0);
4888         }
4889 #endif
4890
4891 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4892         {
4893                 struct rlimit rl;
4894
4895                 ZERO_STRUCT(rl);
4896
4897                 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4898                         rlimit_max = rl.rlim_cur;
4899
4900 #if defined(RLIM_INFINITY)
4901                 if(rl.rlim_cur == RLIM_INFINITY)
4902                         rlimit_max = MAX_OPEN_FILES;
4903 #endif
4904         }
4905 #endif
4906
4907         if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4908                 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4909                         "minimum Windows limit (%d)\n",
4910                         sysctl_max,
4911                         MIN_OPEN_FILES_WINDOWS));
4912                 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4913         }
4914
4915         if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4916                 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4917                         "minimum Windows limit (%d)\n",
4918                         rlimit_max,
4919                         MIN_OPEN_FILES_WINDOWS));
4920                 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4921         }
4922
4923         return MIN(sysctl_max, rlimit_max);
4924 }
4925
4926 /**
4927  * Common part of freeing allocated data for one parameter.
4928  */
4929 static void free_one_parameter_common(void *parm_ptr,
4930                                       struct parm_struct parm)
4931 {
4932         if ((parm.type == P_STRING) ||
4933             (parm.type == P_USTRING))
4934         {
4935                 string_free((char**)parm_ptr);
4936         } else if (parm.type == P_LIST) {
4937                 TALLOC_FREE(*((char***)parm_ptr));
4938         }
4939 }
4940
4941 /**
4942  * Free the allocated data for one parameter for a share
4943  * given as a service struct.
4944  */
4945 static void free_one_parameter(struct loadparm_service *service,
4946                                struct parm_struct parm)
4947 {
4948         void *parm_ptr;
4949
4950         if (parm.p_class != P_LOCAL) {
4951                 return;
4952         }
4953
4954         parm_ptr = lp_parm_ptr(service, &parm);
4955
4956         free_one_parameter_common(parm_ptr, parm);
4957 }
4958
4959 /**
4960  * Free the allocated parameter data of a share given
4961  * as a service struct.
4962  */
4963 static void free_parameters(struct loadparm_service *service)
4964 {
4965         uint32_t i;
4966
4967         for (i=0; parm_table[i].label; i++) {
4968                 free_one_parameter(service, parm_table[i]);
4969         }
4970 }
4971
4972 /**
4973  * Free the allocated data for one parameter for a given share
4974  * specified by an snum.
4975  */
4976 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4977 {
4978         void *parm_ptr;
4979
4980         if (parm.ptr == NULL) {
4981                 return;
4982         }
4983
4984         if (snum < 0) {
4985                 parm_ptr = lp_parm_ptr(NULL, &parm);
4986         } else if (parm.p_class != P_LOCAL) {
4987                 return;
4988         } else {
4989                 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
4990         }
4991
4992         free_one_parameter_common(parm_ptr, parm);
4993 }
4994
4995 /**
4996  * Free the allocated parameter data for a share specified
4997  * by an snum.
4998  */
4999 static void free_parameters_by_snum(int snum)
5000 {
5001         uint32_t i;
5002
5003         for (i=0; parm_table[i].label; i++) {
5004                 free_one_parameter_by_snum(snum, parm_table[i]);
5005         }
5006 }
5007
5008 /**
5009  * Free the allocated global parameters.
5010  */
5011 static void free_global_parameters(void)
5012 {
5013         free_parameters_by_snum(GLOBAL_SECTION_SNUM);
5014 }
5015
5016 static int map_parameter(const char *pszParmName);
5017
5018 struct lp_stored_option {
5019         struct lp_stored_option *prev, *next;
5020         const char *label;
5021         const char *value;
5022 };
5023
5024 static struct lp_stored_option *stored_options;
5025
5026 /*
5027   save options set by lp_set_cmdline() into a list. This list is
5028   re-applied when we do a globals reset, so that cmdline set options
5029   are sticky across reloads of smb.conf
5030  */
5031 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
5032 {
5033         struct lp_stored_option *entry, *entry_next;
5034         for (entry = stored_options; entry != NULL; entry = entry_next) {
5035                 entry_next = entry->next;
5036                 if (strcmp(pszParmName, entry->label) == 0) {
5037                         DLIST_REMOVE(stored_options, entry);
5038                         talloc_free(entry);
5039                         break;
5040                 }
5041         }
5042
5043         entry = talloc(NULL, struct lp_stored_option);
5044         if (!entry) {
5045                 return false;
5046         }
5047
5048         entry->label = talloc_strdup(entry, pszParmName);
5049         if (!entry->label) {
5050                 talloc_free(entry);
5051                 return false;
5052         }
5053
5054         entry->value = talloc_strdup(entry, pszParmValue);
5055         if (!entry->value) {
5056                 talloc_free(entry);
5057                 return false;
5058         }
5059
5060         DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
5061
5062         return true;
5063 }
5064
5065 static bool apply_lp_set_cmdline(void)
5066 {
5067         struct lp_stored_option *entry = NULL;
5068         for (entry = stored_options; entry != NULL; entry = entry->next) {
5069                 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
5070                         DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
5071                                   entry->label, entry->value));
5072                         return false;
5073                 }
5074         }
5075         return true;
5076 }
5077
5078 /***************************************************************************
5079  Initialise the global parameter structure.
5080 ***************************************************************************/
5081
5082 static void init_globals(bool reinit_globals)
5083 {
5084         static bool done_init = False;
5085         char *s = NULL;
5086         int i;
5087
5088         /* If requested to initialize only once and we've already done it... */
5089         if (!reinit_globals && done_init) {
5090                 /* ... then we have nothing more to do */
5091                 return;
5092         }
5093
5094         if (!done_init) {
5095                 /* The logfile can be set before this is invoked. Free it if so. */
5096                 if (Globals.szLogFile != NULL) {
5097                         string_free(&Globals.szLogFile);
5098                         Globals.szLogFile = NULL;
5099                 }
5100                 done_init = True;
5101         } else {
5102                 free_global_parameters();
5103         }
5104
5105         /* This memset and the free_global_parameters() above will
5106          * wipe out smb.conf options set with lp_set_cmdline().  The
5107          * apply_lp_set_cmdline() call puts these values back in the
5108          * table once the defaults are set */
5109         memset((void *)&Globals, '\0', sizeof(Globals));
5110
5111         for (i = 0; parm_table[i].label; i++) {
5112                 if ((parm_table[i].type == P_STRING ||
5113                      parm_table[i].type == P_USTRING) &&
5114                     parm_table[i].ptr)
5115                 {
5116                         string_set(lp_parm_ptr(NULL, &parm_table[i]), "");
5117                 }
5118         }
5119
5120
5121         string_set(&sDefault.fstype, FSTYPE_STRING);
5122         string_set(&sDefault.szPrintjobUsername, "%U");
5123
5124         init_printer_values(&sDefault);
5125
5126
5127         DEBUG(3, ("Initialising global parameters\n"));
5128
5129         /* Must manually force to upper case here, as this does not go via the handler */
5130         string_set(&Globals.szNetbiosName, myhostname_upper());
5131
5132         string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
5133         string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
5134
5135         /* use the new 'hash2' method by default, with a prefix of 1 */
5136         string_set(&Globals.szManglingMethod, "hash2");
5137         Globals.mangle_prefix = 1;
5138
5139         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5140
5141         /* using UTF8 by default allows us to support all chars */
5142         string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5143
5144         /* Use codepage 850 as a default for the dos character set */
5145         string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5146
5147         /*
5148          * Allow the default PASSWD_CHAT to be overridden in local.h.
5149          */
5150         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5151
5152         string_set(&Globals.szWorkgroup, WORKGROUP);
5153
5154         string_set(&Globals.szPasswdProgram, "");
5155         string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5156         string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5157         string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5158         string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5159         string_set(&Globals.szSocketAddress, "0.0.0.0");
5160         /*
5161          * By default support explicit binding to broadcast
5162          * addresses.
5163          */
5164         Globals.bNmbdBindExplicitBroadcast = true;
5165
5166         if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5167                 smb_panic("init_globals: ENOMEM");
5168         }
5169         string_set(&Globals.szServerString, s);
5170         SAFE_FREE(s);
5171 #ifdef DEVELOPER
5172         string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5173 #endif
5174
5175         string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5176
5177         string_set(&Globals.szLogonDrive, "");
5178         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5179         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5180         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5181
5182         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5183         string_set(&Globals.szPasswordServer, "*");
5184
5185         Globals.AlgorithmicRidBase = BASE_RID;
5186
5187         Globals.bLoadPrinters = True;
5188         Globals.PrintcapCacheTime = 750;        /* 12.5 minutes */
5189
5190         Globals.ConfigBackend = config_backend;
5191
5192         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5193         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5194         Globals.max_xmit = 0x4104;
5195         Globals.max_mux = 50;   /* This is *needed* for profile support. */
5196         Globals.lpqcachetime = 30;      /* changed to handle large print servers better -- jerry */
5197         Globals.bDisableSpoolss = False;
5198         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5199         Globals.pwordlevel = 0;
5200         Globals.unamelevel = 0;
5201         Globals.deadtime = 0;
5202         Globals.getwd_cache = true;
5203         Globals.bLargeReadwrite = True;
5204         Globals.max_log_size = 5000;
5205         Globals.max_open_files = max_open_files();
5206         Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5207         Globals.maxprotocol = PROTOCOL_NT1;
5208         Globals.minprotocol = PROTOCOL_CORE;
5209         Globals.security = SEC_USER;
5210         Globals.paranoid_server_security = True;
5211         Globals.bEncryptPasswords = True;
5212         Globals.bUpdateEncrypt = False;
5213         Globals.clientSchannel = Auto;
5214         Globals.serverSchannel = Auto;
5215         Globals.bReadRaw = True;
5216         Globals.bWriteRaw = True;
5217         Globals.bNullPasswords = False;
5218         Globals.bObeyPamRestrictions = False;
5219         Globals.syslog = 1;
5220         Globals.bSyslogOnly = False;
5221         Globals.bTimestampLogs = True;
5222         string_set(&Globals.szLogLevel, "0");
5223         Globals.bDebugPrefixTimestamp = False;
5224         Globals.bDebugHiresTimestamp = true;
5225         Globals.bDebugPid = False;
5226         Globals.bDebugUid = False;
5227         Globals.bDebugClass = False;
5228         Globals.bEnableCoreFiles = True;
5229         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
5230         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
5231         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
5232         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
5233         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
5234         Globals.lm_interval = 60;
5235 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5236         Globals.bNISHomeMap = False;
5237 #ifdef WITH_NISPLUS_HOME
5238         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5239 #else
5240         string_set(&Globals.szNISHomeMapName, "auto.home");
5241 #endif
5242 #endif
5243         Globals.bTimeServer = False;
5244         Globals.bBindInterfacesOnly = False;
5245         Globals.bUnixPasswdSync = False;
5246         Globals.bPamPasswordChange = False;
5247         Globals.bPasswdChatDebug = False;
5248         Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5249         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
5250         Globals.bNTStatusSupport = True; /* Use NT status by default. */
5251         Globals.bStatCache = True;      /* use stat cache by default */
5252         Globals.iMaxStatCacheSize = 256; /* 256k by default */
5253         Globals.restrict_anonymous = 0;
5254         Globals.bClientLanManAuth = False;      /* Do NOT use the LanMan hash if it is available */
5255         Globals.bClientPlaintextAuth = False;   /* Do NOT use a plaintext password even if is requested by the server */
5256         Globals.bLanmanAuth = False;    /* Do NOT use the LanMan hash, even if it is supplied */
5257         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5258         Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
5259         /* Note, that we will also use NTLM2 session security (which is different), if it is available */
5260
5261         Globals.map_to_guest = 0;       /* By Default, "Never" */
5262         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
5263         Globals.enhanced_browsing = true;
5264         Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5265 #ifdef MMAP_BLACKLIST
5266         Globals.bUseMmap = False;
5267 #else
5268         Globals.bUseMmap = True;
5269 #endif
5270         Globals.bUnixExtensions = True;
5271         Globals.bResetOnZeroVC = False;
5272         Globals.bLogWriteableFilesOnExit = False;
5273         Globals.bCreateKrb5Conf = true;
5274         Globals.winbindMaxDomainConnections = 1;
5275
5276         /* hostname lookups can be very expensive and are broken on
5277            a large number of sites (tridge) */
5278         Globals.bHostnameLookups = False;
5279
5280         string_set(&Globals.szPassdbBackend, "tdbsam");
5281         string_set(&Globals.szLdapSuffix, "");
5282         string_set(&Globals.szLdapMachineSuffix, "");
5283         string_set(&Globals.szLdapUserSuffix, "");
5284         string_set(&Globals.szLdapGroupSuffix, "");
5285         string_set(&Globals.szLdapIdmapSuffix, "");
5286
5287         string_set(&Globals.szLdapAdminDn, "");
5288         Globals.ldap_ssl = LDAP_SSL_START_TLS;
5289         Globals.ldap_ssl_ads = False;
5290         Globals.ldap_deref = -1;
5291         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5292         Globals.ldap_delete_dn = False;
5293         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5294         Globals.ldap_follow_referral = Auto;
5295         Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5296         Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5297         Globals.ldap_page_size = LDAP_PAGE_SIZE;
5298
5299         Globals.ldap_debug_level = 0;
5300         Globals.ldap_debug_threshold = 10;
5301
5302         /* This is what we tell the afs client. in reality we set the token 
5303          * to never expire, though, when this runs out the afs client will 
5304          * forget the token. Set to 0 to get NEVERDATE.*/
5305         Globals.iAfsTokenLifetime = 604800;
5306         Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5307
5308 /* these parameters are set to defaults that are more appropriate
5309    for the increasing samba install base:
5310
5311    as a member of the workgroup, that will possibly become a
5312    _local_ master browser (lm = True).  this is opposed to a forced
5313    local master browser startup (pm = True).
5314
5315    doesn't provide WINS server service by default (wsupp = False),
5316    and doesn't provide domain master browser services by default, either.
5317
5318 */
5319
5320         Globals.bMsAddPrinterWizard = True;
5321         Globals.os_level = 20;
5322         Globals.bLocalMaster = True;
5323         Globals.iDomainMaster = Auto;   /* depending on bDomainLogons */
5324         Globals.bDomainLogons = False;
5325         Globals.bBrowseList = True;
5326         Globals.bWINSsupport = False;
5327         Globals.bWINSproxy = False;
5328
5329         TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5330         Globals.InitLogonDelay = 100; /* 100 ms default delay */
5331
5332         Globals.bDNSproxy = True;
5333
5334         /* this just means to use them if they exist */
5335         Globals.bKernelOplocks = True;
5336
5337         Globals.bAllowTrustedDomains = True;
5338         string_set(&Globals.szIdmapBackend, "tdb");
5339         Globals.bIdmapReadOnly = false;
5340
5341         string_set(&Globals.szTemplateShell, "/bin/false");
5342         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5343         string_set(&Globals.szWinbindSeparator, "\\");
5344
5345         string_set(&Globals.szCupsServer, "");
5346         string_set(&Globals.szIPrintServer, "");
5347
5348         string_set(&Globals.ctdbdSocket, "");
5349         Globals.szClusterAddresses = NULL;
5350         Globals.clustering = False;
5351         Globals.ctdb_timeout = 0;
5352         Globals.ctdb_locktime_warn_threshold = 0;
5353
5354         Globals.winbind_cache_time = 300;       /* 5 minutes */
5355         Globals.winbind_reconnect_delay = 30;   /* 30 seconds */
5356         Globals.winbind_max_clients = 200;
5357         Globals.bWinbindEnumUsers = False;
5358         Globals.bWinbindEnumGroups = False;
5359         Globals.bWinbindUseDefaultDomain = False;
5360         Globals.bWinbindTrustedDomainsOnly = False;
5361         Globals.bWinbindNestedGroups = True;
5362         Globals.winbind_expand_groups = 1;
5363         Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
5364         Globals.bWinbindRefreshTickets = False;
5365         Globals.bWinbindOfflineLogon = False;
5366
5367         Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5368         Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5369
5370         Globals.bPassdbExpandExplicit = False;
5371
5372         Globals.name_cache_timeout = 660; /* In seconds */
5373
5374         Globals.bUseSpnego = True;
5375         Globals.bClientUseSpnego = True;
5376
5377         Globals.client_signing = Auto;
5378         Globals.server_signing = False;
5379
5380         Globals.bDeferSharingViolations = True;
5381         string_set(&Globals.smb_ports, SMB_PORTS);
5382
5383         Globals.bEnablePrivileges = True;
5384         Globals.bHostMSDfs        = True;
5385         Globals.bASUSupport       = False;
5386
5387         /* User defined shares. */
5388         if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5389                 smb_panic("init_globals: ENOMEM");
5390         }
5391         string_set(&Globals.szUsersharePath, s);
5392         SAFE_FREE(s);
5393         string_set(&Globals.szUsershareTemplateShare, "");
5394         Globals.iUsershareMaxShares = 0;
5395         /* By default disallow sharing of directories not owned by the sharer. */
5396         Globals.bUsershareOwnerOnly = True;
5397         /* By default disallow guest access to usershares. */
5398         Globals.bUsershareAllowGuests = False;
5399
5400         Globals.iKeepalive = DEFAULT_KEEPALIVE;
5401
5402         /* By default no shares out of the registry */
5403         Globals.bRegistryShares = False;
5404
5405         Globals.iminreceivefile = 0;
5406
5407         Globals.bMapUntrustedToDomain = false;
5408         Globals.bMulticastDnsRegister = true;
5409
5410         Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
5411         Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
5412         Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
5413         Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5414
5415         string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5416
5417         /* Now put back the settings that were set with lp_set_cmdline() */
5418         apply_lp_set_cmdline();
5419 }
5420
5421 /*******************************************************************
5422  Convenience routine to grab string parameters into temporary memory
5423  and run standard_sub_basic on them. The buffers can be written to by
5424  callers without affecting the source string.
5425 ********************************************************************/
5426
5427 static char *lp_string(const char *s)
5428 {
5429         char *ret;
5430         TALLOC_CTX *ctx = talloc_tos();
5431
5432         /* The follow debug is useful for tracking down memory problems
5433            especially if you have an inner loop that is calling a lp_*()
5434            function that returns a string.  Perhaps this debug should be
5435            present all the time? */
5436
5437 #if 0
5438         DEBUG(10, ("lp_string(%s)\n", s));
5439 #endif
5440         if (!s) {
5441                 return NULL;
5442         }
5443
5444         ret = talloc_sub_basic(ctx,
5445                         get_current_username(),
5446                         current_user_info.domain,
5447                         s);
5448         if (trim_char(ret, '\"', '\"')) {
5449                 if (strchr(ret,'\"') != NULL) {
5450                         TALLOC_FREE(ret);
5451                         ret = talloc_sub_basic(ctx,
5452                                         get_current_username(),
5453                                         current_user_info.domain,
5454                                         s);
5455                 }
5456         }
5457         return ret;
5458 }
5459
5460 /*
5461    In this section all the functions that are used to access the
5462    parameters from the rest of the program are defined
5463 */
5464
5465 #define FN_GLOBAL_STRING(fn_name,ptr) \
5466  char *fn_name(void) {return(lp_string(*(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5467 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5468  const char *fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5469 #define FN_GLOBAL_LIST(fn_name,ptr) \
5470  const char **fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5471 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5472  bool fn_name(void) {return(*(bool *)(&Globals.ptr));}
5473 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5474  char fn_name(void) {return(*(char *)(&Globals.ptr));}
5475 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5476  int fn_name(void) {return(*(int *)(&Globals.ptr));}
5477
5478 #define FN_LOCAL_STRING(fn_name,val) \
5479  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5480 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5481  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5482 #define FN_LOCAL_LIST(fn_name,val) \
5483  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5484 #define FN_LOCAL_BOOL(fn_name,val) \
5485  bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5486 #define FN_LOCAL_INTEGER(fn_name,val) \
5487  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5488
5489 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5490  bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5491 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5492  int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5493 #define FN_LOCAL_CHAR(fn_name,val) \
5494  char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5495
5496 FN_GLOBAL_CONST_STRING(lp_smb_ports, smb_ports)
5497 FN_GLOBAL_CONST_STRING(lp_dos_charset, dos_charset)
5498 FN_GLOBAL_CONST_STRING(lp_unix_charset, unix_charset)
5499 FN_GLOBAL_STRING(lp_logfile, szLogFile)
5500 FN_GLOBAL_STRING(lp_configfile, szConfigFile)
5501 FN_GLOBAL_CONST_STRING(lp_smb_passwd_file, szSMBPasswdFile)
5502 FN_GLOBAL_CONST_STRING(lp_private_dir, szPrivateDir)
5503 FN_GLOBAL_STRING(lp_serverstring, szServerString)
5504 FN_GLOBAL_INTEGER(lp_printcap_cache_time, PrintcapCacheTime)
5505 FN_GLOBAL_STRING(lp_addport_cmd, szAddPortCommand)
5506 FN_GLOBAL_STRING(lp_enumports_cmd, szEnumPortsCommand)
5507 FN_GLOBAL_STRING(lp_addprinter_cmd, szAddPrinterCommand)
5508 FN_GLOBAL_STRING(lp_deleteprinter_cmd, szDeletePrinterCommand)
5509 FN_GLOBAL_STRING(lp_os2_driver_map, szOs2DriverMap)
5510 FN_GLOBAL_CONST_STRING(lp_lockdir, szLockDir)
5511 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5512  * build process or in smb.conf, we use that value.  Otherwise they
5513  * default to the value of lp_lockdir(). */
5514 const char *lp_statedir(void) {
5515         if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5516             (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5517                 return(*(char **)(&Globals.szStateDir) ?
5518                        *(char **)(&Globals.szStateDir) : "");
5519         else
5520                 return(*(char **)(&Globals.szLockDir) ?
5521                        *(char **)(&Globals.szLockDir) : "");
5522 }
5523 const char *lp_cachedir(void) {
5524         if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5525             (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5526                 return(*(char **)(&Globals.szCacheDir) ?
5527                        *(char **)(&Globals.szCacheDir) : "");
5528         else
5529                 return(*(char **)(&Globals.szLockDir) ?
5530                        *(char **)(&Globals.szLockDir) : "");
5531 }
5532 FN_GLOBAL_CONST_STRING(lp_piddir, szPidDir)
5533 FN_GLOBAL_STRING(lp_mangling_method, szManglingMethod)
5534 FN_GLOBAL_INTEGER(lp_mangle_prefix, mangle_prefix)
5535 FN_GLOBAL_CONST_STRING(lp_utmpdir, szUtmpDir)
5536 FN_GLOBAL_CONST_STRING(lp_wtmpdir, szWtmpDir)
5537 FN_GLOBAL_BOOL(lp_utmp, bUtmp)
5538 FN_GLOBAL_STRING(lp_rootdir, szRootdir)
5539 FN_GLOBAL_STRING(lp_perfcount_module, szSMBPerfcountModule)
5540 FN_GLOBAL_STRING(lp_defaultservice, szDefaultService)
5541 FN_GLOBAL_STRING(lp_msg_command, szMsgCommand)
5542 FN_GLOBAL_STRING(lp_get_quota_command, szGetQuota)
5543 FN_GLOBAL_STRING(lp_set_quota_command, szSetQuota)
5544 FN_GLOBAL_STRING(lp_auto_services, szAutoServices)
5545 FN_GLOBAL_STRING(lp_passwd_program, szPasswdProgram)
5546 FN_GLOBAL_STRING(lp_passwd_chat, szPasswdChat)
5547 FN_GLOBAL_CONST_STRING(lp_passwordserver, szPasswordServer)
5548 FN_GLOBAL_CONST_STRING(lp_name_resolve_order, szNameResolveOrder)
5549 FN_GLOBAL_CONST_STRING(lp_workgroup, szWorkgroup)
5550 FN_GLOBAL_CONST_STRING(lp_netbios_name, szNetbiosName)
5551 FN_GLOBAL_CONST_STRING(lp_netbios_scope, szNetbiosScope)
5552 FN_GLOBAL_CONST_STRING(lp_realm, szRealmUpper)
5553 FN_GLOBAL_CONST_STRING(lp_dnsdomain, szDnsDomain)
5554 FN_GLOBAL_CONST_STRING(lp_afs_username_map, szAfsUsernameMap)
5555 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, iAfsTokenLifetime)
5556 FN_GLOBAL_STRING(lp_log_nt_token_command, szLogNtTokenCommand)
5557 FN_GLOBAL_STRING(lp_username_map, szUsernameMap)
5558 FN_GLOBAL_CONST_STRING(lp_logon_script, szLogonScript)
5559 FN_GLOBAL_CONST_STRING(lp_logon_path, szLogonPath)
5560 FN_GLOBAL_CONST_STRING(lp_logon_drive, szLogonDrive)
5561 FN_GLOBAL_CONST_STRING(lp_logon_home, szLogonHome)
5562 FN_GLOBAL_STRING(lp_remote_announce, szRemoteAnnounce)
5563 FN_GLOBAL_STRING(lp_remote_browse_sync, szRemoteBrowseSync)
5564 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, bNmbdBindExplicitBroadcast)
5565 FN_GLOBAL_LIST(lp_wins_server_list, szWINSservers)
5566 FN_GLOBAL_LIST(lp_interfaces, szInterfaces)
5567 FN_GLOBAL_STRING(lp_nis_home_map_name, szNISHomeMapName)
5568 FN_GLOBAL_LIST(lp_netbios_aliases, szNetbiosAliases)
5569 FN_GLOBAL_CONST_STRING(lp_passdb_backend, szPassdbBackend)
5570 FN_GLOBAL_LIST(lp_preload_modules, szPreloadModules)
5571 FN_GLOBAL_STRING(lp_panic_action, szPanicAction)
5572 FN_GLOBAL_STRING(lp_adduser_script, szAddUserScript)
5573 FN_GLOBAL_STRING(lp_renameuser_script, szRenameUserScript)
5574 FN_GLOBAL_STRING(lp_deluser_script, szDelUserScript)
5575
5576 FN_GLOBAL_CONST_STRING(lp_guestaccount, szGuestaccount)
5577 FN_GLOBAL_STRING(lp_addgroup_script, szAddGroupScript)
5578 FN_GLOBAL_STRING(lp_delgroup_script, szDelGroupScript)
5579 FN_GLOBAL_STRING(lp_addusertogroup_script, szAddUserToGroupScript)
5580 FN_GLOBAL_STRING(lp_deluserfromgroup_script, szDelUserFromGroupScript)
5581 FN_GLOBAL_STRING(lp_setprimarygroup_script, szSetPrimaryGroupScript)
5582
5583 FN_GLOBAL_STRING(lp_addmachine_script, szAddMachineScript)
5584
5585 FN_GLOBAL_STRING(lp_shutdown_script, szShutdownScript)
5586 FN_GLOBAL_STRING(lp_abort_shutdown_script, szAbortShutdownScript)
5587 FN_GLOBAL_STRING(lp_username_map_script, szUsernameMapScript)
5588 FN_GLOBAL_INTEGER(lp_username_map_cache_time, iUsernameMapCacheTime)
5589
5590 FN_GLOBAL_STRING(lp_check_password_script, szCheckPasswordScript)
5591
5592 FN_GLOBAL_STRING(lp_wins_hook, szWINSHook)
5593 FN_GLOBAL_CONST_STRING(lp_template_homedir, szTemplateHomedir)
5594 FN_GLOBAL_CONST_STRING(lp_template_shell, szTemplateShell)
5595 FN_GLOBAL_CONST_STRING(lp_winbind_separator, szWinbindSeparator)
5596 FN_GLOBAL_INTEGER(lp_acl_compatibility, iAclCompat)
5597 FN_GLOBAL_BOOL(lp_winbind_enum_users, bWinbindEnumUsers)
5598 FN_GLOBAL_BOOL(lp_winbind_enum_groups, bWinbindEnumGroups)
5599 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, bWinbindUseDefaultDomain)
5600 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, bWinbindTrustedDomainsOnly)
5601 FN_GLOBAL_BOOL(lp_winbind_nested_groups, bWinbindNestedGroups)
5602 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, winbind_expand_groups)
5603 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, bWinbindRefreshTickets)
5604 FN_GLOBAL_BOOL(lp_winbind_offline_logon, bWinbindOfflineLogon)
5605 FN_GLOBAL_BOOL(lp_winbind_normalize_names, bWinbindNormalizeNames)
5606 FN_GLOBAL_BOOL(lp_winbind_rpc_only, bWinbindRpcOnly)
5607 FN_GLOBAL_BOOL(lp_create_krb5_conf, bCreateKrb5Conf)
5608 static FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections_int,
5609                   winbindMaxDomainConnections)
5610
5611 int lp_winbind_max_domain_connections(void)
5612 {
5613         if (lp_winbind_offline_logon() &&
5614             lp_winbind_max_domain_connections_int() > 1) {
5615                 DEBUG(1, ("offline logons active, restricting max domain "
5616                           "connections to 1\n"));
5617                 return 1;
5618         }
5619         return MAX(1, lp_winbind_max_domain_connections_int());
5620 }
5621
5622 FN_GLOBAL_CONST_STRING(lp_idmap_backend, szIdmapBackend)
5623 FN_GLOBAL_INTEGER(lp_idmap_cache_time, iIdmapCacheTime)
5624 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, iIdmapNegativeCacheTime)
5625 FN_GLOBAL_INTEGER(lp_keepalive, iKeepalive)
5626 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, bPassdbExpandExplicit)
5627
5628 FN_GLOBAL_STRING(lp_ldap_suffix, szLdapSuffix)
5629 FN_GLOBAL_STRING(lp_ldap_admin_dn, szLdapAdminDn)
5630 FN_GLOBAL_INTEGER(lp_ldap_ssl, ldap_ssl)
5631 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, ldap_ssl_ads)
5632 FN_GLOBAL_INTEGER(lp_ldap_deref, ldap_deref)
5633 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, ldap_follow_referral)
5634 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, ldap_passwd_sync)
5635 FN_GLOBAL_BOOL(lp_ldap_delete_dn, ldap_delete_dn)
5636 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, ldap_replication_sleep)
5637 FN_GLOBAL_INTEGER(lp_ldap_timeout, ldap_timeout)
5638 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, ldap_connection_timeout)
5639 FN_GLOBAL_INTEGER(lp_ldap_page_size, ldap_page_size)
5640 FN_GLOBAL_INTEGER(lp_ldap_debug_level, ldap_debug_level)
5641 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, ldap_debug_threshold)
5642 FN_GLOBAL_STRING(lp_add_share_cmd, szAddShareCommand)
5643 FN_GLOBAL_STRING(lp_change_share_cmd, szChangeShareCommand)
5644 FN_GLOBAL_STRING(lp_delete_share_cmd, szDeleteShareCommand)
5645 FN_GLOBAL_STRING(lp_usershare_path, szUsersharePath)
5646 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, szUsersharePrefixAllowList)
5647 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, szUsersharePrefixDenyList)
5648
5649 FN_GLOBAL_LIST(lp_eventlog_list, szEventLogs)
5650
5651 FN_GLOBAL_BOOL(lp_registry_shares, bRegistryShares)
5652 FN_GLOBAL_BOOL(lp_usershare_allow_guests, bUsershareAllowGuests)
5653 FN_GLOBAL_BOOL(lp_usershare_owner_only, bUsershareOwnerOnly)
5654 FN_GLOBAL_BOOL(lp_disable_netbios, bDisableNetbios)
5655 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, bResetOnZeroVC)
5656 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5657                bLogWriteableFilesOnExit)
5658 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, bMsAddPrinterWizard)
5659 FN_GLOBAL_BOOL(lp_dns_proxy, bDNSproxy)
5660 FN_GLOBAL_BOOL(lp_wins_support, bWINSsupport)
5661 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, bWINSsupport)
5662 FN_GLOBAL_BOOL(lp_wins_proxy, bWINSproxy)
5663 FN_GLOBAL_BOOL(lp_local_master, bLocalMaster)
5664 FN_GLOBAL_BOOL(lp_domain_logons, bDomainLogons)
5665 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, szInitLogonDelayedHosts)
5666 FN_GLOBAL_INTEGER(lp_init_logon_delay, InitLogonDelay)
5667 FN_GLOBAL_BOOL(lp_load_printers, bLoadPrinters)
5668 FN_GLOBAL_BOOL(_lp_readraw, bReadRaw)
5669 FN_GLOBAL_BOOL(lp_large_readwrite, bLargeReadwrite)
5670 FN_GLOBAL_BOOL(_lp_writeraw, bWriteRaw)
5671 FN_GLOBAL_BOOL(lp_null_passwords, bNullPasswords)
5672 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, bObeyPamRestrictions)
5673 FN_GLOBAL_BOOL(lp_encrypted_passwords, bEncryptPasswords)
5674 FN_GLOBAL_INTEGER(lp_client_schannel, clientSchannel)
5675 FN_GLOBAL_INTEGER(lp_server_schannel, serverSchannel)
5676 FN_GLOBAL_BOOL(lp_syslog_only, bSyslogOnly)
5677 FN_GLOBAL_BOOL(lp_timestamp_logs, bTimestampLogs)
5678 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, bDebugPrefixTimestamp)
5679 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, bDebugHiresTimestamp)
5680 FN_GLOBAL_BOOL(lp_debug_pid, bDebugPid)
5681 FN_GLOBAL_BOOL(lp_debug_uid, bDebugUid)
5682 FN_GLOBAL_BOOL(lp_debug_class, bDebugClass)
5683 FN_GLOBAL_BOOL(lp_enable_core_files, bEnableCoreFiles)
5684 FN_GLOBAL_BOOL(lp_browse_list, bBrowseList)
5685 FN_GLOBAL_BOOL(lp_nis_home_map, bNISHomeMap)
5686 static FN_GLOBAL_BOOL(lp_time_server, bTimeServer)
5687 FN_GLOBAL_BOOL(lp_bind_interfaces_only, bBindInterfacesOnly)
5688 FN_GLOBAL_BOOL(lp_pam_password_change, bPamPasswordChange)
5689 FN_GLOBAL_BOOL(lp_unix_password_sync, bUnixPasswdSync)
5690 FN_GLOBAL_BOOL(lp_passwd_chat_debug, bPasswdChatDebug)
5691 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, iPasswdChatTimeout)
5692 FN_GLOBAL_BOOL(lp_nt_pipe_support, bNTPipeSupport)
5693 FN_GLOBAL_BOOL(lp_nt_status_support, bNTStatusSupport)
5694 FN_GLOBAL_BOOL(lp_stat_cache, bStatCache)
5695 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, iMaxStatCacheSize)
5696 FN_GLOBAL_BOOL(lp_allow_trusted_domains, bAllowTrustedDomains)
5697 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, bMapUntrustedToDomain)
5698 FN_GLOBAL_INTEGER(lp_restrict_anonymous, restrict_anonymous)
5699 FN_GLOBAL_BOOL(lp_lanman_auth, bLanmanAuth)
5700 FN_GLOBAL_BOOL(lp_ntlm_auth, bNTLMAuth)
5701 FN_GLOBAL_BOOL(lp_client_plaintext_auth, bClientPlaintextAuth)
5702 FN_GLOBAL_BOOL(lp_client_lanman_auth, bClientLanManAuth)
5703 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, bClientNTLMv2Auth)
5704 FN_GLOBAL_BOOL(lp_host_msdfs, bHostMSDfs)
5705 FN_GLOBAL_BOOL(lp_kernel_oplocks, bKernelOplocks)
5706 FN_GLOBAL_BOOL(lp_enhanced_browsing, enhanced_browsing)
5707 FN_GLOBAL_BOOL(lp_use_mmap, bUseMmap)
5708 FN_GLOBAL_BOOL(lp_unix_extensions, bUnixExtensions)
5709 FN_GLOBAL_BOOL(lp_use_spnego, bUseSpnego)
5710 FN_GLOBAL_BOOL(lp_client_use_spnego, bClientUseSpnego)
5711 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, client_use_spnego_principal)
5712 FN_GLOBAL_BOOL(lp_send_spnego_principal, send_spnego_principal)
5713 FN_GLOBAL_BOOL(lp_hostname_lookups, bHostnameLookups)
5714 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5715 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5716 FN_GLOBAL_CONST_STRING(lp_dedicated_keytab_file, szDedicatedKeytabFile)
5717 FN_GLOBAL_INTEGER(lp_kerberos_method, iKerberosMethod)
5718 FN_GLOBAL_BOOL(lp_defer_sharing_violations, bDeferSharingViolations)
5719 FN_GLOBAL_BOOL(lp_enable_privileges, bEnablePrivileges)
5720 FN_GLOBAL_BOOL(lp_enable_asu_support, bASUSupport)
5721 FN_GLOBAL_INTEGER(lp_os_level, os_level)
5722 FN_GLOBAL_INTEGER(lp_max_ttl, max_ttl)
5723 FN_GLOBAL_INTEGER(lp_max_wins_ttl, max_wins_ttl)
5724 FN_GLOBAL_INTEGER(lp_min_wins_ttl, min_wins_ttl)
5725 FN_GLOBAL_INTEGER(lp_max_log_size, max_log_size)
5726 FN_GLOBAL_INTEGER(lp_max_open_files, max_open_files)
5727 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, open_files_db_hash_size)
5728 FN_GLOBAL_INTEGER(lp_maxxmit, max_xmit)
5729 FN_GLOBAL_INTEGER(lp_maxmux, max_mux)
5730 FN_GLOBAL_INTEGER(lp_passwordlevel, pwordlevel)
5731 FN_GLOBAL_INTEGER(lp_usernamelevel, unamelevel)
5732 FN_GLOBAL_INTEGER(lp_deadtime, deadtime)
5733 FN_GLOBAL_BOOL(lp_getwd_cache, getwd_cache)
5734 static FN_GLOBAL_INTEGER(_lp_maxprotocol, maxprotocol)
5735 int lp_maxprotocol(void)
5736 {
5737         int ret = _lp_maxprotocol();
5738         if ((ret == PROTOCOL_SMB2) && (lp_security() == SEC_SHARE)) {
5739                 DEBUG(2,("WARNING!!: \"security = share\" is incompatible "
5740                         "with the SMB2 protocol. Resetting to SMB1.\n" ));
5741                         lp_do_parameter(-1, "max protocol", "NT1");
5742                 return PROTOCOL_NT1;
5743         }
5744         return ret;
5745 }
5746 FN_GLOBAL_INTEGER(lp_minprotocol, minprotocol)
5747 FN_GLOBAL_INTEGER(lp_security, security)
5748 FN_GLOBAL_LIST(lp_auth_methods, AuthMethods)
5749 FN_GLOBAL_BOOL(lp_paranoid_server_security, paranoid_server_security)
5750 FN_GLOBAL_INTEGER(lp_maxdisksize, maxdisksize)
5751 FN_GLOBAL_INTEGER(lp_lpqcachetime, lpqcachetime)
5752 FN_GLOBAL_INTEGER(lp_max_smbd_processes, iMaxSmbdProcesses)
5753 FN_GLOBAL_BOOL(_lp_disable_spoolss, bDisableSpoolss)
5754 FN_GLOBAL_INTEGER(lp_syslog, syslog)
5755 FN_GLOBAL_INTEGER(lp_lm_announce, lm_announce)
5756 FN_GLOBAL_INTEGER(lp_lm_interval, lm_interval)
5757 FN_GLOBAL_INTEGER(lp_machine_password_timeout, machine_password_timeout)
5758 FN_GLOBAL_INTEGER(lp_map_to_guest, map_to_guest)
5759 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, oplock_break_wait_time)
5760 FN_GLOBAL_INTEGER(lp_lock_spin_time, iLockSpinTime)
5761 FN_GLOBAL_INTEGER(lp_usershare_max_shares, iUsershareMaxShares)
5762 FN_GLOBAL_CONST_STRING(lp_socket_options, szSocketOptions)
5763 FN_GLOBAL_INTEGER(lp_config_backend, ConfigBackend)
5764 FN_GLOBAL_INTEGER(lp_smb2_max_read, ismb2_max_read)
5765 FN_GLOBAL_INTEGER(lp_smb2_max_write, ismb2_max_write)
5766 FN_GLOBAL_INTEGER(lp_smb2_max_trans, ismb2_max_trans)
5767 int lp_smb2_max_credits(void)
5768 {
5769         if (Globals.ismb2_max_credits == 0) {
5770                 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5771         }
5772         return Globals.ismb2_max_credits;
5773 }
5774 FN_LOCAL_STRING(lp_preexec, szPreExec)
5775 FN_LOCAL_STRING(lp_postexec, szPostExec)
5776 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5777 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5778 FN_LOCAL_STRING(lp_servicename, szService)
5779 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5780 FN_LOCAL_STRING(lp_pathname, szPath)
5781 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5782 FN_LOCAL_STRING(lp_username, szUsername)
5783 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5784 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5785 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5786 FN_GLOBAL_LIST(lp_svcctl_list, szServicesList)
5787 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5788 FN_GLOBAL_STRING(lp_cups_server, szCupsServer)
5789 int lp_cups_encrypt(void)
5790 {
5791         int result = 0;
5792 #ifdef HAVE_HTTPCONNECTENCRYPT
5793         switch (Globals.CupsEncrypt) {
5794                 case Auto:
5795                         result = HTTP_ENCRYPT_REQUIRED;
5796                         break;
5797                 case True:
5798                         result = HTTP_ENCRYPT_ALWAYS;
5799                         break;
5800                 case False:
5801                         result = HTTP_ENCRYPT_NEVER;
5802                         break;
5803         }
5804 #endif
5805         return result;
5806 }
5807 FN_GLOBAL_STRING(lp_iprint_server, szIPrintServer)
5808 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, cups_connection_timeout)
5809 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, ctdbdSocket)
5810 FN_GLOBAL_LIST(lp_cluster_addresses, szClusterAddresses)
5811 FN_GLOBAL_BOOL(lp_clustering, clustering)
5812 FN_GLOBAL_INTEGER(lp_ctdb_timeout, ctdb_timeout)
5813 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, ctdb_locktime_warn_threshold)
5814 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5815 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5816 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5817 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5818 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5819 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5820 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5821 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5822 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5823 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5824 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5825 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5826 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5827 FN_LOCAL_STRING(lp_comment, comment)
5828 FN_LOCAL_STRING(lp_force_user, force_user)
5829 FN_LOCAL_STRING(lp_force_group, force_group)
5830 FN_LOCAL_LIST(lp_readlist, readlist)
5831 FN_LOCAL_LIST(lp_writelist, writelist)
5832 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5833 FN_LOCAL_STRING(lp_fstype, fstype)
5834 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5835 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5836 static FN_LOCAL_STRING(lp_volume, volume)
5837 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5838 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5839 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5840 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5841 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5842 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5843 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5844 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5845 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5846 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5847 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5848 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5849 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5850 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5851 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5852 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5853 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5854 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5855 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5856 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5857 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5858 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5859 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5860 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5861 FN_LOCAL_BOOL(lp_print_notify_backchannel, bPrintNotifyBackchannel)
5862 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5863 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5864 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5865 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5866 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5867 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5868 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5869 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5870 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5871 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5872 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5873 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5874 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5875 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5876 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5877 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5878 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5879 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5880 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5881 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5882 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5883 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5884 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5885 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5886 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, bAsyncSMBEchoHandler)
5887 FN_GLOBAL_BOOL(lp_multicast_dns_register, bMulticastDnsRegister)
5888 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5889 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5890 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5891 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5892 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5893 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5894 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5895 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5896 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5897 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5898 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5899 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5900 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5901 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5902 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5903 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5904 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5905 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5906 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5907 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5908 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5909 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5910 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5911 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5912 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5913 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5914 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5915 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5916 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5917 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5918 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5919 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5920 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5921 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5922 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5923 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5924 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5925 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5926 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5927 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5928 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5929 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5930 FN_GLOBAL_INTEGER(lp_winbind_cache_time, winbind_cache_time)
5931 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, winbind_reconnect_delay)
5932 FN_GLOBAL_INTEGER(lp_winbind_max_clients, winbind_max_clients)
5933 FN_GLOBAL_LIST(lp_winbind_nss_info, szWinbindNssInfo)
5934 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, AlgorithmicRidBase)
5935 FN_GLOBAL_INTEGER(lp_name_cache_timeout, name_cache_timeout)
5936 FN_GLOBAL_INTEGER(lp_client_signing, client_signing)
5937 FN_GLOBAL_INTEGER(lp_server_signing, server_signing)
5938 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, client_ldap_sasl_wrapping)
5939
5940 FN_GLOBAL_CONST_STRING(lp_ncalrpc_dir, ncalrpc_dir)
5941
5942 /* local prototypes */
5943
5944 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5945 static const char *get_boolean(bool bool_value);
5946 static int getservicebyname(const char *pszServiceName,
5947                             struct loadparm_service *pserviceDest);
5948 static void copy_service(struct loadparm_service *pserviceDest,
5949                          struct loadparm_service *pserviceSource,
5950                          struct bitmap *pcopymapDest);
5951 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5952                          void *userdata);
5953 static bool do_section(const char *pszSectionName, void *userdata);
5954 static void init_copymap(struct loadparm_service *pservice);
5955 static bool hash_a_service(const char *name, int number);
5956 static void free_service_byindex(int iService);
5957 static void free_param_opts(struct param_opt_struct **popts);
5958 static void show_parameter(int parmIndex);
5959 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5960
5961 /*
5962  * This is a helper function for parametrical options support.  It returns a
5963  * pointer to parametrical option value if it exists or NULL otherwise. Actual
5964  * parametrical functions are quite simple
5965  */
5966 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5967                                                 const char *option)
5968 {
5969         bool global_section = False;
5970         char* param_key;
5971         struct param_opt_struct *data;
5972
5973         if (snum >= iNumServices) return NULL;
5974
5975         if (snum < 0) { 
5976                 data = Globals.param_opt;
5977                 global_section = True;
5978         } else {
5979                 data = ServicePtrs[snum]->param_opt;
5980         }
5981
5982         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5983                 DEBUG(0,("asprintf failed!\n"));
5984                 return NULL;
5985         }
5986
5987         while (data) {
5988                 if (strwicmp(data->key, param_key) == 0) {
5989                         string_free(&param_key);
5990                         return data;
5991                 }
5992                 data = data->next;
5993         }
5994
5995         if (!global_section) {
5996                 /* Try to fetch the same option but from globals */
5997                 /* but only if we are not already working with Globals */
5998                 data = Globals.param_opt;
5999                 while (data) {
6000                         if (strwicmp(data->key, param_key) == 0) {
6001                                 string_free(&param_key);
6002                                 return data;
6003                         }
6004                         data = data->next;
6005                 }
6006         }
6007
6008         string_free(&param_key);
6009
6010         return NULL;
6011 }
6012
6013
6014 #define MISSING_PARAMETER(name) \
6015     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
6016
6017 /*******************************************************************
6018 convenience routine to return int parameters.
6019 ********************************************************************/
6020 static int lp_int(const char *s)
6021 {
6022
6023         if (!s || !*s) {
6024                 MISSING_PARAMETER(lp_int);
6025                 return (-1);
6026         }
6027
6028         return (int)strtol(s, NULL, 0);
6029 }
6030
6031 /*******************************************************************
6032 convenience routine to return unsigned long parameters.
6033 ********************************************************************/
6034 static unsigned long lp_ulong(const char *s)
6035 {
6036
6037         if (!s || !*s) {
6038                 MISSING_PARAMETER(lp_ulong);
6039                 return (0);
6040         }
6041
6042         return strtoul(s, NULL, 0);
6043 }
6044
6045 /*******************************************************************
6046 convenience routine to return boolean parameters.
6047 ********************************************************************/
6048 static bool lp_bool(const char *s)
6049 {
6050         bool ret = False;
6051
6052         if (!s || !*s) {
6053                 MISSING_PARAMETER(lp_bool);
6054                 return False;
6055         }
6056
6057         if (!set_boolean(s, &ret)) {
6058                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
6059                 return False;
6060         }
6061
6062         return ret;
6063 }
6064
6065 /*******************************************************************
6066 convenience routine to return enum parameters.
6067 ********************************************************************/
6068 static int lp_enum(const char *s,const struct enum_list *_enum)
6069 {
6070         int i;
6071
6072         if (!s || !*s || !_enum) {
6073                 MISSING_PARAMETER(lp_enum);
6074                 return (-1);
6075         }
6076
6077         for (i=0; _enum[i].name; i++) {
6078                 if (strequal(_enum[i].name,s))
6079                         return _enum[i].value;
6080         }
6081
6082         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
6083         return (-1);
6084 }
6085
6086 #undef MISSING_PARAMETER
6087
6088 /* Return parametric option from a given service. Type is a part of option before ':' */
6089 /* Parametric option has following syntax: 'Type: option = value' */
6090 /* the returned value is talloced on the talloc_tos() */
6091 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
6092 {
6093         struct param_opt_struct *data = get_parametrics(snum, type, option);
6094
6095         if (data == NULL||data->value==NULL) {
6096                 if (def) {
6097                         return lp_string(def);
6098                 } else {
6099                         return NULL;
6100                 }
6101         }
6102
6103         return lp_string(data->value);
6104 }
6105
6106 /* Return parametric option from a given service. Type is a part of option before ':' */
6107 /* Parametric option has following syntax: 'Type: option = value' */
6108 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6109 {
6110         struct param_opt_struct *data = get_parametrics(snum, type, option);
6111
6112         if (data == NULL||data->value==NULL)
6113                 return def;
6114
6115         return data->value;
6116 }
6117
6118 /* Return parametric option from a given service. Type is a part of option before ':' */
6119 /* Parametric option has following syntax: 'Type: option = value' */
6120
6121 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6122 {
6123         struct param_opt_struct *data = get_parametrics(snum, type, option);
6124
6125         if (data == NULL||data->value==NULL)
6126                 return (const char **)def;
6127
6128         if (data->list==NULL) {
6129                 data->list = str_list_make_v3(NULL, data->value, NULL);
6130         }
6131
6132         return (const char **)data->list;
6133 }
6134
6135 /* Return parametric option from a given service. Type is a part of option before ':' */
6136 /* Parametric option has following syntax: 'Type: option = value' */
6137
6138 int lp_parm_int(int snum, const char *type, const char *option, int def)
6139 {
6140         struct param_opt_struct *data = get_parametrics(snum, type, option);
6141
6142         if (data && data->value && *data->value)
6143                 return lp_int(data->value);
6144
6145         return def;
6146 }
6147
6148 /* Return parametric option from a given service. Type is a part of option before ':' */
6149 /* Parametric option has following syntax: 'Type: option = value' */
6150
6151 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6152 {
6153         struct param_opt_struct *data = get_parametrics(snum, type, option);
6154
6155         if (data && data->value && *data->value)
6156                 return lp_ulong(data->value);
6157
6158         return def;
6159 }
6160
6161 /* Return parametric option from a given service. Type is a part of option before ':' */
6162 /* Parametric option has following syntax: 'Type: option = value' */
6163
6164 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6165 {
6166         struct param_opt_struct *data = get_parametrics(snum, type, option);
6167
6168         if (data && data->value && *data->value)
6169                 return lp_bool(data->value);
6170
6171         return def;
6172 }
6173
6174 /* Return parametric option from a given service. Type is a part of option before ':' */
6175 /* Parametric option has following syntax: 'Type: option = value' */
6176
6177 int lp_parm_enum(int snum, const char *type, const char *option,
6178                  const struct enum_list *_enum, int def)
6179 {
6180         struct param_opt_struct *data = get_parametrics(snum, type, option);
6181
6182         if (data && data->value && *data->value && _enum)
6183                 return lp_enum(data->value, _enum);
6184
6185         return def;
6186 }
6187
6188
6189 /***************************************************************************
6190  Initialise a service to the defaults.
6191 ***************************************************************************/
6192
6193 static void init_service(struct loadparm_service *pservice)
6194 {
6195         memset((char *)pservice, '\0', sizeof(struct loadparm_service));
6196         copy_service(pservice, &sDefault, NULL);
6197 }
6198
6199
6200 /**
6201  * free a param_opts structure.
6202  * param_opts handling should be moved to talloc;
6203  * then this whole functions reduces to a TALLOC_FREE().
6204  */
6205
6206 static void free_param_opts(struct param_opt_struct **popts)
6207 {
6208         struct param_opt_struct *opt, *next_opt;
6209
6210         if (popts == NULL) {
6211                 return;
6212         }
6213
6214         if (*popts != NULL) {
6215                 DEBUG(5, ("Freeing parametrics:\n"));
6216         }
6217         opt = *popts;
6218         while (opt != NULL) {
6219                 string_free(&opt->key);
6220                 string_free(&opt->value);
6221                 TALLOC_FREE(opt->list);
6222                 next_opt = opt->next;
6223                 SAFE_FREE(opt);
6224                 opt = next_opt;
6225         }
6226         *popts = NULL;
6227 }
6228
6229 /***************************************************************************
6230  Free the dynamically allocated parts of a service struct.
6231 ***************************************************************************/
6232
6233 static void free_service(struct loadparm_service *pservice)
6234 {
6235         if (!pservice)
6236                 return;
6237
6238         if (pservice->szService)
6239                 DEBUG(5, ("free_service: Freeing service %s\n",
6240                        pservice->szService));
6241
6242         free_parameters(pservice);
6243
6244         string_free(&pservice->szService);
6245         TALLOC_FREE(pservice->copymap);
6246
6247         free_param_opts(&pservice->param_opt);
6248
6249         ZERO_STRUCTP(pservice);
6250 }
6251
6252
6253 /***************************************************************************
6254  remove a service indexed in the ServicePtrs array from the ServiceHash
6255  and free the dynamically allocated parts
6256 ***************************************************************************/
6257
6258 static void free_service_byindex(int idx)
6259 {
6260         if ( !LP_SNUM_OK(idx) ) 
6261                 return;
6262
6263         ServicePtrs[idx]->valid = False;
6264         invalid_services[num_invalid_services++] = idx;
6265
6266         /* we have to cleanup the hash record */
6267
6268         if (ServicePtrs[idx]->szService) {
6269                 char *canon_name = canonicalize_servicename(
6270                         talloc_tos(),
6271                         ServicePtrs[idx]->szService );
6272
6273                 dbwrap_delete_bystring(ServiceHash, canon_name );
6274                 TALLOC_FREE(canon_name);
6275         }
6276
6277         free_service(ServicePtrs[idx]);
6278 }
6279
6280 /***************************************************************************
6281  Add a new service to the services array initialising it with the given 
6282  service. 
6283 ***************************************************************************/
6284
6285 static int add_a_service(const struct loadparm_service *pservice, const char *name)
6286 {
6287         int i;
6288         struct loadparm_service tservice;
6289         int num_to_alloc = iNumServices + 1;
6290
6291         tservice = *pservice;
6292
6293         /* it might already exist */
6294         if (name) {
6295                 i = getservicebyname(name, NULL);
6296                 if (i >= 0) {
6297                         return (i);
6298                 }
6299         }
6300
6301         /* find an invalid one */
6302         i = iNumServices;
6303         if (num_invalid_services > 0) {
6304                 i = invalid_services[--num_invalid_services];
6305         }
6306
6307         /* if not, then create one */
6308         if (i == iNumServices) {
6309                 struct loadparm_service **tsp;
6310                 int *tinvalid;
6311
6312                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
6313                 if (tsp == NULL) {
6314                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6315                         return (-1);
6316                 }
6317                 ServicePtrs = tsp;
6318                 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct loadparm_service);
6319                 if (!ServicePtrs[iNumServices]) {
6320                         DEBUG(0,("add_a_service: out of memory!\n"));
6321                         return (-1);
6322                 }
6323                 iNumServices++;
6324
6325                 /* enlarge invalid_services here for now... */
6326                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6327                                              num_to_alloc);
6328                 if (tinvalid == NULL) {
6329                         DEBUG(0,("add_a_service: failed to enlarge "
6330                                  "invalid_services!\n"));
6331                         return (-1);
6332                 }
6333                 invalid_services = tinvalid;
6334         } else {
6335                 free_service_byindex(i);
6336         }
6337
6338         ServicePtrs[i]->valid = True;
6339
6340         init_service(ServicePtrs[i]);
6341         copy_service(ServicePtrs[i], &tservice, NULL);
6342         if (name)
6343                 string_set(&ServicePtrs[i]->szService, name);
6344
6345         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
6346                 i, ServicePtrs[i]->szService));
6347
6348         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6349                 return (-1);
6350         }
6351
6352         return (i);
6353 }
6354
6355 /***************************************************************************
6356   Convert a string to uppercase and remove whitespaces.
6357 ***************************************************************************/
6358
6359 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6360 {
6361         char *result;
6362
6363         if ( !src ) {
6364                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6365                 return NULL;
6366         }
6367
6368         result = talloc_strdup(ctx, src);
6369         SMB_ASSERT(result != NULL);
6370
6371         strlower_m(result);
6372         return result;
6373 }
6374
6375 /***************************************************************************
6376   Add a name/index pair for the services array to the hash table.
6377 ***************************************************************************/
6378
6379 static bool hash_a_service(const char *name, int idx)
6380 {
6381         char *canon_name;
6382
6383         if ( !ServiceHash ) {
6384                 DEBUG(10,("hash_a_service: creating servicehash\n"));
6385                 ServiceHash = db_open_rbt(NULL);
6386                 if ( !ServiceHash ) {
6387                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6388                         return False;
6389                 }
6390         }
6391
6392         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6393                 idx, name));
6394
6395         canon_name = canonicalize_servicename(talloc_tos(), name );
6396
6397         dbwrap_store_bystring(ServiceHash, canon_name,
6398                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
6399                               TDB_REPLACE);
6400
6401         TALLOC_FREE(canon_name);
6402
6403         return True;
6404 }
6405
6406 /***************************************************************************
6407  Add a new home service, with the specified home directory, defaults coming
6408  from service ifrom.
6409 ***************************************************************************/
6410
6411 bool lp_add_home(const char *pszHomename, int iDefaultService,
6412                  const char *user, const char *pszHomedir)
6413 {
6414         int i;
6415
6416         if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6417                         pszHomedir[0] == '\0') {
6418                 return false;
6419         }
6420
6421         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6422
6423         if (i < 0)
6424                 return (False);
6425
6426         if (!(*(ServicePtrs[iDefaultService]->szPath))
6427             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6428                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6429         }
6430
6431         if (!(*(ServicePtrs[i]->comment))) {
6432                 char *comment = NULL;
6433                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6434                         return false;
6435                 }
6436                 string_set(&ServicePtrs[i]->comment, comment);
6437                 SAFE_FREE(comment);
6438         }
6439
6440         /* set the browseable flag from the global default */
6441
6442         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6443         ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6444
6445         ServicePtrs[i]->autoloaded = True;
6446
6447         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
6448                user, ServicePtrs[i]->szPath ));
6449
6450         return (True);
6451 }
6452
6453 /***************************************************************************
6454  Add a new service, based on an old one.
6455 ***************************************************************************/
6456
6457 int lp_add_service(const char *pszService, int iDefaultService)
6458 {
6459         if (iDefaultService < 0) {
6460                 return add_a_service(&sDefault, pszService);
6461         }
6462
6463         return (add_a_service(ServicePtrs[iDefaultService], pszService));
6464 }
6465
6466 /***************************************************************************
6467  Add the IPC service.
6468 ***************************************************************************/
6469
6470 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6471 {
6472         char *comment = NULL;
6473         int i = add_a_service(&sDefault, ipc_name);
6474
6475         if (i < 0)
6476                 return (False);
6477
6478         if (asprintf(&comment, "IPC Service (%s)",
6479                                 Globals.szServerString) < 0) {
6480                 return (False);
6481         }
6482
6483         string_set(&ServicePtrs[i]->szPath, tmpdir());
6484         string_set(&ServicePtrs[i]->szUsername, "");
6485         string_set(&ServicePtrs[i]->comment, comment);
6486         string_set(&ServicePtrs[i]->fstype, "IPC");
6487         ServicePtrs[i]->iMaxConnections = 0;
6488         ServicePtrs[i]->bAvailable = True;
6489         ServicePtrs[i]->bRead_only = True;
6490         ServicePtrs[i]->bGuest_only = False;
6491         ServicePtrs[i]->bAdministrative_share = True;
6492         ServicePtrs[i]->bGuest_ok = guest_ok;
6493         ServicePtrs[i]->bPrint_ok = False;
6494         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6495
6496         DEBUG(3, ("adding IPC service\n"));
6497
6498         SAFE_FREE(comment);
6499         return (True);
6500 }
6501
6502 /***************************************************************************
6503  Add a new printer service, with defaults coming from service iFrom.
6504 ***************************************************************************/
6505
6506 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6507 {
6508         const char *comment = "From Printcap";
6509         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6510
6511         if (i < 0)
6512                 return (False);
6513
6514         /* note that we do NOT default the availability flag to True - */
6515         /* we take it from the default service passed. This allows all */
6516         /* dynamic printers to be disabled by disabling the [printers] */
6517         /* entry (if/when the 'available' keyword is implemented!).    */
6518
6519         /* the printer name is set to the service name. */
6520         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6521         string_set(&ServicePtrs[i]->comment, comment);
6522
6523         /* set the browseable flag from the gloabl default */
6524         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6525
6526         /* Printers cannot be read_only. */
6527         ServicePtrs[i]->bRead_only = False;
6528         /* No share modes on printer services. */
6529         ServicePtrs[i]->bShareModes = False;
6530         /* No oplocks on printer services. */
6531         ServicePtrs[i]->bOpLocks = False;
6532         /* Printer services must be printable. */
6533         ServicePtrs[i]->bPrint_ok = True;
6534
6535         DEBUG(3, ("adding printer service %s\n", pszPrintername));
6536
6537         return (True);
6538 }
6539
6540
6541 /***************************************************************************
6542  Check whether the given parameter name is valid.
6543  Parametric options (names containing a colon) are considered valid.
6544 ***************************************************************************/
6545
6546 bool lp_parameter_is_valid(const char *pszParmName)
6547 {
6548         return ((map_parameter(pszParmName) != -1) ||
6549                 (strchr(pszParmName, ':') != NULL));
6550 }
6551
6552 /***************************************************************************
6553  Check whether the given name is the name of a global parameter.
6554  Returns True for strings belonging to parameters of class
6555  P_GLOBAL, False for all other strings, also for parametric options
6556  and strings not belonging to any option.
6557 ***************************************************************************/
6558
6559 bool lp_parameter_is_global(const char *pszParmName)
6560 {
6561         int num = map_parameter(pszParmName);
6562
6563         if (num >= 0) {
6564                 return (parm_table[num].p_class == P_GLOBAL);
6565         }
6566
6567         return False;
6568 }
6569
6570 /**************************************************************************
6571  Check whether the given name is the canonical name of a parameter.
6572  Returns False if it is not a valid parameter Name.
6573  For parametric options, True is returned.
6574 **************************************************************************/
6575
6576 bool lp_parameter_is_canonical(const char *parm_name)
6577 {
6578         if (!lp_parameter_is_valid(parm_name)) {
6579                 return False;
6580         }
6581
6582         return (map_parameter(parm_name) ==
6583                 map_parameter_canonical(parm_name, NULL));
6584 }
6585
6586 /**************************************************************************
6587  Determine the canonical name for a parameter.
6588  Indicate when it is an inverse (boolean) synonym instead of a
6589  "usual" synonym.
6590 **************************************************************************/
6591
6592 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6593                                bool *inverse)
6594 {
6595         int num;
6596
6597         if (!lp_parameter_is_valid(parm_name)) {
6598                 *canon_parm = NULL;
6599                 return False;
6600         }
6601
6602         num = map_parameter_canonical(parm_name, inverse);
6603         if (num < 0) {
6604                 /* parametric option */
6605                 *canon_parm = parm_name;
6606         } else {
6607                 *canon_parm = parm_table[num].label;
6608         }
6609
6610         return True;
6611
6612 }
6613
6614 /**************************************************************************
6615  Determine the canonical name for a parameter.
6616  Turn the value given into the inverse boolean expression when
6617  the synonym is an invers boolean synonym.
6618
6619  Return True if parm_name is a valid parameter name and
6620  in case it is an invers boolean synonym, if the val string could
6621  successfully be converted to the reverse bool.
6622  Return false in all other cases.
6623 **************************************************************************/
6624
6625 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6626                                           const char *val,
6627                                           const char **canon_parm,
6628                                           const char **canon_val)
6629 {
6630         int num;
6631         bool inverse;
6632
6633         if (!lp_parameter_is_valid(parm_name)) {
6634                 *canon_parm = NULL;
6635                 *canon_val = NULL;
6636                 return False;
6637         }
6638
6639         num = map_parameter_canonical(parm_name, &inverse);
6640         if (num < 0) {
6641                 /* parametric option */
6642                 *canon_parm = parm_name;
6643                 *canon_val = val;
6644         } else {
6645                 *canon_parm = parm_table[num].label;
6646                 if (inverse) {
6647                         if (!lp_invert_boolean(val, canon_val)) {
6648                                 *canon_val = NULL;
6649                                 return False;
6650                         }
6651                 } else {
6652                         *canon_val = val;
6653                 }
6654         }
6655
6656         return True;
6657 }
6658
6659 /***************************************************************************
6660  Map a parameter's string representation to something we can use. 
6661  Returns False if the parameter string is not recognised, else TRUE.
6662 ***************************************************************************/
6663
6664 static int map_parameter(const char *pszParmName)
6665 {
6666         int iIndex;
6667
6668         if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6669                 return (-1);
6670
6671         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6672                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6673                         return (iIndex);
6674
6675         /* Warn only if it isn't parametric option */
6676         if (strchr(pszParmName, ':') == NULL)
6677                 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6678         /* We do return 'fail' for parametric options as well because they are
6679            stored in different storage
6680          */
6681         return (-1);
6682 }
6683
6684 /***************************************************************************
6685  Map a parameter's string representation to the index of the canonical
6686  form of the parameter (it might be a synonym).
6687  Returns -1 if the parameter string is not recognised.
6688 ***************************************************************************/
6689
6690 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6691 {
6692         int parm_num, canon_num;
6693         bool loc_inverse = False;
6694
6695         parm_num = map_parameter(pszParmName);
6696         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6697                 /* invalid, parametric or no canidate for synonyms ... */
6698                 goto done;
6699         }
6700
6701         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6702                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6703                         parm_num = canon_num;
6704                         goto done;
6705                 }
6706         }
6707
6708 done:
6709         if (inverse != NULL) {
6710                 *inverse = loc_inverse;
6711         }
6712         return parm_num;
6713 }
6714
6715 /***************************************************************************
6716  return true if parameter number parm1 is a synonym of parameter
6717  number parm2 (parm2 being the principal name).
6718  set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6719  False otherwise.
6720 ***************************************************************************/
6721
6722 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6723 {
6724         if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6725             (parm_table[parm1].flags & FLAG_HIDE) &&
6726             !(parm_table[parm2].flags & FLAG_HIDE))
6727         {
6728                 if (inverse != NULL) {
6729                         if ((parm_table[parm1].type == P_BOOLREV) &&
6730                             (parm_table[parm2].type == P_BOOL))
6731                         {
6732                                 *inverse = True;
6733                         } else {
6734                                 *inverse = False;
6735                         }
6736                 }
6737                 return True;
6738         }
6739         return False;
6740 }
6741
6742 /***************************************************************************
6743  Show one parameter's name, type, [values,] and flags.
6744  (helper functions for show_parameter_list)
6745 ***************************************************************************/
6746
6747 static void show_parameter(int parmIndex)
6748 {
6749         int enumIndex, flagIndex;
6750         int parmIndex2;
6751         bool hadFlag;
6752         bool hadSyn;
6753         bool inverse;
6754         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6755                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6756                 "P_ENUM", "P_SEP"};
6757         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6758                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6759                 FLAG_HIDE, FLAG_DOS_STRING};
6760         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6761                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6762                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6763
6764         printf("%s=%s", parm_table[parmIndex].label,
6765                type[parm_table[parmIndex].type]);
6766         if (parm_table[parmIndex].type == P_ENUM) {
6767                 printf(",");
6768                 for (enumIndex=0;
6769                      parm_table[parmIndex].enum_list[enumIndex].name;
6770                      enumIndex++)
6771                 {
6772                         printf("%s%s",
6773                                enumIndex ? "|" : "",
6774                                parm_table[parmIndex].enum_list[enumIndex].name);
6775                 }
6776         }
6777         printf(",");
6778         hadFlag = False;
6779         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6780                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6781                         printf("%s%s",
6782                                 hadFlag ? "|" : "",
6783                                 flag_names[flagIndex]);
6784                         hadFlag = True;
6785                 }
6786         }
6787
6788         /* output synonyms */
6789         hadSyn = False;
6790         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6791                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6792                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6793                                parm_table[parmIndex2].label);
6794                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6795                         if (!hadSyn) {
6796                                 printf(" (synonyms: ");
6797                                 hadSyn = True;
6798                         } else {
6799                                 printf(", ");
6800                         }
6801                         printf("%s%s", parm_table[parmIndex2].label,
6802                                inverse ? "[i]" : "");
6803                 }
6804         }
6805         if (hadSyn) {
6806                 printf(")");
6807         }
6808
6809         printf("\n");
6810 }
6811
6812 /***************************************************************************
6813  Show all parameter's name, type, [values,] and flags.
6814 ***************************************************************************/
6815
6816 void show_parameter_list(void)
6817 {
6818         int classIndex, parmIndex;
6819         const char *section_names[] = { "local", "global", NULL};
6820
6821         for (classIndex=0; section_names[classIndex]; classIndex++) {
6822                 printf("[%s]\n", section_names[classIndex]);
6823                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6824                         if (parm_table[parmIndex].p_class == classIndex) {
6825                                 show_parameter(parmIndex);
6826                         }
6827                 }
6828         }
6829 }
6830
6831 /***************************************************************************
6832  Check if a given string correctly represents a boolean value.
6833 ***************************************************************************/
6834
6835 bool lp_string_is_valid_boolean(const char *parm_value)
6836 {
6837         return set_boolean(parm_value, NULL);
6838 }
6839
6840 /***************************************************************************
6841  Get the standard string representation of a boolean value ("yes" or "no")
6842 ***************************************************************************/
6843
6844 static const char *get_boolean(bool bool_value)
6845 {
6846         static const char *yes_str = "yes";
6847         static const char *no_str = "no";
6848
6849         return (bool_value ? yes_str : no_str);
6850 }
6851
6852 /***************************************************************************
6853  Provide the string of the negated boolean value associated to the boolean
6854  given as a string. Returns False if the passed string does not correctly
6855  represent a boolean.
6856 ***************************************************************************/
6857
6858 bool lp_invert_boolean(const char *str, const char **inverse_str)
6859 {
6860         bool val;
6861
6862         if (!set_boolean(str, &val)) {
6863                 return False;
6864         }
6865
6866         *inverse_str = get_boolean(!val);
6867         return True;
6868 }
6869
6870 /***************************************************************************
6871  Provide the canonical string representation of a boolean value given
6872  as a string. Return True on success, False if the string given does
6873  not correctly represent a boolean.
6874 ***************************************************************************/
6875
6876 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6877 {
6878         bool val;
6879
6880         if (!set_boolean(str, &val)) {
6881                 return False;
6882         }
6883
6884         *canon_str = get_boolean(val);
6885         return True;
6886 }
6887
6888 /***************************************************************************
6889 Find a service by name. Otherwise works like get_service.
6890 ***************************************************************************/
6891
6892 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
6893 {
6894         int iService = -1;
6895         char *canon_name;
6896         TDB_DATA data;
6897
6898         if (ServiceHash == NULL) {
6899                 return -1;
6900         }
6901
6902         canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6903
6904         data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6905
6906         if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6907                 iService = *(int *)data.dptr;
6908         }
6909
6910         TALLOC_FREE(canon_name);
6911
6912         if ((iService != -1) && (LP_SNUM_OK(iService))
6913             && (pserviceDest != NULL)) {
6914                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6915         }
6916
6917         return (iService);
6918 }
6919
6920 /***************************************************************************
6921  Copy a service structure to another.
6922  If pcopymapDest is NULL then copy all fields
6923 ***************************************************************************/
6924
6925 /**
6926  * Add a parametric option to a param_opt_struct,
6927  * replacing old value, if already present.
6928  */
6929 static void set_param_opt(struct param_opt_struct **opt_list,
6930                           const char *opt_name,
6931                           const char *opt_value,
6932                           unsigned flags)
6933 {
6934         struct param_opt_struct *new_opt, *opt;
6935         bool not_added;
6936
6937         if (opt_list == NULL) {
6938                 return;
6939         }
6940
6941         opt = *opt_list;
6942         not_added = true;
6943
6944         /* Traverse destination */
6945         while (opt) {
6946                 /* If we already have same option, override it */
6947                 if (strwicmp(opt->key, opt_name) == 0) {
6948                         if ((opt->flags & FLAG_CMDLINE) &&
6949                             !(flags & FLAG_CMDLINE)) {
6950                                 /* it's been marked as not to be
6951                                    overridden */
6952                                 return;
6953                         }
6954                         string_free(&opt->value);
6955                         TALLOC_FREE(opt->list);
6956                         opt->value = SMB_STRDUP(opt_value);
6957                         opt->flags = flags;
6958                         not_added = false;
6959                         break;
6960                 }
6961                 opt = opt->next;
6962         }
6963         if (not_added) {
6964             new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6965             new_opt->key = SMB_STRDUP(opt_name);
6966             new_opt->value = SMB_STRDUP(opt_value);
6967             new_opt->list = NULL;
6968             new_opt->flags = flags;
6969             DLIST_ADD(*opt_list, new_opt);
6970         }
6971 }
6972
6973 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
6974                          struct bitmap *pcopymapDest)
6975 {
6976         int i;
6977         bool bcopyall = (pcopymapDest == NULL);
6978         struct param_opt_struct *data;
6979
6980         for (i = 0; parm_table[i].label; i++)
6981                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6982                     (bcopyall || bitmap_query(pcopymapDest,i))) {
6983                         void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
6984                         void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
6985
6986                         switch (parm_table[i].type) {
6987                                 case P_BOOL:
6988                                 case P_BOOLREV:
6989                                         *(bool *)dest_ptr = *(bool *)src_ptr;
6990                                         break;
6991
6992                                 case P_INTEGER:
6993                                 case P_ENUM:
6994                                 case P_OCTAL:
6995                                         *(int *)dest_ptr = *(int *)src_ptr;
6996                                         break;
6997
6998                                 case P_CHAR:
6999                                         *(char *)dest_ptr = *(char *)src_ptr;
7000                                         break;
7001
7002                                 case P_STRING:
7003                                         string_set((char **)dest_ptr,
7004                                                    *(char **)src_ptr);
7005                                         break;
7006
7007                                 case P_USTRING:
7008                                 {
7009                                         char *upper_string = strupper_talloc(talloc_tos(), 
7010                                                                              *(char **)src_ptr);
7011                                         string_set((char **)dest_ptr,
7012                                                    upper_string);
7013                                         TALLOC_FREE(upper_string);
7014                                         break;
7015                                 }
7016                                 case P_LIST:
7017                                         TALLOC_FREE(*((char ***)dest_ptr));
7018                                         *((char ***)dest_ptr) = str_list_copy(NULL, 
7019                                                       *(const char ***)src_ptr);
7020                                         break;
7021                                 default:
7022                                         break;
7023                         }
7024                 }
7025
7026         if (bcopyall) {
7027                 init_copymap(pserviceDest);
7028                 if (pserviceSource->copymap)
7029                         bitmap_copy(pserviceDest->copymap,
7030                                     pserviceSource->copymap);
7031         }
7032
7033         data = pserviceSource->param_opt;
7034         while (data) {
7035                 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->flags);
7036                 data = data->next;
7037         }
7038 }
7039
7040 /***************************************************************************
7041 Check a service for consistency. Return False if the service is in any way
7042 incomplete or faulty, else True.
7043 ***************************************************************************/
7044
7045 bool service_ok(int iService)
7046 {
7047         bool bRetval;
7048
7049         bRetval = True;
7050         if (ServicePtrs[iService]->szService[0] == '\0') {
7051                 DEBUG(0, ("The following message indicates an internal error:\n"));
7052                 DEBUG(0, ("No service name in service entry.\n"));
7053                 bRetval = False;
7054         }
7055
7056         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
7057         /* I can't see why you'd want a non-printable printer service...        */
7058         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
7059                 if (!ServicePtrs[iService]->bPrint_ok) {
7060                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
7061                                ServicePtrs[iService]->szService));
7062                         ServicePtrs[iService]->bPrint_ok = True;
7063                 }
7064                 /* [printers] service must also be non-browsable. */
7065                 if (ServicePtrs[iService]->bBrowseable)
7066                         ServicePtrs[iService]->bBrowseable = False;
7067         }
7068
7069         if (ServicePtrs[iService]->szPath[0] == '\0' &&
7070             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
7071             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
7072             ) {
7073                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
7074                         ServicePtrs[iService]->szService));
7075                 ServicePtrs[iService]->bAvailable = False;
7076         }
7077
7078         /* If a service is flagged unavailable, log the fact at level 1. */
7079         if (!ServicePtrs[iService]->bAvailable)
7080                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
7081                           ServicePtrs[iService]->szService));
7082
7083         return (bRetval);
7084 }
7085
7086 static struct smbconf_ctx *lp_smbconf_ctx(void)
7087 {
7088         sbcErr err;
7089         static struct smbconf_ctx *conf_ctx = NULL;
7090
7091         if (conf_ctx == NULL) {
7092                 err = smbconf_init(NULL, &conf_ctx, "registry:");
7093                 if (!SBC_ERROR_IS_OK(err)) {
7094                         DEBUG(1, ("error initializing registry configuration: "
7095                                   "%s\n", sbcErrorString(err)));
7096                         conf_ctx = NULL;
7097                 }
7098         }
7099
7100         return conf_ctx;
7101 }
7102
7103 static bool process_smbconf_service(struct smbconf_service *service)
7104 {
7105         uint32_t count;
7106         bool ret;
7107
7108         if (service == NULL) {
7109                 return false;
7110         }
7111
7112         ret = do_section(service->name, NULL);
7113         if (ret != true) {
7114                 return false;
7115         }
7116         for (count = 0; count < service->num_params; count++) {
7117                 ret = do_parameter(service->param_names[count],
7118                                    service->param_values[count],
7119                                    NULL);
7120                 if (ret != true) {
7121                         return false;
7122                 }
7123         }
7124         if (iServiceIndex >= 0) {
7125                 return service_ok(iServiceIndex);
7126         }
7127         return true;
7128 }
7129
7130 /**
7131  * load a service from registry and activate it
7132  */
7133 bool process_registry_service(const char *service_name)
7134 {
7135         sbcErr err;
7136         struct smbconf_service *service = NULL;
7137         TALLOC_CTX *mem_ctx = talloc_stackframe();
7138         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7139         bool ret = false;
7140
7141         if (conf_ctx == NULL) {
7142                 goto done;
7143         }
7144
7145         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7146
7147         if (!smbconf_share_exists(conf_ctx, service_name)) {
7148                 /*
7149                  * Registry does not contain data for this service (yet),
7150                  * but make sure lp_load doesn't return false.
7151                  */
7152                 ret = true;
7153                 goto done;
7154         }
7155
7156         err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7157         if (!SBC_ERROR_IS_OK(err)) {
7158                 goto done;
7159         }
7160
7161         ret = process_smbconf_service(service);
7162         if (!ret) {
7163                 goto done;
7164         }
7165
7166         /* store the csn */
7167         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7168
7169 done:
7170         TALLOC_FREE(mem_ctx);
7171         return ret;
7172 }
7173
7174 /*
7175  * process_registry_globals
7176  */
7177 static bool process_registry_globals(void)
7178 {
7179         bool ret;
7180
7181         add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7182
7183         ret = do_parameter("registry shares", "yes", NULL);
7184         if (!ret) {
7185                 return ret;
7186         }
7187
7188         return process_registry_service(GLOBAL_NAME);
7189 }
7190
7191 bool process_registry_shares(void)
7192 {
7193         sbcErr err;
7194         uint32_t count;
7195         struct smbconf_service **service = NULL;
7196         uint32_t num_shares = 0;
7197         TALLOC_CTX *mem_ctx = talloc_stackframe();
7198         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7199         bool ret = false;
7200
7201         if (conf_ctx == NULL) {
7202                 goto done;
7203         }
7204
7205         err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7206         if (!SBC_ERROR_IS_OK(err)) {
7207                 goto done;
7208         }
7209
7210         ret = true;
7211
7212         for (count = 0; count < num_shares; count++) {
7213                 if (strequal(service[count]->name, GLOBAL_NAME)) {
7214                         continue;
7215                 }
7216                 ret = process_smbconf_service(service[count]);
7217                 if (!ret) {
7218                         goto done;
7219                 }
7220         }
7221
7222         /* store the csn */
7223         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7224
7225 done:
7226         TALLOC_FREE(mem_ctx);
7227         return ret;
7228 }
7229
7230 #define MAX_INCLUDE_DEPTH 100
7231
7232 static uint8_t include_depth;
7233
7234 static struct file_lists {
7235         struct file_lists *next;
7236         char *name;
7237         char *subfname;
7238         time_t modtime;
7239 } *file_lists = NULL;
7240
7241 /*******************************************************************
7242  Keep a linked list of all config files so we know when one has changed 
7243  it's date and needs to be reloaded.
7244 ********************************************************************/
7245
7246 static void add_to_file_list(const char *fname, const char *subfname)
7247 {
7248         struct file_lists *f = file_lists;
7249
7250         while (f) {
7251                 if (f->name && !strcmp(f->name, fname))
7252                         break;
7253                 f = f->next;
7254         }
7255
7256         if (!f) {
7257                 f = SMB_MALLOC_P(struct file_lists);
7258                 if (!f)
7259                         return;
7260                 f->next = file_lists;
7261                 f->name = SMB_STRDUP(fname);
7262                 if (!f->name) {
7263                         SAFE_FREE(f);
7264                         return;
7265                 }
7266                 f->subfname = SMB_STRDUP(subfname);
7267                 if (!f->subfname) {
7268                         SAFE_FREE(f->name);
7269                         SAFE_FREE(f);
7270                         return;
7271                 }
7272                 file_lists = f;
7273                 f->modtime = file_modtime(subfname);
7274         } else {
7275                 time_t t = file_modtime(subfname);
7276                 if (t)
7277                         f->modtime = t;
7278         }
7279         return;
7280 }
7281
7282 /**
7283  * Free the file lists
7284  */
7285 static void free_file_list(void)
7286 {
7287         struct file_lists *f;
7288         struct file_lists *next;
7289
7290         f = file_lists;
7291         while( f ) {
7292                 next = f->next;
7293                 SAFE_FREE( f->name );
7294                 SAFE_FREE( f->subfname );
7295                 SAFE_FREE( f );
7296                 f = next;
7297         }
7298         file_lists = NULL;
7299 }
7300
7301
7302 /**
7303  * Utility function for outsiders to check if we're running on registry.
7304  */
7305 bool lp_config_backend_is_registry(void)
7306 {
7307         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7308 }
7309
7310 /**
7311  * Utility function to check if the config backend is FILE.
7312  */
7313 bool lp_config_backend_is_file(void)
7314 {
7315         return (lp_config_backend() == CONFIG_BACKEND_FILE);
7316 }
7317
7318 /*******************************************************************
7319  Check if a config file has changed date.
7320 ********************************************************************/
7321
7322 bool lp_file_list_changed(void)
7323 {
7324         struct file_lists *f = file_lists;
7325
7326         DEBUG(6, ("lp_file_list_changed()\n"));
7327
7328         while (f) {
7329                 time_t mod_time;
7330
7331                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7332                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7333
7334                         if (conf_ctx == NULL) {
7335                                 return false;
7336                         }
7337                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7338                                             NULL))
7339                         {
7340                                 DEBUGADD(6, ("registry config changed\n"));
7341                                 return true;
7342                         }
7343                 } else {
7344                         char *n2 = NULL;
7345                         n2 = talloc_sub_basic(talloc_tos(),
7346                                               get_current_username(),
7347                                               current_user_info.domain,
7348                                               f->name);
7349                         if (!n2) {
7350                                 return false;
7351                         }
7352                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
7353                                      f->name, n2, ctime(&f->modtime)));
7354
7355                         mod_time = file_modtime(n2);
7356
7357                         if (mod_time &&
7358                             ((f->modtime != mod_time) ||
7359                              (f->subfname == NULL) ||
7360                              (strcmp(n2, f->subfname) != 0)))
7361                         {
7362                                 DEBUGADD(6,
7363                                          ("file %s modified: %s\n", n2,
7364                                           ctime(&mod_time)));
7365                                 f->modtime = mod_time;
7366                                 SAFE_FREE(f->subfname);
7367                                 f->subfname = SMB_STRDUP(n2);
7368                                 TALLOC_FREE(n2);
7369                                 return true;
7370                         }
7371                         TALLOC_FREE(n2);
7372                 }
7373                 f = f->next;
7374         }
7375         return (False);
7376 }
7377
7378
7379 /**
7380  * Initialize iconv conversion descriptors.
7381  *
7382  * This is called the first time it is needed, and also called again
7383  * every time the configuration is reloaded, because the charset or
7384  * codepage might have changed.
7385  **/
7386 static void init_iconv(void)
7387 {
7388         global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
7389                                                       lp_unix_charset(),
7390                                                       true, global_iconv_handle);
7391 }
7392
7393 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7394 {
7395         if (strcmp(*ptr, pszParmValue) != 0) {
7396                 string_set(ptr, pszParmValue);
7397                 init_iconv();
7398         }
7399         return True;
7400 }
7401
7402 static bool handle_dos_charset(int snum, const char *pszParmValue, char **ptr)
7403 {
7404         bool is_utf8 = false;
7405         size_t len = strlen(pszParmValue);
7406
7407         if (len == 4 || len == 5) {
7408                 /* Don't use StrCaseCmp here as we don't want to
7409                    initialize iconv. */
7410                 if ((toupper_ascii(pszParmValue[0]) == 'U') &&
7411                     (toupper_ascii(pszParmValue[1]) == 'T') &&
7412                     (toupper_ascii(pszParmValue[2]) == 'F')) {
7413                         if (len == 4) {
7414                                 if (pszParmValue[3] == '8') {
7415                                         is_utf8 = true;
7416                                 }
7417                         } else {
7418                                 if (pszParmValue[3] == '-' &&
7419                                     pszParmValue[4] == '8') {
7420                                         is_utf8 = true;
7421                                 }
7422                         }
7423                 }
7424         }
7425
7426         if (strcmp(*ptr, pszParmValue) != 0) {
7427                 if (is_utf8) {
7428                         DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
7429                                 "be UTF8, using (default value) %s instead.\n",
7430                                 DEFAULT_DOS_CHARSET));
7431                         pszParmValue = DEFAULT_DOS_CHARSET;
7432                 }
7433                 string_set(ptr, pszParmValue);
7434                 init_iconv();
7435         }
7436         return true;
7437 }
7438
7439 static bool handle_realm(int snum, const char *pszParmValue, char **ptr)
7440 {
7441         bool ret = true;
7442         char *realm = strupper_talloc(talloc_tos(), pszParmValue);
7443         char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
7444
7445         ret &= string_set(&Globals.szRealm, pszParmValue);
7446         ret &= string_set(&Globals.szRealmUpper, realm);
7447         ret &= string_set(&Globals.szDnsDomain, dnsdomain);
7448         TALLOC_FREE(realm);
7449         TALLOC_FREE(dnsdomain);
7450
7451         return ret;
7452 }
7453
7454 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7455 {
7456         TALLOC_FREE(Globals.szNetbiosAliases);
7457         Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
7458         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7459 }
7460
7461 /***************************************************************************
7462  Handle the include operation.
7463 ***************************************************************************/
7464 static bool bAllowIncludeRegistry = true;
7465
7466 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7467 {
7468         char *fname;
7469
7470         if (include_depth >= MAX_INCLUDE_DEPTH) {
7471                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7472                           include_depth));
7473                 return false;
7474         }
7475
7476         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7477                 if (!bAllowIncludeRegistry) {
7478                         return true;
7479                 }
7480                 if (bInGlobalSection) {
7481                         bool ret;
7482                         include_depth++;
7483                         ret = process_registry_globals();
7484                         include_depth--;
7485                         return ret;
7486                 } else {
7487                         DEBUG(1, ("\"include = registry\" only effective "
7488                                   "in %s section\n", GLOBAL_NAME));
7489                         return false;
7490                 }
7491         }
7492
7493         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7494                                  current_user_info.domain,
7495                                  pszParmValue);
7496
7497         add_to_file_list(pszParmValue, fname);
7498
7499         string_set(ptr, fname);
7500
7501         if (file_exist(fname)) {
7502                 bool ret;
7503                 include_depth++;
7504                 ret = pm_process(fname, do_section, do_parameter, NULL);
7505                 include_depth--;
7506                 TALLOC_FREE(fname);
7507                 return ret;
7508         }
7509
7510         DEBUG(2, ("Can't find include file %s\n", fname));
7511         TALLOC_FREE(fname);
7512         return true;
7513 }
7514
7515 /***************************************************************************
7516  Handle the interpretation of the copy parameter.
7517 ***************************************************************************/
7518
7519 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7520 {
7521         bool bRetval;
7522         int iTemp;
7523         struct loadparm_service serviceTemp;
7524
7525         string_set(ptr, pszParmValue);
7526
7527         init_service(&serviceTemp);
7528
7529         bRetval = False;
7530
7531         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7532
7533         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7534                 if (iTemp == iServiceIndex) {
7535                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7536                 } else {
7537                         copy_service(ServicePtrs[iServiceIndex],
7538                                      &serviceTemp,
7539                                      ServicePtrs[iServiceIndex]->copymap);
7540                         bRetval = True;
7541                 }
7542         } else {
7543                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7544                 bRetval = False;
7545         }
7546
7547         free_service(&serviceTemp);
7548         return (bRetval);
7549 }
7550
7551 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7552 {
7553         Globals.ldap_debug_level = lp_int(pszParmValue);
7554         init_ldap_debugging();
7555         return true;
7556 }
7557
7558 /***************************************************************************
7559  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
7560  parameters is:
7561
7562  [global]
7563
7564         idmap uid = 1000-1999
7565         idmap gid = 700-899
7566
7567  We only do simple parsing checks here.  The strings are parsed into useful
7568  structures in the idmap daemon code.
7569
7570 ***************************************************************************/
7571
7572 /* Some lp_ routines to return idmap [ug]id information */
7573
7574 static uid_t idmap_uid_low, idmap_uid_high;
7575 static gid_t idmap_gid_low, idmap_gid_high;
7576
7577 bool lp_idmap_uid(uid_t *low, uid_t *high)
7578 {
7579         if (idmap_uid_low == 0 || idmap_uid_high == 0)
7580                 return False;
7581
7582         if (low)
7583                 *low = idmap_uid_low;
7584
7585         if (high)
7586                 *high = idmap_uid_high;
7587
7588         return True;
7589 }
7590
7591 bool lp_idmap_gid(gid_t *low, gid_t *high)
7592 {
7593         if (idmap_gid_low == 0 || idmap_gid_high == 0)
7594                 return False;
7595
7596         if (low)
7597                 *low = idmap_gid_low;
7598
7599         if (high)
7600                 *high = idmap_gid_high;
7601
7602         return True;
7603 }
7604
7605 static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr)
7606 {
7607         lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7608
7609         return true;
7610 }
7611
7612 /* Do some simple checks on "idmap [ug]id" parameter values */
7613
7614 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7615 {
7616         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7617
7618         return True;
7619 }
7620
7621 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7622 {
7623         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7624
7625         return True;
7626 }
7627
7628 /***************************************************************************
7629  Handle the DEBUG level list.
7630 ***************************************************************************/
7631
7632 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7633 {
7634         string_set(ptr, pszParmValueIn);
7635         return debug_parse_levels(pszParmValueIn);
7636 }
7637
7638 /***************************************************************************
7639  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7640 ***************************************************************************/
7641
7642 static const char *append_ldap_suffix( const char *str )
7643 {
7644         const char *suffix_string;
7645
7646
7647         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7648                                         Globals.szLdapSuffix );
7649         if ( !suffix_string ) {
7650                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7651                 return "";
7652         }
7653
7654         return suffix_string;
7655 }
7656
7657 const char *lp_ldap_machine_suffix(void)
7658 {
7659         if (Globals.szLdapMachineSuffix[0])
7660                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7661
7662         return lp_string(Globals.szLdapSuffix);
7663 }
7664
7665 const char *lp_ldap_user_suffix(void)
7666 {
7667         if (Globals.szLdapUserSuffix[0])
7668                 return append_ldap_suffix(Globals.szLdapUserSuffix);
7669
7670         return lp_string(Globals.szLdapSuffix);
7671 }
7672
7673 const char *lp_ldap_group_suffix(void)
7674 {
7675         if (Globals.szLdapGroupSuffix[0])
7676                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7677
7678         return lp_string(Globals.szLdapSuffix);
7679 }
7680
7681 const char *lp_ldap_idmap_suffix(void)
7682 {
7683         if (Globals.szLdapIdmapSuffix[0])
7684                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7685
7686         return lp_string(Globals.szLdapSuffix);
7687 }
7688
7689 /****************************************************************************
7690  set the value for a P_ENUM
7691  ***************************************************************************/
7692
7693 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7694                               int *ptr )
7695 {
7696         int i;
7697
7698         for (i = 0; parm->enum_list[i].name; i++) {
7699                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7700                         *ptr = parm->enum_list[i].value;
7701                         return;
7702                 }
7703         }
7704         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7705                   pszParmValue, parm->label));
7706 }
7707
7708 /***************************************************************************
7709 ***************************************************************************/
7710
7711 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7712 {
7713         static int parm_num = -1;
7714         struct loadparm_service *s;
7715
7716         if ( parm_num == -1 )
7717                 parm_num = map_parameter( "printing" );
7718
7719         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7720
7721         if ( snum < 0 )
7722                 s = &sDefault;
7723         else
7724                 s = ServicePtrs[snum];
7725
7726         init_printer_values( s );
7727
7728         return True;
7729 }
7730
7731
7732 /***************************************************************************
7733  Initialise a copymap.
7734 ***************************************************************************/
7735
7736 static void init_copymap(struct loadparm_service *pservice)
7737 {
7738         int i;
7739
7740         TALLOC_FREE(pservice->copymap);
7741
7742         pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7743         if (!pservice->copymap)
7744                 DEBUG(0,
7745                       ("Couldn't allocate copymap!! (size %d)\n",
7746                        (int)NUMPARAMETERS));
7747         else
7748                 for (i = 0; i < NUMPARAMETERS; i++)
7749                         bitmap_set(pservice->copymap, i);
7750 }
7751
7752 /**
7753   return the parameter pointer for a parameter
7754 */
7755 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
7756 {
7757         if (service == NULL) {
7758                 if (parm->p_class == P_LOCAL)
7759                         return parm->ptr;
7760                 else if (parm->p_class == P_GLOBAL)
7761                         return parm->ptr;
7762                 else return NULL;
7763         } else {
7764                 return (void *)(((char *)service) + PTR_DIFF(parm->ptr, &sDefault));
7765         }
7766 }
7767
7768 /***************************************************************************
7769  Return the local pointer to a parameter given the service number and parameter
7770 ***************************************************************************/
7771
7772 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
7773 {
7774         return lp_parm_ptr(ServicePtrs[snum], parm);
7775 }
7776
7777 /***************************************************************************
7778  Process a parameter for a particular service number. If snum < 0
7779  then assume we are in the globals.
7780 ***************************************************************************/
7781
7782 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7783 {
7784         int parmnum, i;
7785         void *parm_ptr = NULL;  /* where we are going to store the result */
7786         struct param_opt_struct **opt_list;
7787
7788         parmnum = map_parameter(pszParmName);
7789
7790         if (parmnum < 0) {
7791                 if (strchr(pszParmName, ':') == NULL) {
7792                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7793                                   pszParmName));
7794                         return (True);
7795                 }
7796
7797                 /*
7798                  * We've got a parametric option
7799                  */
7800
7801                 opt_list = (snum < 0)
7802                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7803                 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7804
7805                 return (True);
7806         }
7807
7808         /* if it's already been set by the command line, then we don't
7809            override here */
7810         if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7811                 return true;
7812         }
7813
7814         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7815                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7816                           pszParmName));
7817         }
7818
7819         /* we might point at a service, the default service or a global */
7820         if (snum < 0) {
7821                 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
7822         } else {
7823                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7824                         DEBUG(0,
7825                               ("Global parameter %s found in service section!\n",
7826                                pszParmName));
7827                         return (True);
7828                 }
7829                 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
7830         }
7831
7832         if (snum >= 0) {
7833                 if (!ServicePtrs[snum]->copymap)
7834                         init_copymap(ServicePtrs[snum]);
7835
7836                 /* this handles the aliases - set the copymap for other entries with
7837                    the same data pointer */
7838                 for (i = 0; parm_table[i].label; i++)
7839                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7840                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7841         }
7842
7843         /* if it is a special case then go ahead */
7844         if (parm_table[parmnum].special) {
7845                 return parm_table[parmnum].special(snum, pszParmValue,
7846                                                    (char **)parm_ptr);
7847         }
7848
7849         /* now switch on the type of variable it is */
7850         switch (parm_table[parmnum].type)
7851         {
7852                 case P_BOOL:
7853                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7854                         break;
7855
7856                 case P_BOOLREV:
7857                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7858                         break;
7859
7860                 case P_INTEGER:
7861                         *(int *)parm_ptr = lp_int(pszParmValue);
7862                         break;
7863
7864                 case P_CHAR:
7865                         *(char *)parm_ptr = *pszParmValue;
7866                         break;
7867
7868                 case P_OCTAL:
7869                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7870                         if ( i != 1 ) {
7871                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7872                         }
7873                         break;
7874
7875                 case P_LIST:
7876                         TALLOC_FREE(*((char ***)parm_ptr));
7877                         *(char ***)parm_ptr = str_list_make_v3(
7878                                 NULL, pszParmValue, NULL);
7879                         break;
7880
7881                 case P_STRING:
7882                         string_set((char **)parm_ptr, pszParmValue);
7883                         break;
7884
7885                 case P_USTRING:
7886                 {
7887                         char *upper_string = strupper_talloc(talloc_tos(), 
7888                                                              pszParmValue);
7889                         string_set((char **)parm_ptr, upper_string);
7890                         TALLOC_FREE(upper_string);
7891                         break;
7892                 }
7893                 case P_ENUM:
7894                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7895                         break;
7896                 case P_SEP:
7897                         break;
7898         }
7899
7900         return (True);
7901 }
7902
7903 /***************************************************************************
7904 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7905 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7906 ***************************************************************************/
7907
7908 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7909 {
7910         int parmnum, i;
7911         parmnum = map_parameter(pszParmName);
7912         if (parmnum >= 0) {
7913                 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7914                 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7915                         return false;
7916                 }
7917                 parm_table[parmnum].flags |= FLAG_CMDLINE;
7918
7919                 /* we have to also set FLAG_CMDLINE on aliases.  Aliases must
7920                  * be grouped in the table, so we don't have to search the
7921                  * whole table */
7922                 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
7923                         parm_table[i].flags |= FLAG_CMDLINE;
7924                 }
7925                 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
7926                         parm_table[i].flags |= FLAG_CMDLINE;
7927                 }
7928
7929                 if (store_values) {
7930                         store_lp_set_cmdline(pszParmName, pszParmValue);
7931                 }
7932                 return true;
7933         }
7934
7935         /* it might be parametric */
7936         if (strchr(pszParmName, ':') != NULL) {
7937                 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7938                 if (store_values) {
7939                         store_lp_set_cmdline(pszParmName, pszParmValue);
7940                 }
7941                 return true;
7942         }
7943
7944         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
7945         return true;
7946 }
7947
7948 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7949 {
7950         return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7951 }
7952
7953 /***************************************************************************
7954  Process a parameter.
7955 ***************************************************************************/
7956
7957 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7958                          void *userdata)
7959 {
7960         if (!bInGlobalSection && bGlobalOnly)
7961                 return (True);
7962
7963         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7964
7965         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7966                                 pszParmName, pszParmValue));
7967 }
7968
7969 /*
7970   set a option from the commandline in 'a=b' format. Use to support --option
7971 */
7972 bool lp_set_option(const char *option)
7973 {
7974         char *p, *s;
7975         bool ret;
7976
7977         s = talloc_strdup(NULL, option);
7978         if (!s) {
7979                 return false;
7980         }
7981
7982         p = strchr(s, '=');
7983         if (!p) {
7984                 talloc_free(s);
7985                 return false;
7986         }
7987
7988         *p = 0;
7989
7990         /* skip white spaces after the = sign */
7991         do {
7992                 p++;
7993         } while (*p == ' ');
7994
7995         ret = lp_set_cmdline(s, p);
7996         talloc_free(s);
7997         return ret;
7998 }
7999
8000 /**************************************************************************
8001  Print a parameter of the specified type.
8002 ***************************************************************************/
8003
8004 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
8005 {
8006         int i;
8007         switch (p->type)
8008         {
8009                 case P_ENUM:
8010                         for (i = 0; p->enum_list[i].name; i++) {
8011                                 if (*(int *)ptr == p->enum_list[i].value) {
8012                                         fprintf(f, "%s",
8013                                                 p->enum_list[i].name);
8014                                         break;
8015                                 }
8016                         }
8017                         break;
8018
8019                 case P_BOOL:
8020                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
8021                         break;
8022
8023                 case P_BOOLREV:
8024                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
8025                         break;
8026
8027                 case P_INTEGER:
8028                         fprintf(f, "%d", *(int *)ptr);
8029                         break;
8030
8031                 case P_CHAR:
8032                         fprintf(f, "%c", *(char *)ptr);
8033                         break;
8034
8035                 case P_OCTAL: {
8036                         char *o = octal_string(*(int *)ptr);
8037                         fprintf(f, "%s", o);
8038                         TALLOC_FREE(o);
8039                         break;
8040                 }
8041
8042                 case P_LIST:
8043                         if ((char ***)ptr && *(char ***)ptr) {
8044                                 char **list = *(char ***)ptr;
8045                                 for (; *list; list++) {
8046                                         /* surround strings with whitespace in double quotes */
8047                                         if ( strchr_m( *list, ' ' ) )
8048                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
8049                                         else
8050                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
8051                                 }
8052                         }
8053                         break;
8054
8055                 case P_STRING:
8056                 case P_USTRING:
8057                         if (*(char **)ptr) {
8058                                 fprintf(f, "%s", *(char **)ptr);
8059                         }
8060                         break;
8061                 case P_SEP:
8062                         break;
8063         }
8064 }
8065
8066 /***************************************************************************
8067  Check if two parameters are equal.
8068 ***************************************************************************/
8069
8070 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8071 {
8072         switch (type) {
8073                 case P_BOOL:
8074                 case P_BOOLREV:
8075                         return (*((bool *)ptr1) == *((bool *)ptr2));
8076
8077                 case P_INTEGER:
8078                 case P_ENUM:
8079                 case P_OCTAL:
8080                         return (*((int *)ptr1) == *((int *)ptr2));
8081
8082                 case P_CHAR:
8083                         return (*((char *)ptr1) == *((char *)ptr2));
8084
8085                 case P_LIST:
8086                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8087
8088                 case P_STRING:
8089                 case P_USTRING:
8090                 {
8091                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8092                         if (p1 && !*p1)
8093                                 p1 = NULL;
8094                         if (p2 && !*p2)
8095                                 p2 = NULL;
8096                         return (p1 == p2 || strequal(p1, p2));
8097                 }
8098                 case P_SEP:
8099                         break;
8100         }
8101         return (False);
8102 }
8103
8104 /***************************************************************************
8105  Initialize any local varients in the sDefault table.
8106 ***************************************************************************/
8107
8108 void init_locals(void)
8109 {
8110         /* None as yet. */
8111 }
8112
8113 /***************************************************************************
8114  Process a new section (service). At this stage all sections are services.
8115  Later we'll have special sections that permit server parameters to be set.
8116  Returns True on success, False on failure. 
8117 ***************************************************************************/
8118
8119 static bool do_section(const char *pszSectionName, void *userdata)
8120 {
8121         bool bRetval;
8122         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8123                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8124         bRetval = False;
8125
8126         /* if we were in a global section then do the local inits */
8127         if (bInGlobalSection && !isglobal)
8128                 init_locals();
8129
8130         /* if we've just struck a global section, note the fact. */
8131         bInGlobalSection = isglobal;
8132
8133         /* check for multiple global sections */
8134         if (bInGlobalSection) {
8135                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8136                 return (True);
8137         }
8138
8139         if (!bInGlobalSection && bGlobalOnly)
8140                 return (True);
8141
8142         /* if we have a current service, tidy it up before moving on */
8143         bRetval = True;
8144
8145         if (iServiceIndex >= 0)
8146                 bRetval = service_ok(iServiceIndex);
8147
8148         /* if all is still well, move to the next record in the services array */
8149         if (bRetval) {
8150                 /* We put this here to avoid an odd message order if messages are */
8151                 /* issued by the post-processing of a previous section. */
8152                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8153
8154                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8155                     < 0) {
8156                         DEBUG(0, ("Failed to add a new service\n"));
8157                         return (False);
8158                 }
8159                 /* Clean all parametric options for service */
8160                 /* They will be added during parsing again */
8161                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
8162         }
8163
8164         return (bRetval);
8165 }
8166
8167
8168 /***************************************************************************
8169  Determine if a partcular base parameter is currentl set to the default value.
8170 ***************************************************************************/
8171
8172 static bool is_default(int i)
8173 {
8174         if (!defaults_saved)
8175                 return False;
8176         switch (parm_table[i].type) {
8177                 case P_LIST:
8178                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
8179                                               *(const char ***)lp_parm_ptr(NULL, 
8180                                                                            &parm_table[i]));
8181                 case P_STRING:
8182                 case P_USTRING:
8183                         return strequal(parm_table[i].def.svalue,
8184                                         *(char **)lp_parm_ptr(NULL, 
8185                                                               &parm_table[i]));
8186                 case P_BOOL:
8187                 case P_BOOLREV:
8188                         return parm_table[i].def.bvalue ==
8189                                 *(bool *)lp_parm_ptr(NULL, 
8190                                                      &parm_table[i]);
8191                 case P_CHAR:
8192                         return parm_table[i].def.cvalue ==
8193                                 *(char *)lp_parm_ptr(NULL, 
8194                                                      &parm_table[i]);
8195                 case P_INTEGER:
8196                 case P_OCTAL:
8197                 case P_ENUM:
8198                         return parm_table[i].def.ivalue ==
8199                                 *(int *)lp_parm_ptr(NULL, 
8200                                                     &parm_table[i]);
8201                 case P_SEP:
8202                         break;
8203         }
8204         return False;
8205 }
8206
8207 /***************************************************************************
8208 Display the contents of the global structure.
8209 ***************************************************************************/
8210
8211 static void dump_globals(FILE *f)
8212 {
8213         int i;
8214         struct param_opt_struct *data;
8215
8216         fprintf(f, "[global]\n");
8217
8218         for (i = 0; parm_table[i].label; i++)
8219                 if (parm_table[i].p_class == P_GLOBAL &&
8220                     !(parm_table[i].flags & FLAG_META) &&
8221                     parm_table[i].ptr &&
8222                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8223                         if (defaults_saved && is_default(i))
8224                                 continue;
8225                         fprintf(f, "\t%s = ", parm_table[i].label);
8226                         print_parameter(&parm_table[i], lp_parm_ptr(NULL, 
8227                                                                     &parm_table[i]),
8228                                         f);
8229                         fprintf(f, "\n");
8230         }
8231         if (Globals.param_opt != NULL) {
8232                 data = Globals.param_opt;
8233                 while(data) {
8234                         fprintf(f, "\t%s = %s\n", data->key, data->value);
8235                         data = data->next;
8236                 }
8237         }
8238
8239 }
8240
8241 /***************************************************************************
8242  Return True if a local parameter is currently set to the global default.
8243 ***************************************************************************/
8244
8245 bool lp_is_default(int snum, struct parm_struct *parm)
8246 {
8247         return equal_parameter(parm->type,
8248                                lp_parm_ptr(ServicePtrs[snum], parm),
8249                                lp_parm_ptr(NULL, parm));
8250 }
8251
8252 /***************************************************************************
8253  Display the contents of a single services record.
8254 ***************************************************************************/
8255
8256 static void dump_a_service(struct loadparm_service *pService, FILE * f)
8257 {
8258         int i;
8259         struct param_opt_struct *data;
8260
8261         if (pService != &sDefault)
8262                 fprintf(f, "[%s]\n", pService->szService);
8263
8264         for (i = 0; parm_table[i].label; i++) {
8265
8266                 if (parm_table[i].p_class == P_LOCAL &&
8267                     !(parm_table[i].flags & FLAG_META) &&
8268                     parm_table[i].ptr &&
8269                     (*parm_table[i].label != '-') &&
8270                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
8271                 {
8272                         if (pService == &sDefault) {
8273                                 if (defaults_saved && is_default(i))
8274                                         continue;
8275                         } else {
8276                                 if (equal_parameter(parm_table[i].type,
8277                                                     lp_parm_ptr(pService, &parm_table[i]),
8278                                                     lp_parm_ptr(NULL, &parm_table[i])))
8279                                         continue;
8280                         }
8281
8282                         fprintf(f, "\t%s = ", parm_table[i].label);
8283                         print_parameter(&parm_table[i],
8284                                         lp_parm_ptr(pService, &parm_table[i]),
8285                                         f);
8286                         fprintf(f, "\n");
8287                 }
8288         }
8289
8290                 if (pService->param_opt != NULL) {
8291                         data = pService->param_opt;
8292                         while(data) {
8293                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
8294                                 data = data->next;
8295                         }
8296                 }
8297 }
8298
8299 /***************************************************************************
8300  Display the contents of a parameter of a single services record.
8301 ***************************************************************************/
8302
8303 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8304 {
8305         int i;
8306         bool result = False;
8307         parm_class p_class;
8308         unsigned flag = 0;
8309         fstring local_parm_name;
8310         char *parm_opt;
8311         const char *parm_opt_value;
8312
8313         /* check for parametrical option */
8314         fstrcpy( local_parm_name, parm_name);
8315         parm_opt = strchr( local_parm_name, ':');
8316
8317         if (parm_opt) {
8318                 *parm_opt = '\0';
8319                 parm_opt++;
8320                 if (strlen(parm_opt)) {
8321                         parm_opt_value = lp_parm_const_string( snum,
8322                                 local_parm_name, parm_opt, NULL);
8323                         if (parm_opt_value) {
8324                                 printf( "%s\n", parm_opt_value);
8325                                 result = True;
8326                         }
8327                 }
8328                 return result;
8329         }
8330
8331         /* check for a key and print the value */
8332         if (isGlobal) {
8333                 p_class = P_GLOBAL;
8334                 flag = FLAG_GLOBAL;
8335         } else
8336                 p_class = P_LOCAL;
8337
8338         for (i = 0; parm_table[i].label; i++) {
8339                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8340                     !(parm_table[i].flags & FLAG_META) &&
8341                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8342                     parm_table[i].ptr &&
8343                     (*parm_table[i].label != '-') &&
8344                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
8345                 {
8346                         void *ptr;
8347
8348                         if (isGlobal) {
8349                                 ptr = lp_parm_ptr(NULL, 
8350                                                   &parm_table[i]);
8351                         } else {
8352                                 ptr = lp_parm_ptr(ServicePtrs[snum], 
8353                                                   &parm_table[i]);
8354                         }
8355
8356                         print_parameter(&parm_table[i],
8357                                         ptr, f);
8358                         fprintf(f, "\n");
8359                         result = True;
8360                         break;
8361                 }
8362         }
8363
8364         return result;
8365 }
8366
8367 /***************************************************************************
8368  Return info about the requested parameter (given as a string).
8369  Return NULL when the string is not a valid parameter name.
8370 ***************************************************************************/
8371
8372 struct parm_struct *lp_get_parameter(const char *param_name)
8373 {
8374         int num = map_parameter(param_name);
8375
8376         if (num < 0) {
8377                 return NULL;
8378         }
8379
8380         return &parm_table[num];
8381 }
8382
8383 /***************************************************************************
8384  Return info about the next parameter in a service.
8385  snum==GLOBAL_SECTION_SNUM gives the globals.
8386  Return NULL when out of parameters.
8387 ***************************************************************************/
8388
8389 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8390 {
8391         if (snum < 0) {
8392                 /* do the globals */
8393                 for (; parm_table[*i].label; (*i)++) {
8394                         if (parm_table[*i].p_class == P_SEPARATOR)
8395                                 return &parm_table[(*i)++];
8396
8397                         if (!parm_table[*i].ptr
8398                             || (*parm_table[*i].label == '-'))
8399                                 continue;
8400
8401                         if ((*i) > 0
8402                             && (parm_table[*i].ptr ==
8403                                 parm_table[(*i) - 1].ptr))
8404                                 continue;
8405
8406                         if (is_default(*i) && !allparameters)
8407                                 continue;
8408
8409                         return &parm_table[(*i)++];
8410                 }
8411         } else {
8412                 struct loadparm_service *pService = ServicePtrs[snum];
8413
8414                 for (; parm_table[*i].label; (*i)++) {
8415                         if (parm_table[*i].p_class == P_SEPARATOR)
8416                                 return &parm_table[(*i)++];
8417
8418                         if (parm_table[*i].p_class == P_LOCAL &&
8419                             parm_table[*i].ptr &&
8420                             (*parm_table[*i].label != '-') &&
8421                             ((*i) == 0 ||
8422                              (parm_table[*i].ptr !=
8423                               parm_table[(*i) - 1].ptr)))
8424                         {
8425                                 if (allparameters ||
8426                                     !equal_parameter(parm_table[*i].type,
8427                                                      lp_parm_ptr(pService, 
8428                                                                  &parm_table[*i]),
8429                                                      lp_parm_ptr(NULL, 
8430                                                                  &parm_table[*i])))
8431                                 {
8432                                         return &parm_table[(*i)++];
8433                                 }
8434                         }
8435                 }
8436         }
8437
8438         return NULL;
8439 }
8440
8441
8442 #if 0
8443 /***************************************************************************
8444  Display the contents of a single copy structure.
8445 ***************************************************************************/
8446 static void dump_copy_map(bool *pcopymap)
8447 {
8448         int i;
8449         if (!pcopymap)
8450                 return;
8451
8452         printf("\n\tNon-Copied parameters:\n");
8453
8454         for (i = 0; parm_table[i].label; i++)
8455                 if (parm_table[i].p_class == P_LOCAL &&
8456                     parm_table[i].ptr && !pcopymap[i] &&
8457                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8458                 {
8459                         printf("\t\t%s\n", parm_table[i].label);
8460                 }
8461 }
8462 #endif
8463
8464 /***************************************************************************
8465  Return TRUE if the passed service number is within range.
8466 ***************************************************************************/
8467
8468 bool lp_snum_ok(int iService)
8469 {
8470         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8471 }
8472
8473 /***************************************************************************
8474  Auto-load some home services.
8475 ***************************************************************************/
8476
8477 static void lp_add_auto_services(char *str)
8478 {
8479         char *s;
8480         char *p;
8481         int homes;
8482         char *saveptr;
8483
8484         if (!str)
8485                 return;
8486
8487         s = SMB_STRDUP(str);
8488         if (!s)
8489                 return;
8490
8491         homes = lp_servicenumber(HOMES_NAME);
8492
8493         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8494              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8495                 char *home;
8496
8497                 if (lp_servicenumber(p) >= 0)
8498                         continue;
8499
8500                 home = get_user_home_dir(talloc_tos(), p);
8501
8502                 if (home && home[0] && homes >= 0)
8503                         lp_add_home(p, homes, p, home);
8504
8505                 TALLOC_FREE(home);
8506         }
8507         SAFE_FREE(s);
8508 }
8509
8510 /***************************************************************************
8511  Auto-load one printer.
8512 ***************************************************************************/
8513
8514 void lp_add_one_printer(const char *name, const char *comment,
8515                         const char *location, void *pdata)
8516 {
8517         int printers = lp_servicenumber(PRINTERS_NAME);
8518         int i;
8519
8520         if (lp_servicenumber(name) < 0) {
8521                 lp_add_printer(name, printers);
8522                 if ((i = lp_servicenumber(name)) >= 0) {
8523                         string_set(&ServicePtrs[i]->comment, comment);
8524                         ServicePtrs[i]->autoloaded = True;
8525                 }
8526         }
8527 }
8528
8529 /***************************************************************************
8530  Have we loaded a services file yet?
8531 ***************************************************************************/
8532
8533 bool lp_loaded(void)
8534 {
8535         return (bLoaded);
8536 }
8537
8538 /***************************************************************************
8539  Unload unused services.
8540 ***************************************************************************/
8541
8542 void lp_killunused(struct smbd_server_connection *sconn,
8543                    bool (*snumused) (struct smbd_server_connection *, int))
8544 {
8545         int i;
8546         for (i = 0; i < iNumServices; i++) {
8547                 if (!VALID(i))
8548                         continue;
8549
8550                 /* don't kill autoloaded or usershare services */
8551                 if ( ServicePtrs[i]->autoloaded ||
8552                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8553                         continue;
8554                 }
8555
8556                 if (!snumused || !snumused(sconn, i)) {
8557                         free_service_byindex(i);
8558                 }
8559         }
8560 }
8561
8562 /**
8563  * Kill all except autoloaded and usershare services - convenience wrapper
8564  */
8565 void lp_kill_all_services(void)
8566 {
8567         lp_killunused(NULL, NULL);
8568 }
8569
8570 /***************************************************************************
8571  Unload a service.
8572 ***************************************************************************/
8573
8574 void lp_killservice(int iServiceIn)
8575 {
8576         if (VALID(iServiceIn)) {
8577                 free_service_byindex(iServiceIn);
8578         }
8579 }
8580
8581 /***************************************************************************
8582  Save the curent values of all global and sDefault parameters into the 
8583  defaults union. This allows swat and testparm to show only the
8584  changed (ie. non-default) parameters.
8585 ***************************************************************************/
8586
8587 static void lp_save_defaults(void)
8588 {
8589         int i;
8590         for (i = 0; parm_table[i].label; i++) {
8591                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8592                         continue;
8593                 switch (parm_table[i].type) {
8594                         case P_LIST:
8595                                 parm_table[i].def.lvalue = str_list_copy(
8596                                         NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
8597                                 break;
8598                         case P_STRING:
8599                         case P_USTRING:
8600                                 if (parm_table[i].ptr) {
8601                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
8602                                 } else {
8603                                         parm_table[i].def.svalue = NULL;
8604                                 }
8605                                 break;
8606                         case P_BOOL:
8607                         case P_BOOLREV:
8608                                 parm_table[i].def.bvalue =
8609                                         *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
8610                                 break;
8611                         case P_CHAR:
8612                                 parm_table[i].def.cvalue =
8613                                         *(char *)lp_parm_ptr(NULL, &parm_table[i]);
8614                                 break;
8615                         case P_INTEGER:
8616                         case P_OCTAL:
8617                         case P_ENUM:
8618                                 parm_table[i].def.ivalue =
8619                                         *(int *)lp_parm_ptr(NULL, &parm_table[i]);
8620                                 break;
8621                         case P_SEP:
8622                                 break;
8623                 }
8624         }
8625         defaults_saved = True;
8626 }
8627
8628 /***********************************************************
8629  If we should send plaintext/LANMAN passwords in the clinet
8630 ************************************************************/
8631
8632 static void set_allowed_client_auth(void)
8633 {
8634         if (Globals.bClientNTLMv2Auth) {
8635                 Globals.bClientLanManAuth = False;
8636         }
8637         if (!Globals.bClientLanManAuth) {
8638                 Globals.bClientPlaintextAuth = False;
8639         }
8640 }
8641
8642 /***************************************************************************
8643  JRA.
8644  The following code allows smbd to read a user defined share file.
8645  Yes, this is my intent. Yes, I'm comfortable with that...
8646
8647  THE FOLLOWING IS SECURITY CRITICAL CODE.
8648
8649  It washes your clothes, it cleans your house, it guards you while you sleep...
8650  Do not f%^k with it....
8651 ***************************************************************************/
8652
8653 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8654
8655 /***************************************************************************
8656  Check allowed stat state of a usershare file.
8657  Ensure we print out who is dicking with us so the admin can
8658  get their sorry ass fired.
8659 ***************************************************************************/
8660
8661 static bool check_usershare_stat(const char *fname,
8662                                  const SMB_STRUCT_STAT *psbuf)
8663 {
8664         if (!S_ISREG(psbuf->st_ex_mode)) {
8665                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8666                         "not a regular file\n",
8667                         fname, (unsigned int)psbuf->st_ex_uid ));
8668                 return False;
8669         }
8670
8671         /* Ensure this doesn't have the other write bit set. */
8672         if (psbuf->st_ex_mode & S_IWOTH) {
8673                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8674                         "public write. Refusing to allow as a usershare file.\n",
8675                         fname, (unsigned int)psbuf->st_ex_uid ));
8676                 return False;
8677         }
8678
8679         /* Should be 10k or less. */
8680         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8681                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8682                         "too large (%u) to be a user share file.\n",
8683                         fname, (unsigned int)psbuf->st_ex_uid,
8684                         (unsigned int)psbuf->st_ex_size ));
8685                 return False;
8686         }
8687
8688         return True;
8689 }
8690
8691 /***************************************************************************
8692  Parse the contents of a usershare file.
8693 ***************************************************************************/
8694
8695 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8696                         SMB_STRUCT_STAT *psbuf,
8697                         const char *servicename,
8698                         int snum,
8699                         char **lines,
8700                         int numlines,
8701                         char **pp_sharepath,
8702                         char **pp_comment,
8703                         char **pp_cp_servicename,
8704                         struct security_descriptor **ppsd,
8705                         bool *pallow_guest)
8706 {
8707         const char **prefixallowlist = lp_usershare_prefix_allow_list();
8708         const char **prefixdenylist = lp_usershare_prefix_deny_list();
8709         int us_vers;
8710         SMB_STRUCT_DIR *dp;
8711         SMB_STRUCT_STAT sbuf;
8712         char *sharepath = NULL;
8713         char *comment = NULL;
8714
8715         *pp_sharepath = NULL;
8716         *pp_comment = NULL;
8717
8718         *pallow_guest = False;
8719
8720         if (numlines < 4) {
8721                 return USERSHARE_MALFORMED_FILE;
8722         }
8723
8724         if (strcmp(lines[0], "#VERSION 1") == 0) {
8725                 us_vers = 1;
8726         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8727                 us_vers = 2;
8728                 if (numlines < 5) {
8729                         return USERSHARE_MALFORMED_FILE;
8730                 }
8731         } else {
8732                 return USERSHARE_BAD_VERSION;
8733         }
8734
8735         if (strncmp(lines[1], "path=", 5) != 0) {
8736                 return USERSHARE_MALFORMED_PATH;
8737         }
8738
8739         sharepath = talloc_strdup(ctx, &lines[1][5]);
8740         if (!sharepath) {
8741                 return USERSHARE_POSIX_ERR;
8742         }
8743         trim_string(sharepath, " ", " ");
8744
8745         if (strncmp(lines[2], "comment=", 8) != 0) {
8746                 return USERSHARE_MALFORMED_COMMENT_DEF;
8747         }
8748
8749         comment = talloc_strdup(ctx, &lines[2][8]);
8750         if (!comment) {
8751                 return USERSHARE_POSIX_ERR;
8752         }
8753         trim_string(comment, " ", " ");
8754         trim_char(comment, '"', '"');
8755
8756         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8757                 return USERSHARE_MALFORMED_ACL_DEF;
8758         }
8759
8760         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8761                 return USERSHARE_ACL_ERR;
8762         }
8763
8764         if (us_vers == 2) {
8765                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8766                         return USERSHARE_MALFORMED_ACL_DEF;
8767                 }
8768                 if (lines[4][9] == 'y') {
8769                         *pallow_guest = True;
8770                 }
8771
8772                 /* Backwards compatible extension to file version #2. */
8773                 if (numlines > 5) {
8774                         if (strncmp(lines[5], "sharename=", 10) != 0) {
8775                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
8776                         }
8777                         if (!strequal(&lines[5][10], servicename)) {
8778                                 return USERSHARE_BAD_SHARENAME;
8779                         }
8780                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8781                         if (!*pp_cp_servicename) {
8782                                 return USERSHARE_POSIX_ERR;
8783                         }
8784                 }
8785         }
8786
8787         if (*pp_cp_servicename == NULL) {
8788                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8789                 if (!*pp_cp_servicename) {
8790                         return USERSHARE_POSIX_ERR;
8791                 }
8792         }
8793
8794         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8795                 /* Path didn't change, no checks needed. */
8796                 *pp_sharepath = sharepath;
8797                 *pp_comment = comment;
8798                 return USERSHARE_OK;
8799         }
8800
8801         /* The path *must* be absolute. */
8802         if (sharepath[0] != '/') {
8803                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8804                         servicename, sharepath));
8805                 return USERSHARE_PATH_NOT_ABSOLUTE;
8806         }
8807
8808         /* If there is a usershare prefix deny list ensure one of these paths
8809            doesn't match the start of the user given path. */
8810         if (prefixdenylist) {
8811                 int i;
8812                 for ( i=0; prefixdenylist[i]; i++ ) {
8813                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8814                                 servicename, i, prefixdenylist[i], sharepath ));
8815                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8816                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8817                                         "usershare prefix deny list entries.\n",
8818                                         servicename, sharepath));
8819                                 return USERSHARE_PATH_IS_DENIED;
8820                         }
8821                 }
8822         }
8823
8824         /* If there is a usershare prefix allow list ensure one of these paths
8825            does match the start of the user given path. */
8826
8827         if (prefixallowlist) {
8828                 int i;
8829                 for ( i=0; prefixallowlist[i]; i++ ) {
8830                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8831                                 servicename, i, prefixallowlist[i], sharepath ));
8832                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8833                                 break;
8834                         }
8835                 }
8836                 if (prefixallowlist[i] == NULL) {
8837                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8838                                 "usershare prefix allow list entries.\n",
8839                                 servicename, sharepath));
8840                         return USERSHARE_PATH_NOT_ALLOWED;
8841                 }
8842         }
8843
8844         /* Ensure this is pointing to a directory. */
8845         dp = sys_opendir(sharepath);
8846
8847         if (!dp) {
8848                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8849                         servicename, sharepath));
8850                 return USERSHARE_PATH_NOT_DIRECTORY;
8851         }
8852
8853         /* Ensure the owner of the usershare file has permission to share
8854            this directory. */
8855
8856         if (sys_stat(sharepath, &sbuf, false) == -1) {
8857                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8858                         servicename, sharepath, strerror(errno) ));
8859                 sys_closedir(dp);
8860                 return USERSHARE_POSIX_ERR;
8861         }
8862
8863         sys_closedir(dp);
8864
8865         if (!S_ISDIR(sbuf.st_ex_mode)) {
8866                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8867                         servicename, sharepath ));
8868                 return USERSHARE_PATH_NOT_DIRECTORY;
8869         }
8870
8871         /* Check if sharing is restricted to owner-only. */
8872         /* psbuf is the stat of the usershare definition file,
8873            sbuf is the stat of the target directory to be shared. */
8874
8875         if (lp_usershare_owner_only()) {
8876                 /* root can share anything. */
8877                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8878                         return USERSHARE_PATH_NOT_ALLOWED;
8879                 }
8880         }
8881
8882         *pp_sharepath = sharepath;
8883         *pp_comment = comment;
8884         return USERSHARE_OK;
8885 }
8886
8887 /***************************************************************************
8888  Deal with a usershare file.
8889  Returns:
8890         >= 0 - snum
8891         -1 - Bad name, invalid contents.
8892            - service name already existed and not a usershare, problem
8893             with permissions to share directory etc.
8894 ***************************************************************************/
8895
8896 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8897 {
8898         SMB_STRUCT_STAT sbuf;
8899         SMB_STRUCT_STAT lsbuf;
8900         char *fname = NULL;
8901         char *sharepath = NULL;
8902         char *comment = NULL;
8903         char *cp_service_name = NULL;
8904         char **lines = NULL;
8905         int numlines = 0;
8906         int fd = -1;
8907         int iService = -1;
8908         TALLOC_CTX *ctx = talloc_stackframe();
8909         struct security_descriptor *psd = NULL;
8910         bool guest_ok = False;
8911         char *canon_name = NULL;
8912         bool added_service = false;
8913         int ret = -1;
8914
8915         /* Ensure share name doesn't contain invalid characters. */
8916         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8917                 DEBUG(0,("process_usershare_file: share name %s contains "
8918                         "invalid characters (any of %s)\n",
8919                         file_name, INVALID_SHARENAME_CHARS ));
8920                 goto out;
8921         }
8922
8923         canon_name = canonicalize_servicename(ctx, file_name);
8924         if (!canon_name) {
8925                 goto out;
8926         }
8927
8928         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8929         if (!fname) {
8930                 goto out;
8931         }
8932
8933         /* Minimize the race condition by doing an lstat before we
8934            open and fstat. Ensure this isn't a symlink link. */
8935
8936         if (sys_lstat(fname, &lsbuf, false) != 0) {
8937                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8938                         fname, strerror(errno) ));
8939                 goto out;
8940         }
8941
8942         /* This must be a regular file, not a symlink, directory or
8943            other strange filetype. */
8944         if (!check_usershare_stat(fname, &lsbuf)) {
8945                 goto out;
8946         }
8947
8948         {
8949                 TDB_DATA data = dbwrap_fetch_bystring(
8950                         ServiceHash, canon_name, canon_name);
8951
8952                 iService = -1;
8953
8954                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8955                         iService = *(int *)data.dptr;
8956                 }
8957         }
8958
8959         if (iService != -1 &&
8960             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8961                              &lsbuf.st_ex_mtime) == 0) {
8962                 /* Nothing changed - Mark valid and return. */
8963                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8964                         canon_name ));
8965                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8966                 ret = iService;
8967                 goto out;
8968         }
8969
8970         /* Try and open the file read only - no symlinks allowed. */
8971 #ifdef O_NOFOLLOW
8972         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8973 #else
8974         fd = sys_open(fname, O_RDONLY, 0);
8975 #endif
8976
8977         if (fd == -1) {
8978                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8979                         fname, strerror(errno) ));
8980                 goto out;
8981         }
8982
8983         /* Now fstat to be *SURE* it's a regular file. */
8984         if (sys_fstat(fd, &sbuf, false) != 0) {
8985                 close(fd);
8986                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8987                         fname, strerror(errno) ));
8988                 goto out;
8989         }
8990
8991         /* Is it the same dev/inode as was lstated ? */
8992         if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8993                 close(fd);
8994                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8995                         "Symlink spoofing going on ?\n", fname ));
8996                 goto out;
8997         }
8998
8999         /* This must be a regular file, not a symlink, directory or
9000            other strange filetype. */
9001         if (!check_usershare_stat(fname, &sbuf)) {
9002                 goto out;
9003         }
9004
9005         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
9006
9007         close(fd);
9008         if (lines == NULL) {
9009                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
9010                         fname, (unsigned int)sbuf.st_ex_uid ));
9011                 goto out;
9012         }
9013
9014         if (parse_usershare_file(ctx, &sbuf, file_name,
9015                         iService, lines, numlines, &sharepath,
9016                         &comment, &cp_service_name,
9017                         &psd, &guest_ok) != USERSHARE_OK) {
9018                 goto out;
9019         }
9020
9021         /* Everything ok - add the service possibly using a template. */
9022         if (iService < 0) {
9023                 const struct loadparm_service *sp = &sDefault;
9024                 if (snum_template != -1) {
9025                         sp = ServicePtrs[snum_template];
9026                 }
9027
9028                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
9029                         DEBUG(0, ("process_usershare_file: Failed to add "
9030                                 "new service %s\n", cp_service_name));
9031                         goto out;
9032                 }
9033
9034                 added_service = true;
9035
9036                 /* Read only is controlled by usershare ACL below. */
9037                 ServicePtrs[iService]->bRead_only = False;
9038         }
9039
9040         /* Write the ACL of the new/modified share. */
9041         if (!set_share_security(canon_name, psd)) {
9042                  DEBUG(0, ("process_usershare_file: Failed to set share "
9043                         "security for user share %s\n",
9044                         canon_name ));
9045                 goto out;
9046         }
9047
9048         /* If from a template it may be marked invalid. */
9049         ServicePtrs[iService]->valid = True;
9050
9051         /* Set the service as a valid usershare. */
9052         ServicePtrs[iService]->usershare = USERSHARE_VALID;
9053
9054         /* Set guest access. */
9055         if (lp_usershare_allow_guests()) {
9056                 ServicePtrs[iService]->bGuest_ok = guest_ok;
9057         }
9058
9059         /* And note when it was loaded. */
9060         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
9061         string_set(&ServicePtrs[iService]->szPath, sharepath);
9062         string_set(&ServicePtrs[iService]->comment, comment);
9063
9064         ret = iService;
9065
9066   out:
9067
9068         if (ret == -1 && iService != -1 && added_service) {
9069                 lp_remove_service(iService);
9070         }
9071
9072         TALLOC_FREE(lines);
9073         TALLOC_FREE(ctx);
9074         return ret;
9075 }
9076
9077 /***************************************************************************
9078  Checks if a usershare entry has been modified since last load.
9079 ***************************************************************************/
9080
9081 static bool usershare_exists(int iService, struct timespec *last_mod)
9082 {
9083         SMB_STRUCT_STAT lsbuf;
9084         const char *usersharepath = Globals.szUsersharePath;
9085         char *fname;
9086
9087         if (asprintf(&fname, "%s/%s",
9088                                 usersharepath,
9089                                 ServicePtrs[iService]->szService) < 0) {
9090                 return false;
9091         }
9092
9093         if (sys_lstat(fname, &lsbuf, false) != 0) {
9094                 SAFE_FREE(fname);
9095                 return false;
9096         }
9097
9098         if (!S_ISREG(lsbuf.st_ex_mode)) {
9099                 SAFE_FREE(fname);
9100                 return false;
9101         }
9102
9103         SAFE_FREE(fname);
9104         *last_mod = lsbuf.st_ex_mtime;
9105         return true;
9106 }
9107
9108 /***************************************************************************
9109  Load a usershare service by name. Returns a valid servicenumber or -1.
9110 ***************************************************************************/
9111
9112 int load_usershare_service(const char *servicename)
9113 {
9114         SMB_STRUCT_STAT sbuf;
9115         const char *usersharepath = Globals.szUsersharePath;
9116         int max_user_shares = Globals.iUsershareMaxShares;
9117         int snum_template = -1;
9118
9119         if (*usersharepath == 0 ||  max_user_shares == 0) {
9120                 return -1;
9121         }
9122
9123         if (sys_stat(usersharepath, &sbuf, false) != 0) {
9124                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9125                         usersharepath, strerror(errno) ));
9126                 return -1;
9127         }
9128
9129         if (!S_ISDIR(sbuf.st_ex_mode)) {
9130                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9131                         usersharepath ));
9132                 return -1;
9133         }
9134
9135         /*
9136          * This directory must be owned by root, and have the 't' bit set.
9137          * It also must not be writable by "other".
9138          */
9139
9140 #ifdef S_ISVTX
9141         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9142 #else
9143         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9144 #endif
9145                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9146                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
9147                         usersharepath ));
9148                 return -1;
9149         }
9150
9151         /* Ensure the template share exists if it's set. */
9152         if (Globals.szUsershareTemplateShare[0]) {
9153                 /* We can't use lp_servicenumber here as we are recommending that
9154                    template shares have -valid=False set. */
9155                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9156                         if (ServicePtrs[snum_template]->szService &&
9157                                         strequal(ServicePtrs[snum_template]->szService,
9158                                                 Globals.szUsershareTemplateShare)) {
9159                                 break;
9160                         }
9161                 }
9162
9163                 if (snum_template == -1) {
9164                         DEBUG(0,("load_usershare_service: usershare template share %s "
9165                                 "does not exist.\n",
9166                                 Globals.szUsershareTemplateShare ));
9167                         return -1;
9168                 }
9169         }
9170
9171         return process_usershare_file(usersharepath, servicename, snum_template);
9172 }
9173
9174 /***************************************************************************
9175  Load all user defined shares from the user share directory.
9176  We only do this if we're enumerating the share list.
9177  This is the function that can delete usershares that have
9178  been removed.
9179 ***************************************************************************/
9180
9181 int load_usershare_shares(struct smbd_server_connection *sconn)
9182 {
9183         SMB_STRUCT_DIR *dp;
9184         SMB_STRUCT_STAT sbuf;
9185         SMB_STRUCT_DIRENT *de;
9186         int num_usershares = 0;
9187         int max_user_shares = Globals.iUsershareMaxShares;
9188         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9189         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9190         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9191         int iService;
9192         int snum_template = -1;
9193         const char *usersharepath = Globals.szUsersharePath;
9194         int ret = lp_numservices();
9195
9196         if (max_user_shares == 0 || *usersharepath == '\0') {
9197                 return lp_numservices();
9198         }
9199
9200         if (sys_stat(usersharepath, &sbuf, false) != 0) {
9201                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9202                         usersharepath, strerror(errno) ));
9203                 return ret;
9204         }
9205
9206         /*
9207          * This directory must be owned by root, and have the 't' bit set.
9208          * It also must not be writable by "other".
9209          */
9210
9211 #ifdef S_ISVTX
9212         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9213 #else
9214         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9215 #endif
9216                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9217                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
9218                         usersharepath ));
9219                 return ret;
9220         }
9221
9222         /* Ensure the template share exists if it's set. */
9223         if (Globals.szUsershareTemplateShare[0]) {
9224                 /* We can't use lp_servicenumber here as we are recommending that
9225                    template shares have -valid=False set. */
9226                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9227                         if (ServicePtrs[snum_template]->szService &&
9228                                         strequal(ServicePtrs[snum_template]->szService,
9229                                                 Globals.szUsershareTemplateShare)) {
9230                                 break;
9231                         }
9232                 }
9233
9234                 if (snum_template == -1) {
9235                         DEBUG(0,("load_usershare_shares: usershare template share %s "
9236                                 "does not exist.\n",
9237                                 Globals.szUsershareTemplateShare ));
9238                         return ret;
9239                 }
9240         }
9241
9242         /* Mark all existing usershares as pending delete. */
9243         for (iService = iNumServices - 1; iService >= 0; iService--) {
9244                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9245                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9246                 }
9247         }
9248
9249         dp = sys_opendir(usersharepath);
9250         if (!dp) {
9251                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9252                         usersharepath, strerror(errno) ));
9253                 return ret;
9254         }
9255
9256         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9257                         (de = sys_readdir(dp));
9258                         num_dir_entries++ ) {
9259                 int r;
9260                 const char *n = de->d_name;
9261
9262                 /* Ignore . and .. */
9263                 if (*n == '.') {
9264                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9265                                 continue;
9266                         }
9267                 }
9268
9269                 if (n[0] == ':') {
9270                         /* Temporary file used when creating a share. */
9271                         num_tmp_dir_entries++;
9272                 }
9273
9274                 /* Allow 20% tmp entries. */
9275                 if (num_tmp_dir_entries > allowed_tmp_entries) {
9276                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9277                                 "in directory %s\n",
9278                                 num_tmp_dir_entries, usersharepath));
9279                         break;
9280                 }
9281
9282                 r = process_usershare_file(usersharepath, n, snum_template);
9283                 if (r == 0) {
9284                         /* Update the services count. */
9285                         num_usershares++;
9286                         if (num_usershares >= max_user_shares) {
9287                                 DEBUG(0,("load_usershare_shares: max user shares reached "
9288                                         "on file %s in directory %s\n",
9289                                         n, usersharepath ));
9290                                 break;
9291                         }
9292                 } else if (r == -1) {
9293                         num_bad_dir_entries++;
9294                 }
9295
9296                 /* Allow 20% bad entries. */
9297                 if (num_bad_dir_entries > allowed_bad_entries) {
9298                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9299                                 "in directory %s\n",
9300                                 num_bad_dir_entries, usersharepath));
9301                         break;
9302                 }
9303
9304                 /* Allow 20% bad entries. */
9305                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9306                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9307                         "in directory %s\n",
9308                         num_dir_entries, usersharepath));
9309                         break;
9310                 }
9311         }
9312
9313         sys_closedir(dp);
9314
9315         /* Sweep through and delete any non-refreshed usershares that are
9316            not currently in use. */
9317         for (iService = iNumServices - 1; iService >= 0; iService--) {
9318                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9319                         if (conn_snum_used(sconn, iService)) {
9320                                 continue;
9321                         }
9322                         /* Remove from the share ACL db. */
9323                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9324                                 lp_servicename(iService) ));
9325                         delete_share_security(lp_servicename(iService));
9326                         free_service_byindex(iService);
9327                 }
9328         }
9329
9330         return lp_numservices();
9331 }
9332
9333 /********************************************************
9334  Destroy global resources allocated in this file
9335 ********************************************************/
9336
9337 void gfree_loadparm(void)
9338 {
9339         int i;
9340
9341         free_file_list();
9342
9343         /* Free resources allocated to services */
9344
9345         for ( i = 0; i < iNumServices; i++ ) {
9346                 if ( VALID(i) ) {
9347                         free_service_byindex(i);
9348                 }
9349         }
9350
9351         SAFE_FREE( ServicePtrs );
9352         iNumServices = 0;
9353
9354         /* Now release all resources allocated to global
9355            parameters and the default service */
9356
9357         free_global_parameters();
9358 }
9359
9360
9361 /***************************************************************************
9362  Allow client apps to specify that they are a client
9363 ***************************************************************************/
9364 void lp_set_in_client(bool b)
9365 {
9366     in_client = b;
9367 }
9368
9369
9370 /***************************************************************************
9371  Determine if we're running in a client app
9372 ***************************************************************************/
9373 bool lp_is_in_client(void)
9374 {
9375     return in_client;
9376 }
9377
9378 /***************************************************************************
9379  Load the services array from the services file. Return True on success, 
9380  False on failure.
9381 ***************************************************************************/
9382
9383 static bool lp_load_ex(const char *pszFname,
9384                        bool global_only,
9385                        bool save_defaults,
9386                        bool add_ipc,
9387                        bool initialize_globals,
9388                        bool allow_include_registry,
9389                        bool allow_registry_shares)
9390 {
9391         char *n2 = NULL;
9392         bool bRetval;
9393
9394         bRetval = False;
9395
9396         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9397
9398         bInGlobalSection = True;
9399         bGlobalOnly = global_only;
9400         bAllowIncludeRegistry = allow_include_registry;
9401
9402         init_globals(initialize_globals);
9403
9404         free_file_list();
9405
9406         if (save_defaults) {
9407                 init_locals();
9408                 lp_save_defaults();
9409         }
9410
9411         free_param_opts(&Globals.param_opt);
9412
9413         lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
9414
9415         /* We get sections first, so have to start 'behind' to make up */
9416         iServiceIndex = -1;
9417
9418         if (lp_config_backend_is_file()) {
9419                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9420                                         current_user_info.domain,
9421                                         pszFname);
9422                 if (!n2) {
9423                         smb_panic("lp_load_ex: out of memory");
9424                 }
9425
9426                 add_to_file_list(pszFname, n2);
9427
9428                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9429                 TALLOC_FREE(n2);
9430
9431                 /* finish up the last section */
9432                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9433                 if (bRetval) {
9434                         if (iServiceIndex >= 0) {
9435                                 bRetval = service_ok(iServiceIndex);
9436                         }
9437                 }
9438
9439                 if (lp_config_backend_is_registry()) {
9440                         /* config backend changed to registry in config file */
9441                         /*
9442                          * We need to use this extra global variable here to
9443                          * survive restart: init_globals uses this as a default
9444                          * for ConfigBackend. Otherwise, init_globals would
9445                          *  send us into an endless loop here.
9446                          */
9447                         config_backend = CONFIG_BACKEND_REGISTRY;
9448                         /* start over */
9449                         DEBUG(1, ("lp_load_ex: changing to config backend "
9450                                   "registry\n"));
9451                         init_globals(true);
9452                         lp_kill_all_services();
9453                         return lp_load_ex(pszFname, global_only, save_defaults,
9454                                           add_ipc, initialize_globals,
9455                                           allow_include_registry,
9456                                           allow_registry_shares);
9457                 }
9458         } else if (lp_config_backend_is_registry()) {
9459                 bRetval = process_registry_globals();
9460         } else {
9461                 DEBUG(0, ("Illegal config  backend given: %d\n",
9462                           lp_config_backend()));
9463                 bRetval = false;
9464         }
9465
9466         if (bRetval && lp_registry_shares() && allow_registry_shares) {
9467                 bRetval = process_registry_shares();
9468         }
9469
9470         lp_add_auto_services(lp_auto_services());
9471
9472         if (add_ipc) {
9473                 /* When 'restrict anonymous = 2' guest connections to ipc$
9474                    are denied */
9475                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9476                 if ( lp_enable_asu_support() ) {
9477                         lp_add_ipc("ADMIN$", false);
9478                 }
9479         }
9480
9481         set_server_role();
9482         set_default_server_announce_type();
9483         set_allowed_client_auth();
9484
9485         if (lp_security() == SEC_SHARE) {
9486                 DEBUG(1, ("WARNING: The security=share option is deprecated\n"));
9487         } else if (lp_security() == SEC_SERVER) {
9488                 DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
9489         }
9490
9491         if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
9492                 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
9493                           lp_passwordserver()));
9494         }
9495
9496         bLoaded = True;
9497
9498         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9499         /* if bWINSsupport is true and we are in the client            */
9500         if (lp_is_in_client() && Globals.bWINSsupport) {
9501                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9502         }
9503
9504         init_iconv();
9505
9506         fault_configure(smb_panic_s3);
9507
9508         bAllowIncludeRegistry = true;
9509
9510         return (bRetval);
9511 }
9512
9513 bool lp_load(const char *pszFname,
9514              bool global_only,
9515              bool save_defaults,
9516              bool add_ipc,
9517              bool initialize_globals)
9518 {
9519         return lp_load_ex(pszFname,
9520                           global_only,
9521                           save_defaults,
9522                           add_ipc,
9523                           initialize_globals,
9524                           true,   /* allow_include_registry */
9525                           false); /* allow_registry_shares*/
9526 }
9527
9528 bool lp_load_initial_only(const char *pszFname)
9529 {
9530         return lp_load_ex(pszFname,
9531                           true,   /* global only */
9532                           false,  /* save_defaults */
9533                           false,  /* add_ipc */
9534                           true,   /* initialize_globals */
9535                           false,  /* allow_include_registry */
9536                           false); /* allow_registry_shares*/
9537 }
9538
9539 bool lp_load_with_registry_shares(const char *pszFname,
9540                                   bool global_only,
9541                                   bool save_defaults,
9542                                   bool add_ipc,
9543                                   bool initialize_globals)
9544 {
9545         return lp_load_ex(pszFname,
9546                           global_only,
9547                           save_defaults,
9548                           add_ipc,
9549                           initialize_globals,
9550                           true,  /* allow_include_registry */
9551                           true); /* allow_registry_shares*/
9552 }
9553
9554 /***************************************************************************
9555  Return the max number of services.
9556 ***************************************************************************/
9557
9558 int lp_numservices(void)
9559 {
9560         return (iNumServices);
9561 }
9562
9563 /***************************************************************************
9564 Display the contents of the services array in human-readable form.
9565 ***************************************************************************/
9566
9567 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9568 {
9569         int iService;
9570
9571         if (show_defaults)
9572                 defaults_saved = False;
9573
9574         dump_globals(f);
9575
9576         dump_a_service(&sDefault, f);
9577
9578         for (iService = 0; iService < maxtoprint; iService++) {
9579                 fprintf(f,"\n");
9580                 lp_dump_one(f, show_defaults, iService);
9581         }
9582 }
9583
9584 /***************************************************************************
9585 Display the contents of one service in human-readable form.
9586 ***************************************************************************/
9587
9588 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9589 {
9590         if (VALID(snum)) {
9591                 if (ServicePtrs[snum]->szService[0] == '\0')
9592                         return;
9593                 dump_a_service(ServicePtrs[snum], f);
9594         }
9595 }
9596
9597 /***************************************************************************
9598 Return the number of the service with the given name, or -1 if it doesn't
9599 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9600 getservicebyname()! This works ONLY if all services have been loaded, and
9601 does not copy the found service.
9602 ***************************************************************************/
9603
9604 int lp_servicenumber(const char *pszServiceName)
9605 {
9606         int iService;
9607         fstring serviceName;
9608
9609         if (!pszServiceName) {
9610                 return GLOBAL_SECTION_SNUM;
9611         }
9612
9613         for (iService = iNumServices - 1; iService >= 0; iService--) {
9614                 if (VALID(iService) && ServicePtrs[iService]->szService) {
9615                         /*
9616                          * The substitution here is used to support %U is
9617                          * service names
9618                          */
9619                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
9620                         standard_sub_basic(get_current_username(),
9621                                            current_user_info.domain,
9622                                            serviceName,sizeof(serviceName));
9623                         if (strequal(serviceName, pszServiceName)) {
9624                                 break;
9625                         }
9626                 }
9627         }
9628
9629         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9630                 struct timespec last_mod;
9631
9632                 if (!usershare_exists(iService, &last_mod)) {
9633                         /* Remove the share security tdb entry for it. */
9634                         delete_share_security(lp_servicename(iService));
9635                         /* Remove it from the array. */
9636                         free_service_byindex(iService);
9637                         /* Doesn't exist anymore. */
9638                         return GLOBAL_SECTION_SNUM;
9639                 }
9640
9641                 /* Has it been modified ? If so delete and reload. */
9642                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9643                                      &last_mod) < 0) {
9644                         /* Remove it from the array. */
9645                         free_service_byindex(iService);
9646                         /* and now reload it. */
9647                         iService = load_usershare_service(pszServiceName);
9648                 }
9649         }
9650
9651         if (iService < 0) {
9652                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9653                 return GLOBAL_SECTION_SNUM;
9654         }
9655
9656         return (iService);
9657 }
9658
9659 bool share_defined(const char *service_name)
9660 {
9661         return (lp_servicenumber(service_name) != -1);
9662 }
9663
9664 /*******************************************************************
9665  A useful volume label function. 
9666 ********************************************************************/
9667
9668 const char *volume_label(int snum)
9669 {
9670         char *ret;
9671         const char *label = lp_volume(snum);
9672         if (!*label) {
9673                 label = lp_servicename(snum);
9674         }
9675
9676         /* This returns a 33 byte guarenteed null terminated string. */
9677         ret = talloc_strndup(talloc_tos(), label, 32);
9678         if (!ret) {
9679                 return "";
9680         }               
9681         return ret;
9682 }
9683
9684 /*******************************************************************
9685  Set the server type we will announce as via nmbd.
9686 ********************************************************************/
9687
9688 static void set_default_server_announce_type(void)
9689 {
9690         default_server_announce = 0;
9691         default_server_announce |= SV_TYPE_WORKSTATION;
9692         default_server_announce |= SV_TYPE_SERVER;
9693         default_server_announce |= SV_TYPE_SERVER_UNIX;
9694
9695         /* note that the flag should be set only if we have a 
9696            printer service but nmbd doesn't actually load the 
9697            services so we can't tell   --jerry */
9698
9699         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9700
9701         default_server_announce |= SV_TYPE_SERVER_NT;
9702         default_server_announce |= SV_TYPE_NT;
9703
9704         switch (lp_server_role()) {
9705                 case ROLE_DOMAIN_MEMBER:
9706                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9707                         break;
9708                 case ROLE_DOMAIN_PDC:
9709                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9710                         break;
9711                 case ROLE_DOMAIN_BDC:
9712                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9713                         break;
9714                 case ROLE_STANDALONE:
9715                 default:
9716                         break;
9717         }
9718         if (lp_time_server())
9719                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9720
9721         if (lp_host_msdfs())
9722                 default_server_announce |= SV_TYPE_DFS_SERVER;
9723 }
9724
9725 /***********************************************************
9726  If we are PDC then prefer us as DMB
9727 ************************************************************/
9728
9729 bool lp_domain_master(void)
9730 {
9731         if (Globals.iDomainMaster == Auto)
9732                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9733
9734         return (bool)Globals.iDomainMaster;
9735 }
9736
9737 /***********************************************************
9738  If we are PDC then prefer us as DMB
9739 ************************************************************/
9740
9741 bool lp_domain_master_true_or_auto(void)
9742 {
9743         if (Globals.iDomainMaster) /* auto or yes */
9744                 return true;
9745
9746         return false;
9747 }
9748
9749 /***********************************************************
9750  If we are DMB then prefer us as LMB
9751 ************************************************************/
9752
9753 bool lp_preferred_master(void)
9754 {
9755         if (Globals.iPreferredMaster == Auto)
9756                 return (lp_local_master() && lp_domain_master());
9757
9758         return (bool)Globals.iPreferredMaster;
9759 }
9760
9761 /*******************************************************************
9762  Remove a service.
9763 ********************************************************************/
9764
9765 void lp_remove_service(int snum)
9766 {
9767         ServicePtrs[snum]->valid = False;
9768         invalid_services[num_invalid_services++] = snum;
9769 }
9770
9771 /*******************************************************************
9772  Copy a service.
9773 ********************************************************************/
9774
9775 void lp_copy_service(int snum, const char *new_name)
9776 {
9777         do_section(new_name, NULL);
9778         if (snum >= 0) {
9779                 snum = lp_servicenumber(new_name);
9780                 if (snum >= 0)
9781                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9782         }
9783 }
9784
9785
9786 /*******************************************************************
9787  Get the default server type we will announce as via nmbd.
9788 ********************************************************************/
9789
9790 int lp_default_server_announce(void)
9791 {
9792         return default_server_announce;
9793 }
9794
9795 /***********************************************************
9796  Set the global name resolution order (used in smbclient).
9797 ************************************************************/
9798
9799 void lp_set_name_resolve_order(const char *new_order)
9800 {
9801         string_set(&Globals.szNameResolveOrder, new_order);
9802 }
9803
9804 const char *lp_printername(int snum)
9805 {
9806         const char *ret = _lp_printername(snum);
9807         if (ret == NULL || (ret != NULL && *ret == '\0'))
9808                 ret = lp_const_servicename(snum);
9809
9810         return ret;
9811 }
9812
9813
9814 /***********************************************************
9815  Allow daemons such as winbindd to fix their logfile name.
9816 ************************************************************/
9817
9818 void lp_set_logfile(const char *name)
9819 {
9820         string_set(&Globals.szLogFile, name);
9821         debug_set_logfile(name);
9822 }
9823
9824 /*******************************************************************
9825  Return the max print jobs per queue.
9826 ********************************************************************/
9827
9828 int lp_maxprintjobs(int snum)
9829 {
9830         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9831         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9832                 maxjobs = PRINT_MAX_JOBID - 1;
9833
9834         return maxjobs;
9835 }
9836
9837 const char *lp_printcapname(void)
9838 {
9839         if ((Globals.szPrintcapname != NULL) &&
9840             (Globals.szPrintcapname[0] != '\0'))
9841                 return Globals.szPrintcapname;
9842
9843         if (sDefault.iPrinting == PRINT_CUPS) {
9844 #ifdef HAVE_CUPS
9845                 return "cups";
9846 #else
9847                 return "lpstat";
9848 #endif
9849         }
9850
9851         if (sDefault.iPrinting == PRINT_BSD)
9852                 return "/etc/printcap";
9853
9854         return PRINTCAP_NAME;
9855 }
9856
9857 static uint32 spoolss_state;
9858
9859 bool lp_disable_spoolss( void )
9860 {
9861         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9862                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9863
9864         return spoolss_state == SVCCTL_STOPPED ? True : False;
9865 }
9866
9867 void lp_set_spoolss_state( uint32 state )
9868 {
9869         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9870
9871         spoolss_state = state;
9872 }
9873
9874 uint32 lp_get_spoolss_state( void )
9875 {
9876         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9877 }
9878
9879 /*******************************************************************
9880  Ensure we don't use sendfile if server smb signing is active.
9881 ********************************************************************/
9882
9883 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9884 {
9885         bool sign_active = false;
9886
9887         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9888         if (get_Protocol() < PROTOCOL_NT1) {
9889                 return false;
9890         }
9891         if (signing_state) {
9892                 sign_active = smb_signing_is_active(signing_state);
9893         }
9894         return (_lp_use_sendfile(snum) &&
9895                         (get_remote_arch() != RA_WIN95) &&
9896                         !sign_active);
9897 }
9898
9899 /*******************************************************************
9900  Turn off sendfile if we find the underlying OS doesn't support it.
9901 ********************************************************************/
9902
9903 void set_use_sendfile(int snum, bool val)
9904 {
9905         if (LP_SNUM_OK(snum))
9906                 ServicePtrs[snum]->bUseSendfile = val;
9907         else
9908                 sDefault.bUseSendfile = val;
9909 }
9910
9911 /*******************************************************************
9912  Turn off storing DOS attributes if this share doesn't support it.
9913 ********************************************************************/
9914
9915 void set_store_dos_attributes(int snum, bool val)
9916 {
9917         if (!LP_SNUM_OK(snum))
9918                 return;
9919         ServicePtrs[(snum)]->bStoreDosAttributes = val;
9920 }
9921
9922 void lp_set_mangling_method(const char *new_method)
9923 {
9924         string_set(&Globals.szManglingMethod, new_method);
9925 }
9926
9927 /*******************************************************************
9928  Global state for POSIX pathname processing.
9929 ********************************************************************/
9930
9931 static bool posix_pathnames;
9932
9933 bool lp_posix_pathnames(void)
9934 {
9935         return posix_pathnames;
9936 }
9937
9938 /*******************************************************************
9939  Change everything needed to ensure POSIX pathname processing (currently
9940  not much).
9941 ********************************************************************/
9942
9943 void lp_set_posix_pathnames(void)
9944 {
9945         posix_pathnames = True;
9946 }
9947
9948 /*******************************************************************
9949  Global state for POSIX lock processing - CIFS unix extensions.
9950 ********************************************************************/
9951
9952 bool posix_default_lock_was_set;
9953 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9954
9955 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9956 {
9957         if (posix_default_lock_was_set) {
9958                 return posix_cifsx_locktype;
9959         } else {
9960                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9961         }
9962 }
9963
9964 /*******************************************************************
9965 ********************************************************************/
9966
9967 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9968 {
9969         posix_default_lock_was_set = True;
9970         posix_cifsx_locktype = val;
9971 }
9972
9973 int lp_min_receive_file_size(void)
9974 {
9975         if (Globals.iminreceivefile < 0) {
9976                 return 0;
9977         }
9978         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9979 }
9980
9981 /*******************************************************************
9982  If socket address is an empty character string, it is necessary to 
9983  define it as "0.0.0.0". 
9984 ********************************************************************/
9985
9986 const char *lp_socket_address(void)
9987 {
9988         char *sock_addr = Globals.szSocketAddress;
9989
9990         if (sock_addr[0] == '\0'){
9991                 string_set(&Globals.szSocketAddress, "0.0.0.0");
9992         }
9993         return  Globals.szSocketAddress;
9994 }
9995
9996 void lp_set_passdb_backend(const char *backend)
9997 {
9998         string_set(&Globals.szPassdbBackend, backend);
9999 }
10000
10001 /*******************************************************************
10002  Safe wide links checks.
10003  This helper function always verify the validity of wide links,
10004  even after a configuration file reload.
10005 ********************************************************************/
10006
10007 static bool lp_widelinks_internal(int snum)
10008 {
10009         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
10010                         sDefault.bWidelinks);
10011 }
10012
10013 void widelinks_warning(int snum)
10014 {
10015         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10016                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10017                         "These parameters are incompatible. "
10018                         "Wide links will be disabled for this share.\n",
10019                         lp_servicename(snum) ));
10020         }
10021 }
10022
10023 bool lp_widelinks(int snum)
10024 {
10025         /* wide links is always incompatible with unix extensions */
10026         if (lp_unix_extensions()) {
10027                 return false;
10028         }
10029
10030         return lp_widelinks_internal(snum);
10031 }
10032
10033 bool lp_writeraw(void)
10034 {
10035         if (lp_async_smb_echo_handler()) {
10036                 return false;
10037         }
10038         return _lp_writeraw();
10039 }
10040
10041 bool lp_readraw(void)
10042 {
10043         if (lp_async_smb_echo_handler()) {
10044                 return false;
10045         }
10046         return _lp_readraw();
10047 }