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