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