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