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