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