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