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