s3:loadparm: use the returnvalue of service_ok() in process_smbconf_service().
[samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13    
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18    
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23    
24    You should have received a copy of the GNU General Public License
25    along with this program.  If not, see <http://www.gnu.org/licenses/>.
26 */
27
28 /*
29  *  Load parameters.
30  *
31  *  This module provides suitable callback functions for the params
32  *  module. It builds the internal table of service details which is
33  *  then used by the rest of the server.
34  *
35  * To add a parameter:
36  *
37  * 1) add it to the global or service structure definition
38  * 2) add it to the parm_table
39  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40  * 4) If it's a global then initialise it in init_globals. If a local
41  *    (ie. service) parameter then initialise it in the sDefault structure
42  *  
43  *
44  * Notes:
45  *   The configuration file is processed sequentially for speed. It is NOT
46  *   accessed randomly as happens in 'real' Windows. For this reason, there
47  *   is a fair bit of sequence-dependent code here - ie., code which assumes
48  *   that certain things happen before others. In particular, the code which
49  *   happens at the boundary between sections is delicately poised, so be
50  *   careful!
51  *
52  */
53
54 #include "includes.h"
55 #include "printing.h"
56
57 #ifdef HAVE_HTTPCONNECTENCRYPT
58 #include <cups/http.h>
59 #endif
60
61 bool bLoaded = False;
62
63 extern enum protocol_types Protocol;
64 extern userdom_struct current_user_info;
65
66 #ifndef GLOBAL_NAME
67 #define GLOBAL_NAME "global"
68 #endif
69
70 #ifndef PRINTERS_NAME
71 #define PRINTERS_NAME "printers"
72 #endif
73
74 #ifndef HOMES_NAME
75 #define HOMES_NAME "homes"
76 #endif
77
78 /* the special value for the include parameter
79  * to be interpreted not as a file name but to
80  * trigger loading of the global smb.conf options
81  * from registry. */
82 #ifndef INCLUDE_REGISTRY_NAME
83 #define INCLUDE_REGISTRY_NAME "registry"
84 #endif
85
86 static bool in_client = False;          /* Not in the client by default */
87 static struct smbconf_csn conf_last_csn;
88
89 #define CONFIG_BACKEND_FILE 0
90 #define CONFIG_BACKEND_REGISTRY 1
91
92 static int config_backend = CONFIG_BACKEND_FILE;
93
94 /* some helpful bits */
95 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
96 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
97
98 #define USERSHARE_VALID 1
99 #define USERSHARE_PENDING_DELETE 2
100
101 static bool defaults_saved = False;
102
103 struct param_opt_struct {
104         struct param_opt_struct *prev, *next;
105         char *key;
106         char *value;
107         char **list;
108 };
109
110 /*
111  * This structure describes global (ie., server-wide) parameters.
112  */
113 struct global {
114         int ConfigBackend;
115         char *smb_ports;
116         char *dos_charset;
117         char *unix_charset;
118         char *display_charset;
119         char *szPrintcapname;
120         char *szAddPortCommand;
121         char *szEnumPortsCommand;
122         char *szAddPrinterCommand;
123         char *szDeletePrinterCommand;
124         char *szOs2DriverMap;
125         char *szLockDir;
126         char *szStateDir;
127         char *szCacheDir;
128         char *szPidDir;
129         char *szRootdir;
130         char *szDefaultService;
131         char *szGetQuota;
132         char *szSetQuota;
133         char *szMsgCommand;
134         char *szServerString;
135         char *szAutoServices;
136         char *szPasswdProgram;
137         char *szPasswdChat;
138         char *szLogFile;
139         char *szConfigFile;
140         char *szSMBPasswdFile;
141         char *szPrivateDir;
142         char *szPassdbBackend;
143         char **szPreloadModules;
144         char *szPasswordServer;
145         char *szSocketOptions;
146         char *szRealm;
147         char *szAfsUsernameMap;
148         int iAfsTokenLifetime;
149         char *szLogNtTokenCommand;
150         char *szUsernameMap;
151         char *szLogonScript;
152         char *szLogonPath;
153         char *szLogonDrive;
154         char *szLogonHome;
155         char **szWINSservers;
156         char **szInterfaces;
157         char *szRemoteAnnounce;
158         char *szRemoteBrowseSync;
159         char *szSocketAddress;
160         char *szNISHomeMapName;
161         char *szAnnounceVersion;        /* This is initialised in init_globals */
162         char *szWorkgroup;
163         char *szNetbiosName;
164         char **szNetbiosAliases;
165         char *szNetbiosScope;
166         char *szNameResolveOrder;
167         char *szPanicAction;
168         char *szAddUserScript;
169         char *szRenameUserScript;
170         char *szDelUserScript;
171         char *szAddGroupScript;
172         char *szDelGroupScript;
173         char *szAddUserToGroupScript;
174         char *szDelUserFromGroupScript;
175         char *szSetPrimaryGroupScript;
176         char *szAddMachineScript;
177         char *szShutdownScript;
178         char *szAbortShutdownScript;
179         char *szUsernameMapScript;
180         char *szCheckPasswordScript;
181         char *szWINSHook;
182         char *szUtmpDir;
183         char *szWtmpDir;
184         bool bUtmp;
185         char *szIdmapUID;
186         char *szIdmapGID;
187         bool bPassdbExpandExplicit;
188         int AlgorithmicRidBase;
189         char *szTemplateHomedir;
190         char *szTemplateShell;
191         char *szWinbindSeparator;
192         bool bWinbindEnumUsers;
193         bool bWinbindEnumGroups;
194         bool bWinbindUseDefaultDomain;
195         bool bWinbindTrustedDomainsOnly;
196         bool bWinbindNestedGroups;
197         int  winbind_expand_groups;
198         bool bWinbindRefreshTickets;
199         bool bWinbindOfflineLogon;
200         bool bWinbindNormalizeNames;
201         bool bWinbindRpcOnly;
202         char *szIdmapBackend;
203         char *szIdmapAllocBackend;
204         char *szAddShareCommand;
205         char *szChangeShareCommand;
206         char *szDeleteShareCommand;
207         char **szEventLogs;
208         char *szGuestaccount;
209         char *szManglingMethod;
210         char **szServicesList;
211         char *szUsersharePath;
212         char *szUsershareTemplateShare;
213         char **szUsersharePrefixAllowList;
214         char **szUsersharePrefixDenyList;
215         int mangle_prefix;
216         int max_log_size;
217         char *szLogLevel;
218         int max_xmit;
219         int max_mux;
220         int max_open_files;
221         int open_files_db_hash_size;
222         int pwordlevel;
223         int unamelevel;
224         int deadtime;
225         bool getwd_cache;
226         int maxprotocol;
227         int minprotocol;
228         int security;
229         char **AuthMethods;
230         bool paranoid_server_security;
231         int maxdisksize;
232         int lpqcachetime;
233         int iMaxSmbdProcesses;
234         bool bDisableSpoolss;
235         int syslog;
236         int os_level;
237         bool enhanced_browsing;
238         int max_ttl;
239         int max_wins_ttl;
240         int min_wins_ttl;
241         int lm_announce;
242         int lm_interval;
243         int announce_as;        /* This is initialised in init_globals */
244         int machine_password_timeout;
245         int map_to_guest;
246         int oplock_break_wait_time;
247         int winbind_cache_time;
248         int winbind_reconnect_delay;
249         int winbind_max_idle_children;
250         char **szWinbindNssInfo;
251         int iLockSpinTime;
252         char *szLdapMachineSuffix;
253         char *szLdapUserSuffix;
254         char *szLdapIdmapSuffix;
255         char *szLdapGroupSuffix;
256         int ldap_ssl;
257         bool ldap_ssl_ads;
258         char *szLdapSuffix;
259         char *szLdapAdminDn;
260         int ldap_debug_level;
261         int ldap_debug_threshold;
262         int iAclCompat;
263         char *szCupsServer;
264         int CupsEncrypt;
265         char *szIPrintServer;
266         char *ctdbdSocket;
267         char **szClusterAddresses;
268         bool clustering;
269         int ldap_passwd_sync;
270         int ldap_replication_sleep;
271         int ldap_timeout; /* This is initialised in init_globals */
272         int ldap_connection_timeout;
273         int ldap_page_size;
274         bool ldap_delete_dn;
275         bool bMsAddPrinterWizard;
276         bool bDNSproxy;
277         bool bWINSsupport;
278         bool bWINSproxy;
279         bool bLocalMaster;
280         int  iPreferredMaster;
281         int iDomainMaster;
282         bool bDomainLogons;
283         char **szInitLogonDelayedHosts;
284         int InitLogonDelay;
285         bool bEncryptPasswords;
286         bool bUpdateEncrypt;
287         int  clientSchannel;
288         int  serverSchannel;
289         bool bNullPasswords;
290         bool bObeyPamRestrictions;
291         bool bLoadPrinters;
292         int PrintcapCacheTime;
293         bool bLargeReadwrite;
294         bool bReadRaw;
295         bool bWriteRaw;
296         bool bSyslogOnly;
297         bool bBrowseList;
298         bool bNISHomeMap;
299         bool bTimeServer;
300         bool bBindInterfacesOnly;
301         bool bPamPasswordChange;
302         bool bUnixPasswdSync;
303         bool bPasswdChatDebug;
304         int iPasswdChatTimeout;
305         bool bTimestampLogs;
306         bool bNTSmbSupport;
307         bool bNTPipeSupport;
308         bool bNTStatusSupport;
309         bool bStatCache;
310         int iMaxStatCacheSize;
311         bool bKernelOplocks;
312         bool bAllowTrustedDomains;
313         bool bLanmanAuth;
314         bool bNTLMAuth;
315         bool bUseSpnego;
316         bool bClientLanManAuth;
317         bool bClientNTLMv2Auth;
318         bool bClientPlaintextAuth;
319         bool bClientUseSpnego;
320         bool bDebugPrefixTimestamp;
321         bool bDebugHiresTimestamp;
322         bool bDebugPid;
323         bool bDebugUid;
324         bool bDebugClass;
325         bool bEnableCoreFiles;
326         bool bHostMSDfs;
327         bool bUseMmap;
328         bool bHostnameLookups;
329         bool bUnixExtensions;
330         bool bDisableNetbios;
331         char * szDedicatedKeytabFile;
332         int  iKerberosMethod;
333         bool bDeferSharingViolations;
334         bool bEnablePrivileges;
335         bool bASUSupport;
336         bool bUsershareOwnerOnly;
337         bool bUsershareAllowGuests;
338         bool bRegistryShares;
339         int restrict_anonymous;
340         int name_cache_timeout;
341         int client_signing;
342         int server_signing;
343         int client_ldap_sasl_wrapping;
344         int iUsershareMaxShares;
345         int iIdmapCacheTime;
346         int iIdmapNegativeCacheTime;
347         bool bResetOnZeroVC;
348         int iKeepalive;
349         int iminreceivefile;
350         struct param_opt_struct *param_opt;
351         int cups_connection_timeout;
352         char *szSMBPerfcountModule;
353         bool bMapUntrustedToDomain;
354 };
355
356 static struct global Globals;
357
358 /*
359  * This structure describes a single service.
360  */
361 struct service {
362         bool valid;
363         bool autoloaded;
364         int usershare;
365         time_t usershare_last_mod;
366         char *szService;
367         char *szPath;
368         char *szUsername;
369         char **szInvalidUsers;
370         char **szValidUsers;
371         char **szAdminUsers;
372         char *szCopy;
373         char *szInclude;
374         char *szPreExec;
375         char *szPostExec;
376         char *szRootPreExec;
377         char *szRootPostExec;
378         char *szCupsOptions;
379         char *szPrintcommand;
380         char *szLpqcommand;
381         char *szLprmcommand;
382         char *szLppausecommand;
383         char *szLpresumecommand;
384         char *szQueuepausecommand;
385         char *szQueueresumecommand;
386         char *szPrintername;
387         char *szPrintjobUsername;
388         char *szDontdescend;
389         char **szHostsallow;
390         char **szHostsdeny;
391         char *szMagicScript;
392         char *szMagicOutput;
393         char *szVetoFiles;
394         char *szHideFiles;
395         char *szVetoOplockFiles;
396         char *comment;
397         char *force_user;
398         char *force_group;
399         char **readlist;
400         char **writelist;
401         char **printer_admin;
402         char *volume;
403         char *fstype;
404         char **szVfsObjects;
405         char *szMSDfsProxy;
406         char *szAioWriteBehind;
407         char *szDfree;
408         int iMinPrintSpace;
409         int iMaxPrintJobs;
410         int iMaxReportedPrintJobs;
411         int iWriteCacheSize;
412         int iCreate_mask;
413         int iCreate_force_mode;
414         int iSecurity_mask;
415         int iSecurity_force_mode;
416         int iDir_mask;
417         int iDir_force_mode;
418         int iDir_Security_mask;
419         int iDir_Security_force_mode;
420         int iMaxConnections;
421         int iDefaultCase;
422         int iPrinting;
423         int iOplockContentionLimit;
424         int iCSCPolicy;
425         int iBlock_size;
426         int iDfreeCacheTime;
427         bool bPreexecClose;
428         bool bRootpreexecClose;
429         int  iCaseSensitive;
430         bool bCasePreserve;
431         bool bShortCasePreserve;
432         bool bHideDotFiles;
433         bool bHideSpecialFiles;
434         bool bHideUnReadable;
435         bool bHideUnWriteableFiles;
436         bool bBrowseable;
437         bool bAccessBasedShareEnum;
438         bool bAvailable;
439         bool bRead_only;
440         bool bNo_set_dir;
441         bool bGuest_only;
442         bool bAdministrative_share;
443         bool bGuest_ok;
444         bool bPrint_ok;
445         bool bMap_system;
446         bool bMap_hidden;
447         bool bMap_archive;
448         bool bStoreDosAttributes;
449         bool bDmapiSupport;
450         bool bLocking;
451         int iStrictLocking;
452         bool bPosixLocking;
453         bool bShareModes;
454         bool bOpLocks;
455         bool bLevel2OpLocks;
456         bool bOnlyUser;
457         bool bMangledNames;
458         bool bWidelinks;
459         bool bSymlinks;
460         bool bSyncAlways;
461         bool bStrictAllocate;
462         bool bStrictSync;
463         char magic_char;
464         struct bitmap *copymap;
465         bool bDeleteReadonly;
466         bool bFakeOplocks;
467         bool bDeleteVetoFiles;
468         bool bDosFilemode;
469         bool bDosFiletimes;
470         bool bDosFiletimeResolution;
471         bool bFakeDirCreateTimes;
472         bool bBlockingLocks;
473         bool bInheritPerms;
474         bool bInheritACLS;
475         bool bInheritOwner;
476         bool bMSDfsRoot;
477         bool bUseClientDriver;
478         bool bDefaultDevmode;
479         bool bForcePrintername;
480         bool bNTAclSupport;
481         bool bForceUnknownAclUser;
482         bool bUseSendfile;
483         bool bProfileAcls;
484         bool bMap_acl_inherit;
485         bool bAfs_Share;
486         bool bEASupport;
487         bool bAclCheckPermissions;
488         bool bAclMapFullControl;
489         bool bAclGroupControl;
490         bool bChangeNotify;
491         bool bKernelChangeNotify;
492         int iallocation_roundup_size;
493         int iAioReadSize;
494         int iAioWriteSize;
495         int iMap_readonly;
496         int iDirectoryNameCacheSize;
497         int ismb_encrypt;
498         struct param_opt_struct *param_opt;
499
500         char dummy[3];          /* for alignment */
501 };
502
503
504 /* This is a default service used to prime a services structure */
505 static struct service sDefault = {
506         True,                   /* valid */
507         False,                  /* not autoloaded */
508         0,                      /* not a usershare */
509         (time_t)0,              /* No last mod time */
510         NULL,                   /* szService */
511         NULL,                   /* szPath */
512         NULL,                   /* szUsername */
513         NULL,                   /* szInvalidUsers */
514         NULL,                   /* szValidUsers */
515         NULL,                   /* szAdminUsers */
516         NULL,                   /* szCopy */
517         NULL,                   /* szInclude */
518         NULL,                   /* szPreExec */
519         NULL,                   /* szPostExec */
520         NULL,                   /* szRootPreExec */
521         NULL,                   /* szRootPostExec */
522         NULL,                   /* szCupsOptions */
523         NULL,                   /* szPrintcommand */
524         NULL,                   /* szLpqcommand */
525         NULL,                   /* szLprmcommand */
526         NULL,                   /* szLppausecommand */
527         NULL,                   /* szLpresumecommand */
528         NULL,                   /* szQueuepausecommand */
529         NULL,                   /* szQueueresumecommand */
530         NULL,                   /* szPrintername */
531         NULL,                   /* szPrintjobUsername */
532         NULL,                   /* szDontdescend */
533         NULL,                   /* szHostsallow */
534         NULL,                   /* szHostsdeny */
535         NULL,                   /* szMagicScript */
536         NULL,                   /* szMagicOutput */
537         NULL,                   /* szVetoFiles */
538         NULL,                   /* szHideFiles */
539         NULL,                   /* szVetoOplockFiles */
540         NULL,                   /* comment */
541         NULL,                   /* force user */
542         NULL,                   /* force group */
543         NULL,                   /* readlist */
544         NULL,                   /* writelist */
545         NULL,                   /* printer admin */
546         NULL,                   /* volume */
547         NULL,                   /* fstype */
548         NULL,                   /* vfs objects */
549         NULL,                   /* szMSDfsProxy */
550         NULL,                   /* szAioWriteBehind */
551         NULL,                   /* szDfree */
552         0,                      /* iMinPrintSpace */
553         1000,                   /* iMaxPrintJobs */
554         0,                      /* iMaxReportedPrintJobs */
555         0,                      /* iWriteCacheSize */
556         0744,                   /* iCreate_mask */
557         0000,                   /* iCreate_force_mode */
558         0777,                   /* iSecurity_mask */
559         0,                      /* iSecurity_force_mode */
560         0755,                   /* iDir_mask */
561         0000,                   /* iDir_force_mode */
562         0777,                   /* iDir_Security_mask */
563         0,                      /* iDir_Security_force_mode */
564         0,                      /* iMaxConnections */
565         CASE_LOWER,             /* iDefaultCase */
566         DEFAULT_PRINTING,       /* iPrinting */
567         2,                      /* iOplockContentionLimit */
568         0,                      /* iCSCPolicy */
569         1024,                   /* iBlock_size */
570         0,                      /* iDfreeCacheTime */
571         False,                  /* bPreexecClose */
572         False,                  /* bRootpreexecClose */
573         Auto,                   /* case sensitive */
574         True,                   /* case preserve */
575         True,                   /* short case preserve */
576         True,                   /* bHideDotFiles */
577         False,                  /* bHideSpecialFiles */
578         False,                  /* bHideUnReadable */
579         False,                  /* bHideUnWriteableFiles */
580         True,                   /* bBrowseable */
581         False,                  /* bAccessBasedShareEnum */
582         True,                   /* bAvailable */
583         True,                   /* bRead_only */
584         True,                   /* bNo_set_dir */
585         False,                  /* bGuest_only */
586         False,                  /* bAdministrative_share */
587         False,                  /* bGuest_ok */
588         False,                  /* bPrint_ok */
589         False,                  /* bMap_system */
590         False,                  /* bMap_hidden */
591         True,                   /* bMap_archive */
592         False,                  /* bStoreDosAttributes */
593         False,                  /* bDmapiSupport */
594         True,                   /* bLocking */
595         Auto,                   /* iStrictLocking */
596         True,                   /* bPosixLocking */
597         True,                   /* bShareModes */
598         True,                   /* bOpLocks */
599         True,                   /* bLevel2OpLocks */
600         False,                  /* bOnlyUser */
601         True,                   /* bMangledNames */
602         True,                   /* bWidelinks */
603         True,                   /* bSymlinks */
604         False,                  /* bSyncAlways */
605         False,                  /* bStrictAllocate */
606         False,                  /* bStrictSync */
607         '~',                    /* magic char */
608         NULL,                   /* copymap */
609         False,                  /* bDeleteReadonly */
610         False,                  /* bFakeOplocks */
611         False,                  /* bDeleteVetoFiles */
612         False,                  /* bDosFilemode */
613         True,                   /* bDosFiletimes */
614         False,                  /* bDosFiletimeResolution */
615         False,                  /* bFakeDirCreateTimes */
616         True,                   /* bBlockingLocks */
617         False,                  /* bInheritPerms */
618         False,                  /* bInheritACLS */
619         False,                  /* bInheritOwner */
620         False,                  /* bMSDfsRoot */
621         False,                  /* bUseClientDriver */
622         True,                   /* bDefaultDevmode */
623         False,                  /* bForcePrintername */
624         True,                   /* bNTAclSupport */
625         False,                  /* bForceUnknownAclUser */
626         False,                  /* bUseSendfile */
627         False,                  /* bProfileAcls */
628         False,                  /* bMap_acl_inherit */
629         False,                  /* bAfs_Share */
630         False,                  /* bEASupport */
631         True,                   /* bAclCheckPermissions */
632         True,                   /* bAclMapFullControl */
633         False,                  /* bAclGroupControl */
634         True,                   /* bChangeNotify */
635         True,                   /* bKernelChangeNotify */
636         SMB_ROUNDUP_ALLOCATION_SIZE,            /* iallocation_roundup_size */
637         0,                      /* iAioReadSize */
638         0,                      /* iAioWriteSize */
639         MAP_READONLY_YES,       /* iMap_readonly */
640 #ifdef BROKEN_DIRECTORY_HANDLING
641         0,                      /* iDirectoryNameCacheSize */
642 #else
643         100,                    /* iDirectoryNameCacheSize */
644 #endif
645         Auto,                   /* ismb_encrypt */
646         NULL,                   /* Parametric options */
647
648         ""                      /* dummy */
649 };
650
651 /* local variables */
652 static struct service **ServicePtrs = NULL;
653 static int iNumServices = 0;
654 static int iServiceIndex = 0;
655 static struct db_context *ServiceHash;
656 static int *invalid_services = NULL;
657 static int num_invalid_services = 0;
658 static bool bInGlobalSection = True;
659 static bool bGlobalOnly = False;
660 static int server_role;
661 static int default_server_announce;
662
663 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
664
665 /* prototypes for the special type handlers */
666 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
667 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
668 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
669 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
670 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
671 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
672 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
673 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
674 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
675 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
676 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
677 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
678
679 static void set_server_role(void);
680 static void set_default_server_announce_type(void);
681 static void set_allowed_client_auth(void);
682
683 static void *lp_local_ptr(struct service *service, void *ptr);
684
685 static 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                 return service_ok(iServiceIndex);
6823         }
6824         return true;
6825 }
6826
6827 /**
6828  * load a service from registry and activate it
6829  */
6830 bool process_registry_service(const char *service_name)
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         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6843
6844         if (!smbconf_share_exists(conf_ctx, service_name)) {
6845                 /*
6846                  * Registry does not contain data for this service (yet),
6847                  * but make sure lp_load doesn't return false.
6848                  */
6849                 ret = true;
6850                 goto done;
6851         }
6852
6853         werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6854         if (!W_ERROR_IS_OK(werr)) {
6855                 goto done;
6856         }
6857
6858         ret = process_smbconf_service(service);
6859         if (!ret) {
6860                 goto done;
6861         }
6862
6863         /* store the csn */
6864         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6865
6866 done:
6867         TALLOC_FREE(mem_ctx);
6868         return ret;
6869 }
6870
6871 /*
6872  * process_registry_globals
6873  */
6874 static bool process_registry_globals(void)
6875 {
6876         bool ret;
6877
6878         ret = do_parameter("registry shares", "yes", NULL);
6879         if (!ret) {
6880                 return ret;
6881         }
6882
6883         return process_registry_service(GLOBAL_NAME);
6884 }
6885
6886 bool process_registry_shares(void)
6887 {
6888         WERROR werr;
6889         uint32_t count;
6890         struct smbconf_service **service = NULL;
6891         uint32_t num_shares = 0;
6892         TALLOC_CTX *mem_ctx = talloc_stackframe();
6893         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6894         bool ret = false;
6895
6896         if (conf_ctx == NULL) {
6897                 goto done;
6898         }
6899
6900         werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6901         if (!W_ERROR_IS_OK(werr)) {
6902                 goto done;
6903         }
6904
6905         ret = true;
6906
6907         for (count = 0; count < num_shares; count++) {
6908                 if (strequal(service[count]->name, GLOBAL_NAME)) {
6909                         continue;
6910                 }
6911                 ret = process_smbconf_service(service[count]);
6912                 if (!ret) {
6913                         goto done;
6914                 }
6915         }
6916
6917         /* store the csn */
6918         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6919
6920 done:
6921         TALLOC_FREE(mem_ctx);
6922         return ret;
6923 }
6924
6925 #define MAX_INCLUDE_DEPTH 100
6926
6927 static uint8_t include_depth;
6928
6929 static struct file_lists {
6930         struct file_lists *next;
6931         char *name;
6932         char *subfname;
6933         time_t modtime;
6934 } *file_lists = NULL;
6935
6936 /*******************************************************************
6937  Keep a linked list of all config files so we know when one has changed 
6938  it's date and needs to be reloaded.
6939 ********************************************************************/
6940
6941 static void add_to_file_list(const char *fname, const char *subfname)
6942 {
6943         struct file_lists *f = file_lists;
6944
6945         while (f) {
6946                 if (f->name && !strcmp(f->name, fname))
6947                         break;
6948                 f = f->next;
6949         }
6950
6951         if (!f) {
6952                 f = SMB_MALLOC_P(struct file_lists);
6953                 if (!f)
6954                         return;
6955                 f->next = file_lists;
6956                 f->name = SMB_STRDUP(fname);
6957                 if (!f->name) {
6958                         SAFE_FREE(f);
6959                         return;
6960                 }
6961                 f->subfname = SMB_STRDUP(subfname);
6962                 if (!f->subfname) {
6963                         SAFE_FREE(f);
6964                         return;
6965                 }
6966                 file_lists = f;
6967                 f->modtime = file_modtime(subfname);
6968         } else {
6969                 time_t t = file_modtime(subfname);
6970                 if (t)
6971                         f->modtime = t;
6972         }
6973 }
6974
6975 /**
6976  * Utility function for outsiders to check if we're running on registry.
6977  */
6978 bool lp_config_backend_is_registry(void)
6979 {
6980         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6981 }
6982
6983 /**
6984  * Utility function to check if the config backend is FILE.
6985  */
6986 bool lp_config_backend_is_file(void)
6987 {
6988         return (lp_config_backend() == CONFIG_BACKEND_FILE);
6989 }
6990
6991 /*******************************************************************
6992  Check if a config file has changed date.
6993 ********************************************************************/
6994
6995 bool lp_file_list_changed(void)
6996 {
6997         struct file_lists *f = file_lists;
6998
6999         DEBUG(6, ("lp_file_list_changed()\n"));
7000
7001         if (lp_config_backend_is_registry()) {
7002                 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7003
7004                 if (conf_ctx == NULL) {
7005                         return false;
7006                 }
7007                 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
7008                         DEBUGADD(6, ("registry config changed\n"));
7009                         return true;
7010                 }
7011         }
7012
7013         while (f) {
7014                 char *n2 = NULL;
7015                 time_t mod_time;
7016
7017                 n2 = alloc_sub_basic(get_current_username(),
7018                                     current_user_info.domain,
7019                                     f->name);
7020                 if (!n2) {
7021                         return false;
7022                 }
7023                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
7024                              f->name, n2, ctime(&f->modtime)));
7025
7026                 mod_time = file_modtime(n2);
7027
7028                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
7029                         DEBUGADD(6,
7030                                  ("file %s modified: %s\n", n2,
7031                                   ctime(&mod_time)));
7032                         f->modtime = mod_time;
7033                         SAFE_FREE(f->subfname);
7034                         f->subfname = n2; /* Passing ownership of
7035                                              return from alloc_sub_basic
7036                                              above. */
7037                         return true;
7038                 }
7039                 SAFE_FREE(n2);
7040                 f = f->next;
7041         }
7042         return (False);
7043 }
7044
7045
7046 /***************************************************************************
7047  Run standard_sub_basic on netbios name... needed because global_myname
7048  is not accessed through any lp_ macro.
7049  Note: We must *NOT* use string_set() here as ptr points to global_myname.
7050 ***************************************************************************/
7051
7052 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7053 {
7054         bool ret;
7055         char *netbios_name = alloc_sub_basic(get_current_username(),
7056                                         current_user_info.domain,
7057                                         pszParmValue);
7058
7059         ret = set_global_myname(netbios_name);
7060         SAFE_FREE(netbios_name);
7061         string_set(&Globals.szNetbiosName,global_myname());
7062
7063         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7064                global_myname()));
7065
7066         return ret;
7067 }
7068
7069 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7070 {
7071         if (strcmp(*ptr, pszParmValue) != 0) {
7072                 string_set(ptr, pszParmValue);
7073                 init_iconv();
7074         }
7075         return True;
7076 }
7077
7078
7079
7080 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7081 {
7082         bool ret;
7083         
7084         ret = set_global_myworkgroup(pszParmValue);
7085         string_set(&Globals.szWorkgroup,lp_workgroup());
7086         
7087         return ret;
7088 }
7089
7090 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7091 {
7092         bool ret;
7093         
7094         ret = set_global_scope(pszParmValue);
7095         string_set(&Globals.szNetbiosScope,global_scope());
7096
7097         return ret;
7098 }
7099
7100 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7101 {
7102         TALLOC_FREE(Globals.szNetbiosAliases);
7103         Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7104         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7105 }
7106
7107 /***************************************************************************
7108  Handle the include operation.
7109 ***************************************************************************/
7110 static bool bAllowIncludeRegistry = true;
7111
7112 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7113 {
7114         char *fname;
7115
7116         if (include_depth >= MAX_INCLUDE_DEPTH) {
7117                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7118                           include_depth));
7119                 return false;
7120         }
7121
7122         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7123                 if (!bAllowIncludeRegistry) {
7124                         return true;
7125                 }
7126                 if (bInGlobalSection) {
7127                         bool ret;
7128                         include_depth++;
7129                         ret = process_registry_globals();
7130                         include_depth--;
7131                         return ret;
7132                 } else {
7133                         DEBUG(1, ("\"include = registry\" only effective "
7134                                   "in %s section\n", GLOBAL_NAME));
7135                         return false;
7136                 }
7137         }
7138
7139         fname = alloc_sub_basic(get_current_username(),
7140                                 current_user_info.domain,
7141                                 pszParmValue);
7142
7143         add_to_file_list(pszParmValue, fname);
7144
7145         string_set(ptr, fname);
7146
7147         if (file_exist(fname)) {
7148                 bool ret;
7149                 include_depth++;
7150                 ret = pm_process(fname, do_section, do_parameter, NULL);
7151                 include_depth--;
7152                 SAFE_FREE(fname);
7153                 return ret;
7154         }
7155
7156         DEBUG(2, ("Can't find include file %s\n", fname));
7157         SAFE_FREE(fname);
7158         return true;
7159 }
7160
7161 /***************************************************************************
7162  Handle the interpretation of the copy parameter.
7163 ***************************************************************************/
7164
7165 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7166 {
7167         bool bRetval;
7168         int iTemp;
7169         struct service serviceTemp;
7170
7171         string_set(ptr, pszParmValue);
7172
7173         init_service(&serviceTemp);
7174
7175         bRetval = False;
7176
7177         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7178
7179         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7180                 if (iTemp == iServiceIndex) {
7181                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7182                 } else {
7183                         copy_service(ServicePtrs[iServiceIndex],
7184                                      &serviceTemp,
7185                                      ServicePtrs[iServiceIndex]->copymap);
7186                         bRetval = True;
7187                 }
7188         } else {
7189                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7190                 bRetval = False;
7191         }
7192
7193         free_service(&serviceTemp);
7194         return (bRetval);
7195 }
7196
7197 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7198 {
7199         Globals.ldap_debug_level = lp_int(pszParmValue);
7200         init_ldap_debugging();
7201         return true;
7202 }
7203
7204 /***************************************************************************
7205  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
7206  parameters is:
7207
7208  [global]
7209
7210         idmap uid = 1000-1999
7211         idmap gid = 700-899
7212
7213  We only do simple parsing checks here.  The strings are parsed into useful
7214  structures in the idmap daemon code.
7215
7216 ***************************************************************************/
7217
7218 /* Some lp_ routines to return idmap [ug]id information */
7219
7220 static uid_t idmap_uid_low, idmap_uid_high;
7221 static gid_t idmap_gid_low, idmap_gid_high;
7222
7223 bool lp_idmap_uid(uid_t *low, uid_t *high)
7224 {
7225         if (idmap_uid_low == 0 || idmap_uid_high == 0)
7226                 return False;
7227
7228         if (low)
7229                 *low = idmap_uid_low;
7230
7231         if (high)
7232                 *high = idmap_uid_high;
7233
7234         return True;
7235 }
7236
7237 bool lp_idmap_gid(gid_t *low, gid_t *high)
7238 {
7239         if (idmap_gid_low == 0 || idmap_gid_high == 0)
7240                 return False;
7241
7242         if (low)
7243                 *low = idmap_gid_low;
7244
7245         if (high)
7246                 *high = idmap_gid_high;
7247
7248         return True;
7249 }
7250
7251 /* Do some simple checks on "idmap [ug]id" parameter values */
7252
7253 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7254 {
7255         uint32 low, high;
7256
7257         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7258                 return False;
7259
7260         /* Parse OK */
7261
7262         string_set(ptr, pszParmValue);
7263
7264         idmap_uid_low = low;
7265         idmap_uid_high = high;
7266
7267         return True;
7268 }
7269
7270 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7271 {
7272         uint32 low, high;
7273
7274         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7275                 return False;
7276
7277         /* Parse OK */
7278
7279         string_set(ptr, pszParmValue);
7280
7281         idmap_gid_low = low;
7282         idmap_gid_high = high;
7283
7284         return True;
7285 }
7286
7287 /***************************************************************************
7288  Handle the DEBUG level list.
7289 ***************************************************************************/
7290
7291 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7292 {
7293         string_set(ptr, pszParmValueIn);
7294         return debug_parse_levels(pszParmValueIn);
7295 }
7296
7297 /***************************************************************************
7298  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7299 ***************************************************************************/
7300
7301 static const char *append_ldap_suffix( const char *str )
7302 {
7303         const char *suffix_string;
7304
7305
7306         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7307                                         Globals.szLdapSuffix );
7308         if ( !suffix_string ) {
7309                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7310                 return "";
7311         }
7312
7313         return suffix_string;
7314 }
7315
7316 const char *lp_ldap_machine_suffix(void)
7317 {
7318         if (Globals.szLdapMachineSuffix[0])
7319                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7320
7321         return lp_string(Globals.szLdapSuffix);
7322 }
7323
7324 const char *lp_ldap_user_suffix(void)
7325 {
7326         if (Globals.szLdapUserSuffix[0])
7327                 return append_ldap_suffix(Globals.szLdapUserSuffix);
7328
7329         return lp_string(Globals.szLdapSuffix);
7330 }
7331
7332 const char *lp_ldap_group_suffix(void)
7333 {
7334         if (Globals.szLdapGroupSuffix[0])
7335                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7336
7337         return lp_string(Globals.szLdapSuffix);
7338 }
7339
7340 const char *lp_ldap_idmap_suffix(void)
7341 {
7342         if (Globals.szLdapIdmapSuffix[0])
7343                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7344
7345         return lp_string(Globals.szLdapSuffix);
7346 }
7347
7348 /****************************************************************************
7349  set the value for a P_ENUM
7350  ***************************************************************************/
7351
7352 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7353                               int *ptr )
7354 {
7355         int i;
7356
7357         for (i = 0; parm->enum_list[i].name; i++) {
7358                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7359                         *ptr = parm->enum_list[i].value;
7360                         return;
7361                 }
7362         }
7363         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7364                   pszParmValue, parm->label));
7365 }
7366
7367 /***************************************************************************
7368 ***************************************************************************/
7369
7370 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7371 {
7372         static int parm_num = -1;
7373         struct service *s;
7374
7375         if ( parm_num == -1 )
7376                 parm_num = map_parameter( "printing" );
7377
7378         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7379
7380         if ( snum < 0 )
7381                 s = &sDefault;
7382         else
7383                 s = ServicePtrs[snum];
7384
7385         init_printer_values( s );
7386
7387         return True;
7388 }
7389
7390
7391 /***************************************************************************
7392  Initialise a copymap.
7393 ***************************************************************************/
7394
7395 static void init_copymap(struct service *pservice)
7396 {
7397         int i;
7398         if (pservice->copymap) {
7399                 bitmap_free(pservice->copymap);
7400         }
7401         pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7402         if (!pservice->copymap)
7403                 DEBUG(0,
7404                       ("Couldn't allocate copymap!! (size %d)\n",
7405                        (int)NUMPARAMETERS));
7406         else
7407                 for (i = 0; i < NUMPARAMETERS; i++)
7408                         bitmap_set(pservice->copymap, i);
7409 }
7410
7411 /***************************************************************************
7412  Return the local pointer to a parameter given a service struct and the
7413  pointer into the default structure.
7414 ***************************************************************************/
7415
7416 static void *lp_local_ptr(struct service *service, void *ptr)
7417 {
7418         return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7419 }
7420
7421 /***************************************************************************
7422  Return the local pointer to a parameter given the service number and the 
7423  pointer into the default structure.
7424 ***************************************************************************/
7425
7426 void *lp_local_ptr_by_snum(int snum, void *ptr)
7427 {
7428         return lp_local_ptr(ServicePtrs[snum], ptr);
7429 }
7430
7431 /***************************************************************************
7432  Process a parameter for a particular service number. If snum < 0
7433  then assume we are in the globals.
7434 ***************************************************************************/
7435
7436 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7437 {
7438         int parmnum, i;
7439         void *parm_ptr = NULL;  /* where we are going to store the result */
7440         void *def_ptr = NULL;
7441         struct param_opt_struct **opt_list;
7442
7443         parmnum = map_parameter(pszParmName);
7444
7445         if (parmnum < 0) {
7446                 if (strchr(pszParmName, ':') == NULL) {
7447                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7448                                   pszParmName));
7449                         return (True);
7450                 }
7451
7452                 /*
7453                  * We've got a parametric option
7454                  */
7455
7456                 opt_list = (snum < 0)
7457                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7458                 set_param_opt(opt_list, pszParmName, pszParmValue);
7459
7460                 return (True);
7461         }
7462
7463         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7464                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7465                           pszParmName));
7466         }
7467
7468         def_ptr = parm_table[parmnum].ptr;
7469
7470         /* we might point at a service, the default service or a global */
7471         if (snum < 0) {
7472                 parm_ptr = def_ptr;
7473         } else {
7474                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7475                         DEBUG(0,
7476                               ("Global parameter %s found in service section!\n",
7477                                pszParmName));
7478                         return (True);
7479                 }
7480                 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7481         }
7482
7483         if (snum >= 0) {
7484                 if (!ServicePtrs[snum]->copymap)
7485                         init_copymap(ServicePtrs[snum]);
7486
7487                 /* this handles the aliases - set the copymap for other entries with
7488                    the same data pointer */
7489                 for (i = 0; parm_table[i].label; i++)
7490                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7491                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7492         }
7493
7494         /* if it is a special case then go ahead */
7495         if (parm_table[parmnum].special) {
7496                 return parm_table[parmnum].special(snum, pszParmValue,
7497                                                    (char **)parm_ptr);
7498         }
7499
7500         /* now switch on the type of variable it is */
7501         switch (parm_table[parmnum].type)
7502         {
7503                 case P_BOOL:
7504                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7505                         break;
7506
7507                 case P_BOOLREV:
7508                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7509                         break;
7510
7511                 case P_INTEGER:
7512                         *(int *)parm_ptr = lp_int(pszParmValue);
7513                         break;
7514
7515                 case P_CHAR:
7516                         *(char *)parm_ptr = *pszParmValue;
7517                         break;
7518
7519                 case P_OCTAL:
7520                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7521                         if ( i != 1 ) {
7522                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7523                         }
7524                         break;
7525
7526                 case P_LIST:
7527                         TALLOC_FREE(*((char ***)parm_ptr));
7528                         *(char ***)parm_ptr = str_list_make_v3(
7529                                 talloc_autofree_context(), pszParmValue, NULL);
7530                         break;
7531
7532                 case P_STRING:
7533                         string_set((char **)parm_ptr, pszParmValue);
7534                         break;
7535
7536                 case P_USTRING:
7537                         string_set((char **)parm_ptr, pszParmValue);
7538                         strupper_m(*(char **)parm_ptr);
7539                         break;
7540
7541                 case P_ENUM:
7542                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7543                         break;
7544                 case P_SEP:
7545                         break;
7546         }
7547
7548         return (True);
7549 }
7550
7551 /***************************************************************************
7552  Process a parameter.
7553 ***************************************************************************/
7554
7555 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7556                          void *userdata)
7557 {
7558         if (!bInGlobalSection && bGlobalOnly)
7559                 return (True);
7560
7561         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7562
7563         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7564                                 pszParmName, pszParmValue));
7565 }
7566
7567 /***************************************************************************
7568  Print a parameter of the specified type.
7569 ***************************************************************************/
7570
7571 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7572 {
7573         int i;
7574         switch (p->type)
7575         {
7576                 case P_ENUM:
7577                         for (i = 0; p->enum_list[i].name; i++) {
7578                                 if (*(int *)ptr == p->enum_list[i].value) {
7579                                         fprintf(f, "%s",
7580                                                 p->enum_list[i].name);
7581                                         break;
7582                                 }
7583                         }
7584                         break;
7585
7586                 case P_BOOL:
7587                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7588                         break;
7589
7590                 case P_BOOLREV:
7591                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7592                         break;
7593
7594                 case P_INTEGER:
7595                         fprintf(f, "%d", *(int *)ptr);
7596                         break;
7597
7598                 case P_CHAR:
7599                         fprintf(f, "%c", *(char *)ptr);
7600                         break;
7601
7602                 case P_OCTAL: {
7603                         char *o = octal_string(*(int *)ptr);
7604                         fprintf(f, "%s", o);
7605                         TALLOC_FREE(o);
7606                         break;
7607                 }
7608
7609                 case P_LIST:
7610                         if ((char ***)ptr && *(char ***)ptr) {
7611                                 char **list = *(char ***)ptr;
7612                                 for (; *list; list++) {
7613                                         /* surround strings with whitespace in double quotes */
7614                                         if ( strchr_m( *list, ' ' ) )
7615                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7616                                         else
7617                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7618                                 }
7619                         }
7620                         break;
7621
7622                 case P_STRING:
7623                 case P_USTRING:
7624                         if (*(char **)ptr) {
7625                                 fprintf(f, "%s", *(char **)ptr);
7626                         }
7627                         break;
7628                 case P_SEP:
7629                         break;
7630         }
7631 }
7632
7633 /***************************************************************************
7634  Check if two parameters are equal.
7635 ***************************************************************************/
7636
7637 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7638 {
7639         switch (type) {
7640                 case P_BOOL:
7641                 case P_BOOLREV:
7642                         return (*((bool *)ptr1) == *((bool *)ptr2));
7643
7644                 case P_INTEGER:
7645                 case P_ENUM:
7646                 case P_OCTAL:
7647                         return (*((int *)ptr1) == *((int *)ptr2));
7648
7649                 case P_CHAR:
7650                         return (*((char *)ptr1) == *((char *)ptr2));
7651
7652                 case P_LIST:
7653                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7654
7655                 case P_STRING:
7656                 case P_USTRING:
7657                 {
7658                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7659                         if (p1 && !*p1)
7660                                 p1 = NULL;
7661                         if (p2 && !*p2)
7662                                 p2 = NULL;
7663                         return (p1 == p2 || strequal(p1, p2));
7664                 }
7665                 case P_SEP:
7666                         break;
7667         }
7668         return (False);
7669 }
7670
7671 /***************************************************************************
7672  Initialize any local varients in the sDefault table.
7673 ***************************************************************************/
7674
7675 void init_locals(void)
7676 {
7677         /* None as yet. */
7678 }
7679
7680 /***************************************************************************
7681  Process a new section (service). At this stage all sections are services.
7682  Later we'll have special sections that permit server parameters to be set.
7683  Returns True on success, False on failure. 
7684 ***************************************************************************/
7685
7686 static bool do_section(const char *pszSectionName, void *userdata)
7687 {
7688         bool bRetval;
7689         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7690                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7691         bRetval = False;
7692
7693         /* if we were in a global section then do the local inits */
7694         if (bInGlobalSection && !isglobal)
7695                 init_locals();
7696
7697         /* if we've just struck a global section, note the fact. */
7698         bInGlobalSection = isglobal;
7699
7700         /* check for multiple global sections */
7701         if (bInGlobalSection) {
7702                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7703                 return (True);
7704         }
7705
7706         if (!bInGlobalSection && bGlobalOnly)
7707                 return (True);
7708
7709         /* if we have a current service, tidy it up before moving on */
7710         bRetval = True;
7711
7712         if (iServiceIndex >= 0)
7713                 bRetval = service_ok(iServiceIndex);
7714
7715         /* if all is still well, move to the next record in the services array */
7716         if (bRetval) {
7717                 /* We put this here to avoid an odd message order if messages are */
7718                 /* issued by the post-processing of a previous section. */
7719                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7720
7721                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7722                     < 0) {
7723                         DEBUG(0, ("Failed to add a new service\n"));
7724                         return (False);
7725                 }
7726         }
7727
7728         return (bRetval);
7729 }
7730
7731
7732 /***************************************************************************
7733  Determine if a partcular base parameter is currentl set to the default value.
7734 ***************************************************************************/
7735
7736 static bool is_default(int i)
7737 {
7738         if (!defaults_saved)
7739                 return False;
7740         switch (parm_table[i].type) {
7741                 case P_LIST:
7742                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
7743                                                 *(const char ***)parm_table[i].ptr);
7744                 case P_STRING:
7745                 case P_USTRING:
7746                         return strequal(parm_table[i].def.svalue,
7747                                         *(char **)parm_table[i].ptr);
7748                 case P_BOOL:
7749                 case P_BOOLREV:
7750                         return parm_table[i].def.bvalue ==
7751                                 *(bool *)parm_table[i].ptr;
7752                 case P_CHAR:
7753                         return parm_table[i].def.cvalue ==
7754                                 *(char *)parm_table[i].ptr;
7755                 case P_INTEGER:
7756                 case P_OCTAL:
7757                 case P_ENUM:
7758                         return parm_table[i].def.ivalue ==
7759                                 *(int *)parm_table[i].ptr;
7760                 case P_SEP:
7761                         break;
7762         }
7763         return False;
7764 }
7765
7766 /***************************************************************************
7767 Display the contents of the global structure.
7768 ***************************************************************************/
7769
7770 static void dump_globals(FILE *f)
7771 {
7772         int i;
7773         struct param_opt_struct *data;
7774         
7775         fprintf(f, "[global]\n");
7776
7777         for (i = 0; parm_table[i].label; i++)
7778                 if (parm_table[i].p_class == P_GLOBAL &&
7779                     parm_table[i].ptr &&
7780                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7781                         if (defaults_saved && is_default(i))
7782                                 continue;
7783                         fprintf(f, "\t%s = ", parm_table[i].label);
7784                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
7785                         fprintf(f, "\n");
7786         }
7787         if (Globals.param_opt != NULL) {
7788                 data = Globals.param_opt;
7789                 while(data) {
7790                         fprintf(f, "\t%s = %s\n", data->key, data->value);
7791                         data = data->next;
7792                 }
7793         }
7794
7795 }
7796
7797 /***************************************************************************
7798  Return True if a local parameter is currently set to the global default.
7799 ***************************************************************************/
7800
7801 bool lp_is_default(int snum, struct parm_struct *parm)
7802 {
7803         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7804
7805         return equal_parameter(parm->type,
7806                                ((char *)ServicePtrs[snum]) + pdiff,
7807                                ((char *)&sDefault) + pdiff);
7808 }
7809
7810 /***************************************************************************
7811  Display the contents of a single services record.
7812 ***************************************************************************/
7813
7814 static void dump_a_service(struct service *pService, FILE * f)
7815 {
7816         int i;
7817         struct param_opt_struct *data;
7818         
7819         if (pService != &sDefault)
7820                 fprintf(f, "[%s]\n", pService->szService);
7821
7822         for (i = 0; parm_table[i].label; i++) {
7823
7824                 if (parm_table[i].p_class == P_LOCAL &&
7825                     parm_table[i].ptr &&
7826                     (*parm_table[i].label != '-') &&
7827                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7828                 {
7829                 
7830                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7831
7832                         if (pService == &sDefault) {
7833                                 if (defaults_saved && is_default(i))
7834                                         continue;
7835                         } else {
7836                                 if (equal_parameter(parm_table[i].type,
7837                                                     ((char *)pService) +
7838                                                     pdiff,
7839                                                     ((char *)&sDefault) +
7840                                                     pdiff))
7841                                         continue;
7842                         }
7843
7844                         fprintf(f, "\t%s = ", parm_table[i].label);
7845                         print_parameter(&parm_table[i],
7846                                         ((char *)pService) + pdiff, f);
7847                         fprintf(f, "\n");
7848                 }
7849         }
7850
7851                 if (pService->param_opt != NULL) {
7852                         data = pService->param_opt;
7853                         while(data) {
7854                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
7855                                 data = data->next;
7856                         }
7857                 }
7858 }
7859
7860 /***************************************************************************
7861  Display the contents of a parameter of a single services record.
7862 ***************************************************************************/
7863
7864 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7865 {
7866         int i;
7867         bool result = False;
7868         parm_class p_class;
7869         unsigned flag = 0;
7870         fstring local_parm_name;
7871         char *parm_opt;
7872         const char *parm_opt_value;
7873
7874         /* check for parametrical option */
7875         fstrcpy( local_parm_name, parm_name);
7876         parm_opt = strchr( local_parm_name, ':');
7877
7878         if (parm_opt) {
7879                 *parm_opt = '\0';
7880                 parm_opt++;
7881                 if (strlen(parm_opt)) {
7882                         parm_opt_value = lp_parm_const_string( snum,
7883                                 local_parm_name, parm_opt, NULL);
7884                         if (parm_opt_value) {
7885                                 printf( "%s\n", parm_opt_value);
7886                                 result = True;
7887                         }
7888                 }
7889                 return result;
7890         }
7891
7892         /* check for a key and print the value */
7893         if (isGlobal) {
7894                 p_class = P_GLOBAL;
7895                 flag = FLAG_GLOBAL;
7896         } else
7897                 p_class = P_LOCAL;
7898
7899         for (i = 0; parm_table[i].label; i++) {
7900                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7901                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7902                     parm_table[i].ptr &&
7903                     (*parm_table[i].label != '-') &&
7904                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7905                 {
7906                         void *ptr;
7907
7908                         if (isGlobal) {
7909                                 ptr = parm_table[i].ptr;
7910                         } else {
7911                                 struct service *pService = ServicePtrs[snum];
7912                                 ptr = ((char *)pService) +
7913                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
7914                         }
7915
7916                         print_parameter(&parm_table[i],
7917                                         ptr, f);
7918                         fprintf(f, "\n");
7919                         result = True;
7920                         break;
7921                 }
7922         }
7923
7924         return result;
7925 }
7926
7927 /***************************************************************************
7928  Return info about the requested parameter (given as a string).
7929  Return NULL when the string is not a valid parameter name.
7930 ***************************************************************************/
7931
7932 struct parm_struct *lp_get_parameter(const char *param_name)
7933 {
7934         int num = map_parameter(param_name);
7935
7936         if (num < 0) {
7937                 return NULL;
7938         }
7939
7940         return &parm_table[num];
7941 }
7942
7943 /***************************************************************************
7944  Return info about the next parameter in a service.
7945  snum==GLOBAL_SECTION_SNUM gives the globals.
7946  Return NULL when out of parameters.
7947 ***************************************************************************/
7948
7949 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7950 {
7951         if (snum < 0) {
7952                 /* do the globals */
7953                 for (; parm_table[*i].label; (*i)++) {
7954                         if (parm_table[*i].p_class == P_SEPARATOR)
7955                                 return &parm_table[(*i)++];
7956
7957                         if (!parm_table[*i].ptr
7958                             || (*parm_table[*i].label == '-'))
7959                                 continue;
7960
7961                         if ((*i) > 0
7962                             && (parm_table[*i].ptr ==
7963                                 parm_table[(*i) - 1].ptr))
7964                                 continue;
7965                         
7966                         if (is_default(*i) && !allparameters)
7967                                 continue;
7968
7969                         return &parm_table[(*i)++];
7970                 }
7971         } else {
7972                 struct service *pService = ServicePtrs[snum];
7973
7974                 for (; parm_table[*i].label; (*i)++) {
7975                         if (parm_table[*i].p_class == P_SEPARATOR)
7976                                 return &parm_table[(*i)++];
7977
7978                         if (parm_table[*i].p_class == P_LOCAL &&
7979                             parm_table[*i].ptr &&
7980                             (*parm_table[*i].label != '-') &&
7981                             ((*i) == 0 ||
7982                              (parm_table[*i].ptr !=
7983                               parm_table[(*i) - 1].ptr)))
7984                         {
7985                                 int pdiff =
7986                                         PTR_DIFF(parm_table[*i].ptr,
7987                                                  &sDefault);
7988
7989                                 if (allparameters ||
7990                                     !equal_parameter(parm_table[*i].type,
7991                                                      ((char *)pService) +
7992                                                      pdiff,
7993                                                      ((char *)&sDefault) +
7994                                                      pdiff))
7995                                 {
7996                                         return &parm_table[(*i)++];
7997                                 }
7998                         }
7999                 }
8000         }
8001
8002         return NULL;
8003 }
8004
8005
8006 #if 0
8007 /***************************************************************************
8008  Display the contents of a single copy structure.
8009 ***************************************************************************/
8010 static void dump_copy_map(bool *pcopymap)
8011 {
8012         int i;
8013         if (!pcopymap)
8014                 return;
8015
8016         printf("\n\tNon-Copied parameters:\n");
8017
8018         for (i = 0; parm_table[i].label; i++)
8019                 if (parm_table[i].p_class == P_LOCAL &&
8020                     parm_table[i].ptr && !pcopymap[i] &&
8021                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8022                 {
8023                         printf("\t\t%s\n", parm_table[i].label);
8024                 }
8025 }
8026 #endif
8027
8028 /***************************************************************************
8029  Return TRUE if the passed service number is within range.
8030 ***************************************************************************/
8031
8032 bool lp_snum_ok(int iService)
8033 {
8034         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8035 }
8036
8037 /***************************************************************************
8038  Auto-load some home services.
8039 ***************************************************************************/
8040
8041 static void lp_add_auto_services(char *str)
8042 {
8043         char *s;
8044         char *p;
8045         int homes;
8046         char *saveptr;
8047
8048         if (!str)
8049                 return;
8050
8051         s = SMB_STRDUP(str);
8052         if (!s)
8053                 return;
8054
8055         homes = lp_servicenumber(HOMES_NAME);
8056
8057         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8058              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8059                 char *home;
8060
8061                 if (lp_servicenumber(p) >= 0)
8062                         continue;
8063
8064                 home = get_user_home_dir(talloc_tos(), p);
8065
8066                 if (home && homes >= 0)
8067                         lp_add_home(p, homes, p, home);
8068
8069                 TALLOC_FREE(home);
8070         }
8071         SAFE_FREE(s);
8072 }
8073
8074 /***************************************************************************
8075  Auto-load one printer.
8076 ***************************************************************************/
8077
8078 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8079 {
8080         int printers = lp_servicenumber(PRINTERS_NAME);
8081         int i;
8082
8083         if (lp_servicenumber(name) < 0) {
8084                 lp_add_printer(name, printers);
8085                 if ((i = lp_servicenumber(name)) >= 0) {
8086                         string_set(&ServicePtrs[i]->comment, comment);
8087                         ServicePtrs[i]->autoloaded = True;
8088                 }
8089         }
8090 }
8091
8092 /***************************************************************************
8093  Have we loaded a services file yet?
8094 ***************************************************************************/
8095
8096 bool lp_loaded(void)
8097 {
8098         return (bLoaded);
8099 }
8100
8101 /***************************************************************************
8102  Unload unused services.
8103 ***************************************************************************/
8104
8105 void lp_killunused(bool (*snumused) (int))
8106 {
8107         int i;
8108         for (i = 0; i < iNumServices; i++) {
8109                 if (!VALID(i))
8110                         continue;
8111
8112                 /* don't kill autoloaded or usershare services */
8113                 if ( ServicePtrs[i]->autoloaded ||
8114                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8115                         continue;
8116                 }
8117
8118                 if (!snumused || !snumused(i)) {
8119                         free_service_byindex(i);
8120                 }
8121         }
8122 }
8123
8124 /**
8125  * Kill all except autoloaded and usershare services - convenience wrapper
8126  */
8127 void lp_kill_all_services(void)
8128 {
8129         lp_killunused(NULL);
8130 }
8131
8132 /***************************************************************************
8133  Unload a service.
8134 ***************************************************************************/
8135
8136 void lp_killservice(int iServiceIn)
8137 {
8138         if (VALID(iServiceIn)) {
8139                 free_service_byindex(iServiceIn);
8140         }
8141 }
8142
8143 /***************************************************************************
8144  Save the curent values of all global and sDefault parameters into the 
8145  defaults union. This allows swat and testparm to show only the
8146  changed (ie. non-default) parameters.
8147 ***************************************************************************/
8148
8149 static void lp_save_defaults(void)
8150 {
8151         int i;
8152         for (i = 0; parm_table[i].label; i++) {
8153                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8154                         continue;
8155                 switch (parm_table[i].type) {
8156                         case P_LIST:
8157                                 parm_table[i].def.lvalue = str_list_copy(
8158                                         NULL, *(const char ***)parm_table[i].ptr);
8159                                 break;
8160                         case P_STRING:
8161                         case P_USTRING:
8162                                 if (parm_table[i].ptr) {
8163                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8164                                 } else {
8165                                         parm_table[i].def.svalue = NULL;
8166                                 }
8167                                 break;
8168                         case P_BOOL:
8169                         case P_BOOLREV:
8170                                 parm_table[i].def.bvalue =
8171                                         *(bool *)parm_table[i].ptr;
8172                                 break;
8173                         case P_CHAR:
8174                                 parm_table[i].def.cvalue =
8175                                         *(char *)parm_table[i].ptr;
8176                                 break;
8177                         case P_INTEGER:
8178                         case P_OCTAL:
8179                         case P_ENUM:
8180                                 parm_table[i].def.ivalue =
8181                                         *(int *)parm_table[i].ptr;
8182                                 break;
8183                         case P_SEP:
8184                                 break;
8185                 }
8186         }
8187         defaults_saved = True;
8188 }
8189
8190 /*******************************************************************
8191  Set the server type we will announce as via nmbd.
8192 ********************************************************************/
8193
8194 static const struct srv_role_tab {
8195         uint32 role;
8196         const char *role_str;
8197 } srv_role_tab [] = {
8198         { ROLE_STANDALONE, "ROLE_STANDALONE" },
8199         { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8200         { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8201         { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8202         { 0, NULL }
8203 };
8204
8205 const char* server_role_str(uint32 role)
8206 {
8207         int i = 0;
8208         for (i=0; srv_role_tab[i].role_str; i++) {
8209                 if (role == srv_role_tab[i].role) {
8210                         return srv_role_tab[i].role_str;
8211                 }
8212         }
8213         return NULL;
8214 }
8215
8216 static void set_server_role(void)
8217 {
8218         server_role = ROLE_STANDALONE;
8219
8220         switch (lp_security()) {
8221                 case SEC_SHARE:
8222                         if (lp_domain_logons())
8223                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8224                         break;
8225                 case SEC_SERVER:
8226                         if (lp_domain_logons())
8227                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8228                         /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8229                         server_role = ROLE_STANDALONE;
8230                         break;
8231                 case SEC_DOMAIN:
8232                         if (lp_domain_logons()) {
8233                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8234                                 server_role = ROLE_DOMAIN_BDC;
8235                                 break;
8236                         }
8237                         server_role = ROLE_DOMAIN_MEMBER;
8238                         break;
8239                 case SEC_ADS:
8240                         if (lp_domain_logons()) {
8241                                 server_role = ROLE_DOMAIN_PDC;
8242                                 break;
8243                         }
8244                         server_role = ROLE_DOMAIN_MEMBER;
8245                         break;
8246                 case SEC_USER:
8247                         if (lp_domain_logons()) {
8248
8249                                 if (Globals.iDomainMaster) /* auto or yes */ 
8250                                         server_role = ROLE_DOMAIN_PDC;
8251                                 else
8252                                         server_role = ROLE_DOMAIN_BDC;
8253                         }
8254                         break;
8255                 default:
8256                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8257                         break;
8258         }
8259
8260         DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8261 }
8262
8263 /***********************************************************
8264  If we should send plaintext/LANMAN passwords in the clinet
8265 ************************************************************/
8266
8267 static void set_allowed_client_auth(void)
8268 {
8269         if (Globals.bClientNTLMv2Auth) {
8270                 Globals.bClientLanManAuth = False;
8271         }
8272         if (!Globals.bClientLanManAuth) {
8273                 Globals.bClientPlaintextAuth = False;
8274         }
8275 }
8276
8277 /***************************************************************************
8278  JRA.
8279  The following code allows smbd to read a user defined share file.
8280  Yes, this is my intent. Yes, I'm comfortable with that...
8281
8282  THE FOLLOWING IS SECURITY CRITICAL CODE.
8283
8284  It washes your clothes, it cleans your house, it guards you while you sleep...
8285  Do not f%^k with it....
8286 ***************************************************************************/
8287
8288 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8289
8290 /***************************************************************************
8291  Check allowed stat state of a usershare file.
8292  Ensure we print out who is dicking with us so the admin can
8293  get their sorry ass fired.
8294 ***************************************************************************/
8295
8296 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8297 {
8298         if (!S_ISREG(psbuf->st_mode)) {
8299                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8300                         "not a regular file\n",
8301                         fname, (unsigned int)psbuf->st_uid ));
8302                 return False;
8303         }
8304
8305         /* Ensure this doesn't have the other write bit set. */
8306         if (psbuf->st_mode & S_IWOTH) {
8307                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8308                         "public write. Refusing to allow as a usershare file.\n",
8309                         fname, (unsigned int)psbuf->st_uid ));
8310                 return False;
8311         }
8312
8313         /* Should be 10k or less. */
8314         if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8315                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8316                         "too large (%u) to be a user share file.\n",
8317                         fname, (unsigned int)psbuf->st_uid,
8318                         (unsigned int)psbuf->st_size ));
8319                 return False;
8320         }
8321
8322         return True;
8323 }
8324
8325 /***************************************************************************
8326  Parse the contents of a usershare file.
8327 ***************************************************************************/
8328
8329 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8330                         SMB_STRUCT_STAT *psbuf,
8331                         const char *servicename,
8332                         int snum,
8333                         char **lines,
8334                         int numlines,
8335                         char **pp_sharepath,
8336                         char **pp_comment,
8337                         SEC_DESC **ppsd,
8338                         bool *pallow_guest)
8339 {
8340         const char **prefixallowlist = lp_usershare_prefix_allow_list();
8341         const char **prefixdenylist = lp_usershare_prefix_deny_list();
8342         int us_vers;
8343         SMB_STRUCT_DIR *dp;
8344         SMB_STRUCT_STAT sbuf;
8345         char *sharepath = NULL;
8346         char *comment = NULL;
8347
8348         *pp_sharepath = NULL;
8349         *pp_comment = NULL;
8350
8351         *pallow_guest = False;
8352
8353         if (numlines < 4) {
8354                 return USERSHARE_MALFORMED_FILE;
8355         }
8356
8357         if (strcmp(lines[0], "#VERSION 1") == 0) {
8358                 us_vers = 1;
8359         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8360                 us_vers = 2;
8361                 if (numlines < 5) {
8362                         return USERSHARE_MALFORMED_FILE;
8363                 }
8364         } else {
8365                 return USERSHARE_BAD_VERSION;
8366         }
8367
8368         if (strncmp(lines[1], "path=", 5) != 0) {
8369                 return USERSHARE_MALFORMED_PATH;
8370         }
8371
8372         sharepath = talloc_strdup(ctx, &lines[1][5]);
8373         if (!sharepath) {
8374                 return USERSHARE_POSIX_ERR;
8375         }
8376         trim_string(sharepath, " ", " ");
8377
8378         if (strncmp(lines[2], "comment=", 8) != 0) {
8379                 return USERSHARE_MALFORMED_COMMENT_DEF;
8380         }
8381
8382         comment = talloc_strdup(ctx, &lines[2][8]);
8383         if (!comment) {
8384                 return USERSHARE_POSIX_ERR;
8385         }
8386         trim_string(comment, " ", " ");
8387         trim_char(comment, '"', '"');
8388
8389         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8390                 return USERSHARE_MALFORMED_ACL_DEF;
8391         }
8392
8393         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8394                 return USERSHARE_ACL_ERR;
8395         }
8396
8397         if (us_vers == 2) {
8398                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8399                         return USERSHARE_MALFORMED_ACL_DEF;
8400                 }
8401                 if (lines[4][9] == 'y') {
8402                         *pallow_guest = True;
8403                 }
8404         }
8405
8406         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8407                 /* Path didn't change, no checks needed. */
8408                 *pp_sharepath = sharepath;
8409                 *pp_comment = comment;
8410                 return USERSHARE_OK;
8411         }
8412
8413         /* The path *must* be absolute. */
8414         if (sharepath[0] != '/') {
8415                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8416                         servicename, sharepath));
8417                 return USERSHARE_PATH_NOT_ABSOLUTE;
8418         }
8419
8420         /* If there is a usershare prefix deny list ensure one of these paths
8421            doesn't match the start of the user given path. */
8422         if (prefixdenylist) {
8423                 int i;
8424                 for ( i=0; prefixdenylist[i]; i++ ) {
8425                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8426                                 servicename, i, prefixdenylist[i], sharepath ));
8427                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8428                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8429                                         "usershare prefix deny list entries.\n",
8430                                         servicename, sharepath));
8431                                 return USERSHARE_PATH_IS_DENIED;
8432                         }
8433                 }
8434         }
8435
8436         /* If there is a usershare prefix allow list ensure one of these paths
8437            does match the start of the user given path. */
8438
8439         if (prefixallowlist) {
8440                 int i;
8441                 for ( i=0; prefixallowlist[i]; i++ ) {
8442                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8443                                 servicename, i, prefixallowlist[i], sharepath ));
8444                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8445                                 break;
8446                         }
8447                 }
8448                 if (prefixallowlist[i] == NULL) {
8449                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8450                                 "usershare prefix allow list entries.\n",
8451                                 servicename, sharepath));
8452                         return USERSHARE_PATH_NOT_ALLOWED;
8453                 }
8454         }
8455
8456         /* Ensure this is pointing to a directory. */
8457         dp = sys_opendir(sharepath);
8458
8459         if (!dp) {
8460                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8461                         servicename, sharepath));
8462                 return USERSHARE_PATH_NOT_DIRECTORY;
8463         }
8464
8465         /* Ensure the owner of the usershare file has permission to share
8466            this directory. */
8467
8468         if (sys_stat(sharepath, &sbuf) == -1) {
8469                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8470                         servicename, sharepath, strerror(errno) ));
8471                 sys_closedir(dp);
8472                 return USERSHARE_POSIX_ERR;
8473         }
8474
8475         sys_closedir(dp);
8476
8477         if (!S_ISDIR(sbuf.st_mode)) {
8478                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8479                         servicename, sharepath ));
8480                 return USERSHARE_PATH_NOT_DIRECTORY;
8481         }
8482
8483         /* Check if sharing is restricted to owner-only. */
8484         /* psbuf is the stat of the usershare definition file,
8485            sbuf is the stat of the target directory to be shared. */
8486
8487         if (lp_usershare_owner_only()) {
8488                 /* root can share anything. */
8489                 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8490                         return USERSHARE_PATH_NOT_ALLOWED;
8491                 }
8492         }
8493
8494         *pp_sharepath = sharepath;
8495         *pp_comment = comment;
8496         return USERSHARE_OK;
8497 }
8498
8499 /***************************************************************************
8500  Deal with a usershare file.
8501  Returns:
8502         >= 0 - snum
8503         -1 - Bad name, invalid contents.
8504            - service name already existed and not a usershare, problem
8505             with permissions to share directory etc.
8506 ***************************************************************************/
8507
8508 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8509 {
8510         SMB_STRUCT_STAT sbuf;
8511         SMB_STRUCT_STAT lsbuf;
8512         char *fname = NULL;
8513         char *sharepath = NULL;
8514         char *comment = NULL;
8515         fstring service_name;
8516         char **lines = NULL;
8517         int numlines = 0;
8518         int fd = -1;
8519         int iService = -1;
8520         TALLOC_CTX *ctx = NULL;
8521         SEC_DESC *psd = NULL;
8522         bool guest_ok = False;
8523
8524         /* Ensure share name doesn't contain invalid characters. */
8525         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8526                 DEBUG(0,("process_usershare_file: share name %s contains "
8527                         "invalid characters (any of %s)\n",
8528                         file_name, INVALID_SHARENAME_CHARS ));
8529                 return -1;
8530         }
8531
8532         fstrcpy(service_name, file_name);
8533
8534         if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8535         }
8536
8537         /* Minimize the race condition by doing an lstat before we
8538            open and fstat. Ensure this isn't a symlink link. */
8539
8540         if (sys_lstat(fname, &lsbuf) != 0) {
8541                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8542                         fname, strerror(errno) ));
8543                 SAFE_FREE(fname);
8544                 return -1;
8545         }
8546
8547         /* This must be a regular file, not a symlink, directory or
8548            other strange filetype. */
8549         if (!check_usershare_stat(fname, &lsbuf)) {
8550                 SAFE_FREE(fname);
8551                 return -1;
8552         }
8553
8554         {
8555                 char *canon_name = canonicalize_servicename(service_name);
8556                 TDB_DATA data = dbwrap_fetch_bystring(
8557                         ServiceHash, canon_name, canon_name);
8558
8559                 iService = -1;
8560
8561                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8562                         iService = *(int *)data.dptr;
8563                 }
8564                 TALLOC_FREE(canon_name);
8565         }
8566
8567         if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8568                 /* Nothing changed - Mark valid and return. */
8569                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8570                         service_name ));
8571                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8572                 SAFE_FREE(fname);
8573                 return iService;
8574         }
8575
8576         /* Try and open the file read only - no symlinks allowed. */
8577 #ifdef O_NOFOLLOW
8578         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8579 #else
8580         fd = sys_open(fname, O_RDONLY, 0);
8581 #endif
8582
8583         if (fd == -1) {
8584                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8585                         fname, strerror(errno) ));
8586                 SAFE_FREE(fname);
8587                 return -1;
8588         }
8589
8590         /* Now fstat to be *SURE* it's a regular file. */
8591         if (sys_fstat(fd, &sbuf) != 0) {
8592                 close(fd);
8593                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8594                         fname, strerror(errno) ));
8595                 SAFE_FREE(fname);
8596                 return -1;
8597         }
8598
8599         /* Is it the same dev/inode as was lstated ? */
8600         if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8601                 close(fd);
8602                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8603                         "Symlink spoofing going on ?\n", fname ));
8604                 SAFE_FREE(fname);
8605                 return -1;
8606         }
8607
8608         /* This must be a regular file, not a symlink, directory or
8609            other strange filetype. */
8610         if (!check_usershare_stat(fname, &sbuf)) {
8611                 SAFE_FREE(fname);
8612                 return -1;
8613         }
8614
8615         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8616
8617         close(fd);
8618         if (lines == NULL) {
8619                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8620                         fname, (unsigned int)sbuf.st_uid ));
8621                 SAFE_FREE(fname);
8622                 return -1;
8623         }
8624
8625         SAFE_FREE(fname);
8626
8627         /* Should we allow printers to be shared... ? */
8628         ctx = talloc_init("usershare_sd_xctx");
8629         if (!ctx) {
8630                 TALLOC_FREE(lines);
8631                 return 1;
8632         }
8633
8634         if (parse_usershare_file(ctx, &sbuf, service_name,
8635                         iService, lines, numlines, &sharepath,
8636                         &comment, &psd, &guest_ok) != USERSHARE_OK) {
8637                 talloc_destroy(ctx);
8638                 TALLOC_FREE(lines);
8639                 return -1;
8640         }
8641
8642         TALLOC_FREE(lines);
8643
8644         /* Everything ok - add the service possibly using a template. */
8645         if (iService < 0) {
8646                 const struct service *sp = &sDefault;
8647                 if (snum_template != -1) {
8648                         sp = ServicePtrs[snum_template];
8649                 }
8650
8651                 if ((iService = add_a_service(sp, service_name)) < 0) {
8652                         DEBUG(0, ("process_usershare_file: Failed to add "
8653                                 "new service %s\n", service_name));
8654                         talloc_destroy(ctx);
8655                         return -1;
8656                 }
8657
8658                 /* Read only is controlled by usershare ACL below. */
8659                 ServicePtrs[iService]->bRead_only = False;
8660         }
8661
8662         /* Write the ACL of the new/modified share. */
8663         if (!set_share_security(service_name, psd)) {
8664                  DEBUG(0, ("process_usershare_file: Failed to set share "
8665                         "security for user share %s\n",
8666                         service_name ));
8667                 lp_remove_service(iService);
8668                 talloc_destroy(ctx);
8669                 return -1;
8670         }
8671
8672         /* If from a template it may be marked invalid. */
8673         ServicePtrs[iService]->valid = True;
8674
8675         /* Set the service as a valid usershare. */
8676         ServicePtrs[iService]->usershare = USERSHARE_VALID;
8677
8678         /* Set guest access. */
8679         if (lp_usershare_allow_guests()) {
8680                 ServicePtrs[iService]->bGuest_ok = guest_ok;
8681         }
8682
8683         /* And note when it was loaded. */
8684         ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8685         string_set(&ServicePtrs[iService]->szPath, sharepath);
8686         string_set(&ServicePtrs[iService]->comment, comment);
8687
8688         talloc_destroy(ctx);
8689
8690         return iService;
8691 }
8692
8693 /***************************************************************************
8694  Checks if a usershare entry has been modified since last load.
8695 ***************************************************************************/
8696
8697 static bool usershare_exists(int iService, time_t *last_mod)
8698 {
8699         SMB_STRUCT_STAT lsbuf;
8700         const char *usersharepath = Globals.szUsersharePath;
8701         char *fname;
8702
8703         if (asprintf(&fname, "%s/%s",
8704                                 usersharepath,
8705                                 ServicePtrs[iService]->szService) < 0) {
8706                 return false;
8707         }
8708
8709         if (sys_lstat(fname, &lsbuf) != 0) {
8710                 SAFE_FREE(fname);
8711                 return false;
8712         }
8713
8714         if (!S_ISREG(lsbuf.st_mode)) {
8715                 SAFE_FREE(fname);
8716                 return false;
8717         }
8718
8719         SAFE_FREE(fname);
8720         *last_mod = lsbuf.st_mtime;
8721         return true;
8722 }
8723
8724 /***************************************************************************
8725  Load a usershare service by name. Returns a valid servicenumber or -1.
8726 ***************************************************************************/
8727
8728 int load_usershare_service(const char *servicename)
8729 {
8730         SMB_STRUCT_STAT sbuf;
8731         const char *usersharepath = Globals.szUsersharePath;
8732         int max_user_shares = Globals.iUsershareMaxShares;
8733         int snum_template = -1;
8734
8735         if (*usersharepath == 0 ||  max_user_shares == 0) {
8736                 return -1;
8737         }
8738
8739         if (sys_stat(usersharepath, &sbuf) != 0) {
8740                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8741                         usersharepath, strerror(errno) ));
8742                 return -1;
8743         }
8744
8745         if (!S_ISDIR(sbuf.st_mode)) {
8746                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8747                         usersharepath ));
8748                 return -1;
8749         }
8750
8751         /*
8752          * This directory must be owned by root, and have the 't' bit set.
8753          * It also must not be writable by "other".
8754          */
8755
8756 #ifdef S_ISVTX
8757         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8758 #else
8759         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8760 #endif
8761                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8762                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8763                         usersharepath ));
8764                 return -1;
8765         }
8766
8767         /* Ensure the template share exists if it's set. */
8768         if (Globals.szUsershareTemplateShare[0]) {
8769                 /* We can't use lp_servicenumber here as we are recommending that
8770                    template shares have -valid=False set. */
8771                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8772                         if (ServicePtrs[snum_template]->szService &&
8773                                         strequal(ServicePtrs[snum_template]->szService,
8774                                                 Globals.szUsershareTemplateShare)) {
8775                                 break;
8776                         }
8777                 }
8778
8779                 if (snum_template == -1) {
8780                         DEBUG(0,("load_usershare_service: usershare template share %s "
8781                                 "does not exist.\n",
8782                                 Globals.szUsershareTemplateShare ));
8783                         return -1;
8784                 }
8785         }
8786
8787         return process_usershare_file(usersharepath, servicename, snum_template);
8788 }
8789
8790 /***************************************************************************
8791  Load all user defined shares from the user share directory.
8792  We only do this if we're enumerating the share list.
8793  This is the function that can delete usershares that have
8794  been removed.
8795 ***************************************************************************/
8796
8797 int load_usershare_shares(void)
8798 {
8799         SMB_STRUCT_DIR *dp;
8800         SMB_STRUCT_STAT sbuf;
8801         SMB_STRUCT_DIRENT *de;
8802         int num_usershares = 0;
8803         int max_user_shares = Globals.iUsershareMaxShares;
8804         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8805         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8806         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8807         int iService;
8808         int snum_template = -1;
8809         const char *usersharepath = Globals.szUsersharePath;
8810         int ret = lp_numservices();
8811
8812         if (max_user_shares == 0 || *usersharepath == '\0') {
8813                 return lp_numservices();
8814         }
8815
8816         if (sys_stat(usersharepath, &sbuf) != 0) {
8817                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8818                         usersharepath, strerror(errno) ));
8819                 return ret;
8820         }
8821
8822         /*
8823          * This directory must be owned by root, and have the 't' bit set.
8824          * It also must not be writable by "other".
8825          */
8826
8827 #ifdef S_ISVTX
8828         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8829 #else
8830         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8831 #endif
8832                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8833                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8834                         usersharepath ));
8835                 return ret;
8836         }
8837
8838         /* Ensure the template share exists if it's set. */
8839         if (Globals.szUsershareTemplateShare[0]) {
8840                 /* We can't use lp_servicenumber here as we are recommending that
8841                    template shares have -valid=False set. */
8842                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8843                         if (ServicePtrs[snum_template]->szService &&
8844                                         strequal(ServicePtrs[snum_template]->szService,
8845                                                 Globals.szUsershareTemplateShare)) {
8846                                 break;
8847                         }
8848                 }
8849
8850                 if (snum_template == -1) {
8851                         DEBUG(0,("load_usershare_shares: usershare template share %s "
8852                                 "does not exist.\n",
8853                                 Globals.szUsershareTemplateShare ));
8854                         return ret;
8855                 }
8856         }
8857
8858         /* Mark all existing usershares as pending delete. */
8859         for (iService = iNumServices - 1; iService >= 0; iService--) {
8860                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8861                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8862                 }
8863         }
8864
8865         dp = sys_opendir(usersharepath);
8866         if (!dp) {
8867                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8868                         usersharepath, strerror(errno) ));
8869                 return ret;
8870         }
8871
8872         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8873                         (de = sys_readdir(dp));
8874                         num_dir_entries++ ) {
8875                 int r;
8876                 const char *n = de->d_name;
8877
8878                 /* Ignore . and .. */
8879                 if (*n == '.') {
8880                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8881                                 continue;
8882                         }
8883                 }
8884
8885                 if (n[0] == ':') {
8886                         /* Temporary file used when creating a share. */
8887                         num_tmp_dir_entries++;
8888                 }
8889
8890                 /* Allow 20% tmp entries. */
8891                 if (num_tmp_dir_entries > allowed_tmp_entries) {
8892                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8893                                 "in directory %s\n",
8894                                 num_tmp_dir_entries, usersharepath));
8895                         break;
8896                 }
8897
8898                 r = process_usershare_file(usersharepath, n, snum_template);
8899                 if (r == 0) {
8900                         /* Update the services count. */
8901                         num_usershares++;
8902                         if (num_usershares >= max_user_shares) {
8903                                 DEBUG(0,("load_usershare_shares: max user shares reached "
8904                                         "on file %s in directory %s\n",
8905                                         n, usersharepath ));
8906                                 break;
8907                         }
8908                 } else if (r == -1) {
8909                         num_bad_dir_entries++;
8910                 }
8911
8912                 /* Allow 20% bad entries. */
8913                 if (num_bad_dir_entries > allowed_bad_entries) {
8914                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8915                                 "in directory %s\n",
8916                                 num_bad_dir_entries, usersharepath));
8917                         break;
8918                 }
8919
8920                 /* Allow 20% bad entries. */
8921                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8922                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8923                         "in directory %s\n",
8924                         num_dir_entries, usersharepath));
8925                         break;
8926                 }
8927         }
8928
8929         sys_closedir(dp);
8930
8931         /* Sweep through and delete any non-refreshed usershares that are
8932            not currently in use. */
8933         for (iService = iNumServices - 1; iService >= 0; iService--) {
8934                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8935                         if (conn_snum_used(iService)) {
8936                                 continue;
8937                         }
8938                         /* Remove from the share ACL db. */
8939                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8940                                 lp_servicename(iService) ));
8941                         delete_share_security(lp_servicename(iService));
8942                         free_service_byindex(iService);
8943                 }
8944         }
8945
8946         return lp_numservices();
8947 }
8948
8949 /********************************************************
8950  Destroy global resources allocated in this file
8951 ********************************************************/
8952
8953 void gfree_loadparm(void)
8954 {
8955         struct file_lists *f;
8956         struct file_lists *next;
8957         int i;
8958
8959         /* Free the file lists */
8960
8961         f = file_lists;
8962         while( f ) {
8963                 next = f->next;
8964                 SAFE_FREE( f->name );
8965                 SAFE_FREE( f->subfname );
8966                 SAFE_FREE( f );
8967                 f = next;
8968         }
8969         file_lists = NULL;
8970
8971         /* Free resources allocated to services */
8972
8973         for ( i = 0; i < iNumServices; i++ ) {
8974                 if ( VALID(i) ) {
8975                         free_service_byindex(i);
8976                 }
8977         }
8978
8979         SAFE_FREE( ServicePtrs );
8980         iNumServices = 0;
8981
8982         /* Now release all resources allocated to global
8983            parameters and the default service */
8984
8985         free_global_parameters();
8986 }
8987
8988
8989 /***************************************************************************
8990  Allow client apps to specify that they are a client
8991 ***************************************************************************/
8992 void lp_set_in_client(bool b)
8993 {
8994     in_client = b;
8995 }
8996
8997
8998 /***************************************************************************
8999  Determine if we're running in a client app
9000 ***************************************************************************/
9001 bool lp_is_in_client(void)
9002 {
9003     return in_client;
9004 }
9005
9006 /***************************************************************************
9007  Load the services array from the services file. Return True on success, 
9008  False on failure.
9009 ***************************************************************************/
9010
9011 bool lp_load_ex(const char *pszFname,
9012                 bool global_only,
9013                 bool save_defaults,
9014                 bool add_ipc,
9015                 bool initialize_globals,
9016                 bool allow_include_registry,
9017                 bool allow_registry_shares)
9018 {
9019         char *n2 = NULL;
9020         bool bRetval;
9021
9022         bRetval = False;
9023
9024         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9025
9026         bInGlobalSection = True;
9027         bGlobalOnly = global_only;
9028         bAllowIncludeRegistry = allow_include_registry;
9029
9030         init_globals(! initialize_globals);
9031         debug_init();
9032
9033         if (save_defaults) {
9034                 init_locals();
9035                 lp_save_defaults();
9036         }
9037
9038         free_param_opts(&Globals.param_opt);
9039
9040         /* We get sections first, so have to start 'behind' to make up */
9041         iServiceIndex = -1;
9042
9043         if (lp_config_backend_is_file()) {
9044                 n2 = alloc_sub_basic(get_current_username(),
9045                                         current_user_info.domain,
9046                                         pszFname);
9047                 if (!n2) {
9048                         smb_panic("lp_load_ex: out of memory");
9049                 }
9050
9051                 add_to_file_list(pszFname, n2);
9052
9053                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9054                 SAFE_FREE(n2);
9055
9056                 /* finish up the last section */
9057                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9058                 if (bRetval) {
9059                         if (iServiceIndex >= 0) {
9060                                 bRetval = service_ok(iServiceIndex);
9061                         }
9062                 }
9063
9064                 if (lp_config_backend_is_registry()) {
9065                         /* config backend changed to registry in config file */
9066                         /*
9067                          * We need to use this extra global variable here to
9068                          * survive restart: init_globals uses this as a default
9069                          * for ConfigBackend. Otherwise, init_globals would
9070                          *  send us into an endless loop here.
9071                          */
9072                         config_backend = CONFIG_BACKEND_REGISTRY;
9073                         /* start over */
9074                         DEBUG(1, ("lp_load_ex: changing to config backend "
9075                                   "registry\n"));
9076                         init_globals(false);
9077                         lp_kill_all_services();
9078                         return lp_load_ex(pszFname, global_only, save_defaults,
9079                                           add_ipc, initialize_globals,
9080                                           allow_include_registry,
9081                                           allow_registry_shares);
9082                 }
9083         } else if (lp_config_backend_is_registry()) {
9084                 bRetval = process_registry_globals();
9085         } else {
9086                 DEBUG(0, ("Illegal config  backend given: %d\n",
9087                           lp_config_backend()));
9088                 bRetval = false;
9089         }
9090
9091         if (bRetval && lp_registry_shares() && allow_registry_shares) {
9092                 bRetval = process_registry_shares();
9093         }
9094
9095         lp_add_auto_services(lp_auto_services());
9096
9097         if (add_ipc) {
9098                 /* When 'restrict anonymous = 2' guest connections to ipc$
9099                    are denied */
9100                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9101                 if ( lp_enable_asu_support() ) {
9102                         lp_add_ipc("ADMIN$", false);
9103                 }
9104         }
9105
9106         set_server_role();
9107         set_default_server_announce_type();
9108         set_allowed_client_auth();
9109
9110         bLoaded = True;
9111
9112         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9113         /* if bWINSsupport is true and we are in the client            */
9114         if (lp_is_in_client() && Globals.bWINSsupport) {
9115                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9116         }
9117
9118         init_iconv();
9119
9120         bAllowIncludeRegistry = true;
9121
9122         return (bRetval);
9123 }
9124
9125 bool lp_load(const char *pszFname,
9126              bool global_only,
9127              bool save_defaults,
9128              bool add_ipc,
9129              bool initialize_globals)
9130 {
9131         return lp_load_ex(pszFname,
9132                           global_only,
9133                           save_defaults,
9134                           add_ipc,
9135                           initialize_globals,
9136                           true, false);
9137 }
9138
9139 bool lp_load_initial_only(const char *pszFname)
9140 {
9141         return lp_load_ex(pszFname,
9142                           true,
9143                           false,
9144                           false,
9145                           true,
9146                           false,
9147                           false);
9148 }
9149
9150 bool lp_load_with_registry_shares(const char *pszFname,
9151                                   bool global_only,
9152                                   bool save_defaults,
9153                                   bool add_ipc,
9154                                   bool initialize_globals)
9155 {
9156         return lp_load_ex(pszFname,
9157                           global_only,
9158                           save_defaults,
9159                           add_ipc,
9160                           initialize_globals,
9161                           true,
9162                           true);
9163 }
9164
9165 /***************************************************************************
9166  Return the max number of services.
9167 ***************************************************************************/
9168
9169 int lp_numservices(void)
9170 {
9171         return (iNumServices);
9172 }
9173
9174 /***************************************************************************
9175 Display the contents of the services array in human-readable form.
9176 ***************************************************************************/
9177
9178 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9179 {
9180         int iService;
9181
9182         if (show_defaults)
9183                 defaults_saved = False;
9184
9185         dump_globals(f);
9186
9187         dump_a_service(&sDefault, f);
9188
9189         for (iService = 0; iService < maxtoprint; iService++) {
9190                 fprintf(f,"\n");
9191                 lp_dump_one(f, show_defaults, iService);
9192         }
9193 }
9194
9195 /***************************************************************************
9196 Display the contents of one service in human-readable form.
9197 ***************************************************************************/
9198
9199 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9200 {
9201         if (VALID(snum)) {
9202                 if (ServicePtrs[snum]->szService[0] == '\0')
9203                         return;
9204                 dump_a_service(ServicePtrs[snum], f);
9205         }
9206 }
9207
9208 /***************************************************************************
9209 Return the number of the service with the given name, or -1 if it doesn't
9210 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9211 getservicebyname()! This works ONLY if all services have been loaded, and
9212 does not copy the found service.
9213 ***************************************************************************/
9214
9215 int lp_servicenumber(const char *pszServiceName)
9216 {
9217         int iService;
9218         fstring serviceName;
9219         
9220         if (!pszServiceName) {
9221                 return GLOBAL_SECTION_SNUM;
9222         }
9223         
9224         for (iService = iNumServices - 1; iService >= 0; iService--) {
9225                 if (VALID(iService) && ServicePtrs[iService]->szService) {
9226                         /*
9227                          * The substitution here is used to support %U is
9228                          * service names
9229                          */
9230                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
9231                         standard_sub_basic(get_current_username(),
9232                                            current_user_info.domain,
9233                                            serviceName,sizeof(serviceName));
9234                         if (strequal(serviceName, pszServiceName)) {
9235                                 break;
9236                         }
9237                 }
9238         }
9239
9240         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9241                 time_t last_mod;
9242
9243                 if (!usershare_exists(iService, &last_mod)) {
9244                         /* Remove the share security tdb entry for it. */
9245                         delete_share_security(lp_servicename(iService));
9246                         /* Remove it from the array. */
9247                         free_service_byindex(iService);
9248                         /* Doesn't exist anymore. */
9249                         return GLOBAL_SECTION_SNUM;
9250                 }
9251
9252                 /* Has it been modified ? If so delete and reload. */
9253                 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9254                         /* Remove it from the array. */
9255                         free_service_byindex(iService);
9256                         /* and now reload it. */
9257                         iService = load_usershare_service(pszServiceName);
9258                 }
9259         }
9260
9261         if (iService < 0) {
9262                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9263                 return GLOBAL_SECTION_SNUM;
9264         }
9265
9266         return (iService);
9267 }
9268
9269 bool share_defined(const char *service_name)
9270 {
9271         return (lp_servicenumber(service_name) != -1);
9272 }
9273
9274 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9275                                       const char *sharename)
9276 {
9277         struct share_params *result;
9278         char *sname;
9279         int snum;
9280
9281         if (!(sname = SMB_STRDUP(sharename))) {
9282                 return NULL;
9283         }
9284
9285         snum = find_service(sname);
9286         SAFE_FREE(sname);
9287
9288         if (snum < 0) {
9289                 return NULL;
9290         }
9291
9292         if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9293                 DEBUG(0, ("talloc failed\n"));
9294                 return NULL;
9295         }
9296
9297         result->service = snum;
9298         return result;
9299 }
9300
9301 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9302 {
9303         struct share_iterator *result;
9304
9305         if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9306                 DEBUG(0, ("talloc failed\n"));
9307                 return NULL;
9308         }
9309
9310         result->next_id = 0;
9311         return result;
9312 }
9313
9314 struct share_params *next_share(struct share_iterator *list)
9315 {
9316         struct share_params *result;
9317
9318         while (!lp_snum_ok(list->next_id) &&
9319                (list->next_id < lp_numservices())) {
9320                 list->next_id += 1;
9321         }
9322
9323         if (list->next_id >= lp_numservices()) {
9324                 return NULL;
9325         }
9326
9327         if (!(result = TALLOC_P(list, struct share_params))) {
9328                 DEBUG(0, ("talloc failed\n"));
9329                 return NULL;
9330         }
9331
9332         result->service = list->next_id;
9333         list->next_id += 1;
9334         return result;
9335 }
9336
9337 struct share_params *next_printer(struct share_iterator *list)
9338 {
9339         struct share_params *result;
9340
9341         while ((result = next_share(list)) != NULL) {
9342                 if (lp_print_ok(result->service)) {
9343                         break;
9344                 }
9345         }
9346         return result;
9347 }
9348
9349 /*
9350  * This is a hack for a transition period until we transformed all code from
9351  * service numbers to struct share_params.
9352  */
9353
9354 struct share_params *snum2params_static(int snum)
9355 {
9356         static struct share_params result;
9357         result.service = snum;
9358         return &result;
9359 }
9360
9361 /*******************************************************************
9362  A useful volume label function. 
9363 ********************************************************************/
9364
9365 const char *volume_label(int snum)
9366 {
9367         char *ret;
9368         const char *label = lp_volume(snum);
9369         if (!*label) {
9370                 label = lp_servicename(snum);
9371         }
9372                 
9373         /* This returns a 33 byte guarenteed null terminated string. */
9374         ret = talloc_strndup(talloc_tos(), label, 32);
9375         if (!ret) {
9376                 return "";
9377         }               
9378         return ret;
9379 }
9380
9381 /*******************************************************************
9382  Set the server type we will announce as via nmbd.
9383 ********************************************************************/
9384
9385 static void set_default_server_announce_type(void)
9386 {
9387         default_server_announce = 0;
9388         default_server_announce |= SV_TYPE_WORKSTATION;
9389         default_server_announce |= SV_TYPE_SERVER;
9390         default_server_announce |= SV_TYPE_SERVER_UNIX;
9391
9392         /* note that the flag should be set only if we have a 
9393            printer service but nmbd doesn't actually load the 
9394            services so we can't tell   --jerry */
9395
9396         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9397
9398         switch (lp_announce_as()) {
9399                 case ANNOUNCE_AS_NT_SERVER:
9400                         default_server_announce |= SV_TYPE_SERVER_NT;
9401                         /* fall through... */
9402                 case ANNOUNCE_AS_NT_WORKSTATION:
9403                         default_server_announce |= SV_TYPE_NT;
9404                         break;
9405                 case ANNOUNCE_AS_WIN95:
9406                         default_server_announce |= SV_TYPE_WIN95_PLUS;
9407                         break;
9408                 case ANNOUNCE_AS_WFW:
9409                         default_server_announce |= SV_TYPE_WFW;
9410                         break;
9411                 default:
9412                         break;
9413         }
9414
9415         switch (lp_server_role()) {
9416                 case ROLE_DOMAIN_MEMBER:
9417                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9418                         break;
9419                 case ROLE_DOMAIN_PDC:
9420                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9421                         break;
9422                 case ROLE_DOMAIN_BDC:
9423                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9424                         break;
9425                 case ROLE_STANDALONE:
9426                 default:
9427                         break;
9428         }
9429         if (lp_time_server())
9430                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9431
9432         if (lp_host_msdfs())
9433                 default_server_announce |= SV_TYPE_DFS_SERVER;
9434 }
9435
9436 /***********************************************************
9437  returns role of Samba server
9438 ************************************************************/
9439
9440 int lp_server_role(void)
9441 {
9442         return server_role;
9443 }
9444
9445 /***********************************************************
9446  If we are PDC then prefer us as DMB
9447 ************************************************************/
9448
9449 bool lp_domain_master(void)
9450 {
9451         if (Globals.iDomainMaster == Auto)
9452                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9453
9454         return (bool)Globals.iDomainMaster;
9455 }
9456
9457 /***********************************************************
9458  If we are DMB then prefer us as LMB
9459 ************************************************************/
9460
9461 bool lp_preferred_master(void)
9462 {
9463         if (Globals.iPreferredMaster == Auto)
9464                 return (lp_local_master() && lp_domain_master());
9465
9466         return (bool)Globals.iPreferredMaster;
9467 }
9468
9469 /*******************************************************************
9470  Remove a service.
9471 ********************************************************************/
9472
9473 void lp_remove_service(int snum)
9474 {
9475         ServicePtrs[snum]->valid = False;
9476         invalid_services[num_invalid_services++] = snum;
9477 }
9478
9479 /*******************************************************************
9480  Copy a service.
9481 ********************************************************************/
9482
9483 void lp_copy_service(int snum, const char *new_name)
9484 {
9485         do_section(new_name, NULL);
9486         if (snum >= 0) {
9487                 snum = lp_servicenumber(new_name);
9488                 if (snum >= 0)
9489                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9490         }
9491 }
9492
9493
9494 /*******************************************************************
9495  Get the default server type we will announce as via nmbd.
9496 ********************************************************************/
9497
9498 int lp_default_server_announce(void)
9499 {
9500         return default_server_announce;
9501 }
9502
9503 /*******************************************************************
9504  Split the announce version into major and minor numbers.
9505 ********************************************************************/
9506
9507 int lp_major_announce_version(void)
9508 {
9509         static bool got_major = False;
9510         static int major_version = DEFAULT_MAJOR_VERSION;
9511         char *vers;
9512         char *p;
9513
9514         if (got_major)
9515                 return major_version;
9516
9517         got_major = True;
9518         if ((vers = lp_announce_version()) == NULL)
9519                 return major_version;
9520
9521         if ((p = strchr_m(vers, '.')) == 0)
9522                 return major_version;
9523
9524         *p = '\0';
9525         major_version = atoi(vers);
9526         return major_version;
9527 }
9528
9529 int lp_minor_announce_version(void)
9530 {
9531         static bool got_minor = False;
9532         static int minor_version = DEFAULT_MINOR_VERSION;
9533         char *vers;
9534         char *p;
9535
9536         if (got_minor)
9537                 return minor_version;
9538
9539         got_minor = True;
9540         if ((vers = lp_announce_version()) == NULL)
9541                 return minor_version;
9542
9543         if ((p = strchr_m(vers, '.')) == 0)
9544                 return minor_version;
9545
9546         p++;
9547         minor_version = atoi(p);
9548         return minor_version;
9549 }
9550
9551 /***********************************************************
9552  Set the global name resolution order (used in smbclient).
9553 ************************************************************/
9554
9555 void lp_set_name_resolve_order(const char *new_order)
9556 {
9557         string_set(&Globals.szNameResolveOrder, new_order);
9558 }
9559
9560 const char *lp_printername(int snum)
9561 {
9562         const char *ret = _lp_printername(snum);
9563         if (ret == NULL || (ret != NULL && *ret == '\0'))
9564                 ret = lp_const_servicename(snum);
9565
9566         return ret;
9567 }
9568
9569
9570 /***********************************************************
9571  Allow daemons such as winbindd to fix their logfile name.
9572 ************************************************************/
9573
9574 void lp_set_logfile(const char *name)
9575 {
9576         string_set(&Globals.szLogFile, name);
9577         debug_set_logfile(name);
9578 }
9579
9580 /*******************************************************************
9581  Return the max print jobs per queue.
9582 ********************************************************************/
9583
9584 int lp_maxprintjobs(int snum)
9585 {
9586         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9587         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9588                 maxjobs = PRINT_MAX_JOBID - 1;
9589
9590         return maxjobs;
9591 }
9592
9593 const char *lp_printcapname(void)
9594 {
9595         if ((Globals.szPrintcapname != NULL) &&
9596             (Globals.szPrintcapname[0] != '\0'))
9597                 return Globals.szPrintcapname;
9598
9599         if (sDefault.iPrinting == PRINT_CUPS) {
9600 #ifdef HAVE_CUPS
9601                 return "cups";
9602 #else
9603                 return "lpstat";
9604 #endif
9605         }
9606
9607         if (sDefault.iPrinting == PRINT_BSD)
9608                 return "/etc/printcap";
9609
9610         return PRINTCAP_NAME;
9611 }
9612
9613 static uint32 spoolss_state;
9614
9615 bool lp_disable_spoolss( void )
9616 {
9617         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9618                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9619
9620         return spoolss_state == SVCCTL_STOPPED ? True : False;
9621 }
9622
9623 void lp_set_spoolss_state( uint32 state )
9624 {
9625         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9626
9627         spoolss_state = state;
9628 }
9629
9630 uint32 lp_get_spoolss_state( void )
9631 {
9632         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9633 }
9634
9635 /*******************************************************************
9636  Ensure we don't use sendfile if server smb signing is active.
9637 ********************************************************************/
9638
9639 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9640 {
9641         bool sign_active = false;
9642
9643         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9644         if (Protocol < PROTOCOL_NT1) {
9645                 return false;
9646         }
9647         if (signing_state) {
9648                 sign_active = smb_signing_is_active(signing_state);
9649         }
9650         return (_lp_use_sendfile(snum) &&
9651                         (get_remote_arch() != RA_WIN95) &&
9652                         !sign_active);
9653 }
9654
9655 /*******************************************************************
9656  Turn off sendfile if we find the underlying OS doesn't support it.
9657 ********************************************************************/
9658
9659 void set_use_sendfile(int snum, bool val)
9660 {
9661         if (LP_SNUM_OK(snum))
9662                 ServicePtrs[snum]->bUseSendfile = val;
9663         else
9664                 sDefault.bUseSendfile = val;
9665 }
9666
9667 /*******************************************************************
9668  Turn off storing DOS attributes if this share doesn't support it.
9669 ********************************************************************/
9670
9671 void set_store_dos_attributes(int snum, bool val)
9672 {
9673         if (!LP_SNUM_OK(snum))
9674                 return;
9675         ServicePtrs[(snum)]->bStoreDosAttributes = val;
9676 }
9677
9678 void lp_set_mangling_method(const char *new_method)
9679 {
9680         string_set(&Globals.szManglingMethod, new_method);
9681 }
9682
9683 /*******************************************************************
9684  Global state for POSIX pathname processing.
9685 ********************************************************************/
9686
9687 static bool posix_pathnames;
9688
9689 bool lp_posix_pathnames(void)
9690 {
9691         return posix_pathnames;
9692 }
9693
9694 /*******************************************************************
9695  Change everything needed to ensure POSIX pathname processing (currently
9696  not much).
9697 ********************************************************************/
9698
9699 void lp_set_posix_pathnames(void)
9700 {
9701         posix_pathnames = True;
9702 }
9703
9704 /*******************************************************************
9705  Global state for POSIX lock processing - CIFS unix extensions.
9706 ********************************************************************/
9707
9708 bool posix_default_lock_was_set;
9709 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9710
9711 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9712 {
9713         if (posix_default_lock_was_set) {
9714                 return posix_cifsx_locktype;
9715         } else {
9716                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9717         }
9718 }
9719
9720 /*******************************************************************
9721 ********************************************************************/
9722
9723 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9724 {
9725         posix_default_lock_was_set = True;
9726         posix_cifsx_locktype = val;
9727 }
9728
9729 int lp_min_receive_file_size(void)
9730 {
9731         if (Globals.iminreceivefile < 0) {
9732                 return 0;
9733         }
9734         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9735 }
9736
9737 /*******************************************************************
9738  If socket address is an empty character string, it is necessary to 
9739  define it as "0.0.0.0". 
9740 ********************************************************************/
9741
9742 const char *lp_socket_address(void)
9743 {
9744         char *sock_addr = Globals.szSocketAddress;
9745         
9746         if (sock_addr[0] == '\0'){
9747                 string_set(&Globals.szSocketAddress, "0.0.0.0");
9748         }
9749         return  Globals.szSocketAddress;
9750 }