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