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