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