57fdb6e044f72bedcfba2ae7b6d4d0c9651afff3
[ira/wip.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13    
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18    
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23    
24    You should have received a copy of the GNU General Public License
25    along with this program.  If not, see <http://www.gnu.org/licenses/>.
26 */
27
28 /*
29  *  Load parameters.
30  *
31  *  This module provides suitable callback functions for the params
32  *  module. It builds the internal table of service details which is
33  *  then used by the rest of the server.
34  *
35  * To add a parameter:
36  *
37  * 1) add it to the global or service structure definition
38  * 2) add it to the parm_table
39  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40  * 4) If it's a global then initialise it in init_globals. If a local
41  *    (ie. service) parameter then initialise it in the sDefault structure
42  *  
43  *
44  * Notes:
45  *   The configuration file is processed sequentially for speed. It is NOT
46  *   accessed randomly as happens in 'real' Windows. For this reason, there
47  *   is a fair bit of sequence-dependent code here - ie., code which assumes
48  *   that certain things happen before others. In particular, the code which
49  *   happens at the boundary between sections is delicately poised, so be
50  *   careful!
51  *
52  */
53
54 #include "includes.h"
55 #include "printing.h"
56
57 #ifdef HAVE_HTTPCONNECTENCRYPT
58 #include <cups/http.h>
59 #endif
60
61 bool bLoaded = False;
62
63 extern enum protocol_types Protocol;
64 extern userdom_struct current_user_info;
65
66 #ifndef GLOBAL_NAME
67 #define GLOBAL_NAME "global"
68 #endif
69
70 #ifndef PRINTERS_NAME
71 #define PRINTERS_NAME "printers"
72 #endif
73
74 #ifndef HOMES_NAME
75 #define HOMES_NAME "homes"
76 #endif
77
78 /* the special value for the include parameter
79  * to be interpreted not as a file name but to
80  * trigger loading of the global smb.conf options
81  * from registry. */
82 #ifndef INCLUDE_REGISTRY_NAME
83 #define INCLUDE_REGISTRY_NAME "registry"
84 #endif
85
86 static bool in_client = False;          /* Not in the client by default */
87 static struct smbconf_csn conf_last_csn;
88
89 #define CONFIG_BACKEND_FILE 0
90 #define CONFIG_BACKEND_REGISTRY 1
91
92 static int config_backend = CONFIG_BACKEND_FILE;
93
94 /* some helpful bits */
95 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
96 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
97
98 #define USERSHARE_VALID 1
99 #define USERSHARE_PENDING_DELETE 2
100
101 static bool defaults_saved = False;
102
103 struct param_opt_struct {
104         struct param_opt_struct *prev, *next;
105         char *key;
106         char *value;
107         char **list;
108 };
109
110 /*
111  * This structure describes global (ie., server-wide) parameters.
112  */
113 struct global {
114         int ConfigBackend;
115         char *smb_ports;
116         char *dos_charset;
117         char *unix_charset;
118         char *display_charset;
119         char *szPrintcapname;
120         char *szAddPortCommand;
121         char *szEnumPortsCommand;
122         char *szAddPrinterCommand;
123         char *szDeletePrinterCommand;
124         char *szOs2DriverMap;
125         char *szLockDir;
126         char *szStateDir;
127         char *szCacheDir;
128         char *szPidDir;
129         char *szRootdir;
130         char *szDefaultService;
131         char *szGetQuota;
132         char *szSetQuota;
133         char *szMsgCommand;
134         char *szServerString;
135         char *szAutoServices;
136         char *szPasswdProgram;
137         char *szPasswdChat;
138         char *szLogFile;
139         char *szConfigFile;
140         char *szSMBPasswdFile;
141         char *szPrivateDir;
142         char *szPassdbBackend;
143         char **szPreloadModules;
144         char *szPasswordServer;
145         char *szSocketOptions;
146         char *szRealm;
147         char *szAfsUsernameMap;
148         int iAfsTokenLifetime;
149         char *szLogNtTokenCommand;
150         char *szUsernameMap;
151         char *szLogonScript;
152         char *szLogonPath;
153         char *szLogonDrive;
154         char *szLogonHome;
155         char **szWINSservers;
156         char **szInterfaces;
157         char *szRemoteAnnounce;
158         char *szRemoteBrowseSync;
159         char *szSocketAddress;
160         char *szNISHomeMapName;
161         char *szAnnounceVersion;        /* This is initialised in init_globals */
162         char *szWorkgroup;
163         char *szNetbiosName;
164         char **szNetbiosAliases;
165         char *szNetbiosScope;
166         char *szNameResolveOrder;
167         char *szPanicAction;
168         char *szAddUserScript;
169         char *szRenameUserScript;
170         char *szDelUserScript;
171         char *szAddGroupScript;
172         char *szDelGroupScript;
173         char *szAddUserToGroupScript;
174         char *szDelUserFromGroupScript;
175         char *szSetPrimaryGroupScript;
176         char *szAddMachineScript;
177         char *szShutdownScript;
178         char *szAbortShutdownScript;
179         char *szUsernameMapScript;
180         char *szCheckPasswordScript;
181         char *szWINSHook;
182         char *szUtmpDir;
183         char *szWtmpDir;
184         bool bUtmp;
185         char *szIdmapUID;
186         char *szIdmapGID;
187         bool bPassdbExpandExplicit;
188         int AlgorithmicRidBase;
189         char *szTemplateHomedir;
190         char *szTemplateShell;
191         char *szWinbindSeparator;
192         bool bWinbindEnumUsers;
193         bool bWinbindEnumGroups;
194         bool bWinbindUseDefaultDomain;
195         bool bWinbindTrustedDomainsOnly;
196         bool bWinbindNestedGroups;
197         int  winbind_expand_groups;
198         bool bWinbindRefreshTickets;
199         bool bWinbindOfflineLogon;
200         bool bWinbindNormalizeNames;
201         bool bWinbindRpcOnly;
202         char *szIdmapBackend;
203         char *szIdmapAllocBackend;
204         char *szAddShareCommand;
205         char *szChangeShareCommand;
206         char *szDeleteShareCommand;
207         char **szEventLogs;
208         char *szGuestaccount;
209         char *szManglingMethod;
210         char **szServicesList;
211         char *szUsersharePath;
212         char *szUsershareTemplateShare;
213         char **szUsersharePrefixAllowList;
214         char **szUsersharePrefixDenyList;
215         int mangle_prefix;
216         int max_log_size;
217         char *szLogLevel;
218         int max_xmit;
219         int max_mux;
220         int max_open_files;
221         int open_files_db_hash_size;
222         int pwordlevel;
223         int unamelevel;
224         int deadtime;
225         bool getwd_cache;
226         int maxprotocol;
227         int minprotocol;
228         int security;
229         char **AuthMethods;
230         bool paranoid_server_security;
231         int maxdisksize;
232         int lpqcachetime;
233         int iMaxSmbdProcesses;
234         bool bDisableSpoolss;
235         int syslog;
236         int os_level;
237         bool enhanced_browsing;
238         int max_ttl;
239         int max_wins_ttl;
240         int min_wins_ttl;
241         int lm_announce;
242         int lm_interval;
243         int announce_as;        /* This is initialised in init_globals */
244         int machine_password_timeout;
245         int map_to_guest;
246         int oplock_break_wait_time;
247         int winbind_cache_time;
248         int winbind_reconnect_delay;
249         int winbind_max_idle_children;
250         char **szWinbindNssInfo;
251         int iLockSpinTime;
252         char *szLdapMachineSuffix;
253         char *szLdapUserSuffix;
254         char *szLdapIdmapSuffix;
255         char *szLdapGroupSuffix;
256         int ldap_ssl;
257         bool ldap_ssl_ads;
258         char *szLdapSuffix;
259         char *szLdapAdminDn;
260         int ldap_debug_level;
261         int ldap_debug_threshold;
262         int iAclCompat;
263         char *szCupsServer;
264         int CupsEncrypt;
265         char *szIPrintServer;
266         char *ctdbdSocket;
267         char **szClusterAddresses;
268         bool clustering;
269         int ldap_passwd_sync;
270         int ldap_replication_sleep;
271         int ldap_timeout; /* This is initialised in init_globals */
272         int ldap_connection_timeout;
273         int ldap_page_size;
274         bool ldap_delete_dn;
275         bool bMsAddPrinterWizard;
276         bool bDNSproxy;
277         bool bWINSsupport;
278         bool bWINSproxy;
279         bool bLocalMaster;
280         int  iPreferredMaster;
281         int iDomainMaster;
282         bool bDomainLogons;
283         char **szInitLogonDelayedHosts;
284         int InitLogonDelay;
285         bool bEncryptPasswords;
286         bool bUpdateEncrypt;
287         int  clientSchannel;
288         int  serverSchannel;
289         bool bNullPasswords;
290         bool bObeyPamRestrictions;
291         bool bLoadPrinters;
292         int PrintcapCacheTime;
293         bool bLargeReadwrite;
294         bool bReadRaw;
295         bool bWriteRaw;
296         bool bSyslogOnly;
297         bool bBrowseList;
298         bool bNISHomeMap;
299         bool bTimeServer;
300         bool bBindInterfacesOnly;
301         bool bPamPasswordChange;
302         bool bUnixPasswdSync;
303         bool bPasswdChatDebug;
304         int iPasswdChatTimeout;
305         bool bTimestampLogs;
306         bool bNTSmbSupport;
307         bool bNTPipeSupport;
308         bool bNTStatusSupport;
309         bool bStatCache;
310         int iMaxStatCacheSize;
311         bool bKernelOplocks;
312         bool bAllowTrustedDomains;
313         bool bLanmanAuth;
314         bool bNTLMAuth;
315         bool bUseSpnego;
316         bool bClientLanManAuth;
317         bool bClientNTLMv2Auth;
318         bool bClientPlaintextAuth;
319         bool bClientUseSpnego;
320         bool bDebugPrefixTimestamp;
321         bool bDebugHiresTimestamp;
322         bool bDebugPid;
323         bool bDebugUid;
324         bool bDebugClass;
325         bool bEnableCoreFiles;
326         bool bHostMSDfs;
327         bool bUseMmap;
328         bool bHostnameLookups;
329         bool bUnixExtensions;
330         bool bDisableNetbios;
331         char * szDedicatedKeytabFile;
332         int  iKerberosMethod;
333         bool bDeferSharingViolations;
334         bool bEnablePrivileges;
335         bool bASUSupport;
336         bool bUsershareOwnerOnly;
337         bool bUsershareAllowGuests;
338         bool bRegistryShares;
339         int restrict_anonymous;
340         int name_cache_timeout;
341         int client_signing;
342         int server_signing;
343         int client_ldap_sasl_wrapping;
344         int iUsershareMaxShares;
345         int iIdmapCacheTime;
346         int iIdmapNegativeCacheTime;
347         bool bResetOnZeroVC;
348         int iKeepalive;
349         int iminreceivefile;
350         struct param_opt_struct *param_opt;
351         int cups_connection_timeout;
352         char *szSMBPerfcountModule;
353         bool bMapUntrustedToDomain;
354         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
5146         ret = talloc_sub_basic(ctx,
5147                         get_current_username(),
5148                         current_user_info.domain,
5149                         s);
5150         if (trim_char(ret, '\"', '\"')) {
5151                 if (strchr(ret,'\"') != NULL) {
5152                         TALLOC_FREE(ret);
5153                         ret = talloc_sub_basic(ctx,
5154                                         get_current_username(),
5155                                         current_user_info.domain,
5156                                         s);
5157                 }
5158         }
5159         return ret;
5160 }
5161
5162 /*
5163    In this section all the functions that are used to access the
5164    parameters from the rest of the program are defined
5165 */
5166
5167 #define FN_GLOBAL_STRING(fn_name,ptr) \
5168  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5169 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5170  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5171 #define FN_GLOBAL_LIST(fn_name,ptr) \
5172  const char **fn_name(void) {return(*(const char ***)(ptr));}
5173 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5174  bool fn_name(void) {return(*(bool *)(ptr));}
5175 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5176  char fn_name(void) {return(*(char *)(ptr));}
5177 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5178  int fn_name(void) {return(*(int *)(ptr));}
5179
5180 #define FN_LOCAL_STRING(fn_name,val) \
5181  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5182 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5183  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5184 #define FN_LOCAL_LIST(fn_name,val) \
5185  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5186 #define FN_LOCAL_BOOL(fn_name,val) \
5187  bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5188 #define FN_LOCAL_INTEGER(fn_name,val) \
5189  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5190
5191 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5192  bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5193 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5194  int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5195 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5196  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));}
5197 #define FN_LOCAL_CHAR(fn_name,val) \
5198  char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5199
5200 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5201 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5202 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5203 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5204 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5205 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5206 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5207 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5208 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5209 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5210 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5211 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5212 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5213 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5214 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5215 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5216 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5217  * build process or in smb.conf, we use that value.  Otherwise they
5218  * default to the value of lp_lockdir(). */
5219 char *lp_statedir(void) {
5220         if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5221             (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5222                 return(lp_string(*(char **)(&Globals.szStateDir) ?
5223                     *(char **)(&Globals.szStateDir) : ""));
5224         else
5225                 return(lp_string(*(char **)(&Globals.szLockDir) ?
5226                     *(char **)(&Globals.szLockDir) : ""));
5227 }
5228 char *lp_cachedir(void) {
5229         if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5230             (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5231                 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5232                     *(char **)(&Globals.szCacheDir) : ""));
5233         else
5234                 return(lp_string(*(char **)(&Globals.szLockDir) ?
5235                     *(char **)(&Globals.szLockDir) : ""));
5236 }
5237 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5238 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5239 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5240 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5241 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5242 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5243 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5244 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5245 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5246 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5247 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5248 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5249 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5250 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5251 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5252 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5253 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5254 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5255 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5256 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5257 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5258 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5259 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5260 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5261 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5262 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5263 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5264 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5265 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5266 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5267 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5268 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5269 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5270 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5271  * lp_passdb_backend() should be replace by the this macro again after
5272  * some releases.
5273  * */
5274 const char *lp_passdb_backend(void)
5275 {
5276         char *delim, *quote;
5277
5278         delim = strchr( Globals.szPassdbBackend, ' ');
5279         /* no space at all */
5280         if (delim == NULL) {
5281                 goto out;
5282         }
5283
5284         quote = strchr(Globals.szPassdbBackend, '"');
5285         /* no quote char or non in the first part */
5286         if (quote == NULL || quote > delim) {
5287                 *delim = '\0';
5288                 goto warn;
5289         }
5290
5291         quote = strchr(quote+1, '"');
5292         if (quote == NULL) {
5293                 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5294                 goto out;
5295         } else if (*(quote+1) == '\0') {
5296                 /* space, fitting quote char, and one backend only */
5297                 goto out;
5298         } else {
5299                 /* terminate string after the fitting quote char */
5300                 *(quote+1) = '\0';
5301         }
5302
5303 warn:
5304         DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends.  This\n"
5305                 "is deprecated since Samba 3.0.23.  Please check WHATSNEW.txt or the section 'Passdb\n"
5306                 "Changes' from the ChangeNotes as part of the Samba HOWTO collection.  Only the first\n"
5307                 "backend (%s) is used.  The rest is ignored.\n", Globals.szPassdbBackend));
5308
5309 out:
5310         return Globals.szPassdbBackend;
5311 }
5312 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5313 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5314 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5315 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5316 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5317
5318 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5319 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5320 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5321 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5322 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5323 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5324
5325 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5326
5327 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5328 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5329 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5330
5331 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5332
5333 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5334 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5335 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5336 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5337 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5338 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5339 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5340 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5341 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5342 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5343 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5344 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5345 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5346 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5347 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5348
5349 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5350 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5351 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5352 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5353 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5354 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5355
5356 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5357 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5358 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5359 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5360 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5361 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5362 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5363 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5364 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5365 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5366 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5367 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5368 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5369 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5370 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5371 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5372 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5373 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5374
5375 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5376
5377 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5378 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5379 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5380 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5381 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5382 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5383 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5384 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5385 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5386 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5387 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5388 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5389 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5390 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5391 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5392 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5393 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5394 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5395 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5396 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5397 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5398 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5399 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5400 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5401 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5402 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5403 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5404 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5405 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5406 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5407 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5408 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5409 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5410 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5411 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5412 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5413 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5414 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5415 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5416 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5417 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5418 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5419 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5420 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5421 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5422 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5423 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5424 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5425 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5426 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5427 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5428 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5429 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5430 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5431 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5432 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5433 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5434 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5435 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5436 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5437 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5438 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5439 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5440 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5441 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5442 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5443 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5444 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5445 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5446 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5447 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5448 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5449 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5450 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5451 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5452 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5453 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5454 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5455 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5456 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5457 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5458 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5459 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5460 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5461 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5462 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5463 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5464 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5465 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5466 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5467 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5468 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5469 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5470 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5471 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5472 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5473 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5474 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5475 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5476 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5477
5478 FN_LOCAL_STRING(lp_preexec, szPreExec)
5479 FN_LOCAL_STRING(lp_postexec, szPostExec)
5480 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5481 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5482 FN_LOCAL_STRING(lp_servicename, szService)
5483 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5484 FN_LOCAL_STRING(lp_pathname, szPath)
5485 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5486 FN_LOCAL_STRING(lp_username, szUsername)
5487 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5488 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5489 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5490 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5491 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5492 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5493 int lp_cups_encrypt(void)
5494 {
5495 #ifdef HAVE_HTTPCONNECTENCRYPT
5496         switch (Globals.CupsEncrypt) {
5497                 case Auto:
5498                         Globals.CupsEncrypt = HTTP_ENCRYPT_REQUIRED;
5499                         break;
5500                 case True:
5501                         Globals.CupsEncrypt = HTTP_ENCRYPT_ALWAYS;
5502                         break;
5503                 case False:
5504                         Globals.CupsEncrypt = HTTP_ENCRYPT_NEVER;
5505                         break;
5506         }
5507 #endif
5508         return Globals.CupsEncrypt;
5509 }
5510 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5511 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5512 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5513 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5514 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5515 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5516 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5517 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5518 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5519 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5520 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5521 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5522 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5523 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5524 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5525 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5526 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5527 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5528 FN_LOCAL_STRING(lp_comment, comment)
5529 FN_LOCAL_STRING(lp_force_user, force_user)
5530 FN_LOCAL_STRING(lp_force_group, force_group)
5531 FN_LOCAL_LIST(lp_readlist, readlist)
5532 FN_LOCAL_LIST(lp_writelist, writelist)
5533 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5534 FN_LOCAL_STRING(lp_fstype, fstype)
5535 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5536 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5537 static FN_LOCAL_STRING(lp_volume, volume)
5538 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5539 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5540 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5541 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5542 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5543 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5544 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5545 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5546 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5547 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5548 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5549 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5550 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5551 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5552 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5553 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5554 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5555 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5556 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5557 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5558 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5559 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5560 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5561 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5562 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5563 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5564 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5565 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5566 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5567 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5568 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5569 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5570 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5571 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5572 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5573 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5574 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5575 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5576 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5577 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5578 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5579 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5580 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5581 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5582 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5583 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5584 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5585 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5586 FN_GLOBAL_BOOL(lp_fake_dir_create_times, &Globals.bFakeDirCreateTimes)
5587 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5588 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5589 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5590 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5591 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5592 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5593 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5594 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5595 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5596 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5597 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5598 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5599 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5600 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5601 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5602 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5603 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5604 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5605 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5606 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5607 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5608 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5609 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5610 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5611 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5612 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5613 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5614 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5615 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5616 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5617 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5618 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5619 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5620 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5621 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5622 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5623 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5624 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5625 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5626 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5627 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5628 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5629 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5630 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5631 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5632 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5633 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5634 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5635 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5636 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5637
5638 /* local prototypes */
5639
5640 static int map_parameter(const char *pszParmName);
5641 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5642 static const char *get_boolean(bool bool_value);
5643 static int getservicebyname(const char *pszServiceName,
5644                             struct service *pserviceDest);
5645 static void copy_service(struct service *pserviceDest,
5646                          struct service *pserviceSource,
5647                          struct bitmap *pcopymapDest);
5648 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5649                          void *userdata);
5650 static bool do_section(const char *pszSectionName, void *userdata);
5651 static void init_copymap(struct service *pservice);
5652 static bool hash_a_service(const char *name, int number);
5653 static void free_service_byindex(int iService);
5654 static void free_param_opts(struct param_opt_struct **popts);
5655 static char * canonicalize_servicename(const char *name);
5656 static void show_parameter(int parmIndex);
5657 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5658
5659 /*
5660  * This is a helper function for parametrical options support.  It returns a
5661  * pointer to parametrical option value if it exists or NULL otherwise. Actual
5662  * parametrical functions are quite simple
5663  */
5664 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5665                                                 const char *option)
5666 {
5667         bool global_section = False;
5668         char* param_key;
5669         struct param_opt_struct *data;
5670         
5671         if (snum >= iNumServices) return NULL;
5672         
5673         if (snum < 0) { 
5674                 data = Globals.param_opt;
5675                 global_section = True;
5676         } else {
5677                 data = ServicePtrs[snum]->param_opt;
5678         }
5679     
5680         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5681                 DEBUG(0,("asprintf failed!\n"));
5682                 return NULL;
5683         }
5684
5685         while (data) {
5686                 if (strwicmp(data->key, param_key) == 0) {
5687                         string_free(&param_key);
5688                         return data;
5689                 }
5690                 data = data->next;
5691         }
5692
5693         if (!global_section) {
5694                 /* Try to fetch the same option but from globals */
5695                 /* but only if we are not already working with Globals */
5696                 data = Globals.param_opt;
5697                 while (data) {
5698                         if (strwicmp(data->key, param_key) == 0) {
5699                                 string_free(&param_key);
5700                                 return data;
5701                         }
5702                         data = data->next;
5703                 }
5704         }
5705
5706         string_free(&param_key);
5707         
5708         return NULL;
5709 }
5710
5711
5712 #define MISSING_PARAMETER(name) \
5713     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5714
5715 /*******************************************************************
5716 convenience routine to return int parameters.
5717 ********************************************************************/
5718 static int lp_int(const char *s)
5719 {
5720
5721         if (!s || !*s) {
5722                 MISSING_PARAMETER(lp_int);
5723                 return (-1);
5724         }
5725
5726         return (int)strtol(s, NULL, 0);
5727 }
5728
5729 /*******************************************************************
5730 convenience routine to return unsigned long parameters.
5731 ********************************************************************/
5732 static unsigned long lp_ulong(const char *s)
5733 {
5734
5735         if (!s || !*s) {
5736                 MISSING_PARAMETER(lp_ulong);
5737                 return (0);
5738         }
5739
5740         return strtoul(s, NULL, 0);
5741 }
5742
5743 /*******************************************************************
5744 convenience routine to return boolean parameters.
5745 ********************************************************************/
5746 static bool lp_bool(const char *s)
5747 {
5748         bool ret = False;
5749
5750         if (!s || !*s) {
5751                 MISSING_PARAMETER(lp_bool);
5752                 return False;
5753         }
5754         
5755         if (!set_boolean(s, &ret)) {
5756                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5757                 return False;
5758         }
5759
5760         return ret;
5761 }
5762
5763 /*******************************************************************
5764 convenience routine to return enum parameters.
5765 ********************************************************************/
5766 static int lp_enum(const char *s,const struct enum_list *_enum)
5767 {
5768         int i;
5769
5770         if (!s || !*s || !_enum) {
5771                 MISSING_PARAMETER(lp_enum);
5772                 return (-1);
5773         }
5774         
5775         for (i=0; _enum[i].name; i++) {
5776                 if (strequal(_enum[i].name,s))
5777                         return _enum[i].value;
5778         }
5779
5780         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5781         return (-1);
5782 }
5783
5784 #undef MISSING_PARAMETER
5785
5786 /* DO NOT USE lp_parm_string ANYMORE!!!!
5787  * use lp_parm_const_string or lp_parm_talloc_string
5788  *
5789  * lp_parm_string is only used to let old modules find this symbol
5790  */
5791 #undef lp_parm_string
5792  char *lp_parm_string(const char *servicename, const char *type, const char *option);
5793  char *lp_parm_string(const char *servicename, const char *type, const char *option)
5794 {
5795         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5796 }
5797
5798 /* Return parametric option from a given service. Type is a part of option before ':' */
5799 /* Parametric option has following syntax: 'Type: option = value' */
5800 /* the returned value is talloced on the talloc_tos() */
5801 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5802 {
5803         struct param_opt_struct *data = get_parametrics(snum, type, option);
5804         
5805         if (data == NULL||data->value==NULL) {
5806                 if (def) {
5807                         return lp_string(def);
5808                 } else {
5809                         return NULL;
5810                 }
5811         }
5812
5813         return lp_string(data->value);
5814 }
5815
5816 /* Return parametric option from a given service. Type is a part of option before ':' */
5817 /* Parametric option has following syntax: 'Type: option = value' */
5818 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5819 {
5820         struct param_opt_struct *data = get_parametrics(snum, type, option);
5821         
5822         if (data == NULL||data->value==NULL)
5823                 return def;
5824                 
5825         return data->value;
5826 }
5827
5828 /* Return parametric option from a given service. Type is a part of option before ':' */
5829 /* Parametric option has following syntax: 'Type: option = value' */
5830
5831 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5832 {
5833         struct param_opt_struct *data = get_parametrics(snum, type, option);
5834
5835         if (data == NULL||data->value==NULL)
5836                 return (const char **)def;
5837                 
5838         if (data->list==NULL) {
5839                 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5840         }
5841
5842         return (const char **)data->list;
5843 }
5844
5845 /* Return parametric option from a given service. Type is a part of option before ':' */
5846 /* Parametric option has following syntax: 'Type: option = value' */
5847
5848 int lp_parm_int(int snum, const char *type, const char *option, int def)
5849 {
5850         struct param_opt_struct *data = get_parametrics(snum, type, option);
5851         
5852         if (data && data->value && *data->value)
5853                 return lp_int(data->value);
5854
5855         return def;
5856 }
5857
5858 /* Return parametric option from a given service. Type is a part of option before ':' */
5859 /* Parametric option has following syntax: 'Type: option = value' */
5860
5861 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5862 {
5863         struct param_opt_struct *data = get_parametrics(snum, type, option);
5864         
5865         if (data && data->value && *data->value)
5866                 return lp_ulong(data->value);
5867
5868         return def;
5869 }
5870
5871 /* Return parametric option from a given service. Type is a part of option before ':' */
5872 /* Parametric option has following syntax: 'Type: option = value' */
5873
5874 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5875 {
5876         struct param_opt_struct *data = get_parametrics(snum, type, option);
5877         
5878         if (data && data->value && *data->value)
5879                 return lp_bool(data->value);
5880
5881         return def;
5882 }
5883
5884 /* Return parametric option from a given service. Type is a part of option before ':' */
5885 /* Parametric option has following syntax: 'Type: option = value' */
5886
5887 int lp_parm_enum(int snum, const char *type, const char *option,
5888                  const struct enum_list *_enum, int def)
5889 {
5890         struct param_opt_struct *data = get_parametrics(snum, type, option);
5891         
5892         if (data && data->value && *data->value && _enum)
5893                 return lp_enum(data->value, _enum);
5894
5895         return def;
5896 }
5897
5898
5899 /***************************************************************************
5900  Initialise a service to the defaults.
5901 ***************************************************************************/
5902
5903 static void init_service(struct service *pservice)
5904 {
5905         memset((char *)pservice, '\0', sizeof(struct service));
5906         copy_service(pservice, &sDefault, NULL);
5907 }
5908
5909
5910 /**
5911  * free a param_opts structure.
5912  * param_opts handling should be moved to talloc;
5913  * then this whole functions reduces to a TALLOC_FREE().
5914  */
5915
5916 static void free_param_opts(struct param_opt_struct **popts)
5917 {
5918         struct param_opt_struct *opt, *next_opt;
5919
5920         if (popts == NULL) {
5921                 return;
5922         }
5923
5924         if (*popts != NULL) {
5925                 DEBUG(5, ("Freeing parametrics:\n"));
5926         }
5927         opt = *popts;
5928         while (opt != NULL) {
5929                 string_free(&opt->key);
5930                 string_free(&opt->value);
5931                 TALLOC_FREE(opt->list);
5932                 next_opt = opt->next;
5933                 SAFE_FREE(opt);
5934                 opt = next_opt;
5935         }
5936         *popts = NULL;
5937 }
5938
5939 /***************************************************************************
5940  Free the dynamically allocated parts of a service struct.
5941 ***************************************************************************/
5942
5943 static void free_service(struct service *pservice)
5944 {
5945         if (!pservice)
5946                 return;
5947
5948         if (pservice->szService)
5949                 DEBUG(5, ("free_service: Freeing service %s\n",
5950                        pservice->szService));
5951
5952         free_parameters(pservice);
5953
5954         string_free(&pservice->szService);
5955         bitmap_free(pservice->copymap);
5956
5957         free_param_opts(&pservice->param_opt);
5958
5959         ZERO_STRUCTP(pservice);
5960 }
5961
5962
5963 /***************************************************************************
5964  remove a service indexed in the ServicePtrs array from the ServiceHash
5965  and free the dynamically allocated parts
5966 ***************************************************************************/
5967
5968 static void free_service_byindex(int idx)
5969 {
5970         if ( !LP_SNUM_OK(idx) ) 
5971                 return;
5972
5973         ServicePtrs[idx]->valid = False;
5974         invalid_services[num_invalid_services++] = idx;
5975
5976         /* we have to cleanup the hash record */
5977
5978         if (ServicePtrs[idx]->szService) {
5979                 char *canon_name = canonicalize_servicename(
5980                         ServicePtrs[idx]->szService );
5981                 
5982                 dbwrap_delete_bystring(ServiceHash, canon_name );
5983                 TALLOC_FREE(canon_name);
5984         }
5985
5986         free_service(ServicePtrs[idx]);
5987 }
5988
5989 /***************************************************************************
5990  Add a new service to the services array initialising it with the given 
5991  service. 
5992 ***************************************************************************/
5993
5994 static int add_a_service(const struct service *pservice, const char *name)
5995 {
5996         int i;
5997         struct service tservice;
5998         int num_to_alloc = iNumServices + 1;
5999
6000         tservice = *pservice;
6001
6002         /* it might already exist */
6003         if (name) {
6004                 i = getservicebyname(name, NULL);
6005                 if (i >= 0) {
6006                         /* Clean all parametric options for service */
6007                         /* They will be added during parsing again */
6008                         free_param_opts(&ServicePtrs[i]->param_opt);
6009                         return (i);
6010                 }
6011         }
6012
6013         /* find an invalid one */
6014         i = iNumServices;
6015         if (num_invalid_services > 0) {
6016                 i = invalid_services[--num_invalid_services];
6017         }
6018
6019         /* if not, then create one */
6020         if (i == iNumServices) {
6021                 struct service **tsp;
6022                 int *tinvalid;
6023                 
6024                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6025                 if (tsp == NULL) {
6026                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6027                         return (-1);
6028                 }
6029                 ServicePtrs = tsp;
6030                 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6031                 if (!ServicePtrs[iNumServices]) {
6032                         DEBUG(0,("add_a_service: out of memory!\n"));
6033                         return (-1);
6034                 }
6035                 iNumServices++;
6036
6037                 /* enlarge invalid_services here for now... */
6038                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6039                                              num_to_alloc);
6040                 if (tinvalid == NULL) {
6041                         DEBUG(0,("add_a_service: failed to enlarge "
6042                                  "invalid_services!\n"));
6043                         return (-1);
6044                 }
6045                 invalid_services = tinvalid;
6046         } else {
6047                 free_service_byindex(i);
6048         }
6049
6050         ServicePtrs[i]->valid = True;
6051
6052         init_service(ServicePtrs[i]);
6053         copy_service(ServicePtrs[i], &tservice, NULL);
6054         if (name)
6055                 string_set(&ServicePtrs[i]->szService, name);
6056                 
6057         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
6058                 i, ServicePtrs[i]->szService));
6059
6060         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6061                 return (-1);
6062         }
6063                 
6064         return (i);
6065 }
6066
6067 /***************************************************************************
6068   Convert a string to uppercase and remove whitespaces.
6069 ***************************************************************************/
6070
6071 static char *canonicalize_servicename(const char *src)
6072 {
6073         char *result;
6074
6075         if ( !src ) {
6076                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6077                 return NULL;
6078         }
6079
6080         result = talloc_strdup(talloc_tos(), src);
6081         SMB_ASSERT(result != NULL);
6082
6083         strlower_m(result);
6084         return result;
6085 }
6086
6087 /***************************************************************************
6088   Add a name/index pair for the services array to the hash table.
6089 ***************************************************************************/
6090
6091 static bool hash_a_service(const char *name, int idx)
6092 {
6093         char *canon_name;
6094
6095         if ( !ServiceHash ) {
6096                 DEBUG(10,("hash_a_service: creating servicehash\n"));
6097                 ServiceHash = db_open_rbt(NULL);
6098                 if ( !ServiceHash ) {
6099                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6100                         return False;
6101                 }
6102         }
6103
6104         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6105                 idx, name));
6106
6107         canon_name = canonicalize_servicename( name );
6108
6109         dbwrap_store_bystring(ServiceHash, canon_name,
6110                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
6111                               TDB_REPLACE);
6112
6113         TALLOC_FREE(canon_name);
6114
6115         return True;
6116 }
6117
6118 /***************************************************************************
6119  Add a new home service, with the specified home directory, defaults coming
6120  from service ifrom.
6121 ***************************************************************************/
6122
6123 bool lp_add_home(const char *pszHomename, int iDefaultService,
6124                  const char *user, const char *pszHomedir)
6125 {
6126         int i;
6127
6128         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6129
6130         if (i < 0)
6131                 return (False);
6132
6133         if (!(*(ServicePtrs[iDefaultService]->szPath))
6134             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6135                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6136         }
6137
6138         if (!(*(ServicePtrs[i]->comment))) {
6139                 char *comment = NULL;
6140                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6141                         return false;
6142                 }
6143                 string_set(&ServicePtrs[i]->comment, comment);
6144                 SAFE_FREE(comment);
6145         }
6146
6147         /* set the browseable flag from the global default */
6148
6149         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6150         ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6151
6152         ServicePtrs[i]->autoloaded = True;
6153
6154         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
6155                user, ServicePtrs[i]->szPath ));
6156
6157         return (True);
6158 }
6159
6160 /***************************************************************************
6161  Add a new service, based on an old one.
6162 ***************************************************************************/
6163
6164 int lp_add_service(const char *pszService, int iDefaultService)
6165 {
6166         if (iDefaultService < 0) {
6167                 return add_a_service(&sDefault, pszService);
6168         }
6169
6170         return (add_a_service(ServicePtrs[iDefaultService], pszService));
6171 }
6172
6173 /***************************************************************************
6174  Add the IPC service.
6175 ***************************************************************************/
6176
6177 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6178 {
6179         char *comment = NULL;
6180         int i = add_a_service(&sDefault, ipc_name);
6181
6182         if (i < 0)
6183                 return (False);
6184
6185         if (asprintf(&comment, "IPC Service (%s)",
6186                                 Globals.szServerString) < 0) {
6187                 return (False);
6188         }
6189
6190         string_set(&ServicePtrs[i]->szPath, tmpdir());
6191         string_set(&ServicePtrs[i]->szUsername, "");
6192         string_set(&ServicePtrs[i]->comment, comment);
6193         string_set(&ServicePtrs[i]->fstype, "IPC");
6194         ServicePtrs[i]->iMaxConnections = 0;
6195         ServicePtrs[i]->bAvailable = True;
6196         ServicePtrs[i]->bRead_only = True;
6197         ServicePtrs[i]->bGuest_only = False;
6198         ServicePtrs[i]->bAdministrative_share = True;
6199         ServicePtrs[i]->bGuest_ok = guest_ok;
6200         ServicePtrs[i]->bPrint_ok = False;
6201         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6202
6203         DEBUG(3, ("adding IPC service\n"));
6204
6205         SAFE_FREE(comment);
6206         return (True);
6207 }
6208
6209 /***************************************************************************
6210  Add a new printer service, with defaults coming from service iFrom.
6211 ***************************************************************************/
6212
6213 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6214 {
6215         const char *comment = "From Printcap";
6216         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6217
6218         if (i < 0)
6219                 return (False);
6220
6221         /* note that we do NOT default the availability flag to True - */
6222         /* we take it from the default service passed. This allows all */
6223         /* dynamic printers to be disabled by disabling the [printers] */
6224         /* entry (if/when the 'available' keyword is implemented!).    */
6225
6226         /* the printer name is set to the service name. */
6227         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6228         string_set(&ServicePtrs[i]->comment, comment);
6229
6230         /* set the browseable flag from the gloabl default */
6231         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6232
6233         /* Printers cannot be read_only. */
6234         ServicePtrs[i]->bRead_only = False;
6235         /* No share modes on printer services. */
6236         ServicePtrs[i]->bShareModes = False;
6237         /* No oplocks on printer services. */
6238         ServicePtrs[i]->bOpLocks = False;
6239         /* Printer services must be printable. */
6240         ServicePtrs[i]->bPrint_ok = True;
6241         
6242         DEBUG(3, ("adding printer service %s\n", pszPrintername));
6243
6244         return (True);
6245 }
6246
6247
6248 /***************************************************************************
6249  Check whether the given parameter name is valid.
6250  Parametric options (names containing a colon) are considered valid.
6251 ***************************************************************************/
6252
6253 bool lp_parameter_is_valid(const char *pszParmName)
6254 {
6255         return ((map_parameter(pszParmName) != -1) ||
6256                 (strchr(pszParmName, ':') != NULL));
6257 }
6258
6259 /***************************************************************************
6260  Check whether the given name is the name of a global parameter.
6261  Returns True for strings belonging to parameters of class
6262  P_GLOBAL, False for all other strings, also for parametric options
6263  and strings not belonging to any option.
6264 ***************************************************************************/
6265
6266 bool lp_parameter_is_global(const char *pszParmName)
6267 {
6268         int num = map_parameter(pszParmName);
6269
6270         if (num >= 0) {
6271                 return (parm_table[num].p_class == P_GLOBAL);
6272         }
6273
6274         return False;
6275 }
6276
6277 /**************************************************************************
6278  Check whether the given name is the canonical name of a parameter.
6279  Returns False if it is not a valid parameter Name.
6280  For parametric options, True is returned.
6281 **************************************************************************/
6282
6283 bool lp_parameter_is_canonical(const char *parm_name)
6284 {
6285         if (!lp_parameter_is_valid(parm_name)) {
6286                 return False;
6287         }
6288
6289         return (map_parameter(parm_name) ==
6290                 map_parameter_canonical(parm_name, NULL));
6291 }
6292
6293 /**************************************************************************
6294  Determine the canonical name for a parameter.
6295  Indicate when it is an inverse (boolean) synonym instead of a
6296  "usual" synonym.
6297 **************************************************************************/
6298
6299 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6300                                bool *inverse)
6301 {
6302         int num;
6303
6304         if (!lp_parameter_is_valid(parm_name)) {
6305                 *canon_parm = NULL;
6306                 return False;
6307         }
6308
6309         num = map_parameter_canonical(parm_name, inverse);
6310         if (num < 0) {
6311                 /* parametric option */
6312                 *canon_parm = parm_name;
6313         } else {
6314                 *canon_parm = parm_table[num].label;
6315         }
6316
6317         return True;
6318
6319 }
6320
6321 /**************************************************************************
6322  Determine the canonical name for a parameter.
6323  Turn the value given into the inverse boolean expression when
6324  the synonym is an invers boolean synonym.
6325
6326  Return True if parm_name is a valid parameter name and
6327  in case it is an invers boolean synonym, if the val string could
6328  successfully be converted to the reverse bool.
6329  Return false in all other cases.
6330 **************************************************************************/
6331
6332 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6333                                           const char *val,
6334                                           const char **canon_parm,
6335                                           const char **canon_val)
6336 {
6337         int num;
6338         bool inverse;
6339
6340         if (!lp_parameter_is_valid(parm_name)) {
6341                 *canon_parm = NULL;
6342                 *canon_val = NULL;
6343                 return False;
6344         }
6345
6346         num = map_parameter_canonical(parm_name, &inverse);
6347         if (num < 0) {
6348                 /* parametric option */
6349                 *canon_parm = parm_name;
6350                 *canon_val = val;
6351         } else {
6352                 *canon_parm = parm_table[num].label;
6353                 if (inverse) {
6354                         if (!lp_invert_boolean(val, canon_val)) {
6355                                 *canon_val = NULL;
6356                                 return False;
6357                         }
6358                 } else {
6359                         *canon_val = val;
6360                 }
6361         }
6362
6363         return True;
6364 }
6365
6366 /***************************************************************************
6367  Map a parameter's string representation to something we can use. 
6368  Returns False if the parameter string is not recognised, else TRUE.
6369 ***************************************************************************/
6370
6371 static int map_parameter(const char *pszParmName)
6372 {
6373         int iIndex;
6374
6375         if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6376                 return (-1);
6377
6378         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6379                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6380                         return (iIndex);
6381
6382         /* Warn only if it isn't parametric option */
6383         if (strchr(pszParmName, ':') == NULL)
6384                 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6385         /* We do return 'fail' for parametric options as well because they are
6386            stored in different storage
6387          */
6388         return (-1);
6389 }
6390
6391 /***************************************************************************
6392  Map a parameter's string representation to the index of the canonical
6393  form of the parameter (it might be a synonym).
6394  Returns -1 if the parameter string is not recognised.
6395 ***************************************************************************/
6396
6397 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6398 {
6399         int parm_num, canon_num;
6400         bool loc_inverse = False;
6401
6402         parm_num = map_parameter(pszParmName);
6403         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6404                 /* invalid, parametric or no canidate for synonyms ... */
6405                 goto done;
6406         }
6407
6408         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6409                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6410                         parm_num = canon_num;
6411                         goto done;
6412                 }
6413         }
6414
6415 done:
6416         if (inverse != NULL) {
6417                 *inverse = loc_inverse;
6418         }
6419         return parm_num;
6420 }
6421
6422 /***************************************************************************
6423  return true if parameter number parm1 is a synonym of parameter
6424  number parm2 (parm2 being the principal name).
6425  set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6426  False otherwise.
6427 ***************************************************************************/
6428
6429 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6430 {
6431         if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6432             (parm_table[parm1].flags & FLAG_HIDE) &&
6433             !(parm_table[parm2].flags & FLAG_HIDE))
6434         {
6435                 if (inverse != NULL) {
6436                         if ((parm_table[parm1].type == P_BOOLREV) &&
6437                             (parm_table[parm2].type == P_BOOL))
6438                         {
6439                                 *inverse = True;
6440                         } else {
6441                                 *inverse = False;
6442                         }
6443                 }
6444                 return True;
6445         }
6446         return False;
6447 }
6448
6449 /***************************************************************************
6450  Show one parameter's name, type, [values,] and flags.
6451  (helper functions for show_parameter_list)
6452 ***************************************************************************/
6453
6454 static void show_parameter(int parmIndex)
6455 {
6456         int enumIndex, flagIndex;
6457         int parmIndex2;
6458         bool hadFlag;
6459         bool hadSyn;
6460         bool inverse;
6461         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6462                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6463                 "P_ENUM", "P_SEP"};
6464         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6465                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6466                 FLAG_HIDE, FLAG_DOS_STRING};
6467         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6468                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6469                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6470
6471         printf("%s=%s", parm_table[parmIndex].label,
6472                type[parm_table[parmIndex].type]);
6473         if (parm_table[parmIndex].type == P_ENUM) {
6474                 printf(",");
6475                 for (enumIndex=0;
6476                      parm_table[parmIndex].enum_list[enumIndex].name;
6477                      enumIndex++)
6478                 {
6479                         printf("%s%s",
6480                                enumIndex ? "|" : "",
6481                                parm_table[parmIndex].enum_list[enumIndex].name);
6482                 }
6483         }
6484         printf(",");
6485         hadFlag = False;
6486         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6487                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6488                         printf("%s%s",
6489                                 hadFlag ? "|" : "",
6490                                 flag_names[flagIndex]);
6491                         hadFlag = True;
6492                 }
6493         }
6494
6495         /* output synonyms */
6496         hadSyn = False;
6497         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6498                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6499                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6500                                parm_table[parmIndex2].label);
6501                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6502                         if (!hadSyn) {
6503                                 printf(" (synonyms: ");
6504                                 hadSyn = True;
6505                         } else {
6506                                 printf(", ");
6507                         }
6508                         printf("%s%s", parm_table[parmIndex2].label,
6509                                inverse ? "[i]" : "");
6510                 }
6511         }
6512         if (hadSyn) {
6513                 printf(")");
6514         }
6515
6516         printf("\n");
6517 }
6518
6519 /***************************************************************************
6520  Show all parameter's name, type, [values,] and flags.
6521 ***************************************************************************/
6522
6523 void show_parameter_list(void)
6524 {
6525         int classIndex, parmIndex;
6526         const char *section_names[] = { "local", "global", NULL};
6527
6528         for (classIndex=0; section_names[classIndex]; classIndex++) {
6529                 printf("[%s]\n", section_names[classIndex]);
6530                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6531                         if (parm_table[parmIndex].p_class == classIndex) {
6532                                 show_parameter(parmIndex);
6533                         }
6534                 }
6535         }
6536 }
6537
6538 /***************************************************************************
6539  Check if a given string correctly represents a boolean value.
6540 ***************************************************************************/
6541
6542 bool lp_string_is_valid_boolean(const char *parm_value)
6543 {
6544         return set_boolean(parm_value, NULL);
6545 }
6546
6547 /***************************************************************************
6548  Get the standard string representation of a boolean value ("yes" or "no")
6549 ***************************************************************************/
6550
6551 static const char *get_boolean(bool bool_value)
6552 {
6553         static const char *yes_str = "yes";
6554         static const char *no_str = "no";
6555
6556         return (bool_value ? yes_str : no_str);
6557 }
6558
6559 /***************************************************************************
6560  Provide the string of the negated boolean value associated to the boolean
6561  given as a string. Returns False if the passed string does not correctly
6562  represent a boolean.
6563 ***************************************************************************/
6564
6565 bool lp_invert_boolean(const char *str, const char **inverse_str)
6566 {
6567         bool val;
6568
6569         if (!set_boolean(str, &val)) {
6570                 return False;
6571         }
6572
6573         *inverse_str = get_boolean(!val);
6574         return True;
6575 }
6576
6577 /***************************************************************************
6578  Provide the canonical string representation of a boolean value given
6579  as a string. Return True on success, False if the string given does
6580  not correctly represent a boolean.
6581 ***************************************************************************/
6582
6583 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6584 {
6585         bool val;
6586
6587         if (!set_boolean(str, &val)) {
6588                 return False;
6589         }
6590
6591         *canon_str = get_boolean(val);
6592         return True;
6593 }
6594
6595 /***************************************************************************
6596 Find a service by name. Otherwise works like get_service.
6597 ***************************************************************************/
6598
6599 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6600 {
6601         int iService = -1;
6602         char *canon_name;
6603         TDB_DATA data;
6604
6605         if (ServiceHash == NULL) {
6606                 return -1;
6607         }
6608
6609         canon_name = canonicalize_servicename(pszServiceName);
6610
6611         data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6612
6613         if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6614                 iService = *(int *)data.dptr;
6615         }
6616
6617         TALLOC_FREE(canon_name);
6618
6619         if ((iService != -1) && (LP_SNUM_OK(iService))
6620             && (pserviceDest != NULL)) {
6621                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6622         }
6623
6624         return (iService);
6625 }
6626
6627 /***************************************************************************
6628  Copy a service structure to another.
6629  If pcopymapDest is NULL then copy all fields
6630 ***************************************************************************/
6631
6632 /**
6633  * Add a parametric option to a param_opt_struct,
6634  * replacing old value, if already present.
6635  */
6636 static void set_param_opt(struct param_opt_struct **opt_list,
6637                           const char *opt_name,
6638                           const char *opt_value)
6639 {
6640         struct param_opt_struct *new_opt, *opt;
6641         bool not_added;
6642
6643         if (opt_list == NULL) {
6644                 return;
6645         }
6646
6647         opt = *opt_list;
6648         not_added = true;
6649
6650         /* Traverse destination */
6651         while (opt) {
6652                 /* If we already have same option, override it */
6653                 if (strwicmp(opt->key, opt_name) == 0) {
6654                         string_free(&opt->value);
6655                         TALLOC_FREE(opt->list);
6656                         opt->value = SMB_STRDUP(opt_value);
6657                         not_added = false;
6658                         break;
6659                 }
6660                 opt = opt->next;
6661         }
6662         if (not_added) {
6663             new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6664             new_opt->key = SMB_STRDUP(opt_name);
6665             new_opt->value = SMB_STRDUP(opt_value);
6666             new_opt->list = NULL;
6667             DLIST_ADD(*opt_list, new_opt);
6668         }
6669 }
6670
6671 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6672                          struct bitmap *pcopymapDest)
6673 {
6674         int i;
6675         bool bcopyall = (pcopymapDest == NULL);
6676         struct param_opt_struct *data;
6677
6678         for (i = 0; parm_table[i].label; i++)
6679                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6680                     (bcopyall || bitmap_query(pcopymapDest,i))) {
6681                         void *def_ptr = parm_table[i].ptr;
6682                         void *src_ptr =
6683                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6684                                                                     &sDefault);
6685                         void *dest_ptr =
6686                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6687                                                                   &sDefault);
6688
6689                         switch (parm_table[i].type) {
6690                                 case P_BOOL:
6691                                 case P_BOOLREV:
6692                                         *(bool *)dest_ptr = *(bool *)src_ptr;
6693                                         break;
6694
6695                                 case P_INTEGER:
6696                                 case P_ENUM:
6697                                 case P_OCTAL:
6698                                         *(int *)dest_ptr = *(int *)src_ptr;
6699                                         break;
6700
6701                                 case P_CHAR:
6702                                         *(char *)dest_ptr = *(char *)src_ptr;
6703                                         break;
6704
6705                                 case P_STRING:
6706                                         string_set((char **)dest_ptr,
6707                                                    *(char **)src_ptr);
6708                                         break;
6709
6710                                 case P_USTRING:
6711                                         string_set((char **)dest_ptr,
6712                                                    *(char **)src_ptr);
6713                                         strupper_m(*(char **)dest_ptr);
6714                                         break;
6715                                 case P_LIST:
6716                                         TALLOC_FREE(*((char ***)dest_ptr));
6717                                         *((char ***)dest_ptr) = str_list_copy(NULL, 
6718                                                       *(const char ***)src_ptr);
6719                                         break;
6720                                 default:
6721                                         break;
6722                         }
6723                 }
6724
6725         if (bcopyall) {
6726                 init_copymap(pserviceDest);
6727                 if (pserviceSource->copymap)
6728                         bitmap_copy(pserviceDest->copymap,
6729                                     pserviceSource->copymap);
6730         }
6731         
6732         data = pserviceSource->param_opt;
6733         while (data) {
6734                 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6735                 data = data->next;
6736         }
6737 }
6738
6739 /***************************************************************************
6740 Check a service for consistency. Return False if the service is in any way
6741 incomplete or faulty, else True.
6742 ***************************************************************************/
6743
6744 bool service_ok(int iService)
6745 {
6746         bool bRetval;
6747
6748         bRetval = True;
6749         if (ServicePtrs[iService]->szService[0] == '\0') {
6750                 DEBUG(0, ("The following message indicates an internal error:\n"));
6751                 DEBUG(0, ("No service name in service entry.\n"));
6752                 bRetval = False;
6753         }
6754
6755         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6756         /* I can't see why you'd want a non-printable printer service...        */
6757         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6758                 if (!ServicePtrs[iService]->bPrint_ok) {
6759                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6760                                ServicePtrs[iService]->szService));
6761                         ServicePtrs[iService]->bPrint_ok = True;
6762                 }
6763                 /* [printers] service must also be non-browsable. */
6764                 if (ServicePtrs[iService]->bBrowseable)
6765                         ServicePtrs[iService]->bBrowseable = False;
6766         }
6767
6768         if (ServicePtrs[iService]->szPath[0] == '\0' &&
6769             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6770             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6771             ) {
6772                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6773                         ServicePtrs[iService]->szService));
6774                 ServicePtrs[iService]->bAvailable = False;
6775         }
6776
6777         /* If a service is flagged unavailable, log the fact at level 1. */
6778         if (!ServicePtrs[iService]->bAvailable)
6779                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6780                           ServicePtrs[iService]->szService));
6781
6782         return (bRetval);
6783 }
6784
6785 static struct smbconf_ctx *lp_smbconf_ctx(void)
6786 {
6787         WERROR werr;
6788         static struct smbconf_ctx *conf_ctx = NULL;
6789
6790         if (conf_ctx == NULL) {
6791                 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6792                 if (!W_ERROR_IS_OK(werr)) {
6793                         DEBUG(1, ("error initializing registry configuration: "
6794                                   "%s\n", win_errstr(werr)));
6795                         conf_ctx = NULL;
6796                 }
6797         }
6798
6799         return conf_ctx;
6800 }
6801
6802 static bool process_smbconf_service(struct smbconf_service *service)
6803 {
6804         uint32_t count;
6805         bool ret;
6806
6807         if (service == NULL) {
6808                 return false;
6809         }
6810
6811         ret = do_section(service->name, NULL);
6812         if (ret != true) {
6813                 return false;
6814         }
6815         for (count = 0; count < service->num_params; count++) {
6816                 ret = do_parameter(service->param_names[count],
6817                                    service->param_values[count],
6818                                    NULL);
6819                 if (ret != true) {
6820                         return false;
6821                 }
6822         }
6823         if (iServiceIndex >= 0) {
6824                 return service_ok(iServiceIndex);
6825         }
6826         return true;
6827 }
6828
6829 /**
6830  * load a service from registry and activate it
6831  */
6832 bool process_registry_service(const char *service_name)
6833 {
6834         WERROR werr;
6835         struct smbconf_service *service = NULL;
6836         TALLOC_CTX *mem_ctx = talloc_stackframe();
6837         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6838         bool ret = false;
6839
6840         if (conf_ctx == NULL) {
6841                 goto done;
6842         }
6843
6844         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6845
6846         if (!smbconf_share_exists(conf_ctx, service_name)) {
6847                 /*
6848                  * Registry does not contain data for this service (yet),
6849                  * but make sure lp_load doesn't return false.
6850                  */
6851                 ret = true;
6852                 goto done;
6853         }
6854
6855         werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6856         if (!W_ERROR_IS_OK(werr)) {
6857                 goto done;
6858         }
6859
6860         ret = process_smbconf_service(service);
6861         if (!ret) {
6862                 goto done;
6863         }
6864
6865         /* store the csn */
6866         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6867
6868 done:
6869         TALLOC_FREE(mem_ctx);
6870         return ret;
6871 }
6872
6873 /*
6874  * process_registry_globals
6875  */
6876 static bool process_registry_globals(void)
6877 {
6878         bool ret;
6879
6880         add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6881
6882         ret = do_parameter("registry shares", "yes", NULL);
6883         if (!ret) {
6884                 return ret;
6885         }
6886
6887         return process_registry_service(GLOBAL_NAME);
6888 }
6889
6890 bool process_registry_shares(void)
6891 {
6892         WERROR werr;
6893         uint32_t count;
6894         struct smbconf_service **service = NULL;
6895         uint32_t num_shares = 0;
6896         TALLOC_CTX *mem_ctx = talloc_stackframe();
6897         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6898         bool ret = false;
6899
6900         if (conf_ctx == NULL) {
6901                 goto done;
6902         }
6903
6904         werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6905         if (!W_ERROR_IS_OK(werr)) {
6906                 goto done;
6907         }
6908
6909         ret = true;
6910
6911         for (count = 0; count < num_shares; count++) {
6912                 if (strequal(service[count]->name, GLOBAL_NAME)) {
6913                         continue;
6914                 }
6915                 ret = process_smbconf_service(service[count]);
6916                 if (!ret) {
6917                         goto done;
6918                 }
6919         }
6920
6921         /* store the csn */
6922         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6923
6924 done:
6925         TALLOC_FREE(mem_ctx);
6926         return ret;
6927 }
6928
6929 #define MAX_INCLUDE_DEPTH 100
6930
6931 static uint8_t include_depth;
6932
6933 static struct file_lists {
6934         struct file_lists *next;
6935         char *name;
6936         char *subfname;
6937         time_t modtime;
6938 } *file_lists = NULL;
6939
6940 /*******************************************************************
6941  Keep a linked list of all config files so we know when one has changed 
6942  it's date and needs to be reloaded.
6943 ********************************************************************/
6944
6945 static void add_to_file_list(const char *fname, const char *subfname)
6946 {
6947         struct file_lists *f = file_lists;
6948
6949         while (f) {
6950                 if (f->name && !strcmp(f->name, fname))
6951                         break;
6952                 f = f->next;
6953         }
6954
6955         if (!f) {
6956                 f = SMB_MALLOC_P(struct file_lists);
6957                 if (!f)
6958                         return;
6959                 f->next = file_lists;
6960                 f->name = SMB_STRDUP(fname);
6961                 if (!f->name) {
6962                         SAFE_FREE(f);
6963                         return;
6964                 }
6965                 f->subfname = SMB_STRDUP(subfname);
6966                 if (!f->subfname) {
6967                         SAFE_FREE(f);
6968                         return;
6969                 }
6970                 file_lists = f;
6971                 f->modtime = file_modtime(subfname);
6972         } else {
6973                 time_t t = file_modtime(subfname);
6974                 if (t)
6975                         f->modtime = t;
6976         }
6977 }
6978
6979 /**
6980  * Free the file lists
6981  */
6982 static void free_file_list(void)
6983 {
6984         struct file_lists *f;
6985         struct file_lists *next;
6986
6987         f = file_lists;
6988         while( f ) {
6989                 next = f->next;
6990                 SAFE_FREE( f->name );
6991                 SAFE_FREE( f->subfname );
6992                 SAFE_FREE( f );
6993                 f = next;
6994         }
6995         file_lists = NULL;
6996 }
6997
6998
6999 /**
7000  * Utility function for outsiders to check if we're running on registry.
7001  */
7002 bool lp_config_backend_is_registry(void)
7003 {
7004         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7005 }
7006
7007 /**
7008  * Utility function to check if the config backend is FILE.
7009  */
7010 bool lp_config_backend_is_file(void)
7011 {
7012         return (lp_config_backend() == CONFIG_BACKEND_FILE);
7013 }
7014
7015 /*******************************************************************
7016  Check if a config file has changed date.
7017 ********************************************************************/
7018
7019 bool lp_file_list_changed(void)
7020 {
7021         struct file_lists *f = file_lists;
7022
7023         DEBUG(6, ("lp_file_list_changed()\n"));
7024
7025         while (f) {
7026                 char *n2 = NULL;
7027                 time_t mod_time;
7028
7029                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7030                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7031
7032                         if (conf_ctx == NULL) {
7033                                 return false;
7034                         }
7035                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7036                                             NULL))
7037                         {
7038                                 DEBUGADD(6, ("registry config changed\n"));
7039                                 return true;
7040                         }
7041                 } else {
7042                         n2 = alloc_sub_basic(get_current_username(),
7043                                             current_user_info.domain,
7044                                             f->name);
7045                         if (!n2) {
7046                                 return false;
7047                         }
7048                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
7049                                      f->name, n2, ctime(&f->modtime)));
7050
7051                         mod_time = file_modtime(n2);
7052
7053                         if (mod_time &&
7054                             ((f->modtime != mod_time) ||
7055                              (f->subfname == NULL) ||
7056                              (strcmp(n2, f->subfname) != 0)))
7057                         {
7058                                 DEBUGADD(6,
7059                                          ("file %s modified: %s\n", n2,
7060                                           ctime(&mod_time)));
7061                                 f->modtime = mod_time;
7062                                 SAFE_FREE(f->subfname);
7063                                 f->subfname = n2; /* Passing ownership of
7064                                                      return from alloc_sub_basic
7065                                                      above. */
7066                                 return true;
7067                         }
7068                         SAFE_FREE(n2);
7069                 }
7070                 f = f->next;
7071         }
7072         return (False);
7073 }
7074
7075
7076 /***************************************************************************
7077  Run standard_sub_basic on netbios name... needed because global_myname
7078  is not accessed through any lp_ macro.
7079  Note: We must *NOT* use string_set() here as ptr points to global_myname.
7080 ***************************************************************************/
7081
7082 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7083 {
7084         bool ret;
7085         char *netbios_name = alloc_sub_basic(get_current_username(),
7086                                         current_user_info.domain,
7087                                         pszParmValue);
7088
7089         ret = set_global_myname(netbios_name);
7090         SAFE_FREE(netbios_name);
7091         string_set(&Globals.szNetbiosName,global_myname());
7092
7093         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7094                global_myname()));
7095
7096         return ret;
7097 }
7098
7099 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7100 {
7101         if (strcmp(*ptr, pszParmValue) != 0) {
7102                 string_set(ptr, pszParmValue);
7103                 init_iconv();
7104         }
7105         return True;
7106 }
7107
7108
7109
7110 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7111 {
7112         bool ret;
7113         
7114         ret = set_global_myworkgroup(pszParmValue);
7115         string_set(&Globals.szWorkgroup,lp_workgroup());
7116         
7117         return ret;
7118 }
7119
7120 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7121 {
7122         bool ret;
7123         
7124         ret = set_global_scope(pszParmValue);
7125         string_set(&Globals.szNetbiosScope,global_scope());
7126
7127         return ret;
7128 }
7129
7130 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7131 {
7132         TALLOC_FREE(Globals.szNetbiosAliases);
7133         Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7134         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7135 }
7136
7137 /***************************************************************************
7138  Handle the include operation.
7139 ***************************************************************************/
7140 static bool bAllowIncludeRegistry = true;
7141
7142 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7143 {
7144         char *fname;
7145
7146         if (include_depth >= MAX_INCLUDE_DEPTH) {
7147                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7148                           include_depth));
7149                 return false;
7150         }
7151
7152         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7153                 if (!bAllowIncludeRegistry) {
7154                         return true;
7155                 }
7156                 if (bInGlobalSection) {
7157                         bool ret;
7158                         include_depth++;
7159                         ret = process_registry_globals();
7160                         include_depth--;
7161                         return ret;
7162                 } else {
7163                         DEBUG(1, ("\"include = registry\" only effective "
7164                                   "in %s section\n", GLOBAL_NAME));
7165                         return false;
7166                 }
7167         }
7168
7169         fname = alloc_sub_basic(get_current_username(),
7170                                 current_user_info.domain,
7171                                 pszParmValue);
7172
7173         add_to_file_list(pszParmValue, fname);
7174
7175         string_set(ptr, fname);
7176
7177         if (file_exist(fname)) {
7178                 bool ret;
7179                 include_depth++;
7180                 ret = pm_process(fname, do_section, do_parameter, NULL);
7181                 include_depth--;
7182                 SAFE_FREE(fname);
7183                 return ret;
7184         }
7185
7186         DEBUG(2, ("Can't find include file %s\n", fname));
7187         SAFE_FREE(fname);
7188         return true;
7189 }
7190
7191 /***************************************************************************
7192  Handle the interpretation of the copy parameter.
7193 ***************************************************************************/
7194
7195 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7196 {
7197         bool bRetval;
7198         int iTemp;
7199         struct service serviceTemp;
7200
7201         string_set(ptr, pszParmValue);
7202
7203         init_service(&serviceTemp);
7204
7205         bRetval = False;
7206
7207         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7208
7209         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7210                 if (iTemp == iServiceIndex) {
7211                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7212                 } else {
7213                         copy_service(ServicePtrs[iServiceIndex],
7214                                      &serviceTemp,
7215                                      ServicePtrs[iServiceIndex]->copymap);
7216                         bRetval = True;
7217                 }
7218         } else {
7219                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7220                 bRetval = False;
7221         }
7222
7223         free_service(&serviceTemp);
7224         return (bRetval);
7225 }
7226
7227 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7228 {
7229         Globals.ldap_debug_level = lp_int(pszParmValue);
7230         init_ldap_debugging();
7231         return true;
7232 }
7233
7234 /***************************************************************************
7235  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
7236  parameters is:
7237
7238  [global]
7239
7240         idmap uid = 1000-1999
7241         idmap gid = 700-899
7242
7243  We only do simple parsing checks here.  The strings are parsed into useful
7244  structures in the idmap daemon code.
7245
7246 ***************************************************************************/
7247
7248 /* Some lp_ routines to return idmap [ug]id information */
7249
7250 static uid_t idmap_uid_low, idmap_uid_high;
7251 static gid_t idmap_gid_low, idmap_gid_high;
7252
7253 bool lp_idmap_uid(uid_t *low, uid_t *high)
7254 {
7255         if (idmap_uid_low == 0 || idmap_uid_high == 0)
7256                 return False;
7257
7258         if (low)
7259                 *low = idmap_uid_low;
7260
7261         if (high)
7262                 *high = idmap_uid_high;
7263
7264         return True;
7265 }
7266
7267 bool lp_idmap_gid(gid_t *low, gid_t *high)
7268 {
7269         if (idmap_gid_low == 0 || idmap_gid_high == 0)
7270                 return False;
7271
7272         if (low)
7273                 *low = idmap_gid_low;
7274
7275         if (high)
7276                 *high = idmap_gid_high;
7277
7278         return True;
7279 }
7280
7281 /* Do some simple checks on "idmap [ug]id" parameter values */
7282
7283 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7284 {
7285         uint32 low, high;
7286
7287         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7288                 return False;
7289
7290         /* Parse OK */
7291
7292         string_set(ptr, pszParmValue);
7293
7294         idmap_uid_low = low;
7295         idmap_uid_high = high;
7296
7297         return True;
7298 }
7299
7300 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7301 {
7302         uint32 low, high;
7303
7304         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7305                 return False;
7306
7307         /* Parse OK */
7308
7309         string_set(ptr, pszParmValue);
7310
7311         idmap_gid_low = low;
7312         idmap_gid_high = high;
7313
7314         return True;
7315 }
7316
7317 /***************************************************************************
7318  Handle the DEBUG level list.
7319 ***************************************************************************/
7320
7321 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7322 {
7323         string_set(ptr, pszParmValueIn);
7324         return debug_parse_levels(pszParmValueIn);
7325 }
7326
7327 /***************************************************************************
7328  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7329 ***************************************************************************/
7330
7331 static const char *append_ldap_suffix( const char *str )
7332 {
7333         const char *suffix_string;
7334
7335
7336         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7337                                         Globals.szLdapSuffix );
7338         if ( !suffix_string ) {
7339                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7340                 return "";
7341         }
7342
7343         return suffix_string;
7344 }
7345
7346 const char *lp_ldap_machine_suffix(void)
7347 {
7348         if (Globals.szLdapMachineSuffix[0])
7349                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7350
7351         return lp_string(Globals.szLdapSuffix);
7352 }
7353
7354 const char *lp_ldap_user_suffix(void)
7355 {
7356         if (Globals.szLdapUserSuffix[0])
7357                 return append_ldap_suffix(Globals.szLdapUserSuffix);
7358
7359         return lp_string(Globals.szLdapSuffix);
7360 }
7361
7362 const char *lp_ldap_group_suffix(void)
7363 {
7364         if (Globals.szLdapGroupSuffix[0])
7365                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7366
7367         return lp_string(Globals.szLdapSuffix);
7368 }
7369
7370 const char *lp_ldap_idmap_suffix(void)
7371 {
7372         if (Globals.szLdapIdmapSuffix[0])
7373                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7374
7375         return lp_string(Globals.szLdapSuffix);
7376 }
7377
7378 /****************************************************************************
7379  set the value for a P_ENUM
7380  ***************************************************************************/
7381
7382 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7383                               int *ptr )
7384 {
7385         int i;
7386
7387         for (i = 0; parm->enum_list[i].name; i++) {
7388                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7389                         *ptr = parm->enum_list[i].value;
7390                         return;
7391                 }
7392         }
7393         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7394                   pszParmValue, parm->label));
7395 }
7396
7397 /***************************************************************************
7398 ***************************************************************************/
7399
7400 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7401 {
7402         static int parm_num = -1;
7403         struct service *s;
7404
7405         if ( parm_num == -1 )
7406                 parm_num = map_parameter( "printing" );
7407
7408         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7409
7410         if ( snum < 0 )
7411                 s = &sDefault;
7412         else
7413                 s = ServicePtrs[snum];
7414
7415         init_printer_values( s );
7416
7417         return True;
7418 }
7419
7420
7421 /***************************************************************************
7422  Initialise a copymap.
7423 ***************************************************************************/
7424
7425 static void init_copymap(struct service *pservice)
7426 {
7427         int i;
7428         if (pservice->copymap) {
7429                 bitmap_free(pservice->copymap);
7430         }
7431         pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7432         if (!pservice->copymap)
7433                 DEBUG(0,
7434                       ("Couldn't allocate copymap!! (size %d)\n",
7435                        (int)NUMPARAMETERS));
7436         else
7437                 for (i = 0; i < NUMPARAMETERS; i++)
7438                         bitmap_set(pservice->copymap, i);
7439 }
7440
7441 /***************************************************************************
7442  Return the local pointer to a parameter given a service struct and the
7443  pointer into the default structure.
7444 ***************************************************************************/
7445
7446 static void *lp_local_ptr(struct service *service, void *ptr)
7447 {
7448         return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7449 }
7450
7451 /***************************************************************************
7452  Return the local pointer to a parameter given the service number and the 
7453  pointer into the default structure.
7454 ***************************************************************************/
7455
7456 void *lp_local_ptr_by_snum(int snum, void *ptr)
7457 {
7458         return lp_local_ptr(ServicePtrs[snum], ptr);
7459 }
7460
7461 /***************************************************************************
7462  Process a parameter for a particular service number. If snum < 0
7463  then assume we are in the globals.
7464 ***************************************************************************/
7465
7466 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7467 {
7468         int parmnum, i;
7469         void *parm_ptr = NULL;  /* where we are going to store the result */
7470         void *def_ptr = NULL;
7471         struct param_opt_struct **opt_list;
7472
7473         parmnum = map_parameter(pszParmName);
7474
7475         if (parmnum < 0) {
7476                 if (strchr(pszParmName, ':') == NULL) {
7477                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7478                                   pszParmName));
7479                         return (True);
7480                 }
7481
7482                 /*
7483                  * We've got a parametric option
7484                  */
7485
7486                 opt_list = (snum < 0)
7487                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7488                 set_param_opt(opt_list, pszParmName, pszParmValue);
7489
7490                 return (True);
7491         }
7492
7493         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7494                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7495                           pszParmName));
7496         }
7497
7498         def_ptr = parm_table[parmnum].ptr;
7499
7500         /* we might point at a service, the default service or a global */
7501         if (snum < 0) {
7502                 parm_ptr = def_ptr;
7503         } else {
7504                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7505                         DEBUG(0,
7506                               ("Global parameter %s found in service section!\n",
7507                                pszParmName));
7508                         return (True);
7509                 }
7510                 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7511         }
7512
7513         if (snum >= 0) {
7514                 if (!ServicePtrs[snum]->copymap)
7515                         init_copymap(ServicePtrs[snum]);
7516
7517                 /* this handles the aliases - set the copymap for other entries with
7518                    the same data pointer */
7519                 for (i = 0; parm_table[i].label; i++)
7520                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7521                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7522         }
7523
7524         /* if it is a special case then go ahead */
7525         if (parm_table[parmnum].special) {
7526                 return parm_table[parmnum].special(snum, pszParmValue,
7527                                                    (char **)parm_ptr);
7528         }
7529
7530         /* now switch on the type of variable it is */
7531         switch (parm_table[parmnum].type)
7532         {
7533                 case P_BOOL:
7534                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7535                         break;
7536
7537                 case P_BOOLREV:
7538                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7539                         break;
7540
7541                 case P_INTEGER:
7542                         *(int *)parm_ptr = lp_int(pszParmValue);
7543                         break;
7544
7545                 case P_CHAR:
7546                         *(char *)parm_ptr = *pszParmValue;
7547                         break;
7548
7549                 case P_OCTAL:
7550                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7551                         if ( i != 1 ) {
7552                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7553                         }
7554                         break;
7555
7556                 case P_LIST:
7557                         TALLOC_FREE(*((char ***)parm_ptr));
7558                         *(char ***)parm_ptr = str_list_make_v3(
7559                                 talloc_autofree_context(), pszParmValue, NULL);
7560                         break;
7561
7562                 case P_STRING:
7563                         string_set((char **)parm_ptr, pszParmValue);
7564                         break;
7565
7566                 case P_USTRING:
7567                         string_set((char **)parm_ptr, pszParmValue);
7568                         strupper_m(*(char **)parm_ptr);
7569                         break;
7570
7571                 case P_ENUM:
7572                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7573                         break;
7574                 case P_SEP:
7575                         break;
7576         }
7577
7578         return (True);
7579 }
7580
7581 /***************************************************************************
7582  Process a parameter.
7583 ***************************************************************************/
7584
7585 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7586                          void *userdata)
7587 {
7588         if (!bInGlobalSection && bGlobalOnly)
7589                 return (True);
7590
7591         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7592
7593         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7594                                 pszParmName, pszParmValue));
7595 }
7596
7597 /***************************************************************************
7598  Print a parameter of the specified type.
7599 ***************************************************************************/
7600
7601 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7602 {
7603         int i;
7604         switch (p->type)
7605         {
7606                 case P_ENUM:
7607                         for (i = 0; p->enum_list[i].name; i++) {
7608                                 if (*(int *)ptr == p->enum_list[i].value) {
7609                                         fprintf(f, "%s",
7610                                                 p->enum_list[i].name);
7611                                         break;
7612                                 }
7613                         }
7614                         break;
7615
7616                 case P_BOOL:
7617                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7618                         break;
7619
7620                 case P_BOOLREV:
7621                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7622                         break;
7623
7624                 case P_INTEGER:
7625                         fprintf(f, "%d", *(int *)ptr);
7626                         break;
7627
7628                 case P_CHAR:
7629                         fprintf(f, "%c", *(char *)ptr);
7630                         break;
7631
7632                 case P_OCTAL: {
7633                         char *o = octal_string(*(int *)ptr);
7634                         fprintf(f, "%s", o);
7635                         TALLOC_FREE(o);
7636                         break;
7637                 }
7638
7639                 case P_LIST:
7640                         if ((char ***)ptr && *(char ***)ptr) {
7641                                 char **list = *(char ***)ptr;
7642                                 for (; *list; list++) {
7643                                         /* surround strings with whitespace in double quotes */
7644                                         if ( strchr_m( *list, ' ' ) )
7645                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7646                                         else
7647                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7648                                 }
7649                         }
7650                         break;
7651
7652                 case P_STRING:
7653                 case P_USTRING:
7654                         if (*(char **)ptr) {
7655                                 fprintf(f, "%s", *(char **)ptr);
7656                         }
7657                         break;
7658                 case P_SEP:
7659                         break;
7660         }
7661 }
7662
7663 /***************************************************************************
7664  Check if two parameters are equal.
7665 ***************************************************************************/
7666
7667 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7668 {
7669         switch (type) {
7670                 case P_BOOL:
7671                 case P_BOOLREV:
7672                         return (*((bool *)ptr1) == *((bool *)ptr2));
7673
7674                 case P_INTEGER:
7675                 case P_ENUM:
7676                 case P_OCTAL:
7677                         return (*((int *)ptr1) == *((int *)ptr2));
7678
7679                 case P_CHAR:
7680                         return (*((char *)ptr1) == *((char *)ptr2));
7681
7682                 case P_LIST:
7683                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7684
7685                 case P_STRING:
7686                 case P_USTRING:
7687                 {
7688                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7689                         if (p1 && !*p1)
7690                                 p1 = NULL;
7691                         if (p2 && !*p2)
7692                                 p2 = NULL;
7693                         return (p1 == p2 || strequal(p1, p2));
7694                 }
7695                 case P_SEP:
7696                         break;
7697         }
7698         return (False);
7699 }
7700
7701 /***************************************************************************
7702  Initialize any local varients in the sDefault table.
7703 ***************************************************************************/
7704
7705 void init_locals(void)
7706 {
7707         /* None as yet. */
7708 }
7709
7710 /***************************************************************************
7711  Process a new section (service). At this stage all sections are services.
7712  Later we'll have special sections that permit server parameters to be set.
7713  Returns True on success, False on failure. 
7714 ***************************************************************************/
7715
7716 static bool do_section(const char *pszSectionName, void *userdata)
7717 {
7718         bool bRetval;
7719         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7720                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7721         bRetval = False;
7722
7723         /* if we were in a global section then do the local inits */
7724         if (bInGlobalSection && !isglobal)
7725                 init_locals();
7726
7727         /* if we've just struck a global section, note the fact. */
7728         bInGlobalSection = isglobal;
7729
7730         /* check for multiple global sections */
7731         if (bInGlobalSection) {
7732                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7733                 return (True);
7734         }
7735
7736         if (!bInGlobalSection && bGlobalOnly)
7737                 return (True);
7738
7739         /* if we have a current service, tidy it up before moving on */
7740         bRetval = True;
7741
7742         if (iServiceIndex >= 0)
7743                 bRetval = service_ok(iServiceIndex);
7744
7745         /* if all is still well, move to the next record in the services array */
7746         if (bRetval) {
7747                 /* We put this here to avoid an odd message order if messages are */
7748                 /* issued by the post-processing of a previous section. */
7749                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7750
7751                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7752                     < 0) {
7753                         DEBUG(0, ("Failed to add a new service\n"));
7754                         return (False);
7755                 }
7756         }
7757
7758         return (bRetval);
7759 }
7760
7761
7762 /***************************************************************************
7763  Determine if a partcular base parameter is currentl set to the default value.
7764 ***************************************************************************/
7765
7766 static bool is_default(int i)
7767 {
7768         if (!defaults_saved)
7769                 return False;
7770         switch (parm_table[i].type) {
7771                 case P_LIST:
7772                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
7773                                                 *(const char ***)parm_table[i].ptr);
7774                 case P_STRING:
7775                 case P_USTRING:
7776                         return strequal(parm_table[i].def.svalue,
7777                                         *(char **)parm_table[i].ptr);
7778                 case P_BOOL:
7779                 case P_BOOLREV:
7780                         return parm_table[i].def.bvalue ==
7781                                 *(bool *)parm_table[i].ptr;
7782                 case P_CHAR:
7783                         return parm_table[i].def.cvalue ==
7784                                 *(char *)parm_table[i].ptr;
7785                 case P_INTEGER:
7786                 case P_OCTAL:
7787                 case P_ENUM:
7788                         return parm_table[i].def.ivalue ==
7789                                 *(int *)parm_table[i].ptr;
7790                 case P_SEP:
7791                         break;
7792         }
7793         return False;
7794 }
7795
7796 /***************************************************************************
7797 Display the contents of the global structure.
7798 ***************************************************************************/
7799
7800 static void dump_globals(FILE *f)
7801 {
7802         int i;
7803         struct param_opt_struct *data;
7804         
7805         fprintf(f, "[global]\n");
7806
7807         for (i = 0; parm_table[i].label; i++)
7808                 if (parm_table[i].p_class == P_GLOBAL &&
7809                     !(parm_table[i].flags & FLAG_META) &&
7810                     parm_table[i].ptr &&
7811                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7812                         if (defaults_saved && is_default(i))
7813                                 continue;
7814                         fprintf(f, "\t%s = ", parm_table[i].label);
7815                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
7816                         fprintf(f, "\n");
7817         }
7818         if (Globals.param_opt != NULL) {
7819                 data = Globals.param_opt;
7820                 while(data) {
7821                         fprintf(f, "\t%s = %s\n", data->key, data->value);
7822                         data = data->next;
7823                 }
7824         }
7825
7826 }
7827
7828 /***************************************************************************
7829  Return True if a local parameter is currently set to the global default.
7830 ***************************************************************************/
7831
7832 bool lp_is_default(int snum, struct parm_struct *parm)
7833 {
7834         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7835
7836         return equal_parameter(parm->type,
7837                                ((char *)ServicePtrs[snum]) + pdiff,
7838                                ((char *)&sDefault) + pdiff);
7839 }
7840
7841 /***************************************************************************
7842  Display the contents of a single services record.
7843 ***************************************************************************/
7844
7845 static void dump_a_service(struct service *pService, FILE * f)
7846 {
7847         int i;
7848         struct param_opt_struct *data;
7849         
7850         if (pService != &sDefault)
7851                 fprintf(f, "[%s]\n", pService->szService);
7852
7853         for (i = 0; parm_table[i].label; i++) {
7854
7855                 if (parm_table[i].p_class == P_LOCAL &&
7856                     !(parm_table[i].flags & FLAG_META) &&
7857                     parm_table[i].ptr &&
7858                     (*parm_table[i].label != '-') &&
7859                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7860                 {
7861                 
7862                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7863
7864                         if (pService == &sDefault) {
7865                                 if (defaults_saved && is_default(i))
7866                                         continue;
7867                         } else {
7868                                 if (equal_parameter(parm_table[i].type,
7869                                                     ((char *)pService) +
7870                                                     pdiff,
7871                                                     ((char *)&sDefault) +
7872                                                     pdiff))
7873                                         continue;
7874                         }
7875
7876                         fprintf(f, "\t%s = ", parm_table[i].label);
7877                         print_parameter(&parm_table[i],
7878                                         ((char *)pService) + pdiff, f);
7879                         fprintf(f, "\n");
7880                 }
7881         }
7882
7883                 if (pService->param_opt != NULL) {
7884                         data = pService->param_opt;
7885                         while(data) {
7886                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
7887                                 data = data->next;
7888                         }
7889                 }
7890 }
7891
7892 /***************************************************************************
7893  Display the contents of a parameter of a single services record.
7894 ***************************************************************************/
7895
7896 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7897 {
7898         int i;
7899         bool result = False;
7900         parm_class p_class;
7901         unsigned flag = 0;
7902         fstring local_parm_name;
7903         char *parm_opt;
7904         const char *parm_opt_value;
7905
7906         /* check for parametrical option */
7907         fstrcpy( local_parm_name, parm_name);
7908         parm_opt = strchr( local_parm_name, ':');
7909
7910         if (parm_opt) {
7911                 *parm_opt = '\0';
7912                 parm_opt++;
7913                 if (strlen(parm_opt)) {
7914                         parm_opt_value = lp_parm_const_string( snum,
7915                                 local_parm_name, parm_opt, NULL);
7916                         if (parm_opt_value) {
7917                                 printf( "%s\n", parm_opt_value);
7918                                 result = True;
7919                         }
7920                 }
7921                 return result;
7922         }
7923
7924         /* check for a key and print the value */
7925         if (isGlobal) {
7926                 p_class = P_GLOBAL;
7927                 flag = FLAG_GLOBAL;
7928         } else
7929                 p_class = P_LOCAL;
7930
7931         for (i = 0; parm_table[i].label; i++) {
7932                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7933                     !(parm_table[i].flags & FLAG_META) &&
7934                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7935                     parm_table[i].ptr &&
7936                     (*parm_table[i].label != '-') &&
7937                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7938                 {
7939                         void *ptr;
7940
7941                         if (isGlobal) {
7942                                 ptr = parm_table[i].ptr;
7943                         } else {
7944                                 struct service *pService = ServicePtrs[snum];
7945                                 ptr = ((char *)pService) +
7946                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
7947                         }
7948
7949                         print_parameter(&parm_table[i],
7950                                         ptr, f);
7951                         fprintf(f, "\n");
7952                         result = True;
7953                         break;
7954                 }
7955         }
7956
7957         return result;
7958 }
7959
7960 /***************************************************************************
7961  Return info about the requested parameter (given as a string).
7962  Return NULL when the string is not a valid parameter name.
7963 ***************************************************************************/
7964
7965 struct parm_struct *lp_get_parameter(const char *param_name)
7966 {
7967         int num = map_parameter(param_name);
7968
7969         if (num < 0) {
7970                 return NULL;
7971         }
7972
7973         return &parm_table[num];
7974 }
7975
7976 /***************************************************************************
7977  Return info about the next parameter in a service.
7978  snum==GLOBAL_SECTION_SNUM gives the globals.
7979  Return NULL when out of parameters.
7980 ***************************************************************************/
7981
7982 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7983 {
7984         if (snum < 0) {
7985                 /* do the globals */
7986                 for (; parm_table[*i].label; (*i)++) {
7987                         if (parm_table[*i].p_class == P_SEPARATOR)
7988                                 return &parm_table[(*i)++];
7989
7990                         if (!parm_table[*i].ptr
7991                             || (*parm_table[*i].label == '-'))
7992                                 continue;
7993
7994                         if ((*i) > 0
7995                             && (parm_table[*i].ptr ==
7996                                 parm_table[(*i) - 1].ptr))
7997                                 continue;
7998                         
7999                         if (is_default(*i) && !allparameters)
8000                                 continue;
8001
8002                         return &parm_table[(*i)++];
8003                 }
8004         } else {
8005                 struct service *pService = ServicePtrs[snum];
8006
8007                 for (; parm_table[*i].label; (*i)++) {
8008                         if (parm_table[*i].p_class == P_SEPARATOR)
8009                                 return &parm_table[(*i)++];
8010
8011                         if (parm_table[*i].p_class == P_LOCAL &&
8012                             parm_table[*i].ptr &&
8013                             (*parm_table[*i].label != '-') &&
8014                             ((*i) == 0 ||
8015                              (parm_table[*i].ptr !=
8016                               parm_table[(*i) - 1].ptr)))
8017                         {
8018                                 int pdiff =
8019                                         PTR_DIFF(parm_table[*i].ptr,
8020                                                  &sDefault);
8021
8022                                 if (allparameters ||
8023                                     !equal_parameter(parm_table[*i].type,
8024                                                      ((char *)pService) +
8025                                                      pdiff,
8026                                                      ((char *)&sDefault) +
8027                                                      pdiff))
8028                                 {
8029                                         return &parm_table[(*i)++];
8030                                 }
8031                         }
8032                 }
8033         }
8034
8035         return NULL;
8036 }
8037
8038
8039 #if 0
8040 /***************************************************************************
8041  Display the contents of a single copy structure.
8042 ***************************************************************************/
8043 static void dump_copy_map(bool *pcopymap)
8044 {
8045         int i;
8046         if (!pcopymap)
8047                 return;
8048
8049         printf("\n\tNon-Copied parameters:\n");
8050
8051         for (i = 0; parm_table[i].label; i++)
8052                 if (parm_table[i].p_class == P_LOCAL &&
8053                     parm_table[i].ptr && !pcopymap[i] &&
8054                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8055                 {
8056                         printf("\t\t%s\n", parm_table[i].label);
8057                 }
8058 }
8059 #endif
8060
8061 /***************************************************************************
8062  Return TRUE if the passed service number is within range.
8063 ***************************************************************************/
8064
8065 bool lp_snum_ok(int iService)
8066 {
8067         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8068 }
8069
8070 /***************************************************************************
8071  Auto-load some home services.
8072 ***************************************************************************/
8073
8074 static void lp_add_auto_services(char *str)
8075 {
8076         char *s;
8077         char *p;
8078         int homes;
8079         char *saveptr;
8080
8081         if (!str)
8082                 return;
8083
8084         s = SMB_STRDUP(str);
8085         if (!s)
8086                 return;
8087
8088         homes = lp_servicenumber(HOMES_NAME);
8089
8090         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8091              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8092                 char *home;
8093
8094                 if (lp_servicenumber(p) >= 0)
8095                         continue;
8096
8097                 home = get_user_home_dir(talloc_tos(), p);
8098
8099                 if (home && homes >= 0)
8100                         lp_add_home(p, homes, p, home);
8101
8102                 TALLOC_FREE(home);
8103         }
8104         SAFE_FREE(s);
8105 }
8106
8107 /***************************************************************************
8108  Auto-load one printer.
8109 ***************************************************************************/
8110
8111 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8112 {
8113         int printers = lp_servicenumber(PRINTERS_NAME);
8114         int i;
8115
8116         if (lp_servicenumber(name) < 0) {
8117                 lp_add_printer(name, printers);
8118                 if ((i = lp_servicenumber(name)) >= 0) {
8119                         string_set(&ServicePtrs[i]->comment, comment);
8120                         ServicePtrs[i]->autoloaded = True;
8121                 }
8122         }
8123 }
8124
8125 /***************************************************************************
8126  Have we loaded a services file yet?
8127 ***************************************************************************/
8128
8129 bool lp_loaded(void)
8130 {
8131         return (bLoaded);
8132 }
8133
8134 /***************************************************************************
8135  Unload unused services.
8136 ***************************************************************************/
8137
8138 void lp_killunused(bool (*snumused) (int))
8139 {
8140         int i;
8141         for (i = 0; i < iNumServices; i++) {
8142                 if (!VALID(i))
8143                         continue;
8144
8145                 /* don't kill autoloaded or usershare services */
8146                 if ( ServicePtrs[i]->autoloaded ||
8147                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8148                         continue;
8149                 }
8150
8151                 if (!snumused || !snumused(i)) {
8152                         free_service_byindex(i);
8153                 }
8154         }
8155 }
8156
8157 /**
8158  * Kill all except autoloaded and usershare services - convenience wrapper
8159  */
8160 void lp_kill_all_services(void)
8161 {
8162         lp_killunused(NULL);
8163 }
8164
8165 /***************************************************************************
8166  Unload a service.
8167 ***************************************************************************/
8168
8169 void lp_killservice(int iServiceIn)
8170 {
8171         if (VALID(iServiceIn)) {
8172                 free_service_byindex(iServiceIn);
8173         }
8174 }
8175
8176 /***************************************************************************
8177  Save the curent values of all global and sDefault parameters into the 
8178  defaults union. This allows swat and testparm to show only the
8179  changed (ie. non-default) parameters.
8180 ***************************************************************************/
8181
8182 static void lp_save_defaults(void)
8183 {
8184         int i;
8185         for (i = 0; parm_table[i].label; i++) {
8186                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8187                         continue;
8188                 switch (parm_table[i].type) {
8189                         case P_LIST:
8190                                 parm_table[i].def.lvalue = str_list_copy(
8191                                         NULL, *(const char ***)parm_table[i].ptr);
8192                                 break;
8193                         case P_STRING:
8194                         case P_USTRING:
8195                                 if (parm_table[i].ptr) {
8196                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8197                                 } else {
8198                                         parm_table[i].def.svalue = NULL;
8199                                 }
8200                                 break;
8201                         case P_BOOL:
8202                         case P_BOOLREV:
8203                                 parm_table[i].def.bvalue =
8204                                         *(bool *)parm_table[i].ptr;
8205                                 break;
8206                         case P_CHAR:
8207                                 parm_table[i].def.cvalue =
8208                                         *(char *)parm_table[i].ptr;
8209                                 break;
8210                         case P_INTEGER:
8211                         case P_OCTAL:
8212                         case P_ENUM:
8213                                 parm_table[i].def.ivalue =
8214                                         *(int *)parm_table[i].ptr;
8215                                 break;
8216                         case P_SEP:
8217                                 break;
8218                 }
8219         }
8220         defaults_saved = True;
8221 }
8222
8223 /*******************************************************************
8224  Set the server type we will announce as via nmbd.
8225 ********************************************************************/
8226
8227 static const struct srv_role_tab {
8228         uint32 role;
8229         const char *role_str;
8230 } srv_role_tab [] = {
8231         { ROLE_STANDALONE, "ROLE_STANDALONE" },
8232         { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8233         { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8234         { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8235         { 0, NULL }
8236 };
8237
8238 const char* server_role_str(uint32 role)
8239 {
8240         int i = 0;
8241         for (i=0; srv_role_tab[i].role_str; i++) {
8242                 if (role == srv_role_tab[i].role) {
8243                         return srv_role_tab[i].role_str;
8244                 }
8245         }
8246         return NULL;
8247 }
8248
8249 static void set_server_role(void)
8250 {
8251         server_role = ROLE_STANDALONE;
8252
8253         switch (lp_security()) {
8254                 case SEC_SHARE:
8255                         if (lp_domain_logons())
8256                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8257                         break;
8258                 case SEC_SERVER:
8259                         if (lp_domain_logons())
8260                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8261                         /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8262                         server_role = ROLE_STANDALONE;
8263                         break;
8264                 case SEC_DOMAIN:
8265                         if (lp_domain_logons()) {
8266                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8267                                 server_role = ROLE_DOMAIN_BDC;
8268                                 break;
8269                         }
8270                         server_role = ROLE_DOMAIN_MEMBER;
8271                         break;
8272                 case SEC_ADS:
8273                         if (lp_domain_logons()) {
8274                                 server_role = ROLE_DOMAIN_PDC;
8275                                 break;
8276                         }
8277                         server_role = ROLE_DOMAIN_MEMBER;
8278                         break;
8279                 case SEC_USER:
8280                         if (lp_domain_logons()) {
8281
8282                                 if (Globals.iDomainMaster) /* auto or yes */ 
8283                                         server_role = ROLE_DOMAIN_PDC;
8284                                 else
8285                                         server_role = ROLE_DOMAIN_BDC;
8286                         }
8287                         break;
8288                 default:
8289                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8290                         break;
8291         }
8292
8293         DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8294 }
8295
8296 /***********************************************************
8297  If we should send plaintext/LANMAN passwords in the clinet
8298 ************************************************************/
8299
8300 static void set_allowed_client_auth(void)
8301 {
8302         if (Globals.bClientNTLMv2Auth) {
8303                 Globals.bClientLanManAuth = False;
8304         }
8305         if (!Globals.bClientLanManAuth) {
8306                 Globals.bClientPlaintextAuth = False;
8307         }
8308 }
8309
8310 /***************************************************************************
8311  JRA.
8312  The following code allows smbd to read a user defined share file.
8313  Yes, this is my intent. Yes, I'm comfortable with that...
8314
8315  THE FOLLOWING IS SECURITY CRITICAL CODE.
8316
8317  It washes your clothes, it cleans your house, it guards you while you sleep...
8318  Do not f%^k with it....
8319 ***************************************************************************/
8320
8321 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8322
8323 /***************************************************************************
8324  Check allowed stat state of a usershare file.
8325  Ensure we print out who is dicking with us so the admin can
8326  get their sorry ass fired.
8327 ***************************************************************************/
8328
8329 static bool check_usershare_stat(const char *fname,
8330                                  const SMB_STRUCT_STAT *psbuf)
8331 {
8332         if (!S_ISREG(psbuf->st_ex_mode)) {
8333                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8334                         "not a regular file\n",
8335                         fname, (unsigned int)psbuf->st_ex_uid ));
8336                 return False;
8337         }
8338
8339         /* Ensure this doesn't have the other write bit set. */
8340         if (psbuf->st_ex_mode & S_IWOTH) {
8341                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8342                         "public write. Refusing to allow as a usershare file.\n",
8343                         fname, (unsigned int)psbuf->st_ex_uid ));
8344                 return False;
8345         }
8346
8347         /* Should be 10k or less. */
8348         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8349                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8350                         "too large (%u) to be a user share file.\n",
8351                         fname, (unsigned int)psbuf->st_ex_uid,
8352                         (unsigned int)psbuf->st_ex_size ));
8353                 return False;
8354         }
8355
8356         return True;
8357 }
8358
8359 /***************************************************************************
8360  Parse the contents of a usershare file.
8361 ***************************************************************************/
8362
8363 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8364                         SMB_STRUCT_STAT *psbuf,
8365                         const char *servicename,
8366                         int snum,
8367                         char **lines,
8368                         int numlines,
8369                         char **pp_sharepath,
8370                         char **pp_comment,
8371                         SEC_DESC **ppsd,
8372                         bool *pallow_guest)
8373 {
8374         const char **prefixallowlist = lp_usershare_prefix_allow_list();
8375         const char **prefixdenylist = lp_usershare_prefix_deny_list();
8376         int us_vers;
8377         SMB_STRUCT_DIR *dp;
8378         SMB_STRUCT_STAT sbuf;
8379         char *sharepath = NULL;
8380         char *comment = NULL;
8381
8382         *pp_sharepath = NULL;
8383         *pp_comment = NULL;
8384
8385         *pallow_guest = False;
8386
8387         if (numlines < 4) {
8388                 return USERSHARE_MALFORMED_FILE;
8389         }
8390
8391         if (strcmp(lines[0], "#VERSION 1") == 0) {
8392                 us_vers = 1;
8393         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8394                 us_vers = 2;
8395                 if (numlines < 5) {
8396                         return USERSHARE_MALFORMED_FILE;
8397                 }
8398         } else {
8399                 return USERSHARE_BAD_VERSION;
8400         }
8401
8402         if (strncmp(lines[1], "path=", 5) != 0) {
8403                 return USERSHARE_MALFORMED_PATH;
8404         }
8405
8406         sharepath = talloc_strdup(ctx, &lines[1][5]);
8407         if (!sharepath) {
8408                 return USERSHARE_POSIX_ERR;
8409         }
8410         trim_string(sharepath, " ", " ");
8411
8412         if (strncmp(lines[2], "comment=", 8) != 0) {
8413                 return USERSHARE_MALFORMED_COMMENT_DEF;
8414         }
8415
8416         comment = talloc_strdup(ctx, &lines[2][8]);
8417         if (!comment) {
8418                 return USERSHARE_POSIX_ERR;
8419         }
8420         trim_string(comment, " ", " ");
8421         trim_char(comment, '"', '"');
8422
8423         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8424                 return USERSHARE_MALFORMED_ACL_DEF;
8425         }
8426
8427         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8428                 return USERSHARE_ACL_ERR;
8429         }
8430
8431         if (us_vers == 2) {
8432                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8433                         return USERSHARE_MALFORMED_ACL_DEF;
8434                 }
8435                 if (lines[4][9] == 'y') {
8436                         *pallow_guest = True;
8437                 }
8438         }
8439
8440         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8441                 /* Path didn't change, no checks needed. */
8442                 *pp_sharepath = sharepath;
8443                 *pp_comment = comment;
8444                 return USERSHARE_OK;
8445         }
8446
8447         /* The path *must* be absolute. */
8448         if (sharepath[0] != '/') {
8449                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8450                         servicename, sharepath));
8451                 return USERSHARE_PATH_NOT_ABSOLUTE;
8452         }
8453
8454         /* If there is a usershare prefix deny list ensure one of these paths
8455            doesn't match the start of the user given path. */
8456         if (prefixdenylist) {
8457                 int i;
8458                 for ( i=0; prefixdenylist[i]; i++ ) {
8459                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8460                                 servicename, i, prefixdenylist[i], sharepath ));
8461                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8462                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8463                                         "usershare prefix deny list entries.\n",
8464                                         servicename, sharepath));
8465                                 return USERSHARE_PATH_IS_DENIED;
8466                         }
8467                 }
8468         }
8469
8470         /* If there is a usershare prefix allow list ensure one of these paths
8471            does match the start of the user given path. */
8472
8473         if (prefixallowlist) {
8474                 int i;
8475                 for ( i=0; prefixallowlist[i]; i++ ) {
8476                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8477                                 servicename, i, prefixallowlist[i], sharepath ));
8478                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8479                                 break;
8480                         }
8481                 }
8482                 if (prefixallowlist[i] == NULL) {
8483                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8484                                 "usershare prefix allow list entries.\n",
8485                                 servicename, sharepath));
8486                         return USERSHARE_PATH_NOT_ALLOWED;
8487                 }
8488         }
8489
8490         /* Ensure this is pointing to a directory. */
8491         dp = sys_opendir(sharepath);
8492
8493         if (!dp) {
8494                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8495                         servicename, sharepath));
8496                 return USERSHARE_PATH_NOT_DIRECTORY;
8497         }
8498
8499         /* Ensure the owner of the usershare file has permission to share
8500            this directory. */
8501
8502         if (sys_stat(sharepath, &sbuf) == -1) {
8503                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8504                         servicename, sharepath, strerror(errno) ));
8505                 sys_closedir(dp);
8506                 return USERSHARE_POSIX_ERR;
8507         }
8508
8509         sys_closedir(dp);
8510
8511         if (!S_ISDIR(sbuf.st_ex_mode)) {
8512                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8513                         servicename, sharepath ));
8514                 return USERSHARE_PATH_NOT_DIRECTORY;
8515         }
8516
8517         /* Check if sharing is restricted to owner-only. */
8518         /* psbuf is the stat of the usershare definition file,
8519            sbuf is the stat of the target directory to be shared. */
8520
8521         if (lp_usershare_owner_only()) {
8522                 /* root can share anything. */
8523                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8524                         return USERSHARE_PATH_NOT_ALLOWED;
8525                 }
8526         }
8527
8528         *pp_sharepath = sharepath;
8529         *pp_comment = comment;
8530         return USERSHARE_OK;
8531 }
8532
8533 /***************************************************************************
8534  Deal with a usershare file.
8535  Returns:
8536         >= 0 - snum
8537         -1 - Bad name, invalid contents.
8538            - service name already existed and not a usershare, problem
8539             with permissions to share directory etc.
8540 ***************************************************************************/
8541
8542 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8543 {
8544         SMB_STRUCT_STAT sbuf;
8545         SMB_STRUCT_STAT lsbuf;
8546         char *fname = NULL;
8547         char *sharepath = NULL;
8548         char *comment = NULL;
8549         fstring service_name;
8550         char **lines = NULL;
8551         int numlines = 0;
8552         int fd = -1;
8553         int iService = -1;
8554         TALLOC_CTX *ctx = NULL;
8555         SEC_DESC *psd = NULL;
8556         bool guest_ok = False;
8557
8558         /* Ensure share name doesn't contain invalid characters. */
8559         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8560                 DEBUG(0,("process_usershare_file: share name %s contains "
8561                         "invalid characters (any of %s)\n",
8562                         file_name, INVALID_SHARENAME_CHARS ));
8563                 return -1;
8564         }
8565
8566         fstrcpy(service_name, file_name);
8567
8568         if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8569         }
8570
8571         /* Minimize the race condition by doing an lstat before we
8572            open and fstat. Ensure this isn't a symlink link. */
8573
8574         if (sys_lstat(fname, &lsbuf) != 0) {
8575                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8576                         fname, strerror(errno) ));
8577                 SAFE_FREE(fname);
8578                 return -1;
8579         }
8580
8581         /* This must be a regular file, not a symlink, directory or
8582            other strange filetype. */
8583         if (!check_usershare_stat(fname, &lsbuf)) {
8584                 SAFE_FREE(fname);
8585                 return -1;
8586         }
8587
8588         {
8589                 char *canon_name = canonicalize_servicename(service_name);
8590                 TDB_DATA data = dbwrap_fetch_bystring(
8591                         ServiceHash, canon_name, canon_name);
8592
8593                 iService = -1;
8594
8595                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8596                         iService = *(int *)data.dptr;
8597                 }
8598                 TALLOC_FREE(canon_name);
8599         }
8600
8601         if (iService != -1 &&
8602             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8603                              &lsbuf.st_ex_mtime) == 0) {
8604                 /* Nothing changed - Mark valid and return. */
8605                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8606                         service_name ));
8607                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8608                 SAFE_FREE(fname);
8609                 return iService;
8610         }
8611
8612         /* Try and open the file read only - no symlinks allowed. */
8613 #ifdef O_NOFOLLOW
8614         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8615 #else
8616         fd = sys_open(fname, O_RDONLY, 0);
8617 #endif
8618
8619         if (fd == -1) {
8620                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8621                         fname, strerror(errno) ));
8622                 SAFE_FREE(fname);
8623                 return -1;
8624         }
8625
8626         /* Now fstat to be *SURE* it's a regular file. */
8627         if (sys_fstat(fd, &sbuf) != 0) {
8628                 close(fd);
8629                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8630                         fname, strerror(errno) ));
8631                 SAFE_FREE(fname);
8632                 return -1;
8633         }
8634
8635         /* Is it the same dev/inode as was lstated ? */
8636         if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8637                 close(fd);
8638                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8639                         "Symlink spoofing going on ?\n", fname ));
8640                 SAFE_FREE(fname);
8641                 return -1;
8642         }
8643
8644         /* This must be a regular file, not a symlink, directory or
8645            other strange filetype. */
8646         if (!check_usershare_stat(fname, &sbuf)) {
8647                 SAFE_FREE(fname);
8648                 return -1;
8649         }
8650
8651         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8652
8653         close(fd);
8654         if (lines == NULL) {
8655                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8656                         fname, (unsigned int)sbuf.st_ex_uid ));
8657                 SAFE_FREE(fname);
8658                 return -1;
8659         }
8660
8661         SAFE_FREE(fname);
8662
8663         /* Should we allow printers to be shared... ? */
8664         ctx = talloc_init("usershare_sd_xctx");
8665         if (!ctx) {
8666                 TALLOC_FREE(lines);
8667                 return 1;
8668         }
8669
8670         if (parse_usershare_file(ctx, &sbuf, service_name,
8671                         iService, lines, numlines, &sharepath,
8672                         &comment, &psd, &guest_ok) != USERSHARE_OK) {
8673                 talloc_destroy(ctx);
8674                 TALLOC_FREE(lines);
8675                 return -1;
8676         }
8677
8678         TALLOC_FREE(lines);
8679
8680         /* Everything ok - add the service possibly using a template. */
8681         if (iService < 0) {
8682                 const struct service *sp = &sDefault;
8683                 if (snum_template != -1) {
8684                         sp = ServicePtrs[snum_template];
8685                 }
8686
8687                 if ((iService = add_a_service(sp, service_name)) < 0) {
8688                         DEBUG(0, ("process_usershare_file: Failed to add "
8689                                 "new service %s\n", service_name));
8690                         talloc_destroy(ctx);
8691                         return -1;
8692                 }
8693
8694                 /* Read only is controlled by usershare ACL below. */
8695                 ServicePtrs[iService]->bRead_only = False;
8696         }
8697
8698         /* Write the ACL of the new/modified share. */
8699         if (!set_share_security(service_name, psd)) {
8700                  DEBUG(0, ("process_usershare_file: Failed to set share "
8701                         "security for user share %s\n",
8702                         service_name ));
8703                 lp_remove_service(iService);
8704                 talloc_destroy(ctx);
8705                 return -1;
8706         }
8707
8708         /* If from a template it may be marked invalid. */
8709         ServicePtrs[iService]->valid = True;
8710
8711         /* Set the service as a valid usershare. */
8712         ServicePtrs[iService]->usershare = USERSHARE_VALID;
8713
8714         /* Set guest access. */
8715         if (lp_usershare_allow_guests()) {
8716                 ServicePtrs[iService]->bGuest_ok = guest_ok;
8717         }
8718
8719         /* And note when it was loaded. */
8720         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8721         string_set(&ServicePtrs[iService]->szPath, sharepath);
8722         string_set(&ServicePtrs[iService]->comment, comment);
8723
8724         talloc_destroy(ctx);
8725
8726         return iService;
8727 }
8728
8729 /***************************************************************************
8730  Checks if a usershare entry has been modified since last load.
8731 ***************************************************************************/
8732
8733 static bool usershare_exists(int iService, struct timespec *last_mod)
8734 {
8735         SMB_STRUCT_STAT lsbuf;
8736         const char *usersharepath = Globals.szUsersharePath;
8737         char *fname;
8738
8739         if (asprintf(&fname, "%s/%s",
8740                                 usersharepath,
8741                                 ServicePtrs[iService]->szService) < 0) {
8742                 return false;
8743         }
8744
8745         if (sys_lstat(fname, &lsbuf) != 0) {
8746                 SAFE_FREE(fname);
8747                 return false;
8748         }
8749
8750         if (!S_ISREG(lsbuf.st_ex_mode)) {
8751                 SAFE_FREE(fname);
8752                 return false;
8753         }
8754
8755         SAFE_FREE(fname);
8756         *last_mod = lsbuf.st_ex_mtime;
8757         return true;
8758 }
8759
8760 /***************************************************************************
8761  Load a usershare service by name. Returns a valid servicenumber or -1.
8762 ***************************************************************************/
8763
8764 int load_usershare_service(const char *servicename)
8765 {
8766         SMB_STRUCT_STAT sbuf;
8767         const char *usersharepath = Globals.szUsersharePath;
8768         int max_user_shares = Globals.iUsershareMaxShares;
8769         int snum_template = -1;
8770
8771         if (*usersharepath == 0 ||  max_user_shares == 0) {
8772                 return -1;
8773         }
8774
8775         if (sys_stat(usersharepath, &sbuf) != 0) {
8776                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8777                         usersharepath, strerror(errno) ));
8778                 return -1;
8779         }
8780
8781         if (!S_ISDIR(sbuf.st_ex_mode)) {
8782                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8783                         usersharepath ));
8784                 return -1;
8785         }
8786
8787         /*
8788          * This directory must be owned by root, and have the 't' bit set.
8789          * It also must not be writable by "other".
8790          */
8791
8792 #ifdef S_ISVTX
8793         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8794 #else
8795         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8796 #endif
8797                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8798                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8799                         usersharepath ));
8800                 return -1;
8801         }
8802
8803         /* Ensure the template share exists if it's set. */
8804         if (Globals.szUsershareTemplateShare[0]) {
8805                 /* We can't use lp_servicenumber here as we are recommending that
8806                    template shares have -valid=False set. */
8807                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8808                         if (ServicePtrs[snum_template]->szService &&
8809                                         strequal(ServicePtrs[snum_template]->szService,
8810                                                 Globals.szUsershareTemplateShare)) {
8811                                 break;
8812                         }
8813                 }
8814
8815                 if (snum_template == -1) {
8816                         DEBUG(0,("load_usershare_service: usershare template share %s "
8817                                 "does not exist.\n",
8818                                 Globals.szUsershareTemplateShare ));
8819                         return -1;
8820                 }
8821         }
8822
8823         return process_usershare_file(usersharepath, servicename, snum_template);
8824 }
8825
8826 /***************************************************************************
8827  Load all user defined shares from the user share directory.
8828  We only do this if we're enumerating the share list.
8829  This is the function that can delete usershares that have
8830  been removed.
8831 ***************************************************************************/
8832
8833 int load_usershare_shares(void)
8834 {
8835         SMB_STRUCT_DIR *dp;
8836         SMB_STRUCT_STAT sbuf;
8837         SMB_STRUCT_DIRENT *de;
8838         int num_usershares = 0;
8839         int max_user_shares = Globals.iUsershareMaxShares;
8840         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8841         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8842         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8843         int iService;
8844         int snum_template = -1;
8845         const char *usersharepath = Globals.szUsersharePath;
8846         int ret = lp_numservices();
8847
8848         if (max_user_shares == 0 || *usersharepath == '\0') {
8849                 return lp_numservices();
8850         }
8851
8852         if (sys_stat(usersharepath, &sbuf) != 0) {
8853                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8854                         usersharepath, strerror(errno) ));
8855                 return ret;
8856         }
8857
8858         /*
8859          * This directory must be owned by root, and have the 't' bit set.
8860          * It also must not be writable by "other".
8861          */
8862
8863 #ifdef S_ISVTX
8864         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8865 #else
8866         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8867 #endif
8868                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8869                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8870                         usersharepath ));
8871                 return ret;
8872         }
8873
8874         /* Ensure the template share exists if it's set. */
8875         if (Globals.szUsershareTemplateShare[0]) {
8876                 /* We can't use lp_servicenumber here as we are recommending that
8877                    template shares have -valid=False set. */
8878                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8879                         if (ServicePtrs[snum_template]->szService &&
8880                                         strequal(ServicePtrs[snum_template]->szService,
8881                                                 Globals.szUsershareTemplateShare)) {
8882                                 break;
8883                         }
8884                 }
8885
8886                 if (snum_template == -1) {
8887                         DEBUG(0,("load_usershare_shares: usershare template share %s "
8888                                 "does not exist.\n",
8889                                 Globals.szUsershareTemplateShare ));
8890                         return ret;
8891                 }
8892         }
8893
8894         /* Mark all existing usershares as pending delete. */
8895         for (iService = iNumServices - 1; iService >= 0; iService--) {
8896                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8897                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8898                 }
8899         }
8900
8901         dp = sys_opendir(usersharepath);
8902         if (!dp) {
8903                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8904                         usersharepath, strerror(errno) ));
8905                 return ret;
8906         }
8907
8908         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8909                         (de = sys_readdir(dp));
8910                         num_dir_entries++ ) {
8911                 int r;
8912                 const char *n = de->d_name;
8913
8914                 /* Ignore . and .. */
8915                 if (*n == '.') {
8916                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8917                                 continue;
8918                         }
8919                 }
8920
8921                 if (n[0] == ':') {
8922                         /* Temporary file used when creating a share. */
8923                         num_tmp_dir_entries++;
8924                 }
8925
8926                 /* Allow 20% tmp entries. */
8927                 if (num_tmp_dir_entries > allowed_tmp_entries) {
8928                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8929                                 "in directory %s\n",
8930                                 num_tmp_dir_entries, usersharepath));
8931                         break;
8932                 }
8933
8934                 r = process_usershare_file(usersharepath, n, snum_template);
8935                 if (r == 0) {
8936                         /* Update the services count. */
8937                         num_usershares++;
8938                         if (num_usershares >= max_user_shares) {
8939                                 DEBUG(0,("load_usershare_shares: max user shares reached "
8940                                         "on file %s in directory %s\n",
8941                                         n, usersharepath ));
8942                                 break;
8943                         }
8944                 } else if (r == -1) {
8945                         num_bad_dir_entries++;
8946                 }
8947
8948                 /* Allow 20% bad entries. */
8949                 if (num_bad_dir_entries > allowed_bad_entries) {
8950                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8951                                 "in directory %s\n",
8952                                 num_bad_dir_entries, usersharepath));
8953                         break;
8954                 }
8955
8956                 /* Allow 20% bad entries. */
8957                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8958                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8959                         "in directory %s\n",
8960                         num_dir_entries, usersharepath));
8961                         break;
8962                 }
8963         }
8964
8965         sys_closedir(dp);
8966
8967         /* Sweep through and delete any non-refreshed usershares that are
8968            not currently in use. */
8969         for (iService = iNumServices - 1; iService >= 0; iService--) {
8970                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8971                         if (conn_snum_used(iService)) {
8972                                 continue;
8973                         }
8974                         /* Remove from the share ACL db. */
8975                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8976                                 lp_servicename(iService) ));
8977                         delete_share_security(lp_servicename(iService));
8978                         free_service_byindex(iService);
8979                 }
8980         }
8981
8982         return lp_numservices();
8983 }
8984
8985 /********************************************************
8986  Destroy global resources allocated in this file
8987 ********************************************************/
8988
8989 void gfree_loadparm(void)
8990 {
8991         int i;
8992
8993         free_file_list();
8994
8995         /* Free resources allocated to services */
8996
8997         for ( i = 0; i < iNumServices; i++ ) {
8998                 if ( VALID(i) ) {
8999                         free_service_byindex(i);
9000                 }
9001         }
9002
9003         SAFE_FREE( ServicePtrs );
9004         iNumServices = 0;
9005
9006         /* Now release all resources allocated to global
9007            parameters and the default service */
9008
9009         free_global_parameters();
9010 }
9011
9012
9013 /***************************************************************************
9014  Allow client apps to specify that they are a client
9015 ***************************************************************************/
9016 void lp_set_in_client(bool b)
9017 {
9018     in_client = b;
9019 }
9020
9021
9022 /***************************************************************************
9023  Determine if we're running in a client app
9024 ***************************************************************************/
9025 bool lp_is_in_client(void)
9026 {
9027     return in_client;
9028 }
9029
9030 /***************************************************************************
9031  Load the services array from the services file. Return True on success, 
9032  False on failure.
9033 ***************************************************************************/
9034
9035 bool lp_load_ex(const char *pszFname,
9036                 bool global_only,
9037                 bool save_defaults,
9038                 bool add_ipc,
9039                 bool initialize_globals,
9040                 bool allow_include_registry,
9041                 bool allow_registry_shares)
9042 {
9043         char *n2 = NULL;
9044         bool bRetval;
9045
9046         bRetval = False;
9047
9048         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9049
9050         bInGlobalSection = True;
9051         bGlobalOnly = global_only;
9052         bAllowIncludeRegistry = allow_include_registry;
9053
9054         init_globals(! initialize_globals);
9055         debug_init();
9056
9057         free_file_list();
9058
9059         if (save_defaults) {
9060                 init_locals();
9061                 lp_save_defaults();
9062         }
9063
9064         free_param_opts(&Globals.param_opt);
9065
9066         /* We get sections first, so have to start 'behind' to make up */
9067         iServiceIndex = -1;
9068
9069         if (lp_config_backend_is_file()) {
9070                 n2 = alloc_sub_basic(get_current_username(),
9071                                         current_user_info.domain,
9072                                         pszFname);
9073                 if (!n2) {
9074                         smb_panic("lp_load_ex: out of memory");
9075                 }
9076
9077                 add_to_file_list(pszFname, n2);
9078
9079                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9080                 SAFE_FREE(n2);
9081
9082                 /* finish up the last section */
9083                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9084                 if (bRetval) {
9085                         if (iServiceIndex >= 0) {
9086                                 bRetval = service_ok(iServiceIndex);
9087                         }
9088                 }
9089
9090                 if (lp_config_backend_is_registry()) {
9091                         /* config backend changed to registry in config file */
9092                         /*
9093                          * We need to use this extra global variable here to
9094                          * survive restart: init_globals uses this as a default
9095                          * for ConfigBackend. Otherwise, init_globals would
9096                          *  send us into an endless loop here.
9097                          */
9098                         config_backend = CONFIG_BACKEND_REGISTRY;
9099                         /* start over */
9100                         DEBUG(1, ("lp_load_ex: changing to config backend "
9101                                   "registry\n"));
9102                         init_globals(false);
9103                         lp_kill_all_services();
9104                         return lp_load_ex(pszFname, global_only, save_defaults,
9105                                           add_ipc, initialize_globals,
9106                                           allow_include_registry,
9107                                           allow_registry_shares);
9108                 }
9109         } else if (lp_config_backend_is_registry()) {
9110                 bRetval = process_registry_globals();
9111         } else {
9112                 DEBUG(0, ("Illegal config  backend given: %d\n",
9113                           lp_config_backend()));
9114                 bRetval = false;
9115         }
9116
9117         if (bRetval && lp_registry_shares() && allow_registry_shares) {
9118                 bRetval = process_registry_shares();
9119         }
9120
9121         lp_add_auto_services(lp_auto_services());
9122
9123         if (add_ipc) {
9124                 /* When 'restrict anonymous = 2' guest connections to ipc$
9125                    are denied */
9126                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9127                 if ( lp_enable_asu_support() ) {
9128                         lp_add_ipc("ADMIN$", false);
9129                 }
9130         }
9131
9132         set_server_role();
9133         set_default_server_announce_type();
9134         set_allowed_client_auth();
9135
9136         bLoaded = True;
9137
9138         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9139         /* if bWINSsupport is true and we are in the client            */
9140         if (lp_is_in_client() && Globals.bWINSsupport) {
9141                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9142         }
9143
9144         init_iconv();
9145
9146         bAllowIncludeRegistry = true;
9147
9148         return (bRetval);
9149 }
9150
9151 bool lp_load(const char *pszFname,
9152              bool global_only,
9153              bool save_defaults,
9154              bool add_ipc,
9155              bool initialize_globals)
9156 {
9157         return lp_load_ex(pszFname,
9158                           global_only,
9159                           save_defaults,
9160                           add_ipc,
9161                           initialize_globals,
9162                           true, false);
9163 }
9164
9165 bool lp_load_initial_only(const char *pszFname)
9166 {
9167         return lp_load_ex(pszFname,
9168                           true,
9169                           false,
9170                           false,
9171                           true,
9172                           false,
9173                           false);
9174 }
9175
9176 bool lp_load_with_registry_shares(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,
9188                           true);
9189 }
9190
9191 /***************************************************************************
9192  Return the max number of services.
9193 ***************************************************************************/
9194
9195 int lp_numservices(void)
9196 {
9197         return (iNumServices);
9198 }
9199
9200 /***************************************************************************
9201 Display the contents of the services array in human-readable form.
9202 ***************************************************************************/
9203
9204 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9205 {
9206         int iService;
9207
9208         if (show_defaults)
9209                 defaults_saved = False;
9210
9211         dump_globals(f);
9212
9213         dump_a_service(&sDefault, f);
9214
9215         for (iService = 0; iService < maxtoprint; iService++) {
9216                 fprintf(f,"\n");
9217                 lp_dump_one(f, show_defaults, iService);
9218         }
9219 }
9220
9221 /***************************************************************************
9222 Display the contents of one service in human-readable form.
9223 ***************************************************************************/
9224
9225 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9226 {
9227         if (VALID(snum)) {
9228                 if (ServicePtrs[snum]->szService[0] == '\0')
9229                         return;
9230                 dump_a_service(ServicePtrs[snum], f);
9231         }
9232 }
9233
9234 /***************************************************************************
9235 Return the number of the service with the given name, or -1 if it doesn't
9236 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9237 getservicebyname()! This works ONLY if all services have been loaded, and
9238 does not copy the found service.
9239 ***************************************************************************/
9240
9241 int lp_servicenumber(const char *pszServiceName)
9242 {
9243         int iService;
9244         fstring serviceName;
9245         
9246         if (!pszServiceName) {
9247                 return GLOBAL_SECTION_SNUM;
9248         }
9249         
9250         for (iService = iNumServices - 1; iService >= 0; iService--) {
9251                 if (VALID(iService) && ServicePtrs[iService]->szService) {
9252                         /*
9253                          * The substitution here is used to support %U is
9254                          * service names
9255                          */
9256                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
9257                         standard_sub_basic(get_current_username(),
9258                                            current_user_info.domain,
9259                                            serviceName,sizeof(serviceName));
9260                         if (strequal(serviceName, pszServiceName)) {
9261                                 break;
9262                         }
9263                 }
9264         }
9265
9266         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9267                 struct timespec last_mod;
9268
9269                 if (!usershare_exists(iService, &last_mod)) {
9270                         /* Remove the share security tdb entry for it. */
9271                         delete_share_security(lp_servicename(iService));
9272                         /* Remove it from the array. */
9273                         free_service_byindex(iService);
9274                         /* Doesn't exist anymore. */
9275                         return GLOBAL_SECTION_SNUM;
9276                 }
9277
9278                 /* Has it been modified ? If so delete and reload. */
9279                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9280                                      &last_mod) < 0) {
9281                         /* Remove it from the array. */
9282                         free_service_byindex(iService);
9283                         /* and now reload it. */
9284                         iService = load_usershare_service(pszServiceName);
9285                 }
9286         }
9287
9288         if (iService < 0) {
9289                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9290                 return GLOBAL_SECTION_SNUM;
9291         }
9292
9293         return (iService);
9294 }
9295
9296 bool share_defined(const char *service_name)
9297 {
9298         return (lp_servicenumber(service_name) != -1);
9299 }
9300
9301 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9302                                       const char *sharename)
9303 {
9304         struct share_params *result;
9305         char *sname;
9306         int snum;
9307
9308         if (!(sname = SMB_STRDUP(sharename))) {
9309                 return NULL;
9310         }
9311
9312         snum = find_service(sname);
9313         SAFE_FREE(sname);
9314
9315         if (snum < 0) {
9316                 return NULL;
9317         }
9318
9319         if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9320                 DEBUG(0, ("talloc failed\n"));
9321                 return NULL;
9322         }
9323
9324         result->service = snum;
9325         return result;
9326 }
9327
9328 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9329 {
9330         struct share_iterator *result;
9331
9332         if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9333                 DEBUG(0, ("talloc failed\n"));
9334                 return NULL;
9335         }
9336
9337         result->next_id = 0;
9338         return result;
9339 }
9340
9341 struct share_params *next_share(struct share_iterator *list)
9342 {
9343         struct share_params *result;
9344
9345         while (!lp_snum_ok(list->next_id) &&
9346                (list->next_id < lp_numservices())) {
9347                 list->next_id += 1;
9348         }
9349
9350         if (list->next_id >= lp_numservices()) {
9351                 return NULL;
9352         }
9353
9354         if (!(result = TALLOC_P(list, struct share_params))) {
9355                 DEBUG(0, ("talloc failed\n"));
9356                 return NULL;
9357         }
9358
9359         result->service = list->next_id;
9360         list->next_id += 1;
9361         return result;
9362 }
9363
9364 struct share_params *next_printer(struct share_iterator *list)
9365 {
9366         struct share_params *result;
9367
9368         while ((result = next_share(list)) != NULL) {
9369                 if (lp_print_ok(result->service)) {
9370                         break;
9371                 }
9372         }
9373         return result;
9374 }
9375
9376 /*
9377  * This is a hack for a transition period until we transformed all code from
9378  * service numbers to struct share_params.
9379  */
9380
9381 struct share_params *snum2params_static(int snum)
9382 {
9383         static struct share_params result;
9384         result.service = snum;
9385         return &result;
9386 }
9387
9388 /*******************************************************************
9389  A useful volume label function. 
9390 ********************************************************************/
9391
9392 const char *volume_label(int snum)
9393 {
9394         char *ret;
9395         const char *label = lp_volume(snum);
9396         if (!*label) {
9397                 label = lp_servicename(snum);
9398         }
9399                 
9400         /* This returns a 33 byte guarenteed null terminated string. */
9401         ret = talloc_strndup(talloc_tos(), label, 32);
9402         if (!ret) {
9403                 return "";
9404         }               
9405         return ret;
9406 }
9407
9408 /*******************************************************************
9409  Set the server type we will announce as via nmbd.
9410 ********************************************************************/
9411
9412 static void set_default_server_announce_type(void)
9413 {
9414         default_server_announce = 0;
9415         default_server_announce |= SV_TYPE_WORKSTATION;
9416         default_server_announce |= SV_TYPE_SERVER;
9417         default_server_announce |= SV_TYPE_SERVER_UNIX;
9418
9419         /* note that the flag should be set only if we have a 
9420            printer service but nmbd doesn't actually load the 
9421            services so we can't tell   --jerry */
9422
9423         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9424
9425         switch (lp_announce_as()) {
9426                 case ANNOUNCE_AS_NT_SERVER:
9427                         default_server_announce |= SV_TYPE_SERVER_NT;
9428                         /* fall through... */
9429                 case ANNOUNCE_AS_NT_WORKSTATION:
9430                         default_server_announce |= SV_TYPE_NT;
9431                         break;
9432                 case ANNOUNCE_AS_WIN95:
9433                         default_server_announce |= SV_TYPE_WIN95_PLUS;
9434                         break;
9435                 case ANNOUNCE_AS_WFW:
9436                         default_server_announce |= SV_TYPE_WFW;
9437                         break;
9438                 default:
9439                         break;
9440         }
9441
9442         switch (lp_server_role()) {
9443                 case ROLE_DOMAIN_MEMBER:
9444                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9445                         break;
9446                 case ROLE_DOMAIN_PDC:
9447                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9448                         break;
9449                 case ROLE_DOMAIN_BDC:
9450                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9451                         break;
9452                 case ROLE_STANDALONE:
9453                 default:
9454                         break;
9455         }
9456         if (lp_time_server())
9457                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9458
9459         if (lp_host_msdfs())
9460                 default_server_announce |= SV_TYPE_DFS_SERVER;
9461 }
9462
9463 /***********************************************************
9464  returns role of Samba server
9465 ************************************************************/
9466
9467 int lp_server_role(void)
9468 {
9469         return server_role;
9470 }
9471
9472 /***********************************************************
9473  If we are PDC then prefer us as DMB
9474 ************************************************************/
9475
9476 bool lp_domain_master(void)
9477 {
9478         if (Globals.iDomainMaster == Auto)
9479                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9480
9481         return (bool)Globals.iDomainMaster;
9482 }
9483
9484 /***********************************************************
9485  If we are DMB then prefer us as LMB
9486 ************************************************************/
9487
9488 bool lp_preferred_master(void)
9489 {
9490         if (Globals.iPreferredMaster == Auto)
9491                 return (lp_local_master() && lp_domain_master());
9492
9493         return (bool)Globals.iPreferredMaster;
9494 }
9495
9496 /*******************************************************************
9497  Remove a service.
9498 ********************************************************************/
9499
9500 void lp_remove_service(int snum)
9501 {
9502         ServicePtrs[snum]->valid = False;
9503         invalid_services[num_invalid_services++] = snum;
9504 }
9505
9506 /*******************************************************************
9507  Copy a service.
9508 ********************************************************************/
9509
9510 void lp_copy_service(int snum, const char *new_name)
9511 {
9512         do_section(new_name, NULL);
9513         if (snum >= 0) {
9514                 snum = lp_servicenumber(new_name);
9515                 if (snum >= 0)
9516                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9517         }
9518 }
9519
9520
9521 /*******************************************************************
9522  Get the default server type we will announce as via nmbd.
9523 ********************************************************************/
9524
9525 int lp_default_server_announce(void)
9526 {
9527         return default_server_announce;
9528 }
9529
9530 /*******************************************************************
9531  Split the announce version into major and minor numbers.
9532 ********************************************************************/
9533
9534 int lp_major_announce_version(void)
9535 {
9536         static bool got_major = False;
9537         static int major_version = DEFAULT_MAJOR_VERSION;
9538         char *vers;
9539         char *p;
9540
9541         if (got_major)
9542                 return major_version;
9543
9544         got_major = True;
9545         if ((vers = lp_announce_version()) == NULL)
9546                 return major_version;
9547
9548         if ((p = strchr_m(vers, '.')) == 0)
9549                 return major_version;
9550
9551         *p = '\0';
9552         major_version = atoi(vers);
9553         return major_version;
9554 }
9555
9556 int lp_minor_announce_version(void)
9557 {
9558         static bool got_minor = False;
9559         static int minor_version = DEFAULT_MINOR_VERSION;
9560         char *vers;
9561         char *p;
9562
9563         if (got_minor)
9564                 return minor_version;
9565
9566         got_minor = True;
9567         if ((vers = lp_announce_version()) == NULL)
9568                 return minor_version;
9569
9570         if ((p = strchr_m(vers, '.')) == 0)
9571                 return minor_version;
9572
9573         p++;
9574         minor_version = atoi(p);
9575         return minor_version;
9576 }
9577
9578 /***********************************************************
9579  Set the global name resolution order (used in smbclient).
9580 ************************************************************/
9581
9582 void lp_set_name_resolve_order(const char *new_order)
9583 {
9584         string_set(&Globals.szNameResolveOrder, new_order);
9585 }
9586
9587 const char *lp_printername(int snum)
9588 {
9589         const char *ret = _lp_printername(snum);
9590         if (ret == NULL || (ret != NULL && *ret == '\0'))
9591                 ret = lp_const_servicename(snum);
9592
9593         return ret;
9594 }
9595
9596
9597 /***********************************************************
9598  Allow daemons such as winbindd to fix their logfile name.
9599 ************************************************************/
9600
9601 void lp_set_logfile(const char *name)
9602 {
9603         string_set(&Globals.szLogFile, name);
9604         debug_set_logfile(name);
9605 }
9606
9607 /*******************************************************************
9608  Return the max print jobs per queue.
9609 ********************************************************************/
9610
9611 int lp_maxprintjobs(int snum)
9612 {
9613         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9614         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9615                 maxjobs = PRINT_MAX_JOBID - 1;
9616
9617         return maxjobs;
9618 }
9619
9620 const char *lp_printcapname(void)
9621 {
9622         if ((Globals.szPrintcapname != NULL) &&
9623             (Globals.szPrintcapname[0] != '\0'))
9624                 return Globals.szPrintcapname;
9625
9626         if (sDefault.iPrinting == PRINT_CUPS) {
9627 #ifdef HAVE_CUPS
9628                 return "cups";
9629 #else
9630                 return "lpstat";
9631 #endif
9632         }
9633
9634         if (sDefault.iPrinting == PRINT_BSD)
9635                 return "/etc/printcap";
9636
9637         return PRINTCAP_NAME;
9638 }
9639
9640 static uint32 spoolss_state;
9641
9642 bool lp_disable_spoolss( void )
9643 {
9644         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9645                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9646
9647         return spoolss_state == SVCCTL_STOPPED ? True : False;
9648 }
9649
9650 void lp_set_spoolss_state( uint32 state )
9651 {
9652         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9653
9654         spoolss_state = state;
9655 }
9656
9657 uint32 lp_get_spoolss_state( void )
9658 {
9659         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9660 }
9661
9662 /*******************************************************************
9663  Ensure we don't use sendfile if server smb signing is active.
9664 ********************************************************************/
9665
9666 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9667 {
9668         bool sign_active = false;
9669
9670         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9671         if (Protocol < PROTOCOL_NT1) {
9672                 return false;
9673         }
9674         if (signing_state) {
9675                 sign_active = smb_signing_is_active(signing_state);
9676         }
9677         return (_lp_use_sendfile(snum) &&
9678                         (get_remote_arch() != RA_WIN95) &&
9679                         !sign_active);
9680 }
9681
9682 /*******************************************************************
9683  Turn off sendfile if we find the underlying OS doesn't support it.
9684 ********************************************************************/
9685
9686 void set_use_sendfile(int snum, bool val)
9687 {
9688         if (LP_SNUM_OK(snum))
9689                 ServicePtrs[snum]->bUseSendfile = val;
9690         else
9691                 sDefault.bUseSendfile = val;
9692 }
9693
9694 /*******************************************************************
9695  Turn off storing DOS attributes if this share doesn't support it.
9696 ********************************************************************/
9697
9698 void set_store_dos_attributes(int snum, bool val)
9699 {
9700         if (!LP_SNUM_OK(snum))
9701                 return;
9702         ServicePtrs[(snum)]->bStoreDosAttributes = val;
9703 }
9704
9705 void lp_set_mangling_method(const char *new_method)
9706 {
9707         string_set(&Globals.szManglingMethod, new_method);
9708 }
9709
9710 /*******************************************************************
9711  Global state for POSIX pathname processing.
9712 ********************************************************************/
9713
9714 static bool posix_pathnames;
9715
9716 bool lp_posix_pathnames(void)
9717 {
9718         return posix_pathnames;
9719 }
9720
9721 /*******************************************************************
9722  Change everything needed to ensure POSIX pathname processing (currently
9723  not much).
9724 ********************************************************************/
9725
9726 void lp_set_posix_pathnames(void)
9727 {
9728         posix_pathnames = True;
9729 }
9730
9731 /*******************************************************************
9732  Global state for POSIX lock processing - CIFS unix extensions.
9733 ********************************************************************/
9734
9735 bool posix_default_lock_was_set;
9736 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9737
9738 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9739 {
9740         if (posix_default_lock_was_set) {
9741                 return posix_cifsx_locktype;
9742         } else {
9743                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9744         }
9745 }
9746
9747 /*******************************************************************
9748 ********************************************************************/
9749
9750 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9751 {
9752         posix_default_lock_was_set = True;
9753         posix_cifsx_locktype = val;
9754 }
9755
9756 int lp_min_receive_file_size(void)
9757 {
9758         if (Globals.iminreceivefile < 0) {
9759                 return 0;
9760         }
9761         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9762 }
9763
9764 /*******************************************************************
9765  If socket address is an empty character string, it is necessary to 
9766  define it as "0.0.0.0". 
9767 ********************************************************************/
9768
9769 const char *lp_socket_address(void)
9770 {
9771         char *sock_addr = Globals.szSocketAddress;
9772         
9773         if (sock_addr[0] == '\0'){
9774                 string_set(&Globals.szSocketAddress, "0.0.0.0");
9775         }
9776         return  Globals.szSocketAddress;
9777 }