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