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