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