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