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