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