871fc774a5c65ef1a75a210fb7fdd03794d0995c
[samba.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
75 #ifndef GLOBAL_NAME
76 #define GLOBAL_NAME "global"
77 #endif
78
79 #ifndef PRINTERS_NAME
80 #define PRINTERS_NAME "printers"
81 #endif
82
83 #ifndef HOMES_NAME
84 #define HOMES_NAME "homes"
85 #endif
86
87 /* some helpful bits */
88 #define pSERVICE(i) ServicePtrs[i]
89 #define iSERVICE(i) (*pSERVICE(i))
90 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
91 #define VALID(i) iSERVICE(i).valid
92
93 int keepalive=DEFAULT_KEEPALIVE;
94 extern BOOL use_getwd_cache;
95
96 extern int extra_time_offset;
97
98 static BOOL defaults_saved=False;
99
100 /* 
101  * This structure describes global (ie., server-wide) parameters.
102  */
103 typedef struct
104 {
105   char *szPrintcapname;
106   char *szLockDir;
107   char *szRootdir;
108   char *szDefaultService;
109   char *szDfree;
110   char *szMsgCommand;
111   char *szHostsEquiv;
112   char *szServerString;
113   char *szAutoServices;
114   char *szPasswdProgram;
115   char *szPasswdChat;
116   char *szLogFile;
117   char *szConfigFile;
118   char *szSMBPasswdFile;
119   char *szSMBPassGroupFile;
120   char *szSMBGroupFile;
121   char *szSMBAliasFile;
122   char *szPasswordServer;
123   char *szSocketOptions;
124   char *szValidChars;
125   char *szWorkGroup;
126   char *szUsernameMap;
127   char *szAliasnameMap;
128   char *szGroupnameMap;
129   char *szBuiltinnameMap;
130   char *szNTusernameMap;
131   char *szCharacterSet;
132   char *szLogonScript;
133   char *szLogonPath;
134   char *szLogonDrive;
135   char *szLogonHome;
136   char *szSmbrun;
137   char *szWINSserver;
138   char *szCodingSystem;
139   char *szInterfaces;
140   char *szRemoteAnnounce;
141   char *szRemoteBrowseSync;
142   char *szSocketAddress;
143   char *szNISHomeMapName;
144   char *szAnnounceVersion; /* This is initialised in init_globals */
145   char *szNetbiosAliases;
146   char *szDomainOtherSIDs;
147   char *szDriverFile;
148   char *szNameResolveOrder;
149   char *szLdapServer;
150   char *szLdapSuffix;
151   char *szLdapFilter;
152   char *szLdapRoot;
153   char *szLdapRootPassword; 
154   char *szPanicAction;
155   int max_log_size;
156   int mangled_stack;
157   int max_xmit;
158   int max_mux;
159   int max_open_files;
160   int max_packet;
161   int pwordlevel;
162   int unamelevel;
163   int deadtime;
164   int maxprotocol;
165   int security;
166   int maxdisksize;
167   int lpqcachetime;
168   int syslog;
169   int os_level;
170   int max_ttl;
171   int max_wins_ttl;
172   int min_wins_ttl;
173   int ReadSize;
174   int lm_announce;
175   int lm_interval;
176   int shmem_size;
177   int client_code_page;
178   int announce_as;   /* This is initialised in init_globals */
179   int machine_password_timeout;
180   int change_notify_timeout;
181   int stat_cache_size;
182   int map_to_guest;
183 #ifdef WITH_LDAP
184   int ldap_port;
185 #endif /* WITH_LDAP */
186 #ifdef WITH_SSL
187   int sslVersion;
188   char *sslHostsRequire;
189   char *sslHostsResign;
190   char *sslCaCertDir;
191   char *sslCaCertFile;
192   char *sslCert;
193   char *sslPrivKey;
194   char *sslClientCert;
195   char *sslClientPrivKey;
196   char *sslCiphers;
197   BOOL sslEnabled;
198   BOOL sslReqClientCert;
199   BOOL sslReqServerCert;
200   BOOL sslCompatibility;
201 #endif /* WITH_SSL */
202   BOOL bDNSproxy;
203   BOOL bWINSsupport;
204   BOOL bWINSproxy;
205   BOOL bLocalMaster;
206   BOOL bPreferredMaster;
207   BOOL bDomainMaster;
208   BOOL bDomainLogons;
209   BOOL bEncryptPasswords;
210   BOOL bUpdateEncrypt;
211   BOOL bStripDot;
212   BOOL bNullPasswords;
213   BOOL bLoadPrinters;
214   BOOL bUseRhosts;
215   BOOL bReadRaw;
216   BOOL bWriteRaw;
217   BOOL bReadPrediction;
218   BOOL bReadbmpx;
219   BOOL bSyslogOnly;
220   BOOL bBrowseList;
221   BOOL bUnixRealname;
222   BOOL bNISHomeMap;
223   BOOL bTimeServer;
224   BOOL bBindInterfacesOnly;
225   BOOL bUnixPasswdSync;
226   BOOL bPasswdChatDebug;
227   BOOL bOleLockingCompat;
228   BOOL bTimestampLogs;
229   BOOL bNTSmbSupport;
230   BOOL bNTPipeSupport;
231   BOOL bStatCache;
232   BOOL bKernelOplocks;
233 } global;
234
235 static global Globals;
236
237
238
239 /* 
240  * This structure describes a single service. 
241  */
242 typedef struct
243 {
244   BOOL valid;
245   char *szService;
246   char *szPath;
247   char *szUsername;
248   char *szGuestaccount;
249   char *szInvalidUsers;
250   char *szValidUsers;
251   char *szAdminUsers;
252   char *szCopy;
253   char *szInclude;
254   char *szPreExec;
255   char *szPostExec;
256   char *szRootPreExec;
257   char *szRootPostExec;
258   char *szPrintcommand;
259   char *szLpqcommand;
260   char *szLprmcommand;
261   char *szLppausecommand;
262   char *szLpresumecommand;
263   char *szQueuepausecommand;
264   char *szQueueresumecommand;
265   char *szPrintername;
266   char *szPrinterDriver;
267   char *szPrinterDriverLocation;
268   char *szDontdescend;
269   char *szHostsallow;
270   char *szHostsdeny;
271   char *szMagicScript;
272   char *szMagicOutput;
273   char *szMangledMap;
274   char *szVetoFiles;
275   char *szHideFiles;
276   char *szVetoOplockFiles;
277   char *comment;
278   char *force_user;
279   char *force_group;
280   char *readlist;
281   char *writelist;
282   char *volume;
283   char *fstype;
284   int  iMinPrintSpace;
285   int  iCreate_mask;
286   int  iCreate_force_mode;
287   int  iDir_mask;
288   int  iDir_force_mode;
289   int  iMaxConnections;
290   int  iDefaultCase;
291   int  iPrinting;
292   BOOL bAlternatePerm;
293   BOOL bRevalidate;
294   BOOL bCaseSensitive;
295   BOOL bCasePreserve;
296   BOOL bShortCasePreserve;
297   BOOL bCaseMangle;
298   BOOL status;
299   BOOL bHideDotFiles;
300   BOOL bBrowseable;
301   BOOL bAvailable;
302   BOOL bRead_only;
303   BOOL bNo_set_dir;
304   BOOL bGuest_only;
305   BOOL bGuest_ok;
306   BOOL bPrint_ok;
307   BOOL bPostscript;
308   BOOL bMap_system;
309   BOOL bMap_hidden;
310   BOOL bMap_archive;
311   BOOL bLocking;
312   BOOL bStrictLocking;
313   BOOL bShareModes;
314   BOOL bOpLocks;
315   BOOL bOnlyUser;
316   BOOL bMangledNames;
317   BOOL bWidelinks;
318   BOOL bSymlinks;
319   BOOL bSyncAlways;
320   BOOL bStrictSync;
321   char magic_char;
322   BOOL *copymap;
323   BOOL bDeleteReadonly;
324   BOOL bFakeOplocks;
325   BOOL bDeleteVetoFiles;
326   BOOL bDosFiletimes;
327   BOOL bDosFiletimeResolution;
328   BOOL bFakeDirCreateTimes;
329   BOOL bBlockingLocks;
330   char dummy[3]; /* for alignment */
331 } service;
332
333
334 /* This is a default service used to prime a services structure */
335 static service sDefault = 
336 {
337   True,   /* valid */
338   NULL,    /* szService */
339   NULL,    /* szPath */
340   NULL,    /* szUsername */
341   NULL,    /* szGuestAccount  - this is set in init_globals() */
342   NULL,    /* szInvalidUsers */
343   NULL,    /* szValidUsers */
344   NULL,    /* szAdminUsers */
345   NULL,    /* szCopy */
346   NULL,    /* szInclude */
347   NULL,    /* szPreExec */
348   NULL,    /* szPostExec */
349   NULL,    /* szRootPreExec */
350   NULL,    /* szRootPostExec */
351   NULL,    /* szPrintcommand */
352   NULL,    /* szLpqcommand */
353   NULL,    /* szLprmcommand */
354   NULL,    /* szLppausecommand */
355   NULL,    /* szLpresumecommand */
356   NULL,    /* szQueuepausecommand */
357   NULL,    /* szQueueresumecommand */
358   NULL,    /* szPrintername */
359   NULL,    /* szPrinterDriver - this is set in init_globals() */
360   NULL,    /* szPrinterDriverLocation */
361   NULL,    /* szDontdescend */
362   NULL,    /* szHostsallow */
363   NULL,    /* szHostsdeny */
364   NULL,    /* szMagicScript */
365   NULL,    /* szMagicOutput */
366   NULL,    /* szMangledMap */
367   NULL,    /* szVetoFiles */
368   NULL,    /* szHideFiles */
369   NULL,    /* szVetoOplockFiles */
370   NULL,    /* comment */
371   NULL,    /* force user */
372   NULL,    /* force group */
373   NULL,    /* readlist */
374   NULL,    /* writelist */
375   NULL,    /* volume */
376   NULL,    /* fstype */
377   0,       /* iMinPrintSpace */
378   0744,    /* iCreate_mask */
379   0000,    /* iCreate_force_mode */
380   0755,    /* iDir_mask */
381   0000,    /* iDir_force_mode */
382   0,       /* iMaxConnections */
383   CASE_LOWER, /* iDefaultCase */
384   DEFAULT_PRINTING, /* iPrinting */
385   False,   /* bAlternatePerm */
386   False,   /* revalidate */
387   False,   /* case sensitive */
388   True,   /* case preserve */
389   True,   /* short case preserve */
390   False,  /* case mangle */
391   True,  /* status */
392   True,  /* bHideDotFiles */
393   True,  /* bBrowseable */
394   True,  /* bAvailable */
395   True,  /* bRead_only */
396   True,  /* bNo_set_dir */
397   False, /* bGuest_only */
398   False, /* bGuest_ok */
399   False, /* bPrint_ok */
400   False, /* bPostscript */
401   False, /* bMap_system */
402   False, /* bMap_hidden */
403   True,  /* bMap_archive */
404   True,  /* bLocking */
405   False,  /* bStrictLocking */
406   True,  /* bShareModes */
407   True,  /* bOpLocks */
408   False, /* bOnlyUser */
409   True,  /* bMangledNames */
410   True,  /* bWidelinks */
411   True,  /* bSymlinks */
412   False, /* bSyncAlways */
413   False, /* bStrictSync */
414   '~',   /* magic char */
415   NULL,  /* copymap */
416   False, /* bDeleteReadonly */
417   False, /* bFakeOplocks */
418   False, /* bDeleteVetoFiles */
419   False, /* bDosFiletimes */
420   False, /* bDosFiletimeResolution */
421   False, /* bFakeDirCreateTimes */
422   True,  /* bBlockingLocks */
423   ""     /* dummy */
424 };
425
426
427
428 /* local variables */
429 static service **ServicePtrs = NULL;
430 static int iNumServices = 0;
431 static int iServiceIndex = 0;
432 static BOOL bInGlobalSection = True;
433 static BOOL bGlobalOnly = False;
434 static int default_server_announce;
435
436 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
437
438 /* prototypes for the special type handlers */
439 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
440 static BOOL handle_include(char *pszParmValue, char **ptr);
441 static BOOL handle_copy(char *pszParmValue, char **ptr);
442 static BOOL handle_character_set(char *pszParmValue,char **ptr);
443 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
444
445 static void set_default_server_announce_type(void);
446
447 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"}, 
448                                            {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"}, 
449                                            {PROTOCOL_COREPLUS, "COREPLUS"}, 
450                                            {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
451
452 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"},  {SEC_USER, "USER"}, 
453                                            {SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"},
454                                            {-1, NULL}};
455
456 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"}, 
457                                            {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
458                                            {PRINT_QNX, "qnx"},   {PRINT_PLP, "plp"},
459                                            {PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"},
460                                            {-1, NULL}};
461
462 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
463                                               {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
464
465 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
466
467 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
468
469 /* 
470    Do you want session setups at user level security with a invalid
471    password to be rejected or allowed in as guest? WinNT rejects them
472    but it can be a pain as it means "net view" needs to use a password
473
474    You have 3 choices in the setting of map_to_guest:
475
476    "Never" means session setups with an invalid password
477    are rejected. This is the default.
478
479    "Bad User" means session setups with an invalid password
480    are rejected, unless the username does not exist, in which case it
481    is treated as a guest login
482
483    "Bad Password" means session setups with an invalid password
484    are treated as a guest login
485
486    Note that map_to_guest only has an effect in user or server
487    level security.
488 */
489
490 static struct enum_list enum_map_to_guest[] = {{NEVER_MAP_TO_GUEST, "Never"}, {MAP_TO_GUEST_ON_BAD_USER, "Bad User"}, {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"}, {-1, NULL}};
491
492 #ifdef WITH_SSL
493 static struct enum_list enum_ssl_version[] = {{SMB_SSL_V2, "ssl2"}, {SMB_SSL_V3, "ssl3"},
494   {SMB_SSL_V23, "ssl2or3"}, {SMB_SSL_TLS1, "tls1"}, {-1, NULL}};
495 #endif
496
497 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
498 static struct parm_struct parm_table[] =
499 {
500   {"Base Options", P_SEP, P_SEPARATOR},
501
502   {"comment",          P_STRING,  P_LOCAL,  &sDefault.comment,          NULL,   NULL,  FLAG_BASIC|FLAG_PRINT},
503   {"path",             P_STRING,  P_LOCAL,  &sDefault.szPath,           NULL,   NULL,  FLAG_BASIC|FLAG_PRINT},
504   {"directory",        P_STRING,  P_LOCAL,  &sDefault.szPath,           NULL,   NULL,  0},
505   {"workgroup",        P_USTRING, P_GLOBAL, &Globals.szWorkGroup,       NULL,   NULL,  FLAG_BASIC},
506   {"netbios name",     P_UGSTRING,P_GLOBAL, global_myname,                     NULL,   NULL,  FLAG_BASIC},
507   {"netbios aliases",  P_STRING,  P_GLOBAL, &Globals.szNetbiosAliases,  NULL,   NULL,  0},
508   {"server string",    P_STRING,  P_GLOBAL, &Globals.szServerString,    NULL,   NULL,  FLAG_BASIC},
509   {"interfaces",       P_STRING,  P_GLOBAL, &Globals.szInterfaces,      NULL,   NULL,  FLAG_BASIC},
510   {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL,   NULL,  0},
511
512   {"Security Options", P_SEP, P_SEPARATOR},
513
514   {"security",         P_ENUM,    P_GLOBAL, &Globals.security,          NULL,   enum_security, FLAG_BASIC},
515   {"encrypt passwords",P_BOOL,    P_GLOBAL, &Globals.bEncryptPasswords, NULL,   NULL,  FLAG_BASIC},
516   {"update encrypted", P_BOOL,    P_GLOBAL, &Globals.bUpdateEncrypt,    NULL,   NULL,  FLAG_BASIC},
517   {"use rhosts",       P_BOOL,    P_GLOBAL, &Globals.bUseRhosts,        NULL,   NULL,  0},
518   {"map to guest",     P_ENUM,    P_GLOBAL, &Globals.map_to_guest,      NULL,   enum_map_to_guest, 0},
519   {"null passwords",   P_BOOL,    P_GLOBAL, &Globals.bNullPasswords,    NULL,   NULL,  0},
520   {"password server",  P_STRING,  P_GLOBAL, &Globals.szPasswordServer,  NULL,   NULL,  0},
521   {"smb passwd file",  P_STRING,  P_GLOBAL, &Globals.szSMBPasswdFile,   NULL,   NULL,  0},
522 #if USE_SMBFILE_DB
523   {"smb passgrp file", P_STRING,  P_GLOBAL, &Globals.szSMBPassGroupFile, NULL,   NULL,  0},
524 #endif
525 #if USE_SMBGROUP_DB
526   {"smb group file",   P_STRING,  P_GLOBAL, &Globals.szSMBGroupFile,    NULL,   NULL,  0},
527   {"smb alias file",   P_STRING,  P_GLOBAL, &Globals.szSMBAliasFile,    NULL,   NULL,  0},
528 #endif
529   {"hosts equiv",      P_STRING,  P_GLOBAL, &Globals.szHostsEquiv,      NULL,   NULL,  0},
530   {"root directory",   P_STRING,  P_GLOBAL, &Globals.szRootdir,         NULL,   NULL,  0},
531   {"root dir",         P_STRING,  P_GLOBAL, &Globals.szRootdir,         NULL,   NULL,  0},
532   {"root",             P_STRING,  P_GLOBAL, &Globals.szRootdir,         NULL,   NULL,  0},
533   {"passwd program",   P_STRING,  P_GLOBAL, &Globals.szPasswdProgram,   NULL,   NULL,  0},
534   {"passwd chat",      P_STRING,  P_GLOBAL, &Globals.szPasswdChat,      NULL,   NULL,  0},
535   {"passwd chat debug",P_BOOL,    P_GLOBAL, &Globals.bPasswdChatDebug,  NULL,   NULL,  0},
536   {"username map",     P_STRING,  P_GLOBAL, &Globals.szUsernameMap,     NULL,   NULL,  0},
537   {"password level",   P_INTEGER, P_GLOBAL, &Globals.pwordlevel,        NULL,   NULL,  0},
538   {"username level",   P_INTEGER, P_GLOBAL, &Globals.unamelevel,        NULL,   NULL,  0},
539   {"unix password sync", P_BOOL,  P_GLOBAL, &Globals.bUnixPasswdSync,   NULL,   NULL,  0},
540   {"alternate permissions",P_BOOL,P_LOCAL,  &sDefault.bAlternatePerm,   NULL,   NULL,  FLAG_GLOBAL|FLAG_DEPRECATED},
541   {"revalidate",       P_BOOL,    P_LOCAL,  &sDefault.bRevalidate,      NULL,   NULL,  FLAG_GLOBAL},
542   {"username",         P_STRING,  P_LOCAL,  &sDefault.szUsername,       NULL,   NULL,  FLAG_GLOBAL},
543   {"user",             P_STRING,  P_LOCAL,  &sDefault.szUsername,       NULL,   NULL,  0},
544   {"users",            P_STRING,  P_LOCAL,  &sDefault.szUsername,       NULL,   NULL,  0},
545   {"guest account",    P_STRING,  P_LOCAL,  &sDefault.szGuestaccount,   NULL,   NULL,  FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
546   {"invalid users",    P_STRING,  P_LOCAL,  &sDefault.szInvalidUsers,   NULL,   NULL,  FLAG_GLOBAL},
547   {"valid users",      P_STRING,  P_LOCAL,  &sDefault.szValidUsers,     NULL,   NULL,  FLAG_GLOBAL},
548   {"admin users",      P_STRING,  P_LOCAL,  &sDefault.szAdminUsers,     NULL,   NULL,  FLAG_GLOBAL},
549   {"read list",        P_STRING,  P_LOCAL,  &sDefault.readlist,         NULL,   NULL,  FLAG_GLOBAL},
550   {"write list",       P_STRING,  P_LOCAL,  &sDefault.writelist,        NULL,   NULL,  FLAG_GLOBAL},
551   {"force user",       P_STRING,  P_LOCAL,  &sDefault.force_user,       NULL,   NULL,  0},
552   {"force group",      P_STRING,  P_LOCAL,  &sDefault.force_group,      NULL,   NULL,  0},
553   {"group",            P_STRING,  P_LOCAL,  &sDefault.force_group,      NULL,   NULL,  0},
554   {"read only",        P_BOOL,    P_LOCAL,  &sDefault.bRead_only,       NULL,   NULL,  FLAG_BASIC},
555   {"write ok",         P_BOOLREV, P_LOCAL,  &sDefault.bRead_only,       NULL,   NULL,  0},
556   {"writeable",        P_BOOLREV, P_LOCAL,  &sDefault.bRead_only,       NULL,   NULL,  0},
557   {"writable",         P_BOOLREV, P_LOCAL,  &sDefault.bRead_only,       NULL,   NULL,  0},
558   {"create mask",      P_OCTAL,   P_LOCAL,  &sDefault.iCreate_mask,     NULL,   NULL,  FLAG_GLOBAL},
559   {"create mode",      P_OCTAL,   P_LOCAL,  &sDefault.iCreate_mask,     NULL,   NULL,  FLAG_GLOBAL},
560   {"force create mode",P_OCTAL,   P_LOCAL,  &sDefault.iCreate_force_mode,     NULL,   NULL,  FLAG_GLOBAL},
561   {"directory mask",   P_OCTAL,   P_LOCAL,  &sDefault.iDir_mask,        NULL,   NULL,  FLAG_GLOBAL},
562   {"directory mode",   P_OCTAL,   P_LOCAL,  &sDefault.iDir_mask,        NULL,   NULL,  FLAG_GLOBAL},
563   {"force directory mode",   P_OCTAL,   P_LOCAL,  &sDefault.iDir_force_mode,        NULL,   NULL,  FLAG_GLOBAL},
564   {"guest only",       P_BOOL,    P_LOCAL,  &sDefault.bGuest_only,      NULL,   NULL,  0},
565   {"only guest",       P_BOOL,    P_LOCAL,  &sDefault.bGuest_only,      NULL,   NULL,  0},
566   {"guest ok",         P_BOOL,    P_LOCAL,  &sDefault.bGuest_ok,        NULL,   NULL,  FLAG_BASIC|FLAG_PRINT},
567   {"public",           P_BOOL,    P_LOCAL,  &sDefault.bGuest_ok,        NULL,   NULL,  0},
568   {"only user",        P_BOOL,    P_LOCAL,  &sDefault.bOnlyUser,        NULL,   NULL,  0},
569   {"hosts allow",      P_STRING,  P_LOCAL,  &sDefault.szHostsallow,     NULL,   NULL,  FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
570   {"allow hosts",      P_STRING,  P_LOCAL,  &sDefault.szHostsallow,     NULL,   NULL,  0},
571   {"hosts deny",       P_STRING,  P_LOCAL,  &sDefault.szHostsdeny,      NULL,   NULL,  FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
572   {"deny hosts",       P_STRING,  P_LOCAL,  &sDefault.szHostsdeny,      NULL,   NULL,  0},
573
574 #ifdef WITH_SSL
575   {"Secure Socket Layer Options", P_SEP, P_SEPARATOR},
576
577   {"ssl",              P_BOOL,    P_GLOBAL, &Globals.sslEnabled,        NULL,   NULL,  0 },
578   {"ssl hosts",        P_STRING,  P_GLOBAL, &Globals.sslHostsRequire,   NULL,   NULL,  0 },
579   {"ssl hosts resign", P_STRING,  P_GLOBAL, &Globals.sslHostsResign,   NULL,   NULL,  0} ,
580   {"ssl CA certDir",   P_STRING,  P_GLOBAL, &Globals.sslCaCertDir,      NULL,   NULL,  0 },
581   {"ssl CA certFile",  P_STRING,  P_GLOBAL, &Globals.sslCaCertFile,     NULL,   NULL,  0 },
582   {"ssl server cert",  P_STRING,  P_GLOBAL, &Globals.sslCert,           NULL,   NULL,  0 },
583   {"ssl server key",   P_STRING,  P_GLOBAL, &Globals.sslPrivKey,        NULL,   NULL,  0 },
584   {"ssl client cert",  P_STRING,  P_GLOBAL, &Globals.sslClientCert,     NULL,   NULL,  0 },
585   {"ssl client key",   P_STRING,  P_GLOBAL, &Globals.sslClientPrivKey,  NULL,   NULL,  0 },
586   {"ssl require clientcert",  P_BOOL,  P_GLOBAL, &Globals.sslReqClientCert, NULL,   NULL ,  0},
587   {"ssl require servercert",  P_BOOL,  P_GLOBAL, &Globals.sslReqServerCert, NULL,   NULL ,  0},
588   {"ssl ciphers",      P_STRING,  P_GLOBAL, &Globals.sslCiphers,        NULL,   NULL,  0 },
589   {"ssl version",      P_ENUM,    P_GLOBAL, &Globals.sslVersion,        NULL,   enum_ssl_version, 0},
590   {"ssl compatibility", P_BOOL,    P_GLOBAL, &Globals.sslCompatibility, NULL,   NULL,  0 },
591 #endif        /* WITH_SSL */
592
593   {"Logging Options", P_SEP, P_SEPARATOR},
594
595   {"log level",        P_INTEGER, P_GLOBAL, &DEBUGLEVEL,                NULL,   NULL,  FLAG_BASIC},
596   {"debuglevel",       P_INTEGER, P_GLOBAL, &DEBUGLEVEL,                NULL,   NULL,  0},
597   {"syslog",           P_INTEGER, P_GLOBAL, &Globals.syslog,            NULL,   NULL,  0},
598   {"syslog only",      P_BOOL,    P_GLOBAL, &Globals.bSyslogOnly,       NULL,   NULL,  0},
599   {"log file",         P_STRING,  P_GLOBAL, &Globals.szLogFile,         NULL,   NULL,  0},
600   {"max log size",     P_INTEGER, P_GLOBAL, &Globals.max_log_size,      NULL,   NULL,  0},
601   {"timestamp logs",   P_BOOL,    P_GLOBAL, &Globals.bTimestampLogs,    NULL,   NULL,  0},
602   {"debug timestamp",  P_BOOL,    P_GLOBAL, &Globals.bTimestampLogs,    NULL,   NULL,  0},
603   {"status",           P_BOOL,    P_LOCAL,  &sDefault.status,           NULL,   NULL,  FLAG_GLOBAL},
604
605   {"Protocol Options", P_SEP, P_SEPARATOR},
606
607   {"protocol",         P_ENUM,    P_GLOBAL, &Globals.maxprotocol,       NULL,   enum_protocol, 0},
608   {"read bmpx",        P_BOOL,    P_GLOBAL, &Globals.bReadbmpx,         NULL,   NULL,  0},
609   {"read raw",         P_BOOL,    P_GLOBAL, &Globals.bReadRaw,          NULL,   NULL,  0},
610   {"write raw",        P_BOOL,    P_GLOBAL, &Globals.bWriteRaw,         NULL,   NULL,  0},
611   {"nt smb support",   P_BOOL,    P_GLOBAL, &Globals.bNTSmbSupport,    NULL,   NULL,  0},
612   {"nt pipe support",   P_BOOL,    P_GLOBAL, &Globals.bNTPipeSupport,    NULL,   NULL,  0},
613   {"announce version", P_STRING,  P_GLOBAL, &Globals.szAnnounceVersion, NULL,   NULL,  0},
614   {"announce as",      P_ENUM,    P_GLOBAL, &Globals.announce_as,       NULL,   enum_announce_as, 0},
615   {"max mux",          P_INTEGER, P_GLOBAL, &Globals.max_mux,           NULL,   NULL,  0},
616   {"max xmit",         P_INTEGER, P_GLOBAL, &Globals.max_xmit,          NULL,   NULL,  0},
617   {"name resolve order",  P_STRING,  P_GLOBAL, &Globals.szNameResolveOrder,  NULL,   NULL, 0},
618   {"max packet",       P_INTEGER, P_GLOBAL, &Globals.max_packet,        NULL,   NULL,  0},
619   {"packet size",      P_INTEGER, P_GLOBAL, &Globals.max_packet,        NULL,   NULL,  0},
620   {"max ttl",          P_INTEGER, P_GLOBAL, &Globals.max_ttl,           NULL,   NULL,  0},
621   {"max wins ttl",     P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl,      NULL,   NULL,  0},
622   {"min wins ttl",     P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl,      NULL,   NULL,  0},
623   {"time server",      P_BOOL,    P_GLOBAL, &Globals.bTimeServer,       NULL,   NULL,  0},
624
625   {"Tuning Options", P_SEP, P_SEPARATOR},
626
627   {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL,   NULL,  0},
628   {"deadtime",         P_INTEGER, P_GLOBAL, &Globals.deadtime,          NULL,   NULL,  0},
629   {"getwd cache",      P_BOOL,    P_GLOBAL, &use_getwd_cache,           NULL,   NULL,  0},
630   {"keepalive",        P_INTEGER, P_GLOBAL, &keepalive,                 NULL,   NULL,  0},
631   {"lpq cache time",   P_INTEGER, P_GLOBAL, &Globals.lpqcachetime,      NULL,   NULL,  0},
632   {"max connections",  P_INTEGER, P_LOCAL,  &sDefault.iMaxConnections,  NULL,   NULL,  0},
633   {"max disk size",    P_INTEGER, P_GLOBAL, &Globals.maxdisksize,       NULL,   NULL,  0},
634   {"max open files",   P_INTEGER, P_GLOBAL, &Globals.max_open_files,    NULL,   NULL,  0},
635   {"min print space",  P_INTEGER, P_LOCAL,  &sDefault.iMinPrintSpace,   NULL,   NULL,  0},
636   {"read prediction",  P_BOOL,    P_GLOBAL, &Globals.bReadPrediction,   NULL,   NULL,  0},
637   {"read size",        P_INTEGER, P_GLOBAL, &Globals.ReadSize,          NULL,   NULL,  0},
638   {"shared mem size",  P_INTEGER, P_GLOBAL, &Globals.shmem_size,        NULL,   NULL,  0},
639   {"socket options",   P_GSTRING, P_GLOBAL, user_socket_options,        NULL,   NULL,  0},
640   {"stat cache size",  P_INTEGER, P_GLOBAL, &Globals.stat_cache_size,   NULL,   NULL,  0},
641   {"strict sync",      P_BOOL,    P_LOCAL,  &sDefault.bStrictSync,      NULL,   NULL,  0},
642   {"sync always",      P_BOOL,    P_LOCAL,  &sDefault.bSyncAlways,      NULL,   NULL,  0},
643
644   {"Printing Options", P_SEP, P_SEPARATOR},
645
646   {"load printers",    P_BOOL,    P_GLOBAL, &Globals.bLoadPrinters,     NULL,   NULL,  0},
647   {"printcap name",    P_STRING,  P_GLOBAL, &Globals.szPrintcapname,    NULL,   NULL,  0},
648   {"printcap",         P_STRING,  P_GLOBAL, &Globals.szPrintcapname,    NULL,   NULL,  0},
649   {"printer driver file", P_STRING,  P_GLOBAL, &Globals.szDriverFile,   NULL,   NULL,  0},
650   {"print ok",         P_BOOL,    P_LOCAL,  &sDefault.bPrint_ok,        NULL,   NULL,  0},
651   {"printable",        P_BOOL,    P_LOCAL,  &sDefault.bPrint_ok,        NULL,   NULL,  0},
652   {"postscript",       P_BOOL,    P_LOCAL,  &sDefault.bPostscript,      NULL,   NULL,  FLAG_PRINT},
653   {"printing",         P_ENUM,    P_LOCAL,  &sDefault.iPrinting,        NULL,   enum_printing, FLAG_PRINT|FLAG_GLOBAL},
654   {"print command",    P_STRING,  P_LOCAL,  &sDefault.szPrintcommand,   NULL,   NULL,  FLAG_PRINT|FLAG_GLOBAL},
655   {"lpq command",      P_STRING,  P_LOCAL,  &sDefault.szLpqcommand,     NULL,   NULL,  FLAG_PRINT|FLAG_GLOBAL},
656   {"lprm command",     P_STRING,  P_LOCAL,  &sDefault.szLprmcommand,    NULL,   NULL,  FLAG_PRINT|FLAG_GLOBAL},
657   {"lppause command",  P_STRING,  P_LOCAL,  &sDefault.szLppausecommand, NULL,   NULL,  FLAG_GLOBAL},
658   {"lpresume command", P_STRING,  P_LOCAL,  &sDefault.szLpresumecommand,NULL,   NULL,  FLAG_GLOBAL},
659   {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_GLOBAL},
660   {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_GLOBAL},
661
662   {"printer name",     P_STRING,  P_LOCAL,  &sDefault.szPrintername,    NULL,   NULL,  FLAG_PRINT},
663   {"printer",          P_STRING,  P_LOCAL,  &sDefault.szPrintername,    NULL,   NULL,  0},
664   {"printer driver",   P_STRING,  P_LOCAL,  &sDefault.szPrinterDriver,  NULL,   NULL,  0},
665   {"printer driver location",   P_STRING,  P_LOCAL,  &sDefault.szPrinterDriverLocation,  NULL,   NULL,  FLAG_GLOBAL},
666
667   {"Filename Handling", P_SEP, P_SEPARATOR},
668   {"strip dot",        P_BOOL,    P_GLOBAL, &Globals.bStripDot,         NULL,   NULL,  0},
669   {"character set",    P_STRING,  P_GLOBAL, &Globals.szCharacterSet,    handle_character_set, NULL,  0},
670   {"mangled stack",    P_INTEGER, P_GLOBAL, &Globals.mangled_stack,     NULL,   NULL,  0},
671   {"coding system",    P_STRING,  P_GLOBAL, &Globals.szCodingSystem,    handle_coding_system, NULL,  0},
672   {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page,  NULL,   NULL,  0},
673   {"default case",     P_ENUM, P_LOCAL,  &sDefault.iDefaultCase,        NULL,   enum_case, 0},
674   {"case sensitive",   P_BOOL,    P_LOCAL,  &sDefault.bCaseSensitive,   NULL,   NULL,  FLAG_GLOBAL},
675   {"casesignames",     P_BOOL,    P_LOCAL,  &sDefault.bCaseSensitive,   NULL,   NULL,  0},
676   {"preserve case",    P_BOOL,    P_LOCAL,  &sDefault.bCasePreserve,    NULL,   NULL,  FLAG_GLOBAL},
677   {"short preserve case",P_BOOL,  P_LOCAL,  &sDefault.bShortCasePreserve,NULL,   NULL,  FLAG_GLOBAL},
678   {"mangle case",      P_BOOL,    P_LOCAL,  &sDefault.bCaseMangle,      NULL,   NULL,  FLAG_GLOBAL},
679   {"mangling char",    P_CHAR,    P_LOCAL,  &sDefault.magic_char,       NULL,   NULL,  FLAG_GLOBAL},
680   {"hide dot files",   P_BOOL,    P_LOCAL,  &sDefault.bHideDotFiles,    NULL,   NULL,  FLAG_GLOBAL},
681   {"delete veto files",P_BOOL,    P_LOCAL,  &sDefault.bDeleteVetoFiles, NULL,   NULL,  FLAG_GLOBAL},
682   {"veto files",       P_STRING,  P_LOCAL,  &sDefault.szVetoFiles,      NULL,   NULL,  FLAG_GLOBAL},
683   {"hide files",       P_STRING,  P_LOCAL,  &sDefault.szHideFiles,      NULL,   NULL,  FLAG_GLOBAL},
684   {"veto oplock files",P_STRING,  P_LOCAL,  &sDefault.szVetoOplockFiles,NULL,   NULL,  FLAG_GLOBAL},
685   {"map system",       P_BOOL,    P_LOCAL,  &sDefault.bMap_system,      NULL,   NULL,  FLAG_GLOBAL},
686   {"map hidden",       P_BOOL,    P_LOCAL,  &sDefault.bMap_hidden,      NULL,   NULL,  FLAG_GLOBAL},
687   {"map archive",      P_BOOL,    P_LOCAL,  &sDefault.bMap_archive,     NULL,   NULL,  FLAG_GLOBAL},
688   {"mangled names",    P_BOOL,    P_LOCAL,  &sDefault.bMangledNames,    NULL,   NULL,  FLAG_GLOBAL},
689   {"mangled map",      P_STRING,  P_LOCAL,  &sDefault.szMangledMap,     NULL,   NULL,  FLAG_GLOBAL},
690   {"stat cache",       P_BOOL,    P_GLOBAL, &Globals.bStatCache,        NULL,   NULL,  0},
691
692   {"Domain Options", P_SEP, P_SEPARATOR},
693
694   {"local group map",   P_STRING, P_GLOBAL, &Globals.szAliasnameMap,     NULL,   NULL,  0},
695   {"domain group map",  P_STRING, P_GLOBAL, &Globals.szGroupnameMap,     NULL,   NULL,  0},
696   {"builtin group map", P_STRING, P_GLOBAL, &Globals.szBuiltinnameMap,   NULL,   NULL,  0},
697   {"domain user map",   P_STRING, P_GLOBAL, &Globals.szNTusernameMap,     NULL,   NULL,  0},
698   {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout,  NULL,   NULL,  0},
699
700   {"Logon Options", P_SEP, P_SEPARATOR},
701
702   {"logon script",     P_STRING,  P_GLOBAL, &Globals.szLogonScript,     NULL,   NULL,  0},
703   {"logon path",       P_STRING,  P_GLOBAL, &Globals.szLogonPath,       NULL,   NULL,  0},
704   {"logon drive",      P_STRING,  P_GLOBAL, &Globals.szLogonDrive,      NULL,   NULL,  0},
705   {"logon home",       P_STRING,  P_GLOBAL, &Globals.szLogonHome,       NULL,   NULL,  0},
706   {"domain logons",    P_BOOL,    P_GLOBAL, &Globals.bDomainLogons,     NULL,   NULL,  0},
707
708   {"Browse Options", P_SEP, P_SEPARATOR},
709
710   {"os level",         P_INTEGER, P_GLOBAL, &Globals.os_level,          NULL,   NULL,  FLAG_BASIC},
711   {"lm announce",      P_ENUM,    P_GLOBAL, &Globals.lm_announce,       NULL,   enum_lm_announce, 0},
712   {"lm interval",      P_INTEGER, P_GLOBAL, &Globals.lm_interval,       NULL,   NULL,  0},
713   {"preferred master", P_BOOL,    P_GLOBAL, &Globals.bPreferredMaster,  NULL,   NULL,  FLAG_BASIC},
714   {"prefered master",  P_BOOL,    P_GLOBAL, &Globals.bPreferredMaster,  NULL,   NULL,  0},
715   {"local master",     P_BOOL,    P_GLOBAL, &Globals.bLocalMaster,      NULL,   NULL,  FLAG_BASIC},
716   {"domain master",    P_BOOL,    P_GLOBAL, &Globals.bDomainMaster,     NULL,   NULL,  FLAG_BASIC},
717   {"browse list",      P_BOOL,    P_GLOBAL, &Globals.bBrowseList,       NULL,   NULL,  0},
718   {"browseable",       P_BOOL,    P_LOCAL,  &sDefault.bBrowseable,      NULL,   NULL,  0},
719   {"browsable",        P_BOOL,    P_LOCAL,  &sDefault.bBrowseable,      NULL,   NULL,  0},
720
721   {"WINS Options", P_SEP, P_SEPARATOR},
722
723   {"dns proxy",        P_BOOL,    P_GLOBAL, &Globals.bDNSproxy,         NULL,   NULL,  0},
724   {"wins proxy",       P_BOOL,    P_GLOBAL, &Globals.bWINSproxy,        NULL,   NULL,  0},
725   {"wins server",      P_STRING,  P_GLOBAL, &Globals.szWINSserver,      NULL,   NULL,  FLAG_BASIC},
726   {"wins support",     P_BOOL,    P_GLOBAL, &Globals.bWINSsupport,      NULL,   NULL,  FLAG_BASIC},
727
728   {"Locking Options", P_SEP, P_SEPARATOR},
729
730   {"blocking locks",   P_BOOL,    P_LOCAL,  &sDefault.bBlockingLocks,    NULL,   NULL,  0},
731   {"fake oplocks",     P_BOOL,    P_LOCAL,  &sDefault.bFakeOplocks,     NULL,   NULL,  0},
732   {"kernel oplocks",   P_BOOL,    P_GLOBAL, &Globals.bKernelOplocks,    NULL,   NULL,  FLAG_GLOBAL},
733   {"locking",          P_BOOL,    P_LOCAL,  &sDefault.bLocking,         NULL,   NULL,  FLAG_GLOBAL},
734   {"ole locking compatibility",   P_BOOL,    P_GLOBAL,  &Globals.bOleLockingCompat,   NULL,   NULL,  FLAG_GLOBAL},
735   {"oplocks",          P_BOOL,    P_LOCAL,  &sDefault.bOpLocks,         NULL,   NULL,  FLAG_GLOBAL},
736   {"strict locking",   P_BOOL,    P_LOCAL,  &sDefault.bStrictLocking,   NULL,   NULL,  FLAG_GLOBAL},
737   {"share modes",      P_BOOL,    P_LOCAL,  &sDefault.bShareModes,      NULL,   NULL,  FLAG_GLOBAL},
738
739 #ifdef WITH_LDAP
740   {"Ldap Options", P_SEP, P_SEPARATOR},
741
742   {"ldap server",      P_STRING,  P_GLOBAL, &Globals.szLdapServer,      NULL,   NULL,  0},
743   {"ldap port",        P_INTEGER, P_GLOBAL, &Globals.ldap_port,         NULL,   NULL,  0},
744   {"ldap suffix",      P_STRING,  P_GLOBAL, &Globals.szLdapSuffix,      NULL,   NULL,  0},
745   {"ldap filter",      P_STRING,  P_GLOBAL, &Globals.szLdapFilter,      NULL,   NULL,  0},
746   {"ldap root",        P_STRING,  P_GLOBAL, &Globals.szLdapRoot,        NULL,   NULL,  0},
747   {"ldap root passwd", P_STRING,  P_GLOBAL, &Globals.szLdapRootPassword,NULL,   NULL,  0},
748 #endif /* WITH_LDAP */
749
750
751   {"Miscellaneous Options", P_SEP, P_SEPARATOR},
752
753   {"smbrun",           P_STRING,  P_GLOBAL, &Globals.szSmbrun,          NULL,   NULL,  0},
754   {"config file",      P_STRING,  P_GLOBAL, &Globals.szConfigFile,      NULL,   NULL,  FLAG_HIDE},
755   {"preload",          P_STRING,  P_GLOBAL, &Globals.szAutoServices,    NULL,   NULL,  0},
756   {"auto services",    P_STRING,  P_GLOBAL, &Globals.szAutoServices,    NULL,   NULL,  0},
757   {"lock dir",         P_STRING,  P_GLOBAL, &Globals.szLockDir,         NULL,   NULL,  0},
758   {"lock directory",   P_STRING,  P_GLOBAL, &Globals.szLockDir,         NULL,   NULL,  0},
759   {"default service",  P_STRING,  P_GLOBAL, &Globals.szDefaultService,  NULL,   NULL,  0},
760   {"default",          P_STRING,  P_GLOBAL, &Globals.szDefaultService,  NULL,   NULL,  0},
761   {"message command",  P_STRING,  P_GLOBAL, &Globals.szMsgCommand,      NULL,   NULL,  0},
762   {"dfree command",    P_STRING,  P_GLOBAL, &Globals.szDfree,           NULL,   NULL,  0},
763   {"valid chars",      P_STRING,  P_GLOBAL, &Globals.szValidChars,      handle_valid_chars, NULL,  0},
764   {"remote announce",  P_STRING,  P_GLOBAL, &Globals.szRemoteAnnounce,  NULL,   NULL,  0},
765   {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL,   NULL,  0},
766   {"socket address",   P_STRING,  P_GLOBAL, &Globals.szSocketAddress,   NULL,   NULL,  0},
767   {"homedir map",      P_STRING,  P_GLOBAL, &Globals.szNISHomeMapName,  NULL,   NULL,  0},
768   {"time offset",      P_INTEGER, P_GLOBAL, &extra_time_offset,         NULL,   NULL,  0},
769   {"unix realname",    P_BOOL,    P_GLOBAL, &Globals.bUnixRealname,     NULL,   NULL,  0},
770   {"NIS homedir",      P_BOOL,    P_GLOBAL, &Globals.bNISHomeMap,       NULL,   NULL,  0},
771   {"-valid",           P_BOOL,    P_LOCAL,  &sDefault.valid,            NULL,   NULL,  FLAG_HIDE},
772   {"copy",             P_STRING,  P_LOCAL,  &sDefault.szCopy,           handle_copy, NULL,  FLAG_HIDE},
773   {"include",          P_STRING,  P_LOCAL,  &sDefault.szInclude,        handle_include, NULL,  FLAG_HIDE},
774   {"exec",             P_STRING,  P_LOCAL,  &sDefault.szPreExec,        NULL,   NULL,  0},
775   {"preexec",          P_STRING,  P_LOCAL,  &sDefault.szPreExec,        NULL,   NULL,  0},
776   {"postexec",         P_STRING,  P_LOCAL,  &sDefault.szPostExec,       NULL,   NULL,  0},
777   {"root preexec",     P_STRING,  P_LOCAL,  &sDefault.szRootPreExec,    NULL,   NULL,  0},
778   {"root postexec",    P_STRING,  P_LOCAL,  &sDefault.szRootPostExec,   NULL,   NULL,  0},
779   {"available",        P_BOOL,    P_LOCAL,  &sDefault.bAvailable,       NULL,   NULL,  0},
780   {"volume",           P_STRING,  P_LOCAL,  &sDefault.volume,           NULL,   NULL,  0},
781   {"fstype",           P_STRING,  P_LOCAL,  &sDefault.fstype,           NULL,   NULL,  0},
782   {"set directory",    P_BOOLREV, P_LOCAL,  &sDefault.bNo_set_dir,      NULL,   NULL,  0},
783   {"wide links",       P_BOOL,    P_LOCAL,  &sDefault.bWidelinks,       NULL,   NULL,  FLAG_GLOBAL},
784   {"follow symlinks",  P_BOOL,    P_LOCAL,  &sDefault.bSymlinks,        NULL,   NULL,  FLAG_GLOBAL},
785   {"dont descend",     P_STRING,  P_LOCAL,  &sDefault.szDontdescend,    NULL,   NULL,  0},
786   {"magic script",     P_STRING,  P_LOCAL,  &sDefault.szMagicScript,    NULL,   NULL,  0},
787   {"magic output",     P_STRING,  P_LOCAL,  &sDefault.szMagicOutput,    NULL,   NULL,  0},
788   {"delete readonly",  P_BOOL,    P_LOCAL,  &sDefault.bDeleteReadonly,  NULL,   NULL,  FLAG_GLOBAL},
789   {"dos filetimes",    P_BOOL,    P_LOCAL,  &sDefault.bDosFiletimes,    NULL,   NULL,  FLAG_GLOBAL},
790   {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution,   NULL,  NULL,  FLAG_GLOBAL},
791   
792   {"fake directory create times", P_BOOL,P_LOCAL,  &sDefault.bFakeDirCreateTimes, NULL,   NULL, FLAG_GLOBAL},
793   {"panic action",     P_STRING,  P_GLOBAL, &Globals.szPanicAction,     NULL,   NULL,  0},
794
795   {NULL,               P_BOOL,    P_NONE,   NULL,                       NULL,   NULL, 0}
796 };
797
798
799
800 /***************************************************************************
801 Initialise the global parameter structure.
802 ***************************************************************************/
803 static void init_globals(void)
804 {
805   static BOOL done_init = False;
806   pstring s;
807
808   if (!done_init)
809     {
810       int i;
811       bzero((void *)&Globals,sizeof(Globals));
812
813       for (i = 0; parm_table[i].label; i++) 
814         if ((parm_table[i].type == P_STRING ||
815              parm_table[i].type == P_USTRING) && 
816             parm_table[i].ptr)
817           string_init(parm_table[i].ptr,"");
818
819       string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
820       string_set(&sDefault.szPrinterDriver, "NULL");
821       string_set(&sDefault.fstype, FSTYPE_STRING);
822
823       done_init = True;
824     }
825
826
827   DEBUG(3,("Initialising global parameters\n"));
828
829   string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
830 #if USE_SMBFILE_DB
831   string_set(&Globals.szSMBPassGroupFile, SMB_PASSGRP_FILE);
832 #endif
833 #if USE_SMBGROUP_DB
834   string_set(&Globals.szSMBGroupFile, SMB_GROUP_FILE);
835   string_set(&Globals.szSMBAliasFile, SMB_ALIAS_FILE);
836 #endif
837   string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
838   string_set(&Globals.szWorkGroup, WORKGROUP);
839   string_set(&Globals.szPasswdProgram, PASSWD_PROGRAM);
840   string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
841   string_set(&Globals.szDriverFile, DRIVERFILE);
842   string_set(&Globals.szLockDir, LOCKDIR);
843   string_set(&Globals.szRootdir, "/");
844   string_set(&Globals.szSmbrun, SMBRUN);
845   string_set(&Globals.szSocketAddress, "0.0.0.0");
846   pstrcpy(s, "Samba ");
847   pstrcat(s, VERSION);
848   string_set(&Globals.szServerString,s);
849   slprintf(s,sizeof(s)-1, "%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
850   string_set(&Globals.szAnnounceVersion,s);
851
852   pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
853
854   string_set(&Globals.szLogonDrive, "");
855   /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
856   string_set(&Globals.szLogonHome, "\\\\%N\\%U");
857   string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
858
859   string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast");
860
861   Globals.bLoadPrinters = True;
862   Globals.bUseRhosts = False;
863   Globals.max_packet = 65535;
864   Globals.mangled_stack = 50;
865   Globals.max_xmit = 65535;
866   Globals.max_mux = 50; /* This is *needed* for profile support. */
867   Globals.lpqcachetime = 10;
868   Globals.pwordlevel = 0;
869   Globals.unamelevel = 0;
870   Globals.deadtime = 0;
871   Globals.max_log_size = 5000;
872   Globals.max_open_files = MAX_OPEN_FILES;
873   Globals.maxprotocol = PROTOCOL_NT1;
874   Globals.security = SEC_USER;
875   Globals.bEncryptPasswords = False;
876   Globals.bUpdateEncrypt = False;
877   Globals.bReadRaw = True;
878   Globals.bWriteRaw = True;
879   Globals.bReadPrediction = False;
880   Globals.bReadbmpx = True;
881   Globals.bNullPasswords = False;
882   Globals.bStripDot = False;
883   Globals.syslog = 1;
884   Globals.bSyslogOnly = False;
885   Globals.bTimestampLogs = True;
886   Globals.os_level = 0;
887   Globals.max_ttl = 60*60*24*3; /* 3 days default. */
888   Globals.max_wins_ttl = 60*60*24*6; /* 6 days default. */
889   Globals.min_wins_ttl = 60*60*6; /* 6 hours default. */
890   Globals.machine_password_timeout = 60*60*24*7; /* 7 days default. */
891   Globals.change_notify_timeout = 60; /* 1 minute default. */
892   Globals.ReadSize = 16*1024;
893   Globals.lm_announce = 2;   /* = Auto: send only if LM clients found */
894   Globals.lm_interval = 60;
895   Globals.shmem_size = SHMEM_SIZE;
896   Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */
897   Globals.announce_as = ANNOUNCE_AS_NT;
898   Globals.bUnixRealname = False;
899 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
900   Globals.bNISHomeMap = False;
901 #ifdef WITH_NISPLUS_HOME
902   string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
903 #else
904   string_set(&Globals.szNISHomeMapName, "auto.home");
905 #endif
906 #endif
907   Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
908   Globals.bTimeServer = False;
909   Globals.bBindInterfacesOnly = False;
910   Globals.bUnixPasswdSync = False;
911   Globals.bPasswdChatDebug = False;
912   Globals.bOleLockingCompat = True;
913   Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */
914   Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
915   Globals.bStatCache = True; /* use stat cache by default */
916   Globals.map_to_guest = 0; /* By Default, "Never" */
917
918 #ifdef WITH_LDAP
919   /* default values for ldap */
920   string_set(&Globals.szLdapServer, "localhost");
921   Globals.ldap_port=389;
922 #endif /* WITH_LDAP */
923
924 #ifdef WITH_SSL
925   Globals.sslVersion = SMB_SSL_V23;
926   Globals.sslHostsRequire = NULL;
927   Globals.sslHostsResign = NULL;
928   Globals.sslCaCertDir = NULL;
929   Globals.sslCaCertFile = NULL;
930   Globals.sslCert = NULL;
931   Globals.sslPrivKey = NULL;
932   Globals.sslClientCert = NULL;
933   Globals.sslClientPrivKey = NULL;
934   Globals.sslCiphers = NULL;
935   Globals.sslEnabled = False;
936   Globals.sslReqClientCert = False;
937   Globals.sslReqServerCert = False;
938   Globals.sslCompatibility = False;
939 #endif        /* WITH_SSL */
940
941 /* these parameters are set to defaults that are more appropriate
942    for the increasing samba install base:
943
944    as a member of the workgroup, that will possibly become a
945    _local_ master browser (lm = True).  this is opposed to a forced
946    local master browser startup (pm = True).
947
948    doesn't provide WINS server service by default (wsupp = False),
949    and doesn't provide domain master browser services by default, either.
950
951 */
952
953   Globals.bPreferredMaster = False;
954   Globals.bLocalMaster = True;
955   Globals.bDomainMaster = False;
956   Globals.bDomainLogons = False;
957   Globals.bBrowseList = True;
958   Globals.bWINSsupport = False;
959   Globals.bWINSproxy = False;
960
961   Globals.bDNSproxy = True;
962
963   /*
964    * smbd will check at runtime to see if this value
965    * will really be used or not.
966    */
967   Globals.bKernelOplocks = True;
968
969   /*
970    * This must be done last as it checks the value in 
971    * client_code_page.
972    */
973
974   interpret_coding_system(KANJI);
975 }
976
977 /***************************************************************************
978 check if a string is initialised and if not then initialise it
979 ***************************************************************************/
980 static void string_initial(char **s,char *v)
981 {
982   if (!*s || !**s)
983     string_init(s,v);
984 }
985
986
987 /***************************************************************************
988 Initialise the sDefault parameter structure.
989 ***************************************************************************/
990 static void init_locals(void)
991 {
992   /* choose defaults depending on the type of printing */
993   switch (sDefault.iPrinting)
994     {
995     case PRINT_BSD:
996     case PRINT_AIX:
997     case PRINT_LPRNG:
998     case PRINT_PLP:
999       string_initial(&sDefault.szLpqcommand,"lpq -P%p");
1000       string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
1001       string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
1002       break;
1003
1004     case PRINT_SYSV:
1005     case PRINT_HPUX:
1006       string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
1007       string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
1008       string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
1009 #ifdef SYSV
1010       string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
1011       string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
1012       string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
1013       string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
1014 #else /* SYSV */
1015       string_initial(&sDefault.szQueuepausecommand, "disable %p");
1016       string_initial(&sDefault.szQueueresumecommand, "enable %p");
1017 #endif /* SYSV */
1018       break;
1019
1020     case PRINT_QNX:
1021       string_initial(&sDefault.szLpqcommand,"lpq -P%p");
1022       string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
1023       string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
1024       break;
1025
1026     case PRINT_SOFTQ:
1027       string_initial(&sDefault.szLpqcommand,"qstat -l -d%p");
1028       string_initial(&sDefault.szLprmcommand,"qstat -s -j%j -c");
1029       string_initial(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
1030       string_initial(&sDefault.szLppausecommand,"qstat -s -j%j -h");
1031       string_initial(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
1032       break;
1033       
1034     }
1035 }
1036
1037
1038 /******************************************************************* a
1039 convenience routine to grab string parameters into a rotating buffer,
1040 and run standard_sub_basic on them. The buffers can be written to by
1041 callers without affecting the source string.
1042 ********************************************************************/
1043 static char *lp_string(char *s)
1044 {
1045   static char *bufs[10];
1046   static int buflen[10];
1047   static int next = -1;  
1048   char *ret;
1049   int i;
1050   int len = s?strlen(s):0;
1051
1052   if (next == -1) {
1053     /* initialisation */
1054     for (i=0;i<10;i++) {
1055       bufs[i] = NULL;
1056       buflen[i] = 0;
1057     }
1058     next = 0;
1059   }
1060
1061   len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
1062                                          substitution room */
1063
1064   if (buflen[next] != len) {
1065     buflen[next] = len;
1066     if (bufs[next]) free(bufs[next]);
1067     bufs[next] = (char *)malloc(len);
1068     if (!bufs[next]) {
1069       DEBUG(0,("out of memory in lp_string()"));
1070       exit(1);
1071     }
1072   } 
1073
1074   ret = &bufs[next][0];
1075   next = (next+1)%10;
1076
1077   if (!s) 
1078     *ret = 0;
1079   else
1080     StrCpy(ret,s);
1081
1082   trim_string(ret, "\"", "\"");
1083
1084   standard_sub_basic(ret);
1085   return(ret);
1086 }
1087
1088
1089 /*
1090    In this section all the functions that are used to access the 
1091    parameters from the rest of the program are defined 
1092 */
1093
1094 #define FN_GLOBAL_STRING(fn_name,ptr) \
1095  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1096 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1097  BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1098 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1099  char fn_name(void) {return(*(char *)(ptr));}
1100 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1101  int fn_name(void) {return(*(int *)(ptr));}
1102
1103 #define FN_LOCAL_STRING(fn_name,val) \
1104  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
1105 #define FN_LOCAL_BOOL(fn_name,val) \
1106  BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1107 #define FN_LOCAL_CHAR(fn_name,val) \
1108  char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1109 #define FN_LOCAL_INTEGER(fn_name,val) \
1110  int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1111
1112 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
1113 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
1114 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
1115 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
1116 #if USE_SMBFILE_DB
1117 FN_GLOBAL_STRING(lp_smb_passgrp_file,&Globals.szSMBPassGroupFile)
1118 #endif
1119 #if USE_SMBGROUP_DB
1120 FN_GLOBAL_STRING(lp_smb_group_file,&Globals.szSMBGroupFile)
1121 FN_GLOBAL_STRING(lp_smb_alias_file,&Globals.szSMBAliasFile)
1122 #endif
1123 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
1124 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
1125 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
1126 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
1127 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
1128 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
1129 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
1130 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
1131 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
1132 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
1133 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
1134 FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder)
1135 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
1136 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
1137 FN_GLOBAL_STRING(lp_aliasname_map,&Globals.szAliasnameMap)
1138 FN_GLOBAL_STRING(lp_groupname_map,&Globals.szGroupnameMap)
1139 FN_GLOBAL_STRING(lp_builtinname_map,&Globals.szBuiltinnameMap)
1140 FN_GLOBAL_STRING(lp_ntusrname_map,&Globals.szNTusernameMap)
1141 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript) 
1142 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath) 
1143 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive) 
1144 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome) 
1145 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce) 
1146 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync) 
1147 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
1148 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
1149 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
1150 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
1151 static FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
1152 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
1153 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
1154 FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction)
1155
1156 #ifdef WITH_LDAP
1157 FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer);
1158 FN_GLOBAL_STRING(lp_ldap_suffix,&Globals.szLdapSuffix);
1159 FN_GLOBAL_STRING(lp_ldap_filter,&Globals.szLdapFilter);
1160 FN_GLOBAL_STRING(lp_ldap_root,&Globals.szLdapRoot);
1161 FN_GLOBAL_STRING(lp_ldap_rootpasswd,&Globals.szLdapRootPassword);
1162 #endif /* WITH_LDAP */
1163
1164 #ifdef WITH_SSL
1165 FN_GLOBAL_INTEGER(lp_ssl_version,&Globals.sslVersion);
1166 FN_GLOBAL_STRING(lp_ssl_hosts,&Globals.sslHostsRequire);
1167 FN_GLOBAL_STRING(lp_ssl_hosts_resign,&Globals.sslHostsResign);
1168 FN_GLOBAL_STRING(lp_ssl_cacertdir,&Globals.sslCaCertDir);
1169 FN_GLOBAL_STRING(lp_ssl_cacertfile,&Globals.sslCaCertFile);
1170 FN_GLOBAL_STRING(lp_ssl_cert,&Globals.sslCert);
1171 FN_GLOBAL_STRING(lp_ssl_privkey,&Globals.sslPrivKey);
1172 FN_GLOBAL_STRING(lp_ssl_client_cert,&Globals.sslClientCert);
1173 FN_GLOBAL_STRING(lp_ssl_client_privkey,&Globals.sslClientPrivKey);
1174 FN_GLOBAL_STRING(lp_ssl_ciphers,&Globals.sslCiphers);
1175 FN_GLOBAL_BOOL(lp_ssl_enabled,&Globals.sslEnabled);
1176 FN_GLOBAL_BOOL(lp_ssl_reqClientCert,&Globals.sslReqClientCert);
1177 FN_GLOBAL_BOOL(lp_ssl_reqServerCert,&Globals.sslReqServerCert);
1178 FN_GLOBAL_BOOL(lp_ssl_compatibility,&Globals.sslCompatibility);
1179 #endif        /* WITH_SSL */
1180
1181 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
1182 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
1183 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
1184 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
1185 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
1186 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
1187 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
1188 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
1189 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
1190 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
1191 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
1192 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
1193 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
1194 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
1195 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
1196 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
1197 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
1198 FN_GLOBAL_BOOL(lp_update_encrypted,&Globals.bUpdateEncrypt)
1199 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
1200 FN_GLOBAL_BOOL(lp_timestamp_logs,&Globals.bTimestampLogs)
1201 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
1202 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
1203 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
1204 static FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
1205 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
1206 FN_GLOBAL_BOOL(lp_unix_password_sync,&Globals.bUnixPasswdSync)
1207 FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug)
1208 FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat)
1209 FN_GLOBAL_BOOL(lp_nt_smb_support,&Globals.bNTSmbSupport)
1210 FN_GLOBAL_BOOL(lp_nt_pipe_support,&Globals.bNTPipeSupport)
1211 FN_GLOBAL_BOOL(lp_stat_cache,&Globals.bStatCache)
1212
1213 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
1214 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
1215 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
1216 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
1217 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
1218 FN_GLOBAL_INTEGER(lp_max_open_files,&Globals.max_open_files)
1219 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
1220 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
1221 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
1222 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
1223 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
1224 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
1225 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
1226 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
1227 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
1228 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
1229 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
1230 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
1231 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
1232 static FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
1233 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
1234 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
1235 FN_GLOBAL_INTEGER(lp_machine_password_timeout,&Globals.machine_password_timeout)
1236 FN_GLOBAL_INTEGER(lp_change_notify_timeout,&Globals.change_notify_timeout)
1237 FN_GLOBAL_INTEGER(lp_stat_cache_size,&Globals.stat_cache_size)
1238 FN_GLOBAL_INTEGER(lp_map_to_guest,&Globals.map_to_guest)
1239
1240 #ifdef WITH_LDAP
1241 FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port)
1242 #endif /* WITH_LDAP */
1243
1244 FN_LOCAL_STRING(lp_preexec,szPreExec)
1245 FN_LOCAL_STRING(lp_postexec,szPostExec)
1246 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
1247 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
1248 FN_LOCAL_STRING(lp_servicename,szService)
1249 FN_LOCAL_STRING(lp_pathname,szPath)
1250 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
1251 FN_LOCAL_STRING(lp_username,szUsername)
1252 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
1253 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
1254 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
1255 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
1256 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
1257 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
1258 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
1259 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
1260 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
1261 FN_LOCAL_STRING(lp_queuepausecommand,szQueuepausecommand)
1262 FN_LOCAL_STRING(lp_queueresumecommand,szQueueresumecommand)
1263 FN_LOCAL_STRING(lp_printername,szPrintername)
1264 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
1265 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
1266 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
1267 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
1268 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
1269 FN_LOCAL_STRING(lp_comment,comment)
1270 FN_LOCAL_STRING(lp_force_user,force_user)
1271 FN_LOCAL_STRING(lp_force_group,force_group)
1272 FN_LOCAL_STRING(lp_readlist,readlist)
1273 FN_LOCAL_STRING(lp_writelist,writelist)
1274 FN_LOCAL_STRING(lp_fstype,fstype)
1275 static FN_LOCAL_STRING(lp_volume,volume)
1276 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
1277 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
1278 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
1279 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
1280 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
1281
1282 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
1283 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
1284 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1285 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1286 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1287 FN_LOCAL_BOOL(lp_status,status)
1288 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1289 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1290 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1291 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1292 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1293 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1294 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1295 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1296 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1297 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1298 FN_LOCAL_BOOL(lp_locking,bLocking)
1299 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1300 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1301 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1302 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1303 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1304 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1305 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1306 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1307 FN_LOCAL_BOOL(lp_strict_sync,bStrictSync)
1308 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1309 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1310 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1311 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1312 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1313 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
1314 FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
1315 FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks)
1316
1317 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1318 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1319 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1320 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1321 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1322 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1323 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1324 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1325
1326 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1327
1328
1329
1330 /* local prototypes */
1331 static int    strwicmp( char *psz1, char *psz2 );
1332 static int    map_parameter( char *pszParmName);
1333 static BOOL   set_boolean( BOOL *pb, char *pszParmValue );
1334 static int    getservicebyname(char *pszServiceName, service *pserviceDest);
1335 static void   copy_service( service *pserviceDest, 
1336                             service *pserviceSource,
1337                             BOOL *pcopymapDest );
1338 static BOOL   service_ok(int iService);
1339 static BOOL   do_parameter(char *pszParmName, char *pszParmValue);
1340 static BOOL   do_section(char *pszSectionName);
1341 static void init_copymap(service *pservice);
1342
1343
1344 /***************************************************************************
1345 initialise a service to the defaults
1346 ***************************************************************************/
1347 static void init_service(service *pservice)
1348 {
1349   bzero((char *)pservice,sizeof(service));
1350   copy_service(pservice,&sDefault,NULL);
1351 }
1352
1353
1354 /***************************************************************************
1355 free the dynamically allocated parts of a service struct
1356 ***************************************************************************/
1357 static void free_service(service *pservice)
1358 {
1359   int i;
1360   if (!pservice)
1361      return;
1362
1363   if(pservice->szService)
1364     DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1365
1366   string_free(&pservice->szService);
1367   if (pservice->copymap)
1368   {
1369     free(pservice->copymap);
1370     pservice->copymap = NULL;
1371   }
1372  
1373   for (i=0;parm_table[i].label;i++)
1374     if ((parm_table[i].type == P_STRING ||
1375          parm_table[i].type == P_USTRING) &&
1376         parm_table[i].class == P_LOCAL)
1377       string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1378 }
1379
1380 /***************************************************************************
1381 add a new service to the services array initialising it with the given 
1382 service
1383 ***************************************************************************/
1384 static int add_a_service(service *pservice, char *name)
1385 {
1386   int i;
1387   service tservice;
1388   int num_to_alloc = iNumServices+1;
1389
1390   tservice = *pservice;
1391
1392   /* it might already exist */
1393   if (name) 
1394     {
1395       i = getservicebyname(name,NULL);
1396       if (i >= 0)
1397         return(i);
1398     }
1399
1400   /* find an invalid one */
1401   for (i=0;i<iNumServices;i++)
1402     if (!pSERVICE(i)->valid)
1403       break;
1404
1405   /* if not, then create one */
1406   if (i == iNumServices)
1407     {
1408       ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1409       if (ServicePtrs)
1410         pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1411
1412       if (!ServicePtrs || !pSERVICE(iNumServices))
1413         return(-1);
1414
1415       iNumServices++;
1416     }
1417   else
1418     free_service(pSERVICE(i));
1419
1420   pSERVICE(i)->valid = True;
1421
1422   init_service(pSERVICE(i));
1423   copy_service(pSERVICE(i),&tservice,NULL);
1424   if (name)
1425     string_set(&iSERVICE(i).szService,name);  
1426
1427   return(i);
1428 }
1429
1430 /***************************************************************************
1431 add a new home service, with the specified home directory, defaults coming 
1432 from service ifrom
1433 ***************************************************************************/
1434 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1435 {
1436   int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1437
1438   if (i < 0)
1439     return(False);
1440
1441   if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1442     string_set(&iSERVICE(i).szPath,pszHomedir);
1443   if (!(*(iSERVICE(i).comment)))
1444     {
1445       pstring comment;
1446       slprintf(comment,sizeof(comment)-1,
1447                "Home directory of %s",pszHomename);
1448       string_set(&iSERVICE(i).comment,comment);
1449     }
1450   iSERVICE(i).bAvailable = sDefault.bAvailable;
1451   iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1452
1453   DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1454
1455   return(True);
1456 }
1457
1458 /***************************************************************************
1459 add a new service, based on an old one
1460 ***************************************************************************/
1461 int lp_add_service(char *pszService, int iDefaultService)
1462 {
1463   return(add_a_service(pSERVICE(iDefaultService),pszService));
1464 }
1465
1466
1467 /***************************************************************************
1468 add the IPC service
1469 ***************************************************************************/
1470 static BOOL lp_add_ipc(void)
1471 {
1472   pstring comment;
1473   int i = add_a_service(&sDefault,"IPC$");
1474
1475   if (i < 0)
1476     return(False);
1477
1478   slprintf(comment,sizeof(comment)-1,
1479            "IPC Service (%s)", Globals.szServerString );
1480
1481   string_set(&iSERVICE(i).szPath,tmpdir());
1482   string_set(&iSERVICE(i).szUsername,"");
1483   string_set(&iSERVICE(i).comment,comment);
1484   string_set(&iSERVICE(i).fstype,"IPC");
1485   iSERVICE(i).status = False;
1486   iSERVICE(i).iMaxConnections = 0;
1487   iSERVICE(i).bAvailable = True;
1488   iSERVICE(i).bRead_only = True;
1489   iSERVICE(i).bGuest_only = False;
1490   iSERVICE(i).bGuest_ok = True;
1491   iSERVICE(i).bPrint_ok = False;
1492   iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1493
1494   DEBUG(3,("adding IPC service\n"));
1495
1496   return(True);
1497 }
1498
1499
1500 /***************************************************************************
1501 add a new printer service, with defaults coming from service iFrom
1502 ***************************************************************************/
1503 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1504 {
1505   char *comment = "From Printcap";
1506   int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1507   
1508   if (i < 0)
1509     return(False);
1510   
1511   /* note that we do NOT default the availability flag to True - */
1512   /* we take it from the default service passed. This allows all */
1513   /* dynamic printers to be disabled by disabling the [printers] */
1514   /* entry (if/when the 'available' keyword is implemented!).    */
1515   
1516   /* the printer name is set to the service name. */
1517   string_set(&iSERVICE(i).szPrintername,pszPrintername);
1518   string_set(&iSERVICE(i).comment,comment);
1519   iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1520   /* Printers cannot be read_only. */
1521   iSERVICE(i).bRead_only = False;
1522   /* No share modes on printer services. */
1523   iSERVICE(i).bShareModes = False;
1524   /* No oplocks on printer services. */
1525   iSERVICE(i).bOpLocks = False;
1526   /* Printer services must be printable. */
1527   iSERVICE(i).bPrint_ok = True;
1528   
1529   DEBUG(3,("adding printer service %s\n",pszPrintername));
1530   
1531   return(True);
1532 }
1533
1534
1535 /***************************************************************************
1536 Do a case-insensitive, whitespace-ignoring string compare.
1537 ***************************************************************************/
1538 static int strwicmp(char *psz1, char *psz2)
1539 {
1540    /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1541    /* appropriate value. */
1542    if (psz1 == psz2)
1543       return (0);
1544    else
1545       if (psz1 == NULL)
1546          return (-1);
1547       else
1548           if (psz2 == NULL)
1549               return (1);
1550
1551    /* sync the strings on first non-whitespace */
1552    while (1)
1553    {
1554       while (isspace(*psz1))
1555          psz1++;
1556       while (isspace(*psz2))
1557          psz2++;
1558       if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1559          break;
1560       psz1++;
1561       psz2++;
1562    }
1563    return (*psz1 - *psz2);
1564 }
1565
1566 /***************************************************************************
1567 Map a parameter's string representation to something we can use. 
1568 Returns False if the parameter string is not recognised, else TRUE.
1569 ***************************************************************************/
1570 static int map_parameter(char *pszParmName)
1571 {
1572    int iIndex;
1573
1574    if (*pszParmName == '-')
1575      return(-1);
1576
1577    for (iIndex = 0; parm_table[iIndex].label; iIndex++) 
1578       if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1579          return(iIndex);
1580
1581    DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1582    return(-1);
1583 }
1584
1585
1586 /***************************************************************************
1587 Set a boolean variable from the text value stored in the passed string.
1588 Returns True in success, False if the passed string does not correctly 
1589 represent a boolean.
1590 ***************************************************************************/
1591 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1592 {
1593    BOOL bRetval;
1594
1595    bRetval = True;
1596    if (strwicmp(pszParmValue, "yes") == 0 ||
1597        strwicmp(pszParmValue, "true") == 0 ||
1598        strwicmp(pszParmValue, "1") == 0)
1599       *pb = True;
1600    else
1601       if (strwicmp(pszParmValue, "no") == 0 ||
1602           strwicmp(pszParmValue, "False") == 0 ||
1603           strwicmp(pszParmValue, "0") == 0)
1604          *pb = False;
1605       else
1606       {
1607          DEBUG(0,("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1608                pszParmValue));
1609          bRetval = False;
1610       }
1611    return (bRetval);
1612 }
1613
1614 /***************************************************************************
1615 Find a service by name. Otherwise works like get_service.
1616 ***************************************************************************/
1617 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1618 {
1619    int iService;
1620
1621    for (iService = iNumServices - 1; iService >= 0; iService--)
1622       if (VALID(iService) &&
1623           strwicmp(iSERVICE(iService).szService, pszServiceName) == 0) 
1624       {
1625          if (pserviceDest != NULL)
1626            copy_service(pserviceDest, pSERVICE(iService), NULL);
1627          break;
1628       }
1629
1630    return (iService);
1631 }
1632
1633
1634
1635 /***************************************************************************
1636 Copy a service structure to another
1637
1638 If pcopymapDest is NULL then copy all fields
1639 ***************************************************************************/
1640 static void copy_service(service *pserviceDest, 
1641                          service *pserviceSource,
1642                          BOOL *pcopymapDest)
1643 {
1644   int i;
1645   BOOL bcopyall = (pcopymapDest == NULL);
1646
1647   for (i=0;parm_table[i].label;i++)
1648     if (parm_table[i].ptr && parm_table[i].class == P_LOCAL && 
1649         (bcopyall || pcopymapDest[i]))
1650       {
1651         void *def_ptr = parm_table[i].ptr;
1652         void *src_ptr = 
1653           ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1654         void *dest_ptr = 
1655           ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1656
1657         switch (parm_table[i].type)
1658           {
1659           case P_BOOL:
1660           case P_BOOLREV:
1661             *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1662             break;
1663
1664           case P_INTEGER:
1665           case P_ENUM:
1666           case P_OCTAL:
1667             *(int *)dest_ptr = *(int *)src_ptr;
1668             break;
1669
1670           case P_CHAR:
1671             *(char *)dest_ptr = *(char *)src_ptr;
1672             break;
1673
1674           case P_STRING:
1675             string_set(dest_ptr,*(char **)src_ptr);
1676             break;
1677
1678           case P_USTRING:
1679             string_set(dest_ptr,*(char **)src_ptr);
1680             strupper(*(char **)dest_ptr);
1681             break;
1682           default:
1683             break;
1684           }
1685       }
1686
1687   if (bcopyall)
1688     {
1689       init_copymap(pserviceDest);
1690       if (pserviceSource->copymap)
1691         memcpy((void *)pserviceDest->copymap,
1692                (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1693     }
1694 }
1695
1696 /***************************************************************************
1697 Check a service for consistency. Return False if the service is in any way
1698 incomplete or faulty, else True.
1699 ***************************************************************************/
1700 static BOOL service_ok(int iService)
1701 {
1702    BOOL bRetval;
1703
1704    bRetval = True;
1705    if (iSERVICE(iService).szService[0] == '\0')
1706    {
1707       DEBUG(0,( "The following message indicates an internal error:\n"));
1708       DEBUG(0,( "No service name in service entry.\n"));
1709       bRetval = False;
1710    }
1711
1712    /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1713    /* I can't see why you'd want a non-printable printer service...        */
1714    if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1715       if (!iSERVICE(iService).bPrint_ok)
1716       {
1717          DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1718                iSERVICE(iService).szService));
1719          iSERVICE(iService).bPrint_ok = True;
1720       }
1721
1722    if (iSERVICE(iService).szPath[0] == '\0' &&
1723        strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1724    {
1725       DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1726       string_set(&iSERVICE(iService).szPath,tmpdir());      
1727    }
1728
1729    /* If a service is flagged unavailable, log the fact at level 0. */
1730    if (!iSERVICE(iService).bAvailable) 
1731       DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1732             iSERVICE(iService).szService));
1733
1734    return (bRetval);
1735 }
1736
1737 static struct file_lists {
1738   struct file_lists *next;
1739   char *name;
1740   time_t modtime;
1741 } *file_lists = NULL;
1742
1743 /*******************************************************************
1744 keep a linked list of all config files so we know when one has changed 
1745 it's date and needs to be reloaded
1746 ********************************************************************/
1747 static void add_to_file_list(char *fname)
1748 {
1749   struct file_lists *f=file_lists;
1750
1751   while (f) {
1752     if (f->name && !strcmp(f->name,fname)) break;
1753     f = f->next;
1754   }
1755
1756   if (!f) {
1757     f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1758     if (!f) return;
1759     f->next = file_lists;
1760     f->name = strdup(fname);
1761     if (!f->name) {
1762       free(f);
1763       return;
1764     }
1765     file_lists = f;
1766   }
1767
1768   {
1769     pstring n2;
1770     pstrcpy(n2,fname);
1771     standard_sub_basic(n2);
1772     f->modtime = file_modtime(n2);
1773   }
1774
1775 }
1776
1777 /*******************************************************************
1778 check if a config file has changed date
1779 ********************************************************************/
1780 BOOL lp_file_list_changed(void)
1781 {
1782   struct file_lists *f = file_lists;
1783   DEBUG(6,("lp_file_list_changed()\n"));
1784
1785   while (f)
1786   {
1787     pstring n2;
1788     time_t mod_time;
1789
1790     pstrcpy(n2,f->name);
1791     standard_sub_basic(n2);
1792
1793     DEBUGADD( 6, ( "file %s -> %s  last mod_time: %s\n",
1794                    f->name, n2, ctime(&f->modtime) ) );
1795
1796     mod_time = file_modtime(n2);
1797
1798     if (f->modtime != mod_time) {
1799             DEBUGADD(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1800             f->modtime = mod_time;
1801             return(True);
1802     }
1803     f = f->next;
1804   }
1805   return(False);
1806 }
1807
1808 /***************************************************************************
1809   handle the interpretation of the coding system parameter
1810   *************************************************************************/
1811 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1812 {
1813         string_set(ptr,pszParmValue);
1814         interpret_coding_system(pszParmValue);
1815         return(True);
1816 }
1817
1818 /***************************************************************************
1819 handle the interpretation of the character set system parameter
1820 ***************************************************************************/
1821 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1822 {
1823         string_set(ptr,pszParmValue);
1824         interpret_character_set(pszParmValue);
1825         return(True);
1826 }
1827
1828
1829 /***************************************************************************
1830 handle the valid chars lines
1831 ***************************************************************************/
1832 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1833
1834   string_set(ptr,pszParmValue);
1835
1836   /* A dependency here is that the parameter client code page must be
1837      set before this is called - as calling codepage_initialise()
1838      would overwrite the valid char lines.
1839    */
1840   codepage_initialise(lp_client_code_page());
1841
1842   add_char_string(pszParmValue);
1843   return(True);
1844 }
1845
1846
1847 /***************************************************************************
1848 handle the include operation
1849 ***************************************************************************/
1850 static BOOL handle_include(char *pszParmValue,char **ptr)
1851
1852   pstring fname;
1853   pstrcpy(fname,pszParmValue);
1854
1855   add_to_file_list(fname);
1856
1857   standard_sub_basic(fname);
1858
1859   string_set(ptr,fname);
1860
1861   if (file_exist(fname,NULL))
1862     return(pm_process(fname, do_section, do_parameter));      
1863
1864   DEBUG(2,("Can't find include file %s\n",fname));
1865
1866   return(False);
1867 }
1868
1869
1870 /***************************************************************************
1871 handle the interpretation of the copy parameter
1872 ***************************************************************************/
1873 static BOOL handle_copy(char *pszParmValue,char **ptr)
1874 {
1875    BOOL bRetval;
1876    int iTemp;
1877    service serviceTemp;
1878
1879    string_set(ptr,pszParmValue);
1880
1881    init_service(&serviceTemp);
1882
1883    bRetval = False;
1884    
1885    DEBUG(3,("Copying service from service %s\n",pszParmValue));
1886
1887    if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1888      {
1889        if (iTemp == iServiceIndex)
1890          {
1891            DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1892                     pszParmValue));
1893          }
1894        else
1895          {
1896            copy_service(pSERVICE(iServiceIndex), 
1897                         &serviceTemp,
1898                         iSERVICE(iServiceIndex).copymap);
1899            bRetval = True;
1900          }
1901      }
1902    else
1903      {
1904        DEBUG(0,( "Unable to copy service - source not found: %s\n",
1905                 pszParmValue));
1906        bRetval = False;
1907      }
1908
1909    free_service(&serviceTemp);
1910    return (bRetval);
1911 }
1912
1913
1914 /***************************************************************************
1915 initialise a copymap
1916 ***************************************************************************/
1917 static void init_copymap(service *pservice)
1918 {
1919   int i;
1920   if (pservice->copymap) free(pservice->copymap);
1921   pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1922   if (!pservice->copymap)
1923     DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1924
1925   for (i=0;i<NUMPARAMETERS;i++)
1926     pservice->copymap[i] = True;
1927 }
1928
1929
1930 /***************************************************************************
1931  return the local pointer to a parameter given the service number and the 
1932  pointer into the default structure
1933 ***************************************************************************/
1934 void *lp_local_ptr(int snum, void *ptr)
1935 {
1936         return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
1937 }
1938
1939 /***************************************************************************
1940 Process a parameter for a particular service number. If snum < 0
1941 then assume we are in the globals
1942 ***************************************************************************/
1943 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1944 {
1945    int parmnum, i;
1946    void *parm_ptr=NULL; /* where we are going to store the result */
1947    void *def_ptr=NULL;
1948
1949    parmnum = map_parameter(pszParmName);
1950
1951    if (parmnum < 0)
1952      {
1953        DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1954        return(True);
1955      }
1956
1957    if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1958            DEBUG(1,("WARNING: The \"%s\"option is deprecated\n",
1959                     pszParmName));
1960    }
1961
1962    def_ptr = parm_table[parmnum].ptr;
1963
1964    /* we might point at a service, the default service or a global */
1965    if (snum < 0) {
1966      parm_ptr = def_ptr;
1967    } else {
1968        if (parm_table[parmnum].class == P_GLOBAL) {
1969            DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1970            return(True);
1971          }
1972        parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1973    }
1974
1975    if (snum >= 0) {
1976            if (!iSERVICE(snum).copymap)
1977                    init_copymap(pSERVICE(snum));
1978            
1979            /* this handles the aliases - set the copymap for other entries with
1980               the same data pointer */
1981            for (i=0;parm_table[i].label;i++)
1982                    if (parm_table[i].ptr == parm_table[parmnum].ptr)
1983                            iSERVICE(snum).copymap[i] = False;
1984    }
1985
1986    /* if it is a special case then go ahead */
1987    if (parm_table[parmnum].special) {
1988            parm_table[parmnum].special(pszParmValue,(char **)parm_ptr);
1989            return(True);
1990    }
1991
1992    /* now switch on the type of variable it is */
1993    switch (parm_table[parmnum].type)
1994      {
1995      case P_BOOL:
1996        set_boolean(parm_ptr,pszParmValue);
1997        break;
1998
1999      case P_BOOLREV:
2000        set_boolean(parm_ptr,pszParmValue);
2001        *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
2002        break;
2003
2004      case P_INTEGER:
2005        *(int *)parm_ptr = atoi(pszParmValue);
2006        break;
2007
2008      case P_CHAR:
2009        *(char *)parm_ptr = *pszParmValue;
2010        break;
2011
2012      case P_OCTAL:
2013        sscanf(pszParmValue,"%o",(int *)parm_ptr);
2014        break;
2015
2016      case P_STRING:
2017        string_set(parm_ptr,pszParmValue);
2018        break;
2019
2020      case P_USTRING:
2021        string_set(parm_ptr,pszParmValue);
2022        strupper(*(char **)parm_ptr);
2023        break;
2024
2025      case P_GSTRING:
2026        pstrcpy((char *)parm_ptr,pszParmValue);
2027        break;
2028
2029      case P_UGSTRING:
2030        pstrcpy((char *)parm_ptr,pszParmValue);
2031        strupper((char *)parm_ptr);
2032        break;
2033
2034      case P_ENUM:
2035              for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
2036                      if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
2037                              *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
2038                              break;
2039                      }
2040              }
2041              break;
2042      case P_SEP:
2043              break;
2044      }
2045
2046    return(True);
2047 }
2048
2049 /***************************************************************************
2050 Process a parameter.
2051 ***************************************************************************/
2052 static BOOL do_parameter( char *pszParmName, char *pszParmValue )
2053 {
2054   if( !bInGlobalSection && bGlobalOnly )
2055     return(True);
2056
2057   DEBUGADD( 3, ( "doing parameter %s = %s\n", pszParmName, pszParmValue ) );
2058
2059   return( lp_do_parameter( bInGlobalSection ? -2 : iServiceIndex,
2060                            pszParmName,
2061                            pszParmValue ) );
2062 }
2063
2064
2065 /***************************************************************************
2066 print a parameter of the specified type
2067 ***************************************************************************/
2068 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
2069 {
2070         int i;
2071         switch (p->type) {
2072         case P_ENUM:
2073                 for (i=0;p->enum_list[i].name;i++) {
2074                         if (*(int *)ptr == p->enum_list[i].value) {
2075                                 fprintf(f,"%s",p->enum_list[i].name);
2076                                 break;
2077                         }
2078                 }
2079                 break;
2080
2081         case P_BOOL:
2082                 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
2083                 break;
2084       
2085         case P_BOOLREV:
2086                 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
2087                 break;
2088       
2089         case P_INTEGER:
2090                 fprintf(f,"%d",*(int *)ptr);
2091                 break;
2092       
2093         case P_CHAR:
2094                 fprintf(f,"%c",*(char *)ptr);
2095                 break;
2096       
2097         case P_OCTAL:
2098                 fprintf(f,"0%o",*(int *)ptr);
2099                 break;
2100       
2101         case P_GSTRING:
2102         case P_UGSTRING:
2103                 if ((char *)ptr)
2104                         fprintf(f,"%s",(char *)ptr);
2105                 break;
2106                 
2107         case P_STRING:
2108         case P_USTRING:
2109                 if (*(char **)ptr)
2110                         fprintf(f,"%s",*(char **)ptr);
2111                 break;
2112         case P_SEP:
2113                 break;
2114         }
2115 }
2116
2117
2118 /***************************************************************************
2119 check if two parameters are equal
2120 ***************************************************************************/
2121 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
2122 {
2123   switch (type)
2124     {
2125     case P_BOOL:
2126     case P_BOOLREV:
2127       return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
2128
2129     case P_INTEGER:
2130     case P_ENUM:
2131     case P_OCTAL:
2132       return(*((int *)ptr1) == *((int *)ptr2));
2133       
2134     case P_CHAR:
2135       return(*((char *)ptr1) == *((char *)ptr2));
2136
2137     case P_GSTRING:
2138     case P_UGSTRING:
2139       {
2140         char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
2141         if (p1 && !*p1) p1 = NULL;
2142         if (p2 && !*p2) p2 = NULL;
2143         return(p1==p2 || strequal(p1,p2));
2144       }
2145     case P_STRING:
2146     case P_USTRING:
2147       {
2148         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2149         if (p1 && !*p1) p1 = NULL;
2150         if (p2 && !*p2) p2 = NULL;
2151         return(p1==p2 || strequal(p1,p2));
2152       }
2153      case P_SEP:
2154              break;
2155     }
2156   return(False);
2157 }
2158
2159 /***************************************************************************
2160 Process a new section (service). At this stage all sections are services.
2161 Later we'll have special sections that permit server parameters to be set.
2162 Returns True on success, False on failure.
2163 ***************************************************************************/
2164 static BOOL do_section(char *pszSectionName)
2165 {
2166    BOOL bRetval;
2167    BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) || 
2168                     (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2169    bRetval = False;
2170
2171    /* if we were in a global section then do the local inits */
2172    if (bInGlobalSection && !isglobal)
2173      init_locals();
2174
2175    /* if we've just struck a global section, note the fact. */
2176    bInGlobalSection = isglobal;   
2177
2178    /* check for multiple global sections */
2179    if (bInGlobalSection)
2180    {
2181      DEBUG( 3, ( "Processing section \"[%s]\"\n", pszSectionName ) );
2182      return(True);
2183    }
2184
2185    if (!bInGlobalSection && bGlobalOnly) return(True);
2186
2187    /* if we have a current service, tidy it up before moving on */
2188    bRetval = True;
2189
2190    if (iServiceIndex >= 0)
2191      bRetval = service_ok(iServiceIndex);
2192
2193    /* if all is still well, move to the next record in the services array */
2194    if (bRetval)
2195      {
2196        /* We put this here to avoid an odd message order if messages are */
2197        /* issued by the post-processing of a previous section. */
2198        DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
2199
2200        if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
2201          {
2202            DEBUG(0,("Failed to add a new service\n"));
2203            return(False);
2204          }
2205      }
2206
2207    return (bRetval);
2208 }
2209
2210
2211 /***************************************************************************
2212 determine if a partcular base parameter is currently set to the default value.
2213 ***************************************************************************/
2214 static BOOL is_default(int i)
2215 {
2216         if (!defaults_saved) return False;
2217         switch (parm_table[i].type) {
2218         case P_STRING:
2219         case P_USTRING:
2220                 return strequal(parm_table[i].def.svalue,*(char **)parm_table[i].ptr);
2221         case P_GSTRING:
2222         case P_UGSTRING:
2223                 return strequal(parm_table[i].def.svalue,(char *)parm_table[i].ptr);
2224         case P_BOOL:
2225         case P_BOOLREV:
2226                 return parm_table[i].def.bvalue == *(BOOL *)parm_table[i].ptr;
2227         case P_CHAR:
2228                 return parm_table[i].def.cvalue == *(char *)parm_table[i].ptr;
2229         case P_INTEGER:
2230         case P_OCTAL:
2231         case P_ENUM:
2232                 return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
2233         case P_SEP:
2234                 break;
2235         }
2236         return False;
2237 }
2238
2239
2240 /***************************************************************************
2241 Display the contents of the global structure.
2242 ***************************************************************************/
2243 static void dump_globals(FILE *f)
2244 {
2245         int i;
2246         fprintf(f, "# Global parameters\n");
2247         
2248         for (i=0;parm_table[i].label;i++)
2249                 if (parm_table[i].class == P_GLOBAL &&
2250                     parm_table[i].ptr &&
2251                     (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2252                         if (defaults_saved && is_default(i)) continue;
2253                         fprintf(f,"\t%s = ",parm_table[i].label);
2254                         print_parameter(&parm_table[i],parm_table[i].ptr, f);
2255                         fprintf(f,"\n");
2256                 }
2257 }
2258
2259 /***************************************************************************
2260 return True if a local parameter is currently set to the global default
2261 ***************************************************************************/
2262 BOOL lp_is_default(int snum, struct parm_struct *parm)
2263 {
2264         int pdiff = PTR_DIFF(parm->ptr,&sDefault);
2265                         
2266         return equal_parameter(parm->type,
2267                                ((char *)pSERVICE(snum)) + pdiff,
2268                                ((char *)&sDefault) + pdiff);
2269 }
2270
2271
2272 /***************************************************************************
2273 Display the contents of a single services record.
2274 ***************************************************************************/
2275 static void dump_a_service(service *pService, FILE *f)
2276 {
2277         int i;
2278         if (pService != &sDefault)
2279                 fprintf(f,"\n[%s]\n",pService->szService);
2280
2281         for (i=0;parm_table[i].label;i++)
2282                 if (parm_table[i].class == P_LOCAL &&
2283                     parm_table[i].ptr && 
2284                     (*parm_table[i].label != '-') &&
2285                     (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2286                         int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
2287                         
2288                         if (pService == &sDefault) {
2289                                 if (defaults_saved && is_default(i)) continue;
2290                         } else {
2291                                 if (equal_parameter(parm_table[i].type,
2292                                                     ((char *)pService) + pdiff,
2293                                                     ((char *)&sDefault) + pdiff)) 
2294                                         continue;
2295                         }
2296
2297                         fprintf(f,"\t%s = ",parm_table[i].label);
2298                         print_parameter(&parm_table[i],
2299                                         ((char *)pService) + pdiff, f);
2300                         fprintf(f,"\n");
2301                 }
2302 }
2303
2304
2305 /***************************************************************************
2306 return info about the next service  in a service. snum==-1 gives the globals
2307
2308 return NULL when out of parameters
2309 ***************************************************************************/
2310 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2311 {
2312         if (snum == -1) {
2313                 /* do the globals */
2314                 for (;parm_table[*i].label;(*i)++) {
2315                         if (parm_table[*i].class == P_SEPARATOR) 
2316                                 return &parm_table[(*i)++];
2317
2318                         if (!parm_table[*i].ptr || (*parm_table[*i].label == '-'))
2319                                 continue;
2320                         
2321                         if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr))
2322                                 continue;
2323
2324                         return &parm_table[(*i)++];
2325                 }
2326         } else {
2327                 service *pService = pSERVICE(snum);
2328
2329                 for (;parm_table[*i].label;(*i)++) {
2330                         if (parm_table[*i].class == P_SEPARATOR) 
2331                                 return &parm_table[(*i)++];
2332
2333                         if (parm_table[*i].class == P_LOCAL &&
2334                             parm_table[*i].ptr && 
2335                             (*parm_table[*i].label != '-') &&
2336                             ((*i) == 0 || 
2337                              (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2338                                 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2339                                 
2340                                 if (allparameters ||
2341                                     !equal_parameter(parm_table[*i].type,
2342                                                      ((char *)pService) + pdiff,
2343                                                      ((char *)&sDefault) + pdiff)) {
2344                                         return &parm_table[(*i)++];
2345                                 }
2346                         }
2347                 }
2348         }
2349
2350         return NULL;
2351 }
2352
2353
2354 #if 0
2355 /***************************************************************************
2356 Display the contents of a single copy structure.
2357 ***************************************************************************/
2358 static void dump_copy_map(BOOL *pcopymap)
2359 {
2360   int i;
2361   if (!pcopymap) return;
2362
2363   printf("\n\tNon-Copied parameters:\n");
2364
2365   for (i=0;parm_table[i].label;i++)
2366     if (parm_table[i].class == P_LOCAL &&
2367         parm_table[i].ptr && !pcopymap[i] &&
2368         (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2369       {
2370         printf("\t\t%s\n",parm_table[i].label);
2371       }
2372 }
2373 #endif
2374
2375 /***************************************************************************
2376 Return TRUE if the passed service number is within range.
2377 ***************************************************************************/
2378 BOOL lp_snum_ok(int iService)
2379 {
2380    return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2381 }
2382
2383
2384 /***************************************************************************
2385 auto-load some home services
2386 ***************************************************************************/
2387 static void lp_add_auto_services(char *str)
2388 {
2389         char *s;
2390         char *p;
2391         int homes;
2392
2393         if (!str) return;
2394
2395         s = strdup(str);
2396         if (!s) return;
2397
2398         homes = lp_servicenumber(HOMES_NAME);
2399         
2400         for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
2401                 char *home = get_home_dir(p);
2402                 
2403                 if (lp_servicenumber(p) >= 0) continue;
2404                 
2405                 if (home && homes >= 0) {
2406                         lp_add_home(p,homes,home);
2407                 }
2408         }
2409         free(s);
2410 }
2411
2412 /***************************************************************************
2413 auto-load one printer
2414 ***************************************************************************/
2415 void lp_add_one_printer(char *name,char *comment)
2416 {
2417         int printers = lp_servicenumber(PRINTERS_NAME);
2418         int i;
2419
2420         if (lp_servicenumber(name) < 0)  {
2421                 lp_add_printer(name,printers);
2422                 if ((i=lp_servicenumber(name)) >= 0)
2423                         string_set(&iSERVICE(i).comment,comment);
2424         }
2425 }
2426
2427 /***************************************************************************
2428 have we loaded a services file yet?
2429 ***************************************************************************/
2430 BOOL lp_loaded(void)
2431 {
2432   return(bLoaded);
2433 }
2434
2435 /***************************************************************************
2436 unload unused services
2437 ***************************************************************************/
2438 void lp_killunused(BOOL (*snumused)(int ))
2439 {
2440   int i;
2441   for (i=0;i<iNumServices;i++)
2442     if (VALID(i) && (!snumused || !snumused(i)))
2443       {
2444         iSERVICE(i).valid = False;
2445         free_service(pSERVICE(i));
2446       }
2447 }
2448
2449
2450 /***************************************************************************
2451 save the curent values of all global and sDefault parameters into the 
2452 defaults union. This allows swat and testparm to show only the
2453 changed (ie. non-default) parameters.
2454 ***************************************************************************/
2455 static void lp_save_defaults(void)
2456 {
2457         int i;
2458         for (i = 0; parm_table[i].label; i++) {
2459                 if (i>0 && parm_table[i].ptr == parm_table[i-1].ptr) continue;
2460                 switch (parm_table[i].type) {
2461                 case P_STRING:
2462                 case P_USTRING:
2463                         parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2464                         break;
2465                 case P_GSTRING:
2466                 case P_UGSTRING:
2467                         parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
2468                         break;
2469                 case P_BOOL:
2470                 case P_BOOLREV:
2471                         parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr;
2472                         break;
2473                 case P_CHAR:
2474                         parm_table[i].def.cvalue = *(char *)parm_table[i].ptr;
2475                         break;
2476                 case P_INTEGER:
2477                 case P_OCTAL:
2478                 case P_ENUM:
2479                         parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
2480                         break;
2481                 case P_SEP:
2482                         break;
2483                 }
2484         }
2485         defaults_saved = True;
2486 }
2487
2488
2489 /***************************************************************************
2490 Load the services array from the services file. Return True on success, 
2491 False on failure.
2492 ***************************************************************************/
2493 BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
2494 {
2495   pstring n2;
2496   BOOL bRetval;
2497  
2498   add_to_file_list(pszFname);
2499
2500   bRetval = False;
2501
2502   bInGlobalSection = True;
2503   bGlobalOnly = global_only;
2504   
2505   init_globals();
2506
2507   if (save_defaults) {
2508           init_locals();
2509           lp_save_defaults();
2510   }
2511   
2512   pstrcpy(n2,pszFname);
2513   standard_sub_basic(n2);
2514
2515   /* We get sections first, so have to start 'behind' to make up */
2516   iServiceIndex = -1;
2517   bRetval = pm_process(n2, do_section, do_parameter);
2518   
2519   /* finish up the last section */
2520   DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2521   if (bRetval)
2522     if (iServiceIndex >= 0)
2523       bRetval = service_ok(iServiceIndex);         
2524
2525   lp_add_auto_services(lp_auto_services());
2526
2527   if (add_ipc)
2528           lp_add_ipc();
2529
2530   set_default_server_announce_type();
2531
2532   bLoaded = True;
2533
2534   /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
2535   /* if bWINSsupport is true and we are in the client            */
2536
2537   if (in_client && Globals.bWINSsupport) {
2538
2539     string_set(&Globals.szWINSserver, "127.0.0.1");
2540
2541   }
2542
2543   return (bRetval);
2544 }
2545
2546
2547 /***************************************************************************
2548 return the max number of services
2549 ***************************************************************************/
2550 int lp_numservices(void)
2551 {
2552   return(iNumServices);
2553 }
2554
2555 /***************************************************************************
2556 Display the contents of the services array in human-readable form.
2557 ***************************************************************************/
2558 void lp_dump(FILE *f, BOOL show_defaults)
2559 {
2560    int iService;
2561
2562    if (show_defaults) {
2563            defaults_saved = False;
2564    }
2565
2566    dump_globals(f);
2567    
2568    dump_a_service(&sDefault, f);
2569
2570    for (iService = 0; iService < iNumServices; iService++)
2571    {
2572      if (VALID(iService))
2573        {
2574          if (iSERVICE(iService).szService[0] == '\0')
2575            break;
2576          dump_a_service(pSERVICE(iService), f);
2577        }
2578    }
2579 }
2580
2581
2582 /***************************************************************************
2583 Return the number of the service with the given name, or -1 if it doesn't
2584 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2585 getservicebyname()! This works ONLY if all services have been loaded, and
2586 does not copy the found service.
2587 ***************************************************************************/
2588 int lp_servicenumber(char *pszServiceName)
2589 {
2590    int iService;
2591
2592    for (iService = iNumServices - 1; iService >= 0; iService--)
2593       if (VALID(iService) &&
2594           strequal(lp_servicename(iService), pszServiceName)) 
2595          break;
2596
2597    if (iService < 0)
2598      DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2599    
2600    return (iService);
2601 }
2602
2603 /*******************************************************************
2604   a useful volume label function
2605   ******************************************************************/
2606 char *volume_label(int snum)
2607 {
2608   char *ret = lp_volume(snum);
2609   if (!*ret) return(lp_servicename(snum));
2610   return(ret);
2611 }
2612
2613
2614 /*******************************************************************
2615  Set the server type we will announce as via nmbd.
2616 ********************************************************************/
2617 static void set_default_server_announce_type(void)
2618 {
2619   default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2620                               SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2621   if(lp_announce_as() == ANNOUNCE_AS_NT)
2622     default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2623   else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2624     default_server_announce |= SV_TYPE_WIN95_PLUS;
2625   else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2626     default_server_announce |= SV_TYPE_WFW;
2627   default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2628 }
2629
2630
2631 /*******************************************************************
2632 remove a service
2633 ********************************************************************/
2634 void lp_remove_service(int snum)
2635 {
2636         pSERVICE(snum)->valid = False;
2637 }
2638
2639 /*******************************************************************
2640 copy a service
2641 ********************************************************************/
2642 void lp_copy_service(int snum, char *new_name)
2643 {
2644         char *oldname = lp_servicename(snum);
2645         do_section(new_name);
2646         if (snum >= 0) {
2647                 snum = lp_servicenumber(new_name);
2648                 if (snum >= 0)
2649                         lp_do_parameter(snum, "copy", oldname);
2650         }
2651 }
2652
2653
2654 /*******************************************************************
2655  Get the default server type we will announce as via nmbd.
2656 ********************************************************************/
2657 int lp_default_server_announce(void)
2658 {
2659   return default_server_announce;
2660 }
2661
2662 /*******************************************************************
2663  Split the announce version into major and minor numbers.
2664 ********************************************************************/
2665 int lp_major_announce_version(void)
2666 {
2667   static BOOL got_major = False;
2668   static int major_version = DEFAULT_MAJOR_VERSION;
2669   char *vers;
2670   char *p;
2671
2672   if(got_major)
2673     return major_version;
2674
2675   got_major = True;
2676   if((vers = lp_announce_version()) == NULL)
2677     return major_version;
2678   
2679   if((p = strchr(vers, '.')) == 0)
2680     return major_version;
2681
2682   *p = '\0';
2683   major_version = atoi(vers);
2684   return major_version;
2685 }
2686
2687 int lp_minor_announce_version(void)
2688 {
2689   static BOOL got_minor = False;
2690   static int minor_version = DEFAULT_MINOR_VERSION;
2691   char *vers;
2692   char *p;
2693
2694   if(got_minor)
2695     return minor_version;
2696
2697   got_minor = True;
2698   if((vers = lp_announce_version()) == NULL)
2699     return minor_version;
2700   
2701   if((p = strchr(vers, '.')) == 0)              
2702     return minor_version;
2703     
2704   p++;
2705   minor_version = atoi(p);
2706   return minor_version;
2707 }  
2708
2709 /***********************************************************
2710  Set the global name resolution order (used in smbclient).
2711 ************************************************************/
2712
2713 void lp_set_name_resolve_order(char *new_order)
2714
2715   Globals.szNameResolveOrder = new_order;
2716 }
2717
2718 /***********************************************************
2719  Set the flag that says if kernel oplocks are available 
2720  (called by smbd).
2721 ************************************************************/
2722
2723 static BOOL kernel_oplocks_available = False;
2724
2725 void lp_set_kernel_oplocks(BOOL val)
2726 {
2727   /*
2728    * Only set this to True if kerenl
2729    * oplocks are really available and were
2730    * turned on in the smb.conf file.
2731    */
2732
2733   if(Globals.bKernelOplocks && val)
2734     kernel_oplocks_available = True;
2735   else
2736     kernel_oplocks_available = False;
2737 }
2738
2739 /***********************************************************
2740  Return True if kernel oplocks are available and were turned
2741  on in smb.conf.
2742 ************************************************************/
2743
2744 BOOL lp_kernel_oplocks(void)
2745 {
2746   return kernel_oplocks_available;
2747 }
2748
2749 /***********************************************************
2750  returns role of Samba server
2751 ************************************************************/
2752 int lp_server_role(void)
2753 {
2754         switch (lp_security())
2755         {
2756                 case SEC_SHARE:
2757                 {
2758                         if (lp_domain_logons())
2759                         {
2760                                 DEBUG(0,("Server's Role (logon server) conflicts with share-level security\n"));
2761                         }
2762                         return ROLE_DOMAIN_NONE;
2763                 }
2764                 case SEC_SERVER:
2765                 case SEC_DOMAIN:
2766                 {
2767                         if (lp_domain_logons())
2768                         {
2769                                 return ROLE_DOMAIN_BDC;
2770                         }
2771                         return ROLE_DOMAIN_MEMBER;
2772                 }
2773                 case SEC_USER:
2774                 {
2775                         if (lp_domain_logons())
2776                         {
2777                                 return ROLE_DOMAIN_PDC;
2778                         }
2779                         return ROLE_DOMAIN_NONE;
2780                 }
2781                 default:
2782                 {
2783                         DEBUG(0,("Server's Role undefined due to unknown security mode\n"));
2784                         return ROLE_DOMAIN_NONE;
2785                 }
2786         }
2787 }