s3-param Remove 'announce version' parameter
[kai/samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23
24    You should have received a copy of the GNU General Public License
25    along with this program.  If not, see <http://www.gnu.org/licenses/>.
26 */
27
28 /*
29  *  Load parameters.
30  *
31  *  This module provides suitable callback functions for the params
32  *  module. It builds the internal table of service details which is
33  *  then used by the rest of the server.
34  *
35  * To add a parameter:
36  *
37  * 1) add it to the global or service structure definition
38  * 2) add it to the parm_table
39  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40  * 4) If it's a global then initialise it in init_globals. If a local
41  *    (ie. service) parameter then initialise it in the sDefault structure
42  *  
43  *
44  * Notes:
45  *   The configuration file is processed sequentially for speed. It is NOT
46  *   accessed randomly as happens in 'real' Windows. For this reason, there
47  *   is a fair bit of sequence-dependent code here - ie., code which assumes
48  *   that certain things happen before others. In particular, the code which
49  *   happens at the boundary between sections is delicately poised, so be
50  *   careful!
51  *
52  */
53
54 #include "includes.h"
55 #include "system/filesys.h"
56 #include "util_tdb.h"
57 #include "printing.h"
58 #include "lib/smbconf/smbconf.h"
59 #include "lib/smbconf/smbconf_init.h"
60
61 #include "ads.h"
62 #include "../librpc/gen_ndr/svcctl.h"
63 #include "intl.h"
64 #include "smb_signing.h"
65 #include "dbwrap.h"
66 #include "smbldap.h"
67
68 #ifdef HAVE_SYS_SYSCTL_H
69 #include <sys/sysctl.h>
70 #endif
71
72 #ifdef HAVE_HTTPCONNECTENCRYPT
73 #include <cups/http.h>
74 #endif
75
76 bool bLoaded = False;
77
78 extern userdom_struct current_user_info;
79
80 #ifndef GLOBAL_NAME
81 #define GLOBAL_NAME "global"
82 #endif
83
84 #ifndef PRINTERS_NAME
85 #define PRINTERS_NAME "printers"
86 #endif
87
88 #ifndef HOMES_NAME
89 #define HOMES_NAME "homes"
90 #endif
91
92 /* the special value for the include parameter
93  * to be interpreted not as a file name but to
94  * trigger loading of the global smb.conf options
95  * from registry. */
96 #ifndef INCLUDE_REGISTRY_NAME
97 #define INCLUDE_REGISTRY_NAME "registry"
98 #endif
99
100 static bool in_client = False;          /* Not in the client by default */
101 static struct smbconf_csn conf_last_csn;
102
103 #define CONFIG_BACKEND_FILE 0
104 #define CONFIG_BACKEND_REGISTRY 1
105
106 static int config_backend = CONFIG_BACKEND_FILE;
107
108 /* some helpful bits */
109 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
110 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
111
112 #define USERSHARE_VALID 1
113 #define USERSHARE_PENDING_DELETE 2
114
115 static bool defaults_saved = False;
116
117 struct param_opt_struct {
118         struct param_opt_struct *prev, *next;
119         char *key;
120         char *value;
121         char **list;
122         unsigned flags;
123 };
124
125 /*
126  * This structure describes global (ie., server-wide) parameters.
127  */
128 struct global {
129         int ConfigBackend;
130         char *smb_ports;
131         char *dos_charset;
132         char *unix_charset;
133         char *szPrintcapname;
134         char *szAddPortCommand;
135         char *szEnumPortsCommand;
136         char *szAddPrinterCommand;
137         char *szDeletePrinterCommand;
138         char *szOs2DriverMap;
139         char *szLockDir;
140         char *szStateDir;
141         char *szCacheDir;
142         char *szPidDir;
143         char *szRootdir;
144         char *szDefaultService;
145         char *szGetQuota;
146         char *szSetQuota;
147         char *szMsgCommand;
148         char *szServerString;
149         char *szAutoServices;
150         char *szPasswdProgram;
151         char *szPasswdChat;
152         char *szLogFile;
153         char *szConfigFile;
154         char *szSMBPasswdFile;
155         char *szPrivateDir;
156         char *szPassdbBackend;
157         char **szPreloadModules;
158         char *szPasswordServer;
159         char *szSocketOptions;
160         char *szRealm;
161         char *szRealmUpper;
162         char *szDnsDomain;
163         char *szAfsUsernameMap;
164         int iAfsTokenLifetime;
165         char *szLogNtTokenCommand;
166         char *szUsernameMap;
167         char *szLogonScript;
168         char *szLogonPath;
169         char *szLogonDrive;
170         char *szLogonHome;
171         char **szWINSservers;
172         char **szInterfaces;
173         char *szRemoteAnnounce;
174         char *szRemoteBrowseSync;
175         char *szSocketAddress;
176         bool bNmbdBindExplicitBroadcast;
177         char *szNISHomeMapName;
178         char *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 global Globals;
389
390 /*
391  * This structure describes a single service.
392  */
393 struct service {
394         bool valid;
395         bool autoloaded;
396         int usershare;
397         struct timespec usershare_last_mod;
398         char *szService;
399         char *szPath;
400         char *szUsername;
401         char **szInvalidUsers;
402         char **szValidUsers;
403         char **szAdminUsers;
404         char *szCopy;
405         char *szInclude;
406         char *szPreExec;
407         char *szPostExec;
408         char *szRootPreExec;
409         char *szRootPostExec;
410         char *szCupsOptions;
411         char *szPrintcommand;
412         char *szLpqcommand;
413         char *szLprmcommand;
414         char *szLppausecommand;
415         char *szLpresumecommand;
416         char *szQueuepausecommand;
417         char *szQueueresumecommand;
418         char *szPrintername;
419         char *szPrintjobUsername;
420         char *szDontdescend;
421         char **szHostsallow;
422         char **szHostsdeny;
423         char *szMagicScript;
424         char *szMagicOutput;
425         char *szVetoFiles;
426         char *szHideFiles;
427         char *szVetoOplockFiles;
428         char *comment;
429         char *force_user;
430         char *force_group;
431         char **readlist;
432         char **writelist;
433         char **printer_admin;
434         char *volume;
435         char *fstype;
436         char **szVfsObjects;
437         char *szMSDfsProxy;
438         char *szAioWriteBehind;
439         char *szDfree;
440         int iMinPrintSpace;
441         int iMaxPrintJobs;
442         int iMaxReportedPrintJobs;
443         int iWriteCacheSize;
444         int iCreate_mask;
445         int iCreate_force_mode;
446         int iSecurity_mask;
447         int iSecurity_force_mode;
448         int iDir_mask;
449         int iDir_force_mode;
450         int iDir_Security_mask;
451         int iDir_Security_force_mode;
452         int iMaxConnections;
453         int iDefaultCase;
454         int iPrinting;
455         int iOplockContentionLimit;
456         int iCSCPolicy;
457         int iBlock_size;
458         int iDfreeCacheTime;
459         bool bPreexecClose;
460         bool bRootpreexecClose;
461         int  iCaseSensitive;
462         bool bCasePreserve;
463         bool bShortCasePreserve;
464         bool bHideDotFiles;
465         bool bHideSpecialFiles;
466         bool bHideUnReadable;
467         bool bHideUnWriteableFiles;
468         bool bBrowseable;
469         bool bAccessBasedShareEnum;
470         bool bAvailable;
471         bool bRead_only;
472         bool bNo_set_dir;
473         bool bGuest_only;
474         bool bAdministrative_share;
475         bool bGuest_ok;
476         bool bPrint_ok;
477         bool bPrintNotifyBackchannel;
478         bool bMap_system;
479         bool bMap_hidden;
480         bool bMap_archive;
481         bool bStoreDosAttributes;
482         bool bDmapiSupport;
483         bool bLocking;
484         int iStrictLocking;
485         bool bPosixLocking;
486         bool bShareModes;
487         bool bOpLocks;
488         bool bLevel2OpLocks;
489         bool bOnlyUser;
490         bool bMangledNames;
491         bool bWidelinks;
492         bool bSymlinks;
493         bool bSyncAlways;
494         bool bStrictAllocate;
495         bool bStrictSync;
496         char magic_char;
497         struct bitmap *copymap;
498         bool bDeleteReadonly;
499         bool bFakeOplocks;
500         bool bDeleteVetoFiles;
501         bool bDosFilemode;
502         bool bDosFiletimes;
503         bool bDosFiletimeResolution;
504         bool bFakeDirCreateTimes;
505         bool bBlockingLocks;
506         bool bInheritPerms;
507         bool bInheritACLS;
508         bool bInheritOwner;
509         bool bMSDfsRoot;
510         bool bUseClientDriver;
511         bool bDefaultDevmode;
512         bool bForcePrintername;
513         bool bNTAclSupport;
514         bool bForceUnknownAclUser;
515         bool bUseSendfile;
516         bool bProfileAcls;
517         bool bMap_acl_inherit;
518         bool bAfs_Share;
519         bool bEASupport;
520         bool bAclCheckPermissions;
521         bool bAclMapFullControl;
522         bool bAclGroupControl;
523         bool bChangeNotify;
524         bool bKernelChangeNotify;
525         int iallocation_roundup_size;
526         int iAioReadSize;
527         int iAioWriteSize;
528         int iMap_readonly;
529         int iDirectoryNameCacheSize;
530         int ismb_encrypt;
531         struct param_opt_struct *param_opt;
532
533         char dummy[3];          /* for alignment */
534 };
535
536
537 /* This is a default service used to prime a services structure */
538 static struct service sDefault = {
539         True,                   /* valid */
540         False,                  /* not autoloaded */
541         0,                      /* not a usershare */
542         {0, },                  /* No last mod time */
543         NULL,                   /* szService */
544         NULL,                   /* szPath */
545         NULL,                   /* szUsername */
546         NULL,                   /* szInvalidUsers */
547         NULL,                   /* szValidUsers */
548         NULL,                   /* szAdminUsers */
549         NULL,                   /* szCopy */
550         NULL,                   /* szInclude */
551         NULL,                   /* szPreExec */
552         NULL,                   /* szPostExec */
553         NULL,                   /* szRootPreExec */
554         NULL,                   /* szRootPostExec */
555         NULL,                   /* szCupsOptions */
556         NULL,                   /* szPrintcommand */
557         NULL,                   /* szLpqcommand */
558         NULL,                   /* szLprmcommand */
559         NULL,                   /* szLppausecommand */
560         NULL,                   /* szLpresumecommand */
561         NULL,                   /* szQueuepausecommand */
562         NULL,                   /* szQueueresumecommand */
563         NULL,                   /* szPrintername */
564         NULL,                   /* szPrintjobUsername */
565         NULL,                   /* szDontdescend */
566         NULL,                   /* szHostsallow */
567         NULL,                   /* szHostsdeny */
568         NULL,                   /* szMagicScript */
569         NULL,                   /* szMagicOutput */
570         NULL,                   /* szVetoFiles */
571         NULL,                   /* szHideFiles */
572         NULL,                   /* szVetoOplockFiles */
573         NULL,                   /* comment */
574         NULL,                   /* force user */
575         NULL,                   /* force group */
576         NULL,                   /* readlist */
577         NULL,                   /* writelist */
578         NULL,                   /* printer admin */
579         NULL,                   /* volume */
580         NULL,                   /* fstype */
581         NULL,                   /* vfs objects */
582         NULL,                   /* szMSDfsProxy */
583         NULL,                   /* szAioWriteBehind */
584         NULL,                   /* szDfree */
585         0,                      /* iMinPrintSpace */
586         1000,                   /* iMaxPrintJobs */
587         0,                      /* iMaxReportedPrintJobs */
588         0,                      /* iWriteCacheSize */
589         0744,                   /* iCreate_mask */
590         0000,                   /* iCreate_force_mode */
591         0777,                   /* iSecurity_mask */
592         0,                      /* iSecurity_force_mode */
593         0755,                   /* iDir_mask */
594         0000,                   /* iDir_force_mode */
595         0777,                   /* iDir_Security_mask */
596         0,                      /* iDir_Security_force_mode */
597         0,                      /* iMaxConnections */
598         CASE_LOWER,             /* iDefaultCase */
599         DEFAULT_PRINTING,       /* iPrinting */
600         2,                      /* iOplockContentionLimit */
601         0,                      /* iCSCPolicy */
602         1024,                   /* iBlock_size */
603         0,                      /* iDfreeCacheTime */
604         False,                  /* bPreexecClose */
605         False,                  /* bRootpreexecClose */
606         Auto,                   /* case sensitive */
607         True,                   /* case preserve */
608         True,                   /* short case preserve */
609         True,                   /* bHideDotFiles */
610         False,                  /* bHideSpecialFiles */
611         False,                  /* bHideUnReadable */
612         False,                  /* bHideUnWriteableFiles */
613         True,                   /* bBrowseable */
614         False,                  /* bAccessBasedShareEnum */
615         True,                   /* bAvailable */
616         True,                   /* bRead_only */
617         True,                   /* bNo_set_dir */
618         False,                  /* bGuest_only */
619         False,                  /* bAdministrative_share */
620         False,                  /* bGuest_ok */
621         False,                  /* bPrint_ok */
622         True,                   /* bPrintNotifyBackchannel */
623         False,                  /* bMap_system */
624         False,                  /* bMap_hidden */
625         True,                   /* bMap_archive */
626         False,                  /* bStoreDosAttributes */
627         False,                  /* bDmapiSupport */
628         True,                   /* bLocking */
629         Auto,                   /* iStrictLocking */
630         True,                   /* bPosixLocking */
631         True,                   /* bShareModes */
632         True,                   /* bOpLocks */
633         True,                   /* bLevel2OpLocks */
634         False,                  /* bOnlyUser */
635         True,                   /* bMangledNames */
636         false,                  /* bWidelinks */
637         True,                   /* bSymlinks */
638         False,                  /* bSyncAlways */
639         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 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 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 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 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 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_STRING(lp_passdb_backend, szPassdbBackend)
5570  * lp_passdb_backend() should be replace by the this macro again after
5571  * some releases.
5572  * */
5573 const char *lp_passdb_backend(void)
5574 {
5575         char *delim, *quote;
5576
5577         delim = strchr( Globals.szPassdbBackend, ' ');
5578         /* no space at all */
5579         if (delim == NULL) {
5580                 goto out;
5581         }
5582
5583         quote = strchr(Globals.szPassdbBackend, '"');
5584         /* no quote char or non in the first part */
5585         if (quote == NULL || quote > delim) {
5586                 *delim = '\0';
5587                 goto warn;
5588         }
5589
5590         quote = strchr(quote+1, '"');
5591         if (quote == NULL) {
5592                 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5593                 goto out;
5594         } else if (*(quote+1) == '\0') {
5595                 /* space, fitting quote char, and one backend only */
5596                 goto out;
5597         } else {
5598                 /* terminate string after the fitting quote char */
5599                 *(quote+1) = '\0';
5600         }
5601
5602 warn:
5603         DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends.  This\n"
5604                 "is deprecated since Samba 3.0.23.  Please check WHATSNEW.txt or the section 'Passdb\n"
5605                 "Changes' from the ChangeNotes as part of the Samba HOWTO collection.  Only the first\n"
5606                 "backend (%s) is used.  The rest is ignored.\n", Globals.szPassdbBackend));
5607
5608 out:
5609         return Globals.szPassdbBackend;
5610 }
5611 FN_GLOBAL_LIST(lp_preload_modules, szPreloadModules)
5612 FN_GLOBAL_STRING(lp_panic_action, szPanicAction)
5613 FN_GLOBAL_STRING(lp_adduser_script, szAddUserScript)
5614 FN_GLOBAL_STRING(lp_renameuser_script, szRenameUserScript)
5615 FN_GLOBAL_STRING(lp_deluser_script, szDelUserScript)
5616
5617 FN_GLOBAL_CONST_STRING(lp_guestaccount, szGuestaccount)
5618 FN_GLOBAL_STRING(lp_addgroup_script, szAddGroupScript)
5619 FN_GLOBAL_STRING(lp_delgroup_script, szDelGroupScript)
5620 FN_GLOBAL_STRING(lp_addusertogroup_script, szAddUserToGroupScript)
5621 FN_GLOBAL_STRING(lp_deluserfromgroup_script, szDelUserFromGroupScript)
5622 FN_GLOBAL_STRING(lp_setprimarygroup_script, szSetPrimaryGroupScript)
5623
5624 FN_GLOBAL_STRING(lp_addmachine_script, szAddMachineScript)
5625
5626 FN_GLOBAL_STRING(lp_shutdown_script, szShutdownScript)
5627 FN_GLOBAL_STRING(lp_abort_shutdown_script, szAbortShutdownScript)
5628 FN_GLOBAL_STRING(lp_username_map_script, szUsernameMapScript)
5629 FN_GLOBAL_INTEGER(lp_username_map_cache_time, iUsernameMapCacheTime)
5630
5631 FN_GLOBAL_STRING(lp_check_password_script, szCheckPasswordScript)
5632
5633 FN_GLOBAL_STRING(lp_wins_hook, szWINSHook)
5634 FN_GLOBAL_CONST_STRING(lp_template_homedir, szTemplateHomedir)
5635 FN_GLOBAL_CONST_STRING(lp_template_shell, szTemplateShell)
5636 FN_GLOBAL_CONST_STRING(lp_winbind_separator, szWinbindSeparator)
5637 FN_GLOBAL_INTEGER(lp_acl_compatibility, iAclCompat)
5638 FN_GLOBAL_BOOL(lp_winbind_enum_users, bWinbindEnumUsers)
5639 FN_GLOBAL_BOOL(lp_winbind_enum_groups, bWinbindEnumGroups)
5640 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, bWinbindUseDefaultDomain)
5641 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, bWinbindTrustedDomainsOnly)
5642 FN_GLOBAL_BOOL(lp_winbind_nested_groups, bWinbindNestedGroups)
5643 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, winbind_expand_groups)
5644 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, bWinbindRefreshTickets)
5645 FN_GLOBAL_BOOL(lp_winbind_offline_logon, bWinbindOfflineLogon)
5646 FN_GLOBAL_BOOL(lp_winbind_normalize_names, bWinbindNormalizeNames)
5647 FN_GLOBAL_BOOL(lp_winbind_rpc_only, bWinbindRpcOnly)
5648 FN_GLOBAL_BOOL(lp_create_krb5_conf, bCreateKrb5Conf)
5649 static FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections_int,
5650                   winbindMaxDomainConnections)
5651
5652 int lp_winbind_max_domain_connections(void)
5653 {
5654         if (lp_winbind_offline_logon() &&
5655             lp_winbind_max_domain_connections_int() > 1) {
5656                 DEBUG(1, ("offline logons active, restricting max domain "
5657                           "connections to 1\n"));
5658                 return 1;
5659         }
5660         return MAX(1, lp_winbind_max_domain_connections_int());
5661 }
5662
5663 FN_GLOBAL_CONST_STRING(lp_idmap_backend, szIdmapBackend)
5664 FN_GLOBAL_INTEGER(lp_idmap_cache_time, iIdmapCacheTime)
5665 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, iIdmapNegativeCacheTime)
5666 FN_GLOBAL_INTEGER(lp_keepalive, iKeepalive)
5667 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, bPassdbExpandExplicit)
5668
5669 FN_GLOBAL_STRING(lp_ldap_suffix, szLdapSuffix)
5670 FN_GLOBAL_STRING(lp_ldap_admin_dn, szLdapAdminDn)
5671 FN_GLOBAL_INTEGER(lp_ldap_ssl, ldap_ssl)
5672 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, ldap_ssl_ads)
5673 FN_GLOBAL_INTEGER(lp_ldap_deref, ldap_deref)
5674 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, ldap_follow_referral)
5675 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, ldap_passwd_sync)
5676 FN_GLOBAL_BOOL(lp_ldap_delete_dn, ldap_delete_dn)
5677 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, ldap_replication_sleep)
5678 FN_GLOBAL_INTEGER(lp_ldap_timeout, ldap_timeout)
5679 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, ldap_connection_timeout)
5680 FN_GLOBAL_INTEGER(lp_ldap_page_size, ldap_page_size)
5681 FN_GLOBAL_INTEGER(lp_ldap_debug_level, ldap_debug_level)
5682 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, ldap_debug_threshold)
5683 FN_GLOBAL_STRING(lp_add_share_cmd, szAddShareCommand)
5684 FN_GLOBAL_STRING(lp_change_share_cmd, szChangeShareCommand)
5685 FN_GLOBAL_STRING(lp_delete_share_cmd, szDeleteShareCommand)
5686 FN_GLOBAL_STRING(lp_usershare_path, szUsersharePath)
5687 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, szUsersharePrefixAllowList)
5688 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, szUsersharePrefixDenyList)
5689
5690 FN_GLOBAL_LIST(lp_eventlog_list, szEventLogs)
5691
5692 FN_GLOBAL_BOOL(lp_registry_shares, bRegistryShares)
5693 FN_GLOBAL_BOOL(lp_usershare_allow_guests, bUsershareAllowGuests)
5694 FN_GLOBAL_BOOL(lp_usershare_owner_only, bUsershareOwnerOnly)
5695 FN_GLOBAL_BOOL(lp_disable_netbios, bDisableNetbios)
5696 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, bResetOnZeroVC)
5697 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5698                bLogWriteableFilesOnExit)
5699 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, bMsAddPrinterWizard)
5700 FN_GLOBAL_BOOL(lp_dns_proxy, bDNSproxy)
5701 FN_GLOBAL_BOOL(lp_wins_support, bWINSsupport)
5702 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, bWINSsupport)
5703 FN_GLOBAL_BOOL(lp_wins_proxy, bWINSproxy)
5704 FN_GLOBAL_BOOL(lp_local_master, bLocalMaster)
5705 FN_GLOBAL_BOOL(lp_domain_logons, bDomainLogons)
5706 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, szInitLogonDelayedHosts)
5707 FN_GLOBAL_INTEGER(lp_init_logon_delay, InitLogonDelay)
5708 FN_GLOBAL_BOOL(lp_load_printers, bLoadPrinters)
5709 FN_GLOBAL_BOOL(_lp_readraw, bReadRaw)
5710 FN_GLOBAL_BOOL(lp_large_readwrite, bLargeReadwrite)
5711 FN_GLOBAL_BOOL(_lp_writeraw, bWriteRaw)
5712 FN_GLOBAL_BOOL(lp_null_passwords, bNullPasswords)
5713 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, bObeyPamRestrictions)
5714 FN_GLOBAL_BOOL(lp_encrypted_passwords, bEncryptPasswords)
5715 FN_GLOBAL_INTEGER(lp_client_schannel, clientSchannel)
5716 FN_GLOBAL_INTEGER(lp_server_schannel, serverSchannel)
5717 FN_GLOBAL_BOOL(lp_syslog_only, bSyslogOnly)
5718 FN_GLOBAL_BOOL(lp_timestamp_logs, bTimestampLogs)
5719 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, bDebugPrefixTimestamp)
5720 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, bDebugHiresTimestamp)
5721 FN_GLOBAL_BOOL(lp_debug_pid, bDebugPid)
5722 FN_GLOBAL_BOOL(lp_debug_uid, bDebugUid)
5723 FN_GLOBAL_BOOL(lp_debug_class, bDebugClass)
5724 FN_GLOBAL_BOOL(lp_enable_core_files, bEnableCoreFiles)
5725 FN_GLOBAL_BOOL(lp_browse_list, bBrowseList)
5726 FN_GLOBAL_BOOL(lp_nis_home_map, bNISHomeMap)
5727 static FN_GLOBAL_BOOL(lp_time_server, bTimeServer)
5728 FN_GLOBAL_BOOL(lp_bind_interfaces_only, bBindInterfacesOnly)
5729 FN_GLOBAL_BOOL(lp_pam_password_change, bPamPasswordChange)
5730 FN_GLOBAL_BOOL(lp_unix_password_sync, bUnixPasswdSync)
5731 FN_GLOBAL_BOOL(lp_passwd_chat_debug, bPasswdChatDebug)
5732 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, iPasswdChatTimeout)
5733 FN_GLOBAL_BOOL(lp_nt_pipe_support, bNTPipeSupport)
5734 FN_GLOBAL_BOOL(lp_nt_status_support, bNTStatusSupport)
5735 FN_GLOBAL_BOOL(lp_stat_cache, bStatCache)
5736 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, iMaxStatCacheSize)
5737 FN_GLOBAL_BOOL(lp_allow_trusted_domains, bAllowTrustedDomains)
5738 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, bMapUntrustedToDomain)
5739 FN_GLOBAL_INTEGER(lp_restrict_anonymous, restrict_anonymous)
5740 FN_GLOBAL_BOOL(lp_lanman_auth, bLanmanAuth)
5741 FN_GLOBAL_BOOL(lp_ntlm_auth, bNTLMAuth)
5742 FN_GLOBAL_BOOL(lp_client_plaintext_auth, bClientPlaintextAuth)
5743 FN_GLOBAL_BOOL(lp_client_lanman_auth, bClientLanManAuth)
5744 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, bClientNTLMv2Auth)
5745 FN_GLOBAL_BOOL(lp_host_msdfs, bHostMSDfs)
5746 FN_GLOBAL_BOOL(lp_kernel_oplocks, bKernelOplocks)
5747 FN_GLOBAL_BOOL(lp_enhanced_browsing, enhanced_browsing)
5748 FN_GLOBAL_BOOL(lp_use_mmap, bUseMmap)
5749 FN_GLOBAL_BOOL(lp_unix_extensions, bUnixExtensions)
5750 FN_GLOBAL_BOOL(lp_use_spnego, bUseSpnego)
5751 FN_GLOBAL_BOOL(lp_client_use_spnego, bClientUseSpnego)
5752 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, client_use_spnego_principal)
5753 FN_GLOBAL_BOOL(lp_send_spnego_principal, send_spnego_principal)
5754 FN_GLOBAL_BOOL(lp_hostname_lookups, bHostnameLookups)
5755 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5756 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5757 FN_GLOBAL_CONST_STRING(lp_dedicated_keytab_file, szDedicatedKeytabFile)
5758 FN_GLOBAL_INTEGER(lp_kerberos_method, iKerberosMethod)
5759 FN_GLOBAL_BOOL(lp_defer_sharing_violations, bDeferSharingViolations)
5760 FN_GLOBAL_BOOL(lp_enable_privileges, bEnablePrivileges)
5761 FN_GLOBAL_BOOL(lp_enable_asu_support, bASUSupport)
5762 FN_GLOBAL_INTEGER(lp_os_level, os_level)
5763 FN_GLOBAL_INTEGER(lp_max_ttl, max_ttl)
5764 FN_GLOBAL_INTEGER(lp_max_wins_ttl, max_wins_ttl)
5765 FN_GLOBAL_INTEGER(lp_min_wins_ttl, min_wins_ttl)
5766 FN_GLOBAL_INTEGER(lp_max_log_size, max_log_size)
5767 FN_GLOBAL_INTEGER(lp_max_open_files, max_open_files)
5768 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, open_files_db_hash_size)
5769 FN_GLOBAL_INTEGER(lp_maxxmit, max_xmit)
5770 FN_GLOBAL_INTEGER(lp_maxmux, max_mux)
5771 FN_GLOBAL_INTEGER(lp_passwordlevel, pwordlevel)
5772 FN_GLOBAL_INTEGER(lp_usernamelevel, unamelevel)
5773 FN_GLOBAL_INTEGER(lp_deadtime, deadtime)
5774 FN_GLOBAL_BOOL(lp_getwd_cache, getwd_cache)
5775 static FN_GLOBAL_INTEGER(_lp_maxprotocol, maxprotocol)
5776 int lp_maxprotocol(void)
5777 {
5778         int ret = _lp_maxprotocol();
5779         if ((ret == PROTOCOL_SMB2) && (lp_security() == SEC_SHARE)) {
5780                 DEBUG(2,("WARNING!!: \"security = share\" is incompatible "
5781                         "with the SMB2 protocol. Resetting to SMB1.\n" ));
5782                         lp_do_parameter(-1, "max protocol", "NT1");
5783                 return PROTOCOL_NT1;
5784         }
5785         return ret;
5786 }
5787 FN_GLOBAL_INTEGER(lp_minprotocol, minprotocol)
5788 FN_GLOBAL_INTEGER(lp_security, security)
5789 FN_GLOBAL_LIST(lp_auth_methods, AuthMethods)
5790 FN_GLOBAL_BOOL(lp_paranoid_server_security, paranoid_server_security)
5791 FN_GLOBAL_INTEGER(lp_maxdisksize, maxdisksize)
5792 FN_GLOBAL_INTEGER(lp_lpqcachetime, lpqcachetime)
5793 FN_GLOBAL_INTEGER(lp_max_smbd_processes, iMaxSmbdProcesses)
5794 FN_GLOBAL_BOOL(_lp_disable_spoolss, bDisableSpoolss)
5795 FN_GLOBAL_INTEGER(lp_syslog, syslog)
5796 FN_GLOBAL_INTEGER(lp_lm_announce, lm_announce)
5797 FN_GLOBAL_INTEGER(lp_lm_interval, lm_interval)
5798 FN_GLOBAL_INTEGER(lp_machine_password_timeout, machine_password_timeout)
5799 FN_GLOBAL_INTEGER(lp_map_to_guest, map_to_guest)
5800 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, oplock_break_wait_time)
5801 FN_GLOBAL_INTEGER(lp_lock_spin_time, iLockSpinTime)
5802 FN_GLOBAL_INTEGER(lp_usershare_max_shares, iUsershareMaxShares)
5803 FN_GLOBAL_CONST_STRING(lp_socket_options, szSocketOptions)
5804 FN_GLOBAL_INTEGER(lp_config_backend, ConfigBackend)
5805 FN_GLOBAL_INTEGER(lp_smb2_max_read, ismb2_max_read)
5806 FN_GLOBAL_INTEGER(lp_smb2_max_write, ismb2_max_write)
5807 FN_GLOBAL_INTEGER(lp_smb2_max_trans, ismb2_max_trans)
5808 int lp_smb2_max_credits(void)
5809 {
5810         if (Globals.ismb2_max_credits == 0) {
5811                 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5812         }
5813         return Globals.ismb2_max_credits;
5814 }
5815 FN_LOCAL_STRING(lp_preexec, szPreExec)
5816 FN_LOCAL_STRING(lp_postexec, szPostExec)
5817 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5818 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5819 FN_LOCAL_STRING(lp_servicename, szService)
5820 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5821 FN_LOCAL_STRING(lp_pathname, szPath)
5822 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5823 FN_LOCAL_STRING(lp_username, szUsername)
5824 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5825 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5826 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5827 FN_GLOBAL_LIST(lp_svcctl_list, szServicesList)
5828 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5829 FN_GLOBAL_STRING(lp_cups_server, szCupsServer)
5830 int lp_cups_encrypt(void)
5831 {
5832         int result = 0;
5833 #ifdef HAVE_HTTPCONNECTENCRYPT
5834         switch (Globals.CupsEncrypt) {
5835                 case Auto:
5836                         result = HTTP_ENCRYPT_REQUIRED;
5837                         break;
5838                 case True:
5839                         result = HTTP_ENCRYPT_ALWAYS;
5840                         break;
5841                 case False:
5842                         result = HTTP_ENCRYPT_NEVER;
5843                         break;
5844         }
5845 #endif
5846         return result;
5847 }
5848 FN_GLOBAL_STRING(lp_iprint_server, szIPrintServer)
5849 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, cups_connection_timeout)
5850 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, ctdbdSocket)
5851 FN_GLOBAL_LIST(lp_cluster_addresses, szClusterAddresses)
5852 FN_GLOBAL_BOOL(lp_clustering, clustering)
5853 FN_GLOBAL_INTEGER(lp_ctdb_timeout, ctdb_timeout)
5854 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, ctdb_locktime_warn_threshold)
5855 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5856 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5857 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5858 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5859 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5860 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5861 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5862 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5863 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5864 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5865 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5866 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5867 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5868 FN_LOCAL_STRING(lp_comment, comment)
5869 FN_LOCAL_STRING(lp_force_user, force_user)
5870 FN_LOCAL_STRING(lp_force_group, force_group)
5871 FN_LOCAL_LIST(lp_readlist, readlist)
5872 FN_LOCAL_LIST(lp_writelist, writelist)
5873 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5874 FN_LOCAL_STRING(lp_fstype, fstype)
5875 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5876 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5877 static FN_LOCAL_STRING(lp_volume, volume)
5878 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5879 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5880 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5881 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5882 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5883 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5884 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5885 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5886 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5887 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5888 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5889 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5890 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5891 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5892 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5893 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5894 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5895 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5896 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5897 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5898 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5899 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5900 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5901 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5902 FN_LOCAL_BOOL(lp_print_notify_backchannel, bPrintNotifyBackchannel)
5903 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5904 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5905 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5906 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5907 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5908 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5909 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5910 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5911 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5912 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5913 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5914 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5915 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5916 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5917 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5918 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5919 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5920 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5921 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5922 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5923 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5924 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5925 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5926 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5927 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, bAsyncSMBEchoHandler)
5928 FN_GLOBAL_BOOL(lp_multicast_dns_register, bMulticastDnsRegister)
5929 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5930 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5931 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5932 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5933 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5934 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5935 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5936 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5937 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5938 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5939 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5940 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5941 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5942 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5943 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5944 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5945 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5946 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5947 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5948 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5949 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5950 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5951 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5952 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5953 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5954 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5955 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5956 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5957 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5958 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5959 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5960 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5961 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5962 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5963 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5964 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5965 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5966 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5967 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5968 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5969 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5970 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5971 FN_GLOBAL_INTEGER(lp_winbind_cache_time, winbind_cache_time)
5972 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, winbind_reconnect_delay)
5973 FN_GLOBAL_INTEGER(lp_winbind_max_clients, winbind_max_clients)
5974 FN_GLOBAL_LIST(lp_winbind_nss_info, szWinbindNssInfo)
5975 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, AlgorithmicRidBase)
5976 FN_GLOBAL_INTEGER(lp_name_cache_timeout, name_cache_timeout)
5977 FN_GLOBAL_INTEGER(lp_client_signing, client_signing)
5978 FN_GLOBAL_INTEGER(lp_server_signing, server_signing)
5979 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, client_ldap_sasl_wrapping)
5980
5981 FN_GLOBAL_CONST_STRING(lp_ncalrpc_dir, ncalrpc_dir)
5982
5983 /* local prototypes */
5984
5985 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5986 static const char *get_boolean(bool bool_value);
5987 static int getservicebyname(const char *pszServiceName,
5988                             struct service *pserviceDest);
5989 static void copy_service(struct service *pserviceDest,
5990                          struct service *pserviceSource,
5991                          struct bitmap *pcopymapDest);
5992 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5993                          void *userdata);
5994 static bool do_section(const char *pszSectionName, void *userdata);
5995 static void init_copymap(struct service *pservice);
5996 static bool hash_a_service(const char *name, int number);
5997 static void free_service_byindex(int iService);
5998 static void free_param_opts(struct param_opt_struct **popts);
5999 static void show_parameter(int parmIndex);
6000 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
6001
6002 /*
6003  * This is a helper function for parametrical options support.  It returns a
6004  * pointer to parametrical option value if it exists or NULL otherwise. Actual
6005  * parametrical functions are quite simple
6006  */
6007 static struct param_opt_struct *get_parametrics(int snum, const char *type,
6008                                                 const char *option)
6009 {
6010         bool global_section = False;
6011         char* param_key;
6012         struct param_opt_struct *data;
6013
6014         if (snum >= iNumServices) return NULL;
6015
6016         if (snum < 0) { 
6017                 data = Globals.param_opt;
6018                 global_section = True;
6019         } else {
6020                 data = ServicePtrs[snum]->param_opt;
6021         }
6022
6023         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
6024                 DEBUG(0,("asprintf failed!\n"));
6025                 return NULL;
6026         }
6027
6028         while (data) {
6029                 if (strwicmp(data->key, param_key) == 0) {
6030                         string_free(&param_key);
6031                         return data;
6032                 }
6033                 data = data->next;
6034         }
6035
6036         if (!global_section) {
6037                 /* Try to fetch the same option but from globals */
6038                 /* but only if we are not already working with Globals */
6039                 data = Globals.param_opt;
6040                 while (data) {
6041                         if (strwicmp(data->key, param_key) == 0) {
6042                                 string_free(&param_key);
6043                                 return data;
6044                         }
6045                         data = data->next;
6046                 }
6047         }
6048
6049         string_free(&param_key);
6050
6051         return NULL;
6052 }
6053
6054
6055 #define MISSING_PARAMETER(name) \
6056     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
6057
6058 /*******************************************************************
6059 convenience routine to return int parameters.
6060 ********************************************************************/
6061 static int lp_int(const char *s)
6062 {
6063
6064         if (!s || !*s) {
6065                 MISSING_PARAMETER(lp_int);
6066                 return (-1);
6067         }
6068
6069         return (int)strtol(s, NULL, 0);
6070 }
6071
6072 /*******************************************************************
6073 convenience routine to return unsigned long parameters.
6074 ********************************************************************/
6075 static unsigned long lp_ulong(const char *s)
6076 {
6077
6078         if (!s || !*s) {
6079                 MISSING_PARAMETER(lp_ulong);
6080                 return (0);
6081         }
6082
6083         return strtoul(s, NULL, 0);
6084 }
6085
6086 /*******************************************************************
6087 convenience routine to return boolean parameters.
6088 ********************************************************************/
6089 static bool lp_bool(const char *s)
6090 {
6091         bool ret = False;
6092
6093         if (!s || !*s) {
6094                 MISSING_PARAMETER(lp_bool);
6095                 return False;
6096         }
6097
6098         if (!set_boolean(s, &ret)) {
6099                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
6100                 return False;
6101         }
6102
6103         return ret;
6104 }
6105
6106 /*******************************************************************
6107 convenience routine to return enum parameters.
6108 ********************************************************************/
6109 static int lp_enum(const char *s,const struct enum_list *_enum)
6110 {
6111         int i;
6112
6113         if (!s || !*s || !_enum) {
6114                 MISSING_PARAMETER(lp_enum);
6115                 return (-1);
6116         }
6117
6118         for (i=0; _enum[i].name; i++) {
6119                 if (strequal(_enum[i].name,s))
6120                         return _enum[i].value;
6121         }
6122
6123         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
6124         return (-1);
6125 }
6126
6127 #undef MISSING_PARAMETER
6128
6129 /* DO NOT USE lp_parm_string ANYMORE!!!!
6130  * use lp_parm_const_string or lp_parm_talloc_string
6131  *
6132  * lp_parm_string is only used to let old modules find this symbol
6133  */
6134 #undef lp_parm_string
6135  char *lp_parm_string(const char *servicename, const char *type, const char *option);
6136  char *lp_parm_string(const char *servicename, const char *type, const char *option)
6137 {
6138         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
6139 }
6140
6141 /* Return parametric option from a given service. Type is a part of option before ':' */
6142 /* Parametric option has following syntax: 'Type: option = value' */
6143 /* the returned value is talloced on the talloc_tos() */
6144 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
6145 {
6146         struct param_opt_struct *data = get_parametrics(snum, type, option);
6147
6148         if (data == NULL||data->value==NULL) {
6149                 if (def) {
6150                         return lp_string(def);
6151                 } else {
6152                         return NULL;
6153                 }
6154         }
6155
6156         return lp_string(data->value);
6157 }
6158
6159 /* Return parametric option from a given service. Type is a part of option before ':' */
6160 /* Parametric option has following syntax: 'Type: option = value' */
6161 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6162 {
6163         struct param_opt_struct *data = get_parametrics(snum, type, option);
6164
6165         if (data == NULL||data->value==NULL)
6166                 return def;
6167
6168         return data->value;
6169 }
6170
6171 /* Return parametric option from a given service. Type is a part of option before ':' */
6172 /* Parametric option has following syntax: 'Type: option = value' */
6173
6174 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6175 {
6176         struct param_opt_struct *data = get_parametrics(snum, type, option);
6177
6178         if (data == NULL||data->value==NULL)
6179                 return (const char **)def;
6180
6181         if (data->list==NULL) {
6182                 data->list = str_list_make_v3(NULL, data->value, NULL);
6183         }
6184
6185         return (const char **)data->list;
6186 }
6187
6188 /* Return parametric option from a given service. Type is a part of option before ':' */
6189 /* Parametric option has following syntax: 'Type: option = value' */
6190
6191 int lp_parm_int(int snum, const char *type, const char *option, int def)
6192 {
6193         struct param_opt_struct *data = get_parametrics(snum, type, option);
6194
6195         if (data && data->value && *data->value)
6196                 return lp_int(data->value);
6197
6198         return def;
6199 }
6200
6201 /* Return parametric option from a given service. Type is a part of option before ':' */
6202 /* Parametric option has following syntax: 'Type: option = value' */
6203
6204 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6205 {
6206         struct param_opt_struct *data = get_parametrics(snum, type, option);
6207
6208         if (data && data->value && *data->value)
6209                 return lp_ulong(data->value);
6210
6211         return def;
6212 }
6213
6214 /* Return parametric option from a given service. Type is a part of option before ':' */
6215 /* Parametric option has following syntax: 'Type: option = value' */
6216
6217 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6218 {
6219         struct param_opt_struct *data = get_parametrics(snum, type, option);
6220
6221         if (data && data->value && *data->value)
6222                 return lp_bool(data->value);
6223
6224         return def;
6225 }
6226
6227 /* Return parametric option from a given service. Type is a part of option before ':' */
6228 /* Parametric option has following syntax: 'Type: option = value' */
6229
6230 int lp_parm_enum(int snum, const char *type, const char *option,
6231                  const struct enum_list *_enum, int def)
6232 {
6233         struct param_opt_struct *data = get_parametrics(snum, type, option);
6234
6235         if (data && data->value && *data->value && _enum)
6236                 return lp_enum(data->value, _enum);
6237
6238         return def;
6239 }
6240
6241
6242 /***************************************************************************
6243  Initialise a service to the defaults.
6244 ***************************************************************************/
6245
6246 static void init_service(struct service *pservice)
6247 {
6248         memset((char *)pservice, '\0', sizeof(struct service));
6249         copy_service(pservice, &sDefault, NULL);
6250 }
6251
6252
6253 /**
6254  * free a param_opts structure.
6255  * param_opts handling should be moved to talloc;
6256  * then this whole functions reduces to a TALLOC_FREE().
6257  */
6258
6259 static void free_param_opts(struct param_opt_struct **popts)
6260 {
6261         struct param_opt_struct *opt, *next_opt;
6262
6263         if (popts == NULL) {
6264                 return;
6265         }
6266
6267         if (*popts != NULL) {
6268                 DEBUG(5, ("Freeing parametrics:\n"));
6269         }
6270         opt = *popts;
6271         while (opt != NULL) {
6272                 string_free(&opt->key);
6273                 string_free(&opt->value);
6274                 TALLOC_FREE(opt->list);
6275                 next_opt = opt->next;
6276                 SAFE_FREE(opt);
6277                 opt = next_opt;
6278         }
6279         *popts = NULL;
6280 }
6281
6282 /***************************************************************************
6283  Free the dynamically allocated parts of a service struct.
6284 ***************************************************************************/
6285
6286 static void free_service(struct service *pservice)
6287 {
6288         if (!pservice)
6289                 return;
6290
6291         if (pservice->szService)
6292                 DEBUG(5, ("free_service: Freeing service %s\n",
6293                        pservice->szService));
6294
6295         free_parameters(pservice);
6296
6297         string_free(&pservice->szService);
6298         TALLOC_FREE(pservice->copymap);
6299
6300         free_param_opts(&pservice->param_opt);
6301
6302         ZERO_STRUCTP(pservice);
6303 }
6304
6305
6306 /***************************************************************************
6307  remove a service indexed in the ServicePtrs array from the ServiceHash
6308  and free the dynamically allocated parts
6309 ***************************************************************************/
6310
6311 static void free_service_byindex(int idx)
6312 {
6313         if ( !LP_SNUM_OK(idx) ) 
6314                 return;
6315
6316         ServicePtrs[idx]->valid = False;
6317         invalid_services[num_invalid_services++] = idx;
6318
6319         /* we have to cleanup the hash record */
6320
6321         if (ServicePtrs[idx]->szService) {
6322                 char *canon_name = canonicalize_servicename(
6323                         talloc_tos(),
6324                         ServicePtrs[idx]->szService );
6325
6326                 dbwrap_delete_bystring(ServiceHash, canon_name );
6327                 TALLOC_FREE(canon_name);
6328         }
6329
6330         free_service(ServicePtrs[idx]);
6331 }
6332
6333 /***************************************************************************
6334  Add a new service to the services array initialising it with the given 
6335  service. 
6336 ***************************************************************************/
6337
6338 static int add_a_service(const struct service *pservice, const char *name)
6339 {
6340         int i;
6341         struct service tservice;
6342         int num_to_alloc = iNumServices + 1;
6343
6344         tservice = *pservice;
6345
6346         /* it might already exist */
6347         if (name) {
6348                 i = getservicebyname(name, NULL);
6349                 if (i >= 0) {
6350                         return (i);
6351                 }
6352         }
6353
6354         /* find an invalid one */
6355         i = iNumServices;
6356         if (num_invalid_services > 0) {
6357                 i = invalid_services[--num_invalid_services];
6358         }
6359
6360         /* if not, then create one */
6361         if (i == iNumServices) {
6362                 struct service **tsp;
6363                 int *tinvalid;
6364
6365                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6366                 if (tsp == NULL) {
6367                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6368                         return (-1);
6369                 }
6370                 ServicePtrs = tsp;
6371                 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6372                 if (!ServicePtrs[iNumServices]) {
6373                         DEBUG(0,("add_a_service: out of memory!\n"));
6374                         return (-1);
6375                 }
6376                 iNumServices++;
6377
6378                 /* enlarge invalid_services here for now... */
6379                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6380                                              num_to_alloc);
6381                 if (tinvalid == NULL) {
6382                         DEBUG(0,("add_a_service: failed to enlarge "
6383                                  "invalid_services!\n"));
6384                         return (-1);
6385                 }
6386                 invalid_services = tinvalid;
6387         } else {
6388                 free_service_byindex(i);
6389         }
6390
6391         ServicePtrs[i]->valid = True;
6392
6393         init_service(ServicePtrs[i]);
6394         copy_service(ServicePtrs[i], &tservice, NULL);
6395         if (name)
6396                 string_set(&ServicePtrs[i]->szService, name);
6397
6398         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
6399                 i, ServicePtrs[i]->szService));
6400
6401         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6402                 return (-1);
6403         }
6404
6405         return (i);
6406 }
6407
6408 /***************************************************************************
6409   Convert a string to uppercase and remove whitespaces.
6410 ***************************************************************************/
6411
6412 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6413 {
6414         char *result;
6415
6416         if ( !src ) {
6417                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6418                 return NULL;
6419         }
6420
6421         result = talloc_strdup(ctx, src);
6422         SMB_ASSERT(result != NULL);
6423
6424         strlower_m(result);
6425         return result;
6426 }
6427
6428 /***************************************************************************
6429   Add a name/index pair for the services array to the hash table.
6430 ***************************************************************************/
6431
6432 static bool hash_a_service(const char *name, int idx)
6433 {
6434         char *canon_name;
6435
6436         if ( !ServiceHash ) {
6437                 DEBUG(10,("hash_a_service: creating servicehash\n"));
6438                 ServiceHash = db_open_rbt(NULL);
6439                 if ( !ServiceHash ) {
6440                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6441                         return False;
6442                 }
6443         }
6444
6445         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6446                 idx, name));
6447
6448         canon_name = canonicalize_servicename(talloc_tos(), name );
6449
6450         dbwrap_store_bystring(ServiceHash, canon_name,
6451                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
6452                               TDB_REPLACE);
6453
6454         TALLOC_FREE(canon_name);
6455
6456         return True;
6457 }
6458
6459 /***************************************************************************
6460  Add a new home service, with the specified home directory, defaults coming
6461  from service ifrom.
6462 ***************************************************************************/
6463
6464 bool lp_add_home(const char *pszHomename, int iDefaultService,
6465                  const char *user, const char *pszHomedir)
6466 {
6467         int i;
6468
6469         if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6470                         pszHomedir[0] == '\0') {
6471                 return false;
6472         }
6473
6474         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6475
6476         if (i < 0)
6477                 return (False);
6478
6479         if (!(*(ServicePtrs[iDefaultService]->szPath))
6480             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6481                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6482         }
6483
6484         if (!(*(ServicePtrs[i]->comment))) {
6485                 char *comment = NULL;
6486                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6487                         return false;
6488                 }
6489                 string_set(&ServicePtrs[i]->comment, comment);
6490                 SAFE_FREE(comment);
6491         }
6492
6493         /* set the browseable flag from the global default */
6494
6495         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6496         ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6497
6498         ServicePtrs[i]->autoloaded = True;
6499
6500         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
6501                user, ServicePtrs[i]->szPath ));
6502
6503         return (True);
6504 }
6505
6506 /***************************************************************************
6507  Add a new service, based on an old one.
6508 ***************************************************************************/
6509
6510 int lp_add_service(const char *pszService, int iDefaultService)
6511 {
6512         if (iDefaultService < 0) {
6513                 return add_a_service(&sDefault, pszService);
6514         }
6515
6516         return (add_a_service(ServicePtrs[iDefaultService], pszService));
6517 }
6518
6519 /***************************************************************************
6520  Add the IPC service.
6521 ***************************************************************************/
6522
6523 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6524 {
6525         char *comment = NULL;
6526         int i = add_a_service(&sDefault, ipc_name);
6527
6528         if (i < 0)
6529                 return (False);
6530
6531         if (asprintf(&comment, "IPC Service (%s)",
6532                                 Globals.szServerString) < 0) {
6533                 return (False);
6534         }
6535
6536         string_set(&ServicePtrs[i]->szPath, tmpdir());
6537         string_set(&ServicePtrs[i]->szUsername, "");
6538         string_set(&ServicePtrs[i]->comment, comment);
6539         string_set(&ServicePtrs[i]->fstype, "IPC");
6540         ServicePtrs[i]->iMaxConnections = 0;
6541         ServicePtrs[i]->bAvailable = True;
6542         ServicePtrs[i]->bRead_only = True;
6543         ServicePtrs[i]->bGuest_only = False;
6544         ServicePtrs[i]->bAdministrative_share = True;
6545         ServicePtrs[i]->bGuest_ok = guest_ok;
6546         ServicePtrs[i]->bPrint_ok = False;
6547         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6548
6549         DEBUG(3, ("adding IPC service\n"));
6550
6551         SAFE_FREE(comment);
6552         return (True);
6553 }
6554
6555 /***************************************************************************
6556  Add a new printer service, with defaults coming from service iFrom.
6557 ***************************************************************************/
6558
6559 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6560 {
6561         const char *comment = "From Printcap";
6562         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6563
6564         if (i < 0)
6565                 return (False);
6566
6567         /* note that we do NOT default the availability flag to True - */
6568         /* we take it from the default service passed. This allows all */
6569         /* dynamic printers to be disabled by disabling the [printers] */
6570         /* entry (if/when the 'available' keyword is implemented!).    */
6571
6572         /* the printer name is set to the service name. */
6573         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6574         string_set(&ServicePtrs[i]->comment, comment);
6575
6576         /* set the browseable flag from the gloabl default */
6577         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6578
6579         /* Printers cannot be read_only. */
6580         ServicePtrs[i]->bRead_only = False;
6581         /* No share modes on printer services. */
6582         ServicePtrs[i]->bShareModes = False;
6583         /* No oplocks on printer services. */
6584         ServicePtrs[i]->bOpLocks = False;
6585         /* Printer services must be printable. */
6586         ServicePtrs[i]->bPrint_ok = True;
6587
6588         DEBUG(3, ("adding printer service %s\n", pszPrintername));
6589
6590         return (True);
6591 }
6592
6593
6594 /***************************************************************************
6595  Check whether the given parameter name is valid.
6596  Parametric options (names containing a colon) are considered valid.
6597 ***************************************************************************/
6598
6599 bool lp_parameter_is_valid(const char *pszParmName)
6600 {
6601         return ((map_parameter(pszParmName) != -1) ||
6602                 (strchr(pszParmName, ':') != NULL));
6603 }
6604
6605 /***************************************************************************
6606  Check whether the given name is the name of a global parameter.
6607  Returns True for strings belonging to parameters of class
6608  P_GLOBAL, False for all other strings, also for parametric options
6609  and strings not belonging to any option.
6610 ***************************************************************************/
6611
6612 bool lp_parameter_is_global(const char *pszParmName)
6613 {
6614         int num = map_parameter(pszParmName);
6615
6616         if (num >= 0) {
6617                 return (parm_table[num].p_class == P_GLOBAL);
6618         }
6619
6620         return False;
6621 }
6622
6623 /**************************************************************************
6624  Check whether the given name is the canonical name of a parameter.
6625  Returns False if it is not a valid parameter Name.
6626  For parametric options, True is returned.
6627 **************************************************************************/
6628
6629 bool lp_parameter_is_canonical(const char *parm_name)
6630 {
6631         if (!lp_parameter_is_valid(parm_name)) {
6632                 return False;
6633         }
6634
6635         return (map_parameter(parm_name) ==
6636                 map_parameter_canonical(parm_name, NULL));
6637 }
6638
6639 /**************************************************************************
6640  Determine the canonical name for a parameter.
6641  Indicate when it is an inverse (boolean) synonym instead of a
6642  "usual" synonym.
6643 **************************************************************************/
6644
6645 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6646                                bool *inverse)
6647 {
6648         int num;
6649
6650         if (!lp_parameter_is_valid(parm_name)) {
6651                 *canon_parm = NULL;
6652                 return False;
6653         }
6654
6655         num = map_parameter_canonical(parm_name, inverse);
6656         if (num < 0) {
6657                 /* parametric option */
6658                 *canon_parm = parm_name;
6659         } else {
6660                 *canon_parm = parm_table[num].label;
6661         }
6662
6663         return True;
6664
6665 }
6666
6667 /**************************************************************************
6668  Determine the canonical name for a parameter.
6669  Turn the value given into the inverse boolean expression when
6670  the synonym is an invers boolean synonym.
6671
6672  Return True if parm_name is a valid parameter name and
6673  in case it is an invers boolean synonym, if the val string could
6674  successfully be converted to the reverse bool.
6675  Return false in all other cases.
6676 **************************************************************************/
6677
6678 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6679                                           const char *val,
6680                                           const char **canon_parm,
6681                                           const char **canon_val)
6682 {
6683         int num;
6684         bool inverse;
6685
6686         if (!lp_parameter_is_valid(parm_name)) {
6687                 *canon_parm = NULL;
6688                 *canon_val = NULL;
6689                 return False;
6690         }
6691
6692         num = map_parameter_canonical(parm_name, &inverse);
6693         if (num < 0) {
6694                 /* parametric option */
6695                 *canon_parm = parm_name;
6696                 *canon_val = val;
6697         } else {
6698                 *canon_parm = parm_table[num].label;
6699                 if (inverse) {
6700                         if (!lp_invert_boolean(val, canon_val)) {
6701                                 *canon_val = NULL;
6702                                 return False;
6703                         }
6704                 } else {
6705                         *canon_val = val;
6706                 }
6707         }
6708
6709         return True;
6710 }
6711
6712 /***************************************************************************
6713  Map a parameter's string representation to something we can use. 
6714  Returns False if the parameter string is not recognised, else TRUE.
6715 ***************************************************************************/
6716
6717 static int map_parameter(const char *pszParmName)
6718 {
6719         int iIndex;
6720
6721         if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6722                 return (-1);
6723
6724         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6725                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6726                         return (iIndex);
6727
6728         /* Warn only if it isn't parametric option */
6729         if (strchr(pszParmName, ':') == NULL)
6730                 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6731         /* We do return 'fail' for parametric options as well because they are
6732            stored in different storage
6733          */
6734         return (-1);
6735 }
6736
6737 /***************************************************************************
6738  Map a parameter's string representation to the index of the canonical
6739  form of the parameter (it might be a synonym).
6740  Returns -1 if the parameter string is not recognised.
6741 ***************************************************************************/
6742
6743 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6744 {
6745         int parm_num, canon_num;
6746         bool loc_inverse = False;
6747
6748         parm_num = map_parameter(pszParmName);
6749         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6750                 /* invalid, parametric or no canidate for synonyms ... */
6751                 goto done;
6752         }
6753
6754         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6755                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6756                         parm_num = canon_num;
6757                         goto done;
6758                 }
6759         }
6760
6761 done:
6762         if (inverse != NULL) {
6763                 *inverse = loc_inverse;
6764         }
6765         return parm_num;
6766 }
6767
6768 /***************************************************************************
6769  return true if parameter number parm1 is a synonym of parameter
6770  number parm2 (parm2 being the principal name).
6771  set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6772  False otherwise.
6773 ***************************************************************************/
6774
6775 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6776 {
6777         if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6778             (parm_table[parm1].flags & FLAG_HIDE) &&
6779             !(parm_table[parm2].flags & FLAG_HIDE))
6780         {
6781                 if (inverse != NULL) {
6782                         if ((parm_table[parm1].type == P_BOOLREV) &&
6783                             (parm_table[parm2].type == P_BOOL))
6784                         {
6785                                 *inverse = True;
6786                         } else {
6787                                 *inverse = False;
6788                         }
6789                 }
6790                 return True;
6791         }
6792         return False;
6793 }
6794
6795 /***************************************************************************
6796  Show one parameter's name, type, [values,] and flags.
6797  (helper functions for show_parameter_list)
6798 ***************************************************************************/
6799
6800 static void show_parameter(int parmIndex)
6801 {
6802         int enumIndex, flagIndex;
6803         int parmIndex2;
6804         bool hadFlag;
6805         bool hadSyn;
6806         bool inverse;
6807         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6808                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6809                 "P_ENUM", "P_SEP"};
6810         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6811                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6812                 FLAG_HIDE, FLAG_DOS_STRING};
6813         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6814                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6815                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6816
6817         printf("%s=%s", parm_table[parmIndex].label,
6818                type[parm_table[parmIndex].type]);
6819         if (parm_table[parmIndex].type == P_ENUM) {
6820                 printf(",");
6821                 for (enumIndex=0;
6822                      parm_table[parmIndex].enum_list[enumIndex].name;
6823                      enumIndex++)
6824                 {
6825                         printf("%s%s",
6826                                enumIndex ? "|" : "",
6827                                parm_table[parmIndex].enum_list[enumIndex].name);
6828                 }
6829         }
6830         printf(",");
6831         hadFlag = False;
6832         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6833                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6834                         printf("%s%s",
6835                                 hadFlag ? "|" : "",
6836                                 flag_names[flagIndex]);
6837                         hadFlag = True;
6838                 }
6839         }
6840
6841         /* output synonyms */
6842         hadSyn = False;
6843         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6844                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6845                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6846                                parm_table[parmIndex2].label);
6847                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6848                         if (!hadSyn) {
6849                                 printf(" (synonyms: ");
6850                                 hadSyn = True;
6851                         } else {
6852                                 printf(", ");
6853                         }
6854                         printf("%s%s", parm_table[parmIndex2].label,
6855                                inverse ? "[i]" : "");
6856                 }
6857         }
6858         if (hadSyn) {
6859                 printf(")");
6860         }
6861
6862         printf("\n");
6863 }
6864
6865 /***************************************************************************
6866  Show all parameter's name, type, [values,] and flags.
6867 ***************************************************************************/
6868
6869 void show_parameter_list(void)
6870 {
6871         int classIndex, parmIndex;
6872         const char *section_names[] = { "local", "global", NULL};
6873
6874         for (classIndex=0; section_names[classIndex]; classIndex++) {
6875                 printf("[%s]\n", section_names[classIndex]);
6876                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6877                         if (parm_table[parmIndex].p_class == classIndex) {
6878                                 show_parameter(parmIndex);
6879                         }
6880                 }
6881         }
6882 }
6883
6884 /***************************************************************************
6885  Check if a given string correctly represents a boolean value.
6886 ***************************************************************************/
6887
6888 bool lp_string_is_valid_boolean(const char *parm_value)
6889 {
6890         return set_boolean(parm_value, NULL);
6891 }
6892
6893 /***************************************************************************
6894  Get the standard string representation of a boolean value ("yes" or "no")
6895 ***************************************************************************/
6896
6897 static const char *get_boolean(bool bool_value)
6898 {
6899         static const char *yes_str = "yes";
6900         static const char *no_str = "no";
6901
6902         return (bool_value ? yes_str : no_str);
6903 }
6904
6905 /***************************************************************************
6906  Provide the string of the negated boolean value associated to the boolean
6907  given as a string. Returns False if the passed string does not correctly
6908  represent a boolean.
6909 ***************************************************************************/
6910
6911 bool lp_invert_boolean(const char *str, const char **inverse_str)
6912 {
6913         bool val;
6914
6915         if (!set_boolean(str, &val)) {
6916                 return False;
6917         }
6918
6919         *inverse_str = get_boolean(!val);
6920         return True;
6921 }
6922
6923 /***************************************************************************
6924  Provide the canonical string representation of a boolean value given
6925  as a string. Return True on success, False if the string given does
6926  not correctly represent a boolean.
6927 ***************************************************************************/
6928
6929 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6930 {
6931         bool val;
6932
6933         if (!set_boolean(str, &val)) {
6934                 return False;
6935         }
6936
6937         *canon_str = get_boolean(val);
6938         return True;
6939 }
6940
6941 /***************************************************************************
6942 Find a service by name. Otherwise works like get_service.
6943 ***************************************************************************/
6944
6945 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6946 {
6947         int iService = -1;
6948         char *canon_name;
6949         TDB_DATA data;
6950
6951         if (ServiceHash == NULL) {
6952                 return -1;
6953         }
6954
6955         canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6956
6957         data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6958
6959         if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6960                 iService = *(int *)data.dptr;
6961         }
6962
6963         TALLOC_FREE(canon_name);
6964
6965         if ((iService != -1) && (LP_SNUM_OK(iService))
6966             && (pserviceDest != NULL)) {
6967                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6968         }
6969
6970         return (iService);
6971 }
6972
6973 /***************************************************************************
6974  Copy a service structure to another.
6975  If pcopymapDest is NULL then copy all fields
6976 ***************************************************************************/
6977
6978 /**
6979  * Add a parametric option to a param_opt_struct,
6980  * replacing old value, if already present.
6981  */
6982 static void set_param_opt(struct param_opt_struct **opt_list,
6983                           const char *opt_name,
6984                           const char *opt_value,
6985                           unsigned flags)
6986 {
6987         struct param_opt_struct *new_opt, *opt;
6988         bool not_added;
6989
6990         if (opt_list == NULL) {
6991                 return;
6992         }
6993
6994         opt = *opt_list;
6995         not_added = true;
6996
6997         /* Traverse destination */
6998         while (opt) {
6999                 /* If we already have same option, override it */
7000                 if (strwicmp(opt->key, opt_name) == 0) {
7001                         if ((opt->flags & FLAG_CMDLINE) &&
7002                             !(flags & FLAG_CMDLINE)) {
7003                                 /* it's been marked as not to be
7004                                    overridden */
7005                                 return;
7006                         }
7007                         string_free(&opt->value);
7008                         TALLOC_FREE(opt->list);
7009                         opt->value = SMB_STRDUP(opt_value);
7010                         opt->flags = flags;
7011                         not_added = false;
7012                         break;
7013                 }
7014                 opt = opt->next;
7015         }
7016         if (not_added) {
7017             new_opt = SMB_XMALLOC_P(struct param_opt_struct);
7018             new_opt->key = SMB_STRDUP(opt_name);
7019             new_opt->value = SMB_STRDUP(opt_value);
7020             new_opt->list = NULL;
7021             new_opt->flags = flags;
7022             DLIST_ADD(*opt_list, new_opt);
7023         }
7024 }
7025
7026 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
7027                          struct bitmap *pcopymapDest)
7028 {
7029         int i;
7030         bool bcopyall = (pcopymapDest == NULL);
7031         struct param_opt_struct *data;
7032
7033         for (i = 0; parm_table[i].label; i++)
7034                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
7035                     (bcopyall || bitmap_query(pcopymapDest,i))) {
7036                         void *def_ptr = parm_table[i].ptr;
7037                         void *src_ptr =
7038                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
7039                                                                     &sDefault);
7040                         void *dest_ptr =
7041                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
7042                                                                   &sDefault);
7043
7044                         switch (parm_table[i].type) {
7045                                 case P_BOOL:
7046                                 case P_BOOLREV:
7047                                         *(bool *)dest_ptr = *(bool *)src_ptr;
7048                                         break;
7049
7050                                 case P_INTEGER:
7051                                 case P_ENUM:
7052                                 case P_OCTAL:
7053                                         *(int *)dest_ptr = *(int *)src_ptr;
7054                                         break;
7055
7056                                 case P_CHAR:
7057                                         *(char *)dest_ptr = *(char *)src_ptr;
7058                                         break;
7059
7060                                 case P_STRING:
7061                                         string_set((char **)dest_ptr,
7062                                                    *(char **)src_ptr);
7063                                         break;
7064
7065                                 case P_USTRING:
7066                                 {
7067                                         char *upper_string = strupper_talloc(talloc_tos(), 
7068                                                                              *(char **)src_ptr);
7069                                         string_set((char **)dest_ptr,
7070                                                    upper_string);
7071                                         TALLOC_FREE(upper_string);
7072                                         break;
7073                                 }
7074                                 case P_LIST:
7075                                         TALLOC_FREE(*((char ***)dest_ptr));
7076                                         *((char ***)dest_ptr) = str_list_copy(NULL, 
7077                                                       *(const char ***)src_ptr);
7078                                         break;
7079                                 default:
7080                                         break;
7081                         }
7082                 }
7083
7084         if (bcopyall) {
7085                 init_copymap(pserviceDest);
7086                 if (pserviceSource->copymap)
7087                         bitmap_copy(pserviceDest->copymap,
7088                                     pserviceSource->copymap);
7089         }
7090
7091         data = pserviceSource->param_opt;
7092         while (data) {
7093                 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->flags);
7094                 data = data->next;
7095         }
7096 }
7097
7098 /***************************************************************************
7099 Check a service for consistency. Return False if the service is in any way
7100 incomplete or faulty, else True.
7101 ***************************************************************************/
7102
7103 bool service_ok(int iService)
7104 {
7105         bool bRetval;
7106
7107         bRetval = True;
7108         if (ServicePtrs[iService]->szService[0] == '\0') {
7109                 DEBUG(0, ("The following message indicates an internal error:\n"));
7110                 DEBUG(0, ("No service name in service entry.\n"));
7111                 bRetval = False;
7112         }
7113
7114         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
7115         /* I can't see why you'd want a non-printable printer service...        */
7116         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
7117                 if (!ServicePtrs[iService]->bPrint_ok) {
7118                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
7119                                ServicePtrs[iService]->szService));
7120                         ServicePtrs[iService]->bPrint_ok = True;
7121                 }
7122                 /* [printers] service must also be non-browsable. */
7123                 if (ServicePtrs[iService]->bBrowseable)
7124                         ServicePtrs[iService]->bBrowseable = False;
7125         }
7126
7127         if (ServicePtrs[iService]->szPath[0] == '\0' &&
7128             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
7129             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
7130             ) {
7131                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
7132                         ServicePtrs[iService]->szService));
7133                 ServicePtrs[iService]->bAvailable = False;
7134         }
7135
7136         /* If a service is flagged unavailable, log the fact at level 1. */
7137         if (!ServicePtrs[iService]->bAvailable)
7138                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
7139                           ServicePtrs[iService]->szService));
7140
7141         return (bRetval);
7142 }
7143
7144 static struct smbconf_ctx *lp_smbconf_ctx(void)
7145 {
7146         sbcErr err;
7147         static struct smbconf_ctx *conf_ctx = NULL;
7148
7149         if (conf_ctx == NULL) {
7150                 err = smbconf_init(NULL, &conf_ctx, "registry:");
7151                 if (!SBC_ERROR_IS_OK(err)) {
7152                         DEBUG(1, ("error initializing registry configuration: "
7153                                   "%s\n", sbcErrorString(err)));
7154                         conf_ctx = NULL;
7155                 }
7156         }
7157
7158         return conf_ctx;
7159 }
7160
7161 static bool process_smbconf_service(struct smbconf_service *service)
7162 {
7163         uint32_t count;
7164         bool ret;
7165
7166         if (service == NULL) {
7167                 return false;
7168         }
7169
7170         ret = do_section(service->name, NULL);
7171         if (ret != true) {
7172                 return false;
7173         }
7174         for (count = 0; count < service->num_params; count++) {
7175                 ret = do_parameter(service->param_names[count],
7176                                    service->param_values[count],
7177                                    NULL);
7178                 if (ret != true) {
7179                         return false;
7180                 }
7181         }
7182         if (iServiceIndex >= 0) {
7183                 return service_ok(iServiceIndex);
7184         }
7185         return true;
7186 }
7187
7188 /**
7189  * load a service from registry and activate it
7190  */
7191 bool process_registry_service(const char *service_name)
7192 {
7193         sbcErr err;
7194         struct smbconf_service *service = NULL;
7195         TALLOC_CTX *mem_ctx = talloc_stackframe();
7196         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7197         bool ret = false;
7198
7199         if (conf_ctx == NULL) {
7200                 goto done;
7201         }
7202
7203         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7204
7205         if (!smbconf_share_exists(conf_ctx, service_name)) {
7206                 /*
7207                  * Registry does not contain data for this service (yet),
7208                  * but make sure lp_load doesn't return false.
7209                  */
7210                 ret = true;
7211                 goto done;
7212         }
7213
7214         err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7215         if (!SBC_ERROR_IS_OK(err)) {
7216                 goto done;
7217         }
7218
7219         ret = process_smbconf_service(service);
7220         if (!ret) {
7221                 goto done;
7222         }
7223
7224         /* store the csn */
7225         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7226
7227 done:
7228         TALLOC_FREE(mem_ctx);
7229         return ret;
7230 }
7231
7232 /*
7233  * process_registry_globals
7234  */
7235 static bool process_registry_globals(void)
7236 {
7237         bool ret;
7238
7239         add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7240
7241         ret = do_parameter("registry shares", "yes", NULL);
7242         if (!ret) {
7243                 return ret;
7244         }
7245
7246         return process_registry_service(GLOBAL_NAME);
7247 }
7248
7249 bool process_registry_shares(void)
7250 {
7251         sbcErr err;
7252         uint32_t count;
7253         struct smbconf_service **service = NULL;
7254         uint32_t num_shares = 0;
7255         TALLOC_CTX *mem_ctx = talloc_stackframe();
7256         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7257         bool ret = false;
7258
7259         if (conf_ctx == NULL) {
7260                 goto done;
7261         }
7262
7263         err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7264         if (!SBC_ERROR_IS_OK(err)) {
7265                 goto done;
7266         }
7267
7268         ret = true;
7269
7270         for (count = 0; count < num_shares; count++) {
7271                 if (strequal(service[count]->name, GLOBAL_NAME)) {
7272                         continue;
7273                 }
7274                 ret = process_smbconf_service(service[count]);
7275                 if (!ret) {
7276                         goto done;
7277                 }
7278         }
7279
7280         /* store the csn */
7281         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7282
7283 done:
7284         TALLOC_FREE(mem_ctx);
7285         return ret;
7286 }
7287
7288 #define MAX_INCLUDE_DEPTH 100
7289
7290 static uint8_t include_depth;
7291
7292 static struct file_lists {
7293         struct file_lists *next;
7294         char *name;
7295         char *subfname;
7296         time_t modtime;
7297 } *file_lists = NULL;
7298
7299 /*******************************************************************
7300  Keep a linked list of all config files so we know when one has changed 
7301  it's date and needs to be reloaded.
7302 ********************************************************************/
7303
7304 static void add_to_file_list(const char *fname, const char *subfname)
7305 {
7306         struct file_lists *f = file_lists;
7307
7308         while (f) {
7309                 if (f->name && !strcmp(f->name, fname))
7310                         break;
7311                 f = f->next;
7312         }
7313
7314         if (!f) {
7315                 f = SMB_MALLOC_P(struct file_lists);
7316                 if (!f)
7317                         return;
7318                 f->next = file_lists;
7319                 f->name = SMB_STRDUP(fname);
7320                 if (!f->name) {
7321                         SAFE_FREE(f);
7322                         return;
7323                 }
7324                 f->subfname = SMB_STRDUP(subfname);
7325                 if (!f->subfname) {
7326                         SAFE_FREE(f->name);
7327                         SAFE_FREE(f);
7328                         return;
7329                 }
7330                 file_lists = f;
7331                 f->modtime = file_modtime(subfname);
7332         } else {
7333                 time_t t = file_modtime(subfname);
7334                 if (t)
7335                         f->modtime = t;
7336         }
7337         return;
7338 }
7339
7340 /**
7341  * Free the file lists
7342  */
7343 static void free_file_list(void)
7344 {
7345         struct file_lists *f;
7346         struct file_lists *next;
7347
7348         f = file_lists;
7349         while( f ) {
7350                 next = f->next;
7351                 SAFE_FREE( f->name );
7352                 SAFE_FREE( f->subfname );
7353                 SAFE_FREE( f );
7354                 f = next;
7355         }
7356         file_lists = NULL;
7357 }
7358
7359
7360 /**
7361  * Utility function for outsiders to check if we're running on registry.
7362  */
7363 bool lp_config_backend_is_registry(void)
7364 {
7365         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7366 }
7367
7368 /**
7369  * Utility function to check if the config backend is FILE.
7370  */
7371 bool lp_config_backend_is_file(void)
7372 {
7373         return (lp_config_backend() == CONFIG_BACKEND_FILE);
7374 }
7375
7376 /*******************************************************************
7377  Check if a config file has changed date.
7378 ********************************************************************/
7379
7380 bool lp_file_list_changed(void)
7381 {
7382         struct file_lists *f = file_lists;
7383
7384         DEBUG(6, ("lp_file_list_changed()\n"));
7385
7386         while (f) {
7387                 time_t mod_time;
7388
7389                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7390                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7391
7392                         if (conf_ctx == NULL) {
7393                                 return false;
7394                         }
7395                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7396                                             NULL))
7397                         {
7398                                 DEBUGADD(6, ("registry config changed\n"));
7399                                 return true;
7400                         }
7401                 } else {
7402                         char *n2 = NULL;
7403                         n2 = talloc_sub_basic(talloc_tos(),
7404                                               get_current_username(),
7405                                               current_user_info.domain,
7406                                               f->name);
7407                         if (!n2) {
7408                                 return false;
7409                         }
7410                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
7411                                      f->name, n2, ctime(&f->modtime)));
7412
7413                         mod_time = file_modtime(n2);
7414
7415                         if (mod_time &&
7416                             ((f->modtime != mod_time) ||
7417                              (f->subfname == NULL) ||
7418                              (strcmp(n2, f->subfname) != 0)))
7419                         {
7420                                 DEBUGADD(6,
7421                                          ("file %s modified: %s\n", n2,
7422                                           ctime(&mod_time)));
7423                                 f->modtime = mod_time;
7424                                 SAFE_FREE(f->subfname);
7425                                 f->subfname = SMB_STRDUP(n2);
7426                                 TALLOC_FREE(n2);
7427                                 return true;
7428                         }
7429                         TALLOC_FREE(n2);
7430                 }
7431                 f = f->next;
7432         }
7433         return (False);
7434 }
7435
7436
7437 /**
7438  * Initialize iconv conversion descriptors.
7439  *
7440  * This is called the first time it is needed, and also called again
7441  * every time the configuration is reloaded, because the charset or
7442  * codepage might have changed.
7443  **/
7444 static void init_iconv(void)
7445 {
7446         global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
7447                                                       lp_unix_charset(),
7448                                                       true, global_iconv_handle);
7449 }
7450
7451 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7452 {
7453         if (strcmp(*ptr, pszParmValue) != 0) {
7454                 string_set(ptr, pszParmValue);
7455                 init_iconv();
7456         }
7457         return True;
7458 }
7459
7460 static bool handle_dos_charset(int snum, const char *pszParmValue, char **ptr)
7461 {
7462         bool is_utf8 = false;
7463         size_t len = strlen(pszParmValue);
7464
7465         if (len == 4 || len == 5) {
7466                 /* Don't use StrCaseCmp here as we don't want to
7467                    initialize iconv. */
7468                 if ((toupper_ascii(pszParmValue[0]) == 'U') &&
7469                     (toupper_ascii(pszParmValue[1]) == 'T') &&
7470                     (toupper_ascii(pszParmValue[2]) == 'F')) {
7471                         if (len == 4) {
7472                                 if (pszParmValue[3] == '8') {
7473                                         is_utf8 = true;
7474                                 }
7475                         } else {
7476                                 if (pszParmValue[3] == '-' &&
7477                                     pszParmValue[4] == '8') {
7478                                         is_utf8 = true;
7479                                 }
7480                         }
7481                 }
7482         }
7483
7484         if (strcmp(*ptr, pszParmValue) != 0) {
7485                 if (is_utf8) {
7486                         DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
7487                                 "be UTF8, using (default value) %s instead.\n",
7488                                 DEFAULT_DOS_CHARSET));
7489                         pszParmValue = DEFAULT_DOS_CHARSET;
7490                 }
7491                 string_set(ptr, pszParmValue);
7492                 init_iconv();
7493         }
7494         return true;
7495 }
7496
7497 static bool handle_realm(int snum, const char *pszParmValue, char **ptr)
7498 {
7499         bool ret = true;
7500         char *realm = strupper_talloc(talloc_tos(), pszParmValue);
7501         char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
7502
7503         ret &= string_set(&Globals.szRealm, pszParmValue);
7504         ret &= string_set(&Globals.szRealmUpper, realm);
7505         ret &= string_set(&Globals.szDnsDomain, dnsdomain);
7506         TALLOC_FREE(realm);
7507         TALLOC_FREE(dnsdomain);
7508
7509         return ret;
7510 }
7511
7512 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7513 {
7514         TALLOC_FREE(Globals.szNetbiosAliases);
7515         Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
7516         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7517 }
7518
7519 /***************************************************************************
7520  Handle the include operation.
7521 ***************************************************************************/
7522 static bool bAllowIncludeRegistry = true;
7523
7524 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7525 {
7526         char *fname;
7527
7528         if (include_depth >= MAX_INCLUDE_DEPTH) {
7529                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7530                           include_depth));
7531                 return false;
7532         }
7533
7534         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7535                 if (!bAllowIncludeRegistry) {
7536                         return true;
7537                 }
7538                 if (bInGlobalSection) {
7539                         bool ret;
7540                         include_depth++;
7541                         ret = process_registry_globals();
7542                         include_depth--;
7543                         return ret;
7544                 } else {
7545                         DEBUG(1, ("\"include = registry\" only effective "
7546                                   "in %s section\n", GLOBAL_NAME));
7547                         return false;
7548                 }
7549         }
7550
7551         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7552                                  current_user_info.domain,
7553                                  pszParmValue);
7554
7555         add_to_file_list(pszParmValue, fname);
7556
7557         string_set(ptr, fname);
7558
7559         if (file_exist(fname)) {
7560                 bool ret;
7561                 include_depth++;
7562                 ret = pm_process(fname, do_section, do_parameter, NULL);
7563                 include_depth--;
7564                 TALLOC_FREE(fname);
7565                 return ret;
7566         }
7567
7568         DEBUG(2, ("Can't find include file %s\n", fname));
7569         TALLOC_FREE(fname);
7570         return true;
7571 }
7572
7573 /***************************************************************************
7574  Handle the interpretation of the copy parameter.
7575 ***************************************************************************/
7576
7577 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7578 {
7579         bool bRetval;
7580         int iTemp;
7581         struct service serviceTemp;
7582
7583         string_set(ptr, pszParmValue);
7584
7585         init_service(&serviceTemp);
7586
7587         bRetval = False;
7588
7589         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7590
7591         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7592                 if (iTemp == iServiceIndex) {
7593                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7594                 } else {
7595                         copy_service(ServicePtrs[iServiceIndex],
7596                                      &serviceTemp,
7597                                      ServicePtrs[iServiceIndex]->copymap);
7598                         bRetval = True;
7599                 }
7600         } else {
7601                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7602                 bRetval = False;
7603         }
7604
7605         free_service(&serviceTemp);
7606         return (bRetval);
7607 }
7608
7609 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7610 {
7611         Globals.ldap_debug_level = lp_int(pszParmValue);
7612         init_ldap_debugging();
7613         return true;
7614 }
7615
7616 /***************************************************************************
7617  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
7618  parameters is:
7619
7620  [global]
7621
7622         idmap uid = 1000-1999
7623         idmap gid = 700-899
7624
7625  We only do simple parsing checks here.  The strings are parsed into useful
7626  structures in the idmap daemon code.
7627
7628 ***************************************************************************/
7629
7630 /* Some lp_ routines to return idmap [ug]id information */
7631
7632 static uid_t idmap_uid_low, idmap_uid_high;
7633 static gid_t idmap_gid_low, idmap_gid_high;
7634
7635 bool lp_idmap_uid(uid_t *low, uid_t *high)
7636 {
7637         if (idmap_uid_low == 0 || idmap_uid_high == 0)
7638                 return False;
7639
7640         if (low)
7641                 *low = idmap_uid_low;
7642
7643         if (high)
7644                 *high = idmap_uid_high;
7645
7646         return True;
7647 }
7648
7649 bool lp_idmap_gid(gid_t *low, gid_t *high)
7650 {
7651         if (idmap_gid_low == 0 || idmap_gid_high == 0)
7652                 return False;
7653
7654         if (low)
7655                 *low = idmap_gid_low;
7656
7657         if (high)
7658                 *high = idmap_gid_high;
7659
7660         return True;
7661 }
7662
7663 static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr)
7664 {
7665         lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7666
7667         return true;
7668 }
7669
7670 /* Do some simple checks on "idmap [ug]id" parameter values */
7671
7672 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7673 {
7674         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7675
7676         return True;
7677 }
7678
7679 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7680 {
7681         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7682
7683         return True;
7684 }
7685
7686 /***************************************************************************
7687  Handle the DEBUG level list.
7688 ***************************************************************************/
7689
7690 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7691 {
7692         string_set(ptr, pszParmValueIn);
7693         return debug_parse_levels(pszParmValueIn);
7694 }
7695
7696 /***************************************************************************
7697  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7698 ***************************************************************************/
7699
7700 static const char *append_ldap_suffix( const char *str )
7701 {
7702         const char *suffix_string;
7703
7704
7705         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7706                                         Globals.szLdapSuffix );
7707         if ( !suffix_string ) {
7708                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7709                 return "";
7710         }
7711
7712         return suffix_string;
7713 }
7714
7715 const char *lp_ldap_machine_suffix(void)
7716 {
7717         if (Globals.szLdapMachineSuffix[0])
7718                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7719
7720         return lp_string(Globals.szLdapSuffix);
7721 }
7722
7723 const char *lp_ldap_user_suffix(void)
7724 {
7725         if (Globals.szLdapUserSuffix[0])
7726                 return append_ldap_suffix(Globals.szLdapUserSuffix);
7727
7728         return lp_string(Globals.szLdapSuffix);
7729 }
7730
7731 const char *lp_ldap_group_suffix(void)
7732 {
7733         if (Globals.szLdapGroupSuffix[0])
7734                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7735
7736         return lp_string(Globals.szLdapSuffix);
7737 }
7738
7739 const char *lp_ldap_idmap_suffix(void)
7740 {
7741         if (Globals.szLdapIdmapSuffix[0])
7742                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7743
7744         return lp_string(Globals.szLdapSuffix);
7745 }
7746
7747 /****************************************************************************
7748  set the value for a P_ENUM
7749  ***************************************************************************/
7750
7751 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7752                               int *ptr )
7753 {
7754         int i;
7755
7756         for (i = 0; parm->enum_list[i].name; i++) {
7757                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7758                         *ptr = parm->enum_list[i].value;
7759                         return;
7760                 }
7761         }
7762         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7763                   pszParmValue, parm->label));
7764 }
7765
7766 /***************************************************************************
7767 ***************************************************************************/
7768
7769 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7770 {
7771         static int parm_num = -1;
7772         struct service *s;
7773
7774         if ( parm_num == -1 )
7775                 parm_num = map_parameter( "printing" );
7776
7777         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7778
7779         if ( snum < 0 )
7780                 s = &sDefault;
7781         else
7782                 s = ServicePtrs[snum];
7783
7784         init_printer_values( s );
7785
7786         return True;
7787 }
7788
7789
7790 /***************************************************************************
7791  Initialise a copymap.
7792 ***************************************************************************/
7793
7794 static void init_copymap(struct service *pservice)
7795 {
7796         int i;
7797
7798         TALLOC_FREE(pservice->copymap);
7799
7800         pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7801         if (!pservice->copymap)
7802                 DEBUG(0,
7803                       ("Couldn't allocate copymap!! (size %d)\n",
7804                        (int)NUMPARAMETERS));
7805         else
7806                 for (i = 0; i < NUMPARAMETERS; i++)
7807                         bitmap_set(pservice->copymap, i);
7808 }
7809
7810 /***************************************************************************
7811  Return the local pointer to a parameter given a service struct and the
7812  pointer into the default structure.
7813 ***************************************************************************/
7814
7815 static void *lp_local_ptr(struct service *service, void *ptr)
7816 {
7817         return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7818 }
7819
7820 /***************************************************************************
7821  Return the local pointer to a parameter given the service number and the 
7822  pointer into the default structure.
7823 ***************************************************************************/
7824
7825 void *lp_local_ptr_by_snum(int snum, void *ptr)
7826 {
7827         return lp_local_ptr(ServicePtrs[snum], ptr);
7828 }
7829
7830 /***************************************************************************
7831  Process a parameter for a particular service number. If snum < 0
7832  then assume we are in the globals.
7833 ***************************************************************************/
7834
7835 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7836 {
7837         int parmnum, i;
7838         void *parm_ptr = NULL;  /* where we are going to store the result */
7839         void *def_ptr = NULL;
7840         struct param_opt_struct **opt_list;
7841
7842         parmnum = map_parameter(pszParmName);
7843
7844         if (parmnum < 0) {
7845                 if (strchr(pszParmName, ':') == NULL) {
7846                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7847                                   pszParmName));
7848                         return (True);
7849                 }
7850
7851                 /*
7852                  * We've got a parametric option
7853                  */
7854
7855                 opt_list = (snum < 0)
7856                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7857                 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7858
7859                 return (True);
7860         }
7861
7862         /* if it's already been set by the command line, then we don't
7863            override here */
7864         if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7865                 return true;
7866         }
7867
7868         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7869                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7870                           pszParmName));
7871         }
7872
7873         def_ptr = parm_table[parmnum].ptr;
7874
7875         /* we might point at a service, the default service or a global */
7876         if (snum < 0) {
7877                 parm_ptr = def_ptr;
7878         } else {
7879                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7880                         DEBUG(0,
7881                               ("Global parameter %s found in service section!\n",
7882                                pszParmName));
7883                         return (True);
7884                 }
7885                 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7886         }
7887
7888         if (snum >= 0) {
7889                 if (!ServicePtrs[snum]->copymap)
7890                         init_copymap(ServicePtrs[snum]);
7891
7892                 /* this handles the aliases - set the copymap for other entries with
7893                    the same data pointer */
7894                 for (i = 0; parm_table[i].label; i++)
7895                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7896                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7897         }
7898
7899         /* if it is a special case then go ahead */
7900         if (parm_table[parmnum].special) {
7901                 return parm_table[parmnum].special(snum, pszParmValue,
7902                                                    (char **)parm_ptr);
7903         }
7904
7905         /* now switch on the type of variable it is */
7906         switch (parm_table[parmnum].type)
7907         {
7908                 case P_BOOL:
7909                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7910                         break;
7911
7912                 case P_BOOLREV:
7913                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7914                         break;
7915
7916                 case P_INTEGER:
7917                         *(int *)parm_ptr = lp_int(pszParmValue);
7918                         break;
7919
7920                 case P_CHAR:
7921                         *(char *)parm_ptr = *pszParmValue;
7922                         break;
7923
7924                 case P_OCTAL:
7925                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7926                         if ( i != 1 ) {
7927                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7928                         }
7929                         break;
7930
7931                 case P_LIST:
7932                         TALLOC_FREE(*((char ***)parm_ptr));
7933                         *(char ***)parm_ptr = str_list_make_v3(
7934                                 NULL, pszParmValue, NULL);
7935                         break;
7936
7937                 case P_STRING:
7938                         string_set((char **)parm_ptr, pszParmValue);
7939                         break;
7940
7941                 case P_USTRING:
7942                 {
7943                         char *upper_string = strupper_talloc(talloc_tos(), 
7944                                                              pszParmValue);
7945                         string_set((char **)parm_ptr, upper_string);
7946                         TALLOC_FREE(upper_string);
7947                         break;
7948                 }
7949                 case P_ENUM:
7950                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7951                         break;
7952                 case P_SEP:
7953                         break;
7954         }
7955
7956         return (True);
7957 }
7958
7959 /***************************************************************************
7960 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7961 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7962 ***************************************************************************/
7963
7964 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7965 {
7966         int parmnum, i;
7967         parmnum = map_parameter(pszParmName);
7968         if (parmnum >= 0) {
7969                 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7970                 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7971                         return false;
7972                 }
7973                 parm_table[parmnum].flags |= FLAG_CMDLINE;
7974
7975                 /* we have to also set FLAG_CMDLINE on aliases.  Aliases must
7976                  * be grouped in the table, so we don't have to search the
7977                  * whole table */
7978                 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
7979                         parm_table[i].flags |= FLAG_CMDLINE;
7980                 }
7981                 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
7982                         parm_table[i].flags |= FLAG_CMDLINE;
7983                 }
7984
7985                 if (store_values) {
7986                         store_lp_set_cmdline(pszParmName, pszParmValue);
7987                 }
7988                 return true;
7989         }
7990
7991         /* it might be parametric */
7992         if (strchr(pszParmName, ':') != NULL) {
7993                 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7994                 if (store_values) {
7995                         store_lp_set_cmdline(pszParmName, pszParmValue);
7996                 }
7997                 return true;
7998         }
7999
8000         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
8001         return true;
8002 }
8003
8004 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
8005 {
8006         return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
8007 }
8008
8009 /***************************************************************************
8010  Process a parameter.
8011 ***************************************************************************/
8012
8013 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
8014                          void *userdata)
8015 {
8016         if (!bInGlobalSection && bGlobalOnly)
8017                 return (True);
8018
8019         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
8020
8021         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
8022                                 pszParmName, pszParmValue));
8023 }
8024
8025 /*
8026   set a option from the commandline in 'a=b' format. Use to support --option
8027 */
8028 bool lp_set_option(const char *option)
8029 {
8030         char *p, *s;
8031         bool ret;
8032
8033         s = talloc_strdup(NULL, option);
8034         if (!s) {
8035                 return false;
8036         }
8037
8038         p = strchr(s, '=');
8039         if (!p) {
8040                 talloc_free(s);
8041                 return false;
8042         }
8043
8044         *p = 0;
8045
8046         /* skip white spaces after the = sign */
8047         do {
8048                 p++;
8049         } while (*p == ' ');
8050
8051         ret = lp_set_cmdline(s, p);
8052         talloc_free(s);
8053         return ret;
8054 }
8055
8056 /**************************************************************************
8057  Print a parameter of the specified type.
8058 ***************************************************************************/
8059
8060 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
8061 {
8062         int i;
8063         switch (p->type)
8064         {
8065                 case P_ENUM:
8066                         for (i = 0; p->enum_list[i].name; i++) {
8067                                 if (*(int *)ptr == p->enum_list[i].value) {
8068                                         fprintf(f, "%s",
8069                                                 p->enum_list[i].name);
8070                                         break;
8071                                 }
8072                         }
8073                         break;
8074
8075                 case P_BOOL:
8076                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
8077                         break;
8078
8079                 case P_BOOLREV:
8080                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
8081                         break;
8082
8083                 case P_INTEGER:
8084                         fprintf(f, "%d", *(int *)ptr);
8085                         break;
8086
8087                 case P_CHAR:
8088                         fprintf(f, "%c", *(char *)ptr);
8089                         break;
8090
8091                 case P_OCTAL: {
8092                         char *o = octal_string(*(int *)ptr);
8093                         fprintf(f, "%s", o);
8094                         TALLOC_FREE(o);
8095                         break;
8096                 }
8097
8098                 case P_LIST:
8099                         if ((char ***)ptr && *(char ***)ptr) {
8100                                 char **list = *(char ***)ptr;
8101                                 for (; *list; list++) {
8102                                         /* surround strings with whitespace in double quotes */
8103                                         if ( strchr_m( *list, ' ' ) )
8104                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
8105                                         else
8106                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
8107                                 }
8108                         }
8109                         break;
8110
8111                 case P_STRING:
8112                 case P_USTRING:
8113                         if (*(char **)ptr) {
8114                                 fprintf(f, "%s", *(char **)ptr);
8115                         }
8116                         break;
8117                 case P_SEP:
8118                         break;
8119         }
8120 }
8121
8122 /***************************************************************************
8123  Check if two parameters are equal.
8124 ***************************************************************************/
8125
8126 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8127 {
8128         switch (type) {
8129                 case P_BOOL:
8130                 case P_BOOLREV:
8131                         return (*((bool *)ptr1) == *((bool *)ptr2));
8132
8133                 case P_INTEGER:
8134                 case P_ENUM:
8135                 case P_OCTAL:
8136                         return (*((int *)ptr1) == *((int *)ptr2));
8137
8138                 case P_CHAR:
8139                         return (*((char *)ptr1) == *((char *)ptr2));
8140
8141                 case P_LIST:
8142                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8143
8144                 case P_STRING:
8145                 case P_USTRING:
8146                 {
8147                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8148                         if (p1 && !*p1)
8149                                 p1 = NULL;
8150                         if (p2 && !*p2)
8151                                 p2 = NULL;
8152                         return (p1 == p2 || strequal(p1, p2));
8153                 }
8154                 case P_SEP:
8155                         break;
8156         }
8157         return (False);
8158 }
8159
8160 /***************************************************************************
8161  Initialize any local varients in the sDefault table.
8162 ***************************************************************************/
8163
8164 void init_locals(void)
8165 {
8166         /* None as yet. */
8167 }
8168
8169 /***************************************************************************
8170  Process a new section (service). At this stage all sections are services.
8171  Later we'll have special sections that permit server parameters to be set.
8172  Returns True on success, False on failure. 
8173 ***************************************************************************/
8174
8175 static bool do_section(const char *pszSectionName, void *userdata)
8176 {
8177         bool bRetval;
8178         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8179                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8180         bRetval = False;
8181
8182         /* if we were in a global section then do the local inits */
8183         if (bInGlobalSection && !isglobal)
8184                 init_locals();
8185
8186         /* if we've just struck a global section, note the fact. */
8187         bInGlobalSection = isglobal;
8188
8189         /* check for multiple global sections */
8190         if (bInGlobalSection) {
8191                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8192                 return (True);
8193         }
8194
8195         if (!bInGlobalSection && bGlobalOnly)
8196                 return (True);
8197
8198         /* if we have a current service, tidy it up before moving on */
8199         bRetval = True;
8200
8201         if (iServiceIndex >= 0)
8202                 bRetval = service_ok(iServiceIndex);
8203
8204         /* if all is still well, move to the next record in the services array */
8205         if (bRetval) {
8206                 /* We put this here to avoid an odd message order if messages are */
8207                 /* issued by the post-processing of a previous section. */
8208                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8209
8210                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8211                     < 0) {
8212                         DEBUG(0, ("Failed to add a new service\n"));
8213                         return (False);
8214                 }
8215                 /* Clean all parametric options for service */
8216                 /* They will be added during parsing again */
8217                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
8218         }
8219
8220         return (bRetval);
8221 }
8222
8223
8224 /***************************************************************************
8225  Determine if a partcular base parameter is currentl set to the default value.
8226 ***************************************************************************/
8227
8228 static bool is_default(int i)
8229 {
8230         if (!defaults_saved)
8231                 return False;
8232         switch (parm_table[i].type) {
8233                 case P_LIST:
8234                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
8235                                                 *(const char ***)parm_table[i].ptr);
8236                 case P_STRING:
8237                 case P_USTRING:
8238                         return strequal(parm_table[i].def.svalue,
8239                                         *(char **)parm_table[i].ptr);
8240                 case P_BOOL:
8241                 case P_BOOLREV:
8242                         return parm_table[i].def.bvalue ==
8243                                 *(bool *)parm_table[i].ptr;
8244                 case P_CHAR:
8245                         return parm_table[i].def.cvalue ==
8246                                 *(char *)parm_table[i].ptr;
8247                 case P_INTEGER:
8248                 case P_OCTAL:
8249                 case P_ENUM:
8250                         return parm_table[i].def.ivalue ==
8251                                 *(int *)parm_table[i].ptr;
8252                 case P_SEP:
8253                         break;
8254         }
8255         return False;
8256 }
8257
8258 /***************************************************************************
8259 Display the contents of the global structure.
8260 ***************************************************************************/
8261
8262 static void dump_globals(FILE *f)
8263 {
8264         int i;
8265         struct param_opt_struct *data;
8266
8267         fprintf(f, "[global]\n");
8268
8269         for (i = 0; parm_table[i].label; i++)
8270                 if (parm_table[i].p_class == P_GLOBAL &&
8271                     !(parm_table[i].flags & FLAG_META) &&
8272                     parm_table[i].ptr &&
8273                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8274                         if (defaults_saved && is_default(i))
8275                                 continue;
8276                         fprintf(f, "\t%s = ", parm_table[i].label);
8277                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
8278                         fprintf(f, "\n");
8279         }
8280         if (Globals.param_opt != NULL) {
8281                 data = Globals.param_opt;
8282                 while(data) {
8283                         fprintf(f, "\t%s = %s\n", data->key, data->value);
8284                         data = data->next;
8285                 }
8286         }
8287
8288 }
8289
8290 /***************************************************************************
8291  Return True if a local parameter is currently set to the global default.
8292 ***************************************************************************/
8293
8294 bool lp_is_default(int snum, struct parm_struct *parm)
8295 {
8296         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8297
8298         return equal_parameter(parm->type,
8299                                ((char *)ServicePtrs[snum]) + pdiff,
8300                                ((char *)&sDefault) + pdiff);
8301 }
8302
8303 /***************************************************************************
8304  Display the contents of a single services record.
8305 ***************************************************************************/
8306
8307 static void dump_a_service(struct service *pService, FILE * f)
8308 {
8309         int i;
8310         struct param_opt_struct *data;
8311
8312         if (pService != &sDefault)
8313                 fprintf(f, "[%s]\n", pService->szService);
8314
8315         for (i = 0; parm_table[i].label; i++) {
8316
8317                 if (parm_table[i].p_class == P_LOCAL &&
8318                     !(parm_table[i].flags & FLAG_META) &&
8319                     parm_table[i].ptr &&
8320                     (*parm_table[i].label != '-') &&
8321                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
8322                 {
8323                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8324
8325                         if (pService == &sDefault) {
8326                                 if (defaults_saved && is_default(i))
8327                                         continue;
8328                         } else {
8329                                 if (equal_parameter(parm_table[i].type,
8330                                                     ((char *)pService) +
8331                                                     pdiff,
8332                                                     ((char *)&sDefault) +
8333                                                     pdiff))
8334                                         continue;
8335                         }
8336
8337                         fprintf(f, "\t%s = ", parm_table[i].label);
8338                         print_parameter(&parm_table[i],
8339                                         ((char *)pService) + pdiff, f);
8340                         fprintf(f, "\n");
8341                 }
8342         }
8343
8344                 if (pService->param_opt != NULL) {
8345                         data = pService->param_opt;
8346                         while(data) {
8347                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
8348                                 data = data->next;
8349                         }
8350                 }
8351 }
8352
8353 /***************************************************************************
8354  Display the contents of a parameter of a single services record.
8355 ***************************************************************************/
8356
8357 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8358 {
8359         int i;
8360         bool result = False;
8361         parm_class p_class;
8362         unsigned flag = 0;
8363         fstring local_parm_name;
8364         char *parm_opt;
8365         const char *parm_opt_value;
8366
8367         /* check for parametrical option */
8368         fstrcpy( local_parm_name, parm_name);
8369         parm_opt = strchr( local_parm_name, ':');
8370
8371         if (parm_opt) {
8372                 *parm_opt = '\0';
8373                 parm_opt++;
8374                 if (strlen(parm_opt)) {
8375                         parm_opt_value = lp_parm_const_string( snum,
8376                                 local_parm_name, parm_opt, NULL);
8377                         if (parm_opt_value) {
8378                                 printf( "%s\n", parm_opt_value);
8379                                 result = True;
8380                         }
8381                 }
8382                 return result;
8383         }
8384
8385         /* check for a key and print the value */
8386         if (isGlobal) {
8387                 p_class = P_GLOBAL;
8388                 flag = FLAG_GLOBAL;
8389         } else
8390                 p_class = P_LOCAL;
8391
8392         for (i = 0; parm_table[i].label; i++) {
8393                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8394                     !(parm_table[i].flags & FLAG_META) &&
8395                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8396                     parm_table[i].ptr &&
8397                     (*parm_table[i].label != '-') &&
8398                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
8399                 {
8400                         void *ptr;
8401
8402                         if (isGlobal) {
8403                                 ptr = parm_table[i].ptr;
8404                         } else {
8405                                 struct service *pService = ServicePtrs[snum];
8406                                 ptr = ((char *)pService) +
8407                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
8408                         }
8409
8410                         print_parameter(&parm_table[i],
8411                                         ptr, f);
8412                         fprintf(f, "\n");
8413                         result = True;
8414                         break;
8415                 }
8416         }
8417
8418         return result;
8419 }
8420
8421 /***************************************************************************
8422  Return info about the requested parameter (given as a string).
8423  Return NULL when the string is not a valid parameter name.
8424 ***************************************************************************/
8425
8426 struct parm_struct *lp_get_parameter(const char *param_name)
8427 {
8428         int num = map_parameter(param_name);
8429
8430         if (num < 0) {
8431                 return NULL;
8432         }
8433
8434         return &parm_table[num];
8435 }
8436
8437 /***************************************************************************
8438  Return info about the next parameter in a service.
8439  snum==GLOBAL_SECTION_SNUM gives the globals.
8440  Return NULL when out of parameters.
8441 ***************************************************************************/
8442
8443 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8444 {
8445         if (snum < 0) {
8446                 /* do the globals */
8447                 for (; parm_table[*i].label; (*i)++) {
8448                         if (parm_table[*i].p_class == P_SEPARATOR)
8449                                 return &parm_table[(*i)++];
8450
8451                         if (!parm_table[*i].ptr
8452                             || (*parm_table[*i].label == '-'))
8453                                 continue;
8454
8455                         if ((*i) > 0
8456                             && (parm_table[*i].ptr ==
8457                                 parm_table[(*i) - 1].ptr))
8458                                 continue;
8459
8460                         if (is_default(*i) && !allparameters)
8461                                 continue;
8462
8463                         return &parm_table[(*i)++];
8464                 }
8465         } else {
8466                 struct service *pService = ServicePtrs[snum];
8467
8468                 for (; parm_table[*i].label; (*i)++) {
8469                         if (parm_table[*i].p_class == P_SEPARATOR)
8470                                 return &parm_table[(*i)++];
8471
8472                         if (parm_table[*i].p_class == P_LOCAL &&
8473                             parm_table[*i].ptr &&
8474                             (*parm_table[*i].label != '-') &&
8475                             ((*i) == 0 ||
8476                              (parm_table[*i].ptr !=
8477                               parm_table[(*i) - 1].ptr)))
8478                         {
8479                                 int pdiff =
8480                                         PTR_DIFF(parm_table[*i].ptr,
8481                                                  &sDefault);
8482
8483                                 if (allparameters ||
8484                                     !equal_parameter(parm_table[*i].type,
8485                                                      ((char *)pService) +
8486                                                      pdiff,
8487                                                      ((char *)&sDefault) +
8488                                                      pdiff))
8489                                 {
8490                                         return &parm_table[(*i)++];
8491                                 }
8492                         }
8493                 }
8494         }
8495
8496         return NULL;
8497 }
8498
8499
8500 #if 0
8501 /***************************************************************************
8502  Display the contents of a single copy structure.
8503 ***************************************************************************/
8504 static void dump_copy_map(bool *pcopymap)
8505 {
8506         int i;
8507         if (!pcopymap)
8508                 return;
8509
8510         printf("\n\tNon-Copied parameters:\n");
8511
8512         for (i = 0; parm_table[i].label; i++)
8513                 if (parm_table[i].p_class == P_LOCAL &&
8514                     parm_table[i].ptr && !pcopymap[i] &&
8515                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8516                 {
8517                         printf("\t\t%s\n", parm_table[i].label);
8518                 }
8519 }
8520 #endif
8521
8522 /***************************************************************************
8523  Return TRUE if the passed service number is within range.
8524 ***************************************************************************/
8525
8526 bool lp_snum_ok(int iService)
8527 {
8528         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8529 }
8530
8531 /***************************************************************************
8532  Auto-load some home services.
8533 ***************************************************************************/
8534
8535 static void lp_add_auto_services(char *str)
8536 {
8537         char *s;
8538         char *p;
8539         int homes;
8540         char *saveptr;
8541
8542         if (!str)
8543                 return;
8544
8545         s = SMB_STRDUP(str);
8546         if (!s)
8547                 return;
8548
8549         homes = lp_servicenumber(HOMES_NAME);
8550
8551         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8552              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8553                 char *home;
8554
8555                 if (lp_servicenumber(p) >= 0)
8556                         continue;
8557
8558                 home = get_user_home_dir(talloc_tos(), p);
8559
8560                 if (home && home[0] && homes >= 0)
8561                         lp_add_home(p, homes, p, home);
8562
8563                 TALLOC_FREE(home);
8564         }
8565         SAFE_FREE(s);
8566 }
8567
8568 /***************************************************************************
8569  Auto-load one printer.
8570 ***************************************************************************/
8571
8572 void lp_add_one_printer(const char *name, const char *comment,
8573                         const char *location, void *pdata)
8574 {
8575         int printers = lp_servicenumber(PRINTERS_NAME);
8576         int i;
8577
8578         if (lp_servicenumber(name) < 0) {
8579                 lp_add_printer(name, printers);
8580                 if ((i = lp_servicenumber(name)) >= 0) {
8581                         string_set(&ServicePtrs[i]->comment, comment);
8582                         ServicePtrs[i]->autoloaded = True;
8583                 }
8584         }
8585 }
8586
8587 /***************************************************************************
8588  Have we loaded a services file yet?
8589 ***************************************************************************/
8590
8591 bool lp_loaded(void)
8592 {
8593         return (bLoaded);
8594 }
8595
8596 /***************************************************************************
8597  Unload unused services.
8598 ***************************************************************************/
8599
8600 void lp_killunused(struct smbd_server_connection *sconn,
8601                    bool (*snumused) (struct smbd_server_connection *, int))
8602 {
8603         int i;
8604         for (i = 0; i < iNumServices; i++) {
8605                 if (!VALID(i))
8606                         continue;
8607
8608                 /* don't kill autoloaded or usershare services */
8609                 if ( ServicePtrs[i]->autoloaded ||
8610                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8611                         continue;
8612                 }
8613
8614                 if (!snumused || !snumused(sconn, i)) {
8615                         free_service_byindex(i);
8616                 }
8617         }
8618 }
8619
8620 /**
8621  * Kill all except autoloaded and usershare services - convenience wrapper
8622  */
8623 void lp_kill_all_services(void)
8624 {
8625         lp_killunused(NULL, NULL);
8626 }
8627
8628 /***************************************************************************
8629  Unload a service.
8630 ***************************************************************************/
8631
8632 void lp_killservice(int iServiceIn)
8633 {
8634         if (VALID(iServiceIn)) {
8635                 free_service_byindex(iServiceIn);
8636         }
8637 }
8638
8639 /***************************************************************************
8640  Save the curent values of all global and sDefault parameters into the 
8641  defaults union. This allows swat and testparm to show only the
8642  changed (ie. non-default) parameters.
8643 ***************************************************************************/
8644
8645 static void lp_save_defaults(void)
8646 {
8647         int i;
8648         for (i = 0; parm_table[i].label; i++) {
8649                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8650                         continue;
8651                 switch (parm_table[i].type) {
8652                         case P_LIST:
8653                                 parm_table[i].def.lvalue = str_list_copy(
8654                                         NULL, *(const char ***)parm_table[i].ptr);
8655                                 break;
8656                         case P_STRING:
8657                         case P_USTRING:
8658                                 if (parm_table[i].ptr) {
8659                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8660                                 } else {
8661                                         parm_table[i].def.svalue = NULL;
8662                                 }
8663                                 break;
8664                         case P_BOOL:
8665                         case P_BOOLREV:
8666                                 parm_table[i].def.bvalue =
8667                                         *(bool *)parm_table[i].ptr;
8668                                 break;
8669                         case P_CHAR:
8670                                 parm_table[i].def.cvalue =
8671                                         *(char *)parm_table[i].ptr;
8672                                 break;
8673                         case P_INTEGER:
8674                         case P_OCTAL:
8675                         case P_ENUM:
8676                                 parm_table[i].def.ivalue =
8677                                         *(int *)parm_table[i].ptr;
8678                                 break;
8679                         case P_SEP:
8680                                 break;
8681                 }
8682         }
8683         defaults_saved = True;
8684 }
8685
8686 /***********************************************************
8687  If we should send plaintext/LANMAN passwords in the clinet
8688 ************************************************************/
8689
8690 static void set_allowed_client_auth(void)
8691 {
8692         if (Globals.bClientNTLMv2Auth) {
8693                 Globals.bClientLanManAuth = False;
8694         }
8695         if (!Globals.bClientLanManAuth) {
8696                 Globals.bClientPlaintextAuth = False;
8697         }
8698 }
8699
8700 /***************************************************************************
8701  JRA.
8702  The following code allows smbd to read a user defined share file.
8703  Yes, this is my intent. Yes, I'm comfortable with that...
8704
8705  THE FOLLOWING IS SECURITY CRITICAL CODE.
8706
8707  It washes your clothes, it cleans your house, it guards you while you sleep...
8708  Do not f%^k with it....
8709 ***************************************************************************/
8710
8711 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8712
8713 /***************************************************************************
8714  Check allowed stat state of a usershare file.
8715  Ensure we print out who is dicking with us so the admin can
8716  get their sorry ass fired.
8717 ***************************************************************************/
8718
8719 static bool check_usershare_stat(const char *fname,
8720                                  const SMB_STRUCT_STAT *psbuf)
8721 {
8722         if (!S_ISREG(psbuf->st_ex_mode)) {
8723                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8724                         "not a regular file\n",
8725                         fname, (unsigned int)psbuf->st_ex_uid ));
8726                 return False;
8727         }
8728
8729         /* Ensure this doesn't have the other write bit set. */
8730         if (psbuf->st_ex_mode & S_IWOTH) {
8731                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8732                         "public write. Refusing to allow as a usershare file.\n",
8733                         fname, (unsigned int)psbuf->st_ex_uid ));
8734                 return False;
8735         }
8736
8737         /* Should be 10k or less. */
8738         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8739                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8740                         "too large (%u) to be a user share file.\n",
8741                         fname, (unsigned int)psbuf->st_ex_uid,
8742                         (unsigned int)psbuf->st_ex_size ));
8743                 return False;
8744         }
8745
8746         return True;
8747 }
8748
8749 /***************************************************************************
8750  Parse the contents of a usershare file.
8751 ***************************************************************************/
8752
8753 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8754                         SMB_STRUCT_STAT *psbuf,
8755                         const char *servicename,
8756                         int snum,
8757                         char **lines,
8758                         int numlines,
8759                         char **pp_sharepath,
8760                         char **pp_comment,
8761                         char **pp_cp_servicename,
8762                         struct security_descriptor **ppsd,
8763                         bool *pallow_guest)
8764 {
8765         const char **prefixallowlist = lp_usershare_prefix_allow_list();
8766         const char **prefixdenylist = lp_usershare_prefix_deny_list();
8767         int us_vers;
8768         SMB_STRUCT_DIR *dp;
8769         SMB_STRUCT_STAT sbuf;
8770         char *sharepath = NULL;
8771         char *comment = NULL;
8772
8773         *pp_sharepath = NULL;
8774         *pp_comment = NULL;
8775
8776         *pallow_guest = False;
8777
8778         if (numlines < 4) {
8779                 return USERSHARE_MALFORMED_FILE;
8780         }
8781
8782         if (strcmp(lines[0], "#VERSION 1") == 0) {
8783                 us_vers = 1;
8784         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8785                 us_vers = 2;
8786                 if (numlines < 5) {
8787                         return USERSHARE_MALFORMED_FILE;
8788                 }
8789         } else {
8790                 return USERSHARE_BAD_VERSION;
8791         }
8792
8793         if (strncmp(lines[1], "path=", 5) != 0) {
8794                 return USERSHARE_MALFORMED_PATH;
8795         }
8796
8797         sharepath = talloc_strdup(ctx, &lines[1][5]);
8798         if (!sharepath) {
8799                 return USERSHARE_POSIX_ERR;
8800         }
8801         trim_string(sharepath, " ", " ");
8802
8803         if (strncmp(lines[2], "comment=", 8) != 0) {
8804                 return USERSHARE_MALFORMED_COMMENT_DEF;
8805         }
8806
8807         comment = talloc_strdup(ctx, &lines[2][8]);
8808         if (!comment) {
8809                 return USERSHARE_POSIX_ERR;
8810         }
8811         trim_string(comment, " ", " ");
8812         trim_char(comment, '"', '"');
8813
8814         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8815                 return USERSHARE_MALFORMED_ACL_DEF;
8816         }
8817
8818         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8819                 return USERSHARE_ACL_ERR;
8820         }
8821
8822         if (us_vers == 2) {
8823                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8824                         return USERSHARE_MALFORMED_ACL_DEF;
8825                 }
8826                 if (lines[4][9] == 'y') {
8827                         *pallow_guest = True;
8828                 }
8829
8830                 /* Backwards compatible extension to file version #2. */
8831                 if (numlines > 5) {
8832                         if (strncmp(lines[5], "sharename=", 10) != 0) {
8833                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
8834                         }
8835                         if (!strequal(&lines[5][10], servicename)) {
8836                                 return USERSHARE_BAD_SHARENAME;
8837                         }
8838                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8839                         if (!*pp_cp_servicename) {
8840                                 return USERSHARE_POSIX_ERR;
8841                         }
8842                 }
8843         }
8844
8845         if (*pp_cp_servicename == NULL) {
8846                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8847                 if (!*pp_cp_servicename) {
8848                         return USERSHARE_POSIX_ERR;
8849                 }
8850         }
8851
8852         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8853                 /* Path didn't change, no checks needed. */
8854                 *pp_sharepath = sharepath;
8855                 *pp_comment = comment;
8856                 return USERSHARE_OK;
8857         }
8858
8859         /* The path *must* be absolute. */
8860         if (sharepath[0] != '/') {
8861                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8862                         servicename, sharepath));
8863                 return USERSHARE_PATH_NOT_ABSOLUTE;
8864         }
8865
8866         /* If there is a usershare prefix deny list ensure one of these paths
8867            doesn't match the start of the user given path. */
8868         if (prefixdenylist) {
8869                 int i;
8870                 for ( i=0; prefixdenylist[i]; i++ ) {
8871                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8872                                 servicename, i, prefixdenylist[i], sharepath ));
8873                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8874                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8875                                         "usershare prefix deny list entries.\n",
8876                                         servicename, sharepath));
8877                                 return USERSHARE_PATH_IS_DENIED;
8878                         }
8879                 }
8880         }
8881
8882         /* If there is a usershare prefix allow list ensure one of these paths
8883            does match the start of the user given path. */
8884
8885         if (prefixallowlist) {
8886                 int i;
8887                 for ( i=0; prefixallowlist[i]; i++ ) {
8888                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8889                                 servicename, i, prefixallowlist[i], sharepath ));
8890                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8891                                 break;
8892                         }
8893                 }
8894                 if (prefixallowlist[i] == NULL) {
8895                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8896                                 "usershare prefix allow list entries.\n",
8897                                 servicename, sharepath));
8898                         return USERSHARE_PATH_NOT_ALLOWED;
8899                 }
8900         }
8901
8902         /* Ensure this is pointing to a directory. */
8903         dp = sys_opendir(sharepath);
8904
8905         if (!dp) {
8906                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8907                         servicename, sharepath));
8908                 return USERSHARE_PATH_NOT_DIRECTORY;
8909         }
8910
8911         /* Ensure the owner of the usershare file has permission to share
8912            this directory. */
8913
8914         if (sys_stat(sharepath, &sbuf, false) == -1) {
8915                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8916                         servicename, sharepath, strerror(errno) ));
8917                 sys_closedir(dp);
8918                 return USERSHARE_POSIX_ERR;
8919         }
8920
8921         sys_closedir(dp);
8922
8923         if (!S_ISDIR(sbuf.st_ex_mode)) {
8924                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8925                         servicename, sharepath ));
8926                 return USERSHARE_PATH_NOT_DIRECTORY;
8927         }
8928
8929         /* Check if sharing is restricted to owner-only. */
8930         /* psbuf is the stat of the usershare definition file,
8931            sbuf is the stat of the target directory to be shared. */
8932
8933         if (lp_usershare_owner_only()) {
8934                 /* root can share anything. */
8935                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8936                         return USERSHARE_PATH_NOT_ALLOWED;
8937                 }
8938         }
8939
8940         *pp_sharepath = sharepath;
8941         *pp_comment = comment;
8942         return USERSHARE_OK;
8943 }
8944
8945 /***************************************************************************
8946  Deal with a usershare file.
8947  Returns:
8948         >= 0 - snum
8949         -1 - Bad name, invalid contents.
8950            - service name already existed and not a usershare, problem
8951             with permissions to share directory etc.
8952 ***************************************************************************/
8953
8954 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8955 {
8956         SMB_STRUCT_STAT sbuf;
8957         SMB_STRUCT_STAT lsbuf;
8958         char *fname = NULL;
8959         char *sharepath = NULL;
8960         char *comment = NULL;
8961         char *cp_service_name = NULL;
8962         char **lines = NULL;
8963         int numlines = 0;
8964         int fd = -1;
8965         int iService = -1;
8966         TALLOC_CTX *ctx = talloc_stackframe();
8967         struct security_descriptor *psd = NULL;
8968         bool guest_ok = False;
8969         char *canon_name = NULL;
8970         bool added_service = false;
8971         int ret = -1;
8972
8973         /* Ensure share name doesn't contain invalid characters. */
8974         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8975                 DEBUG(0,("process_usershare_file: share name %s contains "
8976                         "invalid characters (any of %s)\n",
8977                         file_name, INVALID_SHARENAME_CHARS ));
8978                 goto out;
8979         }
8980
8981         canon_name = canonicalize_servicename(ctx, file_name);
8982         if (!canon_name) {
8983                 goto out;
8984         }
8985
8986         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8987         if (!fname) {
8988                 goto out;
8989         }
8990
8991         /* Minimize the race condition by doing an lstat before we
8992            open and fstat. Ensure this isn't a symlink link. */
8993
8994         if (sys_lstat(fname, &lsbuf, false) != 0) {
8995                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8996                         fname, strerror(errno) ));
8997                 goto out;
8998         }
8999
9000         /* This must be a regular file, not a symlink, directory or
9001            other strange filetype. */
9002         if (!check_usershare_stat(fname, &lsbuf)) {
9003                 goto out;
9004         }
9005
9006         {
9007                 TDB_DATA data = dbwrap_fetch_bystring(
9008                         ServiceHash, canon_name, canon_name);
9009
9010                 iService = -1;
9011
9012                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
9013                         iService = *(int *)data.dptr;
9014                 }
9015         }
9016
9017         if (iService != -1 &&
9018             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9019                              &lsbuf.st_ex_mtime) == 0) {
9020                 /* Nothing changed - Mark valid and return. */
9021                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
9022                         canon_name ));
9023                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9024                 ret = iService;
9025                 goto out;
9026         }
9027
9028         /* Try and open the file read only - no symlinks allowed. */
9029 #ifdef O_NOFOLLOW
9030         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
9031 #else
9032         fd = sys_open(fname, O_RDONLY, 0);
9033 #endif
9034
9035         if (fd == -1) {
9036                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
9037                         fname, strerror(errno) ));
9038                 goto out;
9039         }
9040
9041         /* Now fstat to be *SURE* it's a regular file. */
9042         if (sys_fstat(fd, &sbuf, false) != 0) {
9043                 close(fd);
9044                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
9045                         fname, strerror(errno) ));
9046                 goto out;
9047         }
9048
9049         /* Is it the same dev/inode as was lstated ? */
9050         if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
9051                 close(fd);
9052                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
9053                         "Symlink spoofing going on ?\n", fname ));
9054                 goto out;
9055         }
9056
9057         /* This must be a regular file, not a symlink, directory or
9058            other strange filetype. */
9059         if (!check_usershare_stat(fname, &sbuf)) {
9060                 goto out;
9061         }
9062
9063         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
9064
9065         close(fd);
9066         if (lines == NULL) {
9067                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
9068                         fname, (unsigned int)sbuf.st_ex_uid ));
9069                 goto out;
9070         }
9071
9072         if (parse_usershare_file(ctx, &sbuf, file_name,
9073                         iService, lines, numlines, &sharepath,
9074                         &comment, &cp_service_name,
9075                         &psd, &guest_ok) != USERSHARE_OK) {
9076                 goto out;
9077         }
9078
9079         /* Everything ok - add the service possibly using a template. */
9080         if (iService < 0) {
9081                 const struct service *sp = &sDefault;
9082                 if (snum_template != -1) {
9083                         sp = ServicePtrs[snum_template];
9084                 }
9085
9086                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
9087                         DEBUG(0, ("process_usershare_file: Failed to add "
9088                                 "new service %s\n", cp_service_name));
9089                         goto out;
9090                 }
9091
9092                 added_service = true;
9093
9094                 /* Read only is controlled by usershare ACL below. */
9095                 ServicePtrs[iService]->bRead_only = False;
9096         }
9097
9098         /* Write the ACL of the new/modified share. */
9099         if (!set_share_security(canon_name, psd)) {
9100                  DEBUG(0, ("process_usershare_file: Failed to set share "
9101                         "security for user share %s\n",
9102                         canon_name ));
9103                 goto out;
9104         }
9105
9106         /* If from a template it may be marked invalid. */
9107         ServicePtrs[iService]->valid = True;
9108
9109         /* Set the service as a valid usershare. */
9110         ServicePtrs[iService]->usershare = USERSHARE_VALID;
9111
9112         /* Set guest access. */
9113         if (lp_usershare_allow_guests()) {
9114                 ServicePtrs[iService]->bGuest_ok = guest_ok;
9115         }
9116
9117         /* And note when it was loaded. */
9118         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
9119         string_set(&ServicePtrs[iService]->szPath, sharepath);
9120         string_set(&ServicePtrs[iService]->comment, comment);
9121
9122         ret = iService;
9123
9124   out:
9125
9126         if (ret == -1 && iService != -1 && added_service) {
9127                 lp_remove_service(iService);
9128         }
9129
9130         TALLOC_FREE(lines);
9131         TALLOC_FREE(ctx);
9132         return ret;
9133 }
9134
9135 /***************************************************************************
9136  Checks if a usershare entry has been modified since last load.
9137 ***************************************************************************/
9138
9139 static bool usershare_exists(int iService, struct timespec *last_mod)
9140 {
9141         SMB_STRUCT_STAT lsbuf;
9142         const char *usersharepath = Globals.szUsersharePath;
9143         char *fname;
9144
9145         if (asprintf(&fname, "%s/%s",
9146                                 usersharepath,
9147                                 ServicePtrs[iService]->szService) < 0) {
9148                 return false;
9149         }
9150
9151         if (sys_lstat(fname, &lsbuf, false) != 0) {
9152                 SAFE_FREE(fname);
9153                 return false;
9154         }
9155
9156         if (!S_ISREG(lsbuf.st_ex_mode)) {
9157                 SAFE_FREE(fname);
9158                 return false;
9159         }
9160
9161         SAFE_FREE(fname);
9162         *last_mod = lsbuf.st_ex_mtime;
9163         return true;
9164 }
9165
9166 /***************************************************************************
9167  Load a usershare service by name. Returns a valid servicenumber or -1.
9168 ***************************************************************************/
9169
9170 int load_usershare_service(const char *servicename)
9171 {
9172         SMB_STRUCT_STAT sbuf;
9173         const char *usersharepath = Globals.szUsersharePath;
9174         int max_user_shares = Globals.iUsershareMaxShares;
9175         int snum_template = -1;
9176
9177         if (*usersharepath == 0 ||  max_user_shares == 0) {
9178                 return -1;
9179         }
9180
9181         if (sys_stat(usersharepath, &sbuf, false) != 0) {
9182                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9183                         usersharepath, strerror(errno) ));
9184                 return -1;
9185         }
9186
9187         if (!S_ISDIR(sbuf.st_ex_mode)) {
9188                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9189                         usersharepath ));
9190                 return -1;
9191         }
9192
9193         /*
9194          * This directory must be owned by root, and have the 't' bit set.
9195          * It also must not be writable by "other".
9196          */
9197
9198 #ifdef S_ISVTX
9199         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9200 #else
9201         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9202 #endif
9203                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9204                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
9205                         usersharepath ));
9206                 return -1;
9207         }
9208
9209         /* Ensure the template share exists if it's set. */
9210         if (Globals.szUsershareTemplateShare[0]) {
9211                 /* We can't use lp_servicenumber here as we are recommending that
9212                    template shares have -valid=False set. */
9213                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9214                         if (ServicePtrs[snum_template]->szService &&
9215                                         strequal(ServicePtrs[snum_template]->szService,
9216                                                 Globals.szUsershareTemplateShare)) {
9217                                 break;
9218                         }
9219                 }
9220
9221                 if (snum_template == -1) {
9222                         DEBUG(0,("load_usershare_service: usershare template share %s "
9223                                 "does not exist.\n",
9224                                 Globals.szUsershareTemplateShare ));
9225                         return -1;
9226                 }
9227         }
9228
9229         return process_usershare_file(usersharepath, servicename, snum_template);
9230 }
9231
9232 /***************************************************************************
9233  Load all user defined shares from the user share directory.
9234  We only do this if we're enumerating the share list.
9235  This is the function that can delete usershares that have
9236  been removed.
9237 ***************************************************************************/
9238
9239 int load_usershare_shares(struct smbd_server_connection *sconn)
9240 {
9241         SMB_STRUCT_DIR *dp;
9242         SMB_STRUCT_STAT sbuf;
9243         SMB_STRUCT_DIRENT *de;
9244         int num_usershares = 0;
9245         int max_user_shares = Globals.iUsershareMaxShares;
9246         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9247         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9248         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9249         int iService;
9250         int snum_template = -1;
9251         const char *usersharepath = Globals.szUsersharePath;
9252         int ret = lp_numservices();
9253
9254         if (max_user_shares == 0 || *usersharepath == '\0') {
9255                 return lp_numservices();
9256         }
9257
9258         if (sys_stat(usersharepath, &sbuf, false) != 0) {
9259                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9260                         usersharepath, strerror(errno) ));
9261                 return ret;
9262         }
9263
9264         /*
9265          * This directory must be owned by root, and have the 't' bit set.
9266          * It also must not be writable by "other".
9267          */
9268
9269 #ifdef S_ISVTX
9270         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9271 #else
9272         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9273 #endif
9274                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9275                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
9276                         usersharepath ));
9277                 return ret;
9278         }
9279
9280         /* Ensure the template share exists if it's set. */
9281         if (Globals.szUsershareTemplateShare[0]) {
9282                 /* We can't use lp_servicenumber here as we are recommending that
9283                    template shares have -valid=False set. */
9284                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9285                         if (ServicePtrs[snum_template]->szService &&
9286                                         strequal(ServicePtrs[snum_template]->szService,
9287                                                 Globals.szUsershareTemplateShare)) {
9288                                 break;
9289                         }
9290                 }
9291
9292                 if (snum_template == -1) {
9293                         DEBUG(0,("load_usershare_shares: usershare template share %s "
9294                                 "does not exist.\n",
9295                                 Globals.szUsershareTemplateShare ));
9296                         return ret;
9297                 }
9298         }
9299
9300         /* Mark all existing usershares as pending delete. */
9301         for (iService = iNumServices - 1; iService >= 0; iService--) {
9302                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9303                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9304                 }
9305         }
9306
9307         dp = sys_opendir(usersharepath);
9308         if (!dp) {
9309                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9310                         usersharepath, strerror(errno) ));
9311                 return ret;
9312         }
9313
9314         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9315                         (de = sys_readdir(dp));
9316                         num_dir_entries++ ) {
9317                 int r;
9318                 const char *n = de->d_name;
9319
9320                 /* Ignore . and .. */
9321                 if (*n == '.') {
9322                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9323                                 continue;
9324                         }
9325                 }
9326
9327                 if (n[0] == ':') {
9328                         /* Temporary file used when creating a share. */
9329                         num_tmp_dir_entries++;
9330                 }
9331
9332                 /* Allow 20% tmp entries. */
9333                 if (num_tmp_dir_entries > allowed_tmp_entries) {
9334                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9335                                 "in directory %s\n",
9336                                 num_tmp_dir_entries, usersharepath));
9337                         break;
9338                 }
9339
9340                 r = process_usershare_file(usersharepath, n, snum_template);
9341                 if (r == 0) {
9342                         /* Update the services count. */
9343                         num_usershares++;
9344                         if (num_usershares >= max_user_shares) {
9345                                 DEBUG(0,("load_usershare_shares: max user shares reached "
9346                                         "on file %s in directory %s\n",
9347                                         n, usersharepath ));
9348                                 break;
9349                         }
9350                 } else if (r == -1) {
9351                         num_bad_dir_entries++;
9352                 }
9353
9354                 /* Allow 20% bad entries. */
9355                 if (num_bad_dir_entries > allowed_bad_entries) {
9356                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9357                                 "in directory %s\n",
9358                                 num_bad_dir_entries, usersharepath));
9359                         break;
9360                 }
9361
9362                 /* Allow 20% bad entries. */
9363                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9364                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9365                         "in directory %s\n",
9366                         num_dir_entries, usersharepath));
9367                         break;
9368                 }
9369         }
9370
9371         sys_closedir(dp);
9372
9373         /* Sweep through and delete any non-refreshed usershares that are
9374            not currently in use. */
9375         for (iService = iNumServices - 1; iService >= 0; iService--) {
9376                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9377                         if (conn_snum_used(sconn, iService)) {
9378                                 continue;
9379                         }
9380                         /* Remove from the share ACL db. */
9381                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9382                                 lp_servicename(iService) ));
9383                         delete_share_security(lp_servicename(iService));
9384                         free_service_byindex(iService);
9385                 }
9386         }
9387
9388         return lp_numservices();
9389 }
9390
9391 /********************************************************
9392  Destroy global resources allocated in this file
9393 ********************************************************/
9394
9395 void gfree_loadparm(void)
9396 {
9397         int i;
9398
9399         free_file_list();
9400
9401         /* Free resources allocated to services */
9402
9403         for ( i = 0; i < iNumServices; i++ ) {
9404                 if ( VALID(i) ) {
9405                         free_service_byindex(i);
9406                 }
9407         }
9408
9409         SAFE_FREE( ServicePtrs );
9410         iNumServices = 0;
9411
9412         /* Now release all resources allocated to global
9413            parameters and the default service */
9414
9415         free_global_parameters();
9416 }
9417
9418
9419 /***************************************************************************
9420  Allow client apps to specify that they are a client
9421 ***************************************************************************/
9422 void lp_set_in_client(bool b)
9423 {
9424     in_client = b;
9425 }
9426
9427
9428 /***************************************************************************
9429  Determine if we're running in a client app
9430 ***************************************************************************/
9431 bool lp_is_in_client(void)
9432 {
9433     return in_client;
9434 }
9435
9436 /***************************************************************************
9437  Load the services array from the services file. Return True on success, 
9438  False on failure.
9439 ***************************************************************************/
9440
9441 static bool lp_load_ex(const char *pszFname,
9442                        bool global_only,
9443                        bool save_defaults,
9444                        bool add_ipc,
9445                        bool initialize_globals,
9446                        bool allow_include_registry,
9447                        bool allow_registry_shares)
9448 {
9449         char *n2 = NULL;
9450         bool bRetval;
9451
9452         bRetval = False;
9453
9454         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9455
9456         bInGlobalSection = True;
9457         bGlobalOnly = global_only;
9458         bAllowIncludeRegistry = allow_include_registry;
9459
9460         init_globals(initialize_globals);
9461
9462         free_file_list();
9463
9464         if (save_defaults) {
9465                 init_locals();
9466                 lp_save_defaults();
9467         }
9468
9469         free_param_opts(&Globals.param_opt);
9470
9471         lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
9472
9473         /* We get sections first, so have to start 'behind' to make up */
9474         iServiceIndex = -1;
9475
9476         if (lp_config_backend_is_file()) {
9477                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9478                                         current_user_info.domain,
9479                                         pszFname);
9480                 if (!n2) {
9481                         smb_panic("lp_load_ex: out of memory");
9482                 }
9483
9484                 add_to_file_list(pszFname, n2);
9485
9486                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9487                 TALLOC_FREE(n2);
9488
9489                 /* finish up the last section */
9490                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9491                 if (bRetval) {
9492                         if (iServiceIndex >= 0) {
9493                                 bRetval = service_ok(iServiceIndex);
9494                         }
9495                 }
9496
9497                 if (lp_config_backend_is_registry()) {
9498                         /* config backend changed to registry in config file */
9499                         /*
9500                          * We need to use this extra global variable here to
9501                          * survive restart: init_globals uses this as a default
9502                          * for ConfigBackend. Otherwise, init_globals would
9503                          *  send us into an endless loop here.
9504                          */
9505                         config_backend = CONFIG_BACKEND_REGISTRY;
9506                         /* start over */
9507                         DEBUG(1, ("lp_load_ex: changing to config backend "
9508                                   "registry\n"));
9509                         init_globals(true);
9510                         lp_kill_all_services();
9511                         return lp_load_ex(pszFname, global_only, save_defaults,
9512                                           add_ipc, initialize_globals,
9513                                           allow_include_registry,
9514                                           allow_registry_shares);
9515                 }
9516         } else if (lp_config_backend_is_registry()) {
9517                 bRetval = process_registry_globals();
9518         } else {
9519                 DEBUG(0, ("Illegal config  backend given: %d\n",
9520                           lp_config_backend()));
9521                 bRetval = false;
9522         }
9523
9524         if (bRetval && lp_registry_shares() && allow_registry_shares) {
9525                 bRetval = process_registry_shares();
9526         }
9527
9528         lp_add_auto_services(lp_auto_services());
9529
9530         if (add_ipc) {
9531                 /* When 'restrict anonymous = 2' guest connections to ipc$
9532                    are denied */
9533                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9534                 if ( lp_enable_asu_support() ) {
9535                         lp_add_ipc("ADMIN$", false);
9536                 }
9537         }
9538
9539         set_server_role();
9540         set_default_server_announce_type();
9541         set_allowed_client_auth();
9542
9543         if (lp_security() == SEC_SHARE) {
9544                 DEBUG(1, ("WARNING: The security=share option is deprecated\n"));
9545         } else if (lp_security() == SEC_SERVER) {
9546                 DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
9547         }
9548
9549         if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
9550                 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
9551                           lp_passwordserver()));
9552         }
9553
9554         bLoaded = True;
9555
9556         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9557         /* if bWINSsupport is true and we are in the client            */
9558         if (lp_is_in_client() && Globals.bWINSsupport) {
9559                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9560         }
9561
9562         init_iconv();
9563
9564         fault_configure(smb_panic_s3);
9565
9566         bAllowIncludeRegistry = true;
9567
9568         return (bRetval);
9569 }
9570
9571 bool lp_load(const char *pszFname,
9572              bool global_only,
9573              bool save_defaults,
9574              bool add_ipc,
9575              bool initialize_globals)
9576 {
9577         return lp_load_ex(pszFname,
9578                           global_only,
9579                           save_defaults,
9580                           add_ipc,
9581                           initialize_globals,
9582                           true,   /* allow_include_registry */
9583                           false); /* allow_registry_shares*/
9584 }
9585
9586 bool lp_load_initial_only(const char *pszFname)
9587 {
9588         return lp_load_ex(pszFname,
9589                           true,   /* global only */
9590                           false,  /* save_defaults */
9591                           false,  /* add_ipc */
9592                           true,   /* initialize_globals */
9593                           false,  /* allow_include_registry */
9594                           false); /* allow_registry_shares*/
9595 }
9596
9597 bool lp_load_with_registry_shares(const char *pszFname,
9598                                   bool global_only,
9599                                   bool save_defaults,
9600                                   bool add_ipc,
9601                                   bool initialize_globals)
9602 {
9603         return lp_load_ex(pszFname,
9604                           global_only,
9605                           save_defaults,
9606                           add_ipc,
9607                           initialize_globals,
9608                           true,  /* allow_include_registry */
9609                           true); /* allow_registry_shares*/
9610 }
9611
9612 /***************************************************************************
9613  Return the max number of services.
9614 ***************************************************************************/
9615
9616 int lp_numservices(void)
9617 {
9618         return (iNumServices);
9619 }
9620
9621 /***************************************************************************
9622 Display the contents of the services array in human-readable form.
9623 ***************************************************************************/
9624
9625 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9626 {
9627         int iService;
9628
9629         if (show_defaults)
9630                 defaults_saved = False;
9631
9632         dump_globals(f);
9633
9634         dump_a_service(&sDefault, f);
9635
9636         for (iService = 0; iService < maxtoprint; iService++) {
9637                 fprintf(f,"\n");
9638                 lp_dump_one(f, show_defaults, iService);
9639         }
9640 }
9641
9642 /***************************************************************************
9643 Display the contents of one service in human-readable form.
9644 ***************************************************************************/
9645
9646 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9647 {
9648         if (VALID(snum)) {
9649                 if (ServicePtrs[snum]->szService[0] == '\0')
9650                         return;
9651                 dump_a_service(ServicePtrs[snum], f);
9652         }
9653 }
9654
9655 /***************************************************************************
9656 Return the number of the service with the given name, or -1 if it doesn't
9657 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9658 getservicebyname()! This works ONLY if all services have been loaded, and
9659 does not copy the found service.
9660 ***************************************************************************/
9661
9662 int lp_servicenumber(const char *pszServiceName)
9663 {
9664         int iService;
9665         fstring serviceName;
9666
9667         if (!pszServiceName) {
9668                 return GLOBAL_SECTION_SNUM;
9669         }
9670
9671         for (iService = iNumServices - 1; iService >= 0; iService--) {
9672                 if (VALID(iService) && ServicePtrs[iService]->szService) {
9673                         /*
9674                          * The substitution here is used to support %U is
9675                          * service names
9676                          */
9677                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
9678                         standard_sub_basic(get_current_username(),
9679                                            current_user_info.domain,
9680                                            serviceName,sizeof(serviceName));
9681                         if (strequal(serviceName, pszServiceName)) {
9682                                 break;
9683                         }
9684                 }
9685         }
9686
9687         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9688                 struct timespec last_mod;
9689
9690                 if (!usershare_exists(iService, &last_mod)) {
9691                         /* Remove the share security tdb entry for it. */
9692                         delete_share_security(lp_servicename(iService));
9693                         /* Remove it from the array. */
9694                         free_service_byindex(iService);
9695                         /* Doesn't exist anymore. */
9696                         return GLOBAL_SECTION_SNUM;
9697                 }
9698
9699                 /* Has it been modified ? If so delete and reload. */
9700                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9701                                      &last_mod) < 0) {
9702                         /* Remove it from the array. */
9703                         free_service_byindex(iService);
9704                         /* and now reload it. */
9705                         iService = load_usershare_service(pszServiceName);
9706                 }
9707         }
9708
9709         if (iService < 0) {
9710                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9711                 return GLOBAL_SECTION_SNUM;
9712         }
9713
9714         return (iService);
9715 }
9716
9717 bool share_defined(const char *service_name)
9718 {
9719         return (lp_servicenumber(service_name) != -1);
9720 }
9721
9722 /*******************************************************************
9723  A useful volume label function. 
9724 ********************************************************************/
9725
9726 const char *volume_label(int snum)
9727 {
9728         char *ret;
9729         const char *label = lp_volume(snum);
9730         if (!*label) {
9731                 label = lp_servicename(snum);
9732         }
9733
9734         /* This returns a 33 byte guarenteed null terminated string. */
9735         ret = talloc_strndup(talloc_tos(), label, 32);
9736         if (!ret) {
9737                 return "";
9738         }               
9739         return ret;
9740 }
9741
9742 /*******************************************************************
9743  Set the server type we will announce as via nmbd.
9744 ********************************************************************/
9745
9746 static void set_default_server_announce_type(void)
9747 {
9748         default_server_announce = 0;
9749         default_server_announce |= SV_TYPE_WORKSTATION;
9750         default_server_announce |= SV_TYPE_SERVER;
9751         default_server_announce |= SV_TYPE_SERVER_UNIX;
9752
9753         /* note that the flag should be set only if we have a 
9754            printer service but nmbd doesn't actually load the 
9755            services so we can't tell   --jerry */
9756
9757         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9758
9759         default_server_announce |= SV_TYPE_SERVER_NT;
9760         default_server_announce |= SV_TYPE_NT;
9761
9762         switch (lp_server_role()) {
9763                 case ROLE_DOMAIN_MEMBER:
9764                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9765                         break;
9766                 case ROLE_DOMAIN_PDC:
9767                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9768                         break;
9769                 case ROLE_DOMAIN_BDC:
9770                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9771                         break;
9772                 case ROLE_STANDALONE:
9773                 default:
9774                         break;
9775         }
9776         if (lp_time_server())
9777                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9778
9779         if (lp_host_msdfs())
9780                 default_server_announce |= SV_TYPE_DFS_SERVER;
9781 }
9782
9783 /***********************************************************
9784  If we are PDC then prefer us as DMB
9785 ************************************************************/
9786
9787 bool lp_domain_master(void)
9788 {
9789         if (Globals.iDomainMaster == Auto)
9790                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9791
9792         return (bool)Globals.iDomainMaster;
9793 }
9794
9795 /***********************************************************
9796  If we are PDC then prefer us as DMB
9797 ************************************************************/
9798
9799 bool lp_domain_master_true_or_auto(void)
9800 {
9801         if (Globals.iDomainMaster) /* auto or yes */
9802                 return true;
9803
9804         return false;
9805 }
9806
9807 /***********************************************************
9808  If we are DMB then prefer us as LMB
9809 ************************************************************/
9810
9811 bool lp_preferred_master(void)
9812 {
9813         if (Globals.iPreferredMaster == Auto)
9814                 return (lp_local_master() && lp_domain_master());
9815
9816         return (bool)Globals.iPreferredMaster;
9817 }
9818
9819 /*******************************************************************
9820  Remove a service.
9821 ********************************************************************/
9822
9823 void lp_remove_service(int snum)
9824 {
9825         ServicePtrs[snum]->valid = False;
9826         invalid_services[num_invalid_services++] = snum;
9827 }
9828
9829 /*******************************************************************
9830  Copy a service.
9831 ********************************************************************/
9832
9833 void lp_copy_service(int snum, const char *new_name)
9834 {
9835         do_section(new_name, NULL);
9836         if (snum >= 0) {
9837                 snum = lp_servicenumber(new_name);
9838                 if (snum >= 0)
9839                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9840         }
9841 }
9842
9843
9844 /*******************************************************************
9845  Get the default server type we will announce as via nmbd.
9846 ********************************************************************/
9847
9848 int lp_default_server_announce(void)
9849 {
9850         return default_server_announce;
9851 }
9852
9853 /***********************************************************
9854  Set the global name resolution order (used in smbclient).
9855 ************************************************************/
9856
9857 void lp_set_name_resolve_order(const char *new_order)
9858 {
9859         string_set(&Globals.szNameResolveOrder, new_order);
9860 }
9861
9862 const char *lp_printername(int snum)
9863 {
9864         const char *ret = _lp_printername(snum);
9865         if (ret == NULL || (ret != NULL && *ret == '\0'))
9866                 ret = lp_const_servicename(snum);
9867
9868         return ret;
9869 }
9870
9871
9872 /***********************************************************
9873  Allow daemons such as winbindd to fix their logfile name.
9874 ************************************************************/
9875
9876 void lp_set_logfile(const char *name)
9877 {
9878         string_set(&Globals.szLogFile, name);
9879         debug_set_logfile(name);
9880 }
9881
9882 /*******************************************************************
9883  Return the max print jobs per queue.
9884 ********************************************************************/
9885
9886 int lp_maxprintjobs(int snum)
9887 {
9888         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9889         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9890                 maxjobs = PRINT_MAX_JOBID - 1;
9891
9892         return maxjobs;
9893 }
9894
9895 const char *lp_printcapname(void)
9896 {
9897         if ((Globals.szPrintcapname != NULL) &&
9898             (Globals.szPrintcapname[0] != '\0'))
9899                 return Globals.szPrintcapname;
9900
9901         if (sDefault.iPrinting == PRINT_CUPS) {
9902 #ifdef HAVE_CUPS
9903                 return "cups";
9904 #else
9905                 return "lpstat";
9906 #endif
9907         }
9908
9909         if (sDefault.iPrinting == PRINT_BSD)
9910                 return "/etc/printcap";
9911
9912         return PRINTCAP_NAME;
9913 }
9914
9915 static uint32 spoolss_state;
9916
9917 bool lp_disable_spoolss( void )
9918 {
9919         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9920                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9921
9922         return spoolss_state == SVCCTL_STOPPED ? True : False;
9923 }
9924
9925 void lp_set_spoolss_state( uint32 state )
9926 {
9927         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9928
9929         spoolss_state = state;
9930 }
9931
9932 uint32 lp_get_spoolss_state( void )
9933 {
9934         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9935 }
9936
9937 /*******************************************************************
9938  Ensure we don't use sendfile if server smb signing is active.
9939 ********************************************************************/
9940
9941 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9942 {
9943         bool sign_active = false;
9944
9945         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9946         if (get_Protocol() < PROTOCOL_NT1) {
9947                 return false;
9948         }
9949         if (signing_state) {
9950                 sign_active = smb_signing_is_active(signing_state);
9951         }
9952         return (_lp_use_sendfile(snum) &&
9953                         (get_remote_arch() != RA_WIN95) &&
9954                         !sign_active);
9955 }
9956
9957 /*******************************************************************
9958  Turn off sendfile if we find the underlying OS doesn't support it.
9959 ********************************************************************/
9960
9961 void set_use_sendfile(int snum, bool val)
9962 {
9963         if (LP_SNUM_OK(snum))
9964                 ServicePtrs[snum]->bUseSendfile = val;
9965         else
9966                 sDefault.bUseSendfile = val;
9967 }
9968
9969 /*******************************************************************
9970  Turn off storing DOS attributes if this share doesn't support it.
9971 ********************************************************************/
9972
9973 void set_store_dos_attributes(int snum, bool val)
9974 {
9975         if (!LP_SNUM_OK(snum))
9976                 return;
9977         ServicePtrs[(snum)]->bStoreDosAttributes = val;
9978 }
9979
9980 void lp_set_mangling_method(const char *new_method)
9981 {
9982         string_set(&Globals.szManglingMethod, new_method);
9983 }
9984
9985 /*******************************************************************
9986  Global state for POSIX pathname processing.
9987 ********************************************************************/
9988
9989 static bool posix_pathnames;
9990
9991 bool lp_posix_pathnames(void)
9992 {
9993         return posix_pathnames;
9994 }
9995
9996 /*******************************************************************
9997  Change everything needed to ensure POSIX pathname processing (currently
9998  not much).
9999 ********************************************************************/
10000
10001 void lp_set_posix_pathnames(void)
10002 {
10003         posix_pathnames = True;
10004 }
10005
10006 /*******************************************************************
10007  Global state for POSIX lock processing - CIFS unix extensions.
10008 ********************************************************************/
10009
10010 bool posix_default_lock_was_set;
10011 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
10012
10013 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
10014 {
10015         if (posix_default_lock_was_set) {
10016                 return posix_cifsx_locktype;
10017         } else {
10018                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
10019         }
10020 }
10021
10022 /*******************************************************************
10023 ********************************************************************/
10024
10025 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
10026 {
10027         posix_default_lock_was_set = True;
10028         posix_cifsx_locktype = val;
10029 }
10030
10031 int lp_min_receive_file_size(void)
10032 {
10033         if (Globals.iminreceivefile < 0) {
10034                 return 0;
10035         }
10036         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
10037 }
10038
10039 /*******************************************************************
10040  If socket address is an empty character string, it is necessary to 
10041  define it as "0.0.0.0". 
10042 ********************************************************************/
10043
10044 const char *lp_socket_address(void)
10045 {
10046         char *sock_addr = Globals.szSocketAddress;
10047
10048         if (sock_addr[0] == '\0'){
10049                 string_set(&Globals.szSocketAddress, "0.0.0.0");
10050         }
10051         return  Globals.szSocketAddress;
10052 }
10053
10054 void lp_set_passdb_backend(const char *backend)
10055 {
10056         string_set(&Globals.szPassdbBackend, backend);
10057 }
10058
10059 /*******************************************************************
10060  Safe wide links checks.
10061  This helper function always verify the validity of wide links,
10062  even after a configuration file reload.
10063 ********************************************************************/
10064
10065 static bool lp_widelinks_internal(int snum)
10066 {
10067         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
10068                         sDefault.bWidelinks);
10069 }
10070
10071 void widelinks_warning(int snum)
10072 {
10073         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10074                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10075                         "These parameters are incompatible. "
10076                         "Wide links will be disabled for this share.\n",
10077                         lp_servicename(snum) ));
10078         }
10079 }
10080
10081 bool lp_widelinks(int snum)
10082 {
10083         /* wide links is always incompatible with unix extensions */
10084         if (lp_unix_extensions()) {
10085                 return false;
10086         }
10087
10088         return lp_widelinks_internal(snum);
10089 }
10090
10091 bool lp_writeraw(void)
10092 {
10093         if (lp_async_smb_echo_handler()) {
10094                 return false;
10095         }
10096         return _lp_writeraw();
10097 }
10098
10099 bool lp_readraw(void)
10100 {
10101         if (lp_async_smb_echo_handler()) {
10102                 return false;
10103         }
10104         return _lp_readraw();
10105 }