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