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