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