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