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