s3: Wrap usage of rlimit in configure checks
[ira/wip.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13    
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18    
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23    
24    You should have received a copy of the GNU General Public License
25    along with this program.  If not, see <http://www.gnu.org/licenses/>.
26 */
27
28 /*
29  *  Load parameters.
30  *
31  *  This module provides suitable callback functions for the params
32  *  module. It builds the internal table of service details which is
33  *  then used by the rest of the server.
34  *
35  * To add a parameter:
36  *
37  * 1) add it to the global or service structure definition
38  * 2) add it to the parm_table
39  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40  * 4) If it's a global then initialise it in init_globals. If a local
41  *    (ie. service) parameter then initialise it in the sDefault structure
42  *  
43  *
44  * Notes:
45  *   The configuration file is processed sequentially for speed. It is NOT
46  *   accessed randomly as happens in 'real' Windows. For this reason, there
47  *   is a fair bit of sequence-dependent code here - ie., code which assumes
48  *   that certain things happen before others. In particular, the code which
49  *   happens at the boundary between sections is delicately poised, so be
50  *   careful!
51  *
52  */
53
54 #include "includes.h"
55 #include "printing.h"
56
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                 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4674                         rlimit_max = rl.rlim_cur;
4675
4676 #if defined(RLIM_INFINITY)
4677                 if(rl.rlim_cur == RLIM_INFINITY)
4678                         rlimit_max = MAX_OPEN_FILES;
4679         }
4680 #endif
4681 #endif
4682
4683         return MIN(sysctl_max, rlimit_max);
4684 }
4685
4686 /**
4687  * Common part of freeing allocated data for one parameter.
4688  */
4689 static void free_one_parameter_common(void *parm_ptr,
4690                                       struct parm_struct parm)
4691 {
4692         if ((parm.type == P_STRING) ||
4693             (parm.type == P_USTRING))
4694         {
4695                 string_free((char**)parm_ptr);
4696         } else if (parm.type == P_LIST) {
4697                 TALLOC_FREE(*((char***)parm_ptr));
4698         }
4699 }
4700
4701 /**
4702  * Free the allocated data for one parameter for a share
4703  * given as a service struct.
4704  */
4705 static void free_one_parameter(struct service *service,
4706                                struct parm_struct parm)
4707 {
4708         void *parm_ptr;
4709
4710         if (parm.p_class != P_LOCAL) {
4711                 return;
4712         }
4713
4714         parm_ptr = lp_local_ptr(service, parm.ptr);
4715
4716         free_one_parameter_common(parm_ptr, parm);
4717 }
4718
4719 /**
4720  * Free the allocated parameter data of a share given
4721  * as a service struct.
4722  */
4723 static void free_parameters(struct service *service)
4724 {
4725         uint32_t i;
4726
4727         for (i=0; parm_table[i].label; i++) {
4728                 free_one_parameter(service, parm_table[i]);
4729         }
4730 }
4731
4732 /**
4733  * Free the allocated data for one parameter for a given share
4734  * specified by an snum.
4735  */
4736 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4737 {
4738         void *parm_ptr;
4739
4740         if (parm.ptr == NULL) {
4741                 return;
4742         }
4743
4744         if (snum < 0) {
4745                 parm_ptr = parm.ptr;
4746         } else if (parm.p_class != P_LOCAL) {
4747                 return;
4748         } else {
4749                 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4750         }
4751
4752         free_one_parameter_common(parm_ptr, parm);
4753 }
4754
4755 /**
4756  * Free the allocated parameter data for a share specified
4757  * by an snum.
4758  */
4759 static void free_parameters_by_snum(int snum)
4760 {
4761         uint32_t i;
4762
4763         for (i=0; parm_table[i].label; i++) {
4764                 free_one_parameter_by_snum(snum, parm_table[i]);
4765         }
4766 }
4767
4768 /**
4769  * Free the allocated global parameters.
4770  */
4771 static void free_global_parameters(void)
4772 {
4773         free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4774 }
4775
4776 /***************************************************************************
4777  Initialise the global parameter structure.
4778 ***************************************************************************/
4779
4780 static void init_globals(bool first_time_only)
4781 {
4782         static bool done_init = False;
4783         char *s = NULL;
4784         int i;
4785
4786         /* If requested to initialize only once and we've already done it... */
4787         if (first_time_only && done_init) {
4788                 /* ... then we have nothing more to do */
4789                 return;
4790         }
4791
4792         if (!done_init) {
4793                 /* The logfile can be set before this is invoked. Free it if so. */
4794                 if (Globals.szLogFile != NULL) {
4795                         string_free(&Globals.szLogFile);
4796                         Globals.szLogFile = NULL;
4797                 }
4798                 done_init = True;
4799         } else {
4800                 free_global_parameters();
4801         }
4802
4803         memset((void *)&Globals, '\0', sizeof(Globals));
4804
4805         for (i = 0; parm_table[i].label; i++) {
4806                 if ((parm_table[i].type == P_STRING ||
4807                      parm_table[i].type == P_USTRING) &&
4808                     parm_table[i].ptr)
4809                 {
4810                         string_set((char **)parm_table[i].ptr, "");
4811                 }
4812         }
4813
4814         string_set(&sDefault.fstype, FSTYPE_STRING);
4815         string_set(&sDefault.szPrintjobUsername, "%U");
4816
4817         init_printer_values(&sDefault);
4818
4819
4820         DEBUG(3, ("Initialising global parameters\n"));
4821
4822         string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4823         string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4824
4825         /* use the new 'hash2' method by default, with a prefix of 1 */
4826         string_set(&Globals.szManglingMethod, "hash2");
4827         Globals.mangle_prefix = 1;
4828
4829         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4830
4831         /* using UTF8 by default allows us to support all chars */
4832         string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4833
4834 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4835         /* If the system supports nl_langinfo(), try to grab the value
4836            from the user's locale */
4837         string_set(&Globals.display_charset, "LOCALE");
4838 #else
4839         string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4840 #endif
4841
4842         /* Use codepage 850 as a default for the dos character set */
4843         string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4844
4845         /*
4846          * Allow the default PASSWD_CHAT to be overridden in local.h.
4847          */
4848         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4849
4850         set_global_myname(myhostname());
4851         string_set(&Globals.szNetbiosName,global_myname());
4852
4853         set_global_myworkgroup(WORKGROUP);
4854         string_set(&Globals.szWorkgroup, lp_workgroup());
4855
4856         string_set(&Globals.szPasswdProgram, "");
4857         string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4858         string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4859         string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4860         string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4861         string_set(&Globals.szSocketAddress, "0.0.0.0");
4862
4863         if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4864                 smb_panic("init_globals: ENOMEM");
4865         }
4866         string_set(&Globals.szServerString, s);
4867         SAFE_FREE(s);
4868         if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4869                         DEFAULT_MINOR_VERSION) < 0) {
4870                 smb_panic("init_globals: ENOMEM");
4871         }
4872         string_set(&Globals.szAnnounceVersion, s);
4873         SAFE_FREE(s);
4874 #ifdef DEVELOPER
4875         string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4876 #endif
4877
4878         string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4879
4880         string_set(&Globals.szLogonDrive, "");
4881         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4882         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4883         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4884
4885         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4886         string_set(&Globals.szPasswordServer, "*");
4887
4888         Globals.AlgorithmicRidBase = BASE_RID;
4889
4890         Globals.bLoadPrinters = True;
4891         Globals.PrintcapCacheTime = 750;        /* 12.5 minutes */
4892
4893         Globals.ConfigBackend = config_backend;
4894
4895         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4896         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4897         Globals.max_xmit = 0x4104;
4898         Globals.max_mux = 50;   /* This is *needed* for profile support. */
4899         Globals.lpqcachetime = 30;      /* changed to handle large print servers better -- jerry */
4900         Globals.bDisableSpoolss = False;
4901         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4902         Globals.pwordlevel = 0;
4903         Globals.unamelevel = 0;
4904         Globals.deadtime = 0;
4905         Globals.getwd_cache = true;
4906         Globals.bLargeReadwrite = True;
4907         Globals.max_log_size = 5000;
4908         Globals.max_open_files = max_open_files();
4909         Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4910         Globals.maxprotocol = PROTOCOL_NT1;
4911         Globals.minprotocol = PROTOCOL_CORE;
4912         Globals.security = SEC_USER;
4913         Globals.paranoid_server_security = True;
4914         Globals.bEncryptPasswords = True;
4915         Globals.bUpdateEncrypt = False;
4916         Globals.clientSchannel = Auto;
4917         Globals.serverSchannel = Auto;
4918         Globals.bReadRaw = True;
4919         Globals.bWriteRaw = True;
4920         Globals.bNullPasswords = False;
4921         Globals.bObeyPamRestrictions = False;
4922         Globals.syslog = 1;
4923         Globals.bSyslogOnly = False;
4924         Globals.bTimestampLogs = True;
4925         string_set(&Globals.szLogLevel, "0");
4926         Globals.bDebugPrefixTimestamp = False;
4927         Globals.bDebugHiresTimestamp = False;
4928         Globals.bDebugPid = False;
4929         Globals.bDebugUid = False;
4930         Globals.bDebugClass = False;
4931         Globals.bEnableCoreFiles = True;
4932         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
4933         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
4934         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
4935         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
4936         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
4937         Globals.lm_interval = 60;
4938         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4939 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4940         Globals.bNISHomeMap = False;
4941 #ifdef WITH_NISPLUS_HOME
4942         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4943 #else
4944         string_set(&Globals.szNISHomeMapName, "auto.home");
4945 #endif
4946 #endif
4947         Globals.bTimeServer = False;
4948         Globals.bBindInterfacesOnly = False;
4949         Globals.bUnixPasswdSync = False;
4950         Globals.bPamPasswordChange = False;
4951         Globals.bPasswdChatDebug = False;
4952         Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4953         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
4954         Globals.bNTStatusSupport = True; /* Use NT status by default. */
4955         Globals.bStatCache = True;      /* use stat cache by default */
4956         Globals.iMaxStatCacheSize = 256; /* 256k by default */
4957         Globals.restrict_anonymous = 0;
4958         Globals.bClientLanManAuth = False;      /* Do NOT use the LanMan hash if it is available */
4959         Globals.bClientPlaintextAuth = False;   /* Do NOT use a plaintext password even if is requested by the server */
4960         Globals.bLanmanAuth = False;    /* Do NOT use the LanMan hash, even if it is supplied */
4961         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4962         Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4963         /* Note, that we will use NTLM2 session security (which is different), if it is available */
4964
4965         Globals.map_to_guest = 0;       /* By Default, "Never" */
4966         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
4967         Globals.enhanced_browsing = true;
4968         Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4969 #ifdef MMAP_BLACKLIST
4970         Globals.bUseMmap = False;
4971 #else
4972         Globals.bUseMmap = True;
4973 #endif
4974         Globals.bUnixExtensions = True;
4975         Globals.bResetOnZeroVC = False;
4976
4977         /* hostname lookups can be very expensive and are broken on
4978            a large number of sites (tridge) */
4979         Globals.bHostnameLookups = False;
4980
4981         string_set(&Globals.szPassdbBackend, "smbpasswd");
4982         string_set(&Globals.szLdapSuffix, "");
4983         string_set(&Globals.szLdapMachineSuffix, "");
4984         string_set(&Globals.szLdapUserSuffix, "");
4985         string_set(&Globals.szLdapGroupSuffix, "");
4986         string_set(&Globals.szLdapIdmapSuffix, "");
4987
4988         string_set(&Globals.szLdapAdminDn, "");
4989         Globals.ldap_ssl = LDAP_SSL_START_TLS;
4990         Globals.ldap_ssl_ads = False;
4991         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4992         Globals.ldap_delete_dn = False;
4993         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4994         Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4995         Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4996         Globals.ldap_page_size = LDAP_PAGE_SIZE;
4997
4998         Globals.ldap_debug_level = 0;
4999         Globals.ldap_debug_threshold = 10;
5000
5001         /* This is what we tell the afs client. in reality we set the token 
5002          * to never expire, though, when this runs out the afs client will 
5003          * forget the token. Set to 0 to get NEVERDATE.*/
5004         Globals.iAfsTokenLifetime = 604800;
5005         Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5006
5007 /* these parameters are set to defaults that are more appropriate
5008    for the increasing samba install base:
5009
5010    as a member of the workgroup, that will possibly become a
5011    _local_ master browser (lm = True).  this is opposed to a forced
5012    local master browser startup (pm = True).
5013
5014    doesn't provide WINS server service by default (wsupp = False),
5015    and doesn't provide domain master browser services by default, either.
5016
5017 */
5018
5019         Globals.bMsAddPrinterWizard = True;
5020         Globals.os_level = 20;
5021         Globals.bLocalMaster = True;
5022         Globals.iDomainMaster = Auto;   /* depending on bDomainLogons */
5023         Globals.bDomainLogons = False;
5024         Globals.bBrowseList = True;
5025         Globals.bWINSsupport = False;
5026         Globals.bWINSproxy = False;
5027
5028         TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5029         Globals.InitLogonDelay = 100; /* 100 ms default delay */
5030
5031         Globals.bDNSproxy = True;
5032
5033         /* this just means to use them if they exist */
5034         Globals.bKernelOplocks = True;
5035
5036         Globals.bAllowTrustedDomains = True;
5037         string_set(&Globals.szIdmapBackend, "tdb");
5038
5039         string_set(&Globals.szTemplateShell, "/bin/false");
5040         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5041         string_set(&Globals.szWinbindSeparator, "\\");
5042
5043         string_set(&Globals.szCupsServer, "");
5044         string_set(&Globals.szIPrintServer, "");
5045
5046         string_set(&Globals.ctdbdSocket, "");
5047         Globals.szClusterAddresses = NULL;
5048         Globals.clustering = False;
5049
5050         Globals.winbind_cache_time = 300;       /* 5 minutes */
5051         Globals.winbind_reconnect_delay = 30;   /* 30 seconds */
5052         Globals.bWinbindEnumUsers = False;
5053         Globals.bWinbindEnumGroups = False;
5054         Globals.bWinbindUseDefaultDomain = False;
5055         Globals.bWinbindTrustedDomainsOnly = False;
5056         Globals.bWinbindNestedGroups = True;
5057         Globals.winbind_expand_groups = 1;
5058         Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5059         Globals.bWinbindRefreshTickets = False;
5060         Globals.bWinbindOfflineLogon = False;
5061
5062         Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5063         Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5064
5065         Globals.bPassdbExpandExplicit = False;
5066
5067         Globals.name_cache_timeout = 660; /* In seconds */
5068
5069         Globals.bUseSpnego = True;
5070         Globals.bClientUseSpnego = True;
5071
5072         Globals.client_signing = Auto;
5073         Globals.server_signing = False;
5074
5075         Globals.bDeferSharingViolations = True;
5076         string_set(&Globals.smb_ports, SMB_PORTS);
5077
5078         Globals.bEnablePrivileges = True;
5079         Globals.bHostMSDfs        = True;
5080         Globals.bASUSupport       = False;
5081
5082         /* User defined shares. */
5083         if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5084                 smb_panic("init_globals: ENOMEM");
5085         }
5086         string_set(&Globals.szUsersharePath, s);
5087         SAFE_FREE(s);
5088         string_set(&Globals.szUsershareTemplateShare, "");
5089         Globals.iUsershareMaxShares = 0;
5090         /* By default disallow sharing of directories not owned by the sharer. */
5091         Globals.bUsershareOwnerOnly = True;
5092         /* By default disallow guest access to usershares. */
5093         Globals.bUsershareAllowGuests = False;
5094
5095         Globals.iKeepalive = DEFAULT_KEEPALIVE;
5096
5097         /* By default no shares out of the registry */
5098         Globals.bRegistryShares = False;
5099
5100         Globals.iminreceivefile = 0;
5101
5102         Globals.bMapUntrustedToDomain = false;
5103 }
5104
5105 /*******************************************************************
5106  Convenience routine to grab string parameters into temporary memory
5107  and run standard_sub_basic on them. The buffers can be written to by
5108  callers without affecting the source string.
5109 ********************************************************************/
5110
5111 static char *lp_string(const char *s)
5112 {
5113         char *ret;
5114         TALLOC_CTX *ctx = talloc_tos();
5115
5116         /* The follow debug is useful for tracking down memory problems
5117            especially if you have an inner loop that is calling a lp_*()
5118            function that returns a string.  Perhaps this debug should be
5119            present all the time? */
5120
5121 #if 0
5122         DEBUG(10, ("lp_string(%s)\n", s));
5123 #endif
5124
5125         ret = talloc_sub_basic(ctx,
5126                         get_current_username(),
5127                         current_user_info.domain,
5128                         s);
5129         if (trim_char(ret, '\"', '\"')) {
5130                 if (strchr(ret,'\"') != NULL) {
5131                         TALLOC_FREE(ret);
5132                         ret = talloc_sub_basic(ctx,
5133                                         get_current_username(),
5134                                         current_user_info.domain,
5135                                         s);
5136                 }
5137         }
5138         return ret;
5139 }
5140
5141 /*
5142    In this section all the functions that are used to access the
5143    parameters from the rest of the program are defined
5144 */
5145
5146 #define FN_GLOBAL_STRING(fn_name,ptr) \
5147  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5148 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5149  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5150 #define FN_GLOBAL_LIST(fn_name,ptr) \
5151  const char **fn_name(void) {return(*(const char ***)(ptr));}
5152 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5153  bool fn_name(void) {return(*(bool *)(ptr));}
5154 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5155  char fn_name(void) {return(*(char *)(ptr));}
5156 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5157  int fn_name(void) {return(*(int *)(ptr));}
5158
5159 #define FN_LOCAL_STRING(fn_name,val) \
5160  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5161 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5162  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5163 #define FN_LOCAL_LIST(fn_name,val) \
5164  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5165 #define FN_LOCAL_BOOL(fn_name,val) \
5166  bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5167 #define FN_LOCAL_INTEGER(fn_name,val) \
5168  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5169
5170 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5171  bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5172 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5173  int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5174 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5175  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));}
5176 #define FN_LOCAL_CHAR(fn_name,val) \
5177  char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5178
5179 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5180 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5181 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5182 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5183 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5184 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5185 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5186 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5187 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5188 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5189 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5190 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5191 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5192 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5193 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5194 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5195 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5196  * build process or in smb.conf, we use that value.  Otherwise they
5197  * default to the value of lp_lockdir(). */
5198 char *lp_statedir(void) {
5199         if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5200             (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5201                 return(lp_string(*(char **)(&Globals.szStateDir) ?
5202                     *(char **)(&Globals.szStateDir) : ""));
5203         else
5204                 return(lp_string(*(char **)(&Globals.szLockDir) ?
5205                     *(char **)(&Globals.szLockDir) : ""));
5206 }
5207 char *lp_cachedir(void) {
5208         if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5209             (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5210                 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5211                     *(char **)(&Globals.szCacheDir) : ""));
5212         else
5213                 return(lp_string(*(char **)(&Globals.szLockDir) ?
5214                     *(char **)(&Globals.szLockDir) : ""));
5215 }
5216 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5217 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5218 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5219 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5220 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5221 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5222 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5223 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5224 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5225 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5226 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5227 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5228 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5229 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5230 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5231 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5232 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5233 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5234 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5235 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5236 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5237 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5238 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5239 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5240 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5241 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5242 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5243 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5244 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5245 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5246 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5247 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5248 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5249 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5250  * lp_passdb_backend() should be replace by the this macro again after
5251  * some releases.
5252  * */
5253 const char *lp_passdb_backend(void)
5254 {
5255         char *delim, *quote;
5256
5257         delim = strchr( Globals.szPassdbBackend, ' ');
5258         /* no space at all */
5259         if (delim == NULL) {
5260                 goto out;
5261         }
5262
5263         quote = strchr(Globals.szPassdbBackend, '"');
5264         /* no quote char or non in the first part */
5265         if (quote == NULL || quote > delim) {
5266                 *delim = '\0';
5267                 goto warn;
5268         }
5269
5270         quote = strchr(quote+1, '"');
5271         if (quote == NULL) {
5272                 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5273                 goto out;
5274         } else if (*(quote+1) == '\0') {
5275                 /* space, fitting quote char, and one backend only */
5276                 goto out;
5277         } else {
5278                 /* terminate string after the fitting quote char */
5279                 *(quote+1) = '\0';
5280         }
5281
5282 warn:
5283         DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends.  This\n"
5284                 "is deprecated since Samba 3.0.23.  Please check WHATSNEW.txt or the section 'Passdb\n"
5285                 "Changes' from the ChangeNotes as part of the Samba HOWTO collection.  Only the first\n"
5286                 "backend (%s) is used.  The rest is ignored.\n", Globals.szPassdbBackend));
5287
5288 out:
5289         return Globals.szPassdbBackend;
5290 }
5291 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5292 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5293 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5294 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5295 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5296
5297 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5298 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5299 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5300 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5301 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5302 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5303
5304 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5305
5306 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5307 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5308 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5309
5310 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5311
5312 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5313 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5314 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5315 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5316 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5317 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5318 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5319 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5320 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5321 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5322 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5323 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5324 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5325 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5326 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5327
5328 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5329 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5330 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5331 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5332 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5333 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5334
5335 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5336 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5337 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5338 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5339 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5340 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5341 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5342 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5343 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5344 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5345 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5346 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5347 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5348 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5349 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5350 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5351 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5352 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5353
5354 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5355
5356 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5357 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5358 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5359 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5360 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5361 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5362 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5363 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5364 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5365 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5366 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5367 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5368 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5369 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5370 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5371 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5372 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5373 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5374 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5375 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5376 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5377 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5378 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5379 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5380 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5381 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5382 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5383 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5384 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5385 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5386 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5387 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5388 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5389 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5390 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5391 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5392 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5393 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5394 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5395 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5396 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5397 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5398 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5399 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5400 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5401 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5402 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5403 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5404 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5405 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5406 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5407 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5408 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5409 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5410 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5411 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5412 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5413 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5414 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5415 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5416 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5417 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5418 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5419 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5420 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5421 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5422 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5423 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5424 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5425 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5426 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5427 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5428 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5429 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5430 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5431 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5432 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5433 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5434 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5435 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5436 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5437 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5438 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5439 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5440 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5441 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5442 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5443 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5444 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5445 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5446 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5447 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5448 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5449 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5450 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5451 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5452 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5453 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5454 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5455 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5456
5457 FN_LOCAL_STRING(lp_preexec, szPreExec)
5458 FN_LOCAL_STRING(lp_postexec, szPostExec)
5459 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5460 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5461 FN_LOCAL_STRING(lp_servicename, szService)
5462 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5463 FN_LOCAL_STRING(lp_pathname, szPath)
5464 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5465 FN_LOCAL_STRING(lp_username, szUsername)
5466 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5467 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5468 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5469 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5470 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5471 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5472 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5473 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5474 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5475 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5476 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5477 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5478 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5479 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5480 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5481 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5482 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5483 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5484 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5485 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5486 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5487 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5488 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5489 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5490 FN_LOCAL_STRING(lp_comment, comment)
5491 FN_LOCAL_STRING(lp_force_user, force_user)
5492 FN_LOCAL_STRING(lp_force_group, force_group)
5493 FN_LOCAL_LIST(lp_readlist, readlist)
5494 FN_LOCAL_LIST(lp_writelist, writelist)
5495 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5496 FN_LOCAL_STRING(lp_fstype, fstype)
5497 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5498 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5499 static FN_LOCAL_STRING(lp_volume, volume)
5500 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5501 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5502 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5503 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5504 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5505 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5506 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5507 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5508 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5509 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5510 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5511 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5512 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5513 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5514 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5515 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5516 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5517 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5518 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5519 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5520 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5521 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5522 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5523 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5524 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5525 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5526 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5527 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5528 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5529 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5530 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5531 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5532 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5533 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5534 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5535 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5536 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5537 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5538 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5539 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5540 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5541 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5542 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5543 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5544 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5545 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5546 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5547 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5548 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5549 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5550 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5551 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5552 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5553 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5554 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5555 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5556 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5557 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5558 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5559 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5560 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5561 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5562 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5563 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5564 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5565 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5566 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5567 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5568 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5569 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5570 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5571 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5572 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5573 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5574 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5575 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5576 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5577 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5578 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5579 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5580 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5581 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5582 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5583 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5584 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5585 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5586 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5587 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5588 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5589 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5590 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5591 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5592 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5593 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5594 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5595 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5596 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5597 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5598 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5599
5600 /* local prototypes */
5601
5602 static int map_parameter(const char *pszParmName);
5603 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5604 static const char *get_boolean(bool bool_value);
5605 static int getservicebyname(const char *pszServiceName,
5606                             struct service *pserviceDest);
5607 static void copy_service(struct service *pserviceDest,
5608                          struct service *pserviceSource,
5609                          struct bitmap *pcopymapDest);
5610 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5611                          void *userdata);
5612 static bool do_section(const char *pszSectionName, void *userdata);
5613 static void init_copymap(struct service *pservice);
5614 static bool hash_a_service(const char *name, int number);
5615 static void free_service_byindex(int iService);
5616 static void free_param_opts(struct param_opt_struct **popts);
5617 static char * canonicalize_servicename(const char *name);
5618 static void show_parameter(int parmIndex);
5619 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5620
5621 /*
5622  * This is a helper function for parametrical options support.  It returns a
5623  * pointer to parametrical option value if it exists or NULL otherwise. Actual
5624  * parametrical functions are quite simple
5625  */
5626 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5627                                                 const char *option)
5628 {
5629         bool global_section = False;
5630         char* param_key;
5631         struct param_opt_struct *data;
5632         
5633         if (snum >= iNumServices) return NULL;
5634         
5635         if (snum < 0) { 
5636                 data = Globals.param_opt;
5637                 global_section = True;
5638         } else {
5639                 data = ServicePtrs[snum]->param_opt;
5640         }
5641     
5642         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5643                 DEBUG(0,("asprintf failed!\n"));
5644                 return NULL;
5645         }
5646
5647         while (data) {
5648                 if (strwicmp(data->key, param_key) == 0) {
5649                         string_free(&param_key);
5650                         return data;
5651                 }
5652                 data = data->next;
5653         }
5654
5655         if (!global_section) {
5656                 /* Try to fetch the same option but from globals */
5657                 /* but only if we are not already working with Globals */
5658                 data = Globals.param_opt;
5659                 while (data) {
5660                         if (strwicmp(data->key, param_key) == 0) {
5661                                 string_free(&param_key);
5662                                 return data;
5663                         }
5664                         data = data->next;
5665                 }
5666         }
5667
5668         string_free(&param_key);
5669         
5670         return NULL;
5671 }
5672
5673
5674 #define MISSING_PARAMETER(name) \
5675     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5676
5677 /*******************************************************************
5678 convenience routine to return int parameters.
5679 ********************************************************************/
5680 static int lp_int(const char *s)
5681 {
5682
5683         if (!s || !*s) {
5684                 MISSING_PARAMETER(lp_int);
5685                 return (-1);
5686         }
5687
5688         return (int)strtol(s, NULL, 0);
5689 }
5690
5691 /*******************************************************************
5692 convenience routine to return unsigned long parameters.
5693 ********************************************************************/
5694 static unsigned long lp_ulong(const char *s)
5695 {
5696
5697         if (!s || !*s) {
5698                 MISSING_PARAMETER(lp_ulong);
5699                 return (0);
5700         }
5701
5702         return strtoul(s, NULL, 0);
5703 }
5704
5705 /*******************************************************************
5706 convenience routine to return boolean parameters.
5707 ********************************************************************/
5708 static bool lp_bool(const char *s)
5709 {
5710         bool ret = False;
5711
5712         if (!s || !*s) {
5713                 MISSING_PARAMETER(lp_bool);
5714                 return False;
5715         }
5716         
5717         if (!set_boolean(s, &ret)) {
5718                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5719                 return False;
5720         }
5721
5722         return ret;
5723 }
5724
5725 /*******************************************************************
5726 convenience routine to return enum parameters.
5727 ********************************************************************/
5728 static int lp_enum(const char *s,const struct enum_list *_enum)
5729 {
5730         int i;
5731
5732         if (!s || !*s || !_enum) {
5733                 MISSING_PARAMETER(lp_enum);
5734                 return (-1);
5735         }
5736         
5737         for (i=0; _enum[i].name; i++) {
5738                 if (strequal(_enum[i].name,s))
5739                         return _enum[i].value;
5740         }
5741
5742         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5743         return (-1);
5744 }
5745
5746 #undef MISSING_PARAMETER
5747
5748 /* DO NOT USE lp_parm_string ANYMORE!!!!
5749  * use lp_parm_const_string or lp_parm_talloc_string
5750  *
5751  * lp_parm_string is only used to let old modules find this symbol
5752  */
5753 #undef lp_parm_string
5754  char *lp_parm_string(const char *servicename, const char *type, const char *option);
5755  char *lp_parm_string(const char *servicename, const char *type, const char *option)
5756 {
5757         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5758 }
5759
5760 /* Return parametric option from a given service. Type is a part of option before ':' */
5761 /* Parametric option has following syntax: 'Type: option = value' */
5762 /* the returned value is talloced on the talloc_tos() */
5763 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5764 {
5765         struct param_opt_struct *data = get_parametrics(snum, type, option);
5766         
5767         if (data == NULL||data->value==NULL) {
5768                 if (def) {
5769                         return lp_string(def);
5770                 } else {
5771                         return NULL;
5772                 }
5773         }
5774
5775         return lp_string(data->value);
5776 }
5777
5778 /* Return parametric option from a given service. Type is a part of option before ':' */
5779 /* Parametric option has following syntax: 'Type: option = value' */
5780 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5781 {
5782         struct param_opt_struct *data = get_parametrics(snum, type, option);
5783         
5784         if (data == NULL||data->value==NULL)
5785                 return def;
5786                 
5787         return data->value;
5788 }
5789
5790 /* Return parametric option from a given service. Type is a part of option before ':' */
5791 /* Parametric option has following syntax: 'Type: option = value' */
5792
5793 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5794 {
5795         struct param_opt_struct *data = get_parametrics(snum, type, option);
5796
5797         if (data == NULL||data->value==NULL)
5798                 return (const char **)def;
5799                 
5800         if (data->list==NULL) {
5801                 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5802         }
5803
5804         return (const char **)data->list;
5805 }
5806
5807 /* Return parametric option from a given service. Type is a part of option before ':' */
5808 /* Parametric option has following syntax: 'Type: option = value' */
5809
5810 int lp_parm_int(int snum, const char *type, const char *option, int def)
5811 {
5812         struct param_opt_struct *data = get_parametrics(snum, type, option);
5813         
5814         if (data && data->value && *data->value)
5815                 return lp_int(data->value);
5816
5817         return def;
5818 }
5819
5820 /* Return parametric option from a given service. Type is a part of option before ':' */
5821 /* Parametric option has following syntax: 'Type: option = value' */
5822
5823 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5824 {
5825         struct param_opt_struct *data = get_parametrics(snum, type, option);
5826         
5827         if (data && data->value && *data->value)
5828                 return lp_ulong(data->value);
5829
5830         return def;
5831 }
5832
5833 /* Return parametric option from a given service. Type is a part of option before ':' */
5834 /* Parametric option has following syntax: 'Type: option = value' */
5835
5836 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5837 {
5838         struct param_opt_struct *data = get_parametrics(snum, type, option);
5839         
5840         if (data && data->value && *data->value)
5841                 return lp_bool(data->value);
5842
5843         return def;
5844 }
5845
5846 /* Return parametric option from a given service. Type is a part of option before ':' */
5847 /* Parametric option has following syntax: 'Type: option = value' */
5848
5849 int lp_parm_enum(int snum, const char *type, const char *option,
5850                  const struct enum_list *_enum, int def)
5851 {
5852         struct param_opt_struct *data = get_parametrics(snum, type, option);
5853         
5854         if (data && data->value && *data->value && _enum)
5855                 return lp_enum(data->value, _enum);
5856
5857         return def;
5858 }
5859
5860
5861 /***************************************************************************
5862  Initialise a service to the defaults.
5863 ***************************************************************************/
5864
5865 static void init_service(struct service *pservice)
5866 {
5867         memset((char *)pservice, '\0', sizeof(struct service));
5868         copy_service(pservice, &sDefault, NULL);
5869 }
5870
5871
5872 /**
5873  * free a param_opts structure.
5874  * param_opts handling should be moved to talloc;
5875  * then this whole functions reduces to a TALLOC_FREE().
5876  */
5877
5878 static void free_param_opts(struct param_opt_struct **popts)
5879 {
5880         struct param_opt_struct *opt, *next_opt;
5881
5882         if (popts == NULL) {
5883                 return;
5884         }
5885
5886         if (*popts != NULL) {
5887                 DEBUG(5, ("Freeing parametrics:\n"));
5888         }
5889         opt = *popts;
5890         while (opt != NULL) {
5891                 string_free(&opt->key);
5892                 string_free(&opt->value);
5893                 TALLOC_FREE(opt->list);
5894                 next_opt = opt->next;
5895                 SAFE_FREE(opt);
5896                 opt = next_opt;
5897         }
5898         *popts = NULL;
5899 }
5900
5901 /***************************************************************************
5902  Free the dynamically allocated parts of a service struct.
5903 ***************************************************************************/
5904
5905 static void free_service(struct service *pservice)
5906 {
5907         if (!pservice)
5908                 return;
5909
5910         if (pservice->szService)
5911                 DEBUG(5, ("free_service: Freeing service %s\n",
5912                        pservice->szService));
5913
5914         free_parameters(pservice);
5915
5916         string_free(&pservice->szService);
5917         bitmap_free(pservice->copymap);
5918
5919         free_param_opts(&pservice->param_opt);
5920
5921         ZERO_STRUCTP(pservice);
5922 }
5923
5924
5925 /***************************************************************************
5926  remove a service indexed in the ServicePtrs array from the ServiceHash
5927  and free the dynamically allocated parts
5928 ***************************************************************************/
5929
5930 static void free_service_byindex(int idx)
5931 {
5932         if ( !LP_SNUM_OK(idx) ) 
5933                 return;
5934
5935         ServicePtrs[idx]->valid = False;
5936         invalid_services[num_invalid_services++] = idx;
5937
5938         /* we have to cleanup the hash record */
5939
5940         if (ServicePtrs[idx]->szService) {
5941                 char *canon_name = canonicalize_servicename(
5942                         ServicePtrs[idx]->szService );
5943                 
5944                 dbwrap_delete_bystring(ServiceHash, canon_name );
5945                 TALLOC_FREE(canon_name);
5946         }
5947
5948         free_service(ServicePtrs[idx]);
5949 }
5950
5951 /***************************************************************************
5952  Add a new service to the services array initialising it with the given 
5953  service. 
5954 ***************************************************************************/
5955
5956 static int add_a_service(const struct service *pservice, const char *name)
5957 {
5958         int i;
5959         struct service tservice;
5960         int num_to_alloc = iNumServices + 1;
5961
5962         tservice = *pservice;
5963
5964         /* it might already exist */
5965         if (name) {
5966                 i = getservicebyname(name, NULL);
5967                 if (i >= 0) {
5968                         /* Clean all parametric options for service */
5969                         /* They will be added during parsing again */
5970                         free_param_opts(&ServicePtrs[i]->param_opt);
5971                         return (i);
5972                 }
5973         }
5974
5975         /* find an invalid one */
5976         i = iNumServices;
5977         if (num_invalid_services > 0) {
5978                 i = invalid_services[--num_invalid_services];
5979         }
5980
5981         /* if not, then create one */
5982         if (i == iNumServices) {
5983                 struct service **tsp;
5984                 int *tinvalid;
5985                 
5986                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5987                 if (tsp == NULL) {
5988                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5989                         return (-1);
5990                 }
5991                 ServicePtrs = tsp;
5992                 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5993                 if (!ServicePtrs[iNumServices]) {
5994                         DEBUG(0,("add_a_service: out of memory!\n"));
5995                         return (-1);
5996                 }
5997                 iNumServices++;
5998
5999                 /* enlarge invalid_services here for now... */
6000                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6001                                              num_to_alloc);
6002                 if (tinvalid == NULL) {
6003                         DEBUG(0,("add_a_service: failed to enlarge "
6004                                  "invalid_services!\n"));
6005                         return (-1);
6006                 }
6007                 invalid_services = tinvalid;
6008         } else {
6009                 free_service_byindex(i);
6010         }
6011
6012         ServicePtrs[i]->valid = True;
6013
6014         init_service(ServicePtrs[i]);
6015         copy_service(ServicePtrs[i], &tservice, NULL);
6016         if (name)
6017                 string_set(&ServicePtrs[i]->szService, name);
6018                 
6019         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
6020                 i, ServicePtrs[i]->szService));
6021
6022         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6023                 return (-1);
6024         }
6025                 
6026         return (i);
6027 }
6028
6029 /***************************************************************************
6030   Convert a string to uppercase and remove whitespaces.
6031 ***************************************************************************/
6032
6033 static char *canonicalize_servicename(const char *src)
6034 {
6035         char *result;
6036
6037         if ( !src ) {
6038                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6039                 return NULL;
6040         }
6041
6042         result = talloc_strdup(talloc_tos(), src);
6043         SMB_ASSERT(result != NULL);
6044
6045         strlower_m(result);
6046         return result;
6047 }
6048
6049 /***************************************************************************
6050   Add a name/index pair for the services array to the hash table.
6051 ***************************************************************************/
6052
6053 static bool hash_a_service(const char *name, int idx)
6054 {
6055         char *canon_name;
6056
6057         if ( !ServiceHash ) {
6058                 DEBUG(10,("hash_a_service: creating servicehash\n"));
6059                 ServiceHash = db_open_rbt(NULL);
6060                 if ( !ServiceHash ) {
6061                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6062                         return False;
6063                 }
6064         }
6065
6066         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6067                 idx, name));
6068
6069         canon_name = canonicalize_servicename( name );
6070
6071         dbwrap_store_bystring(ServiceHash, canon_name,
6072                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
6073                               TDB_REPLACE);
6074
6075         TALLOC_FREE(canon_name);
6076
6077         return True;
6078 }
6079
6080 /***************************************************************************
6081  Add a new home service, with the specified home directory, defaults coming
6082  from service ifrom.
6083 ***************************************************************************/
6084
6085 bool lp_add_home(const char *pszHomename, int iDefaultService,
6086                  const char *user, const char *pszHomedir)
6087 {
6088         int i;
6089
6090         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6091
6092         if (i < 0)
6093                 return (False);
6094
6095         if (!(*(ServicePtrs[iDefaultService]->szPath))
6096             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6097                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6098         }
6099
6100         if (!(*(ServicePtrs[i]->comment))) {
6101                 char *comment = NULL;
6102                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6103                         return false;
6104                 }
6105                 string_set(&ServicePtrs[i]->comment, comment);
6106                 SAFE_FREE(comment);
6107         }
6108
6109         /* set the browseable flag from the global default */
6110
6111         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6112         ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6113
6114         ServicePtrs[i]->autoloaded = True;
6115
6116         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
6117                user, ServicePtrs[i]->szPath ));
6118
6119         return (True);
6120 }
6121
6122 /***************************************************************************
6123  Add a new service, based on an old one.
6124 ***************************************************************************/
6125
6126 int lp_add_service(const char *pszService, int iDefaultService)
6127 {
6128         if (iDefaultService < 0) {
6129                 return add_a_service(&sDefault, pszService);
6130         }
6131
6132         return (add_a_service(ServicePtrs[iDefaultService], pszService));
6133 }
6134
6135 /***************************************************************************
6136  Add the IPC service.
6137 ***************************************************************************/
6138
6139 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6140 {
6141         char *comment = NULL;
6142         int i = add_a_service(&sDefault, ipc_name);
6143
6144         if (i < 0)
6145                 return (False);
6146
6147         if (asprintf(&comment, "IPC Service (%s)",
6148                                 Globals.szServerString) < 0) {
6149                 return (False);
6150         }
6151
6152         string_set(&ServicePtrs[i]->szPath, tmpdir());
6153         string_set(&ServicePtrs[i]->szUsername, "");
6154         string_set(&ServicePtrs[i]->comment, comment);
6155         string_set(&ServicePtrs[i]->fstype, "IPC");
6156         ServicePtrs[i]->iMaxConnections = 0;
6157         ServicePtrs[i]->bAvailable = True;
6158         ServicePtrs[i]->bRead_only = True;
6159         ServicePtrs[i]->bGuest_only = False;
6160         ServicePtrs[i]->bAdministrative_share = True;
6161         ServicePtrs[i]->bGuest_ok = guest_ok;
6162         ServicePtrs[i]->bPrint_ok = False;
6163         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6164
6165         DEBUG(3, ("adding IPC service\n"));
6166
6167         SAFE_FREE(comment);
6168         return (True);
6169 }
6170
6171 /***************************************************************************
6172  Add a new printer service, with defaults coming from service iFrom.
6173 ***************************************************************************/
6174
6175 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6176 {
6177         const char *comment = "From Printcap";
6178         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6179
6180         if (i < 0)
6181                 return (False);
6182
6183         /* note that we do NOT default the availability flag to True - */
6184         /* we take it from the default service passed. This allows all */
6185         /* dynamic printers to be disabled by disabling the [printers] */
6186         /* entry (if/when the 'available' keyword is implemented!).    */
6187
6188         /* the printer name is set to the service name. */
6189         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6190         string_set(&ServicePtrs[i]->comment, comment);
6191
6192         /* set the browseable flag from the gloabl default */
6193         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6194
6195         /* Printers cannot be read_only. */
6196         ServicePtrs[i]->bRead_only = False;
6197         /* No share modes on printer services. */
6198         ServicePtrs[i]->bShareModes = False;
6199         /* No oplocks on printer services. */
6200         ServicePtrs[i]->bOpLocks = False;
6201         /* Printer services must be printable. */
6202         ServicePtrs[i]->bPrint_ok = True;
6203         
6204         DEBUG(3, ("adding printer service %s\n", pszPrintername));
6205
6206         return (True);
6207 }
6208
6209
6210 /***************************************************************************
6211  Check whether the given parameter name is valid.
6212  Parametric options (names containing a colon) are considered valid.
6213 ***************************************************************************/
6214
6215 bool lp_parameter_is_valid(const char *pszParmName)
6216 {
6217         return ((map_parameter(pszParmName) != -1) ||
6218                 (strchr(pszParmName, ':') != NULL));
6219 }
6220
6221 /***************************************************************************
6222  Check whether the given name is the name of a global parameter.
6223  Returns True for strings belonging to parameters of class
6224  P_GLOBAL, False for all other strings, also for parametric options
6225  and strings not belonging to any option.
6226 ***************************************************************************/
6227
6228 bool lp_parameter_is_global(const char *pszParmName)
6229 {
6230         int num = map_parameter(pszParmName);
6231
6232         if (num >= 0) {
6233                 return (parm_table[num].p_class == P_GLOBAL);
6234         }
6235
6236         return False;
6237 }
6238
6239 /**************************************************************************
6240  Check whether the given name is the canonical name of a parameter.
6241  Returns False if it is not a valid parameter Name.
6242  For parametric options, True is returned.
6243 **************************************************************************/
6244
6245 bool lp_parameter_is_canonical(const char *parm_name)
6246 {
6247         if (!lp_parameter_is_valid(parm_name)) {
6248                 return False;
6249         }
6250
6251         return (map_parameter(parm_name) ==
6252                 map_parameter_canonical(parm_name, NULL));
6253 }
6254
6255 /**************************************************************************
6256  Determine the canonical name for a parameter.
6257  Indicate when it is an inverse (boolean) synonym instead of a
6258  "usual" synonym.
6259 **************************************************************************/
6260
6261 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6262                                bool *inverse)
6263 {
6264         int num;
6265
6266         if (!lp_parameter_is_valid(parm_name)) {
6267                 *canon_parm = NULL;
6268                 return False;
6269         }
6270
6271         num = map_parameter_canonical(parm_name, inverse);
6272         if (num < 0) {
6273                 /* parametric option */
6274                 *canon_parm = parm_name;
6275         } else {
6276                 *canon_parm = parm_table[num].label;
6277         }
6278
6279         return True;
6280
6281 }
6282
6283 /**************************************************************************
6284  Determine the canonical name for a parameter.
6285  Turn the value given into the inverse boolean expression when
6286  the synonym is an invers boolean synonym.
6287
6288  Return True if parm_name is a valid parameter name and
6289  in case it is an invers boolean synonym, if the val string could
6290  successfully be converted to the reverse bool.
6291  Return false in all other cases.
6292 **************************************************************************/
6293
6294 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6295                                           const char *val,
6296                                           const char **canon_parm,
6297                                           const char **canon_val)
6298 {
6299         int num;
6300         bool inverse;
6301
6302         if (!lp_parameter_is_valid(parm_name)) {
6303                 *canon_parm = NULL;
6304                 *canon_val = NULL;
6305                 return False;
6306         }
6307
6308         num = map_parameter_canonical(parm_name, &inverse);
6309         if (num < 0) {
6310                 /* parametric option */
6311                 *canon_parm = parm_name;
6312                 *canon_val = val;
6313         } else {
6314                 *canon_parm = parm_table[num].label;
6315                 if (inverse) {
6316                         if (!lp_invert_boolean(val, canon_val)) {
6317                                 *canon_val = NULL;
6318                                 return False;
6319                         }
6320                 } else {
6321                         *canon_val = val;
6322                 }
6323         }
6324
6325         return True;
6326 }
6327
6328 /***************************************************************************
6329  Map a parameter's string representation to something we can use. 
6330  Returns False if the parameter string is not recognised, else TRUE.
6331 ***************************************************************************/
6332
6333 static int map_parameter(const char *pszParmName)
6334 {
6335         int iIndex;
6336
6337         if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6338                 return (-1);
6339
6340         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6341                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6342                         return (iIndex);
6343
6344         /* Warn only if it isn't parametric option */
6345         if (strchr(pszParmName, ':') == NULL)
6346                 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6347         /* We do return 'fail' for parametric options as well because they are
6348            stored in different storage
6349          */
6350         return (-1);
6351 }
6352
6353 /***************************************************************************
6354  Map a parameter's string representation to the index of the canonical
6355  form of the parameter (it might be a synonym).
6356  Returns -1 if the parameter string is not recognised.
6357 ***************************************************************************/
6358
6359 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6360 {
6361         int parm_num, canon_num;
6362         bool loc_inverse = False;
6363
6364         parm_num = map_parameter(pszParmName);
6365         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6366                 /* invalid, parametric or no canidate for synonyms ... */
6367                 goto done;
6368         }
6369
6370         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6371                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6372                         parm_num = canon_num;
6373                         goto done;
6374                 }
6375         }
6376
6377 done:
6378         if (inverse != NULL) {
6379                 *inverse = loc_inverse;
6380         }
6381         return parm_num;
6382 }
6383
6384 /***************************************************************************
6385  return true if parameter number parm1 is a synonym of parameter
6386  number parm2 (parm2 being the principal name).
6387  set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6388  False otherwise.
6389 ***************************************************************************/
6390
6391 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6392 {
6393         if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6394             (parm_table[parm1].flags & FLAG_HIDE) &&
6395             !(parm_table[parm2].flags & FLAG_HIDE))
6396         {
6397                 if (inverse != NULL) {
6398                         if ((parm_table[parm1].type == P_BOOLREV) &&
6399                             (parm_table[parm2].type == P_BOOL))
6400                         {
6401                                 *inverse = True;
6402                         } else {
6403                                 *inverse = False;
6404                         }
6405                 }
6406                 return True;
6407         }
6408         return False;
6409 }
6410
6411 /***************************************************************************
6412  Show one parameter's name, type, [values,] and flags.
6413  (helper functions for show_parameter_list)
6414 ***************************************************************************/
6415
6416 static void show_parameter(int parmIndex)
6417 {
6418         int enumIndex, flagIndex;
6419         int parmIndex2;
6420         bool hadFlag;
6421         bool hadSyn;
6422         bool inverse;
6423         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6424                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6425                 "P_ENUM", "P_SEP"};
6426         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6427                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6428                 FLAG_HIDE, FLAG_DOS_STRING};
6429         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6430                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6431                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6432
6433         printf("%s=%s", parm_table[parmIndex].label,
6434                type[parm_table[parmIndex].type]);
6435         if (parm_table[parmIndex].type == P_ENUM) {
6436                 printf(",");
6437                 for (enumIndex=0;
6438                      parm_table[parmIndex].enum_list[enumIndex].name;
6439                      enumIndex++)
6440                 {
6441                         printf("%s%s",
6442                                enumIndex ? "|" : "",
6443                                parm_table[parmIndex].enum_list[enumIndex].name);
6444                 }
6445         }
6446         printf(",");
6447         hadFlag = False;
6448         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6449                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6450                         printf("%s%s",
6451                                 hadFlag ? "|" : "",
6452                                 flag_names[flagIndex]);
6453                         hadFlag = True;
6454                 }
6455         }
6456
6457         /* output synonyms */
6458         hadSyn = False;
6459         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6460                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6461                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6462                                parm_table[parmIndex2].label);
6463                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6464                         if (!hadSyn) {
6465                                 printf(" (synonyms: ");
6466                                 hadSyn = True;
6467                         } else {
6468                                 printf(", ");
6469                         }
6470                         printf("%s%s", parm_table[parmIndex2].label,
6471                                inverse ? "[i]" : "");
6472                 }
6473         }
6474         if (hadSyn) {
6475                 printf(")");
6476         }
6477
6478         printf("\n");
6479 }
6480
6481 /***************************************************************************
6482  Show all parameter's name, type, [values,] and flags.
6483 ***************************************************************************/
6484
6485 void show_parameter_list(void)
6486 {
6487         int classIndex, parmIndex;
6488         const char *section_names[] = { "local", "global", NULL};
6489
6490         for (classIndex=0; section_names[classIndex]; classIndex++) {
6491                 printf("[%s]\n", section_names[classIndex]);
6492                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6493                         if (parm_table[parmIndex].p_class == classIndex) {
6494                                 show_parameter(parmIndex);
6495                         }
6496                 }
6497         }
6498 }
6499
6500 /***************************************************************************
6501  Check if a given string correctly represents a boolean value.
6502 ***************************************************************************/
6503
6504 bool lp_string_is_valid_boolean(const char *parm_value)
6505 {
6506         return set_boolean(parm_value, NULL);
6507 }
6508
6509 /***************************************************************************
6510  Get the standard string representation of a boolean value ("yes" or "no")
6511 ***************************************************************************/
6512
6513 static const char *get_boolean(bool bool_value)
6514 {
6515         static const char *yes_str = "yes";
6516         static const char *no_str = "no";
6517
6518         return (bool_value ? yes_str : no_str);
6519 }
6520
6521 /***************************************************************************
6522  Provide the string of the negated boolean value associated to the boolean
6523  given as a string. Returns False if the passed string does not correctly
6524  represent a boolean.
6525 ***************************************************************************/
6526
6527 bool lp_invert_boolean(const char *str, const char **inverse_str)
6528 {
6529         bool val;
6530
6531         if (!set_boolean(str, &val)) {
6532                 return False;
6533         }
6534
6535         *inverse_str = get_boolean(!val);
6536         return True;
6537 }
6538
6539 /***************************************************************************
6540  Provide the canonical string representation of a boolean value given
6541  as a string. Return True on success, False if the string given does
6542  not correctly represent a boolean.
6543 ***************************************************************************/
6544
6545 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6546 {
6547         bool val;
6548
6549         if (!set_boolean(str, &val)) {
6550                 return False;
6551         }
6552
6553         *canon_str = get_boolean(val);
6554         return True;
6555 }
6556
6557 /***************************************************************************
6558 Find a service by name. Otherwise works like get_service.
6559 ***************************************************************************/
6560
6561 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6562 {
6563         int iService = -1;
6564         char *canon_name;
6565         TDB_DATA data;
6566
6567         if (ServiceHash == NULL) {
6568                 return -1;
6569         }
6570
6571         canon_name = canonicalize_servicename(pszServiceName);
6572
6573         data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6574
6575         if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6576                 iService = *(int *)data.dptr;
6577         }
6578
6579         TALLOC_FREE(canon_name);
6580
6581         if ((iService != -1) && (LP_SNUM_OK(iService))
6582             && (pserviceDest != NULL)) {
6583                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6584         }
6585
6586         return (iService);
6587 }
6588
6589 /***************************************************************************
6590  Copy a service structure to another.
6591  If pcopymapDest is NULL then copy all fields
6592 ***************************************************************************/
6593
6594 /**
6595  * Add a parametric option to a param_opt_struct,
6596  * replacing old value, if already present.
6597  */
6598 static void set_param_opt(struct param_opt_struct **opt_list,
6599                           const char *opt_name,
6600                           const char *opt_value)
6601 {
6602         struct param_opt_struct *new_opt, *opt;
6603         bool not_added;
6604
6605         if (opt_list == NULL) {
6606                 return;
6607         }
6608
6609         opt = *opt_list;
6610         not_added = true;
6611
6612         /* Traverse destination */
6613         while (opt) {
6614                 /* If we already have same option, override it */
6615                 if (strwicmp(opt->key, opt_name) == 0) {
6616                         string_free(&opt->value);
6617                         TALLOC_FREE(opt->list);
6618                         opt->value = SMB_STRDUP(opt_value);
6619                         not_added = false;
6620                         break;
6621                 }
6622                 opt = opt->next;
6623         }
6624         if (not_added) {
6625             new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6626             new_opt->key = SMB_STRDUP(opt_name);
6627             new_opt->value = SMB_STRDUP(opt_value);
6628             new_opt->list = NULL;
6629             DLIST_ADD(*opt_list, new_opt);
6630         }
6631 }
6632
6633 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6634                          struct bitmap *pcopymapDest)
6635 {
6636         int i;
6637         bool bcopyall = (pcopymapDest == NULL);
6638         struct param_opt_struct *data;
6639
6640         for (i = 0; parm_table[i].label; i++)
6641                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6642                     (bcopyall || bitmap_query(pcopymapDest,i))) {
6643                         void *def_ptr = parm_table[i].ptr;
6644                         void *src_ptr =
6645                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6646                                                                     &sDefault);
6647                         void *dest_ptr =
6648                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6649                                                                   &sDefault);
6650
6651                         switch (parm_table[i].type) {
6652                                 case P_BOOL:
6653                                 case P_BOOLREV:
6654                                         *(bool *)dest_ptr = *(bool *)src_ptr;
6655                                         break;
6656
6657                                 case P_INTEGER:
6658                                 case P_ENUM:
6659                                 case P_OCTAL:
6660                                         *(int *)dest_ptr = *(int *)src_ptr;
6661                                         break;
6662
6663                                 case P_CHAR:
6664                                         *(char *)dest_ptr = *(char *)src_ptr;
6665                                         break;
6666
6667                                 case P_STRING:
6668                                         string_set((char **)dest_ptr,
6669                                                    *(char **)src_ptr);
6670                                         break;
6671
6672                                 case P_USTRING:
6673                                         string_set((char **)dest_ptr,
6674                                                    *(char **)src_ptr);
6675                                         strupper_m(*(char **)dest_ptr);
6676                                         break;
6677                                 case P_LIST:
6678                                         TALLOC_FREE(*((char ***)dest_ptr));
6679                                         *((char ***)dest_ptr) = str_list_copy(NULL, 
6680                                                       *(const char ***)src_ptr);
6681                                         break;
6682                                 default:
6683                                         break;
6684                         }
6685                 }
6686
6687         if (bcopyall) {
6688                 init_copymap(pserviceDest);
6689                 if (pserviceSource->copymap)
6690                         bitmap_copy(pserviceDest->copymap,
6691                                     pserviceSource->copymap);
6692         }
6693         
6694         data = pserviceSource->param_opt;
6695         while (data) {
6696                 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6697                 data = data->next;
6698         }
6699 }
6700
6701 /***************************************************************************
6702 Check a service for consistency. Return False if the service is in any way
6703 incomplete or faulty, else True.
6704 ***************************************************************************/
6705
6706 bool service_ok(int iService)
6707 {
6708         bool bRetval;
6709
6710         bRetval = True;
6711         if (ServicePtrs[iService]->szService[0] == '\0') {
6712                 DEBUG(0, ("The following message indicates an internal error:\n"));
6713                 DEBUG(0, ("No service name in service entry.\n"));
6714                 bRetval = False;
6715         }
6716
6717         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6718         /* I can't see why you'd want a non-printable printer service...        */
6719         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6720                 if (!ServicePtrs[iService]->bPrint_ok) {
6721                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6722                                ServicePtrs[iService]->szService));
6723                         ServicePtrs[iService]->bPrint_ok = True;
6724                 }
6725                 /* [printers] service must also be non-browsable. */
6726                 if (ServicePtrs[iService]->bBrowseable)
6727                         ServicePtrs[iService]->bBrowseable = False;
6728         }
6729
6730         if (ServicePtrs[iService]->szPath[0] == '\0' &&
6731             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6732             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6733             ) {
6734                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6735                         ServicePtrs[iService]->szService));
6736                 ServicePtrs[iService]->bAvailable = False;
6737         }
6738
6739         /* If a service is flagged unavailable, log the fact at level 1. */
6740         if (!ServicePtrs[iService]->bAvailable)
6741                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6742                           ServicePtrs[iService]->szService));
6743
6744         return (bRetval);
6745 }
6746
6747 static struct smbconf_ctx *lp_smbconf_ctx(void)
6748 {
6749         WERROR werr;
6750         static struct smbconf_ctx *conf_ctx = NULL;
6751
6752         if (conf_ctx == NULL) {
6753                 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6754                 if (!W_ERROR_IS_OK(werr)) {
6755                         DEBUG(1, ("error initializing registry configuration: "
6756                                   "%s\n", win_errstr(werr)));
6757                         conf_ctx = NULL;
6758                 }
6759         }
6760
6761         return conf_ctx;
6762 }
6763
6764 static bool process_smbconf_service(struct smbconf_service *service)
6765 {
6766         uint32_t count;
6767         bool ret;
6768
6769         if (service == NULL) {
6770                 return false;
6771         }
6772
6773         ret = do_section(service->name, NULL);
6774         if (ret != true) {
6775                 return false;
6776         }
6777         for (count = 0; count < service->num_params; count++) {
6778                 ret = do_parameter(service->param_names[count],
6779                                    service->param_values[count],
6780                                    NULL);
6781                 if (ret != true) {
6782                         return false;
6783                 }
6784         }
6785         return true;
6786 }
6787
6788 /*
6789  * process_registry_globals
6790  */
6791 static bool process_registry_globals(void)
6792 {
6793         WERROR werr;
6794         struct smbconf_service *service = NULL;
6795         TALLOC_CTX *mem_ctx = talloc_stackframe();
6796         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6797         bool ret = false;
6798
6799         if (conf_ctx == NULL) {
6800                 goto done;
6801         }
6802
6803         ret = do_parameter("registry shares", "yes", NULL);
6804         if (!ret) {
6805                 goto done;
6806         }
6807
6808         if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6809                 /* nothing to read from the registry yet but make sure lp_load
6810                  * doesn't return false */
6811                 ret = true;
6812                 goto done;
6813         }
6814
6815         werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6816         if (!W_ERROR_IS_OK(werr)) {
6817                 goto done;
6818         }
6819
6820         ret = process_smbconf_service(service);
6821         if (!ret) {
6822                 goto done;
6823         }
6824
6825         /* store the csn */
6826         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6827
6828 done:
6829         TALLOC_FREE(mem_ctx);
6830         return ret;
6831 }
6832
6833 static bool process_registry_shares(void)
6834 {
6835         WERROR werr;
6836         uint32_t count;
6837         struct smbconf_service **service = NULL;
6838         uint32_t num_shares = 0;
6839         TALLOC_CTX *mem_ctx = talloc_stackframe();
6840         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6841         bool ret = false;
6842
6843         if (conf_ctx == NULL) {
6844                 goto done;
6845         }
6846
6847         werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6848         if (!W_ERROR_IS_OK(werr)) {
6849                 goto done;
6850         }
6851
6852         ret = true;
6853
6854         for (count = 0; count < num_shares; count++) {
6855                 if (strequal(service[count]->name, GLOBAL_NAME)) {
6856                         continue;
6857                 }
6858                 ret = process_smbconf_service(service[count]);
6859                 if (!ret) {
6860                         goto done;
6861                 }
6862         }
6863
6864         /* store the csn */
6865         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6866
6867 done:
6868         TALLOC_FREE(mem_ctx);
6869         return ret;
6870 }
6871
6872 static struct file_lists {
6873         struct file_lists *next;
6874         char *name;
6875         char *subfname;
6876         time_t modtime;
6877 } *file_lists = NULL;
6878
6879 /*******************************************************************
6880  Keep a linked list of all config files so we know when one has changed 
6881  it's date and needs to be reloaded.
6882 ********************************************************************/
6883
6884 static void add_to_file_list(const char *fname, const char *subfname)
6885 {
6886         struct file_lists *f = file_lists;
6887
6888         while (f) {
6889                 if (f->name && !strcmp(f->name, fname))
6890                         break;
6891                 f = f->next;
6892         }
6893
6894         if (!f) {
6895                 f = SMB_MALLOC_P(struct file_lists);
6896                 if (!f)
6897                         return;
6898                 f->next = file_lists;
6899                 f->name = SMB_STRDUP(fname);
6900                 if (!f->name) {
6901                         SAFE_FREE(f);
6902                         return;
6903                 }
6904                 f->subfname = SMB_STRDUP(subfname);
6905                 if (!f->subfname) {
6906                         SAFE_FREE(f);
6907                         return;
6908                 }
6909                 file_lists = f;
6910                 f->modtime = file_modtime(subfname);
6911         } else {
6912                 time_t t = file_modtime(subfname);
6913                 if (t)
6914                         f->modtime = t;
6915         }
6916 }
6917
6918 /**
6919  * Utility function for outsiders to check if we're running on registry.
6920  */
6921 bool lp_config_backend_is_registry(void)
6922 {
6923         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6924 }
6925
6926 /**
6927  * Utility function to check if the config backend is FILE.
6928  */
6929 bool lp_config_backend_is_file(void)
6930 {
6931         return (lp_config_backend() == CONFIG_BACKEND_FILE);
6932 }
6933
6934 /*******************************************************************
6935  Check if a config file has changed date.
6936 ********************************************************************/
6937
6938 bool lp_file_list_changed(void)
6939 {
6940         struct file_lists *f = file_lists;
6941
6942         DEBUG(6, ("lp_file_list_changed()\n"));
6943
6944         if (lp_config_backend_is_registry()) {
6945                 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6946
6947                 if (conf_ctx == NULL) {
6948                         return false;
6949                 }
6950                 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6951                         DEBUGADD(6, ("registry config changed\n"));
6952                         return true;
6953                 }
6954         }
6955
6956         while (f) {
6957                 char *n2 = NULL;
6958                 time_t mod_time;
6959
6960                 n2 = alloc_sub_basic(get_current_username(),
6961                                     current_user_info.domain,
6962                                     f->name);
6963                 if (!n2) {
6964                         return false;
6965                 }
6966                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
6967                              f->name, n2, ctime(&f->modtime)));
6968
6969                 mod_time = file_modtime(n2);
6970
6971                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6972                         DEBUGADD(6,
6973                                  ("file %s modified: %s\n", n2,
6974                                   ctime(&mod_time)));
6975                         f->modtime = mod_time;
6976                         SAFE_FREE(f->subfname);
6977                         f->subfname = n2; /* Passing ownership of
6978                                              return from alloc_sub_basic
6979                                              above. */
6980                         return true;
6981                 }
6982                 SAFE_FREE(n2);
6983                 f = f->next;
6984         }
6985         return (False);
6986 }
6987
6988
6989 /***************************************************************************
6990  Run standard_sub_basic on netbios name... needed because global_myname
6991  is not accessed through any lp_ macro.
6992  Note: We must *NOT* use string_set() here as ptr points to global_myname.
6993 ***************************************************************************/
6994
6995 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6996 {
6997         bool ret;
6998         char *netbios_name = alloc_sub_basic(get_current_username(),
6999                                         current_user_info.domain,
7000                                         pszParmValue);
7001
7002         ret = set_global_myname(netbios_name);
7003         SAFE_FREE(netbios_name);
7004         string_set(&Globals.szNetbiosName,global_myname());
7005
7006         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7007                global_myname()));
7008
7009         return ret;
7010 }
7011
7012 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7013 {
7014         if (strcmp(*ptr, pszParmValue) != 0) {
7015                 string_set(ptr, pszParmValue);
7016                 init_iconv();
7017         }
7018         return True;
7019 }
7020
7021
7022
7023 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7024 {
7025         bool ret;
7026         
7027         ret = set_global_myworkgroup(pszParmValue);
7028         string_set(&Globals.szWorkgroup,lp_workgroup());
7029         
7030         return ret;
7031 }
7032
7033 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7034 {
7035         bool ret;
7036         
7037         ret = set_global_scope(pszParmValue);
7038         string_set(&Globals.szNetbiosScope,global_scope());
7039
7040         return ret;
7041 }
7042
7043 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7044 {
7045         TALLOC_FREE(Globals.szNetbiosAliases);
7046         Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7047         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7048 }
7049
7050 /***************************************************************************
7051  Handle the include operation.
7052 ***************************************************************************/
7053 static bool bAllowIncludeRegistry = true;
7054
7055 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7056 {
7057         char *fname;
7058
7059         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7060                 if (!bAllowIncludeRegistry) {
7061                         return true;
7062                 }
7063                 if (bInGlobalSection) {
7064                         return process_registry_globals();
7065                 } else {
7066                         DEBUG(1, ("\"include = registry\" only effective "
7067                                   "in %s section\n", GLOBAL_NAME));
7068                         return false;
7069                 }
7070         }
7071
7072         fname = alloc_sub_basic(get_current_username(),
7073                                 current_user_info.domain,
7074                                 pszParmValue);
7075
7076         add_to_file_list(pszParmValue, fname);
7077
7078         string_set(ptr, fname);
7079
7080         if (file_exist(fname)) {
7081                 bool ret = pm_process(fname, do_section, do_parameter, NULL);
7082                 SAFE_FREE(fname);
7083                 return ret;
7084         }
7085
7086         DEBUG(2, ("Can't find include file %s\n", fname));
7087         SAFE_FREE(fname);
7088         return true;
7089 }
7090
7091 /***************************************************************************
7092  Handle the interpretation of the copy parameter.
7093 ***************************************************************************/
7094
7095 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7096 {
7097         bool bRetval;
7098         int iTemp;
7099         struct service serviceTemp;
7100
7101         string_set(ptr, pszParmValue);
7102
7103         init_service(&serviceTemp);
7104
7105         bRetval = False;
7106
7107         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7108
7109         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7110                 if (iTemp == iServiceIndex) {
7111                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7112                 } else {
7113                         copy_service(ServicePtrs[iServiceIndex],
7114                                      &serviceTemp,
7115                                      ServicePtrs[iServiceIndex]->copymap);
7116                         bRetval = True;
7117                 }
7118         } else {
7119                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7120                 bRetval = False;
7121         }
7122
7123         free_service(&serviceTemp);
7124         return (bRetval);
7125 }
7126
7127 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7128 {
7129         Globals.ldap_debug_level = lp_int(pszParmValue);
7130         init_ldap_debugging();
7131         return true;
7132 }
7133
7134 /***************************************************************************
7135  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
7136  parameters is:
7137
7138  [global]
7139
7140         idmap uid = 1000-1999
7141         idmap gid = 700-899
7142
7143  We only do simple parsing checks here.  The strings are parsed into useful
7144  structures in the idmap daemon code.
7145
7146 ***************************************************************************/
7147
7148 /* Some lp_ routines to return idmap [ug]id information */
7149
7150 static uid_t idmap_uid_low, idmap_uid_high;
7151 static gid_t idmap_gid_low, idmap_gid_high;
7152
7153 bool lp_idmap_uid(uid_t *low, uid_t *high)
7154 {
7155         if (idmap_uid_low == 0 || idmap_uid_high == 0)
7156                 return False;
7157
7158         if (low)
7159                 *low = idmap_uid_low;
7160
7161         if (high)
7162                 *high = idmap_uid_high;
7163
7164         return True;
7165 }
7166
7167 bool lp_idmap_gid(gid_t *low, gid_t *high)
7168 {
7169         if (idmap_gid_low == 0 || idmap_gid_high == 0)
7170                 return False;
7171
7172         if (low)
7173                 *low = idmap_gid_low;
7174
7175         if (high)
7176                 *high = idmap_gid_high;
7177
7178         return True;
7179 }
7180
7181 /* Do some simple checks on "idmap [ug]id" parameter values */
7182
7183 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7184 {
7185         uint32 low, high;
7186
7187         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7188                 return False;
7189
7190         /* Parse OK */
7191
7192         string_set(ptr, pszParmValue);
7193
7194         idmap_uid_low = low;
7195         idmap_uid_high = high;
7196
7197         return True;
7198 }
7199
7200 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7201 {
7202         uint32 low, high;
7203
7204         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7205                 return False;
7206
7207         /* Parse OK */
7208
7209         string_set(ptr, pszParmValue);
7210
7211         idmap_gid_low = low;
7212         idmap_gid_high = high;
7213
7214         return True;
7215 }
7216
7217 /***************************************************************************
7218  Handle the DEBUG level list.
7219 ***************************************************************************/
7220
7221 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7222 {
7223         string_set(ptr, pszParmValueIn);
7224         return debug_parse_levels(pszParmValueIn);
7225 }
7226
7227 /***************************************************************************
7228  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7229 ***************************************************************************/
7230
7231 static const char *append_ldap_suffix( const char *str )
7232 {
7233         const char *suffix_string;
7234
7235
7236         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7237                                         Globals.szLdapSuffix );
7238         if ( !suffix_string ) {
7239                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7240                 return "";
7241         }
7242
7243         return suffix_string;
7244 }
7245
7246 const char *lp_ldap_machine_suffix(void)
7247 {
7248         if (Globals.szLdapMachineSuffix[0])
7249                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7250
7251         return lp_string(Globals.szLdapSuffix);
7252 }
7253
7254 const char *lp_ldap_user_suffix(void)
7255 {
7256         if (Globals.szLdapUserSuffix[0])
7257                 return append_ldap_suffix(Globals.szLdapUserSuffix);
7258
7259         return lp_string(Globals.szLdapSuffix);
7260 }
7261
7262 const char *lp_ldap_group_suffix(void)
7263 {
7264         if (Globals.szLdapGroupSuffix[0])
7265                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7266
7267         return lp_string(Globals.szLdapSuffix);
7268 }
7269
7270 const char *lp_ldap_idmap_suffix(void)
7271 {
7272         if (Globals.szLdapIdmapSuffix[0])
7273                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7274
7275         return lp_string(Globals.szLdapSuffix);
7276 }
7277
7278 /****************************************************************************
7279  set the value for a P_ENUM
7280  ***************************************************************************/
7281
7282 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7283                               int *ptr )
7284 {
7285         int i;
7286
7287         for (i = 0; parm->enum_list[i].name; i++) {
7288                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7289                         *ptr = parm->enum_list[i].value;
7290                         return;
7291                 }
7292         }
7293         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7294                   pszParmValue, parm->label));
7295 }
7296
7297 /***************************************************************************
7298 ***************************************************************************/
7299
7300 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7301 {
7302         static int parm_num = -1;
7303         struct service *s;
7304
7305         if ( parm_num == -1 )
7306                 parm_num = map_parameter( "printing" );
7307
7308         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7309
7310         if ( snum < 0 )
7311                 s = &sDefault;
7312         else
7313                 s = ServicePtrs[snum];
7314
7315         init_printer_values( s );
7316
7317         return True;
7318 }
7319
7320
7321 /***************************************************************************
7322  Initialise a copymap.
7323 ***************************************************************************/
7324
7325 static void init_copymap(struct service *pservice)
7326 {
7327         int i;
7328         if (pservice->copymap) {
7329                 bitmap_free(pservice->copymap);
7330         }
7331         pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7332         if (!pservice->copymap)
7333                 DEBUG(0,
7334                       ("Couldn't allocate copymap!! (size %d)\n",
7335                        (int)NUMPARAMETERS));
7336         else
7337                 for (i = 0; i < NUMPARAMETERS; i++)
7338                         bitmap_set(pservice->copymap, i);
7339 }
7340
7341 /***************************************************************************
7342  Return the local pointer to a parameter given a service struct and the
7343  pointer into the default structure.
7344 ***************************************************************************/
7345
7346 static void *lp_local_ptr(struct service *service, void *ptr)
7347 {
7348         return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7349 }
7350
7351 /***************************************************************************
7352  Return the local pointer to a parameter given the service number and the 
7353  pointer into the default structure.
7354 ***************************************************************************/
7355
7356 void *lp_local_ptr_by_snum(int snum, void *ptr)
7357 {
7358         return lp_local_ptr(ServicePtrs[snum], ptr);
7359 }
7360
7361 /***************************************************************************
7362  Process a parameter for a particular service number. If snum < 0
7363  then assume we are in the globals.
7364 ***************************************************************************/
7365
7366 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7367 {
7368         int parmnum, i;
7369         void *parm_ptr = NULL;  /* where we are going to store the result */
7370         void *def_ptr = NULL;
7371         struct param_opt_struct **opt_list;
7372
7373         parmnum = map_parameter(pszParmName);
7374
7375         if (parmnum < 0) {
7376                 if (strchr(pszParmName, ':') == NULL) {
7377                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7378                                   pszParmName));
7379                         return (True);
7380                 }
7381
7382                 /*
7383                  * We've got a parametric option
7384                  */
7385
7386                 opt_list = (snum < 0)
7387                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7388                 set_param_opt(opt_list, pszParmName, pszParmValue);
7389
7390                 return (True);
7391         }
7392
7393         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7394                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7395                           pszParmName));
7396         }
7397
7398         def_ptr = parm_table[parmnum].ptr;
7399
7400         /* we might point at a service, the default service or a global */
7401         if (snum < 0) {
7402                 parm_ptr = def_ptr;
7403         } else {
7404                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7405                         DEBUG(0,
7406                               ("Global parameter %s found in service section!\n",
7407                                pszParmName));
7408                         return (True);
7409                 }
7410                 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7411         }
7412
7413         if (snum >= 0) {
7414                 if (!ServicePtrs[snum]->copymap)
7415                         init_copymap(ServicePtrs[snum]);
7416
7417                 /* this handles the aliases - set the copymap for other entries with
7418                    the same data pointer */
7419                 for (i = 0; parm_table[i].label; i++)
7420                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7421                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7422         }
7423
7424         /* if it is a special case then go ahead */
7425         if (parm_table[parmnum].special) {
7426                 return parm_table[parmnum].special(snum, pszParmValue,
7427                                                    (char **)parm_ptr);
7428         }
7429
7430         /* now switch on the type of variable it is */
7431         switch (parm_table[parmnum].type)
7432         {
7433                 case P_BOOL:
7434                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7435                         break;
7436
7437                 case P_BOOLREV:
7438                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7439                         break;
7440
7441                 case P_INTEGER:
7442                         *(int *)parm_ptr = lp_int(pszParmValue);
7443                         break;
7444
7445                 case P_CHAR:
7446                         *(char *)parm_ptr = *pszParmValue;
7447                         break;
7448
7449                 case P_OCTAL:
7450                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7451                         if ( i != 1 ) {
7452                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7453                         }
7454                         break;
7455
7456                 case P_LIST:
7457                         TALLOC_FREE(*((char ***)parm_ptr));
7458                         *(char ***)parm_ptr = str_list_make_v3(
7459                                 talloc_autofree_context(), pszParmValue, NULL);
7460                         break;
7461
7462                 case P_STRING:
7463                         string_set((char **)parm_ptr, pszParmValue);
7464                         break;
7465
7466                 case P_USTRING:
7467                         string_set((char **)parm_ptr, pszParmValue);
7468                         strupper_m(*(char **)parm_ptr);
7469                         break;
7470
7471                 case P_ENUM:
7472                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7473                         break;
7474                 case P_SEP:
7475                         break;
7476         }
7477
7478         return (True);
7479 }
7480
7481 /***************************************************************************
7482  Process a parameter.
7483 ***************************************************************************/
7484
7485 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7486                          void *userdata)
7487 {
7488         if (!bInGlobalSection && bGlobalOnly)
7489                 return (True);
7490
7491         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7492
7493         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7494                                 pszParmName, pszParmValue));
7495 }
7496
7497 /***************************************************************************
7498  Print a parameter of the specified type.
7499 ***************************************************************************/
7500
7501 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7502 {
7503         int i;
7504         switch (p->type)
7505         {
7506                 case P_ENUM:
7507                         for (i = 0; p->enum_list[i].name; i++) {
7508                                 if (*(int *)ptr == p->enum_list[i].value) {
7509                                         fprintf(f, "%s",
7510                                                 p->enum_list[i].name);
7511                                         break;
7512                                 }
7513                         }
7514                         break;
7515
7516                 case P_BOOL:
7517                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7518                         break;
7519
7520                 case P_BOOLREV:
7521                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7522                         break;
7523
7524                 case P_INTEGER:
7525                         fprintf(f, "%d", *(int *)ptr);
7526                         break;
7527
7528                 case P_CHAR:
7529                         fprintf(f, "%c", *(char *)ptr);
7530                         break;
7531
7532                 case P_OCTAL: {
7533                         char *o = octal_string(*(int *)ptr);
7534                         fprintf(f, "%s", o);
7535                         TALLOC_FREE(o);
7536                         break;
7537                 }
7538
7539                 case P_LIST:
7540                         if ((char ***)ptr && *(char ***)ptr) {
7541                                 char **list = *(char ***)ptr;
7542                                 for (; *list; list++) {
7543                                         /* surround strings with whitespace in double quotes */
7544                                         if ( strchr_m( *list, ' ' ) )
7545                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7546                                         else
7547                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7548                                 }
7549                         }
7550                         break;
7551
7552                 case P_STRING:
7553                 case P_USTRING:
7554                         if (*(char **)ptr) {
7555                                 fprintf(f, "%s", *(char **)ptr);
7556                         }
7557                         break;
7558                 case P_SEP:
7559                         break;
7560         }
7561 }
7562
7563 /***************************************************************************
7564  Check if two parameters are equal.
7565 ***************************************************************************/
7566
7567 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7568 {
7569         switch (type) {
7570                 case P_BOOL:
7571                 case P_BOOLREV:
7572                         return (*((bool *)ptr1) == *((bool *)ptr2));
7573
7574                 case P_INTEGER:
7575                 case P_ENUM:
7576                 case P_OCTAL:
7577                         return (*((int *)ptr1) == *((int *)ptr2));
7578
7579                 case P_CHAR:
7580                         return (*((char *)ptr1) == *((char *)ptr2));
7581
7582                 case P_LIST:
7583                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7584
7585                 case P_STRING:
7586                 case P_USTRING:
7587                 {
7588                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7589                         if (p1 && !*p1)
7590                                 p1 = NULL;
7591                         if (p2 && !*p2)
7592                                 p2 = NULL;
7593                         return (p1 == p2 || strequal(p1, p2));
7594                 }
7595                 case P_SEP:
7596                         break;
7597         }
7598         return (False);
7599 }
7600
7601 /***************************************************************************
7602  Initialize any local varients in the sDefault table.
7603 ***************************************************************************/
7604
7605 void init_locals(void)
7606 {
7607         /* None as yet. */
7608 }
7609
7610 /***************************************************************************
7611  Process a new section (service). At this stage all sections are services.
7612  Later we'll have special sections that permit server parameters to be set.
7613  Returns True on success, False on failure. 
7614 ***************************************************************************/
7615
7616 static bool do_section(const char *pszSectionName, void *userdata)
7617 {
7618         bool bRetval;
7619         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7620                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7621         bRetval = False;
7622
7623         /* if we were in a global section then do the local inits */
7624         if (bInGlobalSection && !isglobal)
7625                 init_locals();
7626
7627         /* if we've just struck a global section, note the fact. */
7628         bInGlobalSection = isglobal;
7629
7630         /* check for multiple global sections */
7631         if (bInGlobalSection) {
7632                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7633                 return (True);
7634         }
7635
7636         if (!bInGlobalSection && bGlobalOnly)
7637                 return (True);
7638
7639         /* if we have a current service, tidy it up before moving on */
7640         bRetval = True;
7641
7642         if (iServiceIndex >= 0)
7643                 bRetval = service_ok(iServiceIndex);
7644
7645         /* if all is still well, move to the next record in the services array */
7646         if (bRetval) {
7647                 /* We put this here to avoid an odd message order if messages are */
7648                 /* issued by the post-processing of a previous section. */
7649                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7650
7651                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7652                     < 0) {
7653                         DEBUG(0, ("Failed to add a new service\n"));
7654                         return (False);
7655                 }
7656         }
7657
7658         return (bRetval);
7659 }
7660
7661
7662 /***************************************************************************
7663  Determine if a partcular base parameter is currentl set to the default value.
7664 ***************************************************************************/
7665
7666 static bool is_default(int i)
7667 {
7668         if (!defaults_saved)
7669                 return False;
7670         switch (parm_table[i].type) {
7671                 case P_LIST:
7672                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
7673                                                 *(const char ***)parm_table[i].ptr);
7674                 case P_STRING:
7675                 case P_USTRING:
7676                         return strequal(parm_table[i].def.svalue,
7677                                         *(char **)parm_table[i].ptr);
7678                 case P_BOOL:
7679                 case P_BOOLREV:
7680                         return parm_table[i].def.bvalue ==
7681                                 *(bool *)parm_table[i].ptr;
7682                 case P_CHAR:
7683                         return parm_table[i].def.cvalue ==
7684                                 *(char *)parm_table[i].ptr;
7685                 case P_INTEGER:
7686                 case P_OCTAL:
7687                 case P_ENUM:
7688                         return parm_table[i].def.ivalue ==
7689                                 *(int *)parm_table[i].ptr;
7690                 case P_SEP:
7691                         break;
7692         }
7693         return False;
7694 }
7695
7696 /***************************************************************************
7697 Display the contents of the global structure.
7698 ***************************************************************************/
7699
7700 static void dump_globals(FILE *f)
7701 {
7702         int i;
7703         struct param_opt_struct *data;
7704         
7705         fprintf(f, "[global]\n");
7706
7707         for (i = 0; parm_table[i].label; i++)
7708                 if (parm_table[i].p_class == P_GLOBAL &&
7709                     parm_table[i].ptr &&
7710                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7711                         if (defaults_saved && is_default(i))
7712                                 continue;
7713                         fprintf(f, "\t%s = ", parm_table[i].label);
7714                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
7715                         fprintf(f, "\n");
7716         }
7717         if (Globals.param_opt != NULL) {
7718                 data = Globals.param_opt;
7719                 while(data) {
7720                         fprintf(f, "\t%s = %s\n", data->key, data->value);
7721                         data = data->next;
7722                 }
7723         }
7724
7725 }
7726
7727 /***************************************************************************
7728  Return True if a local parameter is currently set to the global default.
7729 ***************************************************************************/
7730
7731 bool lp_is_default(int snum, struct parm_struct *parm)
7732 {
7733         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7734
7735         return equal_parameter(parm->type,
7736                                ((char *)ServicePtrs[snum]) + pdiff,
7737                                ((char *)&sDefault) + pdiff);
7738 }
7739
7740 /***************************************************************************
7741  Display the contents of a single services record.
7742 ***************************************************************************/
7743
7744 static void dump_a_service(struct service *pService, FILE * f)
7745 {
7746         int i;
7747         struct param_opt_struct *data;
7748         
7749         if (pService != &sDefault)
7750                 fprintf(f, "[%s]\n", pService->szService);
7751
7752         for (i = 0; parm_table[i].label; i++) {
7753
7754                 if (parm_table[i].p_class == P_LOCAL &&
7755                     parm_table[i].ptr &&
7756                     (*parm_table[i].label != '-') &&
7757                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7758                 {
7759                 
7760                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7761
7762                         if (pService == &sDefault) {
7763                                 if (defaults_saved && is_default(i))
7764                                         continue;
7765                         } else {
7766                                 if (equal_parameter(parm_table[i].type,
7767                                                     ((char *)pService) +
7768                                                     pdiff,
7769                                                     ((char *)&sDefault) +
7770                                                     pdiff))
7771                                         continue;
7772                         }
7773
7774                         fprintf(f, "\t%s = ", parm_table[i].label);
7775                         print_parameter(&parm_table[i],
7776                                         ((char *)pService) + pdiff, f);
7777                         fprintf(f, "\n");
7778                 }
7779         }
7780
7781                 if (pService->param_opt != NULL) {
7782                         data = pService->param_opt;
7783                         while(data) {
7784                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
7785                                 data = data->next;
7786                         }
7787                 }
7788 }
7789
7790 /***************************************************************************
7791  Display the contents of a parameter of a single services record.
7792 ***************************************************************************/
7793
7794 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7795 {
7796         int i;
7797         bool result = False;
7798         parm_class p_class;
7799         unsigned flag = 0;
7800         fstring local_parm_name;
7801         char *parm_opt;
7802         const char *parm_opt_value;
7803
7804         /* check for parametrical option */
7805         fstrcpy( local_parm_name, parm_name);
7806         parm_opt = strchr( local_parm_name, ':');
7807
7808         if (parm_opt) {
7809                 *parm_opt = '\0';
7810                 parm_opt++;
7811                 if (strlen(parm_opt)) {
7812                         parm_opt_value = lp_parm_const_string( snum,
7813                                 local_parm_name, parm_opt, NULL);
7814                         if (parm_opt_value) {
7815                                 printf( "%s\n", parm_opt_value);
7816                                 result = True;
7817                         }
7818                 }
7819                 return result;
7820         }
7821
7822         /* check for a key and print the value */
7823         if (isGlobal) {
7824                 p_class = P_GLOBAL;
7825                 flag = FLAG_GLOBAL;
7826         } else
7827                 p_class = P_LOCAL;
7828
7829         for (i = 0; parm_table[i].label; i++) {
7830                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7831                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7832                     parm_table[i].ptr &&
7833                     (*parm_table[i].label != '-') &&
7834                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7835                 {
7836                         void *ptr;
7837
7838                         if (isGlobal) {
7839                                 ptr = parm_table[i].ptr;
7840                         } else {
7841                                 struct service *pService = ServicePtrs[snum];
7842                                 ptr = ((char *)pService) +
7843                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
7844                         }
7845
7846                         print_parameter(&parm_table[i],
7847                                         ptr, f);
7848                         fprintf(f, "\n");
7849                         result = True;
7850                         break;
7851                 }
7852         }
7853
7854         return result;
7855 }
7856
7857 /***************************************************************************
7858  Return info about the requested parameter (given as a string).
7859  Return NULL when the string is not a valid parameter name.
7860 ***************************************************************************/
7861
7862 struct parm_struct *lp_get_parameter(const char *param_name)
7863 {
7864         int num = map_parameter(param_name);
7865
7866         if (num < 0) {
7867                 return NULL;
7868         }
7869
7870         return &parm_table[num];
7871 }
7872
7873 /***************************************************************************
7874  Return info about the next parameter in a service.
7875  snum==GLOBAL_SECTION_SNUM gives the globals.
7876  Return NULL when out of parameters.
7877 ***************************************************************************/
7878
7879 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7880 {
7881         if (snum < 0) {
7882                 /* do the globals */
7883                 for (; parm_table[*i].label; (*i)++) {
7884                         if (parm_table[*i].p_class == P_SEPARATOR)
7885                                 return &parm_table[(*i)++];
7886
7887                         if (!parm_table[*i].ptr
7888                             || (*parm_table[*i].label == '-'))
7889                                 continue;
7890
7891                         if ((*i) > 0
7892                             && (parm_table[*i].ptr ==
7893                                 parm_table[(*i) - 1].ptr))
7894                                 continue;
7895                         
7896                         if (is_default(*i) && !allparameters)
7897                                 continue;
7898
7899                         return &parm_table[(*i)++];
7900                 }
7901         } else {
7902                 struct service *pService = ServicePtrs[snum];
7903
7904                 for (; parm_table[*i].label; (*i)++) {
7905                         if (parm_table[*i].p_class == P_SEPARATOR)
7906                                 return &parm_table[(*i)++];
7907
7908                         if (parm_table[*i].p_class == P_LOCAL &&
7909                             parm_table[*i].ptr &&
7910                             (*parm_table[*i].label != '-') &&
7911                             ((*i) == 0 ||
7912                              (parm_table[*i].ptr !=
7913                               parm_table[(*i) - 1].ptr)))
7914                         {
7915                                 int pdiff =
7916                                         PTR_DIFF(parm_table[*i].ptr,
7917                                                  &sDefault);
7918
7919                                 if (allparameters ||
7920                                     !equal_parameter(parm_table[*i].type,
7921                                                      ((char *)pService) +
7922                                                      pdiff,
7923                                                      ((char *)&sDefault) +
7924                                                      pdiff))
7925                                 {
7926                                         return &parm_table[(*i)++];
7927                                 }
7928                         }
7929                 }
7930         }
7931
7932         return NULL;
7933 }
7934
7935
7936 #if 0
7937 /***************************************************************************
7938  Display the contents of a single copy structure.
7939 ***************************************************************************/
7940 static void dump_copy_map(bool *pcopymap)
7941 {
7942         int i;
7943         if (!pcopymap)
7944                 return;
7945
7946         printf("\n\tNon-Copied parameters:\n");
7947
7948         for (i = 0; parm_table[i].label; i++)
7949                 if (parm_table[i].p_class == P_LOCAL &&
7950                     parm_table[i].ptr && !pcopymap[i] &&
7951                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7952                 {
7953                         printf("\t\t%s\n", parm_table[i].label);
7954                 }
7955 }
7956 #endif
7957
7958 /***************************************************************************
7959  Return TRUE if the passed service number is within range.
7960 ***************************************************************************/
7961
7962 bool lp_snum_ok(int iService)
7963 {
7964         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7965 }
7966
7967 /***************************************************************************
7968  Auto-load some home services.
7969 ***************************************************************************/
7970
7971 static void lp_add_auto_services(char *str)
7972 {
7973         char *s;
7974         char *p;
7975         int homes;
7976         char *saveptr;
7977
7978         if (!str)
7979                 return;
7980
7981         s = SMB_STRDUP(str);
7982         if (!s)
7983                 return;
7984
7985         homes = lp_servicenumber(HOMES_NAME);
7986
7987         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7988              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7989                 char *home;
7990
7991                 if (lp_servicenumber(p) >= 0)
7992                         continue;
7993
7994                 home = get_user_home_dir(talloc_tos(), p);
7995
7996                 if (home && homes >= 0)
7997                         lp_add_home(p, homes, p, home);
7998
7999                 TALLOC_FREE(home);
8000         }
8001         SAFE_FREE(s);
8002 }
8003
8004 /***************************************************************************
8005  Auto-load one printer.
8006 ***************************************************************************/
8007
8008 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8009 {
8010         int printers = lp_servicenumber(PRINTERS_NAME);
8011         int i;
8012
8013         if (lp_servicenumber(name) < 0) {
8014                 lp_add_printer(name, printers);
8015                 if ((i = lp_servicenumber(name)) >= 0) {
8016                         string_set(&ServicePtrs[i]->comment, comment);
8017                         ServicePtrs[i]->autoloaded = True;
8018                 }
8019         }
8020 }
8021
8022 /***************************************************************************
8023  Have we loaded a services file yet?
8024 ***************************************************************************/
8025
8026 bool lp_loaded(void)
8027 {
8028         return (bLoaded);
8029 }
8030
8031 /***************************************************************************
8032  Unload unused services.
8033 ***************************************************************************/
8034
8035 void lp_killunused(bool (*snumused) (int))
8036 {
8037         int i;
8038         for (i = 0; i < iNumServices; i++) {
8039                 if (!VALID(i))
8040                         continue;
8041
8042                 /* don't kill autoloaded or usershare services */
8043                 if ( ServicePtrs[i]->autoloaded ||
8044                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8045                         continue;
8046                 }
8047
8048                 if (!snumused || !snumused(i)) {
8049                         free_service_byindex(i);
8050                 }
8051         }
8052 }
8053
8054 /**
8055  * Kill all except autoloaded and usershare services - convenience wrapper
8056  */
8057 void lp_kill_all_services(void)
8058 {
8059         lp_killunused(NULL);
8060 }
8061
8062 /***************************************************************************
8063  Unload a service.
8064 ***************************************************************************/
8065
8066 void lp_killservice(int iServiceIn)
8067 {
8068         if (VALID(iServiceIn)) {
8069                 free_service_byindex(iServiceIn);
8070         }
8071 }
8072
8073 /***************************************************************************
8074  Save the curent values of all global and sDefault parameters into the 
8075  defaults union. This allows swat and testparm to show only the
8076  changed (ie. non-default) parameters.
8077 ***************************************************************************/
8078
8079 static void lp_save_defaults(void)
8080 {
8081         int i;
8082         for (i = 0; parm_table[i].label; i++) {
8083                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8084                         continue;
8085                 switch (parm_table[i].type) {
8086                         case P_LIST:
8087                                 parm_table[i].def.lvalue = str_list_copy(
8088                                         NULL, *(const char ***)parm_table[i].ptr);
8089                                 break;
8090                         case P_STRING:
8091                         case P_USTRING:
8092                                 if (parm_table[i].ptr) {
8093                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8094                                 } else {
8095                                         parm_table[i].def.svalue = NULL;
8096                                 }
8097                                 break;
8098                         case P_BOOL:
8099                         case P_BOOLREV:
8100                                 parm_table[i].def.bvalue =
8101                                         *(bool *)parm_table[i].ptr;
8102                                 break;
8103                         case P_CHAR:
8104                                 parm_table[i].def.cvalue =
8105                                         *(char *)parm_table[i].ptr;
8106                                 break;
8107                         case P_INTEGER:
8108                         case P_OCTAL:
8109                         case P_ENUM:
8110                                 parm_table[i].def.ivalue =
8111                                         *(int *)parm_table[i].ptr;
8112                                 break;
8113                         case P_SEP:
8114                                 break;
8115                 }
8116         }
8117         defaults_saved = True;
8118 }
8119
8120 /*******************************************************************
8121  Set the server type we will announce as via nmbd.
8122 ********************************************************************/
8123
8124 static const struct srv_role_tab {
8125         uint32 role;
8126         const char *role_str;
8127 } srv_role_tab [] = {
8128         { ROLE_STANDALONE, "ROLE_STANDALONE" },
8129         { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8130         { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8131         { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8132         { 0, NULL }
8133 };
8134
8135 const char* server_role_str(uint32 role)
8136 {
8137         int i = 0;
8138         for (i=0; srv_role_tab[i].role_str; i++) {
8139                 if (role == srv_role_tab[i].role) {
8140                         return srv_role_tab[i].role_str;
8141                 }
8142         }
8143         return NULL;
8144 }
8145
8146 static void set_server_role(void)
8147 {
8148         server_role = ROLE_STANDALONE;
8149
8150         switch (lp_security()) {
8151                 case SEC_SHARE:
8152                         if (lp_domain_logons())
8153                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8154                         break;
8155                 case SEC_SERVER:
8156                         if (lp_domain_logons())
8157                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8158                         /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8159                         server_role = ROLE_STANDALONE;
8160                         break;
8161                 case SEC_DOMAIN:
8162                         if (lp_domain_logons()) {
8163                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8164                                 server_role = ROLE_DOMAIN_BDC;
8165                                 break;
8166                         }
8167                         server_role = ROLE_DOMAIN_MEMBER;
8168                         break;
8169                 case SEC_ADS:
8170                         if (lp_domain_logons()) {
8171                                 server_role = ROLE_DOMAIN_PDC;
8172                                 break;
8173                         }
8174                         server_role = ROLE_DOMAIN_MEMBER;
8175                         break;
8176                 case SEC_USER:
8177                         if (lp_domain_logons()) {
8178
8179                                 if (Globals.iDomainMaster) /* auto or yes */ 
8180                                         server_role = ROLE_DOMAIN_PDC;
8181                                 else
8182                                         server_role = ROLE_DOMAIN_BDC;
8183                         }
8184                         break;
8185                 default:
8186                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8187                         break;
8188         }
8189
8190         DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8191 }
8192
8193 /***********************************************************
8194  If we should send plaintext/LANMAN passwords in the clinet
8195 ************************************************************/
8196
8197 static void set_allowed_client_auth(void)
8198 {
8199         if (Globals.bClientNTLMv2Auth) {
8200                 Globals.bClientLanManAuth = False;
8201         }
8202         if (!Globals.bClientLanManAuth) {
8203                 Globals.bClientPlaintextAuth = False;
8204         }
8205 }
8206
8207 /***************************************************************************
8208  JRA.
8209  The following code allows smbd to read a user defined share file.
8210  Yes, this is my intent. Yes, I'm comfortable with that...
8211
8212  THE FOLLOWING IS SECURITY CRITICAL CODE.
8213
8214  It washes your clothes, it cleans your house, it guards you while you sleep...
8215  Do not f%^k with it....
8216 ***************************************************************************/
8217
8218 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8219
8220 /***************************************************************************
8221  Check allowed stat state of a usershare file.
8222  Ensure we print out who is dicking with us so the admin can
8223  get their sorry ass fired.
8224 ***************************************************************************/
8225
8226 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8227 {
8228         if (!S_ISREG(psbuf->st_mode)) {
8229                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8230                         "not a regular file\n",
8231                         fname, (unsigned int)psbuf->st_uid ));
8232                 return False;
8233         }
8234
8235         /* Ensure this doesn't have the other write bit set. */
8236         if (psbuf->st_mode & S_IWOTH) {
8237                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8238                         "public write. Refusing to allow as a usershare file.\n",
8239                         fname, (unsigned int)psbuf->st_uid ));
8240                 return False;
8241         }
8242
8243         /* Should be 10k or less. */
8244         if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8245                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8246                         "too large (%u) to be a user share file.\n",
8247                         fname, (unsigned int)psbuf->st_uid,
8248                         (unsigned int)psbuf->st_size ));
8249                 return False;
8250         }
8251
8252         return True;
8253 }
8254
8255 /***************************************************************************
8256  Parse the contents of a usershare file.
8257 ***************************************************************************/
8258
8259 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8260                         SMB_STRUCT_STAT *psbuf,
8261                         const char *servicename,
8262                         int snum,
8263                         char **lines,
8264                         int numlines,
8265                         char **pp_sharepath,
8266                         char **pp_comment,
8267                         SEC_DESC **ppsd,
8268                         bool *pallow_guest)
8269 {
8270         const char **prefixallowlist = lp_usershare_prefix_allow_list();
8271         const char **prefixdenylist = lp_usershare_prefix_deny_list();
8272         int us_vers;
8273         SMB_STRUCT_DIR *dp;
8274         SMB_STRUCT_STAT sbuf;
8275         char *sharepath = NULL;
8276         char *comment = NULL;
8277
8278         *pp_sharepath = NULL;
8279         *pp_comment = NULL;
8280
8281         *pallow_guest = False;
8282
8283         if (numlines < 4) {
8284                 return USERSHARE_MALFORMED_FILE;
8285         }
8286
8287         if (strcmp(lines[0], "#VERSION 1") == 0) {
8288                 us_vers = 1;
8289         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8290                 us_vers = 2;
8291                 if (numlines < 5) {
8292                         return USERSHARE_MALFORMED_FILE;
8293                 }
8294         } else {
8295                 return USERSHARE_BAD_VERSION;
8296         }
8297
8298         if (strncmp(lines[1], "path=", 5) != 0) {
8299                 return USERSHARE_MALFORMED_PATH;
8300         }
8301
8302         sharepath = talloc_strdup(ctx, &lines[1][5]);
8303         if (!sharepath) {
8304                 return USERSHARE_POSIX_ERR;
8305         }
8306         trim_string(sharepath, " ", " ");
8307
8308         if (strncmp(lines[2], "comment=", 8) != 0) {
8309                 return USERSHARE_MALFORMED_COMMENT_DEF;
8310         }
8311
8312         comment = talloc_strdup(ctx, &lines[2][8]);
8313         if (!comment) {
8314                 return USERSHARE_POSIX_ERR;
8315         }
8316         trim_string(comment, " ", " ");
8317         trim_char(comment, '"', '"');
8318
8319         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8320                 return USERSHARE_MALFORMED_ACL_DEF;
8321         }
8322
8323         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8324                 return USERSHARE_ACL_ERR;
8325         }
8326
8327         if (us_vers == 2) {
8328                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8329                         return USERSHARE_MALFORMED_ACL_DEF;
8330                 }
8331                 if (lines[4][9] == 'y') {
8332                         *pallow_guest = True;
8333                 }
8334         }
8335
8336         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8337                 /* Path didn't change, no checks needed. */
8338                 *pp_sharepath = sharepath;
8339                 *pp_comment = comment;
8340                 return USERSHARE_OK;
8341         }
8342
8343         /* The path *must* be absolute. */
8344         if (sharepath[0] != '/') {
8345                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8346                         servicename, sharepath));
8347                 return USERSHARE_PATH_NOT_ABSOLUTE;
8348         }
8349
8350         /* If there is a usershare prefix deny list ensure one of these paths
8351            doesn't match the start of the user given path. */
8352         if (prefixdenylist) {
8353                 int i;
8354                 for ( i=0; prefixdenylist[i]; i++ ) {
8355                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8356                                 servicename, i, prefixdenylist[i], sharepath ));
8357                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8358                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8359                                         "usershare prefix deny list entries.\n",
8360                                         servicename, sharepath));
8361                                 return USERSHARE_PATH_IS_DENIED;
8362                         }
8363                 }
8364         }
8365
8366         /* If there is a usershare prefix allow list ensure one of these paths
8367            does match the start of the user given path. */
8368
8369         if (prefixallowlist) {
8370                 int i;
8371                 for ( i=0; prefixallowlist[i]; i++ ) {
8372                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8373                                 servicename, i, prefixallowlist[i], sharepath ));
8374                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8375                                 break;
8376                         }
8377                 }
8378                 if (prefixallowlist[i] == NULL) {
8379                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8380                                 "usershare prefix allow list entries.\n",
8381                                 servicename, sharepath));
8382                         return USERSHARE_PATH_NOT_ALLOWED;
8383                 }
8384         }
8385
8386         /* Ensure this is pointing to a directory. */
8387         dp = sys_opendir(sharepath);
8388
8389         if (!dp) {
8390                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8391                         servicename, sharepath));
8392                 return USERSHARE_PATH_NOT_DIRECTORY;
8393         }
8394
8395         /* Ensure the owner of the usershare file has permission to share
8396            this directory. */
8397
8398         if (sys_stat(sharepath, &sbuf) == -1) {
8399                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8400                         servicename, sharepath, strerror(errno) ));
8401                 sys_closedir(dp);
8402                 return USERSHARE_POSIX_ERR;
8403         }
8404
8405         sys_closedir(dp);
8406
8407         if (!S_ISDIR(sbuf.st_mode)) {
8408                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8409                         servicename, sharepath ));
8410                 return USERSHARE_PATH_NOT_DIRECTORY;
8411         }
8412
8413         /* Check if sharing is restricted to owner-only. */
8414         /* psbuf is the stat of the usershare definition file,
8415            sbuf is the stat of the target directory to be shared. */
8416
8417         if (lp_usershare_owner_only()) {
8418                 /* root can share anything. */
8419                 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8420                         return USERSHARE_PATH_NOT_ALLOWED;
8421                 }
8422         }
8423
8424         *pp_sharepath = sharepath;
8425         *pp_comment = comment;
8426         return USERSHARE_OK;
8427 }
8428
8429 /***************************************************************************
8430  Deal with a usershare file.
8431  Returns:
8432         >= 0 - snum
8433         -1 - Bad name, invalid contents.
8434            - service name already existed and not a usershare, problem
8435             with permissions to share directory etc.
8436 ***************************************************************************/
8437
8438 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8439 {
8440         SMB_STRUCT_STAT sbuf;
8441         SMB_STRUCT_STAT lsbuf;
8442         char *fname = NULL;
8443         char *sharepath = NULL;
8444         char *comment = NULL;
8445         fstring service_name;
8446         char **lines = NULL;
8447         int numlines = 0;
8448         int fd = -1;
8449         int iService = -1;
8450         TALLOC_CTX *ctx = NULL;
8451         SEC_DESC *psd = NULL;
8452         bool guest_ok = False;
8453
8454         /* Ensure share name doesn't contain invalid characters. */
8455         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8456                 DEBUG(0,("process_usershare_file: share name %s contains "
8457                         "invalid characters (any of %s)\n",
8458                         file_name, INVALID_SHARENAME_CHARS ));
8459                 return -1;
8460         }
8461
8462         fstrcpy(service_name, file_name);
8463
8464         if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8465         }
8466
8467         /* Minimize the race condition by doing an lstat before we
8468            open and fstat. Ensure this isn't a symlink link. */
8469
8470         if (sys_lstat(fname, &lsbuf) != 0) {
8471                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8472                         fname, strerror(errno) ));
8473                 SAFE_FREE(fname);
8474                 return -1;
8475         }
8476
8477         /* This must be a regular file, not a symlink, directory or
8478            other strange filetype. */
8479         if (!check_usershare_stat(fname, &lsbuf)) {
8480                 SAFE_FREE(fname);
8481                 return -1;
8482         }
8483
8484         {
8485                 char *canon_name = canonicalize_servicename(service_name);
8486                 TDB_DATA data = dbwrap_fetch_bystring(
8487                         ServiceHash, canon_name, canon_name);
8488
8489                 iService = -1;
8490
8491                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8492                         iService = *(int *)data.dptr;
8493                 }
8494                 TALLOC_FREE(canon_name);
8495         }
8496
8497         if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8498                 /* Nothing changed - Mark valid and return. */
8499                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8500                         service_name ));
8501                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8502                 SAFE_FREE(fname);
8503                 return iService;
8504         }
8505
8506         /* Try and open the file read only - no symlinks allowed. */
8507 #ifdef O_NOFOLLOW
8508         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8509 #else
8510         fd = sys_open(fname, O_RDONLY, 0);
8511 #endif
8512
8513         if (fd == -1) {
8514                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8515                         fname, strerror(errno) ));
8516                 SAFE_FREE(fname);
8517                 return -1;
8518         }
8519
8520         /* Now fstat to be *SURE* it's a regular file. */
8521         if (sys_fstat(fd, &sbuf) != 0) {
8522                 close(fd);
8523                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8524                         fname, strerror(errno) ));
8525                 SAFE_FREE(fname);
8526                 return -1;
8527         }
8528
8529         /* Is it the same dev/inode as was lstated ? */
8530         if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8531                 close(fd);
8532                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8533                         "Symlink spoofing going on ?\n", fname ));
8534                 SAFE_FREE(fname);
8535                 return -1;
8536         }
8537
8538         /* This must be a regular file, not a symlink, directory or
8539            other strange filetype. */
8540         if (!check_usershare_stat(fname, &sbuf)) {
8541                 SAFE_FREE(fname);
8542                 return -1;
8543         }
8544
8545         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8546
8547         close(fd);
8548         if (lines == NULL) {
8549                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8550                         fname, (unsigned int)sbuf.st_uid ));
8551                 SAFE_FREE(fname);
8552                 return -1;
8553         }
8554
8555         SAFE_FREE(fname);
8556
8557         /* Should we allow printers to be shared... ? */
8558         ctx = talloc_init("usershare_sd_xctx");
8559         if (!ctx) {
8560                 TALLOC_FREE(lines);
8561                 return 1;
8562         }
8563
8564         if (parse_usershare_file(ctx, &sbuf, service_name,
8565                         iService, lines, numlines, &sharepath,
8566                         &comment, &psd, &guest_ok) != USERSHARE_OK) {
8567                 talloc_destroy(ctx);
8568                 TALLOC_FREE(lines);
8569                 return -1;
8570         }
8571
8572         TALLOC_FREE(lines);
8573
8574         /* Everything ok - add the service possibly using a template. */
8575         if (iService < 0) {
8576                 const struct service *sp = &sDefault;
8577                 if (snum_template != -1) {
8578                         sp = ServicePtrs[snum_template];
8579                 }
8580
8581                 if ((iService = add_a_service(sp, service_name)) < 0) {
8582                         DEBUG(0, ("process_usershare_file: Failed to add "
8583                                 "new service %s\n", service_name));
8584                         talloc_destroy(ctx);
8585                         return -1;
8586                 }
8587
8588                 /* Read only is controlled by usershare ACL below. */
8589                 ServicePtrs[iService]->bRead_only = False;
8590         }
8591
8592         /* Write the ACL of the new/modified share. */
8593         if (!set_share_security(service_name, psd)) {
8594                  DEBUG(0, ("process_usershare_file: Failed to set share "
8595                         "security for user share %s\n",
8596                         service_name ));
8597                 lp_remove_service(iService);
8598                 talloc_destroy(ctx);
8599                 return -1;
8600         }
8601
8602         /* If from a template it may be marked invalid. */
8603         ServicePtrs[iService]->valid = True;
8604
8605         /* Set the service as a valid usershare. */
8606         ServicePtrs[iService]->usershare = USERSHARE_VALID;
8607
8608         /* Set guest access. */
8609         if (lp_usershare_allow_guests()) {
8610                 ServicePtrs[iService]->bGuest_ok = guest_ok;
8611         }
8612
8613         /* And note when it was loaded. */
8614         ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8615         string_set(&ServicePtrs[iService]->szPath, sharepath);
8616         string_set(&ServicePtrs[iService]->comment, comment);
8617
8618         talloc_destroy(ctx);
8619
8620         return iService;
8621 }
8622
8623 /***************************************************************************
8624  Checks if a usershare entry has been modified since last load.
8625 ***************************************************************************/
8626
8627 static bool usershare_exists(int iService, time_t *last_mod)
8628 {
8629         SMB_STRUCT_STAT lsbuf;
8630         const char *usersharepath = Globals.szUsersharePath;
8631         char *fname;
8632
8633         if (asprintf(&fname, "%s/%s",
8634                                 usersharepath,
8635                                 ServicePtrs[iService]->szService) < 0) {
8636                 return false;
8637         }
8638
8639         if (sys_lstat(fname, &lsbuf) != 0) {
8640                 SAFE_FREE(fname);
8641                 return false;
8642         }
8643
8644         if (!S_ISREG(lsbuf.st_mode)) {
8645                 SAFE_FREE(fname);
8646                 return false;
8647         }
8648
8649         SAFE_FREE(fname);
8650         *last_mod = lsbuf.st_mtime;
8651         return true;
8652 }
8653
8654 /***************************************************************************
8655  Load a usershare service by name. Returns a valid servicenumber or -1.
8656 ***************************************************************************/
8657
8658 int load_usershare_service(const char *servicename)
8659 {
8660         SMB_STRUCT_STAT sbuf;
8661         const char *usersharepath = Globals.szUsersharePath;
8662         int max_user_shares = Globals.iUsershareMaxShares;
8663         int snum_template = -1;
8664
8665         if (*usersharepath == 0 ||  max_user_shares == 0) {
8666                 return -1;
8667         }
8668
8669         if (sys_stat(usersharepath, &sbuf) != 0) {
8670                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8671                         usersharepath, strerror(errno) ));
8672                 return -1;
8673         }
8674
8675         if (!S_ISDIR(sbuf.st_mode)) {
8676                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8677                         usersharepath ));
8678                 return -1;
8679         }
8680
8681         /*
8682          * This directory must be owned by root, and have the 't' bit set.
8683          * It also must not be writable by "other".
8684          */
8685
8686 #ifdef S_ISVTX
8687         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8688 #else
8689         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8690 #endif
8691                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8692                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8693                         usersharepath ));
8694                 return -1;
8695         }
8696
8697         /* Ensure the template share exists if it's set. */
8698         if (Globals.szUsershareTemplateShare[0]) {
8699                 /* We can't use lp_servicenumber here as we are recommending that
8700                    template shares have -valid=False set. */
8701                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8702                         if (ServicePtrs[snum_template]->szService &&
8703                                         strequal(ServicePtrs[snum_template]->szService,
8704                                                 Globals.szUsershareTemplateShare)) {
8705                                 break;
8706                         }
8707                 }
8708
8709                 if (snum_template == -1) {
8710                         DEBUG(0,("load_usershare_service: usershare template share %s "
8711                                 "does not exist.\n",
8712                                 Globals.szUsershareTemplateShare ));
8713                         return -1;
8714                 }
8715         }
8716
8717         return process_usershare_file(usersharepath, servicename, snum_template);
8718 }
8719
8720 /***************************************************************************
8721  Load all user defined shares from the user share directory.
8722  We only do this if we're enumerating the share list.
8723  This is the function that can delete usershares that have
8724  been removed.
8725 ***************************************************************************/
8726
8727 int load_usershare_shares(void)
8728 {
8729         SMB_STRUCT_DIR *dp;
8730         SMB_STRUCT_STAT sbuf;
8731         SMB_STRUCT_DIRENT *de;
8732         int num_usershares = 0;
8733         int max_user_shares = Globals.iUsershareMaxShares;
8734         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8735         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8736         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8737         int iService;
8738         int snum_template = -1;
8739         const char *usersharepath = Globals.szUsersharePath;
8740         int ret = lp_numservices();
8741
8742         if (max_user_shares == 0 || *usersharepath == '\0') {
8743                 return lp_numservices();
8744         }
8745
8746         if (sys_stat(usersharepath, &sbuf) != 0) {
8747                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8748                         usersharepath, strerror(errno) ));
8749                 return ret;
8750         }
8751
8752         /*
8753          * This directory must be owned by root, and have the 't' bit set.
8754          * It also must not be writable by "other".
8755          */
8756
8757 #ifdef S_ISVTX
8758         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8759 #else
8760         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8761 #endif
8762                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8763                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8764                         usersharepath ));
8765                 return ret;
8766         }
8767
8768         /* Ensure the template share exists if it's set. */
8769         if (Globals.szUsershareTemplateShare[0]) {
8770                 /* We can't use lp_servicenumber here as we are recommending that
8771                    template shares have -valid=False set. */
8772                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8773                         if (ServicePtrs[snum_template]->szService &&
8774                                         strequal(ServicePtrs[snum_template]->szService,
8775                                                 Globals.szUsershareTemplateShare)) {
8776                                 break;
8777                         }
8778                 }
8779
8780                 if (snum_template == -1) {
8781                         DEBUG(0,("load_usershare_shares: usershare template share %s "
8782                                 "does not exist.\n",
8783                                 Globals.szUsershareTemplateShare ));
8784                         return ret;
8785                 }
8786         }
8787
8788         /* Mark all existing usershares as pending delete. */
8789         for (iService = iNumServices - 1; iService >= 0; iService--) {
8790                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8791                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8792                 }
8793         }
8794
8795         dp = sys_opendir(usersharepath);
8796         if (!dp) {
8797                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8798                         usersharepath, strerror(errno) ));
8799                 return ret;
8800         }
8801
8802         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8803                         (de = sys_readdir(dp));
8804                         num_dir_entries++ ) {
8805                 int r;
8806                 const char *n = de->d_name;
8807
8808                 /* Ignore . and .. */
8809                 if (*n == '.') {
8810                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8811                                 continue;
8812                         }
8813                 }
8814
8815                 if (n[0] == ':') {
8816                         /* Temporary file used when creating a share. */
8817                         num_tmp_dir_entries++;
8818                 }
8819
8820                 /* Allow 20% tmp entries. */
8821                 if (num_tmp_dir_entries > allowed_tmp_entries) {
8822                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8823                                 "in directory %s\n",
8824                                 num_tmp_dir_entries, usersharepath));
8825                         break;
8826                 }
8827
8828                 r = process_usershare_file(usersharepath, n, snum_template);
8829                 if (r == 0) {
8830                         /* Update the services count. */
8831                         num_usershares++;
8832                         if (num_usershares >= max_user_shares) {
8833                                 DEBUG(0,("load_usershare_shares: max user shares reached "
8834                                         "on file %s in directory %s\n",
8835                                         n, usersharepath ));
8836                                 break;
8837                         }
8838                 } else if (r == -1) {
8839                         num_bad_dir_entries++;
8840                 }
8841
8842                 /* Allow 20% bad entries. */
8843                 if (num_bad_dir_entries > allowed_bad_entries) {
8844                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8845                                 "in directory %s\n",
8846                                 num_bad_dir_entries, usersharepath));
8847                         break;
8848                 }
8849
8850                 /* Allow 20% bad entries. */
8851                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8852                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8853                         "in directory %s\n",
8854                         num_dir_entries, usersharepath));
8855                         break;
8856                 }
8857         }
8858
8859         sys_closedir(dp);
8860
8861         /* Sweep through and delete any non-refreshed usershares that are
8862            not currently in use. */
8863         for (iService = iNumServices - 1; iService >= 0; iService--) {
8864                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8865                         if (conn_snum_used(iService)) {
8866                                 continue;
8867                         }
8868                         /* Remove from the share ACL db. */
8869                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8870                                 lp_servicename(iService) ));
8871                         delete_share_security(lp_servicename(iService));
8872                         free_service_byindex(iService);
8873                 }
8874         }
8875
8876         return lp_numservices();
8877 }
8878
8879 /********************************************************
8880  Destroy global resources allocated in this file
8881 ********************************************************/
8882
8883 void gfree_loadparm(void)
8884 {
8885         struct file_lists *f;
8886         struct file_lists *next;
8887         int i;
8888
8889         /* Free the file lists */
8890
8891         f = file_lists;
8892         while( f ) {
8893                 next = f->next;
8894                 SAFE_FREE( f->name );
8895                 SAFE_FREE( f->subfname );
8896                 SAFE_FREE( f );
8897                 f = next;
8898         }
8899         file_lists = NULL;
8900
8901         /* Free resources allocated to services */
8902
8903         for ( i = 0; i < iNumServices; i++ ) {
8904                 if ( VALID(i) ) {
8905                         free_service_byindex(i);
8906                 }
8907         }
8908
8909         SAFE_FREE( ServicePtrs );
8910         iNumServices = 0;
8911
8912         /* Now release all resources allocated to global
8913            parameters and the default service */
8914
8915         free_global_parameters();
8916 }
8917
8918
8919 /***************************************************************************
8920  Allow client apps to specify that they are a client
8921 ***************************************************************************/
8922 void lp_set_in_client(bool b)
8923 {
8924     in_client = b;
8925 }
8926
8927
8928 /***************************************************************************
8929  Determine if we're running in a client app
8930 ***************************************************************************/
8931 bool lp_is_in_client(void)
8932 {
8933     return in_client;
8934 }
8935
8936 /***************************************************************************
8937  Load the services array from the services file. Return True on success, 
8938  False on failure.
8939 ***************************************************************************/
8940
8941 bool lp_load_ex(const char *pszFname,
8942                 bool global_only,
8943                 bool save_defaults,
8944                 bool add_ipc,
8945                 bool initialize_globals,
8946                 bool allow_include_registry,
8947                 bool allow_registry_shares)
8948 {
8949         char *n2 = NULL;
8950         bool bRetval;
8951
8952         bRetval = False;
8953
8954         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8955
8956         bInGlobalSection = True;
8957         bGlobalOnly = global_only;
8958         bAllowIncludeRegistry = allow_include_registry;
8959
8960         init_globals(! initialize_globals);
8961         debug_init();
8962
8963         if (save_defaults) {
8964                 init_locals();
8965                 lp_save_defaults();
8966         }
8967
8968         free_param_opts(&Globals.param_opt);
8969
8970         /* We get sections first, so have to start 'behind' to make up */
8971         iServiceIndex = -1;
8972
8973         if (lp_config_backend_is_file()) {
8974                 n2 = alloc_sub_basic(get_current_username(),
8975                                         current_user_info.domain,
8976                                         pszFname);
8977                 if (!n2) {
8978                         smb_panic("lp_load_ex: out of memory");
8979                 }
8980
8981                 add_to_file_list(pszFname, n2);
8982
8983                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8984                 SAFE_FREE(n2);
8985
8986                 /* finish up the last section */
8987                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8988                 if (bRetval) {
8989                         if (iServiceIndex >= 0) {
8990                                 bRetval = service_ok(iServiceIndex);
8991                         }
8992                 }
8993
8994                 if (lp_config_backend_is_registry()) {
8995                         /* config backend changed to registry in config file */
8996                         /*
8997                          * We need to use this extra global variable here to
8998                          * survive restart: init_globals uses this as a default
8999                          * for ConfigBackend. Otherwise, init_globals would
9000                          *  send us into an endless loop here.
9001                          */
9002                         config_backend = CONFIG_BACKEND_REGISTRY;
9003                         /* start over */
9004                         DEBUG(1, ("lp_load_ex: changing to config backend "
9005                                   "registry\n"));
9006                         init_globals(false);
9007                         lp_kill_all_services();
9008                         return lp_load_ex(pszFname, global_only, save_defaults,
9009                                           add_ipc, initialize_globals,
9010                                           allow_include_registry,
9011                                           allow_registry_shares);
9012                 }
9013         } else if (lp_config_backend_is_registry()) {
9014                 bRetval = process_registry_globals();
9015         } else {
9016                 DEBUG(0, ("Illegal config  backend given: %d\n",
9017                           lp_config_backend()));
9018                 bRetval = false;
9019         }
9020
9021         if (bRetval && lp_registry_shares() && allow_registry_shares) {
9022                 bRetval = process_registry_shares();
9023         }
9024
9025         lp_add_auto_services(lp_auto_services());
9026
9027         if (add_ipc) {
9028                 /* When 'restrict anonymous = 2' guest connections to ipc$
9029                    are denied */
9030                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9031                 if ( lp_enable_asu_support() ) {
9032                         lp_add_ipc("ADMIN$", false);
9033                 }
9034         }
9035
9036         set_server_role();
9037         set_default_server_announce_type();
9038         set_allowed_client_auth();
9039
9040         bLoaded = True;
9041
9042         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9043         /* if bWINSsupport is true and we are in the client            */
9044         if (lp_is_in_client() && Globals.bWINSsupport) {
9045                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9046         }
9047
9048         init_iconv();
9049
9050         bAllowIncludeRegistry = true;
9051
9052         return (bRetval);
9053 }
9054
9055 bool lp_load(const char *pszFname,
9056              bool global_only,
9057              bool save_defaults,
9058              bool add_ipc,
9059              bool initialize_globals)
9060 {
9061         return lp_load_ex(pszFname,
9062                           global_only,
9063                           save_defaults,
9064                           add_ipc,
9065                           initialize_globals,
9066                           true, false);
9067 }
9068
9069 bool lp_load_initial_only(const char *pszFname)
9070 {
9071         return lp_load_ex(pszFname,
9072                           true,
9073                           false,
9074                           false,
9075                           true,
9076                           false,
9077                           false);
9078 }
9079
9080 bool lp_load_with_registry_shares(const char *pszFname,
9081                                   bool global_only,
9082                                   bool save_defaults,
9083                                   bool add_ipc,
9084                                   bool initialize_globals)
9085 {
9086         return lp_load_ex(pszFname,
9087                           global_only,
9088                           save_defaults,
9089                           add_ipc,
9090                           initialize_globals,
9091                           true,
9092                           true);
9093 }
9094
9095 /***************************************************************************
9096  Return the max number of services.
9097 ***************************************************************************/
9098
9099 int lp_numservices(void)
9100 {
9101         return (iNumServices);
9102 }
9103
9104 /***************************************************************************
9105 Display the contents of the services array in human-readable form.
9106 ***************************************************************************/
9107
9108 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9109 {
9110         int iService;
9111
9112         if (show_defaults)
9113                 defaults_saved = False;
9114
9115         dump_globals(f);
9116
9117         dump_a_service(&sDefault, f);
9118
9119         for (iService = 0; iService < maxtoprint; iService++) {
9120                 fprintf(f,"\n");
9121                 lp_dump_one(f, show_defaults, iService);
9122         }
9123 }
9124
9125 /***************************************************************************
9126 Display the contents of one service in human-readable form.
9127 ***************************************************************************/
9128
9129 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9130 {
9131         if (VALID(snum)) {
9132                 if (ServicePtrs[snum]->szService[0] == '\0')
9133                         return;
9134                 dump_a_service(ServicePtrs[snum], f);
9135         }
9136 }
9137
9138 /***************************************************************************
9139 Return the number of the service with the given name, or -1 if it doesn't
9140 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9141 getservicebyname()! This works ONLY if all services have been loaded, and
9142 does not copy the found service.
9143 ***************************************************************************/
9144
9145 int lp_servicenumber(const char *pszServiceName)
9146 {
9147         int iService;
9148         fstring serviceName;
9149         
9150         if (!pszServiceName) {
9151                 return GLOBAL_SECTION_SNUM;
9152         }
9153         
9154         for (iService = iNumServices - 1; iService >= 0; iService--) {
9155                 if (VALID(iService) && ServicePtrs[iService]->szService) {
9156                         /*
9157                          * The substitution here is used to support %U is
9158                          * service names
9159                          */
9160                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
9161                         standard_sub_basic(get_current_username(),
9162                                            current_user_info.domain,
9163                                            serviceName,sizeof(serviceName));
9164                         if (strequal(serviceName, pszServiceName)) {
9165                                 break;
9166                         }
9167                 }
9168         }
9169
9170         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9171                 time_t last_mod;
9172
9173                 if (!usershare_exists(iService, &last_mod)) {
9174                         /* Remove the share security tdb entry for it. */
9175                         delete_share_security(lp_servicename(iService));
9176                         /* Remove it from the array. */
9177                         free_service_byindex(iService);
9178                         /* Doesn't exist anymore. */
9179                         return GLOBAL_SECTION_SNUM;
9180                 }
9181
9182                 /* Has it been modified ? If so delete and reload. */
9183                 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9184                         /* Remove it from the array. */
9185                         free_service_byindex(iService);
9186                         /* and now reload it. */
9187                         iService = load_usershare_service(pszServiceName);
9188                 }
9189         }
9190
9191         if (iService < 0) {
9192                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9193                 return GLOBAL_SECTION_SNUM;
9194         }
9195
9196         return (iService);
9197 }
9198
9199 bool share_defined(const char *service_name)
9200 {
9201         return (lp_servicenumber(service_name) != -1);
9202 }
9203
9204 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9205                                       const char *sharename)
9206 {
9207         struct share_params *result;
9208         char *sname;
9209         int snum;
9210
9211         if (!(sname = SMB_STRDUP(sharename))) {
9212                 return NULL;
9213         }
9214
9215         snum = find_service(sname);
9216         SAFE_FREE(sname);
9217
9218         if (snum < 0) {
9219                 return NULL;
9220         }
9221
9222         if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9223                 DEBUG(0, ("talloc failed\n"));
9224                 return NULL;
9225         }
9226
9227         result->service = snum;
9228         return result;
9229 }
9230
9231 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9232 {
9233         struct share_iterator *result;
9234
9235         if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9236                 DEBUG(0, ("talloc failed\n"));
9237                 return NULL;
9238         }
9239
9240         result->next_id = 0;
9241         return result;
9242 }
9243
9244 struct share_params *next_share(struct share_iterator *list)
9245 {
9246         struct share_params *result;
9247
9248         while (!lp_snum_ok(list->next_id) &&
9249                (list->next_id < lp_numservices())) {
9250                 list->next_id += 1;
9251         }
9252
9253         if (list->next_id >= lp_numservices()) {
9254                 return NULL;
9255         }
9256
9257         if (!(result = TALLOC_P(list, struct share_params))) {
9258                 DEBUG(0, ("talloc failed\n"));
9259                 return NULL;
9260         }
9261
9262         result->service = list->next_id;
9263         list->next_id += 1;
9264         return result;
9265 }
9266
9267 struct share_params *next_printer(struct share_iterator *list)
9268 {
9269         struct share_params *result;
9270
9271         while ((result = next_share(list)) != NULL) {
9272                 if (lp_print_ok(result->service)) {
9273                         break;
9274                 }
9275         }
9276         return result;
9277 }
9278
9279 /*
9280  * This is a hack for a transition period until we transformed all code from
9281  * service numbers to struct share_params.
9282  */
9283
9284 struct share_params *snum2params_static(int snum)
9285 {
9286         static struct share_params result;
9287         result.service = snum;
9288         return &result;
9289 }
9290
9291 /*******************************************************************
9292  A useful volume label function. 
9293 ********************************************************************/
9294
9295 const char *volume_label(int snum)
9296 {
9297         char *ret;
9298         const char *label = lp_volume(snum);
9299         if (!*label) {
9300                 label = lp_servicename(snum);
9301         }
9302                 
9303         /* This returns a 33 byte guarenteed null terminated string. */
9304         ret = talloc_strndup(talloc_tos(), label, 32);
9305         if (!ret) {
9306                 return "";
9307         }               
9308         return ret;
9309 }
9310
9311 /*******************************************************************
9312  Set the server type we will announce as via nmbd.
9313 ********************************************************************/
9314
9315 static void set_default_server_announce_type(void)
9316 {
9317         default_server_announce = 0;
9318         default_server_announce |= SV_TYPE_WORKSTATION;
9319         default_server_announce |= SV_TYPE_SERVER;
9320         default_server_announce |= SV_TYPE_SERVER_UNIX;
9321
9322         /* note that the flag should be set only if we have a 
9323            printer service but nmbd doesn't actually load the 
9324            services so we can't tell   --jerry */
9325
9326         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9327
9328         switch (lp_announce_as()) {
9329                 case ANNOUNCE_AS_NT_SERVER:
9330                         default_server_announce |= SV_TYPE_SERVER_NT;
9331                         /* fall through... */
9332                 case ANNOUNCE_AS_NT_WORKSTATION:
9333                         default_server_announce |= SV_TYPE_NT;
9334                         break;
9335                 case ANNOUNCE_AS_WIN95:
9336                         default_server_announce |= SV_TYPE_WIN95_PLUS;
9337                         break;
9338                 case ANNOUNCE_AS_WFW:
9339                         default_server_announce |= SV_TYPE_WFW;
9340                         break;
9341                 default:
9342                         break;
9343         }
9344
9345         switch (lp_server_role()) {
9346                 case ROLE_DOMAIN_MEMBER:
9347                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9348                         break;
9349                 case ROLE_DOMAIN_PDC:
9350                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9351                         break;
9352                 case ROLE_DOMAIN_BDC:
9353                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9354                         break;
9355                 case ROLE_STANDALONE:
9356                 default:
9357                         break;
9358         }
9359         if (lp_time_server())
9360                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9361
9362         if (lp_host_msdfs())
9363                 default_server_announce |= SV_TYPE_DFS_SERVER;
9364 }
9365
9366 /***********************************************************
9367  returns role of Samba server
9368 ************************************************************/
9369
9370 int lp_server_role(void)
9371 {
9372         return server_role;
9373 }
9374
9375 /***********************************************************
9376  If we are PDC then prefer us as DMB
9377 ************************************************************/
9378
9379 bool lp_domain_master(void)
9380 {
9381         if (Globals.iDomainMaster == Auto)
9382                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9383
9384         return (bool)Globals.iDomainMaster;
9385 }
9386
9387 /***********************************************************
9388  If we are DMB then prefer us as LMB
9389 ************************************************************/
9390
9391 bool lp_preferred_master(void)
9392 {
9393         if (Globals.iPreferredMaster == Auto)
9394                 return (lp_local_master() && lp_domain_master());
9395
9396         return (bool)Globals.iPreferredMaster;
9397 }
9398
9399 /*******************************************************************
9400  Remove a service.
9401 ********************************************************************/
9402
9403 void lp_remove_service(int snum)
9404 {
9405         ServicePtrs[snum]->valid = False;
9406         invalid_services[num_invalid_services++] = snum;
9407 }
9408
9409 /*******************************************************************
9410  Copy a service.
9411 ********************************************************************/
9412
9413 void lp_copy_service(int snum, const char *new_name)
9414 {
9415         do_section(new_name, NULL);
9416         if (snum >= 0) {
9417                 snum = lp_servicenumber(new_name);
9418                 if (snum >= 0)
9419                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9420         }
9421 }
9422
9423
9424 /*******************************************************************
9425  Get the default server type we will announce as via nmbd.
9426 ********************************************************************/
9427
9428 int lp_default_server_announce(void)
9429 {
9430         return default_server_announce;
9431 }
9432
9433 /*******************************************************************
9434  Split the announce version into major and minor numbers.
9435 ********************************************************************/
9436
9437 int lp_major_announce_version(void)
9438 {
9439         static bool got_major = False;
9440         static int major_version = DEFAULT_MAJOR_VERSION;
9441         char *vers;
9442         char *p;
9443
9444         if (got_major)
9445                 return major_version;
9446
9447         got_major = True;
9448         if ((vers = lp_announce_version()) == NULL)
9449                 return major_version;
9450
9451         if ((p = strchr_m(vers, '.')) == 0)
9452                 return major_version;
9453
9454         *p = '\0';
9455         major_version = atoi(vers);
9456         return major_version;
9457 }
9458
9459 int lp_minor_announce_version(void)
9460 {
9461         static bool got_minor = False;
9462         static int minor_version = DEFAULT_MINOR_VERSION;
9463         char *vers;
9464         char *p;
9465
9466         if (got_minor)
9467                 return minor_version;
9468
9469         got_minor = True;
9470         if ((vers = lp_announce_version()) == NULL)
9471                 return minor_version;
9472
9473         if ((p = strchr_m(vers, '.')) == 0)
9474                 return minor_version;
9475
9476         p++;
9477         minor_version = atoi(p);
9478         return minor_version;
9479 }
9480
9481 /***********************************************************
9482  Set the global name resolution order (used in smbclient).
9483 ************************************************************/
9484
9485 void lp_set_name_resolve_order(const char *new_order)
9486 {
9487         string_set(&Globals.szNameResolveOrder, new_order);
9488 }
9489
9490 const char *lp_printername(int snum)
9491 {
9492         const char *ret = _lp_printername(snum);
9493         if (ret == NULL || (ret != NULL && *ret == '\0'))
9494                 ret = lp_const_servicename(snum);
9495
9496         return ret;
9497 }
9498
9499
9500 /***********************************************************
9501  Allow daemons such as winbindd to fix their logfile name.
9502 ************************************************************/
9503
9504 void lp_set_logfile(const char *name)
9505 {
9506         string_set(&Globals.szLogFile, name);
9507         debug_set_logfile(name);
9508 }
9509
9510 /*******************************************************************
9511  Return the max print jobs per queue.
9512 ********************************************************************/
9513
9514 int lp_maxprintjobs(int snum)
9515 {
9516         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9517         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9518                 maxjobs = PRINT_MAX_JOBID - 1;
9519
9520         return maxjobs;
9521 }
9522
9523 const char *lp_printcapname(void)
9524 {
9525         if ((Globals.szPrintcapname != NULL) &&
9526             (Globals.szPrintcapname[0] != '\0'))
9527                 return Globals.szPrintcapname;
9528
9529         if (sDefault.iPrinting == PRINT_CUPS) {
9530 #ifdef HAVE_CUPS
9531                 return "cups";
9532 #else
9533                 return "lpstat";
9534 #endif
9535         }
9536
9537         if (sDefault.iPrinting == PRINT_BSD)
9538                 return "/etc/printcap";
9539
9540         return PRINTCAP_NAME;
9541 }
9542
9543 /*******************************************************************
9544  Ensure we don't use sendfile if server smb signing is active.
9545 ********************************************************************/
9546
9547 static uint32 spoolss_state;
9548
9549 bool lp_disable_spoolss( void )
9550 {
9551         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9552                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9553
9554         return spoolss_state == SVCCTL_STOPPED ? True : False;
9555 }
9556
9557 void lp_set_spoolss_state( uint32 state )
9558 {
9559         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9560
9561         spoolss_state = state;
9562 }
9563
9564 uint32 lp_get_spoolss_state( void )
9565 {
9566         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9567 }
9568
9569 /*******************************************************************
9570  Ensure we don't use sendfile if server smb signing is active.
9571 ********************************************************************/
9572
9573 bool lp_use_sendfile(int snum)
9574 {
9575         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9576         if (Protocol < PROTOCOL_NT1) {
9577                 return False;
9578         }
9579         return (_lp_use_sendfile(snum) &&
9580                         (get_remote_arch() != RA_WIN95) &&
9581                         !srv_is_signing_active());
9582 }
9583
9584 /*******************************************************************
9585  Turn off sendfile if we find the underlying OS doesn't support it.
9586 ********************************************************************/
9587
9588 void set_use_sendfile(int snum, bool val)
9589 {
9590         if (LP_SNUM_OK(snum))
9591                 ServicePtrs[snum]->bUseSendfile = val;
9592         else
9593                 sDefault.bUseSendfile = val;
9594 }
9595
9596 /*******************************************************************
9597  Turn off storing DOS attributes if this share doesn't support it.
9598 ********************************************************************/
9599
9600 void set_store_dos_attributes(int snum, bool val)
9601 {
9602         if (!LP_SNUM_OK(snum))
9603                 return;
9604         ServicePtrs[(snum)]->bStoreDosAttributes = val;
9605 }
9606
9607 void lp_set_mangling_method(const char *new_method)
9608 {
9609         string_set(&Globals.szManglingMethod, new_method);
9610 }
9611
9612 /*******************************************************************
9613  Global state for POSIX pathname processing.
9614 ********************************************************************/
9615
9616 static bool posix_pathnames;
9617
9618 bool lp_posix_pathnames(void)
9619 {
9620         return posix_pathnames;
9621 }
9622
9623 /*******************************************************************
9624  Change everything needed to ensure POSIX pathname processing (currently
9625  not much).
9626 ********************************************************************/
9627
9628 void lp_set_posix_pathnames(void)
9629 {
9630         posix_pathnames = True;
9631 }
9632
9633 /*******************************************************************
9634  Global state for POSIX lock processing - CIFS unix extensions.
9635 ********************************************************************/
9636
9637 bool posix_default_lock_was_set;
9638 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9639
9640 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9641 {
9642         if (posix_default_lock_was_set) {
9643                 return posix_cifsx_locktype;
9644         } else {
9645                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9646         }
9647 }
9648
9649 /*******************************************************************
9650 ********************************************************************/
9651
9652 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9653 {
9654         posix_default_lock_was_set = True;
9655         posix_cifsx_locktype = val;
9656 }
9657
9658 int lp_min_receive_file_size(void)
9659 {
9660         if (Globals.iminreceivefile < 0) {
9661                 return 0;
9662         }
9663         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9664 }
9665
9666 /*******************************************************************
9667  If socket address is an empty character string, it is necessary to 
9668  define it as "0.0.0.0". 
9669 ********************************************************************/
9670
9671 const char *lp_socket_address(void)
9672 {
9673         char *sock_addr = Globals.szSocketAddress;
9674         
9675         if (sock_addr[0] == '\0'){
9676                 string_set(&Globals.szSocketAddress, "0.0.0.0");
9677         }
9678         return  Globals.szSocketAddress;
9679 }