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