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