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