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