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