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