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