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