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