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