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