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