s3-loadparm: Added some comments to lp_load_ex calls.
[ira/wip.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23
24    You should have received a copy of the GNU General Public License
25    along with this program.  If not, see <http://www.gnu.org/licenses/>.
26 */
27
28 /*
29  *  Load parameters.
30  *
31  *  This module provides suitable callback functions for the params
32  *  module. It builds the internal table of service details which is
33  *  then used by the rest of the server.
34  *
35  * To add a parameter:
36  *
37  * 1) add it to the global or service structure definition
38  * 2) add it to the parm_table
39  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40  * 4) If it's a global then initialise it in init_globals. If a local
41  *    (ie. service) parameter then initialise it in the sDefault structure
42  *  
43  *
44  * Notes:
45  *   The configuration file is processed sequentially for speed. It is NOT
46  *   accessed randomly as happens in 'real' Windows. For this reason, there
47  *   is a fair bit of sequence-dependent code here - ie., code which assumes
48  *   that certain things happen before others. In particular, the code which
49  *   happens at the boundary between sections is delicately poised, so be
50  *   careful!
51  *
52  */
53
54 #include "includes.h"
55 #include "printing.h"
56 #include "lib/smbconf/smbconf.h"
57 #include "lib/smbconf/smbconf_init.h"
58 #include "lib/smbconf/smbconf_reg.h"
59
60 #include "ads.h"
61 #include "../librpc/gen_ndr/svcctl.h"
62
63 #ifdef HAVE_SYS_SYSCTL_H
64 #include <sys/sysctl.h>
65 #endif
66
67 #ifdef HAVE_HTTPCONNECTENCRYPT
68 #include <cups/http.h>
69 #endif
70
71 bool bLoaded = False;
72
73 extern userdom_struct current_user_info;
74
75 #ifndef GLOBAL_NAME
76 #define GLOBAL_NAME "global"
77 #endif
78
79 #ifndef PRINTERS_NAME
80 #define PRINTERS_NAME "printers"
81 #endif
82
83 #ifndef HOMES_NAME
84 #define HOMES_NAME "homes"
85 #endif
86
87 /* the special value for the include parameter
88  * to be interpreted not as a file name but to
89  * trigger loading of the global smb.conf options
90  * from registry. */
91 #ifndef INCLUDE_REGISTRY_NAME
92 #define INCLUDE_REGISTRY_NAME "registry"
93 #endif
94
95 static bool in_client = False;          /* Not in the client by default */
96 static struct smbconf_csn conf_last_csn;
97
98 #define CONFIG_BACKEND_FILE 0
99 #define CONFIG_BACKEND_REGISTRY 1
100
101 static int config_backend = CONFIG_BACKEND_FILE;
102
103 /* some helpful bits */
104 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
105 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
106
107 #define USERSHARE_VALID 1
108 #define USERSHARE_PENDING_DELETE 2
109
110 static bool defaults_saved = False;
111
112 struct param_opt_struct {
113         struct param_opt_struct *prev, *next;
114         char *key;
115         char *value;
116         char **list;
117 };
118
119 /*
120  * This structure describes global (ie., server-wide) parameters.
121  */
122 struct global {
123         int ConfigBackend;
124         char *smb_ports;
125         char *dos_charset;
126         char *unix_charset;
127         char *display_charset;
128         char *szPrintcapname;
129         char *szAddPortCommand;
130         char *szEnumPortsCommand;
131         char *szAddPrinterCommand;
132         char *szDeletePrinterCommand;
133         char *szOs2DriverMap;
134         char *szLockDir;
135         char *szStateDir;
136         char *szCacheDir;
137         char *szPidDir;
138         char *szRootdir;
139         char *szDefaultService;
140         char *szGetQuota;
141         char *szSetQuota;
142         char *szMsgCommand;
143         char *szServerString;
144         char *szAutoServices;
145         char *szPasswdProgram;
146         char *szPasswdChat;
147         char *szLogFile;
148         char *szConfigFile;
149         char *szSMBPasswdFile;
150         char *szPrivateDir;
151         char *szPassdbBackend;
152         char **szPreloadModules;
153         char *szPasswordServer;
154         char *szSocketOptions;
155         char *szRealm;
156         char *szAfsUsernameMap;
157         int iAfsTokenLifetime;
158         char *szLogNtTokenCommand;
159         char *szUsernameMap;
160         char *szLogonScript;
161         char *szLogonPath;
162         char *szLogonDrive;
163         char *szLogonHome;
164         char **szWINSservers;
165         char **szInterfaces;
166         char *szRemoteAnnounce;
167         char *szRemoteBrowseSync;
168         char *szSocketAddress;
169         bool bNmbdBindExplicitBroadcast;
170         char *szNISHomeMapName;
171         char *szAnnounceVersion;        /* This is initialised in init_globals */
172         char *szWorkgroup;
173         char *szNetbiosName;
174         char **szNetbiosAliases;
175         char *szNetbiosScope;
176         char *szNameResolveOrder;
177         char *szPanicAction;
178         char *szAddUserScript;
179         char *szRenameUserScript;
180         char *szDelUserScript;
181         char *szAddGroupScript;
182         char *szDelGroupScript;
183         char *szAddUserToGroupScript;
184         char *szDelUserFromGroupScript;
185         char *szSetPrimaryGroupScript;
186         char *szAddMachineScript;
187         char *szShutdownScript;
188         char *szAbortShutdownScript;
189         char *szUsernameMapScript;
190         int iUsernameMapCacheTime;
191         char *szCheckPasswordScript;
192         char *szWINSHook;
193         char *szUtmpDir;
194         char *szWtmpDir;
195         bool bUtmp;
196         char *szIdmapUID;
197         char *szIdmapGID;
198         bool bPassdbExpandExplicit;
199         int AlgorithmicRidBase;
200         char *szTemplateHomedir;
201         char *szTemplateShell;
202         char *szWinbindSeparator;
203         bool bWinbindEnumUsers;
204         bool bWinbindEnumGroups;
205         bool bWinbindUseDefaultDomain;
206         bool bWinbindTrustedDomainsOnly;
207         bool bWinbindNestedGroups;
208         int  winbind_expand_groups;
209         bool bWinbindRefreshTickets;
210         bool bWinbindOfflineLogon;
211         bool bWinbindNormalizeNames;
212         bool bWinbindRpcOnly;
213         bool bCreateKrb5Conf;
214         char *szIdmapBackend;
215         char *szIdmapAllocBackend;
216         char *szAddShareCommand;
217         char *szChangeShareCommand;
218         char *szDeleteShareCommand;
219         char **szEventLogs;
220         char *szGuestaccount;
221         char *szManglingMethod;
222         char **szServicesList;
223         char *szUsersharePath;
224         char *szUsershareTemplateShare;
225         char **szUsersharePrefixAllowList;
226         char **szUsersharePrefixDenyList;
227         int mangle_prefix;
228         int max_log_size;
229         char *szLogLevel;
230         int max_xmit;
231         int max_mux;
232         int max_open_files;
233         int open_files_db_hash_size;
234         int pwordlevel;
235         int unamelevel;
236         int deadtime;
237         bool getwd_cache;
238         int maxprotocol;
239         int minprotocol;
240         int security;
241         char **AuthMethods;
242         bool paranoid_server_security;
243         int maxdisksize;
244         int lpqcachetime;
245         int iMaxSmbdProcesses;
246         bool bDisableSpoolss;
247         int syslog;
248         int os_level;
249         bool enhanced_browsing;
250         int max_ttl;
251         int max_wins_ttl;
252         int min_wins_ttl;
253         int lm_announce;
254         int lm_interval;
255         int announce_as;        /* This is initialised in init_globals */
256         int machine_password_timeout;
257         int map_to_guest;
258         int oplock_break_wait_time;
259         int winbind_cache_time;
260         int winbind_reconnect_delay;
261         int winbind_max_idle_children;
262         char **szWinbindNssInfo;
263         int iLockSpinTime;
264         char *szLdapMachineSuffix;
265         char *szLdapUserSuffix;
266         char *szLdapIdmapSuffix;
267         char *szLdapGroupSuffix;
268         int ldap_ssl;
269         bool ldap_ssl_ads;
270         int ldap_deref;
271         int ldap_follow_referral;
272         char *szLdapSuffix;
273         char *szLdapAdminDn;
274         int ldap_debug_level;
275         int ldap_debug_threshold;
276         int iAclCompat;
277         char *szCupsServer;
278         int CupsEncrypt;
279         char *szIPrintServer;
280         char *ctdbdSocket;
281         char **szClusterAddresses;
282         bool clustering;
283         int ctdb_timeout;
284         int ctdb_locktime_warn_threshold;
285         int ldap_passwd_sync;
286         int ldap_replication_sleep;
287         int ldap_timeout; /* This is initialised in init_globals */
288         int ldap_connection_timeout;
289         int ldap_page_size;
290         bool ldap_delete_dn;
291         bool bMsAddPrinterWizard;
292         bool bDNSproxy;
293         bool bWINSsupport;
294         bool bWINSproxy;
295         bool bLocalMaster;
296         int  iPreferredMaster;
297         int iDomainMaster;
298         bool bDomainLogons;
299         char **szInitLogonDelayedHosts;
300         int InitLogonDelay;
301         bool bEncryptPasswords;
302         bool bUpdateEncrypt;
303         int  clientSchannel;
304         int  serverSchannel;
305         bool bNullPasswords;
306         bool bObeyPamRestrictions;
307         bool bLoadPrinters;
308         int PrintcapCacheTime;
309         bool bLargeReadwrite;
310         bool bReadRaw;
311         bool bWriteRaw;
312         bool bSyslogOnly;
313         bool bBrowseList;
314         bool bNISHomeMap;
315         bool bTimeServer;
316         bool bBindInterfacesOnly;
317         bool bPamPasswordChange;
318         bool bUnixPasswdSync;
319         bool bPasswdChatDebug;
320         int iPasswdChatTimeout;
321         bool bTimestampLogs;
322         bool bNTSmbSupport;
323         bool bNTPipeSupport;
324         bool bNTStatusSupport;
325         bool bStatCache;
326         int iMaxStatCacheSize;
327         bool bKernelOplocks;
328         bool bAllowTrustedDomains;
329         bool bLanmanAuth;
330         bool bNTLMAuth;
331         bool bUseSpnego;
332         bool bClientLanManAuth;
333         bool bClientNTLMv2Auth;
334         bool bClientPlaintextAuth;
335         bool bClientUseSpnego;
336         bool bDebugPrefixTimestamp;
337         bool bDebugHiresTimestamp;
338         bool bDebugPid;
339         bool bDebugUid;
340         bool bDebugClass;
341         bool bEnableCoreFiles;
342         bool bHostMSDfs;
343         bool bUseMmap;
344         bool bHostnameLookups;
345         bool bUnixExtensions;
346         bool bDisableNetbios;
347         char * szDedicatedKeytabFile;
348         int  iKerberosMethod;
349         bool bDeferSharingViolations;
350         bool bEnablePrivileges;
351         bool bASUSupport;
352         bool bUsershareOwnerOnly;
353         bool bUsershareAllowGuests;
354         bool bRegistryShares;
355         int restrict_anonymous;
356         int name_cache_timeout;
357         int client_signing;
358         int server_signing;
359         int client_ldap_sasl_wrapping;
360         int iUsershareMaxShares;
361         int iIdmapCacheTime;
362         int iIdmapNegativeCacheTime;
363         bool bResetOnZeroVC;
364         bool bLogWriteableFilesOnExit;
365         int iKeepalive;
366         int iminreceivefile;
367         struct param_opt_struct *param_opt;
368         int cups_connection_timeout;
369         char *szSMBPerfcountModule;
370         bool bMapUntrustedToDomain;
371         bool bAsyncSMBEchoHandler;
372         int ismb2_max_read;
373         int ismb2_max_write;
374         int ismb2_max_trans;
375 };
376
377 static struct global Globals;
378
379 /*
380  * This structure describes a single service.
381  */
382 struct service {
383         bool valid;
384         bool autoloaded;
385         int usershare;
386         struct timespec usershare_last_mod;
387         char *szService;
388         char *szPath;
389         char *szUsername;
390         char **szInvalidUsers;
391         char **szValidUsers;
392         char **szAdminUsers;
393         char *szCopy;
394         char *szInclude;
395         char *szPreExec;
396         char *szPostExec;
397         char *szRootPreExec;
398         char *szRootPostExec;
399         char *szCupsOptions;
400         char *szPrintcommand;
401         char *szLpqcommand;
402         char *szLprmcommand;
403         char *szLppausecommand;
404         char *szLpresumecommand;
405         char *szQueuepausecommand;
406         char *szQueueresumecommand;
407         char *szPrintername;
408         char *szPrintjobUsername;
409         char *szDontdescend;
410         char **szHostsallow;
411         char **szHostsdeny;
412         char *szMagicScript;
413         char *szMagicOutput;
414         char *szVetoFiles;
415         char *szHideFiles;
416         char *szVetoOplockFiles;
417         char *comment;
418         char *force_user;
419         char *force_group;
420         char **readlist;
421         char **writelist;
422         char **printer_admin;
423         char *volume;
424         char *fstype;
425         char **szVfsObjects;
426         char *szMSDfsProxy;
427         char *szAioWriteBehind;
428         char *szDfree;
429         int iMinPrintSpace;
430         int iMaxPrintJobs;
431         int iMaxReportedPrintJobs;
432         int iWriteCacheSize;
433         int iCreate_mask;
434         int iCreate_force_mode;
435         int iSecurity_mask;
436         int iSecurity_force_mode;
437         int iDir_mask;
438         int iDir_force_mode;
439         int iDir_Security_mask;
440         int iDir_Security_force_mode;
441         int iMaxConnections;
442         int iDefaultCase;
443         int iPrinting;
444         int iOplockContentionLimit;
445         int iCSCPolicy;
446         int iBlock_size;
447         int iDfreeCacheTime;
448         bool bPreexecClose;
449         bool bRootpreexecClose;
450         int  iCaseSensitive;
451         bool bCasePreserve;
452         bool bShortCasePreserve;
453         bool bHideDotFiles;
454         bool bHideSpecialFiles;
455         bool bHideUnReadable;
456         bool bHideUnWriteableFiles;
457         bool bBrowseable;
458         bool bAccessBasedShareEnum;
459         bool bAvailable;
460         bool bRead_only;
461         bool bNo_set_dir;
462         bool bGuest_only;
463         bool bAdministrative_share;
464         bool bGuest_ok;
465         bool bPrint_ok;
466         bool bMap_system;
467         bool bMap_hidden;
468         bool bMap_archive;
469         bool bStoreDosAttributes;
470         bool bDmapiSupport;
471         bool bLocking;
472         int iStrictLocking;
473         bool bPosixLocking;
474         bool bShareModes;
475         bool bOpLocks;
476         bool bLevel2OpLocks;
477         bool bOnlyUser;
478         bool bMangledNames;
479         bool bWidelinks;
480         bool bSymlinks;
481         bool bSyncAlways;
482         bool bStrictAllocate;
483         bool bStrictSync;
484         char magic_char;
485         struct bitmap *copymap;
486         bool bDeleteReadonly;
487         bool bFakeOplocks;
488         bool bDeleteVetoFiles;
489         bool bDosFilemode;
490         bool bDosFiletimes;
491         bool bDosFiletimeResolution;
492         bool bFakeDirCreateTimes;
493         bool bBlockingLocks;
494         bool bInheritPerms;
495         bool bInheritACLS;
496         bool bInheritOwner;
497         bool bMSDfsRoot;
498         bool bUseClientDriver;
499         bool bDefaultDevmode;
500         bool bForcePrintername;
501         bool bNTAclSupport;
502         bool bForceUnknownAclUser;
503         bool bUseSendfile;
504         bool bProfileAcls;
505         bool bMap_acl_inherit;
506         bool bAfs_Share;
507         bool bEASupport;
508         bool bAclCheckPermissions;
509         bool bAclMapFullControl;
510         bool bAclGroupControl;
511         bool bChangeNotify;
512         bool bKernelChangeNotify;
513         int iallocation_roundup_size;
514         int iAioReadSize;
515         int iAioWriteSize;
516         int iMap_readonly;
517         int iDirectoryNameCacheSize;
518         int ismb_encrypt;
519         struct param_opt_struct *param_opt;
520
521         char dummy[3];          /* for alignment */
522 };
523
524
525 /* This is a default service used to prime a services structure */
526 static struct service sDefault = {
527         True,                   /* valid */
528         False,                  /* not autoloaded */
529         0,                      /* not a usershare */
530         {0, },                  /* No last mod time */
531         NULL,                   /* szService */
532         NULL,                   /* szPath */
533         NULL,                   /* szUsername */
534         NULL,                   /* szInvalidUsers */
535         NULL,                   /* szValidUsers */
536         NULL,                   /* szAdminUsers */
537         NULL,                   /* szCopy */
538         NULL,                   /* szInclude */
539         NULL,                   /* szPreExec */
540         NULL,                   /* szPostExec */
541         NULL,                   /* szRootPreExec */
542         NULL,                   /* szRootPostExec */
543         NULL,                   /* szCupsOptions */
544         NULL,                   /* szPrintcommand */
545         NULL,                   /* szLpqcommand */
546         NULL,                   /* szLprmcommand */
547         NULL,                   /* szLppausecommand */
548         NULL,                   /* szLpresumecommand */
549         NULL,                   /* szQueuepausecommand */
550         NULL,                   /* szQueueresumecommand */
551         NULL,                   /* szPrintername */
552         NULL,                   /* szPrintjobUsername */
553         NULL,                   /* szDontdescend */
554         NULL,                   /* szHostsallow */
555         NULL,                   /* szHostsdeny */
556         NULL,                   /* szMagicScript */
557         NULL,                   /* szMagicOutput */
558         NULL,                   /* szVetoFiles */
559         NULL,                   /* szHideFiles */
560         NULL,                   /* szVetoOplockFiles */
561         NULL,                   /* comment */
562         NULL,                   /* force user */
563         NULL,                   /* force group */
564         NULL,                   /* readlist */
565         NULL,                   /* writelist */
566         NULL,                   /* printer admin */
567         NULL,                   /* volume */
568         NULL,                   /* fstype */
569         NULL,                   /* vfs objects */
570         NULL,                   /* szMSDfsProxy */
571         NULL,                   /* szAioWriteBehind */
572         NULL,                   /* szDfree */
573         0,                      /* iMinPrintSpace */
574         1000,                   /* iMaxPrintJobs */
575         0,                      /* iMaxReportedPrintJobs */
576         0,                      /* iWriteCacheSize */
577         0744,                   /* iCreate_mask */
578         0000,                   /* iCreate_force_mode */
579         0777,                   /* iSecurity_mask */
580         0,                      /* iSecurity_force_mode */
581         0755,                   /* iDir_mask */
582         0000,                   /* iDir_force_mode */
583         0777,                   /* iDir_Security_mask */
584         0,                      /* iDir_Security_force_mode */
585         0,                      /* iMaxConnections */
586         CASE_LOWER,             /* iDefaultCase */
587         DEFAULT_PRINTING,       /* iPrinting */
588         2,                      /* iOplockContentionLimit */
589         0,                      /* iCSCPolicy */
590         1024,                   /* iBlock_size */
591         0,                      /* iDfreeCacheTime */
592         False,                  /* bPreexecClose */
593         False,                  /* bRootpreexecClose */
594         Auto,                   /* case sensitive */
595         True,                   /* case preserve */
596         True,                   /* short case preserve */
597         True,                   /* bHideDotFiles */
598         False,                  /* bHideSpecialFiles */
599         False,                  /* bHideUnReadable */
600         False,                  /* bHideUnWriteableFiles */
601         True,                   /* bBrowseable */
602         False,                  /* bAccessBasedShareEnum */
603         True,                   /* bAvailable */
604         True,                   /* bRead_only */
605         True,                   /* bNo_set_dir */
606         False,                  /* bGuest_only */
607         False,                  /* bAdministrative_share */
608         False,                  /* bGuest_ok */
609         False,                  /* bPrint_ok */
610         False,                  /* bMap_system */
611         False,                  /* bMap_hidden */
612         True,                   /* bMap_archive */
613         False,                  /* bStoreDosAttributes */
614         False,                  /* bDmapiSupport */
615         True,                   /* bLocking */
616         Auto,                   /* iStrictLocking */
617         True,                   /* bPosixLocking */
618         True,                   /* bShareModes */
619         True,                   /* bOpLocks */
620         True,                   /* bLevel2OpLocks */
621         False,                  /* bOnlyUser */
622         True,                   /* bMangledNames */
623         false,                  /* bWidelinks */
624         True,                   /* bSymlinks */
625         False,                  /* bSyncAlways */
626         False,                  /* bStrictAllocate */
627         False,                  /* bStrictSync */
628         '~',                    /* magic char */
629         NULL,                   /* copymap */
630         False,                  /* bDeleteReadonly */
631         False,                  /* bFakeOplocks */
632         False,                  /* bDeleteVetoFiles */
633         False,                  /* bDosFilemode */
634         True,                   /* bDosFiletimes */
635         False,                  /* bDosFiletimeResolution */
636         False,                  /* bFakeDirCreateTimes */
637         True,                   /* bBlockingLocks */
638         False,                  /* bInheritPerms */
639         False,                  /* bInheritACLS */
640         False,                  /* bInheritOwner */
641         False,                  /* bMSDfsRoot */
642         False,                  /* bUseClientDriver */
643         True,                   /* bDefaultDevmode */
644         False,                  /* bForcePrintername */
645         True,                   /* bNTAclSupport */
646         False,                  /* bForceUnknownAclUser */
647         False,                  /* bUseSendfile */
648         False,                  /* bProfileAcls */
649         False,                  /* bMap_acl_inherit */
650         False,                  /* bAfs_Share */
651         False,                  /* bEASupport */
652         True,                   /* bAclCheckPermissions */
653         True,                   /* bAclMapFullControl */
654         False,                  /* bAclGroupControl */
655         True,                   /* bChangeNotify */
656         True,                   /* bKernelChangeNotify */
657         SMB_ROUNDUP_ALLOCATION_SIZE,            /* iallocation_roundup_size */
658         0,                      /* iAioReadSize */
659         0,                      /* iAioWriteSize */
660         MAP_READONLY_YES,       /* iMap_readonly */
661 #ifdef BROKEN_DIRECTORY_HANDLING
662         0,                      /* iDirectoryNameCacheSize */
663 #else
664         100,                    /* iDirectoryNameCacheSize */
665 #endif
666         Auto,                   /* ismb_encrypt */
667         NULL,                   /* Parametric options */
668
669         ""                      /* dummy */
670 };
671
672 /* local variables */
673 static struct service **ServicePtrs = NULL;
674 static int iNumServices = 0;
675 static int iServiceIndex = 0;
676 static struct db_context *ServiceHash;
677 static int *invalid_services = NULL;
678 static int num_invalid_services = 0;
679 static bool bInGlobalSection = True;
680 static bool bGlobalOnly = False;
681 static int default_server_announce;
682
683 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
684
685 /* prototypes for the special type handlers */
686 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
687 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
688 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
689 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
690 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
691 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
692 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
693 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
694 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
695 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
696 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
697 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
698
699 static void set_default_server_announce_type(void);
700 static void set_allowed_client_auth(void);
701
702 static void *lp_local_ptr(struct service *service, void *ptr);
703
704 static void add_to_file_list(const char *fname, const char *subfname);
705
706 static const struct enum_list enum_protocol[] = {
707         {PROTOCOL_SMB2, "SMB2"},
708         {PROTOCOL_NT1, "NT1"},
709         {PROTOCOL_LANMAN2, "LANMAN2"},
710         {PROTOCOL_LANMAN1, "LANMAN1"},
711         {PROTOCOL_CORE, "CORE"},
712         {PROTOCOL_COREPLUS, "COREPLUS"},
713         {PROTOCOL_COREPLUS, "CORE+"},
714         {-1, NULL}
715 };
716
717 static const struct enum_list enum_security[] = {
718         {SEC_SHARE, "SHARE"},
719         {SEC_USER, "USER"},
720         {SEC_SERVER, "SERVER"},
721         {SEC_DOMAIN, "DOMAIN"},
722 #ifdef HAVE_ADS
723         {SEC_ADS, "ADS"},
724 #endif
725         {-1, NULL}
726 };
727
728 static const struct enum_list enum_printing[] = {
729         {PRINT_SYSV, "sysv"},
730         {PRINT_AIX, "aix"},
731         {PRINT_HPUX, "hpux"},
732         {PRINT_BSD, "bsd"},
733         {PRINT_QNX, "qnx"},
734         {PRINT_PLP, "plp"},
735         {PRINT_LPRNG, "lprng"},
736         {PRINT_CUPS, "cups"},
737         {PRINT_IPRINT, "iprint"},
738         {PRINT_LPRNT, "nt"},
739         {PRINT_LPROS2, "os2"},
740 #ifdef DEVELOPER
741         {PRINT_TEST, "test"},
742         {PRINT_VLP, "vlp"},
743 #endif /* DEVELOPER */
744         {-1, NULL}
745 };
746
747 static const struct enum_list enum_ldap_sasl_wrapping[] = {
748         {0, "plain"},
749         {ADS_AUTH_SASL_SIGN, "sign"},
750         {ADS_AUTH_SASL_SEAL, "seal"},
751         {-1, NULL}
752 };
753
754 static const struct enum_list enum_ldap_ssl[] = {
755         {LDAP_SSL_OFF, "no"},
756         {LDAP_SSL_OFF, "off"},
757         {LDAP_SSL_START_TLS, "start tls"},
758         {LDAP_SSL_START_TLS, "start_tls"},
759         {-1, NULL}
760 };
761
762 /* LDAP Dereferencing Alias types */
763 #define SAMBA_LDAP_DEREF_NEVER          0
764 #define SAMBA_LDAP_DEREF_SEARCHING      1
765 #define SAMBA_LDAP_DEREF_FINDING        2
766 #define SAMBA_LDAP_DEREF_ALWAYS         3
767
768 static const struct enum_list enum_ldap_deref[] = {
769         {SAMBA_LDAP_DEREF_NEVER, "never"},
770         {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
771         {SAMBA_LDAP_DEREF_FINDING, "finding"},
772         {SAMBA_LDAP_DEREF_ALWAYS, "always"},
773         {-1, "auto"}
774 };
775
776 static const struct enum_list enum_ldap_passwd_sync[] = {
777         {LDAP_PASSWD_SYNC_OFF, "no"},
778         {LDAP_PASSWD_SYNC_OFF, "off"},
779         {LDAP_PASSWD_SYNC_ON, "yes"},
780         {LDAP_PASSWD_SYNC_ON, "on"},
781         {LDAP_PASSWD_SYNC_ONLY, "only"},
782         {-1, NULL}
783 };
784
785 /* Types of machine we can announce as. */
786 #define ANNOUNCE_AS_NT_SERVER 1
787 #define ANNOUNCE_AS_WIN95 2
788 #define ANNOUNCE_AS_WFW 3
789 #define ANNOUNCE_AS_NT_WORKSTATION 4
790
791 static const struct enum_list enum_announce_as[] = {
792         {ANNOUNCE_AS_NT_SERVER, "NT"},
793         {ANNOUNCE_AS_NT_SERVER, "NT Server"},
794         {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
795         {ANNOUNCE_AS_WIN95, "win95"},
796         {ANNOUNCE_AS_WFW, "WfW"},
797         {-1, NULL}
798 };
799
800 static const struct enum_list enum_map_readonly[] = {
801         {MAP_READONLY_NO, "no"},
802         {MAP_READONLY_NO, "false"},
803         {MAP_READONLY_NO, "0"},
804         {MAP_READONLY_YES, "yes"},
805         {MAP_READONLY_YES, "true"},
806         {MAP_READONLY_YES, "1"},
807         {MAP_READONLY_PERMISSIONS, "permissions"},
808         {MAP_READONLY_PERMISSIONS, "perms"},
809         {-1, NULL}
810 };
811
812 static const struct enum_list enum_case[] = {
813         {CASE_LOWER, "lower"},
814         {CASE_UPPER, "upper"},
815         {-1, NULL}
816 };
817
818
819
820 static const struct enum_list enum_bool_auto[] = {
821         {False, "No"},
822         {False, "False"},
823         {False, "0"},
824         {True, "Yes"},
825         {True, "True"},
826         {True, "1"},
827         {Auto, "Auto"},
828         {-1, NULL}
829 };
830
831 static const struct enum_list enum_csc_policy[] = {
832         {CSC_POLICY_MANUAL, "manual"},
833         {CSC_POLICY_DOCUMENTS, "documents"},
834         {CSC_POLICY_PROGRAMS, "programs"},
835         {CSC_POLICY_DISABLE, "disable"},
836         {-1, NULL}
837 };
838
839 /* SMB signing types. */
840 static const struct enum_list enum_smb_signing_vals[] = {
841         {False, "No"},
842         {False, "False"},
843         {False, "0"},
844         {False, "Off"},
845         {False, "disabled"},
846         {True, "Yes"},
847         {True, "True"},
848         {True, "1"},
849         {True, "On"},
850         {True, "enabled"},
851         {Auto, "auto"},
852         {Required, "required"},
853         {Required, "mandatory"},
854         {Required, "force"},
855         {Required, "forced"},
856         {Required, "enforced"},
857         {-1, NULL}
858 };
859
860 /* ACL compatibility options. */
861 static const struct enum_list enum_acl_compat_vals[] = {
862     { ACL_COMPAT_AUTO, "auto" },
863     { ACL_COMPAT_WINNT, "winnt" },
864     { ACL_COMPAT_WIN2K, "win2k" },
865     { -1, NULL}
866 };
867
868 /* 
869    Do you want session setups at user level security with a invalid
870    password to be rejected or allowed in as guest? WinNT rejects them
871    but it can be a pain as it means "net view" needs to use a password
872
873    You have 3 choices in the setting of map_to_guest:
874
875    "Never" means session setups with an invalid password
876    are rejected. This is the default.
877
878    "Bad User" means session setups with an invalid password
879    are rejected, unless the username does not exist, in which case it
880    is treated as a guest login
881
882    "Bad Password" means session setups with an invalid password
883    are treated as a guest login
884
885    Note that map_to_guest only has an effect in user or server
886    level security.
887 */
888
889 static const struct enum_list enum_map_to_guest[] = {
890         {NEVER_MAP_TO_GUEST, "Never"},
891         {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
892         {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
893         {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
894         {-1, NULL}
895 };
896
897 /* Config backend options */
898
899 static const struct enum_list enum_config_backend[] = {
900         {CONFIG_BACKEND_FILE, "file"},
901         {CONFIG_BACKEND_REGISTRY, "registry"},
902         {-1, NULL}
903 };
904
905 /* ADS kerberos ticket verification options */
906
907 static const struct enum_list enum_kerberos_method[] = {
908         {KERBEROS_VERIFY_SECRETS, "default"},
909         {KERBEROS_VERIFY_SECRETS, "secrets only"},
910         {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
911         {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
912         {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
913         {-1, NULL}
914 };
915
916 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
917  *
918  * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
919  * screen in SWAT. This is used to exclude parameters as well as to squash all
920  * parameters that have been duplicated by pseudonyms.
921  *
922  * NOTE: To display a parameter in BASIC view set FLAG_BASIC
923  *       Any parameter that does NOT have FLAG_ADVANCED will not disply at all
924  *       Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
925  *        respective views.
926  *
927  * NOTE2: Handling of duplicated (synonym) parameters:
928  *      Only the first occurance of a parameter should be enabled by FLAG_BASIC
929  *      and/or FLAG_ADVANCED. All duplicates following the first mention should be
930  *      set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
931  *      name first, and all synonyms must follow it with the FLAG_HIDE attribute.
932  */
933
934 static struct parm_struct parm_table[] = {
935         {N_("Base Options"), P_SEP, P_SEPARATOR},
936
937         {
938                 .label          = "dos charset",
939                 .type           = P_STRING,
940                 .p_class        = P_GLOBAL,
941                 .ptr            = &Globals.dos_charset,
942                 .special        = handle_charset,
943                 .enum_list      = NULL,
944                 .flags          = FLAG_ADVANCED
945         },
946         {
947                 .label          = "unix charset",
948                 .type           = P_STRING,
949                 .p_class        = P_GLOBAL,
950                 .ptr            = &Globals.unix_charset,
951                 .special        = handle_charset,
952                 .enum_list      = NULL,
953                 .flags          = FLAG_ADVANCED
954         },
955         {
956                 .label          = "display charset",
957                 .type           = P_STRING,
958                 .p_class        = P_GLOBAL,
959                 .ptr            = &Globals.display_charset,
960                 .special        = handle_charset,
961                 .enum_list      = NULL,
962                 .flags          = FLAG_ADVANCED
963         },
964         {
965                 .label          = "comment",
966                 .type           = P_STRING,
967                 .p_class        = P_LOCAL,
968                 .ptr            = &sDefault.comment,
969                 .special        = NULL,
970                 .enum_list      = NULL,
971                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
972         },
973         {
974                 .label          = "path",
975                 .type           = P_STRING,
976                 .p_class        = P_LOCAL,
977                 .ptr            = &sDefault.szPath,
978                 .special        = NULL,
979                 .enum_list      = NULL,
980                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
981         },
982         {
983                 .label          = "directory",
984                 .type           = P_STRING,
985                 .p_class        = P_LOCAL,
986                 .ptr            = &sDefault.szPath,
987                 .special        = NULL,
988                 .enum_list      = NULL,
989                 .flags          = FLAG_HIDE,
990         },
991         {
992                 .label          = "workgroup",
993                 .type           = P_USTRING,
994                 .p_class        = P_GLOBAL,
995                 .ptr            = &Globals.szWorkgroup,
996                 .special        = handle_workgroup,
997                 .enum_list      = NULL,
998                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
999         },
1000 #ifdef WITH_ADS
1001         {
1002                 .label          = "realm",
1003                 .type           = P_USTRING,
1004                 .p_class        = P_GLOBAL,
1005                 .ptr            = &Globals.szRealm,
1006                 .special        = NULL,
1007                 .enum_list      = NULL,
1008                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1009         },
1010 #endif
1011         {
1012                 .label          = "netbios name",
1013                 .type           = P_USTRING,
1014                 .p_class        = P_GLOBAL,
1015                 .ptr            = &Globals.szNetbiosName,
1016                 .special        = handle_netbios_name,
1017                 .enum_list      = NULL,
1018                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1019         },
1020         {
1021                 .label          = "netbios aliases",
1022                 .type           = P_LIST,
1023                 .p_class        = P_GLOBAL,
1024                 .ptr            = &Globals.szNetbiosAliases,
1025                 .special        = handle_netbios_aliases,
1026                 .enum_list      = NULL,
1027                 .flags          = FLAG_ADVANCED,
1028         },
1029         {
1030                 .label          = "netbios scope",
1031                 .type           = P_USTRING,
1032                 .p_class        = P_GLOBAL,
1033                 .ptr            = &Globals.szNetbiosScope,
1034                 .special        = handle_netbios_scope,
1035                 .enum_list      = NULL,
1036                 .flags          = FLAG_ADVANCED,
1037         },
1038         {
1039                 .label          = "server string",
1040                 .type           = P_STRING,
1041                 .p_class        = P_GLOBAL,
1042                 .ptr            = &Globals.szServerString,
1043                 .special        = NULL,
1044                 .enum_list      = NULL,
1045                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
1046         },
1047         {
1048                 .label          = "interfaces",
1049                 .type           = P_LIST,
1050                 .p_class        = P_GLOBAL,
1051                 .ptr            = &Globals.szInterfaces,
1052                 .special        = NULL,
1053                 .enum_list      = NULL,
1054                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1055         },
1056         {
1057                 .label          = "bind interfaces only",
1058                 .type           = P_BOOL,
1059                 .p_class        = P_GLOBAL,
1060                 .ptr            = &Globals.bBindInterfacesOnly,
1061                 .special        = NULL,
1062                 .enum_list      = NULL,
1063                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
1064         },
1065         {
1066                 .label          = "config backend",
1067                 .type           = P_ENUM,
1068                 .p_class        = P_GLOBAL,
1069                 .ptr            = &Globals.ConfigBackend,
1070                 .special        = NULL,
1071                 .enum_list      = enum_config_backend,
1072                 .flags          = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1073         },
1074
1075         {N_("Security Options"), P_SEP, P_SEPARATOR},
1076
1077         {
1078                 .label          = "security",
1079                 .type           = P_ENUM,
1080                 .p_class        = P_GLOBAL,
1081                 .ptr            = &Globals.security,
1082                 .special        = NULL,
1083                 .enum_list      = enum_security,
1084                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1085         },
1086         {
1087                 .label          = "auth methods",
1088                 .type           = P_LIST,
1089                 .p_class        = P_GLOBAL,
1090                 .ptr            = &Globals.AuthMethods,
1091                 .special        = NULL,
1092                 .enum_list      = NULL,
1093                 .flags          = FLAG_ADVANCED,
1094         },
1095         {
1096                 .label          = "encrypt passwords",
1097                 .type           = P_BOOL,
1098                 .p_class        = P_GLOBAL,
1099                 .ptr            = &Globals.bEncryptPasswords,
1100                 .special        = NULL,
1101                 .enum_list      = NULL,
1102                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1103         },
1104         {
1105                 .label          = "update encrypted",
1106                 .type           = P_BOOL,
1107                 .p_class        = P_GLOBAL,
1108                 .ptr            = &Globals.bUpdateEncrypt,
1109                 .special        = NULL,
1110                 .enum_list      = NULL,
1111                 .flags          = FLAG_ADVANCED,
1112         },
1113         {
1114                 .label          = "client schannel",
1115                 .type           = P_ENUM,
1116                 .p_class        = P_GLOBAL,
1117                 .ptr            = &Globals.clientSchannel,
1118                 .special        = NULL,
1119                 .enum_list      = enum_bool_auto,
1120                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
1121         },
1122         {
1123                 .label          = "server schannel",
1124                 .type           = P_ENUM,
1125                 .p_class        = P_GLOBAL,
1126                 .ptr            = &Globals.serverSchannel,
1127                 .special        = NULL,
1128                 .enum_list      = enum_bool_auto,
1129                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
1130         },
1131         {
1132                 .label          = "allow trusted domains",
1133                 .type           = P_BOOL,
1134                 .p_class        = P_GLOBAL,
1135                 .ptr            = &Globals.bAllowTrustedDomains,
1136                 .special        = NULL,
1137                 .enum_list      = NULL,
1138                 .flags          = FLAG_ADVANCED,
1139         },
1140         {
1141                 .label          = "map to guest",
1142                 .type           = P_ENUM,
1143                 .p_class        = P_GLOBAL,
1144                 .ptr            = &Globals.map_to_guest,
1145                 .special        = NULL,
1146                 .enum_list      = enum_map_to_guest,
1147                 .flags          = FLAG_ADVANCED,
1148         },
1149         {
1150                 .label          = "null passwords",
1151                 .type           = P_BOOL,
1152                 .p_class        = P_GLOBAL,
1153                 .ptr            = &Globals.bNullPasswords,
1154                 .special        = NULL,
1155                 .enum_list      = NULL,
1156                 .flags          = FLAG_ADVANCED,
1157         },
1158         {
1159                 .label          = "obey pam restrictions",
1160                 .type           = P_BOOL,
1161                 .p_class        = P_GLOBAL,
1162                 .ptr            = &Globals.bObeyPamRestrictions,
1163                 .special        = NULL,
1164                 .enum_list      = NULL,
1165                 .flags          = FLAG_ADVANCED,
1166         },
1167         {
1168                 .label          = "password server",
1169                 .type           = P_STRING,
1170                 .p_class        = P_GLOBAL,
1171                 .ptr            = &Globals.szPasswordServer,
1172                 .special        = NULL,
1173                 .enum_list      = NULL,
1174                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
1175         },
1176         {
1177                 .label          = "smb passwd file",
1178                 .type           = P_STRING,
1179                 .p_class        = P_GLOBAL,
1180                 .ptr            = &Globals.szSMBPasswdFile,
1181                 .special        = NULL,
1182                 .enum_list      = NULL,
1183                 .flags          = FLAG_ADVANCED,
1184         },
1185         {
1186                 .label          = "private dir",
1187                 .type           = P_STRING,
1188                 .p_class        = P_GLOBAL,
1189                 .ptr            = &Globals.szPrivateDir,
1190                 .special        = NULL,
1191                 .enum_list      = NULL,
1192                 .flags          = FLAG_ADVANCED,
1193         },
1194         {
1195                 .label          = "passdb backend",
1196                 .type           = P_STRING,
1197                 .p_class        = P_GLOBAL,
1198                 .ptr            = &Globals.szPassdbBackend,
1199                 .special        = NULL,
1200                 .enum_list      = NULL,
1201                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
1202         },
1203         {
1204                 .label          = "algorithmic rid base",
1205                 .type           = P_INTEGER,
1206                 .p_class        = P_GLOBAL,
1207                 .ptr            = &Globals.AlgorithmicRidBase,
1208                 .special        = NULL,
1209                 .enum_list      = NULL,
1210                 .flags          = FLAG_ADVANCED,
1211         },
1212         {
1213                 .label          = "root directory",
1214                 .type           = P_STRING,
1215                 .p_class        = P_GLOBAL,
1216                 .ptr            = &Globals.szRootdir,
1217                 .special        = NULL,
1218                 .enum_list      = NULL,
1219                 .flags          = FLAG_ADVANCED,
1220         },
1221         {
1222                 .label          = "root dir",
1223                 .type           = P_STRING,
1224                 .p_class        = P_GLOBAL,
1225                 .ptr            = &Globals.szRootdir,
1226                 .special        = NULL,
1227                 .enum_list      = NULL,
1228                 .flags          = FLAG_HIDE,
1229         },
1230         {
1231                 .label          = "root",
1232                 .type           = P_STRING,
1233                 .p_class        = P_GLOBAL,
1234                 .ptr            = &Globals.szRootdir,
1235                 .special        = NULL,
1236                 .enum_list      = NULL,
1237                 .flags          = FLAG_HIDE,
1238         },
1239         {
1240                 .label          = "guest account",
1241                 .type           = P_STRING,
1242                 .p_class        = P_GLOBAL,
1243                 .ptr            = &Globals.szGuestaccount,
1244                 .special        = NULL,
1245                 .enum_list      = NULL,
1246                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
1247         },
1248         {
1249                 .label          = "enable privileges",
1250                 .type           = P_BOOL,
1251                 .p_class        = P_GLOBAL,
1252                 .ptr            = &Globals.bEnablePrivileges,
1253                 .special        = NULL,
1254                 .enum_list      = NULL,
1255                 .flags          = FLAG_ADVANCED,
1256         },
1257
1258         {
1259                 .label          = "pam password change",
1260                 .type           = P_BOOL,
1261                 .p_class        = P_GLOBAL,
1262                 .ptr            = &Globals.bPamPasswordChange,
1263                 .special        = NULL,
1264                 .enum_list      = NULL,
1265                 .flags          = FLAG_ADVANCED,
1266         },
1267         {
1268                 .label          = "passwd program",
1269                 .type           = P_STRING,
1270                 .p_class        = P_GLOBAL,
1271                 .ptr            = &Globals.szPasswdProgram,
1272                 .special        = NULL,
1273                 .enum_list      = NULL,
1274                 .flags          = FLAG_ADVANCED,
1275         },
1276         {
1277                 .label          = "passwd chat",
1278                 .type           = P_STRING,
1279                 .p_class        = P_GLOBAL,
1280                 .ptr            = &Globals.szPasswdChat,
1281                 .special        = NULL,
1282                 .enum_list      = NULL,
1283                 .flags          = FLAG_ADVANCED,
1284         },
1285         {
1286                 .label          = "passwd chat debug",
1287                 .type           = P_BOOL,
1288                 .p_class        = P_GLOBAL,
1289                 .ptr            = &Globals.bPasswdChatDebug,
1290                 .special        = NULL,
1291                 .enum_list      = NULL,
1292                 .flags          = FLAG_ADVANCED,
1293         },
1294         {
1295                 .label          = "passwd chat timeout",
1296                 .type           = P_INTEGER,
1297                 .p_class        = P_GLOBAL,
1298                 .ptr            = &Globals.iPasswdChatTimeout,
1299                 .special        = NULL,
1300                 .enum_list      = NULL,
1301                 .flags          = FLAG_ADVANCED,
1302         },
1303         {
1304                 .label          = "check password script",
1305                 .type           = P_STRING,
1306                 .p_class        = P_GLOBAL,
1307                 .ptr            = &Globals.szCheckPasswordScript,
1308                 .special        = NULL,
1309                 .enum_list      = NULL,
1310                 .flags          = FLAG_ADVANCED,
1311         },
1312         {
1313                 .label          = "username map",
1314                 .type           = P_STRING,
1315                 .p_class        = P_GLOBAL,
1316                 .ptr            = &Globals.szUsernameMap,
1317                 .special        = NULL,
1318                 .enum_list      = NULL,
1319                 .flags          = FLAG_ADVANCED,
1320         },
1321         {
1322                 .label          = "password level",
1323                 .type           = P_INTEGER,
1324                 .p_class        = P_GLOBAL,
1325                 .ptr            = &Globals.pwordlevel,
1326                 .special        = NULL,
1327                 .enum_list      = NULL,
1328                 .flags          = FLAG_ADVANCED,
1329         },
1330         {
1331                 .label          = "username level",
1332                 .type           = P_INTEGER,
1333                 .p_class        = P_GLOBAL,
1334                 .ptr            = &Globals.unamelevel,
1335                 .special        = NULL,
1336                 .enum_list      = NULL,
1337                 .flags          = FLAG_ADVANCED,
1338         },
1339         {
1340                 .label          = "unix password sync",
1341                 .type           = P_BOOL,
1342                 .p_class        = P_GLOBAL,
1343                 .ptr            = &Globals.bUnixPasswdSync,
1344                 .special        = NULL,
1345                 .enum_list      = NULL,
1346                 .flags          = FLAG_ADVANCED,
1347         },
1348         {
1349                 .label          = "restrict anonymous",
1350                 .type           = P_INTEGER,
1351                 .p_class        = P_GLOBAL,
1352                 .ptr            = &Globals.restrict_anonymous,
1353                 .special        = NULL,
1354                 .enum_list      = NULL,
1355                 .flags          = FLAG_ADVANCED,
1356         },
1357         {
1358                 .label          = "lanman auth",
1359                 .type           = P_BOOL,
1360                 .p_class        = P_GLOBAL,
1361                 .ptr            = &Globals.bLanmanAuth,
1362                 .special        = NULL,
1363                 .enum_list      = NULL,
1364                 .flags          = FLAG_ADVANCED,
1365         },
1366         {
1367                 .label          = "ntlm auth",
1368                 .type           = P_BOOL,
1369                 .p_class        = P_GLOBAL,
1370                 .ptr            = &Globals.bNTLMAuth,
1371                 .special        = NULL,
1372                 .enum_list      = NULL,
1373                 .flags          = FLAG_ADVANCED,
1374         },
1375         {
1376                 .label          = "client NTLMv2 auth",
1377                 .type           = P_BOOL,
1378                 .p_class        = P_GLOBAL,
1379                 .ptr            = &Globals.bClientNTLMv2Auth,
1380                 .special        = NULL,
1381                 .enum_list      = NULL,
1382                 .flags          = FLAG_ADVANCED,
1383         },
1384         {
1385                 .label          = "client lanman auth",
1386                 .type           = P_BOOL,
1387                 .p_class        = P_GLOBAL,
1388                 .ptr            = &Globals.bClientLanManAuth,
1389                 .special        = NULL,
1390                 .enum_list      = NULL,
1391                 .flags          = FLAG_ADVANCED,
1392         },
1393         {
1394                 .label          = "client plaintext auth",
1395                 .type           = P_BOOL,
1396                 .p_class        = P_GLOBAL,
1397                 .ptr            = &Globals.bClientPlaintextAuth,
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                 .ptr            = &sDefault.szUsername,
1407                 .special        = NULL,
1408                 .enum_list      = NULL,
1409                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1410         },
1411         {
1412                 .label          = "user",
1413                 .type           = P_STRING,
1414                 .p_class        = P_LOCAL,
1415                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.bProfileAcls,
2153                 .special        = NULL,
2154                 .enum_list      = NULL,
2155                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2156         },
2157         {
2158                 .label          = "announce version",
2159                 .type           = P_STRING,
2160                 .p_class        = P_GLOBAL,
2161                 .ptr            = &Globals.szAnnounceVersion,
2162                 .special        = NULL,
2163                 .enum_list      = NULL,
2164                 .flags          = FLAG_ADVANCED,
2165         },
2166         {
2167                 .label          = "announce as",
2168                 .type           = P_ENUM,
2169                 .p_class        = P_GLOBAL,
2170                 .ptr            = &Globals.announce_as,
2171                 .special        = NULL,
2172                 .enum_list      = enum_announce_as,
2173                 .flags          = FLAG_ADVANCED,
2174         },
2175         {
2176                 .label          = "map acl inherit",
2177                 .type           = P_BOOL,
2178                 .p_class        = P_LOCAL,
2179                 .ptr            = &sDefault.bMap_acl_inherit,
2180                 .special        = NULL,
2181                 .enum_list      = NULL,
2182                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2183         },
2184         {
2185                 .label          = "afs share",
2186                 .type           = P_BOOL,
2187                 .p_class        = P_LOCAL,
2188                 .ptr            = &sDefault.bAfs_Share,
2189                 .special        = NULL,
2190                 .enum_list      = NULL,
2191                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2192         },
2193         {
2194                 .label          = "max mux",
2195                 .type           = P_INTEGER,
2196                 .p_class        = P_GLOBAL,
2197                 .ptr            = &Globals.max_mux,
2198                 .special        = NULL,
2199                 .enum_list      = NULL,
2200                 .flags          = FLAG_ADVANCED,
2201         },
2202         {
2203                 .label          = "max xmit",
2204                 .type           = P_INTEGER,
2205                 .p_class        = P_GLOBAL,
2206                 .ptr            = &Globals.max_xmit,
2207                 .special        = NULL,
2208                 .enum_list      = NULL,
2209                 .flags          = FLAG_ADVANCED,
2210         },
2211         {
2212                 .label          = "name resolve order",
2213                 .type           = P_STRING,
2214                 .p_class        = P_GLOBAL,
2215                 .ptr            = &Globals.szNameResolveOrder,
2216                 .special        = NULL,
2217                 .enum_list      = NULL,
2218                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
2219         },
2220         {
2221                 .label          = "max ttl",
2222                 .type           = P_INTEGER,
2223                 .p_class        = P_GLOBAL,
2224                 .ptr            = &Globals.max_ttl,
2225                 .special        = NULL,
2226                 .enum_list      = NULL,
2227                 .flags          = FLAG_ADVANCED,
2228         },
2229         {
2230                 .label          = "max wins ttl",
2231                 .type           = P_INTEGER,
2232                 .p_class        = P_GLOBAL,
2233                 .ptr            = &Globals.max_wins_ttl,
2234                 .special        = NULL,
2235                 .enum_list      = NULL,
2236                 .flags          = FLAG_ADVANCED,
2237         },
2238         {
2239                 .label          = "min wins ttl",
2240                 .type           = P_INTEGER,
2241                 .p_class        = P_GLOBAL,
2242                 .ptr            = &Globals.min_wins_ttl,
2243                 .special        = NULL,
2244                 .enum_list      = NULL,
2245                 .flags          = FLAG_ADVANCED,
2246         },
2247         {
2248                 .label          = "time server",
2249                 .type           = P_BOOL,
2250                 .p_class        = P_GLOBAL,
2251                 .ptr            = &Globals.bTimeServer,
2252                 .special        = NULL,
2253                 .enum_list      = NULL,
2254                 .flags          = FLAG_ADVANCED,
2255         },
2256         {
2257                 .label          = "unix extensions",
2258                 .type           = P_BOOL,
2259                 .p_class        = P_GLOBAL,
2260                 .ptr            = &Globals.bUnixExtensions,
2261                 .special        = NULL,
2262                 .enum_list      = NULL,
2263                 .flags          = FLAG_ADVANCED,
2264         },
2265         {
2266                 .label          = "use spnego",
2267                 .type           = P_BOOL,
2268                 .p_class        = P_GLOBAL,
2269                 .ptr            = &Globals.bUseSpnego,
2270                 .special        = NULL,
2271                 .enum_list      = NULL,
2272                 .flags          = FLAG_ADVANCED,
2273         },
2274         {
2275                 .label          = "client signing",
2276                 .type           = P_ENUM,
2277                 .p_class        = P_GLOBAL,
2278                 .ptr            = &Globals.client_signing,
2279                 .special        = NULL,
2280                 .enum_list      = enum_smb_signing_vals,
2281                 .flags          = FLAG_ADVANCED,
2282         },
2283         {
2284                 .label          = "server signing",
2285                 .type           = P_ENUM,
2286                 .p_class        = P_GLOBAL,
2287                 .ptr            = &Globals.server_signing,
2288                 .special        = NULL,
2289                 .enum_list      = enum_smb_signing_vals,
2290                 .flags          = FLAG_ADVANCED,
2291         },
2292         {
2293                 .label          = "smb encrypt",
2294                 .type           = P_ENUM,
2295                 .p_class        = P_LOCAL,
2296                 .ptr            = &sDefault.ismb_encrypt,
2297                 .special        = NULL,
2298                 .enum_list      = enum_smb_signing_vals,
2299                 .flags          = FLAG_ADVANCED,
2300         },
2301         {
2302                 .label          = "client use spnego",
2303                 .type           = P_BOOL,
2304                 .p_class        = P_GLOBAL,
2305                 .ptr            = &Globals.bClientUseSpnego,
2306                 .special        = NULL,
2307                 .enum_list      = NULL,
2308                 .flags          = FLAG_ADVANCED,
2309         },
2310         {
2311                 .label          = "client ldap sasl wrapping",
2312                 .type           = P_ENUM,
2313                 .p_class        = P_GLOBAL,
2314                 .ptr            = &Globals.client_ldap_sasl_wrapping,
2315                 .special        = NULL,
2316                 .enum_list      = enum_ldap_sasl_wrapping,
2317                 .flags          = FLAG_ADVANCED,
2318         },
2319         {
2320                 .label          = "enable asu support",
2321                 .type           = P_BOOL,
2322                 .p_class        = P_GLOBAL,
2323                 .ptr            = &Globals.bASUSupport,
2324                 .special        = NULL,
2325                 .enum_list      = NULL,
2326                 .flags          = FLAG_ADVANCED,
2327         },
2328         {
2329                 .label          = "svcctl list",
2330                 .type           = P_LIST,
2331                 .p_class        = P_GLOBAL,
2332                 .ptr            = &Globals.szServicesList,
2333                 .special        = NULL,
2334                 .enum_list      = NULL,
2335                 .flags          = FLAG_ADVANCED,
2336         },
2337
2338         {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2339
2340         {
2341                 .label          = "block size",
2342                 .type           = P_INTEGER,
2343                 .p_class        = P_LOCAL,
2344                 .ptr            = &sDefault.iBlock_size,
2345                 .special        = NULL,
2346                 .enum_list      = NULL,
2347                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2348         },
2349         {
2350                 .label          = "deadtime",
2351                 .type           = P_INTEGER,
2352                 .p_class        = P_GLOBAL,
2353                 .ptr            = &Globals.deadtime,
2354                 .special        = NULL,
2355                 .enum_list      = NULL,
2356                 .flags          = FLAG_ADVANCED,
2357         },
2358         {
2359                 .label          = "getwd cache",
2360                 .type           = P_BOOL,
2361                 .p_class        = P_GLOBAL,
2362                 .ptr            = &Globals.getwd_cache,
2363                 .special        = NULL,
2364                 .enum_list      = NULL,
2365                 .flags          = FLAG_ADVANCED,
2366         },
2367         {
2368                 .label          = "keepalive",
2369                 .type           = P_INTEGER,
2370                 .p_class        = P_GLOBAL,
2371                 .ptr            = &Globals.iKeepalive,
2372                 .special        = NULL,
2373                 .enum_list      = NULL,
2374                 .flags          = FLAG_ADVANCED,
2375         },
2376         {
2377                 .label          = "change notify",
2378                 .type           = P_BOOL,
2379                 .p_class        = P_LOCAL,
2380                 .ptr            = &sDefault.bChangeNotify,
2381                 .special        = NULL,
2382                 .enum_list      = NULL,
2383                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2384         },
2385         {
2386                 .label          = "directory name cache size",
2387                 .type           = P_INTEGER,
2388                 .p_class        = P_LOCAL,
2389                 .ptr            = &sDefault.iDirectoryNameCacheSize,
2390                 .special        = NULL,
2391                 .enum_list      = NULL,
2392                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2393         },
2394         {
2395                 .label          = "kernel change notify",
2396                 .type           = P_BOOL,
2397                 .p_class        = P_LOCAL,
2398                 .ptr            = &sDefault.bKernelChangeNotify,
2399                 .special        = NULL,
2400                 .enum_list      = NULL,
2401                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2402         },
2403         {
2404                 .label          = "lpq cache time",
2405                 .type           = P_INTEGER,
2406                 .p_class        = P_GLOBAL,
2407                 .ptr            = &Globals.lpqcachetime,
2408                 .special        = NULL,
2409                 .enum_list      = NULL,
2410                 .flags          = FLAG_ADVANCED,
2411         },
2412         {
2413                 .label          = "max smbd processes",
2414                 .type           = P_INTEGER,
2415                 .p_class        = P_GLOBAL,
2416                 .ptr            = &Globals.iMaxSmbdProcesses,
2417                 .special        = NULL,
2418                 .enum_list      = NULL,
2419                 .flags          = FLAG_ADVANCED,
2420         },
2421         {
2422                 .label          = "max connections",
2423                 .type           = P_INTEGER,
2424                 .p_class        = P_LOCAL,
2425                 .ptr            = &sDefault.iMaxConnections,
2426                 .special        = NULL,
2427                 .enum_list      = NULL,
2428                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2429         },
2430         {
2431                 .label          = "paranoid server security",
2432                 .type           = P_BOOL,
2433                 .p_class        = P_GLOBAL,
2434                 .ptr            = &Globals.paranoid_server_security,
2435                 .special        = NULL,
2436                 .enum_list      = NULL,
2437                 .flags          = FLAG_ADVANCED,
2438         },
2439         {
2440                 .label          = "max disk size",
2441                 .type           = P_INTEGER,
2442                 .p_class        = P_GLOBAL,
2443                 .ptr            = &Globals.maxdisksize,
2444                 .special        = NULL,
2445                 .enum_list      = NULL,
2446                 .flags          = FLAG_ADVANCED,
2447         },
2448         {
2449                 .label          = "max open files",
2450                 .type           = P_INTEGER,
2451                 .p_class        = P_GLOBAL,
2452                 .ptr            = &Globals.max_open_files,
2453                 .special        = NULL,
2454                 .enum_list      = NULL,
2455                 .flags          = FLAG_ADVANCED,
2456         },
2457         {
2458                 .label          = "min print space",
2459                 .type           = P_INTEGER,
2460                 .p_class        = P_LOCAL,
2461                 .ptr            = &sDefault.iMinPrintSpace,
2462                 .special        = NULL,
2463                 .enum_list      = NULL,
2464                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2465         },
2466         {
2467                 .label          = "socket options",
2468                 .type           = P_STRING,
2469                 .p_class        = P_GLOBAL,
2470                 .ptr            = &Globals.szSocketOptions,
2471                 .special        = NULL,
2472                 .enum_list      = NULL,
2473                 .flags          = FLAG_ADVANCED,
2474         },
2475         {
2476                 .label          = "strict allocate",
2477                 .type           = P_BOOL,
2478                 .p_class        = P_LOCAL,
2479                 .ptr            = &sDefault.bStrictAllocate,
2480                 .special        = NULL,
2481                 .enum_list      = NULL,
2482                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2483         },
2484         {
2485                 .label          = "strict sync",
2486                 .type           = P_BOOL,
2487                 .p_class        = P_LOCAL,
2488                 .ptr            = &sDefault.bStrictSync,
2489                 .special        = NULL,
2490                 .enum_list      = NULL,
2491                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2492         },
2493         {
2494                 .label          = "sync always",
2495                 .type           = P_BOOL,
2496                 .p_class        = P_LOCAL,
2497                 .ptr            = &sDefault.bSyncAlways,
2498                 .special        = NULL,
2499                 .enum_list      = NULL,
2500                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2501         },
2502         {
2503                 .label          = "use mmap",
2504                 .type           = P_BOOL,
2505                 .p_class        = P_GLOBAL,
2506                 .ptr            = &Globals.bUseMmap,
2507                 .special        = NULL,
2508                 .enum_list      = NULL,
2509                 .flags          = FLAG_ADVANCED,
2510         },
2511         {
2512                 .label          = "use sendfile",
2513                 .type           = P_BOOL,
2514                 .p_class        = P_LOCAL,
2515                 .ptr            = &sDefault.bUseSendfile,
2516                 .special        = NULL,
2517                 .enum_list      = NULL,
2518                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2519         },
2520         {
2521                 .label          = "hostname lookups",
2522                 .type           = P_BOOL,
2523                 .p_class        = P_GLOBAL,
2524                 .ptr            = &Globals.bHostnameLookups,
2525                 .special        = NULL,
2526                 .enum_list      = NULL,
2527                 .flags          = FLAG_ADVANCED,
2528         },
2529         {
2530                 .label          = "write cache size",
2531                 .type           = P_INTEGER,
2532                 .p_class        = P_LOCAL,
2533                 .ptr            = &sDefault.iWriteCacheSize,
2534                 .special        = NULL,
2535                 .enum_list      = NULL,
2536                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2537         },
2538         {
2539                 .label          = "name cache timeout",
2540                 .type           = P_INTEGER,
2541                 .p_class        = P_GLOBAL,
2542                 .ptr            = &Globals.name_cache_timeout,
2543                 .special        = NULL,
2544                 .enum_list      = NULL,
2545                 .flags          = FLAG_ADVANCED,
2546         },
2547         {
2548                 .label          = "ctdbd socket",
2549                 .type           = P_STRING,
2550                 .p_class        = P_GLOBAL,
2551                 .ptr            = &Globals.ctdbdSocket,
2552                 .special        = NULL,
2553                 .enum_list      = NULL,
2554                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2555         },
2556         {
2557                 .label          = "cluster addresses",
2558                 .type           = P_LIST,
2559                 .p_class        = P_GLOBAL,
2560                 .ptr            = &Globals.szClusterAddresses,
2561                 .special        = NULL,
2562                 .enum_list      = NULL,
2563                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2564         },
2565         {
2566                 .label          = "clustering",
2567                 .type           = P_BOOL,
2568                 .p_class        = P_GLOBAL,
2569                 .ptr            = &Globals.clustering,
2570                 .special        = NULL,
2571                 .enum_list      = NULL,
2572                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2573         },
2574         {
2575                 .label          = "ctdb timeout",
2576                 .type           = P_INTEGER,
2577                 .p_class        = P_GLOBAL,
2578                 .ptr            = &Globals.ctdb_timeout,
2579                 .special        = NULL,
2580                 .enum_list      = NULL,
2581                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2582         },
2583         {
2584                 .label          = "ctdb locktime warn threshold",
2585                 .type           = P_INTEGER,
2586                 .p_class        = P_GLOBAL,
2587                 .ptr            = &Globals.ctdb_locktime_warn_threshold,
2588                 .special        = NULL,
2589                 .enum_list      = NULL,
2590                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
2591         },
2592         {
2593                 .label          = "smb2 max read",
2594                 .type           = P_INTEGER,
2595                 .p_class        = P_GLOBAL,
2596                 .ptr            = &Globals.ismb2_max_read,
2597                 .special        = NULL,
2598                 .enum_list      = NULL,
2599                 .flags          = FLAG_ADVANCED,
2600         },
2601         {
2602                 .label          = "smb2 max write",
2603                 .type           = P_INTEGER,
2604                 .p_class        = P_GLOBAL,
2605                 .ptr            = &Globals.ismb2_max_write,
2606                 .special        = NULL,
2607                 .enum_list      = NULL,
2608                 .flags          = FLAG_ADVANCED,
2609         },
2610         {
2611                 .label          = "smb2 max trans",
2612                 .type           = P_INTEGER,
2613                 .p_class        = P_GLOBAL,
2614                 .ptr            = &Globals.ismb2_max_trans,
2615                 .special        = NULL,
2616                 .enum_list      = NULL,
2617                 .flags          = FLAG_ADVANCED,
2618         },
2619
2620         {N_("Printing Options"), P_SEP, P_SEPARATOR},
2621
2622         {
2623                 .label          = "max reported print jobs",
2624                 .type           = P_INTEGER,
2625                 .p_class        = P_LOCAL,
2626                 .ptr            = &sDefault.iMaxReportedPrintJobs,
2627                 .special        = NULL,
2628                 .enum_list      = NULL,
2629                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2630         },
2631         {
2632                 .label          = "max print jobs",
2633                 .type           = P_INTEGER,
2634                 .p_class        = P_LOCAL,
2635                 .ptr            = &sDefault.iMaxPrintJobs,
2636                 .special        = NULL,
2637                 .enum_list      = NULL,
2638                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2639         },
2640         {
2641                 .label          = "load printers",
2642                 .type           = P_BOOL,
2643                 .p_class        = P_GLOBAL,
2644                 .ptr            = &Globals.bLoadPrinters,
2645                 .special        = NULL,
2646                 .enum_list      = NULL,
2647                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2648         },
2649         {
2650                 .label          = "printcap cache time",
2651                 .type           = P_INTEGER,
2652                 .p_class        = P_GLOBAL,
2653                 .ptr            = &Globals.PrintcapCacheTime,
2654                 .special        = NULL,
2655                 .enum_list      = NULL,
2656                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2657         },
2658         {
2659                 .label          = "printcap name",
2660                 .type           = P_STRING,
2661                 .p_class        = P_GLOBAL,
2662                 .ptr            = &Globals.szPrintcapname,
2663                 .special        = NULL,
2664                 .enum_list      = NULL,
2665                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2666         },
2667         {
2668                 .label          = "printcap",
2669                 .type           = P_STRING,
2670                 .p_class        = P_GLOBAL,
2671                 .ptr            = &Globals.szPrintcapname,
2672                 .special        = NULL,
2673                 .enum_list      = NULL,
2674                 .flags          = FLAG_HIDE,
2675         },
2676         {
2677                 .label          = "printable",
2678                 .type           = P_BOOL,
2679                 .p_class        = P_LOCAL,
2680                 .ptr            = &sDefault.bPrint_ok,
2681                 .special        = NULL,
2682                 .enum_list      = NULL,
2683                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2684         },
2685         {
2686                 .label          = "print ok",
2687                 .type           = P_BOOL,
2688                 .p_class        = P_LOCAL,
2689                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.szLogNtTokenCommand,
4094                 .special        = NULL,
4095                 .enum_list      = NULL,
4096                 .flags          = FLAG_ADVANCED,
4097         },
4098         {
4099                 .label          = "time offset",
4100                 .type           = P_INTEGER,
4101                 .p_class        = P_GLOBAL,
4102                 .ptr            = &extra_time_offset,
4103                 .special        = NULL,
4104                 .enum_list      = NULL,
4105                 .flags          = FLAG_ADVANCED,
4106         },
4107         {
4108                 .label          = "NIS homedir",
4109                 .type           = P_BOOL,
4110                 .p_class        = P_GLOBAL,
4111                 .ptr            = &Globals.bNISHomeMap,
4112                 .special        = NULL,
4113                 .enum_list      = NULL,
4114                 .flags          = FLAG_ADVANCED,
4115         },
4116         {
4117                 .label          = "-valid",
4118                 .type           = P_BOOL,
4119                 .p_class        = P_LOCAL,
4120                 .ptr            = &sDefault.valid,
4121                 .special        = NULL,
4122                 .enum_list      = NULL,
4123                 .flags          = FLAG_HIDE,
4124         },
4125         {
4126                 .label          = "copy",
4127                 .type           = P_STRING,
4128                 .p_class        = P_LOCAL,
4129                 .ptr            = &sDefault.szCopy,
4130                 .special        = handle_copy,
4131                 .enum_list      = NULL,
4132                 .flags          = FLAG_HIDE,
4133         },
4134         {
4135                 .label          = "include",
4136                 .type           = P_STRING,
4137                 .p_class        = P_LOCAL,
4138                 .ptr            = &sDefault.szInclude,
4139                 .special        = handle_include,
4140                 .enum_list      = NULL,
4141                 .flags          = FLAG_HIDE|FLAG_META,
4142         },
4143         {
4144                 .label          = "preexec",
4145                 .type           = P_STRING,
4146                 .p_class        = P_LOCAL,
4147                 .ptr            = &sDefault.szPreExec,
4148                 .special        = NULL,
4149                 .enum_list      = NULL,
4150                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4151         },
4152         {
4153                 .label          = "exec",
4154                 .type           = P_STRING,
4155                 .p_class        = P_LOCAL,
4156                 .ptr            = &sDefault.szPreExec,
4157                 .special        = NULL,
4158                 .enum_list      = NULL,
4159                 .flags          = FLAG_ADVANCED,
4160         },
4161         {
4162                 .label          = "preexec close",
4163                 .type           = P_BOOL,
4164                 .p_class        = P_LOCAL,
4165                 .ptr            = &sDefault.bPreexecClose,
4166                 .special        = NULL,
4167                 .enum_list      = NULL,
4168                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4169         },
4170         {
4171                 .label          = "postexec",
4172                 .type           = P_STRING,
4173                 .p_class        = P_LOCAL,
4174                 .ptr            = &sDefault.szPostExec,
4175                 .special        = NULL,
4176                 .enum_list      = NULL,
4177                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4178         },
4179         {
4180                 .label          = "root preexec",
4181                 .type           = P_STRING,
4182                 .p_class        = P_LOCAL,
4183                 .ptr            = &sDefault.szRootPreExec,
4184                 .special        = NULL,
4185                 .enum_list      = NULL,
4186                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4187         },
4188         {
4189                 .label          = "root preexec close",
4190                 .type           = P_BOOL,
4191                 .p_class        = P_LOCAL,
4192                 .ptr            = &sDefault.bRootpreexecClose,
4193                 .special        = NULL,
4194                 .enum_list      = NULL,
4195                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4196         },
4197         {
4198                 .label          = "root postexec",
4199                 .type           = P_STRING,
4200                 .p_class        = P_LOCAL,
4201                 .ptr            = &sDefault.szRootPostExec,
4202                 .special        = NULL,
4203                 .enum_list      = NULL,
4204                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4205         },
4206         {
4207                 .label          = "available",
4208                 .type           = P_BOOL,
4209                 .p_class        = P_LOCAL,
4210                 .ptr            = &sDefault.bAvailable,
4211                 .special        = NULL,
4212                 .enum_list      = NULL,
4213                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4214         },
4215         {
4216                 .label          = "registry shares",
4217                 .type           = P_BOOL,
4218                 .p_class        = P_GLOBAL,
4219                 .ptr            = &Globals.bRegistryShares,
4220                 .special        = NULL,
4221                 .enum_list      = NULL,
4222                 .flags          = FLAG_ADVANCED,
4223         },
4224         {
4225                 .label          = "usershare allow guests",
4226                 .type           = P_BOOL,
4227                 .p_class        = P_GLOBAL,
4228                 .ptr            = &Globals.bUsershareAllowGuests,
4229                 .special        = NULL,
4230                 .enum_list      = NULL,
4231                 .flags          = FLAG_ADVANCED,
4232         },
4233         {
4234                 .label          = "usershare max shares",
4235                 .type           = P_INTEGER,
4236                 .p_class        = P_GLOBAL,
4237                 .ptr            = &Globals.iUsershareMaxShares,
4238                 .special        = NULL,
4239                 .enum_list      = NULL,
4240                 .flags          = FLAG_ADVANCED,
4241         },
4242         {
4243                 .label          = "usershare owner only",
4244                 .type           = P_BOOL,
4245                 .p_class        = P_GLOBAL,
4246                 .ptr            = &Globals.bUsershareOwnerOnly,
4247                 .special        = NULL,
4248                 .enum_list      = NULL,
4249                 .flags          = FLAG_ADVANCED,
4250         },
4251         {
4252                 .label          = "usershare path",
4253                 .type           = P_STRING,
4254                 .p_class        = P_GLOBAL,
4255                 .ptr            = &Globals.szUsersharePath,
4256                 .special        = NULL,
4257                 .enum_list      = NULL,
4258                 .flags          = FLAG_ADVANCED,
4259         },
4260         {
4261                 .label          = "usershare prefix allow list",
4262                 .type           = P_LIST,
4263                 .p_class        = P_GLOBAL,
4264                 .ptr            = &Globals.szUsersharePrefixAllowList,
4265                 .special        = NULL,
4266                 .enum_list      = NULL,
4267                 .flags          = FLAG_ADVANCED,
4268         },
4269         {
4270                 .label          = "usershare prefix deny list",
4271                 .type           = P_LIST,
4272                 .p_class        = P_GLOBAL,
4273                 .ptr            = &Globals.szUsersharePrefixDenyList,
4274                 .special        = NULL,
4275                 .enum_list      = NULL,
4276                 .flags          = FLAG_ADVANCED,
4277         },
4278         {
4279                 .label          = "usershare template share",
4280                 .type           = P_STRING,
4281                 .p_class        = P_GLOBAL,
4282                 .ptr            = &Globals.szUsershareTemplateShare,
4283                 .special        = NULL,
4284                 .enum_list      = NULL,
4285                 .flags          = FLAG_ADVANCED,
4286         },
4287         {
4288                 .label          = "volume",
4289                 .type           = P_STRING,
4290                 .p_class        = P_LOCAL,
4291                 .ptr            = &sDefault.volume,
4292                 .special        = NULL,
4293                 .enum_list      = NULL,
4294                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4295         },
4296         {
4297                 .label          = "fstype",
4298                 .type           = P_STRING,
4299                 .p_class        = P_LOCAL,
4300                 .ptr            = &sDefault.fstype,
4301                 .special        = NULL,
4302                 .enum_list      = NULL,
4303                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4304         },
4305         {
4306                 .label          = "set directory",
4307                 .type           = P_BOOLREV,
4308                 .p_class        = P_LOCAL,
4309                 .ptr            = &sDefault.bNo_set_dir,
4310                 .special        = NULL,
4311                 .enum_list      = NULL,
4312                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4313         },
4314         {
4315                 .label          = "wide links",
4316                 .type           = P_BOOL,
4317                 .p_class        = P_LOCAL,
4318                 .ptr            = &sDefault.bWidelinks,
4319                 .special        = NULL,
4320                 .enum_list      = NULL,
4321                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4322         },
4323         {
4324                 .label          = "follow symlinks",
4325                 .type           = P_BOOL,
4326                 .p_class        = P_LOCAL,
4327                 .ptr            = &sDefault.bSymlinks,
4328                 .special        = NULL,
4329                 .enum_list      = NULL,
4330                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4331         },
4332         {
4333                 .label          = "dont descend",
4334                 .type           = P_STRING,
4335                 .p_class        = P_LOCAL,
4336                 .ptr            = &sDefault.szDontdescend,
4337                 .special        = NULL,
4338                 .enum_list      = NULL,
4339                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4340         },
4341         {
4342                 .label          = "magic script",
4343                 .type           = P_STRING,
4344                 .p_class        = P_LOCAL,
4345                 .ptr            = &sDefault.szMagicScript,
4346                 .special        = NULL,
4347                 .enum_list      = NULL,
4348                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4349         },
4350         {
4351                 .label          = "magic output",
4352                 .type           = P_STRING,
4353                 .p_class        = P_LOCAL,
4354                 .ptr            = &sDefault.szMagicOutput,
4355                 .special        = NULL,
4356                 .enum_list      = NULL,
4357                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4358         },
4359         {
4360                 .label          = "delete readonly",
4361                 .type           = P_BOOL,
4362                 .p_class        = P_LOCAL,
4363                 .ptr            = &sDefault.bDeleteReadonly,
4364                 .special        = NULL,
4365                 .enum_list      = NULL,
4366                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4367         },
4368         {
4369                 .label          = "dos filemode",
4370                 .type           = P_BOOL,
4371                 .p_class        = P_LOCAL,
4372                 .ptr            = &sDefault.bDosFilemode,
4373                 .special        = NULL,
4374                 .enum_list      = NULL,
4375                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4376         },
4377         {
4378                 .label          = "dos filetimes",
4379                 .type           = P_BOOL,
4380                 .p_class        = P_LOCAL,
4381                 .ptr            = &sDefault.bDosFiletimes,
4382                 .special        = NULL,
4383                 .enum_list      = NULL,
4384                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4385         },
4386         {
4387                 .label          = "dos filetime resolution",
4388                 .type           = P_BOOL,
4389                 .p_class        = P_LOCAL,
4390                 .ptr            = &sDefault.bDosFiletimeResolution,
4391                 .special        = NULL,
4392                 .enum_list      = NULL,
4393                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4394         },
4395         {
4396                 .label          = "fake directory create times",
4397                 .type           = P_BOOL,
4398                 .p_class        = P_LOCAL,
4399                 .ptr            = &sDefault.bFakeDirCreateTimes,
4400                 .special        = NULL,
4401                 .enum_list      = NULL,
4402                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
4403         },
4404         {
4405                 .label          = "async smb echo handler",
4406                 .type           = P_BOOL,
4407                 .p_class        = P_GLOBAL,
4408                 .ptr            = &Globals.bAsyncSMBEchoHandler,
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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &sDefault.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.szIdmapBackend,
4500                 .special        = NULL,
4501                 .enum_list      = NULL,
4502                 .flags          = FLAG_ADVANCED,
4503         },
4504         {
4505                 .label          = "idmap alloc backend",
4506                 .type           = P_STRING,
4507                 .p_class        = P_GLOBAL,
4508                 .ptr            = &Globals.szIdmapAllocBackend,
4509                 .special        = NULL,
4510                 .enum_list      = NULL,
4511                 .flags          = FLAG_ADVANCED,
4512         },
4513         {
4514                 .label          = "idmap cache time",
4515                 .type           = P_INTEGER,
4516                 .p_class        = P_GLOBAL,
4517                 .ptr            = &Globals.iIdmapCacheTime,
4518                 .special        = NULL,
4519                 .enum_list      = NULL,
4520                 .flags          = FLAG_ADVANCED,
4521         },
4522         {
4523                 .label          = "idmap negative cache time",
4524                 .type           = P_INTEGER,
4525                 .p_class        = P_GLOBAL,
4526                 .ptr            = &Globals.iIdmapNegativeCacheTime,
4527                 .special        = NULL,
4528                 .enum_list      = NULL,
4529                 .flags          = FLAG_ADVANCED,
4530         },
4531         {
4532                 .label          = "idmap uid",
4533                 .type           = P_STRING,
4534                 .p_class        = P_GLOBAL,
4535                 .ptr            = &Globals.szIdmapUID,
4536                 .special        = handle_idmap_uid,
4537                 .enum_list      = NULL,
4538                 .flags          = FLAG_ADVANCED,
4539         },
4540         {
4541                 .label          = "winbind uid",
4542                 .type           = P_STRING,
4543                 .p_class        = P_GLOBAL,
4544                 .ptr            = &Globals.szIdmapUID,
4545                 .special        = handle_idmap_uid,
4546                 .enum_list      = NULL,
4547                 .flags          = FLAG_HIDE,
4548         },
4549         {
4550                 .label          = "idmap gid",
4551                 .type           = P_STRING,
4552                 .p_class        = P_GLOBAL,
4553                 .ptr            = &Globals.szIdmapGID,
4554                 .special        = handle_idmap_gid,
4555                 .enum_list      = NULL,
4556                 .flags          = FLAG_ADVANCED,
4557         },
4558         {
4559                 .label          = "winbind gid",
4560                 .type           = P_STRING,
4561                 .p_class        = P_GLOBAL,
4562                 .ptr            = &Globals.szIdmapGID,
4563                 .special        = handle_idmap_gid,
4564                 .enum_list      = NULL,
4565                 .flags          = FLAG_HIDE,
4566         },
4567         {
4568                 .label          = "template homedir",
4569                 .type           = P_STRING,
4570                 .p_class        = P_GLOBAL,
4571                 .ptr            = &Globals.szTemplateHomedir,
4572                 .special        = NULL,
4573                 .enum_list      = NULL,
4574                 .flags          = FLAG_ADVANCED,
4575         },
4576         {
4577                 .label          = "template shell",
4578                 .type           = P_STRING,
4579                 .p_class        = P_GLOBAL,
4580                 .ptr            = &Globals.szTemplateShell,
4581                 .special        = NULL,
4582                 .enum_list      = NULL,
4583                 .flags          = FLAG_ADVANCED,
4584         },
4585         {
4586                 .label          = "winbind separator",
4587                 .type           = P_STRING,
4588                 .p_class        = P_GLOBAL,
4589                 .ptr            = &Globals.szWinbindSeparator,
4590                 .special        = NULL,
4591                 .enum_list      = NULL,
4592                 .flags          = FLAG_ADVANCED,
4593         },
4594         {
4595                 .label          = "winbind cache time",
4596                 .type           = P_INTEGER,
4597                 .p_class        = P_GLOBAL,
4598                 .ptr            = &Globals.winbind_cache_time,
4599                 .special        = NULL,
4600                 .enum_list      = NULL,
4601                 .flags          = FLAG_ADVANCED,
4602         },
4603         {
4604                 .label          = "winbind reconnect delay",
4605                 .type           = P_INTEGER,
4606                 .p_class        = P_GLOBAL,
4607                 .ptr            = &Globals.winbind_reconnect_delay,
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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.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                 .ptr            = &Globals.bCreateKrb5Conf,
4716                 .special        = NULL,
4717                 .enum_list      = NULL,
4718                 .flags          = FLAG_ADVANCED,
4719         },
4720
4721         {NULL,  P_BOOL,  P_NONE,  NULL,  NULL,  NULL,  0}
4722 };
4723
4724 /***************************************************************************
4725  Initialise the sDefault parameter structure for the printer values.
4726 ***************************************************************************/
4727
4728 static void init_printer_values(struct service *pService)
4729 {
4730         /* choose defaults depending on the type of printing */
4731         switch (pService->iPrinting) {
4732                 case PRINT_BSD:
4733                 case PRINT_AIX:
4734                 case PRINT_LPRNT:
4735                 case PRINT_LPROS2:
4736                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4737                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4738                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4739                         break;
4740
4741                 case PRINT_LPRNG:
4742                 case PRINT_PLP:
4743                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4744                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4745                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4746                         string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4747                         string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4748                         string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4749                         string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4750                         break;
4751
4752                 case PRINT_CUPS:
4753                 case PRINT_IPRINT:
4754 #ifdef HAVE_CUPS
4755                         /* set the lpq command to contain the destination printer
4756                            name only.  This is used by cups_queue_get() */
4757                         string_set(&pService->szLpqcommand, "%p");
4758                         string_set(&pService->szLprmcommand, "");
4759                         string_set(&pService->szPrintcommand, "");
4760                         string_set(&pService->szLppausecommand, "");
4761                         string_set(&pService->szLpresumecommand, "");
4762                         string_set(&pService->szQueuepausecommand, "");
4763                         string_set(&pService->szQueueresumecommand, "");
4764 #else
4765                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4766                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4767                         string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4768                         string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4769                         string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4770                         string_set(&pService->szQueuepausecommand, "disable '%p'");
4771                         string_set(&pService->szQueueresumecommand, "enable '%p'");
4772 #endif /* HAVE_CUPS */
4773                         break;
4774
4775                 case PRINT_SYSV:
4776                 case PRINT_HPUX:
4777                         string_set(&pService->szLpqcommand, "lpstat -o%p");
4778                         string_set(&pService->szLprmcommand, "cancel %p-%j");
4779                         string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4780                         string_set(&pService->szQueuepausecommand, "disable %p");
4781                         string_set(&pService->szQueueresumecommand, "enable %p");
4782 #ifndef HPUX
4783                         string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4784                         string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4785 #endif /* HPUX */
4786                         break;
4787
4788                 case PRINT_QNX:
4789                         string_set(&pService->szLpqcommand, "lpq -P%p");
4790                         string_set(&pService->szLprmcommand, "lprm -P%p %j");
4791                         string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4792                         break;
4793
4794 #ifdef DEVELOPER
4795         case PRINT_TEST:
4796         case PRINT_VLP:
4797                 string_set(&pService->szPrintcommand, "vlp print %p %s");
4798                 string_set(&pService->szLpqcommand, "vlp lpq %p");
4799                 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4800                 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4801                 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4802                 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4803                 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4804                 break;
4805 #endif /* DEVELOPER */
4806
4807         }
4808 }
4809 /**
4810  *  Function to return the default value for the maximum number of open
4811  *  file descriptors permitted.  This function tries to consult the
4812  *  kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4813  *  the smaller of those.
4814  */
4815 static int max_open_files(void)
4816 {
4817         int sysctl_max = MAX_OPEN_FILES;
4818         int rlimit_max = MAX_OPEN_FILES;
4819
4820 #ifdef HAVE_SYSCTLBYNAME
4821         {
4822                 size_t size = sizeof(sysctl_max);
4823                 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4824                              0);
4825         }
4826 #endif
4827
4828 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4829         {
4830                 struct rlimit rl;
4831
4832                 ZERO_STRUCT(rl);
4833
4834                 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4835                         rlimit_max = rl.rlim_cur;
4836
4837 #if defined(RLIM_INFINITY)
4838                 if(rl.rlim_cur == RLIM_INFINITY)
4839                         rlimit_max = MAX_OPEN_FILES;
4840         }
4841 #endif
4842 #endif
4843
4844         if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4845                 DEBUG(2,("max_open_files: sysctl_max (%d) below "
4846                         "minimum Windows limit (%d)\n",
4847                         sysctl_max,
4848                         MIN_OPEN_FILES_WINDOWS));
4849                 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4850         }
4851
4852         if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4853                 DEBUG(2,("rlimit_max: rlimit_max (%d) below "
4854                         "minimum Windows limit (%d)\n",
4855                         rlimit_max,
4856                         MIN_OPEN_FILES_WINDOWS));
4857                 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4858         }
4859
4860         return MIN(sysctl_max, rlimit_max);
4861 }
4862
4863 /**
4864  * Common part of freeing allocated data for one parameter.
4865  */
4866 static void free_one_parameter_common(void *parm_ptr,
4867                                       struct parm_struct parm)
4868 {
4869         if ((parm.type == P_STRING) ||
4870             (parm.type == P_USTRING))
4871         {
4872                 string_free((char**)parm_ptr);
4873         } else if (parm.type == P_LIST) {
4874                 TALLOC_FREE(*((char***)parm_ptr));
4875         }
4876 }
4877
4878 /**
4879  * Free the allocated data for one parameter for a share
4880  * given as a service struct.
4881  */
4882 static void free_one_parameter(struct service *service,
4883                                struct parm_struct parm)
4884 {
4885         void *parm_ptr;
4886
4887         if (parm.p_class != P_LOCAL) {
4888                 return;
4889         }
4890
4891         parm_ptr = lp_local_ptr(service, parm.ptr);
4892
4893         free_one_parameter_common(parm_ptr, parm);
4894 }
4895
4896 /**
4897  * Free the allocated parameter data of a share given
4898  * as a service struct.
4899  */
4900 static void free_parameters(struct service *service)
4901 {
4902         uint32_t i;
4903
4904         for (i=0; parm_table[i].label; i++) {
4905                 free_one_parameter(service, parm_table[i]);
4906         }
4907 }
4908
4909 /**
4910  * Free the allocated data for one parameter for a given share
4911  * specified by an snum.
4912  */
4913 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4914 {
4915         void *parm_ptr;
4916
4917         if (parm.ptr == NULL) {
4918                 return;
4919         }
4920
4921         if (snum < 0) {
4922                 parm_ptr = parm.ptr;
4923         } else if (parm.p_class != P_LOCAL) {
4924                 return;
4925         } else {
4926                 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4927         }
4928
4929         free_one_parameter_common(parm_ptr, parm);
4930 }
4931
4932 /**
4933  * Free the allocated parameter data for a share specified
4934  * by an snum.
4935  */
4936 static void free_parameters_by_snum(int snum)
4937 {
4938         uint32_t i;
4939
4940         for (i=0; parm_table[i].label; i++) {
4941                 free_one_parameter_by_snum(snum, parm_table[i]);
4942         }
4943 }
4944
4945 /**
4946  * Free the allocated global parameters.
4947  */
4948 static void free_global_parameters(void)
4949 {
4950         free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4951 }
4952
4953 /***************************************************************************
4954  Initialise the global parameter structure.
4955 ***************************************************************************/
4956
4957 static void init_globals(bool first_time_only)
4958 {
4959         static bool done_init = False;
4960         char *s = NULL;
4961         int i;
4962
4963         /* If requested to initialize only once and we've already done it... */
4964         if (first_time_only && done_init) {
4965                 /* ... then we have nothing more to do */
4966                 return;
4967         }
4968
4969         if (!done_init) {
4970                 /* The logfile can be set before this is invoked. Free it if so. */
4971                 if (Globals.szLogFile != NULL) {
4972                         string_free(&Globals.szLogFile);
4973                         Globals.szLogFile = NULL;
4974                 }
4975                 done_init = True;
4976         } else {
4977                 free_global_parameters();
4978         }
4979
4980         memset((void *)&Globals, '\0', sizeof(Globals));
4981
4982         for (i = 0; parm_table[i].label; i++) {
4983                 if ((parm_table[i].type == P_STRING ||
4984                      parm_table[i].type == P_USTRING) &&
4985                     parm_table[i].ptr)
4986                 {
4987                         string_set((char **)parm_table[i].ptr, "");
4988                 }
4989         }
4990
4991         string_set(&sDefault.fstype, FSTYPE_STRING);
4992         string_set(&sDefault.szPrintjobUsername, "%U");
4993
4994         init_printer_values(&sDefault);
4995
4996
4997         DEBUG(3, ("Initialising global parameters\n"));
4998
4999         string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
5000         string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
5001
5002         /* use the new 'hash2' method by default, with a prefix of 1 */
5003         string_set(&Globals.szManglingMethod, "hash2");
5004         Globals.mangle_prefix = 1;
5005
5006         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5007
5008         /* using UTF8 by default allows us to support all chars */
5009         string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5010
5011 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
5012         /* If the system supports nl_langinfo(), try to grab the value
5013            from the user's locale */
5014         string_set(&Globals.display_charset, "LOCALE");
5015 #else
5016         string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
5017 #endif
5018
5019         /* Use codepage 850 as a default for the dos character set */
5020         string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5021
5022         /*
5023          * Allow the default PASSWD_CHAT to be overridden in local.h.
5024          */
5025         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5026
5027         set_global_myname(myhostname());
5028         string_set(&Globals.szNetbiosName,global_myname());
5029
5030         set_global_myworkgroup(WORKGROUP);
5031         string_set(&Globals.szWorkgroup, lp_workgroup());
5032
5033         string_set(&Globals.szPasswdProgram, "");
5034         string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5035         string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5036         string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5037         string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5038         string_set(&Globals.szSocketAddress, "0.0.0.0");
5039         /*
5040          * By default support explicit binding to broadcast
5041          * addresses.
5042          */
5043         Globals.bNmbdBindExplicitBroadcast = true;
5044
5045         if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5046                 smb_panic("init_globals: ENOMEM");
5047         }
5048         string_set(&Globals.szServerString, s);
5049         SAFE_FREE(s);
5050         if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5051                         DEFAULT_MINOR_VERSION) < 0) {
5052                 smb_panic("init_globals: ENOMEM");
5053         }
5054         string_set(&Globals.szAnnounceVersion, s);
5055         SAFE_FREE(s);
5056 #ifdef DEVELOPER
5057         string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5058 #endif
5059
5060         string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5061
5062         string_set(&Globals.szLogonDrive, "");
5063         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5064         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5065         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5066
5067         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5068         string_set(&Globals.szPasswordServer, "*");
5069
5070         Globals.AlgorithmicRidBase = BASE_RID;
5071
5072         Globals.bLoadPrinters = True;
5073         Globals.PrintcapCacheTime = 750;        /* 12.5 minutes */
5074
5075         Globals.ConfigBackend = config_backend;
5076
5077         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5078         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5079         Globals.max_xmit = 0x4104;
5080         Globals.max_mux = 50;   /* This is *needed* for profile support. */
5081         Globals.lpqcachetime = 30;      /* changed to handle large print servers better -- jerry */
5082         Globals.bDisableSpoolss = False;
5083         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5084         Globals.pwordlevel = 0;
5085         Globals.unamelevel = 0;
5086         Globals.deadtime = 0;
5087         Globals.getwd_cache = true;
5088         Globals.bLargeReadwrite = True;
5089         Globals.max_log_size = 5000;
5090         Globals.max_open_files = max_open_files();
5091         Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5092         Globals.maxprotocol = PROTOCOL_NT1;
5093         Globals.minprotocol = PROTOCOL_CORE;
5094         Globals.security = SEC_USER;
5095         Globals.paranoid_server_security = True;
5096         Globals.bEncryptPasswords = True;
5097         Globals.bUpdateEncrypt = False;
5098         Globals.clientSchannel = Auto;
5099         Globals.serverSchannel = Auto;
5100         Globals.bReadRaw = True;
5101         Globals.bWriteRaw = True;
5102         Globals.bNullPasswords = False;
5103         Globals.bObeyPamRestrictions = False;
5104         Globals.syslog = 1;
5105         Globals.bSyslogOnly = False;
5106         Globals.bTimestampLogs = True;
5107         string_set(&Globals.szLogLevel, "0");
5108         Globals.bDebugPrefixTimestamp = False;
5109         Globals.bDebugHiresTimestamp = true;
5110         Globals.bDebugPid = False;
5111         Globals.bDebugUid = False;
5112         Globals.bDebugClass = False;
5113         Globals.bEnableCoreFiles = True;
5114         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
5115         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
5116         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
5117         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
5118         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
5119         Globals.lm_interval = 60;
5120         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5121 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5122         Globals.bNISHomeMap = False;
5123 #ifdef WITH_NISPLUS_HOME
5124         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5125 #else
5126         string_set(&Globals.szNISHomeMapName, "auto.home");
5127 #endif
5128 #endif
5129         Globals.bTimeServer = False;
5130         Globals.bBindInterfacesOnly = False;
5131         Globals.bUnixPasswdSync = False;
5132         Globals.bPamPasswordChange = False;
5133         Globals.bPasswdChatDebug = False;
5134         Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5135         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
5136         Globals.bNTStatusSupport = True; /* Use NT status by default. */
5137         Globals.bStatCache = True;      /* use stat cache by default */
5138         Globals.iMaxStatCacheSize = 256; /* 256k by default */
5139         Globals.restrict_anonymous = 0;
5140         Globals.bClientLanManAuth = False;      /* Do NOT use the LanMan hash if it is available */
5141         Globals.bClientPlaintextAuth = False;   /* Do NOT use a plaintext password even if is requested by the server */
5142         Globals.bLanmanAuth = False;    /* Do NOT use the LanMan hash, even if it is supplied */
5143         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5144         Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
5145         /* Note, that we will use NTLM2 session security (which is different), if it is available */
5146
5147         Globals.map_to_guest = 0;       /* By Default, "Never" */
5148         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
5149         Globals.enhanced_browsing = true;
5150         Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5151 #ifdef MMAP_BLACKLIST
5152         Globals.bUseMmap = False;
5153 #else
5154         Globals.bUseMmap = True;
5155 #endif
5156         Globals.bUnixExtensions = True;
5157         Globals.bResetOnZeroVC = False;
5158         Globals.bLogWriteableFilesOnExit = False;
5159         Globals.bCreateKrb5Conf = true;
5160
5161         /* hostname lookups can be very expensive and are broken on
5162            a large number of sites (tridge) */
5163         Globals.bHostnameLookups = False;
5164
5165         string_set(&Globals.szPassdbBackend, "tdbsam");
5166         string_set(&Globals.szLdapSuffix, "");
5167         string_set(&Globals.szLdapMachineSuffix, "");
5168         string_set(&Globals.szLdapUserSuffix, "");
5169         string_set(&Globals.szLdapGroupSuffix, "");
5170         string_set(&Globals.szLdapIdmapSuffix, "");
5171
5172         string_set(&Globals.szLdapAdminDn, "");
5173         Globals.ldap_ssl = LDAP_SSL_START_TLS;
5174         Globals.ldap_ssl_ads = False;
5175         Globals.ldap_deref = -1;
5176         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5177         Globals.ldap_delete_dn = False;
5178         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5179         Globals.ldap_follow_referral = Auto;
5180         Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5181         Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5182         Globals.ldap_page_size = LDAP_PAGE_SIZE;
5183
5184         Globals.ldap_debug_level = 0;
5185         Globals.ldap_debug_threshold = 10;
5186
5187         /* This is what we tell the afs client. in reality we set the token 
5188          * to never expire, though, when this runs out the afs client will 
5189          * forget the token. Set to 0 to get NEVERDATE.*/
5190         Globals.iAfsTokenLifetime = 604800;
5191         Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5192
5193 /* these parameters are set to defaults that are more appropriate
5194    for the increasing samba install base:
5195
5196    as a member of the workgroup, that will possibly become a
5197    _local_ master browser (lm = True).  this is opposed to a forced
5198    local master browser startup (pm = True).
5199
5200    doesn't provide WINS server service by default (wsupp = False),
5201    and doesn't provide domain master browser services by default, either.
5202
5203 */
5204
5205         Globals.bMsAddPrinterWizard = True;
5206         Globals.os_level = 20;
5207         Globals.bLocalMaster = True;
5208         Globals.iDomainMaster = Auto;   /* depending on bDomainLogons */
5209         Globals.bDomainLogons = False;
5210         Globals.bBrowseList = True;
5211         Globals.bWINSsupport = False;
5212         Globals.bWINSproxy = False;
5213
5214         TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5215         Globals.InitLogonDelay = 100; /* 100 ms default delay */
5216
5217         Globals.bDNSproxy = True;
5218
5219         /* this just means to use them if they exist */
5220         Globals.bKernelOplocks = True;
5221
5222         Globals.bAllowTrustedDomains = True;
5223         string_set(&Globals.szIdmapBackend, "tdb");
5224
5225         string_set(&Globals.szTemplateShell, "/bin/false");
5226         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5227         string_set(&Globals.szWinbindSeparator, "\\");
5228
5229         string_set(&Globals.szCupsServer, "");
5230         string_set(&Globals.szIPrintServer, "");
5231
5232         string_set(&Globals.ctdbdSocket, "");
5233         Globals.szClusterAddresses = NULL;
5234         Globals.clustering = False;
5235         Globals.ctdb_timeout = 0;
5236         Globals.ctdb_locktime_warn_threshold = 0;
5237
5238         Globals.winbind_cache_time = 300;       /* 5 minutes */
5239         Globals.winbind_reconnect_delay = 30;   /* 30 seconds */
5240         Globals.bWinbindEnumUsers = False;
5241         Globals.bWinbindEnumGroups = False;
5242         Globals.bWinbindUseDefaultDomain = False;
5243         Globals.bWinbindTrustedDomainsOnly = False;
5244         Globals.bWinbindNestedGroups = True;
5245         Globals.winbind_expand_groups = 1;
5246         Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5247         Globals.bWinbindRefreshTickets = False;
5248         Globals.bWinbindOfflineLogon = False;
5249
5250         Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5251         Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5252
5253         Globals.bPassdbExpandExplicit = False;
5254
5255         Globals.name_cache_timeout = 660; /* In seconds */
5256
5257         Globals.bUseSpnego = True;
5258         Globals.bClientUseSpnego = True;
5259
5260         Globals.client_signing = Auto;
5261         Globals.server_signing = False;
5262
5263         Globals.bDeferSharingViolations = True;
5264         string_set(&Globals.smb_ports, SMB_PORTS);
5265
5266         Globals.bEnablePrivileges = True;
5267         Globals.bHostMSDfs        = True;
5268         Globals.bASUSupport       = False;
5269
5270         /* User defined shares. */
5271         if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5272                 smb_panic("init_globals: ENOMEM");
5273         }
5274         string_set(&Globals.szUsersharePath, s);
5275         SAFE_FREE(s);
5276         string_set(&Globals.szUsershareTemplateShare, "");
5277         Globals.iUsershareMaxShares = 0;
5278         /* By default disallow sharing of directories not owned by the sharer. */
5279         Globals.bUsershareOwnerOnly = True;
5280         /* By default disallow guest access to usershares. */
5281         Globals.bUsershareAllowGuests = False;
5282
5283         Globals.iKeepalive = DEFAULT_KEEPALIVE;
5284
5285         /* By default no shares out of the registry */
5286         Globals.bRegistryShares = False;
5287
5288         Globals.iminreceivefile = 0;
5289
5290         Globals.bMapUntrustedToDomain = false;
5291
5292         Globals.ismb2_max_read = 1024*1024;
5293         Globals.ismb2_max_write = 1024*1024;
5294         Globals.ismb2_max_trans = 1024*1024;
5295 }
5296
5297 /*******************************************************************
5298  Convenience routine to grab string parameters into temporary memory
5299  and run standard_sub_basic on them. The buffers can be written to by
5300  callers without affecting the source string.
5301 ********************************************************************/
5302
5303 static char *lp_string(const char *s)
5304 {
5305         char *ret;
5306         TALLOC_CTX *ctx = talloc_tos();
5307
5308         /* The follow debug is useful for tracking down memory problems
5309            especially if you have an inner loop that is calling a lp_*()
5310            function that returns a string.  Perhaps this debug should be
5311            present all the time? */
5312
5313 #if 0
5314         DEBUG(10, ("lp_string(%s)\n", s));
5315 #endif
5316         if (!s) {
5317                 return NULL;
5318         }
5319
5320         ret = talloc_sub_basic(ctx,
5321                         get_current_username(),
5322                         current_user_info.domain,
5323                         s);
5324         if (trim_char(ret, '\"', '\"')) {
5325                 if (strchr(ret,'\"') != NULL) {
5326                         TALLOC_FREE(ret);
5327                         ret = talloc_sub_basic(ctx,
5328                                         get_current_username(),
5329                                         current_user_info.domain,
5330                                         s);
5331                 }
5332         }
5333         return ret;
5334 }
5335
5336 /*
5337    In this section all the functions that are used to access the
5338    parameters from the rest of the program are defined
5339 */
5340
5341 #define FN_GLOBAL_STRING(fn_name,ptr) \
5342  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5343 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5344  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5345 #define FN_GLOBAL_LIST(fn_name,ptr) \
5346  const char **fn_name(void) {return(*(const char ***)(ptr));}
5347 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5348  bool fn_name(void) {return(*(bool *)(ptr));}
5349 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5350  char fn_name(void) {return(*(char *)(ptr));}
5351 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5352  int fn_name(void) {return(*(int *)(ptr));}
5353
5354 #define FN_LOCAL_STRING(fn_name,val) \
5355  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5356 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5357  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5358 #define FN_LOCAL_LIST(fn_name,val) \
5359  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5360 #define FN_LOCAL_BOOL(fn_name,val) \
5361  bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5362 #define FN_LOCAL_INTEGER(fn_name,val) \
5363  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5364
5365 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5366  bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5367 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5368  int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5369 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5370  char *fn_name(const struct share_params *p) {return(lp_string((LP_SNUM_OK(p->service) && ServicePtrs[(p->service)]->val) ? ServicePtrs[(p->service)]->val : sDefault.val));}
5371 #define FN_LOCAL_CHAR(fn_name,val) \
5372  char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5373
5374 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5375 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5376 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5377 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5378 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5379 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5380 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5381 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5382 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5383 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5384 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5385 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5386 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5387 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5388 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5389 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5390 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5391  * build process or in smb.conf, we use that value.  Otherwise they
5392  * default to the value of lp_lockdir(). */
5393 char *lp_statedir(void) {
5394         if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5395             (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5396                 return(lp_string(*(char **)(&Globals.szStateDir) ?
5397                     *(char **)(&Globals.szStateDir) : ""));
5398         else
5399                 return(lp_string(*(char **)(&Globals.szLockDir) ?
5400                     *(char **)(&Globals.szLockDir) : ""));
5401 }
5402 char *lp_cachedir(void) {
5403         if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5404             (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5405                 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5406                     *(char **)(&Globals.szCacheDir) : ""));
5407         else
5408                 return(lp_string(*(char **)(&Globals.szLockDir) ?
5409                     *(char **)(&Globals.szLockDir) : ""));
5410 }
5411 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5412 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5413 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5414 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5415 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5416 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5417 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5418 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5419 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5420 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5421 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5422 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5423 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5424 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5425 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5426 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5427 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5428 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5429 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5430 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5431 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5432 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5433 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5434 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5435 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5436 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5437 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5438 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5439 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5440 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5441 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5442 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5443 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5444 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5445 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5446  * lp_passdb_backend() should be replace by the this macro again after
5447  * some releases.
5448  * */
5449 const char *lp_passdb_backend(void)
5450 {
5451         char *delim, *quote;
5452
5453         delim = strchr( Globals.szPassdbBackend, ' ');
5454         /* no space at all */
5455         if (delim == NULL) {
5456                 goto out;
5457         }
5458
5459         quote = strchr(Globals.szPassdbBackend, '"');
5460         /* no quote char or non in the first part */
5461         if (quote == NULL || quote > delim) {
5462                 *delim = '\0';
5463                 goto warn;
5464         }
5465
5466         quote = strchr(quote+1, '"');
5467         if (quote == NULL) {
5468                 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5469                 goto out;
5470         } else if (*(quote+1) == '\0') {
5471                 /* space, fitting quote char, and one backend only */
5472                 goto out;
5473         } else {
5474                 /* terminate string after the fitting quote char */
5475                 *(quote+1) = '\0';
5476         }
5477
5478 warn:
5479         DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends.  This\n"
5480                 "is deprecated since Samba 3.0.23.  Please check WHATSNEW.txt or the section 'Passdb\n"
5481                 "Changes' from the ChangeNotes as part of the Samba HOWTO collection.  Only the first\n"
5482                 "backend (%s) is used.  The rest is ignored.\n", Globals.szPassdbBackend));
5483
5484 out:
5485         return Globals.szPassdbBackend;
5486 }
5487 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5488 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5489 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5490 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5491 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5492
5493 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5494 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5495 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5496 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5497 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5498 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5499
5500 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5501
5502 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5503 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5504 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5505 FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
5506
5507 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5508
5509 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5510 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5511 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5512 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5513 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5514 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5515 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5516 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5517 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5518 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5519 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5520 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5521 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5522 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5523 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5524 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5525
5526 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5527 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5528 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5529 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5530 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5531 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5532
5533 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5534 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5535 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5536 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5537 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5538 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5539 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5540 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5541 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5542 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5543 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5544 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5545 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5546 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5547 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5548 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5549 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5550 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5551 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5552 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5553
5554 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5555
5556 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5557 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5558 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5559 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5560 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5561 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5562                &Globals.bLogWriteableFilesOnExit)
5563 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5564 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5565 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5566 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5567 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5568 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5569 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5570 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5571 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5572 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5573 FN_GLOBAL_BOOL(_lp_readraw, &Globals.bReadRaw)
5574 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5575 FN_GLOBAL_BOOL(_lp_writeraw, &Globals.bWriteRaw)
5576 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5577 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5578 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5579 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5580 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5581 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5582 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5583 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5584 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5585 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5586 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5587 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5588 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5589 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5590 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5591 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5592 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5593 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5594 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5595 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5596 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5597 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5598 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5599 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5600 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5601 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5602 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5603 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5604 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5605 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5606 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5607 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5608 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5609 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5610 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5611 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5612 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5613 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5614 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5615 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5616 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5617 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5618 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5619 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5620 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5621 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5622 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5623 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5624 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5625 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5626 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5627 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5628 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5629 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5630 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5631 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5632 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5633 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5634 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5635 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5636 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5637 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5638 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5639 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5640 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5641 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5642 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5643 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5644 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5645 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5646 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5647 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5648 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5649 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5650 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5651 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5652 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5653 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5654 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5655 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5656 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5657 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5658 FN_GLOBAL_INTEGER(lp_smb2_max_read, &Globals.ismb2_max_read)
5659 FN_GLOBAL_INTEGER(lp_smb2_max_write, &Globals.ismb2_max_write)
5660 FN_GLOBAL_INTEGER(lp_smb2_max_trans, &Globals.ismb2_max_trans)
5661
5662 FN_LOCAL_STRING(lp_preexec, szPreExec)
5663 FN_LOCAL_STRING(lp_postexec, szPostExec)
5664 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5665 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5666 FN_LOCAL_STRING(lp_servicename, szService)
5667 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5668 FN_LOCAL_STRING(lp_pathname, szPath)
5669 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5670 FN_LOCAL_STRING(lp_username, szUsername)
5671 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5672 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5673 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5674 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5675 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5676 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5677 int lp_cups_encrypt(void)
5678 {
5679         int result = 0;
5680 #ifdef HAVE_HTTPCONNECTENCRYPT
5681         switch (Globals.CupsEncrypt) {
5682                 case Auto:
5683                         result = HTTP_ENCRYPT_REQUIRED;
5684                         break;
5685                 case True:
5686                         result = HTTP_ENCRYPT_ALWAYS;
5687                         break;
5688                 case False:
5689                         result = HTTP_ENCRYPT_NEVER;
5690                         break;
5691         }
5692 #endif
5693         return result;
5694 }
5695 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5696 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5697 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5698 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5699 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5700 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5701 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, &Globals.ctdb_locktime_warn_threshold)
5702 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5703 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5704 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5705 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5706 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5707 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5708 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5709 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5710 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5711 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5712 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5713 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5714 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5715 FN_LOCAL_STRING(lp_comment, comment)
5716 FN_LOCAL_STRING(lp_force_user, force_user)
5717 FN_LOCAL_STRING(lp_force_group, force_group)
5718 FN_LOCAL_LIST(lp_readlist, readlist)
5719 FN_LOCAL_LIST(lp_writelist, writelist)
5720 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5721 FN_LOCAL_STRING(lp_fstype, fstype)
5722 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5723 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5724 static FN_LOCAL_STRING(lp_volume, volume)
5725 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5726 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5727 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5728 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5729 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5730 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5731 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5732 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5733 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5734 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5735 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5736 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5737 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5738 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5739 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5740 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5741 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5742 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5743 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5744 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5745 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5746 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5747 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5748 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5749 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5750 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5751 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5752 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5753 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5754 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5755 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5756 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5757 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5758 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5759 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5760 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5761 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5762 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5763 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5764 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5765 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5766 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5767 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5768 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5769 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5770 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5771 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5772 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5773 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5774 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5775 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5776 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5777 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5778 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5779 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5780 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5781 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5782 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5783 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5784 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5785 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5786 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5787 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5788 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5789 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5790 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5791 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5792 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5793 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5794 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5795 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5796 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5797 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5798 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5799 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5800 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5801 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5802 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5803 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5804 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5805 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5806 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5807 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5808 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5809 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5810 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5811 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5812 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5813 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5814 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5815 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5816 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5817 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5818 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5819 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5820 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5821 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5822 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5823 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5824
5825 /* local prototypes */
5826
5827 static int map_parameter(const char *pszParmName);
5828 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5829 static const char *get_boolean(bool bool_value);
5830 static int getservicebyname(const char *pszServiceName,
5831                             struct service *pserviceDest);
5832 static void copy_service(struct service *pserviceDest,
5833                          struct service *pserviceSource,
5834                          struct bitmap *pcopymapDest);
5835 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5836                          void *userdata);
5837 static bool do_section(const char *pszSectionName, void *userdata);
5838 static void init_copymap(struct service *pservice);
5839 static bool hash_a_service(const char *name, int number);
5840 static void free_service_byindex(int iService);
5841 static void free_param_opts(struct param_opt_struct **popts);
5842 static void show_parameter(int parmIndex);
5843 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5844
5845 /*
5846  * This is a helper function for parametrical options support.  It returns a
5847  * pointer to parametrical option value if it exists or NULL otherwise. Actual
5848  * parametrical functions are quite simple
5849  */
5850 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5851                                                 const char *option)
5852 {
5853         bool global_section = False;
5854         char* param_key;
5855         struct param_opt_struct *data;
5856
5857         if (snum >= iNumServices) return NULL;
5858
5859         if (snum < 0) { 
5860                 data = Globals.param_opt;
5861                 global_section = True;
5862         } else {
5863                 data = ServicePtrs[snum]->param_opt;
5864         }
5865
5866         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5867                 DEBUG(0,("asprintf failed!\n"));
5868                 return NULL;
5869         }
5870
5871         while (data) {
5872                 if (strwicmp(data->key, param_key) == 0) {
5873                         string_free(&param_key);
5874                         return data;
5875                 }
5876                 data = data->next;
5877         }
5878
5879         if (!global_section) {
5880                 /* Try to fetch the same option but from globals */
5881                 /* but only if we are not already working with Globals */
5882                 data = Globals.param_opt;
5883                 while (data) {
5884                         if (strwicmp(data->key, param_key) == 0) {
5885                                 string_free(&param_key);
5886                                 return data;
5887                         }
5888                         data = data->next;
5889                 }
5890         }
5891
5892         string_free(&param_key);
5893
5894         return NULL;
5895 }
5896
5897
5898 #define MISSING_PARAMETER(name) \
5899     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5900
5901 /*******************************************************************
5902 convenience routine to return int parameters.
5903 ********************************************************************/
5904 static int lp_int(const char *s)
5905 {
5906
5907         if (!s || !*s) {
5908                 MISSING_PARAMETER(lp_int);
5909                 return (-1);
5910         }
5911
5912         return (int)strtol(s, NULL, 0);
5913 }
5914
5915 /*******************************************************************
5916 convenience routine to return unsigned long parameters.
5917 ********************************************************************/
5918 static unsigned long lp_ulong(const char *s)
5919 {
5920
5921         if (!s || !*s) {
5922                 MISSING_PARAMETER(lp_ulong);
5923                 return (0);
5924         }
5925
5926         return strtoul(s, NULL, 0);
5927 }
5928
5929 /*******************************************************************
5930 convenience routine to return boolean parameters.
5931 ********************************************************************/
5932 static bool lp_bool(const char *s)
5933 {
5934         bool ret = False;
5935
5936         if (!s || !*s) {
5937                 MISSING_PARAMETER(lp_bool);
5938                 return False;
5939         }
5940
5941         if (!set_boolean(s, &ret)) {
5942                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5943                 return False;
5944         }
5945
5946         return ret;
5947 }
5948
5949 /*******************************************************************
5950 convenience routine to return enum parameters.
5951 ********************************************************************/
5952 static int lp_enum(const char *s,const struct enum_list *_enum)
5953 {
5954         int i;
5955
5956         if (!s || !*s || !_enum) {
5957                 MISSING_PARAMETER(lp_enum);
5958                 return (-1);
5959         }
5960
5961         for (i=0; _enum[i].name; i++) {
5962                 if (strequal(_enum[i].name,s))
5963                         return _enum[i].value;
5964         }
5965
5966         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5967         return (-1);
5968 }
5969
5970 #undef MISSING_PARAMETER
5971
5972 /* DO NOT USE lp_parm_string ANYMORE!!!!
5973  * use lp_parm_const_string or lp_parm_talloc_string
5974  *
5975  * lp_parm_string is only used to let old modules find this symbol
5976  */
5977 #undef lp_parm_string
5978  char *lp_parm_string(const char *servicename, const char *type, const char *option);
5979  char *lp_parm_string(const char *servicename, const char *type, const char *option)
5980 {
5981         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5982 }
5983
5984 /* Return parametric option from a given service. Type is a part of option before ':' */
5985 /* Parametric option has following syntax: 'Type: option = value' */
5986 /* the returned value is talloced on the talloc_tos() */
5987 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5988 {
5989         struct param_opt_struct *data = get_parametrics(snum, type, option);
5990
5991         if (data == NULL||data->value==NULL) {
5992                 if (def) {
5993                         return lp_string(def);
5994                 } else {
5995                         return NULL;
5996                 }
5997         }
5998
5999         return lp_string(data->value);
6000 }
6001
6002 /* Return parametric option from a given service. Type is a part of option before ':' */
6003 /* Parametric option has following syntax: 'Type: option = value' */
6004 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6005 {
6006         struct param_opt_struct *data = get_parametrics(snum, type, option);
6007
6008         if (data == NULL||data->value==NULL)
6009                 return def;
6010
6011         return data->value;
6012 }
6013
6014 /* Return parametric option from a given service. Type is a part of option before ':' */
6015 /* Parametric option has following syntax: 'Type: option = value' */
6016
6017 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6018 {
6019         struct param_opt_struct *data = get_parametrics(snum, type, option);
6020
6021         if (data == NULL||data->value==NULL)
6022                 return (const char **)def;
6023
6024         if (data->list==NULL) {
6025                 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
6026         }
6027
6028         return (const char **)data->list;
6029 }
6030
6031 /* Return parametric option from a given service. Type is a part of option before ':' */
6032 /* Parametric option has following syntax: 'Type: option = value' */
6033
6034 int lp_parm_int(int snum, const char *type, const char *option, int def)
6035 {
6036         struct param_opt_struct *data = get_parametrics(snum, type, option);
6037
6038         if (data && data->value && *data->value)
6039                 return lp_int(data->value);
6040
6041         return def;
6042 }
6043
6044 /* Return parametric option from a given service. Type is a part of option before ':' */
6045 /* Parametric option has following syntax: 'Type: option = value' */
6046
6047 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6048 {
6049         struct param_opt_struct *data = get_parametrics(snum, type, option);
6050
6051         if (data && data->value && *data->value)
6052                 return lp_ulong(data->value);
6053
6054         return def;
6055 }
6056
6057 /* Return parametric option from a given service. Type is a part of option before ':' */
6058 /* Parametric option has following syntax: 'Type: option = value' */
6059
6060 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6061 {
6062         struct param_opt_struct *data = get_parametrics(snum, type, option);
6063
6064         if (data && data->value && *data->value)
6065                 return lp_bool(data->value);
6066
6067         return def;
6068 }
6069
6070 /* Return parametric option from a given service. Type is a part of option before ':' */
6071 /* Parametric option has following syntax: 'Type: option = value' */
6072
6073 int lp_parm_enum(int snum, const char *type, const char *option,
6074                  const struct enum_list *_enum, int def)
6075 {
6076         struct param_opt_struct *data = get_parametrics(snum, type, option);
6077
6078         if (data && data->value && *data->value && _enum)
6079                 return lp_enum(data->value, _enum);
6080
6081         return def;
6082 }
6083
6084
6085 /***************************************************************************
6086  Initialise a service to the defaults.
6087 ***************************************************************************/
6088
6089 static void init_service(struct service *pservice)
6090 {
6091         memset((char *)pservice, '\0', sizeof(struct service));
6092         copy_service(pservice, &sDefault, NULL);
6093 }
6094
6095
6096 /**
6097  * free a param_opts structure.
6098  * param_opts handling should be moved to talloc;
6099  * then this whole functions reduces to a TALLOC_FREE().
6100  */
6101
6102 static void free_param_opts(struct param_opt_struct **popts)
6103 {
6104         struct param_opt_struct *opt, *next_opt;
6105
6106         if (popts == NULL) {
6107                 return;
6108         }
6109
6110         if (*popts != NULL) {
6111                 DEBUG(5, ("Freeing parametrics:\n"));
6112         }
6113         opt = *popts;
6114         while (opt != NULL) {
6115                 string_free(&opt->key);
6116                 string_free(&opt->value);
6117                 TALLOC_FREE(opt->list);
6118                 next_opt = opt->next;
6119                 SAFE_FREE(opt);
6120                 opt = next_opt;
6121         }
6122         *popts = NULL;
6123 }
6124
6125 /***************************************************************************
6126  Free the dynamically allocated parts of a service struct.
6127 ***************************************************************************/
6128
6129 static void free_service(struct service *pservice)
6130 {
6131         if (!pservice)
6132                 return;
6133
6134         if (pservice->szService)
6135                 DEBUG(5, ("free_service: Freeing service %s\n",
6136                        pservice->szService));
6137
6138         free_parameters(pservice);
6139
6140         string_free(&pservice->szService);
6141         TALLOC_FREE(pservice->copymap);
6142
6143         free_param_opts(&pservice->param_opt);
6144
6145         ZERO_STRUCTP(pservice);
6146 }
6147
6148
6149 /***************************************************************************
6150  remove a service indexed in the ServicePtrs array from the ServiceHash
6151  and free the dynamically allocated parts
6152 ***************************************************************************/
6153
6154 static void free_service_byindex(int idx)
6155 {
6156         if ( !LP_SNUM_OK(idx) ) 
6157                 return;
6158
6159         ServicePtrs[idx]->valid = False;
6160         invalid_services[num_invalid_services++] = idx;
6161
6162         /* we have to cleanup the hash record */
6163
6164         if (ServicePtrs[idx]->szService) {
6165                 char *canon_name = canonicalize_servicename(
6166                         talloc_tos(),
6167                         ServicePtrs[idx]->szService );
6168
6169                 dbwrap_delete_bystring(ServiceHash, canon_name );
6170                 TALLOC_FREE(canon_name);
6171         }
6172
6173         free_service(ServicePtrs[idx]);
6174 }
6175
6176 /***************************************************************************
6177  Add a new service to the services array initialising it with the given 
6178  service. 
6179 ***************************************************************************/
6180
6181 static int add_a_service(const struct service *pservice, const char *name)
6182 {
6183         int i;
6184         struct service tservice;
6185         int num_to_alloc = iNumServices + 1;
6186
6187         tservice = *pservice;
6188
6189         /* it might already exist */
6190         if (name) {
6191                 i = getservicebyname(name, NULL);
6192                 if (i >= 0) {
6193                         /* Clean all parametric options for service */
6194                         /* They will be added during parsing again */
6195                         free_param_opts(&ServicePtrs[i]->param_opt);
6196                         return (i);
6197                 }
6198         }
6199
6200         /* find an invalid one */
6201         i = iNumServices;
6202         if (num_invalid_services > 0) {
6203                 i = invalid_services[--num_invalid_services];
6204         }
6205
6206         /* if not, then create one */
6207         if (i == iNumServices) {
6208                 struct service **tsp;
6209                 int *tinvalid;
6210
6211                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6212                 if (tsp == NULL) {
6213                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6214                         return (-1);
6215                 }
6216                 ServicePtrs = tsp;
6217                 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6218                 if (!ServicePtrs[iNumServices]) {
6219                         DEBUG(0,("add_a_service: out of memory!\n"));
6220                         return (-1);
6221                 }
6222                 iNumServices++;
6223
6224                 /* enlarge invalid_services here for now... */
6225                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6226                                              num_to_alloc);
6227                 if (tinvalid == NULL) {
6228                         DEBUG(0,("add_a_service: failed to enlarge "
6229                                  "invalid_services!\n"));
6230                         return (-1);
6231                 }
6232                 invalid_services = tinvalid;
6233         } else {
6234                 free_service_byindex(i);
6235         }
6236
6237         ServicePtrs[i]->valid = True;
6238
6239         init_service(ServicePtrs[i]);
6240         copy_service(ServicePtrs[i], &tservice, NULL);
6241         if (name)
6242                 string_set(&ServicePtrs[i]->szService, name);
6243
6244         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
6245                 i, ServicePtrs[i]->szService));
6246
6247         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6248                 return (-1);
6249         }
6250
6251         return (i);
6252 }
6253
6254 /***************************************************************************
6255   Convert a string to uppercase and remove whitespaces.
6256 ***************************************************************************/
6257
6258 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6259 {
6260         char *result;
6261
6262         if ( !src ) {
6263                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6264                 return NULL;
6265         }
6266
6267         result = talloc_strdup(ctx, src);
6268         SMB_ASSERT(result != NULL);
6269
6270         strlower_m(result);
6271         return result;
6272 }
6273
6274 /***************************************************************************
6275   Add a name/index pair for the services array to the hash table.
6276 ***************************************************************************/
6277
6278 static bool hash_a_service(const char *name, int idx)
6279 {
6280         char *canon_name;
6281
6282         if ( !ServiceHash ) {
6283                 DEBUG(10,("hash_a_service: creating servicehash\n"));
6284                 ServiceHash = db_open_rbt(NULL);
6285                 if ( !ServiceHash ) {
6286                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6287                         return False;
6288                 }
6289         }
6290
6291         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6292                 idx, name));
6293
6294         canon_name = canonicalize_servicename(talloc_tos(), name );
6295
6296         dbwrap_store_bystring(ServiceHash, canon_name,
6297                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
6298                               TDB_REPLACE);
6299
6300         TALLOC_FREE(canon_name);
6301
6302         return True;
6303 }
6304
6305 /***************************************************************************
6306  Add a new home service, with the specified home directory, defaults coming
6307  from service ifrom.
6308 ***************************************************************************/
6309
6310 bool lp_add_home(const char *pszHomename, int iDefaultService,
6311                  const char *user, const char *pszHomedir)
6312 {
6313         int i;
6314
6315         if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6316                         pszHomedir[0] == '\0') {
6317                 return false;
6318         }
6319
6320         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6321
6322         if (i < 0)
6323                 return (False);
6324
6325         if (!(*(ServicePtrs[iDefaultService]->szPath))
6326             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6327                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6328         }
6329
6330         if (!(*(ServicePtrs[i]->comment))) {
6331                 char *comment = NULL;
6332                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6333                         return false;
6334                 }
6335                 string_set(&ServicePtrs[i]->comment, comment);
6336                 SAFE_FREE(comment);
6337         }
6338
6339         /* set the browseable flag from the global default */
6340
6341         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6342         ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6343
6344         ServicePtrs[i]->autoloaded = True;
6345
6346         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
6347                user, ServicePtrs[i]->szPath ));
6348
6349         return (True);
6350 }
6351
6352 /***************************************************************************
6353  Add a new service, based on an old one.
6354 ***************************************************************************/
6355
6356 int lp_add_service(const char *pszService, int iDefaultService)
6357 {
6358         if (iDefaultService < 0) {
6359                 return add_a_service(&sDefault, pszService);
6360         }
6361
6362         return (add_a_service(ServicePtrs[iDefaultService], pszService));
6363 }
6364
6365 /***************************************************************************
6366  Add the IPC service.
6367 ***************************************************************************/
6368
6369 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6370 {
6371         char *comment = NULL;
6372         int i = add_a_service(&sDefault, ipc_name);
6373
6374         if (i < 0)
6375                 return (False);
6376
6377         if (asprintf(&comment, "IPC Service (%s)",
6378                                 Globals.szServerString) < 0) {
6379                 return (False);
6380         }
6381
6382         string_set(&ServicePtrs[i]->szPath, tmpdir());
6383         string_set(&ServicePtrs[i]->szUsername, "");
6384         string_set(&ServicePtrs[i]->comment, comment);
6385         string_set(&ServicePtrs[i]->fstype, "IPC");
6386         ServicePtrs[i]->iMaxConnections = 0;
6387         ServicePtrs[i]->bAvailable = True;
6388         ServicePtrs[i]->bRead_only = True;
6389         ServicePtrs[i]->bGuest_only = False;
6390         ServicePtrs[i]->bAdministrative_share = True;
6391         ServicePtrs[i]->bGuest_ok = guest_ok;
6392         ServicePtrs[i]->bPrint_ok = False;
6393         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6394
6395         DEBUG(3, ("adding IPC service\n"));
6396
6397         SAFE_FREE(comment);
6398         return (True);
6399 }
6400
6401 /***************************************************************************
6402  Add a new printer service, with defaults coming from service iFrom.
6403 ***************************************************************************/
6404
6405 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6406 {
6407         const char *comment = "From Printcap";
6408         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6409
6410         if (i < 0)
6411                 return (False);
6412
6413         /* note that we do NOT default the availability flag to True - */
6414         /* we take it from the default service passed. This allows all */
6415         /* dynamic printers to be disabled by disabling the [printers] */
6416         /* entry (if/when the 'available' keyword is implemented!).    */
6417
6418         /* the printer name is set to the service name. */
6419         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6420         string_set(&ServicePtrs[i]->comment, comment);
6421
6422         /* set the browseable flag from the gloabl default */
6423         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6424
6425         /* Printers cannot be read_only. */
6426         ServicePtrs[i]->bRead_only = False;
6427         /* No share modes on printer services. */
6428         ServicePtrs[i]->bShareModes = False;
6429         /* No oplocks on printer services. */
6430         ServicePtrs[i]->bOpLocks = False;
6431         /* Printer services must be printable. */
6432         ServicePtrs[i]->bPrint_ok = True;
6433
6434         DEBUG(3, ("adding printer service %s\n", pszPrintername));
6435
6436         return (True);
6437 }
6438
6439
6440 /***************************************************************************
6441  Check whether the given parameter name is valid.
6442  Parametric options (names containing a colon) are considered valid.
6443 ***************************************************************************/
6444
6445 bool lp_parameter_is_valid(const char *pszParmName)
6446 {
6447         return ((map_parameter(pszParmName) != -1) ||
6448                 (strchr(pszParmName, ':') != NULL));
6449 }
6450
6451 /***************************************************************************
6452  Check whether the given name is the name of a global parameter.
6453  Returns True for strings belonging to parameters of class
6454  P_GLOBAL, False for all other strings, also for parametric options
6455  and strings not belonging to any option.
6456 ***************************************************************************/
6457
6458 bool lp_parameter_is_global(const char *pszParmName)
6459 {
6460         int num = map_parameter(pszParmName);
6461
6462         if (num >= 0) {
6463                 return (parm_table[num].p_class == P_GLOBAL);
6464         }
6465
6466         return False;
6467 }
6468
6469 /**************************************************************************
6470  Check whether the given name is the canonical name of a parameter.
6471  Returns False if it is not a valid parameter Name.
6472  For parametric options, True is returned.
6473 **************************************************************************/
6474
6475 bool lp_parameter_is_canonical(const char *parm_name)
6476 {
6477         if (!lp_parameter_is_valid(parm_name)) {
6478                 return False;
6479         }
6480
6481         return (map_parameter(parm_name) ==
6482                 map_parameter_canonical(parm_name, NULL));
6483 }
6484
6485 /**************************************************************************
6486  Determine the canonical name for a parameter.
6487  Indicate when it is an inverse (boolean) synonym instead of a
6488  "usual" synonym.
6489 **************************************************************************/
6490
6491 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6492                                bool *inverse)
6493 {
6494         int num;
6495
6496         if (!lp_parameter_is_valid(parm_name)) {
6497                 *canon_parm = NULL;
6498                 return False;
6499         }
6500
6501         num = map_parameter_canonical(parm_name, inverse);
6502         if (num < 0) {
6503                 /* parametric option */
6504                 *canon_parm = parm_name;
6505         } else {
6506                 *canon_parm = parm_table[num].label;
6507         }
6508
6509         return True;
6510
6511 }
6512
6513 /**************************************************************************
6514  Determine the canonical name for a parameter.
6515  Turn the value given into the inverse boolean expression when
6516  the synonym is an invers boolean synonym.
6517
6518  Return True if parm_name is a valid parameter name and
6519  in case it is an invers boolean synonym, if the val string could
6520  successfully be converted to the reverse bool.
6521  Return false in all other cases.
6522 **************************************************************************/
6523
6524 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6525                                           const char *val,
6526                                           const char **canon_parm,
6527                                           const char **canon_val)
6528 {
6529         int num;
6530         bool inverse;
6531
6532         if (!lp_parameter_is_valid(parm_name)) {
6533                 *canon_parm = NULL;
6534                 *canon_val = NULL;
6535                 return False;
6536         }
6537
6538         num = map_parameter_canonical(parm_name, &inverse);
6539         if (num < 0) {
6540                 /* parametric option */
6541                 *canon_parm = parm_name;
6542                 *canon_val = val;
6543         } else {
6544                 *canon_parm = parm_table[num].label;
6545                 if (inverse) {
6546                         if (!lp_invert_boolean(val, canon_val)) {
6547                                 *canon_val = NULL;
6548                                 return False;
6549                         }
6550                 } else {
6551                         *canon_val = val;
6552                 }
6553         }
6554
6555         return True;
6556 }
6557
6558 /***************************************************************************
6559  Map a parameter's string representation to something we can use. 
6560  Returns False if the parameter string is not recognised, else TRUE.
6561 ***************************************************************************/
6562
6563 static int map_parameter(const char *pszParmName)
6564 {
6565         int iIndex;
6566
6567         if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6568                 return (-1);
6569
6570         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6571                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6572                         return (iIndex);
6573
6574         /* Warn only if it isn't parametric option */
6575         if (strchr(pszParmName, ':') == NULL)
6576                 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6577         /* We do return 'fail' for parametric options as well because they are
6578            stored in different storage
6579          */
6580         return (-1);
6581 }
6582
6583 /***************************************************************************
6584  Map a parameter's string representation to the index of the canonical
6585  form of the parameter (it might be a synonym).
6586  Returns -1 if the parameter string is not recognised.
6587 ***************************************************************************/
6588
6589 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6590 {
6591         int parm_num, canon_num;
6592         bool loc_inverse = False;
6593
6594         parm_num = map_parameter(pszParmName);
6595         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6596                 /* invalid, parametric or no canidate for synonyms ... */
6597                 goto done;
6598         }
6599
6600         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6601                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6602                         parm_num = canon_num;
6603                         goto done;
6604                 }
6605         }
6606
6607 done:
6608         if (inverse != NULL) {
6609                 *inverse = loc_inverse;
6610         }
6611         return parm_num;
6612 }
6613
6614 /***************************************************************************
6615  return true if parameter number parm1 is a synonym of parameter
6616  number parm2 (parm2 being the principal name).
6617  set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6618  False otherwise.
6619 ***************************************************************************/
6620
6621 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6622 {
6623         if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6624             (parm_table[parm1].flags & FLAG_HIDE) &&
6625             !(parm_table[parm2].flags & FLAG_HIDE))
6626         {
6627                 if (inverse != NULL) {
6628                         if ((parm_table[parm1].type == P_BOOLREV) &&
6629                             (parm_table[parm2].type == P_BOOL))
6630                         {
6631                                 *inverse = True;
6632                         } else {
6633                                 *inverse = False;
6634                         }
6635                 }
6636                 return True;
6637         }
6638         return False;
6639 }
6640
6641 /***************************************************************************
6642  Show one parameter's name, type, [values,] and flags.
6643  (helper functions for show_parameter_list)
6644 ***************************************************************************/
6645
6646 static void show_parameter(int parmIndex)
6647 {
6648         int enumIndex, flagIndex;
6649         int parmIndex2;
6650         bool hadFlag;
6651         bool hadSyn;
6652         bool inverse;
6653         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6654                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6655                 "P_ENUM", "P_SEP"};
6656         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6657                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6658                 FLAG_HIDE, FLAG_DOS_STRING};
6659         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6660                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6661                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6662
6663         printf("%s=%s", parm_table[parmIndex].label,
6664                type[parm_table[parmIndex].type]);
6665         if (parm_table[parmIndex].type == P_ENUM) {
6666                 printf(",");
6667                 for (enumIndex=0;
6668                      parm_table[parmIndex].enum_list[enumIndex].name;
6669                      enumIndex++)
6670                 {
6671                         printf("%s%s",
6672                                enumIndex ? "|" : "",
6673                                parm_table[parmIndex].enum_list[enumIndex].name);
6674                 }
6675         }
6676         printf(",");
6677         hadFlag = False;
6678         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6679                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6680                         printf("%s%s",
6681                                 hadFlag ? "|" : "",
6682                                 flag_names[flagIndex]);
6683                         hadFlag = True;
6684                 }
6685         }
6686
6687         /* output synonyms */
6688         hadSyn = False;
6689         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6690                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6691                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6692                                parm_table[parmIndex2].label);
6693                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6694                         if (!hadSyn) {
6695                                 printf(" (synonyms: ");
6696                                 hadSyn = True;
6697                         } else {
6698                                 printf(", ");
6699                         }
6700                         printf("%s%s", parm_table[parmIndex2].label,
6701                                inverse ? "[i]" : "");
6702                 }
6703         }
6704         if (hadSyn) {
6705                 printf(")");
6706         }
6707
6708         printf("\n");
6709 }
6710
6711 /***************************************************************************
6712  Show all parameter's name, type, [values,] and flags.
6713 ***************************************************************************/
6714
6715 void show_parameter_list(void)
6716 {
6717         int classIndex, parmIndex;
6718         const char *section_names[] = { "local", "global", NULL};
6719
6720         for (classIndex=0; section_names[classIndex]; classIndex++) {
6721                 printf("[%s]\n", section_names[classIndex]);
6722                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6723                         if (parm_table[parmIndex].p_class == classIndex) {
6724                                 show_parameter(parmIndex);
6725                         }
6726                 }
6727         }
6728 }
6729
6730 /***************************************************************************
6731  Check if a given string correctly represents a boolean value.
6732 ***************************************************************************/
6733
6734 bool lp_string_is_valid_boolean(const char *parm_value)
6735 {
6736         return set_boolean(parm_value, NULL);
6737 }
6738
6739 /***************************************************************************
6740  Get the standard string representation of a boolean value ("yes" or "no")
6741 ***************************************************************************/
6742
6743 static const char *get_boolean(bool bool_value)
6744 {
6745         static const char *yes_str = "yes";
6746         static const char *no_str = "no";
6747
6748         return (bool_value ? yes_str : no_str);
6749 }
6750
6751 /***************************************************************************
6752  Provide the string of the negated boolean value associated to the boolean
6753  given as a string. Returns False if the passed string does not correctly
6754  represent a boolean.
6755 ***************************************************************************/
6756
6757 bool lp_invert_boolean(const char *str, const char **inverse_str)
6758 {
6759         bool val;
6760
6761         if (!set_boolean(str, &val)) {
6762                 return False;
6763         }
6764
6765         *inverse_str = get_boolean(!val);
6766         return True;
6767 }
6768
6769 /***************************************************************************
6770  Provide the canonical string representation of a boolean value given
6771  as a string. Return True on success, False if the string given does
6772  not correctly represent a boolean.
6773 ***************************************************************************/
6774
6775 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6776 {
6777         bool val;
6778
6779         if (!set_boolean(str, &val)) {
6780                 return False;
6781         }
6782
6783         *canon_str = get_boolean(val);
6784         return True;
6785 }
6786
6787 /***************************************************************************
6788 Find a service by name. Otherwise works like get_service.
6789 ***************************************************************************/
6790
6791 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6792 {
6793         int iService = -1;
6794         char *canon_name;
6795         TDB_DATA data;
6796
6797         if (ServiceHash == NULL) {
6798                 return -1;
6799         }
6800
6801         canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6802
6803         data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6804
6805         if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6806                 iService = *(int *)data.dptr;
6807         }
6808
6809         TALLOC_FREE(canon_name);
6810
6811         if ((iService != -1) && (LP_SNUM_OK(iService))
6812             && (pserviceDest != NULL)) {
6813                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6814         }
6815
6816         return (iService);
6817 }
6818
6819 /***************************************************************************
6820  Copy a service structure to another.
6821  If pcopymapDest is NULL then copy all fields
6822 ***************************************************************************/
6823
6824 /**
6825  * Add a parametric option to a param_opt_struct,
6826  * replacing old value, if already present.
6827  */
6828 static void set_param_opt(struct param_opt_struct **opt_list,
6829                           const char *opt_name,
6830                           const char *opt_value)
6831 {
6832         struct param_opt_struct *new_opt, *opt;
6833         bool not_added;
6834
6835         if (opt_list == NULL) {
6836                 return;
6837         }
6838
6839         opt = *opt_list;
6840         not_added = true;
6841
6842         /* Traverse destination */
6843         while (opt) {
6844                 /* If we already have same option, override it */
6845                 if (strwicmp(opt->key, opt_name) == 0) {
6846                         string_free(&opt->value);
6847                         TALLOC_FREE(opt->list);
6848                         opt->value = SMB_STRDUP(opt_value);
6849                         not_added = false;
6850                         break;
6851                 }
6852                 opt = opt->next;
6853         }
6854         if (not_added) {
6855             new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6856             new_opt->key = SMB_STRDUP(opt_name);
6857             new_opt->value = SMB_STRDUP(opt_value);
6858             new_opt->list = NULL;
6859             DLIST_ADD(*opt_list, new_opt);
6860         }
6861 }
6862
6863 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6864                          struct bitmap *pcopymapDest)
6865 {
6866         int i;
6867         bool bcopyall = (pcopymapDest == NULL);
6868         struct param_opt_struct *data;
6869
6870         for (i = 0; parm_table[i].label; i++)
6871                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6872                     (bcopyall || bitmap_query(pcopymapDest,i))) {
6873                         void *def_ptr = parm_table[i].ptr;
6874                         void *src_ptr =
6875                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6876                                                                     &sDefault);
6877                         void *dest_ptr =
6878                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6879                                                                   &sDefault);
6880
6881                         switch (parm_table[i].type) {
6882                                 case P_BOOL:
6883                                 case P_BOOLREV:
6884                                         *(bool *)dest_ptr = *(bool *)src_ptr;
6885                                         break;
6886
6887                                 case P_INTEGER:
6888                                 case P_ENUM:
6889                                 case P_OCTAL:
6890                                         *(int *)dest_ptr = *(int *)src_ptr;
6891                                         break;
6892
6893                                 case P_CHAR:
6894                                         *(char *)dest_ptr = *(char *)src_ptr;
6895                                         break;
6896
6897                                 case P_STRING:
6898                                         string_set((char **)dest_ptr,
6899                                                    *(char **)src_ptr);
6900                                         break;
6901
6902                                 case P_USTRING:
6903                                         string_set((char **)dest_ptr,
6904                                                    *(char **)src_ptr);
6905                                         strupper_m(*(char **)dest_ptr);
6906                                         break;
6907                                 case P_LIST:
6908                                         TALLOC_FREE(*((char ***)dest_ptr));
6909                                         *((char ***)dest_ptr) = str_list_copy(NULL, 
6910                                                       *(const char ***)src_ptr);
6911                                         break;
6912                                 default:
6913                                         break;
6914                         }
6915                 }
6916
6917         if (bcopyall) {
6918                 init_copymap(pserviceDest);
6919                 if (pserviceSource->copymap)
6920                         bitmap_copy(pserviceDest->copymap,
6921                                     pserviceSource->copymap);
6922         }
6923
6924         data = pserviceSource->param_opt;
6925         while (data) {
6926                 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6927                 data = data->next;
6928         }
6929 }
6930
6931 /***************************************************************************
6932 Check a service for consistency. Return False if the service is in any way
6933 incomplete or faulty, else True.
6934 ***************************************************************************/
6935
6936 bool service_ok(int iService)
6937 {
6938         bool bRetval;
6939
6940         bRetval = True;
6941         if (ServicePtrs[iService]->szService[0] == '\0') {
6942                 DEBUG(0, ("The following message indicates an internal error:\n"));
6943                 DEBUG(0, ("No service name in service entry.\n"));
6944                 bRetval = False;
6945         }
6946
6947         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6948         /* I can't see why you'd want a non-printable printer service...        */
6949         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6950                 if (!ServicePtrs[iService]->bPrint_ok) {
6951                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6952                                ServicePtrs[iService]->szService));
6953                         ServicePtrs[iService]->bPrint_ok = True;
6954                 }
6955                 /* [printers] service must also be non-browsable. */
6956                 if (ServicePtrs[iService]->bBrowseable)
6957                         ServicePtrs[iService]->bBrowseable = False;
6958         }
6959
6960         if (ServicePtrs[iService]->szPath[0] == '\0' &&
6961             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6962             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6963             ) {
6964                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6965                         ServicePtrs[iService]->szService));
6966                 ServicePtrs[iService]->bAvailable = False;
6967         }
6968
6969         /* If a service is flagged unavailable, log the fact at level 1. */
6970         if (!ServicePtrs[iService]->bAvailable)
6971                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6972                           ServicePtrs[iService]->szService));
6973
6974         return (bRetval);
6975 }
6976
6977 static struct smbconf_ctx *lp_smbconf_ctx(void)
6978 {
6979         WERROR werr;
6980         static struct smbconf_ctx *conf_ctx = NULL;
6981
6982         if (conf_ctx == NULL) {
6983                 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6984                 if (!W_ERROR_IS_OK(werr)) {
6985                         DEBUG(1, ("error initializing registry configuration: "
6986                                   "%s\n", win_errstr(werr)));
6987                         conf_ctx = NULL;
6988                 }
6989         }
6990
6991         return conf_ctx;
6992 }
6993
6994 static bool process_smbconf_service(struct smbconf_service *service)
6995 {
6996         uint32_t count;
6997         bool ret;
6998
6999         if (service == NULL) {
7000                 return false;
7001         }
7002
7003         ret = do_section(service->name, NULL);
7004         if (ret != true) {
7005                 return false;
7006         }
7007         for (count = 0; count < service->num_params; count++) {
7008                 ret = do_parameter(service->param_names[count],
7009                                    service->param_values[count],
7010                                    NULL);
7011                 if (ret != true) {
7012                         return false;
7013                 }
7014         }
7015         if (iServiceIndex >= 0) {
7016                 return service_ok(iServiceIndex);
7017         }
7018         return true;
7019 }
7020
7021 /**
7022  * load a service from registry and activate it
7023  */
7024 bool process_registry_service(const char *service_name)
7025 {
7026         WERROR werr;
7027         struct smbconf_service *service = NULL;
7028         TALLOC_CTX *mem_ctx = talloc_stackframe();
7029         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7030         bool ret = false;
7031
7032         if (conf_ctx == NULL) {
7033                 goto done;
7034         }
7035
7036         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7037
7038         if (!smbconf_share_exists(conf_ctx, service_name)) {
7039                 /*
7040                  * Registry does not contain data for this service (yet),
7041                  * but make sure lp_load doesn't return false.
7042                  */
7043                 ret = true;
7044                 goto done;
7045         }
7046
7047         werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7048         if (!W_ERROR_IS_OK(werr)) {
7049                 goto done;
7050         }
7051
7052         ret = process_smbconf_service(service);
7053         if (!ret) {
7054                 goto done;
7055         }
7056
7057         /* store the csn */
7058         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7059
7060 done:
7061         TALLOC_FREE(mem_ctx);
7062         return ret;
7063 }
7064
7065 /*
7066  * process_registry_globals
7067  */
7068 static bool process_registry_globals(void)
7069 {
7070         bool ret;
7071
7072         add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7073
7074         ret = do_parameter("registry shares", "yes", NULL);
7075         if (!ret) {
7076                 return ret;
7077         }
7078
7079         return process_registry_service(GLOBAL_NAME);
7080 }
7081
7082 bool process_registry_shares(void)
7083 {
7084         WERROR werr;
7085         uint32_t count;
7086         struct smbconf_service **service = NULL;
7087         uint32_t num_shares = 0;
7088         TALLOC_CTX *mem_ctx = talloc_stackframe();
7089         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7090         bool ret = false;
7091
7092         if (conf_ctx == NULL) {
7093                 goto done;
7094         }
7095
7096         werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7097         if (!W_ERROR_IS_OK(werr)) {
7098                 goto done;
7099         }
7100
7101         ret = true;
7102
7103         for (count = 0; count < num_shares; count++) {
7104                 if (strequal(service[count]->name, GLOBAL_NAME)) {
7105                         continue;
7106                 }
7107                 ret = process_smbconf_service(service[count]);
7108                 if (!ret) {
7109                         goto done;
7110                 }
7111         }
7112
7113         /* store the csn */
7114         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7115
7116 done:
7117         TALLOC_FREE(mem_ctx);
7118         return ret;
7119 }
7120
7121 #define MAX_INCLUDE_DEPTH 100
7122
7123 static uint8_t include_depth;
7124
7125 static struct file_lists {
7126         struct file_lists *next;
7127         char *name;
7128         char *subfname;
7129         time_t modtime;
7130 } *file_lists = NULL;
7131
7132 /*******************************************************************
7133  Keep a linked list of all config files so we know when one has changed 
7134  it's date and needs to be reloaded.
7135 ********************************************************************/
7136
7137 static void add_to_file_list(const char *fname, const char *subfname)
7138 {
7139         struct file_lists *f = file_lists;
7140
7141         while (f) {
7142                 if (f->name && !strcmp(f->name, fname))
7143                         break;
7144                 f = f->next;
7145         }
7146
7147         if (!f) {
7148                 f = SMB_MALLOC_P(struct file_lists);
7149                 if (!f)
7150                         return;
7151                 f->next = file_lists;
7152                 f->name = SMB_STRDUP(fname);
7153                 if (!f->name) {
7154                         SAFE_FREE(f);
7155                         return;
7156                 }
7157                 f->subfname = SMB_STRDUP(subfname);
7158                 if (!f->subfname) {
7159                         SAFE_FREE(f->name);
7160                         SAFE_FREE(f);
7161                         return;
7162                 }
7163                 file_lists = f;
7164                 f->modtime = file_modtime(subfname);
7165         } else {
7166                 time_t t = file_modtime(subfname);
7167                 if (t)
7168                         f->modtime = t;
7169         }
7170         return;
7171 }
7172
7173 /**
7174  * Free the file lists
7175  */
7176 static void free_file_list(void)
7177 {
7178         struct file_lists *f;
7179         struct file_lists *next;
7180
7181         f = file_lists;
7182         while( f ) {
7183                 next = f->next;
7184                 SAFE_FREE( f->name );
7185                 SAFE_FREE( f->subfname );
7186                 SAFE_FREE( f );
7187                 f = next;
7188         }
7189         file_lists = NULL;
7190 }
7191
7192
7193 /**
7194  * Utility function for outsiders to check if we're running on registry.
7195  */
7196 bool lp_config_backend_is_registry(void)
7197 {
7198         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7199 }
7200
7201 /**
7202  * Utility function to check if the config backend is FILE.
7203  */
7204 bool lp_config_backend_is_file(void)
7205 {
7206         return (lp_config_backend() == CONFIG_BACKEND_FILE);
7207 }
7208
7209 /*******************************************************************
7210  Check if a config file has changed date.
7211 ********************************************************************/
7212
7213 bool lp_file_list_changed(void)
7214 {
7215         struct file_lists *f = file_lists;
7216
7217         DEBUG(6, ("lp_file_list_changed()\n"));
7218
7219         while (f) {
7220                 time_t mod_time;
7221
7222                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7223                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7224
7225                         if (conf_ctx == NULL) {
7226                                 return false;
7227                         }
7228                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7229                                             NULL))
7230                         {
7231                                 DEBUGADD(6, ("registry config changed\n"));
7232                                 return true;
7233                         }
7234                 } else {
7235                         char *n2 = NULL;
7236                         n2 = talloc_sub_basic(talloc_tos(),
7237                                               get_current_username(),
7238                                               current_user_info.domain,
7239                                               f->name);
7240                         if (!n2) {
7241                                 return false;
7242                         }
7243                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
7244                                      f->name, n2, ctime(&f->modtime)));
7245
7246                         mod_time = file_modtime(n2);
7247
7248                         if (mod_time &&
7249                             ((f->modtime != mod_time) ||
7250                              (f->subfname == NULL) ||
7251                              (strcmp(n2, f->subfname) != 0)))
7252                         {
7253                                 DEBUGADD(6,
7254                                          ("file %s modified: %s\n", n2,
7255                                           ctime(&mod_time)));
7256                                 f->modtime = mod_time;
7257                                 SAFE_FREE(f->subfname);
7258                                 f->subfname = SMB_STRDUP(n2);
7259                                 TALLOC_FREE(n2);
7260                                 return true;
7261                         }
7262                         TALLOC_FREE(n2);
7263                 }
7264                 f = f->next;
7265         }
7266         return (False);
7267 }
7268
7269
7270 /***************************************************************************
7271  Run standard_sub_basic on netbios name... needed because global_myname
7272  is not accessed through any lp_ macro.
7273  Note: We must *NOT* use string_set() here as ptr points to global_myname.
7274 ***************************************************************************/
7275
7276 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7277 {
7278         bool ret;
7279         char *netbios_name = talloc_sub_basic(
7280                 talloc_tos(), get_current_username(), current_user_info.domain,
7281                 pszParmValue);
7282
7283         ret = set_global_myname(netbios_name);
7284         TALLOC_FREE(netbios_name);
7285         string_set(&Globals.szNetbiosName,global_myname());
7286
7287         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7288                global_myname()));
7289
7290         return ret;
7291 }
7292
7293 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7294 {
7295         if (strcmp(*ptr, pszParmValue) != 0) {
7296                 string_set(ptr, pszParmValue);
7297                 init_iconv();
7298         }
7299         return True;
7300 }
7301
7302
7303
7304 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7305 {
7306         bool ret;
7307
7308         ret = set_global_myworkgroup(pszParmValue);
7309         string_set(&Globals.szWorkgroup,lp_workgroup());
7310
7311         return ret;
7312 }
7313
7314 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7315 {
7316         bool ret;
7317
7318         ret = set_global_scope(pszParmValue);
7319         string_set(&Globals.szNetbiosScope,global_scope());
7320
7321         return ret;
7322 }
7323
7324 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7325 {
7326         TALLOC_FREE(Globals.szNetbiosAliases);
7327         Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7328         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7329 }
7330
7331 /***************************************************************************
7332  Handle the include operation.
7333 ***************************************************************************/
7334 static bool bAllowIncludeRegistry = true;
7335
7336 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7337 {
7338         char *fname;
7339
7340         if (include_depth >= MAX_INCLUDE_DEPTH) {
7341                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7342                           include_depth));
7343                 return false;
7344         }
7345
7346         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7347                 if (!bAllowIncludeRegistry) {
7348                         return true;
7349                 }
7350                 if (bInGlobalSection) {
7351                         bool ret;
7352                         include_depth++;
7353                         ret = process_registry_globals();
7354                         include_depth--;
7355                         return ret;
7356                 } else {
7357                         DEBUG(1, ("\"include = registry\" only effective "
7358                                   "in %s section\n", GLOBAL_NAME));
7359                         return false;
7360                 }
7361         }
7362
7363         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7364                                  current_user_info.domain,
7365                                  pszParmValue);
7366
7367         add_to_file_list(pszParmValue, fname);
7368
7369         string_set(ptr, fname);
7370
7371         if (file_exist(fname)) {
7372                 bool ret;
7373                 include_depth++;
7374                 ret = pm_process(fname, do_section, do_parameter, NULL);
7375                 include_depth--;
7376                 TALLOC_FREE(fname);
7377                 return ret;
7378         }
7379
7380         DEBUG(2, ("Can't find include file %s\n", fname));
7381         TALLOC_FREE(fname);
7382         return true;
7383 }
7384
7385 /***************************************************************************
7386  Handle the interpretation of the copy parameter.
7387 ***************************************************************************/
7388
7389 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7390 {
7391         bool bRetval;
7392         int iTemp;
7393         struct service serviceTemp;
7394
7395         string_set(ptr, pszParmValue);
7396
7397         init_service(&serviceTemp);
7398
7399         bRetval = False;
7400
7401         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7402
7403         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7404                 if (iTemp == iServiceIndex) {
7405                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7406                 } else {
7407                         copy_service(ServicePtrs[iServiceIndex],
7408                                      &serviceTemp,
7409                                      ServicePtrs[iServiceIndex]->copymap);
7410                         bRetval = True;
7411                 }
7412         } else {
7413                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7414                 bRetval = False;
7415         }
7416
7417         free_service(&serviceTemp);
7418         return (bRetval);
7419 }
7420
7421 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7422 {
7423         Globals.ldap_debug_level = lp_int(pszParmValue);
7424         init_ldap_debugging();
7425         return true;
7426 }
7427
7428 /***************************************************************************
7429  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
7430  parameters is:
7431
7432  [global]
7433
7434         idmap uid = 1000-1999
7435         idmap gid = 700-899
7436
7437  We only do simple parsing checks here.  The strings are parsed into useful
7438  structures in the idmap daemon code.
7439
7440 ***************************************************************************/
7441
7442 /* Some lp_ routines to return idmap [ug]id information */
7443
7444 static uid_t idmap_uid_low, idmap_uid_high;
7445 static gid_t idmap_gid_low, idmap_gid_high;
7446
7447 bool lp_idmap_uid(uid_t *low, uid_t *high)
7448 {
7449         if (idmap_uid_low == 0 || idmap_uid_high == 0)
7450                 return False;
7451
7452         if (low)
7453                 *low = idmap_uid_low;
7454
7455         if (high)
7456                 *high = idmap_uid_high;
7457
7458         return True;
7459 }
7460
7461 bool lp_idmap_gid(gid_t *low, gid_t *high)
7462 {
7463         if (idmap_gid_low == 0 || idmap_gid_high == 0)
7464                 return False;
7465
7466         if (low)
7467                 *low = idmap_gid_low;
7468
7469         if (high)
7470                 *high = idmap_gid_high;
7471
7472         return True;
7473 }
7474
7475 /* Do some simple checks on "idmap [ug]id" parameter values */
7476
7477 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7478 {
7479         uint32 low, high;
7480
7481         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7482                 return False;
7483
7484         /* Parse OK */
7485
7486         string_set(ptr, pszParmValue);
7487
7488         idmap_uid_low = low;
7489         idmap_uid_high = high;
7490
7491         return True;
7492 }
7493
7494 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7495 {
7496         uint32 low, high;
7497
7498         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7499                 return False;
7500
7501         /* Parse OK */
7502
7503         string_set(ptr, pszParmValue);
7504
7505         idmap_gid_low = low;
7506         idmap_gid_high = high;
7507
7508         return True;
7509 }
7510
7511 /***************************************************************************
7512  Handle the DEBUG level list.
7513 ***************************************************************************/
7514
7515 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7516 {
7517         string_set(ptr, pszParmValueIn);
7518         return debug_parse_levels(pszParmValueIn);
7519 }
7520
7521 /***************************************************************************
7522  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7523 ***************************************************************************/
7524
7525 static const char *append_ldap_suffix( const char *str )
7526 {
7527         const char *suffix_string;
7528
7529
7530         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7531                                         Globals.szLdapSuffix );
7532         if ( !suffix_string ) {
7533                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7534                 return "";
7535         }
7536
7537         return suffix_string;
7538 }
7539
7540 const char *lp_ldap_machine_suffix(void)
7541 {
7542         if (Globals.szLdapMachineSuffix[0])
7543                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7544
7545         return lp_string(Globals.szLdapSuffix);
7546 }
7547
7548 const char *lp_ldap_user_suffix(void)
7549 {
7550         if (Globals.szLdapUserSuffix[0])
7551                 return append_ldap_suffix(Globals.szLdapUserSuffix);
7552
7553         return lp_string(Globals.szLdapSuffix);
7554 }
7555
7556 const char *lp_ldap_group_suffix(void)
7557 {
7558         if (Globals.szLdapGroupSuffix[0])
7559                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7560
7561         return lp_string(Globals.szLdapSuffix);
7562 }
7563
7564 const char *lp_ldap_idmap_suffix(void)
7565 {
7566         if (Globals.szLdapIdmapSuffix[0])
7567                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7568
7569         return lp_string(Globals.szLdapSuffix);
7570 }
7571
7572 /****************************************************************************
7573  set the value for a P_ENUM
7574  ***************************************************************************/
7575
7576 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7577                               int *ptr )
7578 {
7579         int i;
7580
7581         for (i = 0; parm->enum_list[i].name; i++) {
7582                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7583                         *ptr = parm->enum_list[i].value;
7584                         return;
7585                 }
7586         }
7587         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7588                   pszParmValue, parm->label));
7589 }
7590
7591 /***************************************************************************
7592 ***************************************************************************/
7593
7594 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7595 {
7596         static int parm_num = -1;
7597         struct service *s;
7598
7599         if ( parm_num == -1 )
7600                 parm_num = map_parameter( "printing" );
7601
7602         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7603
7604         if ( snum < 0 )
7605                 s = &sDefault;
7606         else
7607                 s = ServicePtrs[snum];
7608
7609         init_printer_values( s );
7610
7611         return True;
7612 }
7613
7614
7615 /***************************************************************************
7616  Initialise a copymap.
7617 ***************************************************************************/
7618
7619 static void init_copymap(struct service *pservice)
7620 {
7621         int i;
7622
7623         TALLOC_FREE(pservice->copymap);
7624
7625         pservice->copymap = bitmap_talloc(talloc_autofree_context(),
7626                                           NUMPARAMETERS);
7627         if (!pservice->copymap)
7628                 DEBUG(0,
7629                       ("Couldn't allocate copymap!! (size %d)\n",
7630                        (int)NUMPARAMETERS));
7631         else
7632                 for (i = 0; i < NUMPARAMETERS; i++)
7633                         bitmap_set(pservice->copymap, i);
7634 }
7635
7636 /***************************************************************************
7637  Return the local pointer to a parameter given a service struct and the
7638  pointer into the default structure.
7639 ***************************************************************************/
7640
7641 static void *lp_local_ptr(struct service *service, void *ptr)
7642 {
7643         return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7644 }
7645
7646 /***************************************************************************
7647  Return the local pointer to a parameter given the service number and the 
7648  pointer into the default structure.
7649 ***************************************************************************/
7650
7651 void *lp_local_ptr_by_snum(int snum, void *ptr)
7652 {
7653         return lp_local_ptr(ServicePtrs[snum], ptr);
7654 }
7655
7656 /***************************************************************************
7657  Process a parameter for a particular service number. If snum < 0
7658  then assume we are in the globals.
7659 ***************************************************************************/
7660
7661 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7662 {
7663         int parmnum, i;
7664         void *parm_ptr = NULL;  /* where we are going to store the result */
7665         void *def_ptr = NULL;
7666         struct param_opt_struct **opt_list;
7667
7668         parmnum = map_parameter(pszParmName);
7669
7670         if (parmnum < 0) {
7671                 if (strchr(pszParmName, ':') == NULL) {
7672                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7673                                   pszParmName));
7674                         return (True);
7675                 }
7676
7677                 /*
7678                  * We've got a parametric option
7679                  */
7680
7681                 opt_list = (snum < 0)
7682                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7683                 set_param_opt(opt_list, pszParmName, pszParmValue);
7684
7685                 return (True);
7686         }
7687
7688         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7689                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7690                           pszParmName));
7691         }
7692
7693         def_ptr = parm_table[parmnum].ptr;
7694
7695         /* we might point at a service, the default service or a global */
7696         if (snum < 0) {
7697                 parm_ptr = def_ptr;
7698         } else {
7699                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7700                         DEBUG(0,
7701                               ("Global parameter %s found in service section!\n",
7702                                pszParmName));
7703                         return (True);
7704                 }
7705                 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7706         }
7707
7708         if (snum >= 0) {
7709                 if (!ServicePtrs[snum]->copymap)
7710                         init_copymap(ServicePtrs[snum]);
7711
7712                 /* this handles the aliases - set the copymap for other entries with
7713                    the same data pointer */
7714                 for (i = 0; parm_table[i].label; i++)
7715                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7716                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7717         }
7718
7719         /* if it is a special case then go ahead */
7720         if (parm_table[parmnum].special) {
7721                 return parm_table[parmnum].special(snum, pszParmValue,
7722                                                    (char **)parm_ptr);
7723         }
7724
7725         /* now switch on the type of variable it is */
7726         switch (parm_table[parmnum].type)
7727         {
7728                 case P_BOOL:
7729                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7730                         break;
7731
7732                 case P_BOOLREV:
7733                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7734                         break;
7735
7736                 case P_INTEGER:
7737                         *(int *)parm_ptr = lp_int(pszParmValue);
7738                         break;
7739
7740                 case P_CHAR:
7741                         *(char *)parm_ptr = *pszParmValue;
7742                         break;
7743
7744                 case P_OCTAL:
7745                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7746                         if ( i != 1 ) {
7747                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7748                         }
7749                         break;
7750
7751                 case P_LIST:
7752                         TALLOC_FREE(*((char ***)parm_ptr));
7753                         *(char ***)parm_ptr = str_list_make_v3(
7754                                 talloc_autofree_context(), pszParmValue, NULL);
7755                         break;
7756
7757                 case P_STRING:
7758                         string_set((char **)parm_ptr, pszParmValue);
7759                         break;
7760
7761                 case P_USTRING:
7762                         string_set((char **)parm_ptr, pszParmValue);
7763                         strupper_m(*(char **)parm_ptr);
7764                         break;
7765
7766                 case P_ENUM:
7767                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7768                         break;
7769                 case P_SEP:
7770                         break;
7771         }
7772
7773         return (True);
7774 }
7775
7776 /***************************************************************************
7777  Process a parameter.
7778 ***************************************************************************/
7779
7780 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7781                          void *userdata)
7782 {
7783         if (!bInGlobalSection && bGlobalOnly)
7784                 return (True);
7785
7786         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7787
7788         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7789                                 pszParmName, pszParmValue));
7790 }
7791
7792 /***************************************************************************
7793  Print a parameter of the specified type.
7794 ***************************************************************************/
7795
7796 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7797 {
7798         int i;
7799         switch (p->type)
7800         {
7801                 case P_ENUM:
7802                         for (i = 0; p->enum_list[i].name; i++) {
7803                                 if (*(int *)ptr == p->enum_list[i].value) {
7804                                         fprintf(f, "%s",
7805                                                 p->enum_list[i].name);
7806                                         break;
7807                                 }
7808                         }
7809                         break;
7810
7811                 case P_BOOL:
7812                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7813                         break;
7814
7815                 case P_BOOLREV:
7816                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7817                         break;
7818
7819                 case P_INTEGER:
7820                         fprintf(f, "%d", *(int *)ptr);
7821                         break;
7822
7823                 case P_CHAR:
7824                         fprintf(f, "%c", *(char *)ptr);
7825                         break;
7826
7827                 case P_OCTAL: {
7828                         char *o = octal_string(*(int *)ptr);
7829                         fprintf(f, "%s", o);
7830                         TALLOC_FREE(o);
7831                         break;
7832                 }
7833
7834                 case P_LIST:
7835                         if ((char ***)ptr && *(char ***)ptr) {
7836                                 char **list = *(char ***)ptr;
7837                                 for (; *list; list++) {
7838                                         /* surround strings with whitespace in double quotes */
7839                                         if ( strchr_m( *list, ' ' ) )
7840                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7841                                         else
7842                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7843                                 }
7844                         }
7845                         break;
7846
7847                 case P_STRING:
7848                 case P_USTRING:
7849                         if (*(char **)ptr) {
7850                                 fprintf(f, "%s", *(char **)ptr);
7851                         }
7852                         break;
7853                 case P_SEP:
7854                         break;
7855         }
7856 }
7857
7858 /***************************************************************************
7859  Check if two parameters are equal.
7860 ***************************************************************************/
7861
7862 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7863 {
7864         switch (type) {
7865                 case P_BOOL:
7866                 case P_BOOLREV:
7867                         return (*((bool *)ptr1) == *((bool *)ptr2));
7868
7869                 case P_INTEGER:
7870                 case P_ENUM:
7871                 case P_OCTAL:
7872                         return (*((int *)ptr1) == *((int *)ptr2));
7873
7874                 case P_CHAR:
7875                         return (*((char *)ptr1) == *((char *)ptr2));
7876
7877                 case P_LIST:
7878                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7879
7880                 case P_STRING:
7881                 case P_USTRING:
7882                 {
7883                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7884                         if (p1 && !*p1)
7885                                 p1 = NULL;
7886                         if (p2 && !*p2)
7887                                 p2 = NULL;
7888                         return (p1 == p2 || strequal(p1, p2));
7889                 }
7890                 case P_SEP:
7891                         break;
7892         }
7893         return (False);
7894 }
7895
7896 /***************************************************************************
7897  Initialize any local varients in the sDefault table.
7898 ***************************************************************************/
7899
7900 void init_locals(void)
7901 {
7902         /* None as yet. */
7903 }
7904
7905 /***************************************************************************
7906  Process a new section (service). At this stage all sections are services.
7907  Later we'll have special sections that permit server parameters to be set.
7908  Returns True on success, False on failure. 
7909 ***************************************************************************/
7910
7911 static bool do_section(const char *pszSectionName, void *userdata)
7912 {
7913         bool bRetval;
7914         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7915                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7916         bRetval = False;
7917
7918         /* if we were in a global section then do the local inits */
7919         if (bInGlobalSection && !isglobal)
7920                 init_locals();
7921
7922         /* if we've just struck a global section, note the fact. */
7923         bInGlobalSection = isglobal;
7924
7925         /* check for multiple global sections */
7926         if (bInGlobalSection) {
7927                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7928                 return (True);
7929         }
7930
7931         if (!bInGlobalSection && bGlobalOnly)
7932                 return (True);
7933
7934         /* if we have a current service, tidy it up before moving on */
7935         bRetval = True;
7936
7937         if (iServiceIndex >= 0)
7938                 bRetval = service_ok(iServiceIndex);
7939
7940         /* if all is still well, move to the next record in the services array */
7941         if (bRetval) {
7942                 /* We put this here to avoid an odd message order if messages are */
7943                 /* issued by the post-processing of a previous section. */
7944                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7945
7946                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7947                     < 0) {
7948                         DEBUG(0, ("Failed to add a new service\n"));
7949                         return (False);
7950                 }
7951         }
7952
7953         return (bRetval);
7954 }
7955
7956
7957 /***************************************************************************
7958  Determine if a partcular base parameter is currentl set to the default value.
7959 ***************************************************************************/
7960
7961 static bool is_default(int i)
7962 {
7963         if (!defaults_saved)
7964                 return False;
7965         switch (parm_table[i].type) {
7966                 case P_LIST:
7967                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
7968                                                 *(const char ***)parm_table[i].ptr);
7969                 case P_STRING:
7970                 case P_USTRING:
7971                         return strequal(parm_table[i].def.svalue,
7972                                         *(char **)parm_table[i].ptr);
7973                 case P_BOOL:
7974                 case P_BOOLREV:
7975                         return parm_table[i].def.bvalue ==
7976                                 *(bool *)parm_table[i].ptr;
7977                 case P_CHAR:
7978                         return parm_table[i].def.cvalue ==
7979                                 *(char *)parm_table[i].ptr;
7980                 case P_INTEGER:
7981                 case P_OCTAL:
7982                 case P_ENUM:
7983                         return parm_table[i].def.ivalue ==
7984                                 *(int *)parm_table[i].ptr;
7985                 case P_SEP:
7986                         break;
7987         }
7988         return False;
7989 }
7990
7991 /***************************************************************************
7992 Display the contents of the global structure.
7993 ***************************************************************************/
7994
7995 static void dump_globals(FILE *f)
7996 {
7997         int i;
7998         struct param_opt_struct *data;
7999
8000         fprintf(f, "[global]\n");
8001
8002         for (i = 0; parm_table[i].label; i++)
8003                 if (parm_table[i].p_class == P_GLOBAL &&
8004                     !(parm_table[i].flags & FLAG_META) &&
8005                     parm_table[i].ptr &&
8006                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8007                         if (defaults_saved && is_default(i))
8008                                 continue;
8009                         fprintf(f, "\t%s = ", parm_table[i].label);
8010                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
8011                         fprintf(f, "\n");
8012         }
8013         if (Globals.param_opt != NULL) {
8014                 data = Globals.param_opt;
8015                 while(data) {
8016                         fprintf(f, "\t%s = %s\n", data->key, data->value);
8017                         data = data->next;
8018                 }
8019         }
8020
8021 }
8022
8023 /***************************************************************************
8024  Return True if a local parameter is currently set to the global default.
8025 ***************************************************************************/
8026
8027 bool lp_is_default(int snum, struct parm_struct *parm)
8028 {
8029         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8030
8031         return equal_parameter(parm->type,
8032                                ((char *)ServicePtrs[snum]) + pdiff,
8033                                ((char *)&sDefault) + pdiff);
8034 }
8035
8036 /***************************************************************************
8037  Display the contents of a single services record.
8038 ***************************************************************************/
8039
8040 static void dump_a_service(struct service *pService, FILE * f)
8041 {
8042         int i;
8043         struct param_opt_struct *data;
8044
8045         if (pService != &sDefault)
8046                 fprintf(f, "[%s]\n", pService->szService);
8047
8048         for (i = 0; parm_table[i].label; i++) {
8049
8050                 if (parm_table[i].p_class == P_LOCAL &&
8051                     !(parm_table[i].flags & FLAG_META) &&
8052                     parm_table[i].ptr &&
8053                     (*parm_table[i].label != '-') &&
8054                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
8055                 {
8056                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8057
8058                         if (pService == &sDefault) {
8059                                 if (defaults_saved && is_default(i))
8060                                         continue;
8061                         } else {
8062                                 if (equal_parameter(parm_table[i].type,
8063                                                     ((char *)pService) +
8064                                                     pdiff,
8065                                                     ((char *)&sDefault) +
8066                                                     pdiff))
8067                                         continue;
8068                         }
8069
8070                         fprintf(f, "\t%s = ", parm_table[i].label);
8071                         print_parameter(&parm_table[i],
8072                                         ((char *)pService) + pdiff, f);
8073                         fprintf(f, "\n");
8074                 }
8075         }
8076
8077                 if (pService->param_opt != NULL) {
8078                         data = pService->param_opt;
8079                         while(data) {
8080                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
8081                                 data = data->next;
8082                         }
8083                 }
8084 }
8085
8086 /***************************************************************************
8087  Display the contents of a parameter of a single services record.
8088 ***************************************************************************/
8089
8090 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8091 {
8092         int i;
8093         bool result = False;
8094         parm_class p_class;
8095         unsigned flag = 0;
8096         fstring local_parm_name;
8097         char *parm_opt;
8098         const char *parm_opt_value;
8099
8100         /* check for parametrical option */
8101         fstrcpy( local_parm_name, parm_name);
8102         parm_opt = strchr( local_parm_name, ':');
8103
8104         if (parm_opt) {
8105                 *parm_opt = '\0';
8106                 parm_opt++;
8107                 if (strlen(parm_opt)) {
8108                         parm_opt_value = lp_parm_const_string( snum,
8109                                 local_parm_name, parm_opt, NULL);
8110                         if (parm_opt_value) {
8111                                 printf( "%s\n", parm_opt_value);
8112                                 result = True;
8113                         }
8114                 }
8115                 return result;
8116         }
8117
8118         /* check for a key and print the value */
8119         if (isGlobal) {
8120                 p_class = P_GLOBAL;
8121                 flag = FLAG_GLOBAL;
8122         } else
8123                 p_class = P_LOCAL;
8124
8125         for (i = 0; parm_table[i].label; i++) {
8126                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8127                     !(parm_table[i].flags & FLAG_META) &&
8128                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8129                     parm_table[i].ptr &&
8130                     (*parm_table[i].label != '-') &&
8131                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
8132                 {
8133                         void *ptr;
8134
8135                         if (isGlobal) {
8136                                 ptr = parm_table[i].ptr;
8137                         } else {
8138                                 struct service *pService = ServicePtrs[snum];
8139                                 ptr = ((char *)pService) +
8140                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
8141                         }
8142
8143                         print_parameter(&parm_table[i],
8144                                         ptr, f);
8145                         fprintf(f, "\n");
8146                         result = True;
8147                         break;
8148                 }
8149         }
8150
8151         return result;
8152 }
8153
8154 /***************************************************************************
8155  Return info about the requested parameter (given as a string).
8156  Return NULL when the string is not a valid parameter name.
8157 ***************************************************************************/
8158
8159 struct parm_struct *lp_get_parameter(const char *param_name)
8160 {
8161         int num = map_parameter(param_name);
8162
8163         if (num < 0) {
8164                 return NULL;
8165         }
8166
8167         return &parm_table[num];
8168 }
8169
8170 /***************************************************************************
8171  Return info about the next parameter in a service.
8172  snum==GLOBAL_SECTION_SNUM gives the globals.
8173  Return NULL when out of parameters.
8174 ***************************************************************************/
8175
8176 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8177 {
8178         if (snum < 0) {
8179                 /* do the globals */
8180                 for (; parm_table[*i].label; (*i)++) {
8181                         if (parm_table[*i].p_class == P_SEPARATOR)
8182                                 return &parm_table[(*i)++];
8183
8184                         if (!parm_table[*i].ptr
8185                             || (*parm_table[*i].label == '-'))
8186                                 continue;
8187
8188                         if ((*i) > 0
8189                             && (parm_table[*i].ptr ==
8190                                 parm_table[(*i) - 1].ptr))
8191                                 continue;
8192
8193                         if (is_default(*i) && !allparameters)
8194                                 continue;
8195
8196                         return &parm_table[(*i)++];
8197                 }
8198         } else {
8199                 struct service *pService = ServicePtrs[snum];
8200
8201                 for (; parm_table[*i].label; (*i)++) {
8202                         if (parm_table[*i].p_class == P_SEPARATOR)
8203                                 return &parm_table[(*i)++];
8204
8205                         if (parm_table[*i].p_class == P_LOCAL &&
8206                             parm_table[*i].ptr &&
8207                             (*parm_table[*i].label != '-') &&
8208                             ((*i) == 0 ||
8209                              (parm_table[*i].ptr !=
8210                               parm_table[(*i) - 1].ptr)))
8211                         {
8212                                 int pdiff =
8213                                         PTR_DIFF(parm_table[*i].ptr,
8214                                                  &sDefault);
8215
8216                                 if (allparameters ||
8217                                     !equal_parameter(parm_table[*i].type,
8218                                                      ((char *)pService) +
8219                                                      pdiff,
8220                                                      ((char *)&sDefault) +
8221                                                      pdiff))
8222                                 {
8223                                         return &parm_table[(*i)++];
8224                                 }
8225                         }
8226                 }
8227         }
8228
8229         return NULL;
8230 }
8231
8232
8233 #if 0
8234 /***************************************************************************
8235  Display the contents of a single copy structure.
8236 ***************************************************************************/
8237 static void dump_copy_map(bool *pcopymap)
8238 {
8239         int i;
8240         if (!pcopymap)
8241                 return;
8242
8243         printf("\n\tNon-Copied parameters:\n");
8244
8245         for (i = 0; parm_table[i].label; i++)
8246                 if (parm_table[i].p_class == P_LOCAL &&
8247                     parm_table[i].ptr && !pcopymap[i] &&
8248                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8249                 {
8250                         printf("\t\t%s\n", parm_table[i].label);
8251                 }
8252 }
8253 #endif
8254
8255 /***************************************************************************
8256  Return TRUE if the passed service number is within range.
8257 ***************************************************************************/
8258
8259 bool lp_snum_ok(int iService)
8260 {
8261         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8262 }
8263
8264 /***************************************************************************
8265  Auto-load some home services.
8266 ***************************************************************************/
8267
8268 static void lp_add_auto_services(char *str)
8269 {
8270         char *s;
8271         char *p;
8272         int homes;
8273         char *saveptr;
8274
8275         if (!str)
8276                 return;
8277
8278         s = SMB_STRDUP(str);
8279         if (!s)
8280                 return;
8281
8282         homes = lp_servicenumber(HOMES_NAME);
8283
8284         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8285              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8286                 char *home;
8287
8288                 if (lp_servicenumber(p) >= 0)
8289                         continue;
8290
8291                 home = get_user_home_dir(talloc_tos(), p);
8292
8293                 if (home && home[0] && homes >= 0)
8294                         lp_add_home(p, homes, p, home);
8295
8296                 TALLOC_FREE(home);
8297         }
8298         SAFE_FREE(s);
8299 }
8300
8301 /***************************************************************************
8302  Auto-load one printer.
8303 ***************************************************************************/
8304
8305 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8306 {
8307         int printers = lp_servicenumber(PRINTERS_NAME);
8308         int i;
8309
8310         if (lp_servicenumber(name) < 0) {
8311                 lp_add_printer(name, printers);
8312                 if ((i = lp_servicenumber(name)) >= 0) {
8313                         string_set(&ServicePtrs[i]->comment, comment);
8314                         ServicePtrs[i]->autoloaded = True;
8315                 }
8316         }
8317 }
8318
8319 /***************************************************************************
8320  Have we loaded a services file yet?
8321 ***************************************************************************/
8322
8323 bool lp_loaded(void)
8324 {
8325         return (bLoaded);
8326 }
8327
8328 /***************************************************************************
8329  Unload unused services.
8330 ***************************************************************************/
8331
8332 void lp_killunused(bool (*snumused) (int))
8333 {
8334         int i;
8335         for (i = 0; i < iNumServices; i++) {
8336                 if (!VALID(i))
8337                         continue;
8338
8339                 /* don't kill autoloaded or usershare services */
8340                 if ( ServicePtrs[i]->autoloaded ||
8341                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8342                         continue;
8343                 }
8344
8345                 if (!snumused || !snumused(i)) {
8346                         free_service_byindex(i);
8347                 }
8348         }
8349 }
8350
8351 /**
8352  * Kill all except autoloaded and usershare services - convenience wrapper
8353  */
8354 void lp_kill_all_services(void)
8355 {
8356         lp_killunused(NULL);
8357 }
8358
8359 /***************************************************************************
8360  Unload a service.
8361 ***************************************************************************/
8362
8363 void lp_killservice(int iServiceIn)
8364 {
8365         if (VALID(iServiceIn)) {
8366                 free_service_byindex(iServiceIn);
8367         }
8368 }
8369
8370 /***************************************************************************
8371  Save the curent values of all global and sDefault parameters into the 
8372  defaults union. This allows swat and testparm to show only the
8373  changed (ie. non-default) parameters.
8374 ***************************************************************************/
8375
8376 static void lp_save_defaults(void)
8377 {
8378         int i;
8379         for (i = 0; parm_table[i].label; i++) {
8380                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8381                         continue;
8382                 switch (parm_table[i].type) {
8383                         case P_LIST:
8384                                 parm_table[i].def.lvalue = str_list_copy(
8385                                         NULL, *(const char ***)parm_table[i].ptr);
8386                                 break;
8387                         case P_STRING:
8388                         case P_USTRING:
8389                                 if (parm_table[i].ptr) {
8390                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8391                                 } else {
8392                                         parm_table[i].def.svalue = NULL;
8393                                 }
8394                                 break;
8395                         case P_BOOL:
8396                         case P_BOOLREV:
8397                                 parm_table[i].def.bvalue =
8398                                         *(bool *)parm_table[i].ptr;
8399                                 break;
8400                         case P_CHAR:
8401                                 parm_table[i].def.cvalue =
8402                                         *(char *)parm_table[i].ptr;
8403                                 break;
8404                         case P_INTEGER:
8405                         case P_OCTAL:
8406                         case P_ENUM:
8407                                 parm_table[i].def.ivalue =
8408                                         *(int *)parm_table[i].ptr;
8409                                 break;
8410                         case P_SEP:
8411                                 break;
8412                 }
8413         }
8414         defaults_saved = True;
8415 }
8416
8417 /***********************************************************
8418  If we should send plaintext/LANMAN passwords in the clinet
8419 ************************************************************/
8420
8421 static void set_allowed_client_auth(void)
8422 {
8423         if (Globals.bClientNTLMv2Auth) {
8424                 Globals.bClientLanManAuth = False;
8425         }
8426         if (!Globals.bClientLanManAuth) {
8427                 Globals.bClientPlaintextAuth = False;
8428         }
8429 }
8430
8431 /***************************************************************************
8432  JRA.
8433  The following code allows smbd to read a user defined share file.
8434  Yes, this is my intent. Yes, I'm comfortable with that...
8435
8436  THE FOLLOWING IS SECURITY CRITICAL CODE.
8437
8438  It washes your clothes, it cleans your house, it guards you while you sleep...
8439  Do not f%^k with it....
8440 ***************************************************************************/
8441
8442 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8443
8444 /***************************************************************************
8445  Check allowed stat state of a usershare file.
8446  Ensure we print out who is dicking with us so the admin can
8447  get their sorry ass fired.
8448 ***************************************************************************/
8449
8450 static bool check_usershare_stat(const char *fname,
8451                                  const SMB_STRUCT_STAT *psbuf)
8452 {
8453         if (!S_ISREG(psbuf->st_ex_mode)) {
8454                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8455                         "not a regular file\n",
8456                         fname, (unsigned int)psbuf->st_ex_uid ));
8457                 return False;
8458         }
8459
8460         /* Ensure this doesn't have the other write bit set. */
8461         if (psbuf->st_ex_mode & S_IWOTH) {
8462                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8463                         "public write. Refusing to allow as a usershare file.\n",
8464                         fname, (unsigned int)psbuf->st_ex_uid ));
8465                 return False;
8466         }
8467
8468         /* Should be 10k or less. */
8469         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8470                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8471                         "too large (%u) to be a user share file.\n",
8472                         fname, (unsigned int)psbuf->st_ex_uid,
8473                         (unsigned int)psbuf->st_ex_size ));
8474                 return False;
8475         }
8476
8477         return True;
8478 }
8479
8480 /***************************************************************************
8481  Parse the contents of a usershare file.
8482 ***************************************************************************/
8483
8484 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8485                         SMB_STRUCT_STAT *psbuf,
8486                         const char *servicename,
8487                         int snum,
8488                         char **lines,
8489                         int numlines,
8490                         char **pp_sharepath,
8491                         char **pp_comment,
8492                         char **pp_cp_servicename,
8493                         struct security_descriptor **ppsd,
8494                         bool *pallow_guest)
8495 {
8496         const char **prefixallowlist = lp_usershare_prefix_allow_list();
8497         const char **prefixdenylist = lp_usershare_prefix_deny_list();
8498         int us_vers;
8499         SMB_STRUCT_DIR *dp;
8500         SMB_STRUCT_STAT sbuf;
8501         char *sharepath = NULL;
8502         char *comment = NULL;
8503
8504         *pp_sharepath = NULL;
8505         *pp_comment = NULL;
8506
8507         *pallow_guest = False;
8508
8509         if (numlines < 4) {
8510                 return USERSHARE_MALFORMED_FILE;
8511         }
8512
8513         if (strcmp(lines[0], "#VERSION 1") == 0) {
8514                 us_vers = 1;
8515         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8516                 us_vers = 2;
8517                 if (numlines < 5) {
8518                         return USERSHARE_MALFORMED_FILE;
8519                 }
8520         } else {
8521                 return USERSHARE_BAD_VERSION;
8522         }
8523
8524         if (strncmp(lines[1], "path=", 5) != 0) {
8525                 return USERSHARE_MALFORMED_PATH;
8526         }
8527
8528         sharepath = talloc_strdup(ctx, &lines[1][5]);
8529         if (!sharepath) {
8530                 return USERSHARE_POSIX_ERR;
8531         }
8532         trim_string(sharepath, " ", " ");
8533
8534         if (strncmp(lines[2], "comment=", 8) != 0) {
8535                 return USERSHARE_MALFORMED_COMMENT_DEF;
8536         }
8537
8538         comment = talloc_strdup(ctx, &lines[2][8]);
8539         if (!comment) {
8540                 return USERSHARE_POSIX_ERR;
8541         }
8542         trim_string(comment, " ", " ");
8543         trim_char(comment, '"', '"');
8544
8545         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8546                 return USERSHARE_MALFORMED_ACL_DEF;
8547         }
8548
8549         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8550                 return USERSHARE_ACL_ERR;
8551         }
8552
8553         if (us_vers == 2) {
8554                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8555                         return USERSHARE_MALFORMED_ACL_DEF;
8556                 }
8557                 if (lines[4][9] == 'y') {
8558                         *pallow_guest = True;
8559                 }
8560
8561                 /* Backwards compatible extension to file version #2. */
8562                 if (numlines > 5) {
8563                         if (strncmp(lines[5], "sharename=", 10) != 0) {
8564                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
8565                         }
8566                         if (!strequal(&lines[5][10], servicename)) {
8567                                 return USERSHARE_BAD_SHARENAME;
8568                         }
8569                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8570                         if (!*pp_cp_servicename) {
8571                                 return USERSHARE_POSIX_ERR;
8572                         }
8573                 }
8574         }
8575
8576         if (*pp_cp_servicename == NULL) {
8577                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8578                 if (!*pp_cp_servicename) {
8579                         return USERSHARE_POSIX_ERR;
8580                 }
8581         }
8582
8583         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8584                 /* Path didn't change, no checks needed. */
8585                 *pp_sharepath = sharepath;
8586                 *pp_comment = comment;
8587                 return USERSHARE_OK;
8588         }
8589
8590         /* The path *must* be absolute. */
8591         if (sharepath[0] != '/') {
8592                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8593                         servicename, sharepath));
8594                 return USERSHARE_PATH_NOT_ABSOLUTE;
8595         }
8596
8597         /* If there is a usershare prefix deny list ensure one of these paths
8598            doesn't match the start of the user given path. */
8599         if (prefixdenylist) {
8600                 int i;
8601                 for ( i=0; prefixdenylist[i]; i++ ) {
8602                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8603                                 servicename, i, prefixdenylist[i], sharepath ));
8604                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8605                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8606                                         "usershare prefix deny list entries.\n",
8607                                         servicename, sharepath));
8608                                 return USERSHARE_PATH_IS_DENIED;
8609                         }
8610                 }
8611         }
8612
8613         /* If there is a usershare prefix allow list ensure one of these paths
8614            does match the start of the user given path. */
8615
8616         if (prefixallowlist) {
8617                 int i;
8618                 for ( i=0; prefixallowlist[i]; i++ ) {
8619                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8620                                 servicename, i, prefixallowlist[i], sharepath ));
8621                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8622                                 break;
8623                         }
8624                 }
8625                 if (prefixallowlist[i] == NULL) {
8626                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8627                                 "usershare prefix allow list entries.\n",
8628                                 servicename, sharepath));
8629                         return USERSHARE_PATH_NOT_ALLOWED;
8630                 }
8631         }
8632
8633         /* Ensure this is pointing to a directory. */
8634         dp = sys_opendir(sharepath);
8635
8636         if (!dp) {
8637                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8638                         servicename, sharepath));
8639                 return USERSHARE_PATH_NOT_DIRECTORY;
8640         }
8641
8642         /* Ensure the owner of the usershare file has permission to share
8643            this directory. */
8644
8645         if (sys_stat(sharepath, &sbuf, false) == -1) {
8646                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8647                         servicename, sharepath, strerror(errno) ));
8648                 sys_closedir(dp);
8649                 return USERSHARE_POSIX_ERR;
8650         }
8651
8652         sys_closedir(dp);
8653
8654         if (!S_ISDIR(sbuf.st_ex_mode)) {
8655                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8656                         servicename, sharepath ));
8657                 return USERSHARE_PATH_NOT_DIRECTORY;
8658         }
8659
8660         /* Check if sharing is restricted to owner-only. */
8661         /* psbuf is the stat of the usershare definition file,
8662            sbuf is the stat of the target directory to be shared. */
8663
8664         if (lp_usershare_owner_only()) {
8665                 /* root can share anything. */
8666                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8667                         return USERSHARE_PATH_NOT_ALLOWED;
8668                 }
8669         }
8670
8671         *pp_sharepath = sharepath;
8672         *pp_comment = comment;
8673         return USERSHARE_OK;
8674 }
8675
8676 /***************************************************************************
8677  Deal with a usershare file.
8678  Returns:
8679         >= 0 - snum
8680         -1 - Bad name, invalid contents.
8681            - service name already existed and not a usershare, problem
8682             with permissions to share directory etc.
8683 ***************************************************************************/
8684
8685 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8686 {
8687         SMB_STRUCT_STAT sbuf;
8688         SMB_STRUCT_STAT lsbuf;
8689         char *fname = NULL;
8690         char *sharepath = NULL;
8691         char *comment = NULL;
8692         char *cp_service_name = NULL;
8693         char **lines = NULL;
8694         int numlines = 0;
8695         int fd = -1;
8696         int iService = -1;
8697         TALLOC_CTX *ctx = talloc_stackframe();
8698         struct security_descriptor *psd = NULL;
8699         bool guest_ok = False;
8700         char *canon_name = NULL;
8701         bool added_service = false;
8702         int ret = -1;
8703
8704         /* Ensure share name doesn't contain invalid characters. */
8705         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8706                 DEBUG(0,("process_usershare_file: share name %s contains "
8707                         "invalid characters (any of %s)\n",
8708                         file_name, INVALID_SHARENAME_CHARS ));
8709                 goto out;
8710         }
8711
8712         canon_name = canonicalize_servicename(ctx, file_name);
8713         if (!canon_name) {
8714                 goto out;
8715         }
8716
8717         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8718         if (!fname) {
8719                 goto out;
8720         }
8721
8722         /* Minimize the race condition by doing an lstat before we
8723            open and fstat. Ensure this isn't a symlink link. */
8724
8725         if (sys_lstat(fname, &lsbuf, false) != 0) {
8726                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8727                         fname, strerror(errno) ));
8728                 goto out;
8729         }
8730
8731         /* This must be a regular file, not a symlink, directory or
8732            other strange filetype. */
8733         if (!check_usershare_stat(fname, &lsbuf)) {
8734                 goto out;
8735         }
8736
8737         {
8738                 TDB_DATA data = dbwrap_fetch_bystring(
8739                         ServiceHash, canon_name, canon_name);
8740
8741                 iService = -1;
8742
8743                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8744                         iService = *(int *)data.dptr;
8745                 }
8746         }
8747
8748         if (iService != -1 &&
8749             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8750                              &lsbuf.st_ex_mtime) == 0) {
8751                 /* Nothing changed - Mark valid and return. */
8752                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8753                         canon_name ));
8754                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8755                 ret = iService;
8756                 goto out;
8757         }
8758
8759         /* Try and open the file read only - no symlinks allowed. */
8760 #ifdef O_NOFOLLOW
8761         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8762 #else
8763         fd = sys_open(fname, O_RDONLY, 0);
8764 #endif
8765
8766         if (fd == -1) {
8767                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8768                         fname, strerror(errno) ));
8769                 goto out;
8770         }
8771
8772         /* Now fstat to be *SURE* it's a regular file. */
8773         if (sys_fstat(fd, &sbuf, false) != 0) {
8774                 close(fd);
8775                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8776                         fname, strerror(errno) ));
8777                 goto out;
8778         }
8779
8780         /* Is it the same dev/inode as was lstated ? */
8781         if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8782                 close(fd);
8783                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8784                         "Symlink spoofing going on ?\n", fname ));
8785                 goto out;
8786         }
8787
8788         /* This must be a regular file, not a symlink, directory or
8789            other strange filetype. */
8790         if (!check_usershare_stat(fname, &sbuf)) {
8791                 goto out;
8792         }
8793
8794         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8795
8796         close(fd);
8797         if (lines == NULL) {
8798                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8799                         fname, (unsigned int)sbuf.st_ex_uid ));
8800                 goto out;
8801         }
8802
8803         if (parse_usershare_file(ctx, &sbuf, file_name,
8804                         iService, lines, numlines, &sharepath,
8805                         &comment, &cp_service_name,
8806                         &psd, &guest_ok) != USERSHARE_OK) {
8807                 goto out;
8808         }
8809
8810         /* Everything ok - add the service possibly using a template. */
8811         if (iService < 0) {
8812                 const struct service *sp = &sDefault;
8813                 if (snum_template != -1) {
8814                         sp = ServicePtrs[snum_template];
8815                 }
8816
8817                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8818                         DEBUG(0, ("process_usershare_file: Failed to add "
8819                                 "new service %s\n", cp_service_name));
8820                         goto out;
8821                 }
8822
8823                 added_service = true;
8824
8825                 /* Read only is controlled by usershare ACL below. */
8826                 ServicePtrs[iService]->bRead_only = False;
8827         }
8828
8829         /* Write the ACL of the new/modified share. */
8830         if (!set_share_security(canon_name, psd)) {
8831                  DEBUG(0, ("process_usershare_file: Failed to set share "
8832                         "security for user share %s\n",
8833                         canon_name ));
8834                 goto out;
8835         }
8836
8837         /* If from a template it may be marked invalid. */
8838         ServicePtrs[iService]->valid = True;
8839
8840         /* Set the service as a valid usershare. */
8841         ServicePtrs[iService]->usershare = USERSHARE_VALID;
8842
8843         /* Set guest access. */
8844         if (lp_usershare_allow_guests()) {
8845                 ServicePtrs[iService]->bGuest_ok = guest_ok;
8846         }
8847
8848         /* And note when it was loaded. */
8849         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8850         string_set(&ServicePtrs[iService]->szPath, sharepath);
8851         string_set(&ServicePtrs[iService]->comment, comment);
8852
8853         ret = iService;
8854
8855   out:
8856
8857         if (ret == -1 && iService != -1 && added_service) {
8858                 lp_remove_service(iService);
8859         }
8860
8861         TALLOC_FREE(lines);
8862         TALLOC_FREE(ctx);
8863         return ret;
8864 }
8865
8866 /***************************************************************************
8867  Checks if a usershare entry has been modified since last load.
8868 ***************************************************************************/
8869
8870 static bool usershare_exists(int iService, struct timespec *last_mod)
8871 {
8872         SMB_STRUCT_STAT lsbuf;
8873         const char *usersharepath = Globals.szUsersharePath;
8874         char *fname;
8875
8876         if (asprintf(&fname, "%s/%s",
8877                                 usersharepath,
8878                                 ServicePtrs[iService]->szService) < 0) {
8879                 return false;
8880         }
8881
8882         if (sys_lstat(fname, &lsbuf, false) != 0) {
8883                 SAFE_FREE(fname);
8884                 return false;
8885         }
8886
8887         if (!S_ISREG(lsbuf.st_ex_mode)) {
8888                 SAFE_FREE(fname);
8889                 return false;
8890         }
8891
8892         SAFE_FREE(fname);
8893         *last_mod = lsbuf.st_ex_mtime;
8894         return true;
8895 }
8896
8897 /***************************************************************************
8898  Load a usershare service by name. Returns a valid servicenumber or -1.
8899 ***************************************************************************/
8900
8901 int load_usershare_service(const char *servicename)
8902 {
8903         SMB_STRUCT_STAT sbuf;
8904         const char *usersharepath = Globals.szUsersharePath;
8905         int max_user_shares = Globals.iUsershareMaxShares;
8906         int snum_template = -1;
8907
8908         if (*usersharepath == 0 ||  max_user_shares == 0) {
8909                 return -1;
8910         }
8911
8912         if (sys_stat(usersharepath, &sbuf, false) != 0) {
8913                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8914                         usersharepath, strerror(errno) ));
8915                 return -1;
8916         }
8917
8918         if (!S_ISDIR(sbuf.st_ex_mode)) {
8919                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8920                         usersharepath ));
8921                 return -1;
8922         }
8923
8924         /*
8925          * This directory must be owned by root, and have the 't' bit set.
8926          * It also must not be writable by "other".
8927          */
8928
8929 #ifdef S_ISVTX
8930         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8931 #else
8932         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8933 #endif
8934                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8935                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8936                         usersharepath ));
8937                 return -1;
8938         }
8939
8940         /* Ensure the template share exists if it's set. */
8941         if (Globals.szUsershareTemplateShare[0]) {
8942                 /* We can't use lp_servicenumber here as we are recommending that
8943                    template shares have -valid=False set. */
8944                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8945                         if (ServicePtrs[snum_template]->szService &&
8946                                         strequal(ServicePtrs[snum_template]->szService,
8947                                                 Globals.szUsershareTemplateShare)) {
8948                                 break;
8949                         }
8950                 }
8951
8952                 if (snum_template == -1) {
8953                         DEBUG(0,("load_usershare_service: usershare template share %s "
8954                                 "does not exist.\n",
8955                                 Globals.szUsershareTemplateShare ));
8956                         return -1;
8957                 }
8958         }
8959
8960         return process_usershare_file(usersharepath, servicename, snum_template);
8961 }
8962
8963 /***************************************************************************
8964  Load all user defined shares from the user share directory.
8965  We only do this if we're enumerating the share list.
8966  This is the function that can delete usershares that have
8967  been removed.
8968 ***************************************************************************/
8969
8970 int load_usershare_shares(void)
8971 {
8972         SMB_STRUCT_DIR *dp;
8973         SMB_STRUCT_STAT sbuf;
8974         SMB_STRUCT_DIRENT *de;
8975         int num_usershares = 0;
8976         int max_user_shares = Globals.iUsershareMaxShares;
8977         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8978         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8979         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8980         int iService;
8981         int snum_template = -1;
8982         const char *usersharepath = Globals.szUsersharePath;
8983         int ret = lp_numservices();
8984
8985         if (max_user_shares == 0 || *usersharepath == '\0') {
8986                 return lp_numservices();
8987         }
8988
8989         if (sys_stat(usersharepath, &sbuf, false) != 0) {
8990                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8991                         usersharepath, strerror(errno) ));
8992                 return ret;
8993         }
8994
8995         /*
8996          * This directory must be owned by root, and have the 't' bit set.
8997          * It also must not be writable by "other".
8998          */
8999
9000 #ifdef S_ISVTX
9001         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9002 #else
9003         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9004 #endif
9005                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9006                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
9007                         usersharepath ));
9008                 return ret;
9009         }
9010
9011         /* Ensure the template share exists if it's set. */
9012         if (Globals.szUsershareTemplateShare[0]) {
9013                 /* We can't use lp_servicenumber here as we are recommending that
9014                    template shares have -valid=False set. */
9015                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9016                         if (ServicePtrs[snum_template]->szService &&
9017                                         strequal(ServicePtrs[snum_template]->szService,
9018                                                 Globals.szUsershareTemplateShare)) {
9019                                 break;
9020                         }
9021                 }
9022
9023                 if (snum_template == -1) {
9024                         DEBUG(0,("load_usershare_shares: usershare template share %s "
9025                                 "does not exist.\n",
9026                                 Globals.szUsershareTemplateShare ));
9027                         return ret;
9028                 }
9029         }
9030
9031         /* Mark all existing usershares as pending delete. */
9032         for (iService = iNumServices - 1; iService >= 0; iService--) {
9033                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9034                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9035                 }
9036         }
9037
9038         dp = sys_opendir(usersharepath);
9039         if (!dp) {
9040                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9041                         usersharepath, strerror(errno) ));
9042                 return ret;
9043         }
9044
9045         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9046                         (de = sys_readdir(dp));
9047                         num_dir_entries++ ) {
9048                 int r;
9049                 const char *n = de->d_name;
9050
9051                 /* Ignore . and .. */
9052                 if (*n == '.') {
9053                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9054                                 continue;
9055                         }
9056                 }
9057
9058                 if (n[0] == ':') {
9059                         /* Temporary file used when creating a share. */
9060                         num_tmp_dir_entries++;
9061                 }
9062
9063                 /* Allow 20% tmp entries. */
9064                 if (num_tmp_dir_entries > allowed_tmp_entries) {
9065                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9066                                 "in directory %s\n",
9067                                 num_tmp_dir_entries, usersharepath));
9068                         break;
9069                 }
9070
9071                 r = process_usershare_file(usersharepath, n, snum_template);
9072                 if (r == 0) {
9073                         /* Update the services count. */
9074                         num_usershares++;
9075                         if (num_usershares >= max_user_shares) {
9076                                 DEBUG(0,("load_usershare_shares: max user shares reached "
9077                                         "on file %s in directory %s\n",
9078                                         n, usersharepath ));
9079                                 break;
9080                         }
9081                 } else if (r == -1) {
9082                         num_bad_dir_entries++;
9083                 }
9084
9085                 /* Allow 20% bad entries. */
9086                 if (num_bad_dir_entries > allowed_bad_entries) {
9087                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9088                                 "in directory %s\n",
9089                                 num_bad_dir_entries, usersharepath));
9090                         break;
9091                 }
9092
9093                 /* Allow 20% bad entries. */
9094                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9095                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9096                         "in directory %s\n",
9097                         num_dir_entries, usersharepath));
9098                         break;
9099                 }
9100         }
9101
9102         sys_closedir(dp);
9103
9104         /* Sweep through and delete any non-refreshed usershares that are
9105            not currently in use. */
9106         for (iService = iNumServices - 1; iService >= 0; iService--) {
9107                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9108                         if (conn_snum_used(iService)) {
9109                                 continue;
9110                         }
9111                         /* Remove from the share ACL db. */
9112                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9113                                 lp_servicename(iService) ));
9114                         delete_share_security(lp_servicename(iService));
9115                         free_service_byindex(iService);
9116                 }
9117         }
9118
9119         return lp_numservices();
9120 }
9121
9122 /********************************************************
9123  Destroy global resources allocated in this file
9124 ********************************************************/
9125
9126 void gfree_loadparm(void)
9127 {
9128         int i;
9129
9130         free_file_list();
9131
9132         /* Free resources allocated to services */
9133
9134         for ( i = 0; i < iNumServices; i++ ) {
9135                 if ( VALID(i) ) {
9136                         free_service_byindex(i);
9137                 }
9138         }
9139
9140         SAFE_FREE( ServicePtrs );
9141         iNumServices = 0;
9142
9143         /* Now release all resources allocated to global
9144            parameters and the default service */
9145
9146         free_global_parameters();
9147 }
9148
9149
9150 /***************************************************************************
9151  Allow client apps to specify that they are a client
9152 ***************************************************************************/
9153 void lp_set_in_client(bool b)
9154 {
9155     in_client = b;
9156 }
9157
9158
9159 /***************************************************************************
9160  Determine if we're running in a client app
9161 ***************************************************************************/
9162 bool lp_is_in_client(void)
9163 {
9164     return in_client;
9165 }
9166
9167 /***************************************************************************
9168  Load the services array from the services file. Return True on success, 
9169  False on failure.
9170 ***************************************************************************/
9171
9172 bool lp_load_ex(const char *pszFname,
9173                 bool global_only,
9174                 bool save_defaults,
9175                 bool add_ipc,
9176                 bool initialize_globals,
9177                 bool allow_include_registry,
9178                 bool allow_registry_shares)
9179 {
9180         char *n2 = NULL;
9181         bool bRetval;
9182
9183         bRetval = False;
9184
9185         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9186
9187         bInGlobalSection = True;
9188         bGlobalOnly = global_only;
9189         bAllowIncludeRegistry = allow_include_registry;
9190
9191         init_globals(! initialize_globals);
9192         debug_init();
9193
9194         free_file_list();
9195
9196         if (save_defaults) {
9197                 init_locals();
9198                 lp_save_defaults();
9199         }
9200
9201         free_param_opts(&Globals.param_opt);
9202
9203         /* We get sections first, so have to start 'behind' to make up */
9204         iServiceIndex = -1;
9205
9206         if (lp_config_backend_is_file()) {
9207                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9208                                         current_user_info.domain,
9209                                         pszFname);
9210                 if (!n2) {
9211                         smb_panic("lp_load_ex: out of memory");
9212                 }
9213
9214                 add_to_file_list(pszFname, n2);
9215
9216                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9217                 TALLOC_FREE(n2);
9218
9219                 /* finish up the last section */
9220                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9221                 if (bRetval) {
9222                         if (iServiceIndex >= 0) {
9223                                 bRetval = service_ok(iServiceIndex);
9224                         }
9225                 }
9226
9227                 if (lp_config_backend_is_registry()) {
9228                         /* config backend changed to registry in config file */
9229                         /*
9230                          * We need to use this extra global variable here to
9231                          * survive restart: init_globals uses this as a default
9232                          * for ConfigBackend. Otherwise, init_globals would
9233                          *  send us into an endless loop here.
9234                          */
9235                         config_backend = CONFIG_BACKEND_REGISTRY;
9236                         /* start over */
9237                         DEBUG(1, ("lp_load_ex: changing to config backend "
9238                                   "registry\n"));
9239                         init_globals(false);
9240                         lp_kill_all_services();
9241                         return lp_load_ex(pszFname, global_only, save_defaults,
9242                                           add_ipc, initialize_globals,
9243                                           allow_include_registry,
9244                                           allow_registry_shares);
9245                 }
9246         } else if (lp_config_backend_is_registry()) {
9247                 bRetval = process_registry_globals();
9248         } else {
9249                 DEBUG(0, ("Illegal config  backend given: %d\n",
9250                           lp_config_backend()));
9251                 bRetval = false;
9252         }
9253
9254         if (bRetval && lp_registry_shares() && allow_registry_shares) {
9255                 bRetval = process_registry_shares();
9256         }
9257
9258         lp_add_auto_services(lp_auto_services());
9259
9260         if (add_ipc) {
9261                 /* When 'restrict anonymous = 2' guest connections to ipc$
9262                    are denied */
9263                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9264                 if ( lp_enable_asu_support() ) {
9265                         lp_add_ipc("ADMIN$", false);
9266                 }
9267         }
9268
9269         set_server_role();
9270         set_default_server_announce_type();
9271         set_allowed_client_auth();
9272
9273         bLoaded = True;
9274
9275         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9276         /* if bWINSsupport is true and we are in the client            */
9277         if (lp_is_in_client() && Globals.bWINSsupport) {
9278                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9279         }
9280
9281         init_iconv();
9282
9283         bAllowIncludeRegistry = true;
9284
9285         return (bRetval);
9286 }
9287
9288 bool lp_load(const char *pszFname,
9289              bool global_only,
9290              bool save_defaults,
9291              bool add_ipc,
9292              bool initialize_globals)
9293 {
9294         return lp_load_ex(pszFname,
9295                           global_only,
9296                           save_defaults,
9297                           add_ipc,
9298                           initialize_globals,
9299                           true,   /* allow_include_registry */
9300                           false); /* allow_registry_shares*/
9301 }
9302
9303 bool lp_load_initial_only(const char *pszFname)
9304 {
9305         return lp_load_ex(pszFname,
9306                           true,   /* global only */
9307                           false,  /* save_defaults */
9308                           false,  /* add_ipc */
9309                           true,   /* initialize_globals */
9310                           false,  /* allow_include_registry */
9311                           false); /* allow_registry_shares*/
9312 }
9313
9314 bool lp_load_with_registry_shares(const char *pszFname,
9315                                   bool global_only,
9316                                   bool save_defaults,
9317                                   bool add_ipc,
9318                                   bool initialize_globals)
9319 {
9320         return lp_load_ex(pszFname,
9321                           global_only,
9322                           save_defaults,
9323                           add_ipc,
9324                           initialize_globals,
9325                           true,  /* allow_include_registry */
9326                           true); /* allow_registry_shares*/
9327 }
9328
9329 /***************************************************************************
9330  Return the max number of services.
9331 ***************************************************************************/
9332
9333 int lp_numservices(void)
9334 {
9335         return (iNumServices);
9336 }
9337
9338 /***************************************************************************
9339 Display the contents of the services array in human-readable form.
9340 ***************************************************************************/
9341
9342 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9343 {
9344         int iService;
9345
9346         if (show_defaults)
9347                 defaults_saved = False;
9348
9349         dump_globals(f);
9350
9351         dump_a_service(&sDefault, f);
9352
9353         for (iService = 0; iService < maxtoprint; iService++) {
9354                 fprintf(f,"\n");
9355                 lp_dump_one(f, show_defaults, iService);
9356         }
9357 }
9358
9359 /***************************************************************************
9360 Display the contents of one service in human-readable form.
9361 ***************************************************************************/
9362
9363 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9364 {
9365         if (VALID(snum)) {
9366                 if (ServicePtrs[snum]->szService[0] == '\0')
9367                         return;
9368                 dump_a_service(ServicePtrs[snum], f);
9369         }
9370 }
9371
9372 /***************************************************************************
9373 Return the number of the service with the given name, or -1 if it doesn't
9374 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9375 getservicebyname()! This works ONLY if all services have been loaded, and
9376 does not copy the found service.
9377 ***************************************************************************/
9378
9379 int lp_servicenumber(const char *pszServiceName)
9380 {
9381         int iService;
9382         fstring serviceName;
9383
9384         if (!pszServiceName) {
9385                 return GLOBAL_SECTION_SNUM;
9386         }
9387
9388         for (iService = iNumServices - 1; iService >= 0; iService--) {
9389                 if (VALID(iService) && ServicePtrs[iService]->szService) {
9390                         /*
9391                          * The substitution here is used to support %U is
9392                          * service names
9393                          */
9394                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
9395                         standard_sub_basic(get_current_username(),
9396                                            current_user_info.domain,
9397                                            serviceName,sizeof(serviceName));
9398                         if (strequal(serviceName, pszServiceName)) {
9399                                 break;
9400                         }
9401                 }
9402         }
9403
9404         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9405                 struct timespec last_mod;
9406
9407                 if (!usershare_exists(iService, &last_mod)) {
9408                         /* Remove the share security tdb entry for it. */
9409                         delete_share_security(lp_servicename(iService));
9410                         /* Remove it from the array. */
9411                         free_service_byindex(iService);
9412                         /* Doesn't exist anymore. */
9413                         return GLOBAL_SECTION_SNUM;
9414                 }
9415
9416                 /* Has it been modified ? If so delete and reload. */
9417                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9418                                      &last_mod) < 0) {
9419                         /* Remove it from the array. */
9420                         free_service_byindex(iService);
9421                         /* and now reload it. */
9422                         iService = load_usershare_service(pszServiceName);
9423                 }
9424         }
9425
9426         if (iService < 0) {
9427                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9428                 return GLOBAL_SECTION_SNUM;
9429         }
9430
9431         return (iService);
9432 }
9433
9434 bool share_defined(const char *service_name)
9435 {
9436         return (lp_servicenumber(service_name) != -1);
9437 }
9438
9439 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9440                                       const char *sharename)
9441 {
9442         struct share_params *result;
9443         char *sname;
9444         int snum;
9445
9446         if (!(sname = SMB_STRDUP(sharename))) {
9447                 return NULL;
9448         }
9449
9450         snum = find_service(sname);
9451         SAFE_FREE(sname);
9452
9453         if (snum < 0) {
9454                 return NULL;
9455         }
9456
9457         if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9458                 DEBUG(0, ("talloc failed\n"));
9459                 return NULL;
9460         }
9461
9462         result->service = snum;
9463         return result;
9464 }
9465
9466 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9467 {
9468         struct share_iterator *result;
9469
9470         if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9471                 DEBUG(0, ("talloc failed\n"));
9472                 return NULL;
9473         }
9474
9475         result->next_id = 0;
9476         return result;
9477 }
9478
9479 struct share_params *next_share(struct share_iterator *list)
9480 {
9481         struct share_params *result;
9482
9483         while (!lp_snum_ok(list->next_id) &&
9484                (list->next_id < lp_numservices())) {
9485                 list->next_id += 1;
9486         }
9487
9488         if (list->next_id >= lp_numservices()) {
9489                 return NULL;
9490         }
9491
9492         if (!(result = TALLOC_P(list, struct share_params))) {
9493                 DEBUG(0, ("talloc failed\n"));
9494                 return NULL;
9495         }
9496
9497         result->service = list->next_id;
9498         list->next_id += 1;
9499         return result;
9500 }
9501
9502 struct share_params *next_printer(struct share_iterator *list)
9503 {
9504         struct share_params *result;
9505
9506         while ((result = next_share(list)) != NULL) {
9507                 if (lp_print_ok(result->service)) {
9508                         break;
9509                 }
9510         }
9511         return result;
9512 }
9513
9514 /*
9515  * This is a hack for a transition period until we transformed all code from
9516  * service numbers to struct share_params.
9517  */
9518
9519 struct share_params *snum2params_static(int snum)
9520 {
9521         static struct share_params result;
9522         result.service = snum;
9523         return &result;
9524 }
9525
9526 /*******************************************************************
9527  A useful volume label function. 
9528 ********************************************************************/
9529
9530 const char *volume_label(int snum)
9531 {
9532         char *ret;
9533         const char *label = lp_volume(snum);
9534         if (!*label) {
9535                 label = lp_servicename(snum);
9536         }
9537
9538         /* This returns a 33 byte guarenteed null terminated string. */
9539         ret = talloc_strndup(talloc_tos(), label, 32);
9540         if (!ret) {
9541                 return "";
9542         }               
9543         return ret;
9544 }
9545
9546 /*******************************************************************
9547  Set the server type we will announce as via nmbd.
9548 ********************************************************************/
9549
9550 static void set_default_server_announce_type(void)
9551 {
9552         default_server_announce = 0;
9553         default_server_announce |= SV_TYPE_WORKSTATION;
9554         default_server_announce |= SV_TYPE_SERVER;
9555         default_server_announce |= SV_TYPE_SERVER_UNIX;
9556
9557         /* note that the flag should be set only if we have a 
9558            printer service but nmbd doesn't actually load the 
9559            services so we can't tell   --jerry */
9560
9561         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9562
9563         switch (lp_announce_as()) {
9564                 case ANNOUNCE_AS_NT_SERVER:
9565                         default_server_announce |= SV_TYPE_SERVER_NT;
9566                         /* fall through... */
9567                 case ANNOUNCE_AS_NT_WORKSTATION:
9568                         default_server_announce |= SV_TYPE_NT;
9569                         break;
9570                 case ANNOUNCE_AS_WIN95:
9571                         default_server_announce |= SV_TYPE_WIN95_PLUS;
9572                         break;
9573                 case ANNOUNCE_AS_WFW:
9574                         default_server_announce |= SV_TYPE_WFW;
9575                         break;
9576                 default:
9577                         break;
9578         }
9579
9580         switch (lp_server_role()) {
9581                 case ROLE_DOMAIN_MEMBER:
9582                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9583                         break;
9584                 case ROLE_DOMAIN_PDC:
9585                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9586                         break;
9587                 case ROLE_DOMAIN_BDC:
9588                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9589                         break;
9590                 case ROLE_STANDALONE:
9591                 default:
9592                         break;
9593         }
9594         if (lp_time_server())
9595                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9596
9597         if (lp_host_msdfs())
9598                 default_server_announce |= SV_TYPE_DFS_SERVER;
9599 }
9600
9601 /***********************************************************
9602  If we are PDC then prefer us as DMB
9603 ************************************************************/
9604
9605 bool lp_domain_master(void)
9606 {
9607         if (Globals.iDomainMaster == Auto)
9608                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9609
9610         return (bool)Globals.iDomainMaster;
9611 }
9612
9613 /***********************************************************
9614  If we are PDC then prefer us as DMB
9615 ************************************************************/
9616
9617 bool lp_domain_master_true_or_auto(void)
9618 {
9619         if (Globals.iDomainMaster) /* auto or yes */
9620                 return true;
9621
9622         return false;
9623 }
9624
9625 /***********************************************************
9626  If we are DMB then prefer us as LMB
9627 ************************************************************/
9628
9629 bool lp_preferred_master(void)
9630 {
9631         if (Globals.iPreferredMaster == Auto)
9632                 return (lp_local_master() && lp_domain_master());
9633
9634         return (bool)Globals.iPreferredMaster;
9635 }
9636
9637 /*******************************************************************
9638  Remove a service.
9639 ********************************************************************/
9640
9641 void lp_remove_service(int snum)
9642 {
9643         ServicePtrs[snum]->valid = False;
9644         invalid_services[num_invalid_services++] = snum;
9645 }
9646
9647 /*******************************************************************
9648  Copy a service.
9649 ********************************************************************/
9650
9651 void lp_copy_service(int snum, const char *new_name)
9652 {
9653         do_section(new_name, NULL);
9654         if (snum >= 0) {
9655                 snum = lp_servicenumber(new_name);
9656                 if (snum >= 0)
9657                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9658         }
9659 }
9660
9661
9662 /*******************************************************************
9663  Get the default server type we will announce as via nmbd.
9664 ********************************************************************/
9665
9666 int lp_default_server_announce(void)
9667 {
9668         return default_server_announce;
9669 }
9670
9671 /*******************************************************************
9672  Split the announce version into major and minor numbers.
9673 ********************************************************************/
9674
9675 int lp_major_announce_version(void)
9676 {
9677         static bool got_major = False;
9678         static int major_version = DEFAULT_MAJOR_VERSION;
9679         char *vers;
9680         char *p;
9681
9682         if (got_major)
9683                 return major_version;
9684
9685         got_major = True;
9686         if ((vers = lp_announce_version()) == NULL)
9687                 return major_version;
9688
9689         if ((p = strchr_m(vers, '.')) == 0)
9690                 return major_version;
9691
9692         *p = '\0';
9693         major_version = atoi(vers);
9694         return major_version;
9695 }
9696
9697 int lp_minor_announce_version(void)
9698 {
9699         static bool got_minor = False;
9700         static int minor_version = DEFAULT_MINOR_VERSION;
9701         char *vers;
9702         char *p;
9703
9704         if (got_minor)
9705                 return minor_version;
9706
9707         got_minor = True;
9708         if ((vers = lp_announce_version()) == NULL)
9709                 return minor_version;
9710
9711         if ((p = strchr_m(vers, '.')) == 0)
9712                 return minor_version;
9713
9714         p++;
9715         minor_version = atoi(p);
9716         return minor_version;
9717 }
9718
9719 /***********************************************************
9720  Set the global name resolution order (used in smbclient).
9721 ************************************************************/
9722
9723 void lp_set_name_resolve_order(const char *new_order)
9724 {
9725         string_set(&Globals.szNameResolveOrder, new_order);
9726 }
9727
9728 const char *lp_printername(int snum)
9729 {
9730         const char *ret = _lp_printername(snum);
9731         if (ret == NULL || (ret != NULL && *ret == '\0'))
9732                 ret = lp_const_servicename(snum);
9733
9734         return ret;
9735 }
9736
9737
9738 /***********************************************************
9739  Allow daemons such as winbindd to fix their logfile name.
9740 ************************************************************/
9741
9742 void lp_set_logfile(const char *name)
9743 {
9744         string_set(&Globals.szLogFile, name);
9745         debug_set_logfile(name);
9746 }
9747
9748 /*******************************************************************
9749  Return the max print jobs per queue.
9750 ********************************************************************/
9751
9752 int lp_maxprintjobs(int snum)
9753 {
9754         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9755         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9756                 maxjobs = PRINT_MAX_JOBID - 1;
9757
9758         return maxjobs;
9759 }
9760
9761 const char *lp_printcapname(void)
9762 {
9763         if ((Globals.szPrintcapname != NULL) &&
9764             (Globals.szPrintcapname[0] != '\0'))
9765                 return Globals.szPrintcapname;
9766
9767         if (sDefault.iPrinting == PRINT_CUPS) {
9768 #ifdef HAVE_CUPS
9769                 return "cups";
9770 #else
9771                 return "lpstat";
9772 #endif
9773         }
9774
9775         if (sDefault.iPrinting == PRINT_BSD)
9776                 return "/etc/printcap";
9777
9778         return PRINTCAP_NAME;
9779 }
9780
9781 static uint32 spoolss_state;
9782
9783 bool lp_disable_spoolss( void )
9784 {
9785         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9786                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9787
9788         return spoolss_state == SVCCTL_STOPPED ? True : False;
9789 }
9790
9791 void lp_set_spoolss_state( uint32 state )
9792 {
9793         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9794
9795         spoolss_state = state;
9796 }
9797
9798 uint32 lp_get_spoolss_state( void )
9799 {
9800         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9801 }
9802
9803 /*******************************************************************
9804  Ensure we don't use sendfile if server smb signing is active.
9805 ********************************************************************/
9806
9807 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9808 {
9809         bool sign_active = false;
9810
9811         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9812         if (get_Protocol() < PROTOCOL_NT1) {
9813                 return false;
9814         }
9815         if (signing_state) {
9816                 sign_active = smb_signing_is_active(signing_state);
9817         }
9818         return (_lp_use_sendfile(snum) &&
9819                         (get_remote_arch() != RA_WIN95) &&
9820                         !sign_active);
9821 }
9822
9823 /*******************************************************************
9824  Turn off sendfile if we find the underlying OS doesn't support it.
9825 ********************************************************************/
9826
9827 void set_use_sendfile(int snum, bool val)
9828 {
9829         if (LP_SNUM_OK(snum))
9830                 ServicePtrs[snum]->bUseSendfile = val;
9831         else
9832                 sDefault.bUseSendfile = val;
9833 }
9834
9835 /*******************************************************************
9836  Turn off storing DOS attributes if this share doesn't support it.
9837 ********************************************************************/
9838
9839 void set_store_dos_attributes(int snum, bool val)
9840 {
9841         if (!LP_SNUM_OK(snum))
9842                 return;
9843         ServicePtrs[(snum)]->bStoreDosAttributes = val;
9844 }
9845
9846 void lp_set_mangling_method(const char *new_method)
9847 {
9848         string_set(&Globals.szManglingMethod, new_method);
9849 }
9850
9851 /*******************************************************************
9852  Global state for POSIX pathname processing.
9853 ********************************************************************/
9854
9855 static bool posix_pathnames;
9856
9857 bool lp_posix_pathnames(void)
9858 {
9859         return posix_pathnames;
9860 }
9861
9862 /*******************************************************************
9863  Change everything needed to ensure POSIX pathname processing (currently
9864  not much).
9865 ********************************************************************/
9866
9867 void lp_set_posix_pathnames(void)
9868 {
9869         posix_pathnames = True;
9870 }
9871
9872 /*******************************************************************
9873  Global state for POSIX lock processing - CIFS unix extensions.
9874 ********************************************************************/
9875
9876 bool posix_default_lock_was_set;
9877 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9878
9879 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9880 {
9881         if (posix_default_lock_was_set) {
9882                 return posix_cifsx_locktype;
9883         } else {
9884                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9885         }
9886 }
9887
9888 /*******************************************************************
9889 ********************************************************************/
9890
9891 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9892 {
9893         posix_default_lock_was_set = True;
9894         posix_cifsx_locktype = val;
9895 }
9896
9897 int lp_min_receive_file_size(void)
9898 {
9899         if (Globals.iminreceivefile < 0) {
9900                 return 0;
9901         }
9902         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9903 }
9904
9905 /*******************************************************************
9906  If socket address is an empty character string, it is necessary to 
9907  define it as "0.0.0.0". 
9908 ********************************************************************/
9909
9910 const char *lp_socket_address(void)
9911 {
9912         char *sock_addr = Globals.szSocketAddress;
9913
9914         if (sock_addr[0] == '\0'){
9915                 string_set(&Globals.szSocketAddress, "0.0.0.0");
9916         }
9917         return  Globals.szSocketAddress;
9918 }
9919
9920 void lp_set_passdb_backend(const char *backend)
9921 {
9922         string_set(&Globals.szPassdbBackend, backend);
9923 }
9924
9925 /*******************************************************************
9926  Safe wide links checks.
9927  This helper function always verify the validity of wide links,
9928  even after a configuration file reload.
9929 ********************************************************************/
9930
9931 static bool lp_widelinks_internal(int snum)
9932 {
9933         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9934                         sDefault.bWidelinks);
9935 }
9936
9937 void widelinks_warning(int snum)
9938 {
9939         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9940                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9941                         "These parameters are incompatible. "
9942                         "Wide links will be disabled for this share.\n",
9943                         lp_servicename(snum) ));
9944         }
9945 }
9946
9947 bool lp_widelinks(int snum)
9948 {
9949         /* wide links is always incompatible with unix extensions */
9950         if (lp_unix_extensions()) {
9951                 return false;
9952         }
9953
9954         return lp_widelinks_internal(snum);
9955 }
9956
9957 bool lp_writeraw(void)
9958 {
9959         if (lp_async_smb_echo_handler()) {
9960                 return false;
9961         }
9962         return _lp_writeraw();
9963 }
9964
9965 bool lp_readraw(void)
9966 {
9967         if (lp_async_smb_echo_handler()) {
9968                 return false;
9969         }
9970         return _lp_readraw();
9971 }