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