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
13   This program is free software; you can redistribute it and/or modify
14   it under the terms of the GNU General Public License as published by
15   the Free Software Foundation; either version 2 of the License, or
16   (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful,
19   but WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21   GNU General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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
56BOOL in_client = False;		/* Not in the client by default */
57BOOL bLoaded = False;
58
59extern userdom_struct current_user_info;
60extern pstring user_socket_options;
61
62#ifndef GLOBAL_NAME
63#define GLOBAL_NAME "global"
64#endif
65
66#ifndef PRINTERS_NAME
67#define PRINTERS_NAME "printers"
68#endif
69
70#ifndef HOMES_NAME
71#define HOMES_NAME "homes"
72#endif
73
74/* some helpful bits */
75#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
76#define VALID(i) ServicePtrs[i]->valid
77
78int keepalive = DEFAULT_KEEPALIVE;
79BOOL use_getwd_cache = True;
80
81extern int extra_time_offset;
82
83static BOOL defaults_saved = False;
84
85typedef struct _param_opt_struct param_opt_struct;
86struct _param_opt_struct {
87	param_opt_struct *prev, *next;
88	char *key;
89	char *value;
90	char **list;
91};
92
93/*
94 * This structure describes global (ie., server-wide) parameters.
95 */
96typedef struct
97{
98	char *smb_ports;
99	char *dos_charset;
100	char *unix_charset;
101	char *display_charset;
102	char *szPrintcapname;
103	char *szEnumPortsCommand;
104	char *szAddPrinterCommand;
105	char *szDeletePrinterCommand;
106	char *szOs2DriverMap;
107	char *szLockDir;
108	char *szPidDir;
109	char *szRootdir;
110	char *szDefaultService;
111	char *szDfree;
112	char *szGetQuota;
113	char *szSetQuota;
114	char *szMsgCommand;
115	char *szHostsEquiv;
116	char *szServerString;
117	char *szAutoServices;
118	char *szPasswdProgram;
119	char *szPasswdChat;
120	char *szLogFile;
121	char *szConfigFile;
122	char *szSMBPasswdFile;
123	char *szPrivateDir;
124	char **szPassdbBackend;
125	char **szPreloadModules;
126	char *szPasswordServer;
127	char *szSocketOptions;
128	char *szRealm;
129	char *szAfsUsernameMap;
130	int iAfsTokenLifetime;
131 	char *szLogNtTokenCommand;
132	char *szUsernameMap;
133	char *szLogonScript;
134	char *szLogonPath;
135	char *szLogonDrive;
136	char *szLogonHome;
137	char **szWINSservers;
138	char **szInterfaces;
139	char *szRemoteAnnounce;
140	char *szRemoteBrowseSync;
141	char *szSocketAddress;
142	char *szNISHomeMapName;
143	char *szAnnounceVersion;	/* This is initialised in init_globals */
144	char *szWorkgroup;
145	char *szNetbiosName;
146	char **szNetbiosAliases;
147	char *szNetbiosScope;
148	char *szDomainOtherSIDs;
149	char *szNameResolveOrder;
150	char *szPanicAction;
151	char *szAddUserScript;
152	char *szDelUserScript;
153	char *szAddGroupScript;
154	char *szDelGroupScript;
155	char *szAddUserToGroupScript;
156	char *szDelUserFromGroupScript;
157	char *szSetPrimaryGroupScript;
158	char *szAddMachineScript;
159	char *szShutdownScript;
160	char *szAbortShutdownScript;
161	char *szCheckPasswordScript;
162	char *szWINSHook;
163	char *szWINSPartners;
164	char *szUtmpDir;
165	char *szWtmpDir;
166	BOOL bUtmp;
167	char *szIdmapUID;
168	char *szIdmapGID;
169	BOOL bEnableRidAlgorithm;
170	int AlgorithmicRidBase;
171	char *szTemplatePrimaryGroup;
172	char *szTemplateHomedir;
173	char *szTemplateShell;
174	char *szWinbindSeparator;
175	BOOL bWinbindEnableLocalAccounts;
176	BOOL bWinbindEnumUsers;
177	BOOL bWinbindEnumGroups;
178	BOOL bWinbindUseDefaultDomain;
179	BOOL bWinbindTrustedDomainsOnly;
180	BOOL bWinbindNestedGroups;
181	char *szWinbindBackend;
182	char **szIdmapBackend;
183	char *szAddShareCommand;
184	char *szChangeShareCommand;
185	char *szDeleteShareCommand;
186	char *szGuestaccount;
187	char *szManglingMethod;
188	int mangle_prefix;
189	int max_log_size;
190	char *szLogLevel;
191	int max_xmit;
192	int max_mux;
193	int max_open_files;
194	int pwordlevel;
195	int unamelevel;
196	int deadtime;
197	int maxprotocol;
198	int minprotocol;
199	int security;
200	char **AuthMethods;
201	BOOL paranoid_server_security;
202	int maxdisksize;
203	int lpqcachetime;
204	int iMaxSmbdProcesses;
205	BOOL bDisableSpoolss;
206	int syslog;
207	int os_level;
208	int enhanced_browsing;
209	int max_ttl;
210	int max_wins_ttl;
211	int min_wins_ttl;
212	int lm_announce;
213	int lm_interval;
214	int announce_as;	/* This is initialised in init_globals */
215	int machine_password_timeout;
216	int change_notify_timeout;
217	int map_to_guest;
218	int min_passwd_length;
219	int oplock_break_wait_time;
220	int winbind_cache_time;
221	int iLockSpinCount;
222	int iLockSpinTime;
223	char *szLdapMachineSuffix;
224	char *szLdapUserSuffix;
225	char *szLdapIdmapSuffix;
226	char *szLdapGroupSuffix;
227#ifdef WITH_LDAP_SAMCONFIG
228	int ldap_port;
229	char *szLdapServer;
230#endif
231	int ldap_ssl;
232	char *szLdapSuffix;
233	char *szLdapFilter;
234	char *szLdapAdminDn;
235	char *szAclCompat;
236	char *szCupsServer;
237	int ldap_passwd_sync;
238	int ldap_replication_sleep;
239	int ldap_timeout; /* This is initialised in init_globals */
240	BOOL ldap_delete_dn;
241	BOOL bMsAddPrinterWizard;
242	BOOL bDNSproxy;
243	BOOL bWINSsupport;
244	BOOL bWINSproxy;
245	BOOL bLocalMaster;
246	BOOL bPreferredMaster;
247	BOOL bDomainMaster;
248	BOOL bDomainLogons;
249	BOOL bEncryptPasswords;
250	BOOL bUpdateEncrypt;
251	int  clientSchannel;
252	int  serverSchannel;
253	BOOL bNullPasswords;
254	BOOL bObeyPamRestrictions;
255	BOOL bLoadPrinters;
256	int PrintcapCacheTime;
257	BOOL bLargeReadwrite;
258	BOOL bReadRaw;
259	BOOL bWriteRaw;
260	BOOL bReadbmpx;
261	BOOL bSyslogOnly;
262	BOOL bBrowseList;
263	BOOL bNISHomeMap;
264	BOOL bTimeServer;
265	BOOL bBindInterfacesOnly;
266	BOOL bPamPasswordChange;
267	BOOL bUnixPasswdSync;
268	BOOL bPasswdChatDebug;
269	int iPasswdChatTimeout;
270	BOOL bTimestampLogs;
271	BOOL bNTSmbSupport;
272	BOOL bNTPipeSupport;
273	BOOL bNTStatusSupport;
274	BOOL bStatCache;
275	BOOL bKernelOplocks;
276	BOOL bAllowTrustedDomains;
277	BOOL bLanmanAuth;
278	BOOL bNTLMAuth;
279	BOOL bUseSpnego;
280	BOOL bClientLanManAuth;
281	BOOL bClientNTLMv2Auth;
282	BOOL bClientPlaintextAuth;
283	BOOL bClientUseSpnego;
284	BOOL bDebugHiresTimestamp;
285	BOOL bDebugPid;
286	BOOL bDebugUid;
287	BOOL bHostMSDfs;
288	BOOL bUseMmap;
289	BOOL bHostnameLookups;
290	BOOL bUnixExtensions;
291	BOOL bDisableNetbios;
292	BOOL bKernelChangeNotify;
293	BOOL bUseKerberosKeytab;
294	BOOL bDeferSharingViolations;
295	BOOL bEnablePrivileges;
296	int restrict_anonymous;
297	int name_cache_timeout;
298	int client_signing;
299	int server_signing;
300	param_opt_struct *param_opt;
301}
302global;
303
304static global Globals;
305
306/*
307 * This structure describes a single service.
308 */
309typedef struct
310{
311	BOOL valid;
312	BOOL autoloaded;
313	char *szService;
314	char *szPath;
315	char *szUsername;
316	char **szInvalidUsers;
317	char **szValidUsers;
318	char **szAdminUsers;
319	char *szCopy;
320	char *szInclude;
321	char *szPreExec;
322	char *szPostExec;
323	char *szRootPreExec;
324	char *szRootPostExec;
325	char *szCupsOptions;
326	char *szPrintcommand;
327	char *szLpqcommand;
328	char *szLprmcommand;
329	char *szLppausecommand;
330	char *szLpresumecommand;
331	char *szQueuepausecommand;
332	char *szQueueresumecommand;
333	char *szPrintername;
334	char *szDontdescend;
335	char **szHostsallow;
336	char **szHostsdeny;
337	char *szMagicScript;
338	char *szMagicOutput;
339	char *szMangledMap;
340	char *szVetoFiles;
341	char *szHideFiles;
342	char *szVetoOplockFiles;
343	char *comment;
344	char *force_user;
345	char *force_group;
346	char **readlist;
347	char **writelist;
348	char **printer_admin;
349	char *volume;
350	char *fstype;
351	char **szVfsObjects;
352	char *szMSDfsProxy;
353	int iMinPrintSpace;
354	int iMaxPrintJobs;
355	int iMaxReportedPrintJobs;
356	int iWriteCacheSize;
357	int iCreate_mask;
358	int iCreate_force_mode;
359	int iSecurity_mask;
360	int iSecurity_force_mode;
361	int iDir_mask;
362	int iDir_force_mode;
363	int iDir_Security_mask;
364	int iDir_Security_force_mode;
365	int iMaxConnections;
366	int iDefaultCase;
367	int iPrinting;
368	int iOplockContentionLimit;
369	int iCSCPolicy;
370	int iBlock_size;
371	BOOL bPreexecClose;
372	BOOL bRootpreexecClose;
373	int  iCaseSensitive;
374	BOOL bCasePreserve;
375	BOOL bShortCasePreserve;
376	BOOL bHideDotFiles;
377	BOOL bHideSpecialFiles;
378	BOOL bHideUnReadable;
379	BOOL bHideUnWriteableFiles;
380	BOOL bBrowseable;
381	BOOL bAvailable;
382	BOOL bRead_only;
383	BOOL bNo_set_dir;
384	BOOL bGuest_only;
385	BOOL bGuest_ok;
386	BOOL bPrint_ok;
387	BOOL bMap_system;
388	BOOL bMap_hidden;
389	BOOL bMap_archive;
390	BOOL bStoreDosAttributes;
391	BOOL bLocking;
392	int iStrictLocking;
393	BOOL bPosixLocking;
394	BOOL bShareModes;
395	BOOL bOpLocks;
396	BOOL bLevel2OpLocks;
397	BOOL bOnlyUser;
398	BOOL bMangledNames;
399	BOOL bWidelinks;
400	BOOL bSymlinks;
401	BOOL bSyncAlways;
402	BOOL bStrictAllocate;
403	BOOL bStrictSync;
404	char magic_char;
405	BOOL *copymap;
406	BOOL bDeleteReadonly;
407	BOOL bFakeOplocks;
408	BOOL bDeleteVetoFiles;
409	BOOL bDosFilemode;
410	BOOL bDosFiletimes;
411	BOOL bDosFiletimeResolution;
412	BOOL bFakeDirCreateTimes;
413	BOOL bBlockingLocks;
414	BOOL bInheritPerms;
415	BOOL bInheritACLS;
416	BOOL bMSDfsRoot;
417	BOOL bUseClientDriver;
418	BOOL bDefaultDevmode;
419	BOOL bForcePrintername;
420	BOOL bNTAclSupport;
421	BOOL bForceUnknownAclUser;
422	BOOL bUseSendfile;
423	BOOL bProfileAcls;
424	BOOL bMap_acl_inherit;
425	BOOL bAfs_Share;
426	BOOL bEASupport;
427	int iallocation_roundup_size;
428	param_opt_struct *param_opt;
429
430	char dummy[3];		/* for alignment */
431}
432service;
433
434
435/* This is a default service used to prime a services structure */
436static service sDefault = {
437	True,			/* valid */
438	False,			/* not autoloaded */
439	NULL,			/* szService */
440	NULL,			/* szPath */
441	NULL,			/* szUsername */
442	NULL,			/* szInvalidUsers */
443	NULL,			/* szValidUsers */
444	NULL,			/* szAdminUsers */
445	NULL,			/* szCopy */
446	NULL,			/* szInclude */
447	NULL,			/* szPreExec */
448	NULL,			/* szPostExec */
449	NULL,			/* szRootPreExec */
450	NULL,			/* szRootPostExec */
451	NULL,			/* szCupsOptions */
452	NULL,			/* szPrintcommand */
453	NULL,			/* szLpqcommand */
454	NULL,			/* szLprmcommand */
455	NULL,			/* szLppausecommand */
456	NULL,			/* szLpresumecommand */
457	NULL,			/* szQueuepausecommand */
458	NULL,			/* szQueueresumecommand */
459	NULL,			/* szPrintername */
460	NULL,			/* szDontdescend */
461	NULL,			/* szHostsallow */
462	NULL,			/* szHostsdeny */
463	NULL,			/* szMagicScript */
464	NULL,			/* szMagicOutput */
465	NULL,			/* szMangledMap */
466	NULL,			/* szVetoFiles */
467	NULL,			/* szHideFiles */
468	NULL,			/* szVetoOplockFiles */
469	NULL,			/* comment */
470	NULL,			/* force user */
471	NULL,			/* force group */
472	NULL,			/* readlist */
473	NULL,			/* writelist */
474	NULL,			/* printer admin */
475	NULL,			/* volume */
476	NULL,			/* fstype */
477	NULL,			/* vfs objects */
478	NULL,                   /* szMSDfsProxy */
479	0,			/* iMinPrintSpace */
480	1000,			/* iMaxPrintJobs */
481	0,			/* iMaxReportedPrintJobs */
482	0,			/* iWriteCacheSize */
483	0744,			/* iCreate_mask */
484	0000,			/* iCreate_force_mode */
485	0777,			/* iSecurity_mask */
486	0,			/* iSecurity_force_mode */
487	0755,			/* iDir_mask */
488	0000,			/* iDir_force_mode */
489	0777,			/* iDir_Security_mask */
490	0,			/* iDir_Security_force_mode */
491	0,			/* iMaxConnections */
492	CASE_LOWER,		/* iDefaultCase */
493	DEFAULT_PRINTING,	/* iPrinting */
494	2,			/* iOplockContentionLimit */
495	0,			/* iCSCPolicy */
496	1024,           /* iBlock_size */
497	False,			/* bPreexecClose */
498	False,			/* bRootpreexecClose */
499	Auto,			/* case sensitive */
500	True,			/* case preserve */
501	True,			/* short case preserve */
502	True,			/* bHideDotFiles */
503	False,			/* bHideSpecialFiles */
504	False,			/* bHideUnReadable */
505	False,			/* bHideUnWriteableFiles */
506	True,			/* bBrowseable */
507	True,			/* bAvailable */
508	True,			/* bRead_only */
509	True,			/* bNo_set_dir */
510	False,			/* bGuest_only */
511	False,			/* bGuest_ok */
512	False,			/* bPrint_ok */
513	False,			/* bMap_system */
514	False,			/* bMap_hidden */
515	True,			/* bMap_archive */
516	False,			/* bStoreDosAttributes */
517	True,			/* bLocking */
518	True,			/* iStrictLocking */
519	True,			/* bPosixLocking */
520	True,			/* bShareModes */
521	True,			/* bOpLocks */
522	True,			/* bLevel2OpLocks */
523	False,			/* bOnlyUser */
524	True,			/* bMangledNames */
525	True,			/* bWidelinks */
526	True,			/* bSymlinks */
527	False,			/* bSyncAlways */
528	False,			/* bStrictAllocate */
529	False,			/* bStrictSync */
530	'~',			/* magic char */
531	NULL,			/* copymap */
532	False,			/* bDeleteReadonly */
533	False,			/* bFakeOplocks */
534	False,			/* bDeleteVetoFiles */
535	False,			/* bDosFilemode */
536	False,			/* bDosFiletimes */
537	False,			/* bDosFiletimeResolution */
538	False,			/* bFakeDirCreateTimes */
539	True,			/* bBlockingLocks */
540	False,			/* bInheritPerms */
541	False,			/* bInheritACLS */
542	False,			/* bMSDfsRoot */
543	False,			/* bUseClientDriver */
544	False,			/* bDefaultDevmode */
545	False,			/* bForcePrintername */
546	True,			/* bNTAclSupport */
547	False,                  /* bForceUnknownAclUser */
548	False,			/* bUseSendfile */
549	False,			/* bProfileAcls */
550	False,			/* bMap_acl_inherit */
551	False,			/* bAfs_Share */
552	False,			/* bEASupport */
553	SMB_ROUNDUP_ALLOCATION_SIZE,		/* iallocation_roundup_size */
554
555	NULL,			/* Parametric options */
556
557	""			/* dummy */
558};
559
560/* local variables */
561static service **ServicePtrs = NULL;
562static int iNumServices = 0;
563static int iServiceIndex = 0;
564static BOOL bInGlobalSection = True;
565static BOOL bGlobalOnly = False;
566static int server_role;
567static int default_server_announce;
568
569#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
570
571/* prototypes for the special type handlers */
572static BOOL handle_include( int snum, const char *pszParmValue, char **ptr);
573static BOOL handle_copy( int snum, const char *pszParmValue, char **ptr);
574static BOOL handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
575static BOOL handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
576static BOOL handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
577static BOOL handle_debug_list( int snum, const char *pszParmValue, char **ptr );
578static BOOL handle_workgroup( int snum, const char *pszParmValue, char **ptr );
579static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
580static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
581static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
582static BOOL handle_acl_compatibility( int snum, const char *pszParmValue, char **ptr);
583static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
584
585static void set_server_role(void);
586static void set_default_server_announce_type(void);
587static void set_allowed_client_auth(void);
588
589static const struct enum_list enum_protocol[] = {
590	{PROTOCOL_NT1, "NT1"},
591	{PROTOCOL_LANMAN2, "LANMAN2"},
592	{PROTOCOL_LANMAN1, "LANMAN1"},
593	{PROTOCOL_CORE, "CORE"},
594	{PROTOCOL_COREPLUS, "COREPLUS"},
595	{PROTOCOL_COREPLUS, "CORE+"},
596	{-1, NULL}
597};
598
599static const struct enum_list enum_security[] = {
600	{SEC_SHARE, "SHARE"},
601	{SEC_USER, "USER"},
602	{SEC_SERVER, "SERVER"},
603	{SEC_DOMAIN, "DOMAIN"},
604#ifdef HAVE_ADS
605	{SEC_ADS, "ADS"},
606#endif
607	{-1, NULL}
608};
609
610static const struct enum_list enum_printing[] = {
611	{PRINT_SYSV, "sysv"},
612	{PRINT_AIX, "aix"},
613	{PRINT_HPUX, "hpux"},
614	{PRINT_BSD, "bsd"},
615	{PRINT_QNX, "qnx"},
616	{PRINT_PLP, "plp"},
617	{PRINT_LPRNG, "lprng"},
618	{PRINT_CUPS, "cups"},
619	{PRINT_LPRNT, "nt"},
620	{PRINT_LPROS2, "os2"},
621#ifdef DEVELOPER
622	{PRINT_TEST, "test"},
623	{PRINT_VLP, "vlp"},
624#endif /* DEVELOPER */
625	{-1, NULL}
626};
627
628static const struct enum_list enum_ldap_ssl[] = {
629#ifdef WITH_LDAP_SAMCONFIG
630	{LDAP_SSL_ON, "Yes"},
631	{LDAP_SSL_ON, "yes"},
632	{LDAP_SSL_ON, "on"},
633	{LDAP_SSL_ON, "On"},
634#endif
635	{LDAP_SSL_OFF, "no"},
636	{LDAP_SSL_OFF, "No"},
637	{LDAP_SSL_OFF, "off"},
638	{LDAP_SSL_OFF, "Off"},
639	{LDAP_SSL_START_TLS, "start tls"},
640	{LDAP_SSL_START_TLS, "Start_tls"},
641	{-1, NULL}
642};
643
644static const struct enum_list enum_ldap_passwd_sync[] = {
645	{LDAP_PASSWD_SYNC_OFF, "no"},
646	{LDAP_PASSWD_SYNC_OFF, "No"},
647	{LDAP_PASSWD_SYNC_OFF, "off"},
648	{LDAP_PASSWD_SYNC_OFF, "Off"},
649	{LDAP_PASSWD_SYNC_ON, "Yes"},
650	{LDAP_PASSWD_SYNC_ON, "yes"},
651	{LDAP_PASSWD_SYNC_ON, "on"},
652	{LDAP_PASSWD_SYNC_ON, "On"},
653	{LDAP_PASSWD_SYNC_ONLY, "Only"},
654	{LDAP_PASSWD_SYNC_ONLY, "only"},
655	{-1, NULL}
656};
657
658/* Types of machine we can announce as. */
659#define ANNOUNCE_AS_NT_SERVER 1
660#define ANNOUNCE_AS_WIN95 2
661#define ANNOUNCE_AS_WFW 3
662#define ANNOUNCE_AS_NT_WORKSTATION 4
663
664static const struct enum_list enum_announce_as[] = {
665	{ANNOUNCE_AS_NT_SERVER, "NT"},
666	{ANNOUNCE_AS_NT_SERVER, "NT Server"},
667	{ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
668	{ANNOUNCE_AS_WIN95, "win95"},
669	{ANNOUNCE_AS_WFW, "WfW"},
670	{-1, NULL}
671};
672
673static const struct enum_list enum_case[] = {
674	{CASE_LOWER, "lower"},
675	{CASE_UPPER, "upper"},
676	{-1, NULL}
677};
678
679static const struct enum_list enum_bool_auto[] = {
680	{False, "No"},
681	{False, "False"},
682	{False, "0"},
683	{True, "Yes"},
684	{True, "True"},
685	{True, "1"},
686	{Auto, "Auto"},
687	{-1, NULL}
688};
689
690/* Client-side offline caching policy types */
691#define CSC_POLICY_MANUAL 0
692#define CSC_POLICY_DOCUMENTS 1
693#define CSC_POLICY_PROGRAMS 2
694#define CSC_POLICY_DISABLE 3
695
696static const struct enum_list enum_csc_policy[] = {
697	{CSC_POLICY_MANUAL, "manual"},
698	{CSC_POLICY_DOCUMENTS, "documents"},
699	{CSC_POLICY_PROGRAMS, "programs"},
700	{CSC_POLICY_DISABLE, "disable"},
701	{-1, NULL}
702};
703
704/* SMB signing types. */
705static const struct enum_list enum_smb_signing_vals[] = {
706	{False, "No"},
707	{False, "False"},
708	{False, "0"},
709	{False, "Off"},
710	{False, "disabled"},
711	{True, "Yes"},
712	{True, "True"},
713	{True, "1"},
714	{True, "On"},
715	{True, "enabled"},
716	{Auto, "auto"},
717	{Required, "required"},
718	{Required, "mandatory"},
719	{Required, "force"},
720	{Required, "forced"},
721	{Required, "enforced"},
722	{-1, NULL}
723};
724
725
726/*
727   Do you want session setups at user level security with a invalid
728   password to be rejected or allowed in as guest? WinNT rejects them
729   but it can be a pain as it means "net view" needs to use a password
730
731   You have 3 choices in the setting of map_to_guest:
732
733   "Never" means session setups with an invalid password
734   are rejected. This is the default.
735
736   "Bad User" means session setups with an invalid password
737   are rejected, unless the username does not exist, in which case it
738   is treated as a guest login
739
740   "Bad Password" means session setups with an invalid password
741   are treated as a guest login
742
743   Note that map_to_guest only has an effect in user or server
744   level security.
745*/
746
747static const struct enum_list enum_map_to_guest[] = {
748	{NEVER_MAP_TO_GUEST, "Never"},
749	{MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
750	{MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
751	{-1, NULL}
752};
753
754/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
755 *
756 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
757 * screen in SWAT. This is used to exclude parameters as well as to squash all
758 * parameters that have been duplicated by pseudonyms.
759 *
760 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
761 *       Any parameter that does NOT have FLAG_ADVANCED will not disply at all
762 *	 Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
763 *        respective views.
764 *
765 * NOTE2: Handling of duplicated (synonym) paramters:
766 *	Only the first occurance of a parameter should be enabled by FLAG_BASIC
767 *	and/or FLAG_ADVANCED. All duplicates following the first mention should be
768 *	set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
769 *	name first, and all synonyms must follow it with the FLAG_HIDE attribute.
770 */
771
772static struct parm_struct parm_table[] = {
773	{N_("Base Options"), P_SEP, P_SEPARATOR},
774
775	{"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
776	{"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
777	{"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
778	{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
779	{"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
780	{"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
781	{"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
782#ifdef WITH_ADS
783	{"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
784#endif
785	{"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
786	{"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases,  NULL, FLAG_ADVANCED},
787	{"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope,  NULL, FLAG_ADVANCED},
788	{"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
789	{"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
790	{"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
791
792	{N_("Security Options"), P_SEP, P_SEPARATOR},
793
794	{"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
795	{"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
796	{"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
797	{"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
798	{"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
799	{"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
800	{"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
801	{"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED},
802	{"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_DEPRECATED},
803	{"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_DEPRECATED},
804	{"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
805	{"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
806	{"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
807	{"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
808	{"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
809	{"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
810	{"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
811	{"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
812	{"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
813	{"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
814	{"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
815	{"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
816	{"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
817
818	{"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
819	{"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
820	{"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
821	{"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
822	{"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
823	{"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED},
824	{"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
825	{"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
826	{"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
827	{"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
828	{"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
829	{"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
830	{"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
831	{"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
832	{"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
833	{"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
834
835	{"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
836	{"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
837	{"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
838
839	{"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
840	{"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
841	{"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
842	{"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
843	{"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
844	{"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT},
845	{"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
846	{"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
847	{"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
848
849	{"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
850	{"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
851	{"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
852	{"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
853
854	{"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
855	{"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
856	{"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
857	{"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
858	{"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
859	{"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
860	{"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
861	{"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
862	{"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
863	{"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
864	{"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
865	{"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
866	{"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
867	{"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
868	{"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
869
870	{"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
871	{"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
872
873	{"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
874	{"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
875	{"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
876	{"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
877	{"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
878	{"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
879	{"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED},
880
881	{N_("Logging Options"), P_SEP, P_SEPARATOR},
882
883	{"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
884	{"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
885	{"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
886	{"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
887	{"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
888
889	{"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
890	{"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
891	{"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
892	{"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
893	{"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
894	{"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
895
896	{N_("Protocol Options"), P_SEP, P_SEPARATOR},
897
898	{"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED},
899	{"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
900	{"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
901	{"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
902	{"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
903	{"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
904	{"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED},
905	{"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
906	{"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
907	{"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
908
909	{"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility,  NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
910	{ "defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
911	{"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
912	{"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
913	{"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
914	{"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
915	{"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
916
917	{"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
918	{"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as,  FLAG_ADVANCED},
919	{"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
920	{"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
921	{"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
922	{"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
923
924	{"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
925	{"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
926	{"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
927	{"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
928	{"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
929	{"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
930	{"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
931	{"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
932	{"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
933	{"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
934
935	{N_("Tuning Options"), P_SEP, P_SEPARATOR},
936
937	{"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
938	{"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_ADVANCED},
939	{"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
940	{"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
941	{"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED},
942	{"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED},
943
944	{"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
945	{"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
946	{"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
947	{"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
948	{"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
949	{"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
950	{"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
951
952	{"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
953	{"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
954	{"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
955	{"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
956	{"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
957	{"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
958	{"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
959	{"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
960
961	{"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
962
963	{N_("Printing Options"), P_SEP, P_SEPARATOR},
964
965	{"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
966	{"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
967	{"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
968	{"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
969	{"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
970	{"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
971	{"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
972	{"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
973	{"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
974	{"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
975	{"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
976	{"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
977	{"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
978	{"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
979	{"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
980	{"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
981	{"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
982	{"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
983	{"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
984
985	{"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
986	{"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
987	{"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
988	{"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
989	{"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
990
991	{"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
992	{"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
993	{"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
994	{"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
995	{"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
996
997	{N_("Filename Handling"), P_SEP, P_SEPARATOR},
998	{"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
999	{"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
1000
1001	{"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
1002	{"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1003	{"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE},
1004	{"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1005	{"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1006	{"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1007	{"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1008	{"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1009	{"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1010	{"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1011	{"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1012	{"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1013	{"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1014	{"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1015	{"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1016	{"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1017	{"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1018	{"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1019	{"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED },
1020	{"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
1021	{"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1022
1023	{N_("Domain Options"), P_SEP, P_SEPARATOR},
1024
1025	{"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1026
1027	{N_("Logon Options"), P_SEP, P_SEPARATOR},
1028
1029	{"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
1030	{"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
1031	{"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
1032	{"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
1033	{"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
1034	{"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
1035	{"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
1036	{"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
1037	{"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
1038	{"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
1039
1040	{"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
1041	{"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
1042	{"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
1043	{"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
1044	{"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
1045
1046	{N_("Browse Options"), P_SEP, P_SEPARATOR},
1047
1048	{"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1049	{"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
1050	{"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
1051	{"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1052	{"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
1053	{"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1054	{"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1055	{"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
1056	{"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1057	{"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1058	{"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
1059
1060	{N_("WINS Options"), P_SEP, P_SEPARATOR},
1061
1062	{"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
1063	{"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
1064
1065	{"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1066	{"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1067	{"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
1068	{"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1069
1070	{N_("Locking Options"), P_SEP, P_SEPARATOR},
1071
1072	{"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1073	{"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1074	{"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1075	{"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1076	{"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1077	{"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1078	{"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1079
1080	{"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1081	{"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1082	{"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1083	{"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1084	{"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1085	{"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1086	{"share modes", P_BOOL, P_LOCAL,  &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1087
1088	{N_("Ldap Options"), P_SEP, P_SEPARATOR},
1089
1090#ifdef WITH_LDAP_SAMCONFIG
1091	{"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, FLAG_ADVANCED},
1092	{"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, FLAG_ADVANCED},
1093#endif
1094	{"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
1095	{"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
1096	{"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED},
1097	{"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
1098	{"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
1099	{"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
1100	{"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
1101	{"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE},
1102	{"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1103	{"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
1104	{"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
1105	{"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1106	{"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
1107
1108	{N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
1109	{"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
1110	{"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
1111	{"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
1112
1113	{"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1114	{"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1115	{"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1116	{"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
1117	{"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
1118	{"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
1119#ifdef WITH_UTMP
1120	{"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
1121	{"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
1122	{"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
1123#endif
1124
1125	{"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1126	{"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1127	{"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
1128	{"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED},
1129	{"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
1130	{"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
1131	{"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
1132	{"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
1133	{"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
1134	{"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
1135	{"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
1136	{"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1137	{"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1138	{"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
1139	{"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
1140	{"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1141
1142	{"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1143	{"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1144	{"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1145	{"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
1146
1147	{"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1148	{"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1149	{"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1150	{"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1151	{"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1152	{"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1153	{"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1154	{"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1155	{"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1156	{"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1157	{"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1158	{"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1159	{"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1160	{"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1161	{"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1162	{"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1163	{"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1164	{"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1165
1166	{"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1167	{"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
1168
1169	{N_("VFS module options"), P_SEP, P_SEPARATOR},
1170
1171	{"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1172	{"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
1173
1174
1175	{"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1176	{"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1177	{"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
1178
1179	{N_("Winbind options"), P_SEP, P_SEPARATOR},
1180
1181	{"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_DEPRECATED},
1182	{"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED},
1183	{"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED},
1184	{"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE},
1185	{"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED},
1186	{"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE},
1187	{"template primary group", P_STRING, P_GLOBAL, &Globals.szTemplatePrimaryGroup, NULL, NULL, FLAG_ADVANCED},
1188	{"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
1189	{"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
1190	{"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
1191	{"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
1192	{"winbind enable local accounts", P_BOOL, P_GLOBAL, &Globals.bWinbindEnableLocalAccounts, NULL, NULL, FLAG_ADVANCED|FLAG_DEPRECATED},
1193	{"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
1194	{"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
1195	{"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
1196	{"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
1197	{"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
1198
1199	{NULL,  P_BOOL,  P_NONE,  NULL,  NULL,  NULL,  0}
1200};
1201
1202/***************************************************************************
1203 Initialise the sDefault parameter structure for the printer values.
1204***************************************************************************/
1205
1206static void init_printer_values(service *pService)
1207{
1208	/* choose defaults depending on the type of printing */
1209	switch (pService->iPrinting) {
1210		case PRINT_BSD:
1211		case PRINT_AIX:
1212		case PRINT_LPRNT:
1213		case PRINT_LPROS2:
1214			string_set(&pService->szLpqcommand, "lpq -P'%p'");
1215			string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1216			string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1217			break;
1218
1219		case PRINT_LPRNG:
1220		case PRINT_PLP:
1221			string_set(&pService->szLpqcommand, "lpq -P'%p'");
1222			string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1223			string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1224			string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1225			string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1226			string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1227			string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1228			break;
1229
1230		case PRINT_CUPS:
1231#ifdef HAVE_CUPS
1232			/* set the lpq command to contain the destination printer
1233			   name only.  This is used by cups_queue_get() */
1234			string_set(&pService->szLpqcommand, "%p");
1235			string_set(&pService->szLprmcommand, "");
1236			string_set(&pService->szPrintcommand, "");
1237			string_set(&pService->szLppausecommand, "");
1238			string_set(&pService->szLpresumecommand, "");
1239			string_set(&pService->szQueuepausecommand, "");
1240			string_set(&pService->szQueueresumecommand, "");
1241#else
1242			string_set(&pService->szLpqcommand, "/usr/bin/lpq -P'%p'");
1243			string_set(&pService->szLprmcommand, "/usr/bin/lprm -P'%p' %j");
1244			string_set(&pService->szPrintcommand, "/usr/bin/lpr -P'%p' %s; rm %s");
1245			string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1246			string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1247			string_set(&pService->szQueuepausecommand, "/usr/bin/disable '%p'");
1248			string_set(&pService->szQueueresumecommand, "/usr/bin/enable '%p'");
1249#endif /* HAVE_CUPS */
1250			break;
1251
1252		case PRINT_SYSV:
1253		case PRINT_HPUX:
1254			string_set(&pService->szLpqcommand, "lpstat -o%p");
1255			string_set(&pService->szLprmcommand, "cancel %p-%j");
1256			string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1257			string_set(&pService->szQueuepausecommand, "disable %p");
1258			string_set(&pService->szQueueresumecommand, "enable %p");
1259#ifndef HPUX
1260			string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1261			string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1262#endif /* HPUX */
1263			break;
1264
1265		case PRINT_QNX:
1266			string_set(&pService->szLpqcommand, "lpq -P%p");
1267			string_set(&pService->szLprmcommand, "lprm -P%p %j");
1268			string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1269			break;
1270
1271#ifdef DEVELOPER
1272	case PRINT_TEST:
1273	case PRINT_VLP:
1274		string_set(&pService->szPrintcommand, "vlp print %p %s");
1275		string_set(&pService->szLpqcommand, "vlp lpq %p");
1276		string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1277		string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1278		string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1279		string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1280		string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1281		break;
1282#endif /* DEVELOPER */
1283
1284	}
1285}
1286
1287/***************************************************************************
1288 Initialise the global parameter structure.
1289***************************************************************************/
1290
1291static void init_globals(void)
1292{
1293	static BOOL done_init = False;
1294	pstring s;
1295
1296	if (!done_init) {
1297		int i;
1298
1299		/* The logfile can be set before this is invoked. Free it if so. */
1300		if (Globals.szLogFile != NULL) {
1301			string_free(&Globals.szLogFile);
1302			Globals.szLogFile = NULL;
1303		}
1304
1305		memset((void *)&Globals, '\0', sizeof(Globals));
1306
1307		for (i = 0; parm_table[i].label; i++)
1308			if ((parm_table[i].type == P_STRING ||
1309			     parm_table[i].type == P_USTRING) &&
1310			    parm_table[i].ptr)
1311				string_set(parm_table[i].ptr, "");
1312
1313		string_set(&sDefault.fstype, FSTYPE_STRING);
1314
1315		init_printer_values(&sDefault);
1316
1317		done_init = True;
1318	}
1319
1320
1321	DEBUG(3, ("Initialising global parameters\n"));
1322
1323	string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1324	string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1325
1326	/* use the new 'hash2' method by default, with a prefix of 1 */
1327	string_set(&Globals.szManglingMethod, "hash2");
1328	Globals.mangle_prefix = 1;
1329
1330	string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1331
1332	/* using UTF8 by default allows us to support all chars */
1333	string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1334
1335#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1336	/* If the system supports nl_langinfo(), try to grab the value
1337	   from the user's locale */
1338	string_set(&Globals.display_charset, "LOCALE");
1339#else
1340	string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1341#endif
1342
1343	/* Use codepage 850 as a default for the dos character set */
1344	string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1345
1346	/*
1347	 * Allow the default PASSWD_CHAT to be overridden in local.h.
1348	 */
1349	string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1350
1351	set_global_myname(myhostname());
1352	string_set(&Globals.szNetbiosName,global_myname());
1353
1354	set_global_myworkgroup(WORKGROUP);
1355	string_set(&Globals.szWorkgroup, lp_workgroup());
1356
1357	string_set(&Globals.szPasswdProgram, "");
1358	string_set(&Globals.szPidDir, dyn_PIDDIR);
1359	string_set(&Globals.szLockDir, dyn_LOCKDIR);
1360	string_set(&Globals.szSocketAddress, "0.0.0.0");
1361	pstrcpy(s, "Samba ");
1362	pstrcat(s, SAMBA_VERSION_STRING);
1363	string_set(&Globals.szServerString, s);
1364	slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1365		 DEFAULT_MINOR_VERSION);
1366	string_set(&Globals.szAnnounceVersion, s);
1367
1368	pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1369
1370	string_set(&Globals.szLogonDrive, "");
1371	/* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1372	string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1373	string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1374
1375	string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1376	string_set(&Globals.szPasswordServer, "*");
1377
1378	Globals.AlgorithmicRidBase = BASE_RID;
1379
1380	Globals.bLoadPrinters = True;
1381	Globals.PrintcapCacheTime = 0;
1382	/* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1383	/* Discovered by 2 days of pain by Don McCall @ HP :-). */
1384	//Globals.max_xmit = 0x4104;
1385	Globals.max_xmit = 0xffff; /* wklin modified */
1386	Globals.max_mux = 50;	/* This is *needed* for profile support. */
1387	Globals.lpqcachetime = 30;	/* changed to handle large print servers better -- jerry */
1388	Globals.bDisableSpoolss = False;
1389	Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1390	Globals.pwordlevel = 0;
1391	Globals.unamelevel = 0;
1392	Globals.deadtime = 0;
1393	Globals.bLargeReadwrite = True;
1394	Globals.max_log_size = 5000;
1395	Globals.max_open_files = MAX_OPEN_FILES;
1396	Globals.maxprotocol = PROTOCOL_NT1;
1397	Globals.minprotocol = PROTOCOL_CORE;
1398	Globals.security = SEC_USER;
1399	Globals.paranoid_server_security = True;
1400	Globals.bEncryptPasswords = True;
1401	Globals.bUpdateEncrypt = False;
1402	Globals.clientSchannel = Auto;
1403	Globals.serverSchannel = Auto;
1404	Globals.bReadRaw = True;
1405	Globals.bWriteRaw = True;
1406	Globals.bReadbmpx = False;
1407	Globals.bNullPasswords = False;
1408	Globals.bObeyPamRestrictions = False;
1409	Globals.syslog = 1;
1410	Globals.bSyslogOnly = False;
1411	Globals.bTimestampLogs = True;
1412	string_set(&Globals.szLogLevel, "0");
1413	Globals.bDebugHiresTimestamp = False;
1414	Globals.bDebugPid = False;
1415	Globals.bDebugUid = False;
1416	Globals.max_ttl = 60 * 60 * 24 * 3;	/* 3 days default. */
1417	Globals.max_wins_ttl = 60 * 60 * 24 * 6;	/* 6 days default. */
1418	Globals.min_wins_ttl = 60 * 60 * 6;	/* 6 hours default. */
1419	Globals.machine_password_timeout = 60 * 60 * 24 * 7;	/* 7 days default. */
1420	Globals.change_notify_timeout = 60;	/* 1 minute default. */
1421	Globals.bKernelChangeNotify = True;	/* On if we have it. */
1422	Globals.lm_announce = 2;	/* = Auto: send only if LM clients found */
1423	Globals.lm_interval = 60;
1424	Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1425#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1426	Globals.bNISHomeMap = False;
1427#ifdef WITH_NISPLUS_HOME
1428	string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1429#else
1430	string_set(&Globals.szNISHomeMapName, "auto.home");
1431#endif
1432#endif
1433	Globals.bTimeServer = False;
1434	Globals.bBindInterfacesOnly = False;
1435	Globals.bUnixPasswdSync = False;
1436	Globals.bPamPasswordChange = False;
1437	Globals.bPasswdChatDebug = False;
1438	Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1439	Globals.bNTPipeSupport = True;	/* Do NT pipes by default. */
1440	Globals.bNTStatusSupport = True; /* Use NT status by default. */
1441	Globals.bStatCache = True;	/* use stat cache by default */
1442	Globals.restrict_anonymous = 0;
1443	Globals.bClientLanManAuth = True;	/* Do use the LanMan hash if it is available */
1444	Globals.bClientPlaintextAuth = True;	/* Do use a plaintext password if is requested by the server */
1445	Globals.bLanmanAuth = True;	/* Do use the LanMan hash if it is available */
1446	Globals.bNTLMAuth = True;	/* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1447	Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1448	/* Note, that we will use NTLM2 session security (which is different), if it is available */
1449
1450	Globals.map_to_guest = 0;	/* By Default, "Never" */
1451	Globals.min_passwd_length = MINPASSWDLENGTH;	/* By Default, 5. */
1452	Globals.oplock_break_wait_time = 0;	/* By Default, 0 msecs. */
1453	Globals.enhanced_browsing = True;
1454	Globals.iLockSpinCount = 3; /* Try 3 times. */
1455	Globals.iLockSpinTime = 10; /* usec. */
1456#ifdef MMAP_BLACKLIST
1457	Globals.bUseMmap = False;
1458#else
1459	Globals.bUseMmap = True;
1460#endif
1461	Globals.bUnixExtensions = True;
1462
1463	/* hostname lookups can be very expensive and are broken on
1464	   a large number of sites (tridge) */
1465	Globals.bHostnameLookups = False;
1466
1467	str_list_free(&Globals.szPassdbBackend);
1468#ifdef WITH_LDAP_SAMCONFIG
1469	string_set(&Globals.szLdapServer, "localhost");
1470	Globals.ldap_port = 636;
1471	Globals.szPassdbBackend = str_list_make("ldapsam_compat", NULL);
1472#else
1473	Globals.szPassdbBackend = str_list_make("smbpasswd", NULL);
1474#endif /* WITH_LDAP_SAMCONFIG */
1475
1476	string_set(&Globals.szLdapSuffix, "");
1477	string_set(&Globals.szLdapFilter, "(uid=%u)");
1478	string_set(&Globals.szLdapMachineSuffix, "");
1479	string_set(&Globals.szLdapUserSuffix, "");
1480	string_set(&Globals.szLdapGroupSuffix, "");
1481	string_set(&Globals.szLdapIdmapSuffix, "");
1482
1483	string_set(&Globals.szLdapAdminDn, "");
1484	Globals.ldap_ssl = LDAP_SSL_ON;
1485	Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1486	Globals.ldap_delete_dn = False;
1487	Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1488	Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1489
1490	/* This is what we tell the afs client. in reality we set the token
1491	 * to never expire, though, when this runs out the afs client will
1492	 * forget the token. Set to 0 to get NEVERDATE.*/
1493	Globals.iAfsTokenLifetime = 604800;
1494
1495/* these parameters are set to defaults that are more appropriate
1496   for the increasing samba install base:
1497
1498   as a member of the workgroup, that will possibly become a
1499   _local_ master browser (lm = True).  this is opposed to a forced
1500   local master browser startup (pm = True).
1501
1502   doesn't provide WINS server service by default (wsupp = False),
1503   and doesn't provide domain master browser services by default, either.
1504
1505*/
1506
1507	Globals.bMsAddPrinterWizard = True;
1508	Globals.bPreferredMaster = Auto;	/* depending on bDomainMaster */
1509	Globals.os_level = 20;
1510	Globals.bLocalMaster = True;
1511	Globals.bDomainMaster = Auto;	/* depending on bDomainLogons */
1512	Globals.bDomainLogons = False;
1513	Globals.bBrowseList = True;
1514	Globals.bWINSsupport = False;
1515	Globals.bWINSproxy = False;
1516
1517	Globals.bDNSproxy = True;
1518
1519	/* this just means to use them if they exist */
1520	Globals.bKernelOplocks = True;
1521
1522	Globals.bAllowTrustedDomains = True;
1523
1524	string_set(&Globals.szTemplateShell, "/bin/false");
1525	string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1526	string_set(&Globals.szTemplatePrimaryGroup, "nobody");
1527	string_set(&Globals.szWinbindSeparator, "\\");
1528	string_set(&Globals.szAclCompat, "");
1529	string_set(&Globals.szCupsServer, "");
1530
1531	Globals.winbind_cache_time = 300;	/* 5 minutes */
1532	Globals.bWinbindEnableLocalAccounts = False;
1533	Globals.bWinbindEnumUsers = True;
1534	Globals.bWinbindEnumGroups = True;
1535	Globals.bWinbindUseDefaultDomain = False;
1536	Globals.bWinbindTrustedDomainsOnly = False;
1537	Globals.bWinbindNestedGroups = False;
1538
1539	Globals.bEnableRidAlgorithm = True;
1540
1541	Globals.name_cache_timeout = 660; /* In seconds */
1542
1543	Globals.bUseSpnego = True;
1544	Globals.bClientUseSpnego = True;
1545
1546	Globals.client_signing = Auto;
1547	Globals.server_signing = False;
1548
1549	Globals.bDeferSharingViolations = True;
1550	string_set(&Globals.smb_ports, SMB_PORTS);
1551
1552	/* don't enable privileges by default since Domain
1553	   Admins can then assign thr rights to perform certain
1554	   operations as root */
1555
1556	Globals.bEnablePrivileges = False;
1557}
1558
1559static TALLOC_CTX *lp_talloc;
1560
1561/******************************************************************* a
1562 Free up temporary memory - called from the main loop.
1563********************************************************************/
1564
1565void lp_talloc_free(void)
1566{
1567	if (!lp_talloc)
1568		return;
1569	talloc_destroy(lp_talloc);
1570	lp_talloc = NULL;
1571}
1572
1573/*******************************************************************
1574 Convenience routine to grab string parameters into temporary memory
1575 and run standard_sub_basic on them. The buffers can be written to by
1576 callers without affecting the source string.
1577********************************************************************/
1578
1579static char *lp_string(const char *s)
1580{
1581	char *ret, *tmpstr;
1582
1583	/* The follow debug is useful for tracking down memory problems
1584	   especially if you have an inner loop that is calling a lp_*()
1585	   function that returns a string.  Perhaps this debug should be
1586	   present all the time? */
1587
1588#if 0
1589	DEBUG(10, ("lp_string(%s)\n", s));
1590#endif
1591
1592	if (!lp_talloc)
1593		lp_talloc = talloc_init("lp_talloc");
1594
1595	tmpstr = alloc_sub_basic(get_current_username(), s);
1596	if (trim_char(tmpstr, '\"', '\"')) {
1597		if (strchr(tmpstr,'\"') != NULL) {
1598			SAFE_FREE(tmpstr);
1599			tmpstr = alloc_sub_basic(get_current_username(),s);
1600		}
1601	}
1602	ret = talloc_strdup(lp_talloc, tmpstr);
1603	SAFE_FREE(tmpstr);
1604
1605	return (ret);
1606}
1607
1608/*
1609   In this section all the functions that are used to access the
1610   parameters from the rest of the program are defined
1611*/
1612
1613#define FN_GLOBAL_STRING(fn_name,ptr) \
1614 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1615#define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1616 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1617#define FN_GLOBAL_LIST(fn_name,ptr) \
1618 const char **fn_name(void) {return(*(const char ***)(ptr));}
1619#define FN_GLOBAL_BOOL(fn_name,ptr) \
1620 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1621#define FN_GLOBAL_CHAR(fn_name,ptr) \
1622 char fn_name(void) {return(*(char *)(ptr));}
1623#define FN_GLOBAL_INTEGER(fn_name,ptr) \
1624 int fn_name(void) {return(*(int *)(ptr));}
1625
1626#define FN_LOCAL_STRING(fn_name,val) \
1627 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1628#define FN_LOCAL_CONST_STRING(fn_name,val) \
1629 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1630#define FN_LOCAL_LIST(fn_name,val) \
1631 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1632#define FN_LOCAL_BOOL(fn_name,val) \
1633 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1634#define FN_LOCAL_CHAR(fn_name,val) \
1635 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1636#define FN_LOCAL_INTEGER(fn_name,val) \
1637 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1638
1639FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1640FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1641FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1642FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1643FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1644FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1645FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1646FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1647FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1648FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1649FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1650FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1651FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1652FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1653FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1654FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1655FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1656FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1657FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1658FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1659FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1660FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1661FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1662FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1663FN_GLOBAL_STRING(lp_dfree_command, &Globals.szDfree)
1664FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1665FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1666FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1667FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1668FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1669FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1670FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1671FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1672FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1673FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1674FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1675FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1676FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1677FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1678FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1679FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1680FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1681FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1682FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1683FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1684FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1685FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1686FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1687static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1688FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1689FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
1690FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1691FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1692FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1693FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1694
1695FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1696FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1697FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1698FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1699FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1700FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1701
1702FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1703
1704FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1705FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1706
1707FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1708
1709FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1710FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1711FN_GLOBAL_STRING(lp_template_primary_group, &Globals.szTemplatePrimaryGroup)
1712FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1713FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1714FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1715FN_GLOBAL_STRING(lp_acl_compatibility, &Globals.szAclCompat)
1716FN_GLOBAL_BOOL(lp_winbind_enable_local_accounts, &Globals.bWinbindEnableLocalAccounts)
1717FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1718FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1719FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1720FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1721FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1722
1723FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend)
1724FN_GLOBAL_BOOL(lp_enable_rid_algorithm, &Globals.bEnableRidAlgorithm)
1725
1726#ifdef WITH_LDAP_SAMCONFIG
1727FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
1728FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
1729#endif
1730FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1731FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
1732FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1733FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1734FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1735FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1736FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1737FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1738FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1739FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1740FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1741
1742FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1743FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1744FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1745FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1746FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1747FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1748FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1749FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1750FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1751FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1752FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1753FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1754FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1755FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1756FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1757FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1758FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1759FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1760FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1761FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1762FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1763FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1764FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1765FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1766FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1767FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1768static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1769FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1770FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1771FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1772FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1773FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1774FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1775FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1776FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1777FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1778FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1779FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1780FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1781FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1782FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1783FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1784FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1785FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1786FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1787FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1788FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1789FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1790FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1791FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1792FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
1793FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
1794FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
1795FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
1796FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1797FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1798FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1799FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1800FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
1801FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
1802FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
1803FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1804FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1805FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1806FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
1807FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1808FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1809FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1810FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1811FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1812FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
1813FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1814FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
1815FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1816FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
1817static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1818FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1819FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1820FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1821FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout)
1822FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
1823FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length)
1824FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1825FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1826FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1827FN_LOCAL_STRING(lp_preexec, szPreExec)
1828FN_LOCAL_STRING(lp_postexec, szPostExec)
1829FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
1830FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
1831FN_LOCAL_STRING(lp_servicename, szService)
1832FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1833FN_LOCAL_STRING(lp_pathname, szPath)
1834FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
1835FN_LOCAL_STRING(lp_username, szUsername)
1836FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1837FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1838FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1839FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
1840FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
1841FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1842FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1843FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1844FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1845FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1846FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1847FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1848static FN_LOCAL_STRING(_lp_printername, szPrintername)
1849FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1850FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1851FN_LOCAL_STRING(lp_magicscript, szMagicScript)
1852FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
1853FN_LOCAL_STRING(lp_comment, comment)
1854FN_LOCAL_STRING(lp_force_user, force_user)
1855FN_LOCAL_STRING(lp_force_group, force_group)
1856FN_LOCAL_LIST(lp_readlist, readlist)
1857FN_LOCAL_LIST(lp_writelist, writelist)
1858FN_LOCAL_LIST(lp_printer_admin, printer_admin)
1859FN_LOCAL_STRING(lp_fstype, fstype)
1860FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
1861FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1862static FN_LOCAL_STRING(lp_volume, volume)
1863FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
1864FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
1865FN_LOCAL_STRING(lp_hide_files, szHideFiles)
1866FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
1867FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1868FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1869FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
1870FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
1871FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
1872FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
1873FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
1874FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
1875FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
1876FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
1877FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
1878FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1879FN_LOCAL_BOOL(lp_readonly, bRead_only)
1880FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
1881FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1882FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1883FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1884FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1885FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1886FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
1887FN_LOCAL_BOOL(lp_locking, bLocking)
1888FN_LOCAL_INTEGER(lp_strict_locking, iStrictLocking)
1889FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1890FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1891FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1892FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1893FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1894FN_LOCAL_BOOL(lp_manglednames, bMangledNames)
1895FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
1896FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
1897FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
1898FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
1899FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1900FN_LOCAL_BOOL(lp_map_system, bMap_system)
1901FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
1902FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
1903FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
1904FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
1905FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
1906FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
1907FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
1908FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
1909FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
1910FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
1911FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
1912FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
1913FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
1914FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
1915FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
1916FN_LOCAL_BOOL(lp_ea_support, bEASupport)
1917FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
1918FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
1919FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
1920FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
1921FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
1922FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
1923FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
1924FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
1925FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
1926FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
1927FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
1928FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
1929FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1930FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
1931FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1932FN_LOCAL_INTEGER(lp_printing, iPrinting)
1933FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
1934FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
1935FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1936FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
1937FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
1938FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size);
1939FN_LOCAL_CHAR(lp_magicchar, magic_char)
1940FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1941FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
1942FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1943FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1944FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1945
1946/* local prototypes */
1947
1948static int map_parameter(const char *pszParmName);
1949static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1950static int getservicebyname(const char *pszServiceName,
1951			    service * pserviceDest);
1952static void copy_service(service * pserviceDest,
1953			 service * pserviceSource, BOOL *pcopymapDest);
1954static BOOL service_ok(int iService);
1955static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
1956static BOOL do_section(const char *pszSectionName);
1957static void init_copymap(service * pservice);
1958
1959/* This is a helper function for parametrical options support. */
1960/* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1961/* Actual parametrical functions are quite simple */
1962static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
1963{
1964	BOOL global_section = False;
1965	char* param_key;
1966        param_opt_struct *data;
1967
1968	if (snum >= iNumServices) return NULL;
1969
1970	if (snum < 0) {
1971		data = Globals.param_opt;
1972		global_section = True;
1973	} else {
1974		data = ServicePtrs[snum]->param_opt;
1975	}
1976
1977	asprintf(&param_key, "%s:%s", type, option);
1978	if (!param_key) {
1979		DEBUG(0,("asprintf failed!\n"));
1980		return NULL;
1981	}
1982
1983	while (data) {
1984		if (strcmp(data->key, param_key) == 0) {
1985			string_free(&param_key);
1986			return data;
1987		}
1988		data = data->next;
1989	}
1990
1991	if (!global_section) {
1992		/* Try to fetch the same option but from globals */
1993		/* but only if we are not already working with Globals */
1994		data = Globals.param_opt;
1995		while (data) {
1996		        if (strcmp(data->key, param_key) == 0) {
1997			        string_free(&param_key);
1998				return data;
1999			}
2000			data = data->next;
2001		}
2002	}
2003
2004	string_free(&param_key);
2005
2006	return NULL;
2007}
2008
2009
2010/*******************************************************************
2011convenience routine to return int parameters.
2012********************************************************************/
2013static int lp_int(const char *s)
2014{
2015
2016	if (!s) {
2017		DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
2018		return (-1);
2019	}
2020
2021	return atoi(s);
2022}
2023
2024/*******************************************************************
2025convenience routine to return unsigned long parameters.
2026********************************************************************/
2027static int lp_ulong(const char *s)
2028{
2029
2030	if (!s) {
2031		DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
2032		return (-1);
2033	}
2034
2035	return strtoul(s, NULL, 10);
2036}
2037
2038/*******************************************************************
2039convenience routine to return boolean parameters.
2040********************************************************************/
2041static BOOL lp_bool(const char *s)
2042{
2043	BOOL ret = False;
2044
2045	if (!s) {
2046		DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
2047		return False;
2048	}
2049
2050	if (!set_boolean(&ret,s)) {
2051		DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2052		return False;
2053	}
2054
2055	return ret;
2056}
2057
2058/*******************************************************************
2059convenience routine to return enum parameters.
2060********************************************************************/
2061static int lp_enum(const char *s,const struct enum_list *_enum)
2062{
2063	int i;
2064
2065	if (!s || !_enum) {
2066		DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
2067		return (-1);
2068	}
2069
2070	for (i=0; _enum[i].name; i++) {
2071		if (strequal(_enum[i].name,s))
2072			return _enum[i].value;
2073	}
2074
2075	DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2076	return (-1);
2077}
2078
2079
2080/* DO NOT USE lp_parm_string ANYMORE!!!!
2081 * use lp_parm_const_string or lp_parm_talloc_string
2082 *
2083 * lp_parm_string is only used to let old modules find this symbol
2084 */
2085#undef lp_parm_string
2086 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2087{
2088	return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2089}
2090
2091/* Return parametric option from a given service. Type is a part of option before ':' */
2092/* Parametric option has following syntax: 'Type: option = value' */
2093/* the returned value is talloced in lp_talloc */
2094char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2095{
2096	param_opt_struct *data = get_parametrics(snum, type, option);
2097
2098	if (data == NULL||data->value==NULL) {
2099		if (def) {
2100			return lp_string(def);
2101		} else {
2102			return NULL;
2103		}
2104	}
2105
2106	return lp_string(data->value);
2107}
2108
2109/* Return parametric option from a given service. Type is a part of option before ':' */
2110/* Parametric option has following syntax: 'Type: option = value' */
2111const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2112{
2113	param_opt_struct *data = get_parametrics(snum, type, option);
2114
2115	if (data == NULL||data->value==NULL)
2116		return def;
2117
2118	return data->value;
2119}
2120
2121/* Return parametric option from a given service. Type is a part of option before ':' */
2122/* Parametric option has following syntax: 'Type: option = value' */
2123
2124const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2125{
2126	param_opt_struct *data = get_parametrics(snum, type, option);
2127
2128	if (data == NULL||data->value==NULL)
2129		return (const char **)def;
2130
2131	if (data->list==NULL) {
2132		data->list = str_list_make(data->value, NULL);
2133	}
2134
2135	return (const char **)data->list;
2136}
2137
2138/* Return parametric option from a given service. Type is a part of option before ':' */
2139/* Parametric option has following syntax: 'Type: option = value' */
2140
2141int lp_parm_int(int snum, const char *type, const char *option, int def)
2142{
2143	param_opt_struct *data = get_parametrics(snum, type, option);
2144
2145	if (data && data->value && *data->value)
2146		return lp_int(data->value);
2147
2148	return def;
2149}
2150
2151/* Return parametric option from a given service. Type is a part of option before ':' */
2152/* Parametric option has following syntax: 'Type: option = value' */
2153
2154unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2155{
2156	param_opt_struct *data = get_parametrics(snum, type, option);
2157
2158	if (data && data->value && *data->value)
2159		return lp_ulong(data->value);
2160
2161	return def;
2162}
2163
2164/* Return parametric option from a given service. Type is a part of option before ':' */
2165/* Parametric option has following syntax: 'Type: option = value' */
2166
2167BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2168{
2169	param_opt_struct *data = get_parametrics(snum, type, option);
2170
2171	if (data && data->value && *data->value)
2172		return lp_bool(data->value);
2173
2174	return def;
2175}
2176
2177/* Return parametric option from a given service. Type is a part of option before ':' */
2178/* Parametric option has following syntax: 'Type: option = value' */
2179
2180int lp_parm_enum(int snum, const char *type, const char *option,
2181		 const struct enum_list *_enum, int def)
2182{
2183	param_opt_struct *data = get_parametrics(snum, type, option);
2184
2185	if (data && data->value && *data->value && _enum)
2186		return lp_enum(data->value, _enum);
2187
2188	return def;
2189}
2190
2191
2192/***************************************************************************
2193 Initialise a service to the defaults.
2194***************************************************************************/
2195
2196static void init_service(service * pservice)
2197{
2198	memset((char *)pservice, '\0', sizeof(service));
2199	copy_service(pservice, &sDefault, NULL);
2200}
2201
2202/***************************************************************************
2203 Free the dynamically allocated parts of a service struct.
2204***************************************************************************/
2205
2206static void free_service(service *pservice)
2207{
2208	int i;
2209        param_opt_struct *data, *pdata;
2210	if (!pservice)
2211		return;
2212
2213	if (pservice->szService)
2214		DEBUG(5, ("free_service: Freeing service %s\n",
2215		       pservice->szService));
2216
2217	string_free(&pservice->szService);
2218	SAFE_FREE(pservice->copymap);
2219
2220	for (i = 0; parm_table[i].label; i++) {
2221		if ((parm_table[i].type == P_STRING ||
2222		     parm_table[i].type == P_USTRING) &&
2223		    parm_table[i].class == P_LOCAL)
2224			string_free((char **)
2225				    (((char *)pservice) +
2226				     PTR_DIFF(parm_table[i].ptr, &sDefault)));
2227		else if (parm_table[i].type == P_LIST &&
2228			 parm_table[i].class == P_LOCAL)
2229			     str_list_free((char ***)
2230			     		    (((char *)pservice) +
2231					     PTR_DIFF(parm_table[i].ptr, &sDefault)));
2232	}
2233
2234	data = pservice->param_opt;
2235	if (data)
2236		DEBUG(5,("Freeing parametrics:\n"));
2237	while (data) {
2238		DEBUG(5,("[%s = %s]\n", data->key, data->value));
2239		string_free(&data->key);
2240		string_free(&data->value);
2241		str_list_free(&data->list);
2242		pdata = data->next;
2243		SAFE_FREE(data);
2244		data = pdata;
2245	}
2246
2247	ZERO_STRUCTP(pservice);
2248}
2249
2250/***************************************************************************
2251 Add a new service to the services array initialising it with the given
2252 service.
2253***************************************************************************/
2254
2255static int add_a_service(const service *pservice, const char *name)
2256{
2257	int i;
2258	service tservice;
2259	int num_to_alloc = iNumServices + 1;
2260	param_opt_struct *data, *pdata;
2261
2262	tservice = *pservice;
2263
2264	/* it might already exist */
2265	if (name) {
2266		i = getservicebyname(name, NULL);
2267		if (i >= 0) {
2268			/* Clean all parametric options for service */
2269			/* They will be added during parsing again */
2270			data = ServicePtrs[i]->param_opt;
2271			while (data) {
2272				string_free(&data->key);
2273				string_free(&data->value);
2274				str_list_free(&data->list);
2275				pdata = data->next;
2276				SAFE_FREE(data);
2277				data = pdata;
2278			}
2279			ServicePtrs[i]->param_opt = NULL;
2280			return (i);
2281		}
2282	}
2283
2284	/* find an invalid one */
2285	for (i = 0; i < iNumServices; i++)
2286		if (!ServicePtrs[i]->valid)
2287			break;
2288
2289	/* if not, then create one */
2290	if (i == iNumServices) {
2291		service **tsp;
2292
2293		tsp = SMB_REALLOC_ARRAY(ServicePtrs, service *, num_to_alloc);
2294
2295		if (!tsp) {
2296			DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2297			return (-1);
2298		}
2299		else {
2300			ServicePtrs = tsp;
2301			ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2302		}
2303		if (!ServicePtrs[iNumServices]) {
2304			DEBUG(0,("add_a_service: out of memory!\n"));
2305			return (-1);
2306		}
2307
2308		iNumServices++;
2309	} else
2310		free_service(ServicePtrs[i]);
2311
2312	ServicePtrs[i]->valid = True;
2313
2314	init_service(ServicePtrs[i]);
2315	copy_service(ServicePtrs[i], &tservice, NULL);
2316	if (name)
2317		string_set(&ServicePtrs[i]->szService, name);
2318
2319	DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2320		i, ServicePtrs[i]->szService));
2321
2322	return (i);
2323}
2324
2325/***************************************************************************
2326 Add a new home service, with the specified home directory, defaults coming
2327 from service ifrom.
2328***************************************************************************/
2329
2330BOOL lp_add_home(const char *pszHomename, int iDefaultService,
2331		 const char *user, const char *pszHomedir)
2332{
2333	int i;
2334	pstring newHomedir;
2335
2336	i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2337
2338	if (i < 0)
2339		return (False);
2340
2341	if (!(*(ServicePtrs[iDefaultService]->szPath))
2342	    || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2343		pstrcpy(newHomedir, pszHomedir);
2344		string_set(&ServicePtrs[i]->szPath, newHomedir);
2345	}
2346
2347	if (!(*(ServicePtrs[i]->comment))) {
2348		pstring comment;
2349		slprintf(comment, sizeof(comment) - 1,
2350			 "Home directory of %s", user);
2351		string_set(&ServicePtrs[i]->comment, comment);
2352	}
2353
2354	/* set the browseable flag from the gloabl default */
2355
2356	ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2357
2358	ServicePtrs[i]->autoloaded = True;
2359
2360	DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2361	       user, ServicePtrs[i]->szPath ));
2362
2363	return (True);
2364}
2365
2366/***************************************************************************
2367 Add a new service, based on an old one.
2368***************************************************************************/
2369
2370int lp_add_service(const char *pszService, int iDefaultService)
2371{
2372	return (add_a_service(ServicePtrs[iDefaultService], pszService));
2373}
2374
2375/***************************************************************************
2376 Add the IPC service.
2377***************************************************************************/
2378
2379static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2380{
2381	pstring comment;
2382	int i = add_a_service(&sDefault, ipc_name);
2383
2384	if (i < 0)
2385		return (False);
2386
2387	slprintf(comment, sizeof(comment) - 1,
2388		 "IPC Service (%s)", Globals.szServerString);
2389
2390	string_set(&ServicePtrs[i]->szPath, tmpdir());
2391	string_set(&ServicePtrs[i]->szUsername, "");
2392	string_set(&ServicePtrs[i]->comment, comment);
2393	string_set(&ServicePtrs[i]->fstype, "IPC");
2394	ServicePtrs[i]->iMaxConnections = 0;
2395	ServicePtrs[i]->bAvailable = True;
2396	ServicePtrs[i]->bRead_only = True;
2397	ServicePtrs[i]->bGuest_only = False;
2398	ServicePtrs[i]->bGuest_ok = guest_ok;
2399	ServicePtrs[i]->bPrint_ok = False;
2400	ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2401
2402	DEBUG(3, ("adding IPC service\n"));
2403
2404	return (True);
2405}
2406
2407/***************************************************************************
2408 Add a new printer service, with defaults coming from service iFrom.
2409***************************************************************************/
2410
2411BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2412{
2413	const char *comment = "From Printcap";
2414	int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2415
2416	if (i < 0)
2417		return (False);
2418
2419	/* note that we do NOT default the availability flag to True - */
2420	/* we take it from the default service passed. This allows all */
2421	/* dynamic printers to be disabled by disabling the [printers] */
2422	/* entry (if/when the 'available' keyword is implemented!).    */
2423
2424	/* the printer name is set to the service name. */
2425	string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2426	string_set(&ServicePtrs[i]->comment, comment);
2427
2428	/* set the browseable flag from the gloabl default */
2429	ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2430
2431	/* Printers cannot be read_only. */
2432	ServicePtrs[i]->bRead_only = False;
2433	/* No share modes on printer services. */
2434	ServicePtrs[i]->bShareModes = False;
2435	/* No oplocks on printer services. */
2436	ServicePtrs[i]->bOpLocks = False;
2437	/* Printer services must be printable. */
2438	ServicePtrs[i]->bPrint_ok = True;
2439
2440	DEBUG(3, ("adding printer service %s\n", pszPrintername));
2441
2442	return (True);
2443}
2444
2445/***************************************************************************
2446 Map a parameter's string representation to something we can use.
2447 Returns False if the parameter string is not recognised, else TRUE.
2448***************************************************************************/
2449
2450static int map_parameter(const char *pszParmName)
2451{
2452	int iIndex;
2453
2454	if (*pszParmName == '-')
2455		return (-1);
2456
2457	for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2458		if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2459			return (iIndex);
2460
2461	/* Warn only if it isn't parametric option */
2462	if (strchr(pszParmName, ':') == NULL)
2463		DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2464	/* We do return 'fail' for parametric options as well because they are
2465	   stored in different storage
2466	 */
2467	return (-1);
2468}
2469
2470/***************************************************************************
2471 Set a boolean variable from the text value stored in the passed string.
2472 Returns True in success, False if the passed string does not correctly
2473 represent a boolean.
2474***************************************************************************/
2475
2476static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2477{
2478	BOOL bRetval;
2479
2480	bRetval = True;
2481	if (strwicmp(pszParmValue, "yes") == 0 ||
2482	    strwicmp(pszParmValue, "true") == 0 ||
2483	    strwicmp(pszParmValue, "1") == 0)
2484		*pb = True;
2485	else if (strwicmp(pszParmValue, "no") == 0 ||
2486		    strwicmp(pszParmValue, "False") == 0 ||
2487		    strwicmp(pszParmValue, "0") == 0)
2488		*pb = False;
2489	else {
2490		DEBUG(0,
2491		      ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2492		       pszParmValue));
2493		bRetval = False;
2494	}
2495	return (bRetval);
2496}
2497
2498/***************************************************************************
2499Find a service by name. Otherwise works like get_service.
2500***************************************************************************/
2501
2502static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2503{
2504	int iService;
2505
2506	for (iService = iNumServices - 1; iService >= 0; iService--)
2507		if (VALID(iService) &&
2508		    strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
2509			if (pserviceDest != NULL)
2510				copy_service(pserviceDest, ServicePtrs[iService], NULL);
2511			break;
2512		}
2513
2514	return (iService);
2515}
2516
2517/***************************************************************************
2518 Copy a service structure to another.
2519 If pcopymapDest is NULL then copy all fields
2520***************************************************************************/
2521
2522static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2523{
2524	int i;
2525	BOOL bcopyall = (pcopymapDest == NULL);
2526	param_opt_struct *data, *pdata, *paramo;
2527	BOOL not_added;
2528
2529	for (i = 0; parm_table[i].label; i++)
2530		if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
2531		    (bcopyall || pcopymapDest[i])) {
2532			void *def_ptr = parm_table[i].ptr;
2533			void *src_ptr =
2534				((char *)pserviceSource) + PTR_DIFF(def_ptr,
2535								    &sDefault);
2536			void *dest_ptr =
2537				((char *)pserviceDest) + PTR_DIFF(def_ptr,
2538								  &sDefault);
2539
2540			switch (parm_table[i].type) {
2541				case P_BOOL:
2542				case P_BOOLREV:
2543					*(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2544					break;
2545
2546				case P_INTEGER:
2547				case P_ENUM:
2548				case P_OCTAL:
2549					*(int *)dest_ptr = *(int *)src_ptr;
2550					break;
2551
2552				case P_CHAR:
2553					*(char *)dest_ptr = *(char *)src_ptr;
2554					break;
2555
2556				case P_STRING:
2557					string_set(dest_ptr,
2558						   *(char **)src_ptr);
2559					break;
2560
2561				case P_USTRING:
2562					string_set(dest_ptr,
2563						   *(char **)src_ptr);
2564					strupper_m(*(char **)dest_ptr);
2565					break;
2566				case P_LIST:
2567					str_list_free((char ***)dest_ptr);
2568					str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2569					break;
2570				default:
2571					break;
2572			}
2573		}
2574
2575	if (bcopyall) {
2576		init_copymap(pserviceDest);
2577		if (pserviceSource->copymap)
2578			memcpy((void *)pserviceDest->copymap,
2579			       (void *)pserviceSource->copymap,
2580			       sizeof(BOOL) * NUMPARAMETERS);
2581	}
2582
2583	data = pserviceSource->param_opt;
2584	while (data) {
2585		not_added = True;
2586		pdata = pserviceDest->param_opt;
2587		/* Traverse destination */
2588		while (pdata) {
2589			/* If we already have same option, override it */
2590			if (strcmp(pdata->key, data->key) == 0) {
2591				string_free(&pdata->value);
2592				str_list_free(&data->list);
2593				pdata->value = SMB_STRDUP(data->value);
2594				not_added = False;
2595				break;
2596			}
2597			pdata = pdata->next;
2598		}
2599		if (not_added) {
2600		    paramo = SMB_XMALLOC_P(param_opt_struct);
2601		    paramo->key = SMB_STRDUP(data->key);
2602		    paramo->value = SMB_STRDUP(data->value);
2603		    paramo->list = NULL;
2604		    DLIST_ADD(pserviceDest->param_opt, paramo);
2605		}
2606		data = data->next;
2607	}
2608}
2609
2610/***************************************************************************
2611Check a service for consistency. Return False if the service is in any way
2612incomplete or faulty, else True.
2613***************************************************************************/
2614
2615static BOOL service_ok(int iService)
2616{
2617	BOOL bRetval;
2618
2619	bRetval = True;
2620	if (ServicePtrs[iService]->szService[0] == '\0') {
2621		DEBUG(0, ("The following message indicates an internal error:\n"));
2622		DEBUG(0, ("No service name in service entry.\n"));
2623		bRetval = False;
2624	}
2625
2626	/* The [printers] entry MUST be printable. I'm all for flexibility, but */
2627	/* I can't see why you'd want a non-printable printer service...        */
2628	if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2629		if (!ServicePtrs[iService]->bPrint_ok) {
2630			DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2631			       ServicePtrs[iService]->szService));
2632			ServicePtrs[iService]->bPrint_ok = True;
2633		}
2634		/* [printers] service must also be non-browsable. */
2635		if (ServicePtrs[iService]->bBrowseable)
2636			ServicePtrs[iService]->bBrowseable = False;
2637	}
2638
2639	if (ServicePtrs[iService]->szPath[0] == '\0' &&
2640	    strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) {
2641		DEBUG(0, ("No path in service %s - using %s\n",
2642		       ServicePtrs[iService]->szService, tmpdir()));
2643		string_set(&ServicePtrs[iService]->szPath, tmpdir());
2644	}
2645
2646	/* If a service is flagged unavailable, log the fact at level 0. */
2647	if (!ServicePtrs[iService]->bAvailable)
2648		DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2649			  ServicePtrs[iService]->szService));
2650
2651	return (bRetval);
2652}
2653
2654static struct file_lists {
2655	struct file_lists *next;
2656	char *name;
2657	char *subfname;
2658	time_t modtime;
2659} *file_lists = NULL;
2660
2661/*******************************************************************
2662 Keep a linked list of all config files so we know when one has changed
2663 it's date and needs to be reloaded.
2664********************************************************************/
2665
2666static void add_to_file_list(const char *fname, const char *subfname)
2667{
2668	struct file_lists *f = file_lists;
2669
2670	while (f) {
2671		if (f->name && !strcmp(f->name, fname))
2672			break;
2673		f = f->next;
2674	}
2675
2676	if (!f) {
2677		f = SMB_MALLOC_P(struct file_lists);
2678		if (!f)
2679			return;
2680		f->next = file_lists;
2681		f->name = SMB_STRDUP(fname);
2682		if (!f->name) {
2683			SAFE_FREE(f);
2684			return;
2685		}
2686		f->subfname = SMB_STRDUP(subfname);
2687		if (!f->subfname) {
2688			SAFE_FREE(f);
2689			return;
2690		}
2691		file_lists = f;
2692		f->modtime = file_modtime(subfname);
2693	} else {
2694		time_t t = file_modtime(subfname);
2695		if (t)
2696			f->modtime = t;
2697	}
2698}
2699
2700/*******************************************************************
2701 Check if a config file has changed date.
2702********************************************************************/
2703
2704BOOL lp_file_list_changed(void)
2705{
2706	struct file_lists *f = file_lists;
2707
2708 	DEBUG(6, ("lp_file_list_changed()\n"));
2709
2710	while (f) {
2711		pstring n2;
2712		time_t mod_time;
2713
2714		pstrcpy(n2, f->name);
2715		standard_sub_basic( get_current_username(), n2, sizeof(n2) );
2716
2717		DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2718			     f->name, n2, ctime(&f->modtime)));
2719
2720		mod_time = file_modtime(n2);
2721
2722		if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2723			DEBUGADD(6,
2724				 ("file %s modified: %s\n", n2,
2725				  ctime(&mod_time)));
2726			f->modtime = mod_time;
2727			SAFE_FREE(f->subfname);
2728			f->subfname = SMB_STRDUP(n2);
2729			return (True);
2730		}
2731		f = f->next;
2732	}
2733	return (False);
2734}
2735
2736/***************************************************************************
2737 Run standard_sub_basic on netbios name... needed because global_myname
2738 is not accessed through any lp_ macro.
2739 Note: We must *NOT* use string_set() here as ptr points to global_myname.
2740***************************************************************************/
2741
2742static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
2743{
2744	BOOL ret;
2745	pstring netbios_name;
2746
2747	pstrcpy(netbios_name, pszParmValue);
2748
2749	standard_sub_basic(get_current_username(), netbios_name,sizeof(netbios_name));
2750
2751	ret = set_global_myname(netbios_name);
2752	string_set(&Globals.szNetbiosName,global_myname());
2753
2754	DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
2755	       global_myname()));
2756
2757	return ret;
2758}
2759
2760static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
2761{
2762	if (strcmp(*ptr, pszParmValue) != 0) {
2763		string_set(ptr, pszParmValue);
2764		init_iconv();
2765	}
2766	return True;
2767}
2768
2769static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
2770{
2771	BOOL ret;
2772
2773	ret = set_global_myworkgroup(pszParmValue);
2774	string_set(&Globals.szWorkgroup,lp_workgroup());
2775
2776	return ret;
2777}
2778
2779static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
2780{
2781	BOOL ret;
2782
2783	ret = set_global_scope(pszParmValue);
2784	string_set(&Globals.szNetbiosScope,global_scope());
2785
2786	return ret;
2787}
2788
2789static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
2790{
2791	str_list_free(&Globals.szNetbiosAliases);
2792	Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
2793	return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
2794}
2795
2796/***************************************************************************
2797 Handle the include operation.
2798***************************************************************************/
2799
2800static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
2801{
2802	pstring fname;
2803	pstrcpy(fname, pszParmValue);
2804
2805	standard_sub_basic(get_current_username(), fname,sizeof(fname));
2806
2807	add_to_file_list(pszParmValue, fname);
2808
2809	string_set(ptr, fname);
2810
2811	if (file_exist(fname, NULL))
2812		return (pm_process(fname, do_section, do_parameter));
2813
2814	DEBUG(2, ("Can't find include file %s\n", fname));
2815
2816	return (False);
2817}
2818
2819/***************************************************************************
2820 Handle the interpretation of the copy parameter.
2821***************************************************************************/
2822
2823static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
2824{
2825	BOOL bRetval;
2826	int iTemp;
2827	service serviceTemp;
2828
2829	string_set(ptr, pszParmValue);
2830
2831	init_service(&serviceTemp);
2832
2833	bRetval = False;
2834
2835	DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2836
2837	if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2838		if (iTemp == iServiceIndex) {
2839			DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2840		} else {
2841			copy_service(ServicePtrs[iServiceIndex],
2842				     &serviceTemp,
2843				     ServicePtrs[iServiceIndex]->copymap);
2844			bRetval = True;
2845		}
2846	} else {
2847		DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2848		bRetval = False;
2849	}
2850
2851	free_service(&serviceTemp);
2852	return (bRetval);
2853}
2854
2855/***************************************************************************
2856 Handle idmap/non unix account uid and gid allocation parameters.  The format of these
2857 parameters is:
2858
2859 [global]
2860
2861        idmap uid = 1000-1999
2862        idmap gid = 700-899
2863
2864 We only do simple parsing checks here.  The strings are parsed into useful
2865 structures in the idmap daemon code.
2866
2867***************************************************************************/
2868
2869/* Some lp_ routines to return idmap [ug]id information */
2870
2871static uid_t idmap_uid_low, idmap_uid_high;
2872static gid_t idmap_gid_low, idmap_gid_high;
2873
2874BOOL lp_idmap_uid(uid_t *low, uid_t *high)
2875{
2876        if (idmap_uid_low == 0 || idmap_uid_high == 0)
2877                return False;
2878
2879        if (low)
2880                *low = idmap_uid_low;
2881
2882        if (high)
2883                *high = idmap_uid_high;
2884
2885        return True;
2886}
2887
2888BOOL lp_idmap_gid(gid_t *low, gid_t *high)
2889{
2890        if (idmap_gid_low == 0 || idmap_gid_high == 0)
2891                return False;
2892
2893        if (low)
2894                *low = idmap_gid_low;
2895
2896        if (high)
2897                *high = idmap_gid_high;
2898
2899        return True;
2900}
2901
2902/* Do some simple checks on "idmap [ug]id" parameter values */
2903
2904static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
2905{
2906	uint32 low, high;
2907
2908	if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2909		return False;
2910
2911	/* Parse OK */
2912
2913	string_set(ptr, pszParmValue);
2914
2915        idmap_uid_low = low;
2916        idmap_uid_high = high;
2917
2918	return True;
2919}
2920
2921static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
2922{
2923	uint32 low, high;
2924
2925	if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2926		return False;
2927
2928	/* Parse OK */
2929
2930	string_set(ptr, pszParmValue);
2931
2932        idmap_gid_low = low;
2933        idmap_gid_high = high;
2934
2935	return True;
2936}
2937
2938/***************************************************************************
2939 Handle the DEBUG level list.
2940***************************************************************************/
2941
2942static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
2943{
2944	pstring pszParmValue;
2945
2946	pstrcpy(pszParmValue, pszParmValueIn);
2947	string_set(ptr, pszParmValueIn);
2948	return debug_parse_levels( pszParmValue );
2949}
2950
2951/***************************************************************************
2952 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2953***************************************************************************/
2954
2955static char* append_ldap_suffix( const char *str )
2956{
2957	char *suffix_string;
2958
2959
2960	if (!lp_talloc)
2961		lp_talloc = talloc_init("lp_talloc");
2962
2963	suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
2964	if ( !suffix_string ) {
2965		DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2966		return NULL;
2967	}
2968
2969	return suffix_string;
2970}
2971
2972char *lp_ldap_machine_suffix(void)
2973{
2974	if (Globals.szLdapMachineSuffix[0])
2975		return append_ldap_suffix(Globals.szLdapMachineSuffix);
2976
2977	return lp_string(Globals.szLdapSuffix);
2978}
2979
2980char *lp_ldap_user_suffix(void)
2981{
2982	if (Globals.szLdapUserSuffix[0])
2983		return append_ldap_suffix(Globals.szLdapUserSuffix);
2984
2985	return lp_string(Globals.szLdapSuffix);
2986}
2987
2988char *lp_ldap_group_suffix(void)
2989{
2990	if (Globals.szLdapGroupSuffix[0])
2991		return append_ldap_suffix(Globals.szLdapGroupSuffix);
2992
2993	return lp_string(Globals.szLdapSuffix);
2994}
2995
2996char *lp_ldap_idmap_suffix(void)
2997{
2998	if (Globals.szLdapIdmapSuffix[0])
2999		return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3000
3001	return lp_string(Globals.szLdapSuffix);
3002}
3003
3004/***************************************************************************
3005***************************************************************************/
3006
3007static BOOL handle_acl_compatibility(int snum, const char *pszParmValue, char **ptr)
3008{
3009	if (strequal(pszParmValue, "auto"))
3010		string_set(ptr, "");
3011	else if (strequal(pszParmValue, "winnt"))
3012		string_set(ptr, "winnt");
3013	else if (strequal(pszParmValue, "win2k"))
3014		string_set(ptr, "win2k");
3015	else
3016		return False;
3017
3018	return True;
3019}
3020
3021/****************************************************************************
3022 set the value for a P_ENUM
3023 ***************************************************************************/
3024
3025static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3026                              int *ptr )
3027{
3028	int i;
3029
3030	for (i = 0; parm->enum_list[i].name; i++) {
3031		if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3032			*ptr = parm->enum_list[i].value;
3033			break;
3034		}
3035	}
3036}
3037
3038/***************************************************************************
3039***************************************************************************/
3040
3041static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3042{
3043	static int parm_num = -1;
3044	service *s;
3045
3046	if ( parm_num == -1 )
3047		parm_num = map_parameter( "printing" );
3048
3049	lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3050
3051	if ( snum < 0 )
3052		s = &sDefault;
3053	else
3054		s = ServicePtrs[snum];
3055
3056	init_printer_values( s );
3057
3058	return True;
3059}
3060
3061
3062/***************************************************************************
3063 Initialise a copymap.
3064***************************************************************************/
3065
3066static void init_copymap(service * pservice)
3067{
3068	int i;
3069	SAFE_FREE(pservice->copymap);
3070	pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3071	if (!pservice->copymap)
3072		DEBUG(0,
3073		      ("Couldn't allocate copymap!! (size %d)\n",
3074		       (int)NUMPARAMETERS));
3075	else
3076		for (i = 0; i < NUMPARAMETERS; i++)
3077			pservice->copymap[i] = True;
3078}
3079
3080/***************************************************************************
3081 Return the local pointer to a parameter given the service number and the
3082 pointer into the default structure.
3083***************************************************************************/
3084
3085void *lp_local_ptr(int snum, void *ptr)
3086{
3087	return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3088}
3089
3090/***************************************************************************
3091 Process a parameter for a particular service number. If snum < 0
3092 then assume we are in the globals.
3093***************************************************************************/
3094
3095BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3096{
3097	int parmnum, i, slen;
3098	void *parm_ptr = NULL;	/* where we are going to store the result */
3099	void *def_ptr = NULL;
3100	pstring param_key;
3101	char *sep;
3102	param_opt_struct *paramo, *data;
3103	BOOL not_added;
3104
3105	parmnum = map_parameter(pszParmName);
3106
3107	if (parmnum < 0) {
3108		if ((sep=strchr(pszParmName, ':')) != NULL) {
3109			*sep = '\0';
3110			ZERO_STRUCT(param_key);
3111			pstr_sprintf(param_key, "%s:", pszParmName);
3112			slen = strlen(param_key);
3113			pstrcat(param_key, sep+1);
3114			trim_char(param_key+slen, ' ', ' ');
3115			not_added = True;
3116			data = (snum < 0) ? Globals.param_opt :
3117				ServicePtrs[snum]->param_opt;
3118			/* Traverse destination */
3119			while (data) {
3120				/* If we already have same option, override it */
3121				if (strcmp(data->key, param_key) == 0) {
3122					string_free(&data->value);
3123					str_list_free(&data->list);
3124					data->value = SMB_STRDUP(pszParmValue);
3125					not_added = False;
3126					break;
3127				}
3128				data = data->next;
3129			}
3130			if (not_added) {
3131				paramo = SMB_XMALLOC_P(param_opt_struct);
3132				paramo->key = SMB_STRDUP(param_key);
3133				paramo->value = SMB_STRDUP(pszParmValue);
3134				paramo->list = NULL;
3135				if (snum < 0) {
3136					DLIST_ADD(Globals.param_opt, paramo);
3137				} else {
3138					DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3139				}
3140			}
3141
3142			*sep = ':';
3143			return (True);
3144		}
3145		DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3146		return (True);
3147	}
3148
3149	if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3150		DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3151			  pszParmName));
3152	}
3153
3154	def_ptr = parm_table[parmnum].ptr;
3155
3156	/* we might point at a service, the default service or a global */
3157	if (snum < 0) {
3158		parm_ptr = def_ptr;
3159	} else {
3160		if (parm_table[parmnum].class == P_GLOBAL) {
3161			DEBUG(0,
3162			      ("Global parameter %s found in service section!\n",
3163			       pszParmName));
3164			return (True);
3165		}
3166		parm_ptr =
3167			((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3168							    &sDefault);
3169	}
3170
3171	if (snum >= 0) {
3172		if (!ServicePtrs[snum]->copymap)
3173			init_copymap(ServicePtrs[snum]);
3174
3175		/* this handles the aliases - set the copymap for other entries with
3176		   the same data pointer */
3177		for (i = 0; parm_table[i].label; i++)
3178			if (parm_table[i].ptr == parm_table[parmnum].ptr)
3179				ServicePtrs[snum]->copymap[i] = False;
3180	}
3181
3182	/* if it is a special case then go ahead */
3183	if (parm_table[parmnum].special) {
3184		parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3185		return (True);
3186	}
3187
3188	/* now switch on the type of variable it is */
3189	switch (parm_table[parmnum].type)
3190	{
3191		case P_BOOL:
3192			set_boolean(parm_ptr, pszParmValue);
3193			break;
3194
3195		case P_BOOLREV:
3196			set_boolean(parm_ptr, pszParmValue);
3197			*(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
3198			break;
3199
3200		case P_INTEGER:
3201			*(int *)parm_ptr = atoi(pszParmValue);
3202			break;
3203
3204		case P_CHAR:
3205			*(char *)parm_ptr = *pszParmValue;
3206			break;
3207
3208		case P_OCTAL:
3209			sscanf(pszParmValue, "%o", (int *)parm_ptr);
3210			break;
3211
3212		case P_LIST:
3213			str_list_free(parm_ptr);
3214			*(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3215			break;
3216
3217		case P_STRING:
3218			string_set(parm_ptr, pszParmValue);
3219			break;
3220
3221		case P_USTRING:
3222			string_set(parm_ptr, pszParmValue);
3223			strupper_m(*(char **)parm_ptr);
3224			break;
3225
3226		case P_GSTRING:
3227			pstrcpy((char *)parm_ptr, pszParmValue);
3228			break;
3229
3230		case P_UGSTRING:
3231			pstrcpy((char *)parm_ptr, pszParmValue);
3232			strupper_m((char *)parm_ptr);
3233			break;
3234
3235		case P_ENUM:
3236			lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3237			break;
3238		case P_SEP:
3239			break;
3240	}
3241
3242	return (True);
3243}
3244
3245/***************************************************************************
3246 Process a parameter.
3247***************************************************************************/
3248
3249static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3250{
3251	if (!bInGlobalSection && bGlobalOnly)
3252		return (True);
3253
3254	DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3255
3256	return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3257				pszParmName, pszParmValue));
3258}
3259
3260/***************************************************************************
3261 Print a parameter of the specified type.
3262***************************************************************************/
3263
3264static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3265{
3266	int i;
3267	switch (p->type)
3268	{
3269		case P_ENUM:
3270			for (i = 0; p->enum_list[i].name; i++) {
3271				if (*(int *)ptr == p->enum_list[i].value) {
3272					fprintf(f, "%s",
3273						p->enum_list[i].name);
3274					break;
3275				}
3276			}
3277			break;
3278
3279		case P_BOOL:
3280			fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3281			break;
3282
3283		case P_BOOLREV:
3284			fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3285			break;
3286
3287		case P_INTEGER:
3288			fprintf(f, "%d", *(int *)ptr);
3289			break;
3290
3291		case P_CHAR:
3292			fprintf(f, "%c", *(char *)ptr);
3293			break;
3294
3295		case P_OCTAL:
3296			fprintf(f, "%s", octal_string(*(int *)ptr));
3297			break;
3298
3299		case P_LIST:
3300			if ((char ***)ptr && *(char ***)ptr) {
3301				char **list = *(char ***)ptr;
3302
3303				for (; *list; list++) {
3304					/* surround strings with whitespace in double quotes */
3305					if ( strchr_m( *list, ' ' ) )
3306						fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3307					else
3308						fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3309				}
3310			}
3311			break;
3312
3313		case P_GSTRING:
3314		case P_UGSTRING:
3315			if ((char *)ptr) {
3316				fprintf(f, "%s", (char *)ptr);
3317			}
3318			break;
3319
3320		case P_STRING:
3321		case P_USTRING:
3322			if (*(char **)ptr) {
3323				fprintf(f, "%s", *(char **)ptr);
3324			}
3325			break;
3326		case P_SEP:
3327			break;
3328	}
3329}
3330
3331/***************************************************************************
3332 Check if two parameters are equal.
3333***************************************************************************/
3334
3335static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3336{
3337	switch (type) {
3338		case P_BOOL:
3339		case P_BOOLREV:
3340			return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3341
3342		case P_INTEGER:
3343		case P_ENUM:
3344		case P_OCTAL:
3345			return (*((int *)ptr1) == *((int *)ptr2));
3346
3347		case P_CHAR:
3348			return (*((char *)ptr1) == *((char *)ptr2));
3349
3350		case P_LIST:
3351			return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3352
3353		case P_GSTRING:
3354		case P_UGSTRING:
3355		{
3356			char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3357			if (p1 && !*p1)
3358				p1 = NULL;
3359			if (p2 && !*p2)
3360				p2 = NULL;
3361			return (p1 == p2 || strequal(p1, p2));
3362		}
3363		case P_STRING:
3364		case P_USTRING:
3365		{
3366			char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3367			if (p1 && !*p1)
3368				p1 = NULL;
3369			if (p2 && !*p2)
3370				p2 = NULL;
3371			return (p1 == p2 || strequal(p1, p2));
3372		}
3373		case P_SEP:
3374			break;
3375	}
3376	return (False);
3377}
3378
3379/***************************************************************************
3380 Initialize any local varients in the sDefault table.
3381***************************************************************************/
3382
3383void init_locals(void)
3384{
3385	/* None as yet. */
3386}
3387
3388/***************************************************************************
3389 Process a new section (service). At this stage all sections are services.
3390 Later we'll have special sections that permit server parameters to be set.
3391 Returns True on success, False on failure.
3392***************************************************************************/
3393
3394static BOOL do_section(const char *pszSectionName)
3395{
3396	BOOL bRetval;
3397	BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3398			 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3399	bRetval = False;
3400
3401	/* if we were in a global section then do the local inits */
3402	if (bInGlobalSection && !isglobal)
3403		init_locals();
3404
3405	/* if we've just struck a global section, note the fact. */
3406	bInGlobalSection = isglobal;
3407
3408	/* check for multiple global sections */
3409	if (bInGlobalSection) {
3410		DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3411		return (True);
3412	}
3413
3414	if (!bInGlobalSection && bGlobalOnly)
3415		return (True);
3416
3417	/* if we have a current service, tidy it up before moving on */
3418	bRetval = True;
3419
3420	if (iServiceIndex >= 0)
3421		bRetval = service_ok(iServiceIndex);
3422
3423	/* if all is still well, move to the next record in the services array */
3424	if (bRetval) {
3425		/* We put this here to avoid an odd message order if messages are */
3426		/* issued by the post-processing of a previous section. */
3427		DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3428
3429		if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3430		    < 0) {
3431			DEBUG(0, ("Failed to add a new service\n"));
3432			return (False);
3433		}
3434	}
3435
3436	return (bRetval);
3437}
3438
3439
3440/***************************************************************************
3441 Determine if a partcular base parameter is currentl set to the default value.
3442***************************************************************************/
3443
3444static BOOL is_default(int i)
3445{
3446	if (!defaults_saved)
3447		return False;
3448	switch (parm_table[i].type) {
3449		case P_LIST:
3450			return str_list_compare (parm_table[i].def.lvalue,
3451						*(char ***)parm_table[i].ptr);
3452		case P_STRING:
3453		case P_USTRING:
3454			return strequal(parm_table[i].def.svalue,
3455					*(char **)parm_table[i].ptr);
3456		case P_GSTRING:
3457		case P_UGSTRING:
3458			return strequal(parm_table[i].def.svalue,
3459					(char *)parm_table[i].ptr);
3460		case P_BOOL:
3461		case P_BOOLREV:
3462			return parm_table[i].def.bvalue ==
3463				*(BOOL *)parm_table[i].ptr;
3464		case P_CHAR:
3465			return parm_table[i].def.cvalue ==
3466				*(char *)parm_table[i].ptr;
3467		case P_INTEGER:
3468		case P_OCTAL:
3469		case P_ENUM:
3470			return parm_table[i].def.ivalue ==
3471				*(int *)parm_table[i].ptr;
3472		case P_SEP:
3473			break;
3474	}
3475	return False;
3476}
3477
3478/***************************************************************************
3479Display the contents of the global structure.
3480***************************************************************************/
3481
3482static void dump_globals(FILE *f)
3483{
3484	int i;
3485	param_opt_struct *data;
3486
3487	fprintf(f, "# Global parameters\n[global]\n");
3488
3489	for (i = 0; parm_table[i].label; i++)
3490		if (parm_table[i].class == P_GLOBAL &&
3491		    parm_table[i].ptr &&
3492		    (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3493			if (defaults_saved && is_default(i))
3494				continue;
3495			fprintf(f, "\t%s = ", parm_table[i].label);
3496			print_parameter(&parm_table[i], parm_table[i].ptr, f);
3497			fprintf(f, "\n");
3498	}
3499	if (Globals.param_opt != NULL) {
3500		data = Globals.param_opt;
3501		while(data) {
3502			fprintf(f, "\t%s = %s\n", data->key, data->value);
3503			data = data->next;
3504		}
3505        }
3506
3507}
3508
3509/***************************************************************************
3510 Return True if a local parameter is currently set to the global default.
3511***************************************************************************/
3512
3513BOOL lp_is_default(int snum, struct parm_struct *parm)
3514{
3515	int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3516
3517	return equal_parameter(parm->type,
3518			       ((char *)ServicePtrs[snum]) + pdiff,
3519			       ((char *)&sDefault) + pdiff);
3520}
3521
3522/***************************************************************************
3523 Display the contents of a single services record.
3524***************************************************************************/
3525
3526static void dump_a_service(service * pService, FILE * f)
3527{
3528	int i;
3529	param_opt_struct *data;
3530
3531	if (pService != &sDefault)
3532		fprintf(f, "\n[%s]\n", pService->szService);
3533
3534	for (i = 0; parm_table[i].label; i++) {
3535
3536		if (parm_table[i].class == P_LOCAL &&
3537		    parm_table[i].ptr &&
3538		    (*parm_table[i].label != '-') &&
3539		    (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3540		{
3541
3542			int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3543
3544			if (pService == &sDefault) {
3545				if (defaults_saved && is_default(i))
3546					continue;
3547			} else {
3548				if (equal_parameter(parm_table[i].type,
3549						    ((char *)pService) +
3550						    pdiff,
3551						    ((char *)&sDefault) +
3552						    pdiff))
3553					continue;
3554			}
3555
3556			fprintf(f, "\t%s = ", parm_table[i].label);
3557			print_parameter(&parm_table[i],
3558					((char *)pService) + pdiff, f);
3559			fprintf(f, "\n");
3560		}
3561	}
3562
3563	if (pService->param_opt != NULL) {
3564		data = pService->param_opt;
3565		while(data) {
3566			fprintf(f, "\t%s = %s\n", data->key, data->value);
3567			data = data->next;
3568		}
3569	}
3570}
3571
3572
3573/***************************************************************************
3574 Return info about the next service  in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
3575 Return NULL when out of parameters.
3576***************************************************************************/
3577
3578struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3579{
3580	if (snum < 0) {
3581		/* do the globals */
3582		for (; parm_table[*i].label; (*i)++) {
3583			if (parm_table[*i].class == P_SEPARATOR)
3584				return &parm_table[(*i)++];
3585
3586			if (!parm_table[*i].ptr
3587			    || (*parm_table[*i].label == '-'))
3588				continue;
3589
3590			if ((*i) > 0
3591			    && (parm_table[*i].ptr ==
3592				parm_table[(*i) - 1].ptr))
3593				continue;
3594
3595			return &parm_table[(*i)++];
3596		}
3597	} else {
3598		service *pService = ServicePtrs[snum];
3599
3600		for (; parm_table[*i].label; (*i)++) {
3601			if (parm_table[*i].class == P_SEPARATOR)
3602				return &parm_table[(*i)++];
3603
3604			if (parm_table[*i].class == P_LOCAL &&
3605			    parm_table[*i].ptr &&
3606			    (*parm_table[*i].label != '-') &&
3607			    ((*i) == 0 ||
3608			     (parm_table[*i].ptr !=
3609			      parm_table[(*i) - 1].ptr)))
3610			{
3611				int pdiff =
3612					PTR_DIFF(parm_table[*i].ptr,
3613						 &sDefault);
3614
3615				if (allparameters ||
3616				    !equal_parameter(parm_table[*i].type,
3617						     ((char *)pService) +
3618						     pdiff,
3619						     ((char *)&sDefault) +
3620						     pdiff))
3621				{
3622					return &parm_table[(*i)++];
3623				}
3624			}
3625		}
3626	}
3627
3628	return NULL;
3629}
3630
3631
3632#if 0
3633/***************************************************************************
3634 Display the contents of a single copy structure.
3635***************************************************************************/
3636static void dump_copy_map(BOOL *pcopymap)
3637{
3638	int i;
3639	if (!pcopymap)
3640		return;
3641
3642	printf("\n\tNon-Copied parameters:\n");
3643
3644	for (i = 0; parm_table[i].label; i++)
3645		if (parm_table[i].class == P_LOCAL &&
3646		    parm_table[i].ptr && !pcopymap[i] &&
3647		    (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3648		{
3649			printf("\t\t%s\n", parm_table[i].label);
3650		}
3651}
3652#endif
3653
3654/***************************************************************************
3655 Return TRUE if the passed service number is within range.
3656***************************************************************************/
3657
3658BOOL lp_snum_ok(int iService)
3659{
3660	return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3661}
3662
3663/***************************************************************************
3664 Auto-load some home services.
3665***************************************************************************/
3666
3667static void lp_add_auto_services(char *str)
3668{
3669	char *s;
3670	char *p;
3671	int homes;
3672
3673	if (!str)
3674		return;
3675
3676	s = SMB_STRDUP(str);
3677	if (!s)
3678		return;
3679
3680	homes = lp_servicenumber(HOMES_NAME);
3681
3682	for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
3683		char *home = get_user_home_dir(p);
3684
3685		if (lp_servicenumber(p) >= 0)
3686			continue;
3687
3688		if (home && homes >= 0)
3689			lp_add_home(p, homes, p, home);
3690	}
3691	SAFE_FREE(s);
3692}
3693
3694/***************************************************************************
3695 Auto-load one printer.
3696***************************************************************************/
3697
3698void lp_add_one_printer(char *name, char *comment)
3699{
3700	int printers = lp_servicenumber(PRINTERS_NAME);
3701	int i;
3702
3703	if (lp_servicenumber(name) < 0) {
3704		lp_add_printer(name, printers);
3705		if ((i = lp_servicenumber(name)) >= 0) {
3706			string_set(&ServicePtrs[i]->comment, comment);
3707			ServicePtrs[i]->autoloaded = True;
3708		}
3709	}
3710}
3711
3712/***************************************************************************
3713 Have we loaded a services file yet?
3714***************************************************************************/
3715
3716BOOL lp_loaded(void)
3717{
3718	return (bLoaded);
3719}
3720
3721/***************************************************************************
3722 Unload unused services.
3723***************************************************************************/
3724
3725void lp_killunused(BOOL (*snumused) (int))
3726{
3727	int i;
3728	for (i = 0; i < iNumServices; i++) {
3729		if (!VALID(i))
3730			continue;
3731
3732		/* don't kill autoloaded services */
3733		if ( ServicePtrs[i]->autoloaded )
3734			continue;
3735
3736		if (!snumused || !snumused(i)) {
3737			ServicePtrs[i]->valid = False;
3738			free_service(ServicePtrs[i]);
3739		}
3740	}
3741}
3742
3743/***************************************************************************
3744 Unload a service.
3745***************************************************************************/
3746
3747void lp_killservice(int iServiceIn)
3748{
3749	if (VALID(iServiceIn)) {
3750		ServicePtrs[iServiceIn]->valid = False;
3751		free_service(ServicePtrs[iServiceIn]);
3752	}
3753}
3754
3755/***************************************************************************
3756 Save the curent values of all global and sDefault parameters into the
3757 defaults union. This allows swat and testparm to show only the
3758 changed (ie. non-default) parameters.
3759***************************************************************************/
3760
3761static void lp_save_defaults(void)
3762{
3763	int i;
3764	for (i = 0; parm_table[i].label; i++) {
3765		if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
3766			continue;
3767		switch (parm_table[i].type) {
3768			case P_LIST:
3769				str_list_copy(&(parm_table[i].def.lvalue),
3770					    *(const char ***)parm_table[i].ptr);
3771				break;
3772			case P_STRING:
3773			case P_USTRING:
3774				if (parm_table[i].ptr) {
3775					parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
3776				} else {
3777					parm_table[i].def.svalue = NULL;
3778				}
3779				break;
3780			case P_GSTRING:
3781			case P_UGSTRING:
3782				if (parm_table[i].ptr) {
3783					parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
3784				} else {
3785					parm_table[i].def.svalue = NULL;
3786				}
3787				break;
3788			case P_BOOL:
3789			case P_BOOLREV:
3790				parm_table[i].def.bvalue =
3791					*(BOOL *)parm_table[i].ptr;
3792				break;
3793			case P_CHAR:
3794				parm_table[i].def.cvalue =
3795					*(char *)parm_table[i].ptr;
3796				break;
3797			case P_INTEGER:
3798			case P_OCTAL:
3799			case P_ENUM:
3800				parm_table[i].def.ivalue =
3801					*(int *)parm_table[i].ptr;
3802				break;
3803			case P_SEP:
3804				break;
3805		}
3806	}
3807	defaults_saved = True;
3808}
3809
3810/*******************************************************************
3811 Set the server type we will announce as via nmbd.
3812********************************************************************/
3813
3814static void set_server_role(void)
3815{
3816	server_role = ROLE_STANDALONE;
3817
3818	switch (lp_security()) {
3819		case SEC_SHARE:
3820			if (lp_domain_logons())
3821				DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
3822			break;
3823		case SEC_SERVER:
3824			if (lp_domain_logons())
3825				DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
3826			server_role = ROLE_DOMAIN_MEMBER;
3827			break;
3828		case SEC_DOMAIN:
3829			if (lp_domain_logons()) {
3830				DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
3831				server_role = ROLE_DOMAIN_BDC;
3832				break;
3833			}
3834			server_role = ROLE_DOMAIN_MEMBER;
3835			break;
3836		case SEC_ADS:
3837			if (lp_domain_logons()) {
3838				server_role = ROLE_DOMAIN_PDC;
3839				break;
3840			}
3841			server_role = ROLE_DOMAIN_MEMBER;
3842			break;
3843		case SEC_USER:
3844			if (lp_domain_logons()) {
3845
3846				if (Globals.bDomainMaster) /* auto or yes */
3847					server_role = ROLE_DOMAIN_PDC;
3848				else
3849					server_role = ROLE_DOMAIN_BDC;
3850			}
3851			break;
3852		default:
3853			DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3854			break;
3855	}
3856
3857	DEBUG(10, ("set_server_role: role = "));
3858
3859	switch(server_role) {
3860	case ROLE_STANDALONE:
3861		DEBUGADD(10, ("ROLE_STANDALONE\n"));
3862		break;
3863	case ROLE_DOMAIN_MEMBER:
3864		DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3865		break;
3866	case ROLE_DOMAIN_BDC:
3867		DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3868		break;
3869	case ROLE_DOMAIN_PDC:
3870		DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3871		break;
3872	}
3873}
3874
3875/***********************************************************
3876 If we should send plaintext/LANMAN passwords in the clinet
3877************************************************************/
3878static void set_allowed_client_auth(void)
3879{
3880	if (Globals.bClientNTLMv2Auth) {
3881		Globals.bClientLanManAuth = False;
3882	}
3883	if (!Globals.bClientLanManAuth) {
3884		Globals.bClientPlaintextAuth = False;
3885	}
3886}
3887
3888/***************************************************************************
3889 Load the services array from the services file. Return True on success,
3890 False on failure.
3891***************************************************************************/
3892
3893BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3894	     BOOL add_ipc)
3895{
3896	pstring n2;
3897	BOOL bRetval;
3898	param_opt_struct *data, *pdata;
3899
3900	pstrcpy(n2, pszFname);
3901
3902	standard_sub_basic( get_current_username(), n2,sizeof(n2) );
3903
3904	add_to_file_list(pszFname, n2);
3905
3906	bRetval = False;
3907
3908	DEBUG(3, ("lp_load: refreshing parameters\n"));
3909
3910	bInGlobalSection = True;
3911	bGlobalOnly = global_only;
3912
3913	init_globals();
3914	debug_init();
3915
3916	if (save_defaults) {
3917		init_locals();
3918		lp_save_defaults();
3919	}
3920
3921	if (Globals.param_opt != NULL) {
3922		data = Globals.param_opt;
3923		while (data) {
3924			string_free(&data->key);
3925			string_free(&data->value);
3926			str_list_free(&data->list);
3927			pdata = data->next;
3928			SAFE_FREE(data);
3929			data = pdata;
3930		}
3931		Globals.param_opt = NULL;
3932	}
3933
3934	/* We get sections first, so have to start 'behind' to make up */
3935	iServiceIndex = -1;
3936	bRetval = pm_process(n2, do_section, do_parameter);
3937
3938	/* finish up the last section */
3939	DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3940	if (bRetval)
3941		if (iServiceIndex >= 0)
3942			bRetval = service_ok(iServiceIndex);
3943
3944	lp_add_auto_services(lp_auto_services());
3945
3946	if (add_ipc) {
3947		/* When 'restrict anonymous = 2' guest connections to ipc$
3948		   are denied */
3949		lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3950		lp_add_ipc("ADMIN$", False);
3951	}
3952
3953	set_server_role();
3954	set_default_server_announce_type();
3955	set_allowed_client_auth();
3956
3957	bLoaded = True;
3958
3959	/* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3960	/* if bWINSsupport is true and we are in the client            */
3961	if (in_client && Globals.bWINSsupport) {
3962		lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3963	}
3964
3965	init_iconv();
3966
3967	return (bRetval);
3968}
3969
3970/***************************************************************************
3971 Reset the max number of services.
3972***************************************************************************/
3973
3974void lp_resetnumservices(void)
3975{
3976	iNumServices = 0;
3977}
3978
3979/***************************************************************************
3980 Return the max number of services.
3981***************************************************************************/
3982
3983int lp_numservices(void)
3984{
3985	return (iNumServices);
3986}
3987
3988/***************************************************************************
3989Display the contents of the services array in human-readable form.
3990***************************************************************************/
3991
3992void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3993{
3994	int iService;
3995
3996	if (show_defaults)
3997		defaults_saved = False;
3998
3999	dump_globals(f);
4000
4001	dump_a_service(&sDefault, f);
4002
4003	for (iService = 0; iService < maxtoprint; iService++)
4004		lp_dump_one(f, show_defaults, iService);
4005}
4006
4007/***************************************************************************
4008Display the contents of one service in human-readable form.
4009***************************************************************************/
4010
4011void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
4012{
4013	if (VALID(snum)) {
4014		if (ServicePtrs[snum]->szService[0] == '\0')
4015			return;
4016		dump_a_service(ServicePtrs[snum], f);
4017	}
4018}
4019
4020/***************************************************************************
4021Return the number of the service with the given name, or -1 if it doesn't
4022exist. Note that this is a DIFFERENT ANIMAL from the internal function
4023getservicebyname()! This works ONLY if all services have been loaded, and
4024does not copy the found service.
4025***************************************************************************/
4026
4027int lp_servicenumber(const char *pszServiceName)
4028{
4029	int iService;
4030        fstring serviceName;
4031
4032        if (!pszServiceName)
4033        	return GLOBAL_SECTION_SNUM;
4034
4035	for (iService = iNumServices - 1; iService >= 0; iService--) {
4036		if (VALID(iService) && ServicePtrs[iService]->szService) {
4037			/*
4038			 * The substitution here is used to support %U is
4039			 * service names
4040			 */
4041			fstrcpy(serviceName, ServicePtrs[iService]->szService);
4042			standard_sub_basic(get_current_username(), serviceName,sizeof(serviceName));
4043			if (strequal(serviceName, pszServiceName))
4044				break;
4045		}
4046	}
4047
4048	if (iService < 0) {
4049		DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4050		return GLOBAL_SECTION_SNUM;
4051	}
4052
4053	return (iService);
4054}
4055
4056/*******************************************************************
4057 A useful volume label function.
4058********************************************************************/
4059
4060char *volume_label(int snum)
4061{
4062	char *ret = lp_volume(snum);
4063	if (!*ret)
4064		return lp_servicename(snum);
4065	return (ret);
4066}
4067
4068
4069/*******************************************************************
4070 Set the server type we will announce as via nmbd.
4071********************************************************************/
4072
4073static void set_default_server_announce_type(void)
4074{
4075	default_server_announce = 0;
4076	default_server_announce |= SV_TYPE_WORKSTATION;
4077	default_server_announce |= SV_TYPE_SERVER;
4078	default_server_announce |= SV_TYPE_SERVER_UNIX;
4079
4080	/* note that the flag should be set only if we have a
4081	   printer service but nmbd doesn't actually load the
4082	   services so we can't tell   --jerry */
4083    /* Foxconn removed start pling 07/16/2009, disable printer server */
4084	//default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4085    /* Foxconn removed end pling 07/16/2009 */
4086
4087	switch (lp_announce_as()) {
4088		case ANNOUNCE_AS_NT_SERVER:
4089			default_server_announce |= SV_TYPE_SERVER_NT;
4090			/* fall through... */
4091		case ANNOUNCE_AS_NT_WORKSTATION:
4092			default_server_announce |= SV_TYPE_NT;
4093			break;
4094		case ANNOUNCE_AS_WIN95:
4095			default_server_announce |= SV_TYPE_WIN95_PLUS;
4096			break;
4097		case ANNOUNCE_AS_WFW:
4098			default_server_announce |= SV_TYPE_WFW;
4099			break;
4100		default:
4101			break;
4102	}
4103
4104	switch (lp_server_role()) {
4105		case ROLE_DOMAIN_MEMBER:
4106			default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4107			break;
4108		case ROLE_DOMAIN_PDC:
4109			default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4110			break;
4111		case ROLE_DOMAIN_BDC:
4112			default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4113			break;
4114		case ROLE_STANDALONE:
4115		default:
4116			break;
4117	}
4118	if (lp_time_server())
4119		default_server_announce |= SV_TYPE_TIME_SOURCE;
4120
4121	if (lp_host_msdfs())
4122		default_server_announce |= SV_TYPE_DFS_SERVER;
4123}
4124
4125/***********************************************************
4126 returns role of Samba server
4127************************************************************/
4128
4129int lp_server_role(void)
4130{
4131	return server_role;
4132}
4133
4134/***********************************************************
4135 If we are PDC then prefer us as DMB
4136************************************************************/
4137
4138BOOL lp_domain_master(void)
4139{
4140	if (Globals.bDomainMaster == Auto)
4141		return (lp_server_role() == ROLE_DOMAIN_PDC);
4142
4143	return Globals.bDomainMaster;
4144}
4145
4146/***********************************************************
4147 If we are DMB then prefer us as LMB
4148************************************************************/
4149
4150BOOL lp_preferred_master(void)
4151{
4152	if (Globals.bPreferredMaster == Auto)
4153		return (lp_local_master() && lp_domain_master());
4154
4155	return Globals.bPreferredMaster;
4156}
4157
4158/*******************************************************************
4159 Remove a service.
4160********************************************************************/
4161
4162void lp_remove_service(int snum)
4163{
4164	ServicePtrs[snum]->valid = False;
4165}
4166
4167/*******************************************************************
4168 Copy a service.
4169********************************************************************/
4170
4171void lp_copy_service(int snum, const char *new_name)
4172{
4173	do_section(new_name);
4174	if (snum >= 0) {
4175		snum = lp_servicenumber(new_name);
4176		if (snum >= 0)
4177			lp_do_parameter(snum, "copy", lp_servicename(snum));
4178	}
4179}
4180
4181
4182/*******************************************************************
4183 Get the default server type we will announce as via nmbd.
4184********************************************************************/
4185
4186int lp_default_server_announce(void)
4187{
4188	return default_server_announce;
4189}
4190
4191/*******************************************************************
4192 Split the announce version into major and minor numbers.
4193********************************************************************/
4194
4195int lp_major_announce_version(void)
4196{
4197	static BOOL got_major = False;
4198	static int major_version = DEFAULT_MAJOR_VERSION;
4199	char *vers;
4200	char *p;
4201
4202	if (got_major)
4203		return major_version;
4204
4205	got_major = True;
4206	if ((vers = lp_announce_version()) == NULL)
4207		return major_version;
4208
4209	if ((p = strchr_m(vers, '.')) == 0)
4210		return major_version;
4211
4212	*p = '\0';
4213	major_version = atoi(vers);
4214	return major_version;
4215}
4216
4217int lp_minor_announce_version(void)
4218{
4219	static BOOL got_minor = False;
4220	static int minor_version = DEFAULT_MINOR_VERSION;
4221	char *vers;
4222	char *p;
4223
4224	if (got_minor)
4225		return minor_version;
4226
4227	got_minor = True;
4228	if ((vers = lp_announce_version()) == NULL)
4229		return minor_version;
4230
4231	if ((p = strchr_m(vers, '.')) == 0)
4232		return minor_version;
4233
4234	p++;
4235	minor_version = atoi(p);
4236	return minor_version;
4237}
4238
4239/***********************************************************
4240 Set the global name resolution order (used in smbclient).
4241************************************************************/
4242
4243void lp_set_name_resolve_order(const char *new_order)
4244{
4245	string_set(&Globals.szNameResolveOrder, new_order);
4246}
4247
4248const char *lp_printername(int snum)
4249{
4250	const char *ret = _lp_printername(snum);
4251	if (ret == NULL || (ret != NULL && *ret == '\0'))
4252		ret = lp_const_servicename(snum);
4253
4254	return ret;
4255}
4256
4257
4258/****************************************************************
4259 Compatibility fn. for 2.2.2 code.....
4260*****************************************************************/
4261
4262void get_private_directory(pstring privdir)
4263{
4264	pstrcpy (privdir, lp_private_dir());
4265}
4266
4267/***********************************************************
4268 Allow daemons such as winbindd to fix their logfile name.
4269************************************************************/
4270
4271void lp_set_logfile(const char *name)
4272{
4273	string_set(&Globals.szLogFile, name);
4274	pstrcpy(debugf, name);
4275}
4276
4277/*******************************************************************
4278 Return the max print jobs per queue.
4279********************************************************************/
4280
4281int lp_maxprintjobs(int snum)
4282{
4283	int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4284	if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4285		maxjobs = PRINT_MAX_JOBID - 1;
4286
4287	return maxjobs;
4288}
4289
4290const char *lp_printcapname(void)
4291{
4292	if ((Globals.szPrintcapname != NULL) &&
4293	    (Globals.szPrintcapname[0] != '\0'))
4294		return Globals.szPrintcapname;
4295
4296	if (sDefault.iPrinting == PRINT_CUPS) {
4297#ifdef HAVE_CUPS
4298		return "cups";
4299#else
4300		return "lpstat";
4301#endif
4302	}
4303
4304	if (sDefault.iPrinting == PRINT_BSD)
4305		return "/etc/printcap";
4306
4307	return PRINTCAP_NAME;
4308}
4309
4310/*******************************************************************
4311 Ensure we don't use sendfile if server smb signing is active.
4312********************************************************************/
4313
4314BOOL lp_use_sendfile(int snum)
4315{
4316	extern enum protocol_types Protocol;
4317	/* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4318	if (Protocol < PROTOCOL_NT1) {
4319		return False;
4320	}
4321	return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
4322}
4323
4324/*******************************************************************
4325 Turn off sendfile if we find the underlying OS doesn't support it.
4326********************************************************************/
4327
4328void set_use_sendfile(int snum, BOOL val)
4329{
4330	if (LP_SNUM_OK(snum))
4331		ServicePtrs[snum]->bUseSendfile = val;
4332	else
4333		sDefault.bUseSendfile = val;
4334}
4335
4336/*******************************************************************
4337 Turn off storing DOS attributes if this share doesn't support it.
4338********************************************************************/
4339
4340void set_store_dos_attributes(int snum, BOOL val)
4341{
4342	if (!LP_SNUM_OK(snum))
4343		return;
4344	ServicePtrs[(snum)]->bStoreDosAttributes = val;
4345}
4346