Removed "ole locking compat" parameter (no longer used).
[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(FILE *fenv)
1975 {
1976         pstring line;
1977         char *varval;
1978         size_t len;
1979         char *p;
1980
1981         while (!feof(fenv)) {
1982                 if (fgets(line, sizeof(line), fenv) == NULL)
1983                         break;
1984
1985                 if(feof(fenv))
1986                         break;
1987
1988                 if((len = strlen(line)) == 0)
1989                         continue;
1990
1991                 if (line[len - 1] == '\n')
1992                         line[--len] = '\0';
1993
1994                 if ((varval=malloc(len+1)) == NULL) {
1995                         DEBUG(0,("source_env: Not enough memory!\n"));
1996                         return(False);
1997                 }
1998
1999                 DEBUG(4,("source_env: Adding to environment: %s\n", line));
2000                 strncpy(varval, line, len);
2001                 varval[len] = '\0';
2002
2003                 p=strchr(line, (int) '=');
2004                 if (p == NULL) {
2005                         DEBUG(4,("source_env: missing '=': %s\n", line));
2006                         continue;
2007                 }
2008
2009                 if (putenv(varval)) {
2010                         DEBUG(0,("source_env: Failed to put environment variable %s\n", varval ));
2011                         continue;
2012                 }
2013
2014                 *p='\0';
2015                 p++;
2016                 DEBUG(4,("source_env: getting var %s = %s\n", line, getenv(line)));
2017         }
2018
2019         DEBUG(4,("source_env: returning successfully\n"));
2020         return(True);
2021 }
2022
2023 /***************************************************************************
2024  Handle the source environment operation
2025 ***************************************************************************/
2026
2027 static BOOL handle_source_env(char *pszParmValue,char **ptr)
2028 {
2029         pstring fname;
2030         char *p = fname;
2031         FILE *env;
2032         BOOL result;
2033
2034         pstrcpy(fname,pszParmValue);
2035
2036         standard_sub_basic(fname);
2037
2038         string_set(ptr,pszParmValue);
2039
2040         DEBUG(4, ("handle_source_env: checking env type\n"));
2041
2042         /*
2043          * Filename starting with '|' means popen and read from stdin.
2044          */
2045
2046         if (*p == '|') {
2047
2048                 DEBUG(4, ("handle_source_env: source env from pipe\n"));
2049                 p++;
2050
2051                 if ((env = sys_popen(p, "r", True)) == NULL) {
2052                         DEBUG(0,("handle_source_env: Failed to popen %s. Error was %s\n", p, strerror(errno) ));
2053                         return(False);
2054                 }
2055
2056                 DEBUG(4, ("handle_source_env: calling source_env()\n"));
2057                 result = source_env(env);
2058                 sys_pclose(env);
2059
2060         } else {
2061
2062                 SMB_STRUCT_STAT st;
2063
2064                 DEBUG(4, ("handle_source_env: source env from file %s\n", fname));
2065                 if ((env = sys_fopen(fname, "r")) == NULL) {
2066                         DEBUG(0,("handle_source_env: Failed to open file %s, Error was %s\n", fname, strerror(errno) ));
2067                         return(False);
2068                 }
2069
2070                 /*
2071                  * Ensure this file is owned by root and not writable by world.
2072                  */
2073                 if(sys_fstat(fileno(env), &st) != 0) {
2074                         DEBUG(0,("handle_source_env: Failed to stat file %s, Error was %s\n", fname, strerror(errno) ));
2075                         fclose(env);
2076                         return False;
2077                 }
2078
2079                 if((st.st_uid != (uid_t)0) || (st.st_mode & S_IWOTH)) {
2080                         DEBUG(0,("handle_source_env: unsafe to source env file %s. Not owned by root or world writable\n", fname ));
2081                         fclose(env);
2082                         return False;
2083                 }
2084
2085                 result=source_env(env);
2086                 fclose(env);
2087         }
2088         return(result);
2089 }
2090
2091
2092
2093 #ifdef MS_DFS
2094 void set_dfsmap_loaded(int i,BOOL b)
2095 {
2096   pSERVICE(i)->bDfsMapLoaded = b;
2097 }
2098
2099 #endif
2100
2101 /***************************************************************************
2102   handle the interpretation of the vfs object parameter
2103   *************************************************************************/
2104 static BOOL handle_vfs_object(char *pszParmValue,char **ptr)
2105 {
2106     /* Set string value */
2107
2108     string_set(ptr,pszParmValue);
2109
2110     /* Do any other initialisation required for vfs.  Note that
2111        anything done here may have linking repercussions in nmbd. */
2112
2113     return True;
2114 }
2115
2116 /***************************************************************************
2117   handle the interpretation of the coding system parameter
2118   *************************************************************************/
2119 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
2120 {
2121         string_set(ptr,pszParmValue);
2122         interpret_coding_system(pszParmValue);
2123         return(True);
2124 }
2125
2126 /***************************************************************************
2127  Handle the interpretation of the character set system parameter.
2128 ***************************************************************************/
2129
2130 static char *saved_character_set = NULL;
2131
2132 static BOOL handle_character_set(char *pszParmValue,char **ptr)
2133 {
2134     /* A dependency here is that the parameter client code page should be
2135       set before this is called.
2136     */
2137         string_set(ptr,pszParmValue);
2138         strupper(*ptr);
2139         saved_character_set = strdup(*ptr);
2140         interpret_character_set(*ptr,lp_client_code_page());
2141         return(True);
2142 }
2143
2144 /***************************************************************************
2145  Handle the interpretation of the client code page parameter.
2146  We handle this separately so that we can reset the character set
2147  parameter in case this came before 'client code page' in the smb.conf.
2148 ***************************************************************************/
2149
2150 static BOOL handle_client_code_page(char *pszParmValue,char **ptr)
2151 {
2152         Globals.client_code_page = atoi(pszParmValue);
2153         if (saved_character_set != NULL)
2154                 interpret_character_set(saved_character_set,lp_client_code_page());     
2155         return(True);
2156 }
2157
2158 /***************************************************************************
2159 handle the valid chars lines
2160 ***************************************************************************/
2161
2162 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
2163
2164   string_set(ptr,pszParmValue);
2165
2166   /* A dependency here is that the parameter client code page must be
2167      set before this is called - as calling codepage_initialise()
2168      would overwrite the valid char lines.
2169    */
2170   codepage_initialise(lp_client_code_page());
2171
2172   add_char_string(pszParmValue);
2173   return(True);
2174 }
2175
2176 /***************************************************************************
2177 handle the include operation
2178 ***************************************************************************/
2179
2180 static BOOL handle_include(char *pszParmValue,char **ptr)
2181
2182   pstring fname;
2183   pstrcpy(fname,pszParmValue);
2184
2185   add_to_file_list(fname);
2186
2187   standard_sub_basic(fname);
2188
2189   string_set(ptr,fname);
2190
2191   if (file_exist(fname,NULL))
2192     return(pm_process(fname, do_section, do_parameter));      
2193
2194   DEBUG(2,("Can't find include file %s\n",fname));
2195
2196   return(False);
2197 }
2198
2199
2200 /***************************************************************************
2201 handle the interpretation of the copy parameter
2202 ***************************************************************************/
2203 static BOOL handle_copy(char *pszParmValue,char **ptr)
2204 {
2205    BOOL bRetval;
2206    int iTemp;
2207    service serviceTemp;
2208
2209    string_set(ptr,pszParmValue);
2210
2211    init_service(&serviceTemp);
2212
2213    bRetval = False;
2214    
2215    DEBUG(3,("Copying service from service %s\n",pszParmValue));
2216
2217    if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
2218      {
2219        if (iTemp == iServiceIndex)
2220          {
2221            DEBUG(0,("Can't copy service %s - unable to copy self!\n",
2222                     pszParmValue));
2223          }
2224        else
2225          {
2226            copy_service(pSERVICE(iServiceIndex), 
2227                         &serviceTemp,
2228                         iSERVICE(iServiceIndex).copymap);
2229            bRetval = True;
2230          }
2231      }
2232    else
2233      {
2234        DEBUG(0,( "Unable to copy service - source not found: %s\n",
2235                 pszParmValue));
2236        bRetval = False;
2237      }
2238
2239    free_service(&serviceTemp);
2240    return (bRetval);
2241 }
2242
2243 /***************************************************************************
2244 initialise a copymap
2245 ***************************************************************************/
2246 static void init_copymap(service *pservice)
2247 {
2248   int i;
2249   if (pservice->copymap) free(pservice->copymap);
2250   pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
2251   if (!pservice->copymap)
2252     DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",(int)NUMPARAMETERS));
2253   else
2254     for (i=0;i<NUMPARAMETERS;i++)
2255       pservice->copymap[i] = True;
2256 }
2257
2258
2259 /***************************************************************************
2260  return the local pointer to a parameter given the service number and the 
2261  pointer into the default structure
2262 ***************************************************************************/
2263 void *lp_local_ptr(int snum, void *ptr)
2264 {
2265         return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
2266 }
2267
2268 /***************************************************************************
2269 Process a parameter for a particular service number. If snum < 0
2270 then assume we are in the globals
2271 ***************************************************************************/
2272 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
2273 {
2274    int parmnum, i;
2275    void *parm_ptr=NULL; /* where we are going to store the result */
2276    void *def_ptr=NULL;
2277
2278    parmnum = map_parameter(pszParmName);
2279
2280    if (parmnum < 0)
2281      {
2282        DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
2283        return(True);
2284      }
2285
2286    if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2287            DEBUG(1,("WARNING: The \"%s\"option is deprecated\n",
2288                     pszParmName));
2289    }
2290
2291    def_ptr = parm_table[parmnum].ptr;
2292
2293    /* we might point at a service, the default service or a global */
2294    if (snum < 0) {
2295      parm_ptr = def_ptr;
2296    } else {
2297        if (parm_table[parmnum].class == P_GLOBAL) {
2298            DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
2299            return(True);
2300          }
2301        parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
2302    }
2303
2304    if (snum >= 0) {
2305            if (!iSERVICE(snum).copymap)
2306                    init_copymap(pSERVICE(snum));
2307            
2308            /* this handles the aliases - set the copymap for other entries with
2309               the same data pointer */
2310            for (i=0;parm_table[i].label;i++)
2311                    if (parm_table[i].ptr == parm_table[parmnum].ptr)
2312                            iSERVICE(snum).copymap[i] = False;
2313    }
2314
2315    /* if it is a special case then go ahead */
2316    if (parm_table[parmnum].special) {
2317            parm_table[parmnum].special(pszParmValue,(char **)parm_ptr);
2318            return(True);
2319    }
2320
2321    /* now switch on the type of variable it is */
2322    switch (parm_table[parmnum].type)
2323      {
2324      case P_BOOL:
2325        set_boolean(parm_ptr,pszParmValue);
2326        break;
2327
2328      case P_BOOLREV:
2329        set_boolean(parm_ptr,pszParmValue);
2330        *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
2331        break;
2332
2333      case P_INTEGER:
2334        *(int *)parm_ptr = atoi(pszParmValue);
2335        break;
2336
2337      case P_CHAR:
2338        *(char *)parm_ptr = *pszParmValue;
2339        break;
2340
2341      case P_OCTAL:
2342        sscanf(pszParmValue,"%o",(int *)parm_ptr);
2343        break;
2344
2345      case P_STRING:
2346        string_set(parm_ptr,pszParmValue);
2347        if (parm_table[parmnum].flags & FLAG_DOS_STRING)
2348            unix_to_dos(*(char **)parm_ptr, True);
2349        break;
2350
2351      case P_USTRING:
2352        string_set(parm_ptr,pszParmValue);
2353        if (parm_table[parmnum].flags & FLAG_DOS_STRING)
2354            unix_to_dos(*(char **)parm_ptr, True);
2355        strupper(*(char **)parm_ptr);
2356        break;
2357
2358      case P_GSTRING:
2359        pstrcpy((char *)parm_ptr,pszParmValue);
2360        if (parm_table[parmnum].flags & FLAG_DOS_STRING)
2361            unix_to_dos((char *)parm_ptr, True);
2362        break;
2363
2364      case P_UGSTRING:
2365        pstrcpy((char *)parm_ptr,pszParmValue);
2366        if (parm_table[parmnum].flags & FLAG_DOS_STRING)
2367            unix_to_dos((char *)parm_ptr, True);
2368        strupper((char *)parm_ptr);
2369        break;
2370
2371      case P_ENUM:
2372              for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
2373                      if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
2374                              *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
2375                              break;
2376                      }
2377              }
2378              break;
2379      case P_SEP:
2380              break;
2381      }
2382
2383    return(True);
2384 }
2385
2386 /***************************************************************************
2387 Process a parameter.
2388 ***************************************************************************/
2389 static BOOL do_parameter( char *pszParmName, char *pszParmValue )
2390 {
2391   if( !bInGlobalSection && bGlobalOnly )
2392     return(True);
2393
2394   DEBUGADD( 3, ( "doing parameter %s = %s\n", pszParmName, pszParmValue ) );
2395
2396   return( lp_do_parameter( bInGlobalSection ? -2 : iServiceIndex,
2397                            pszParmName,
2398                            pszParmValue ) );
2399 }
2400
2401
2402 /***************************************************************************
2403 print a parameter of the specified type
2404 ***************************************************************************/
2405 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
2406 {
2407         int i;
2408         switch (p->type) {
2409         case P_ENUM:
2410                 for (i=0;p->enum_list[i].name;i++) {
2411                         if (*(int *)ptr == p->enum_list[i].value) {
2412                                 fprintf(f,"%s",p->enum_list[i].name);
2413                                 break;
2414                         }
2415                 }
2416                 break;
2417
2418         case P_BOOL:
2419                 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
2420                 break;
2421       
2422         case P_BOOLREV:
2423                 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
2424                 break;
2425       
2426         case P_INTEGER:
2427                 fprintf(f,"%d",*(int *)ptr);
2428                 break;
2429       
2430         case P_CHAR:
2431                 fprintf(f,"%c",*(char *)ptr);
2432                 break;
2433       
2434         case P_OCTAL:
2435                 fprintf(f,"%s",octal_string(*(int *)ptr));
2436                 break;
2437       
2438         case P_GSTRING:
2439         case P_UGSTRING:
2440                 if ((char *)ptr)
2441                         fprintf(f,"%s",(char *)ptr);
2442                 break;
2443                 
2444         case P_STRING:
2445         case P_USTRING:
2446                 if (*(char **)ptr)
2447                         fprintf(f,"%s",*(char **)ptr);
2448                 break;
2449         case P_SEP:
2450                 break;
2451         }
2452 }
2453
2454
2455 /***************************************************************************
2456 check if two parameters are equal
2457 ***************************************************************************/
2458 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
2459 {
2460   switch (type)
2461     {
2462     case P_BOOL:
2463     case P_BOOLREV:
2464       return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
2465
2466     case P_INTEGER:
2467     case P_ENUM:
2468     case P_OCTAL:
2469       return(*((int *)ptr1) == *((int *)ptr2));
2470       
2471     case P_CHAR:
2472       return(*((char *)ptr1) == *((char *)ptr2));
2473
2474     case P_GSTRING:
2475     case P_UGSTRING:
2476       {
2477         char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
2478         if (p1 && !*p1) p1 = NULL;
2479         if (p2 && !*p2) p2 = NULL;
2480         return(p1==p2 || strequal(p1,p2));
2481       }
2482     case P_STRING:
2483     case P_USTRING:
2484       {
2485         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2486         if (p1 && !*p1) p1 = NULL;
2487         if (p2 && !*p2) p2 = NULL;
2488         return(p1==p2 || strequal(p1,p2));
2489       }
2490      case P_SEP:
2491              break;
2492     }
2493   return(False);
2494 }
2495
2496 /***************************************************************************
2497 Process a new section (service). At this stage all sections are services.
2498 Later we'll have special sections that permit server parameters to be set.
2499 Returns True on success, False on failure.
2500 ***************************************************************************/
2501 static BOOL do_section(char *pszSectionName)
2502 {
2503    BOOL bRetval;
2504    BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) || 
2505                     (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2506    bRetval = False;
2507
2508    /* if we were in a global section then do the local inits */
2509    if (bInGlobalSection && !isglobal)
2510      init_locals();
2511
2512    /* if we've just struck a global section, note the fact. */
2513    bInGlobalSection = isglobal;   
2514
2515    /* check for multiple global sections */
2516    if (bInGlobalSection)
2517    {
2518      DEBUG( 3, ( "Processing section \"[%s]\"\n", pszSectionName ) );
2519      return(True);
2520    }
2521
2522    if (!bInGlobalSection && bGlobalOnly) return(True);
2523
2524    /* if we have a current service, tidy it up before moving on */
2525    bRetval = True;
2526
2527    if (iServiceIndex >= 0)
2528      bRetval = service_ok(iServiceIndex);
2529
2530    /* if all is still well, move to the next record in the services array */
2531    if (bRetval)
2532      {
2533        /* We put this here to avoid an odd message order if messages are */
2534        /* issued by the post-processing of a previous section. */
2535        DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
2536
2537        if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
2538          {
2539            DEBUG(0,("Failed to add a new service\n"));
2540            return(False);
2541          }
2542      }
2543
2544    return (bRetval);
2545 }
2546
2547
2548 /***************************************************************************
2549 determine if a partcular base parameter is currently set to the default value.
2550 ***************************************************************************/
2551 static BOOL is_default(int i)
2552 {
2553         if (!defaults_saved) return False;
2554         switch (parm_table[i].type) {
2555         case P_STRING:
2556         case P_USTRING:
2557                 return strequal(parm_table[i].def.svalue,*(char **)parm_table[i].ptr);
2558         case P_GSTRING:
2559         case P_UGSTRING:
2560                 return strequal(parm_table[i].def.svalue,(char *)parm_table[i].ptr);
2561         case P_BOOL:
2562         case P_BOOLREV:
2563                 return parm_table[i].def.bvalue == *(BOOL *)parm_table[i].ptr;
2564         case P_CHAR:
2565                 return parm_table[i].def.cvalue == *(char *)parm_table[i].ptr;
2566         case P_INTEGER:
2567         case P_OCTAL:
2568         case P_ENUM:
2569                 return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
2570         case P_SEP:
2571                 break;
2572         }
2573         return False;
2574 }
2575
2576
2577 /***************************************************************************
2578 Display the contents of the global structure.
2579 ***************************************************************************/
2580 static void dump_globals(FILE *f)
2581 {
2582         int i;
2583         fprintf(f, "# Global parameters\n[global]\n");
2584         
2585         for (i=0;parm_table[i].label;i++)
2586                 if (parm_table[i].class == P_GLOBAL &&
2587                     parm_table[i].ptr &&
2588                     (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2589                         if (defaults_saved && is_default(i)) continue;
2590                         fprintf(f,"\t%s = ",parm_table[i].label);
2591                         print_parameter(&parm_table[i],parm_table[i].ptr, f);
2592                         fprintf(f,"\n");
2593                 }
2594 }
2595
2596 /***************************************************************************
2597 return True if a local parameter is currently set to the global default
2598 ***************************************************************************/
2599 BOOL lp_is_default(int snum, struct parm_struct *parm)
2600 {
2601         int pdiff = PTR_DIFF(parm->ptr,&sDefault);
2602                         
2603         return equal_parameter(parm->type,
2604                                ((char *)pSERVICE(snum)) + pdiff,
2605                                ((char *)&sDefault) + pdiff);
2606 }
2607
2608
2609 /***************************************************************************
2610 Display the contents of a single services record.
2611 ***************************************************************************/
2612 static void dump_a_service(service *pService, FILE *f)
2613 {
2614         int i;
2615         if (pService != &sDefault)
2616                 fprintf(f,"\n[%s]\n",pService->szService);
2617
2618         for (i=0;parm_table[i].label;i++)
2619                 if (parm_table[i].class == P_LOCAL &&
2620                     parm_table[i].ptr && 
2621                     (*parm_table[i].label != '-') &&
2622                     (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2623                         int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
2624                         
2625                         if (pService == &sDefault) {
2626                                 if (defaults_saved && is_default(i)) continue;
2627                         } else {
2628                                 if (equal_parameter(parm_table[i].type,
2629                                                     ((char *)pService) + pdiff,
2630                                                     ((char *)&sDefault) + pdiff)) 
2631                                         continue;
2632                         }
2633
2634                         fprintf(f,"\t%s = ",parm_table[i].label);
2635                         print_parameter(&parm_table[i],
2636                                         ((char *)pService) + pdiff, f);
2637                         fprintf(f,"\n");
2638                 }
2639 }
2640
2641
2642 /***************************************************************************
2643 return info about the next service  in a service. snum==-1 gives the globals
2644
2645 return NULL when out of parameters
2646 ***************************************************************************/
2647 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2648 {
2649         if (snum == -1) {
2650                 /* do the globals */
2651                 for (;parm_table[*i].label;(*i)++) {
2652                         if (parm_table[*i].class == P_SEPARATOR) 
2653                                 return &parm_table[(*i)++];
2654
2655                         if (!parm_table[*i].ptr || (*parm_table[*i].label == '-'))
2656                                 continue;
2657                         
2658                         if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr))
2659                                 continue;
2660
2661                         return &parm_table[(*i)++];
2662                 }
2663         } else {
2664                 service *pService = pSERVICE(snum);
2665
2666                 for (;parm_table[*i].label;(*i)++) {
2667                         if (parm_table[*i].class == P_SEPARATOR) 
2668                                 return &parm_table[(*i)++];
2669
2670                         if (parm_table[*i].class == P_LOCAL &&
2671                             parm_table[*i].ptr && 
2672                             (*parm_table[*i].label != '-') &&
2673                             ((*i) == 0 || 
2674                              (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2675                                 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2676                                 
2677                                 if (allparameters ||
2678                                     !equal_parameter(parm_table[*i].type,
2679                                                      ((char *)pService) + pdiff,
2680                                                      ((char *)&sDefault) + pdiff)) {
2681                                         return &parm_table[(*i)++];
2682                                 }
2683                         }
2684                 }
2685         }
2686
2687         return NULL;
2688 }
2689
2690
2691 #if 0
2692 /***************************************************************************
2693 Display the contents of a single copy structure.
2694 ***************************************************************************/
2695 static void dump_copy_map(BOOL *pcopymap)
2696 {
2697   int i;
2698   if (!pcopymap) return;
2699
2700   printf("\n\tNon-Copied parameters:\n");
2701
2702   for (i=0;parm_table[i].label;i++)
2703     if (parm_table[i].class == P_LOCAL &&
2704         parm_table[i].ptr && !pcopymap[i] &&
2705         (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2706       {
2707         printf("\t\t%s\n",parm_table[i].label);
2708       }
2709 }
2710 #endif
2711
2712 /***************************************************************************
2713 Return TRUE if the passed service number is within range.
2714 ***************************************************************************/
2715 BOOL lp_snum_ok(int iService)
2716 {
2717    return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2718 }
2719
2720
2721 /***************************************************************************
2722 auto-load some home services
2723 ***************************************************************************/
2724 static void lp_add_auto_services(char *str)
2725 {
2726         char *s;
2727         char *p;
2728         int homes;
2729
2730         if (!str) return;
2731
2732         s = strdup(str);
2733         if (!s) return;
2734
2735         homes = lp_servicenumber(HOMES_NAME);
2736         
2737         for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
2738                 char *home = get_user_home_dir(p);
2739                 
2740                 if (lp_servicenumber(p) >= 0) continue;
2741                 
2742                 if (home && homes >= 0) {
2743                         lp_add_home(p,homes,home);
2744                 }
2745         }
2746         free(s);
2747 }
2748
2749 /***************************************************************************
2750 auto-load one printer
2751 ***************************************************************************/
2752 void lp_add_one_printer(char *name,char *comment)
2753 {
2754         int printers = lp_servicenumber(PRINTERS_NAME);
2755         int i;
2756
2757         if (lp_servicenumber(name) < 0)  {
2758                 lp_add_printer(name,printers);
2759                 if ((i=lp_servicenumber(name)) >= 0)
2760                         string_set(&iSERVICE(i).comment,comment);
2761         }
2762 }
2763
2764 /***************************************************************************
2765 have we loaded a services file yet?
2766 ***************************************************************************/
2767 BOOL lp_loaded(void)
2768 {
2769   return(bLoaded);
2770 }
2771
2772 /***************************************************************************
2773 unload unused services
2774 ***************************************************************************/
2775 void lp_killunused(BOOL (*snumused)(int ))
2776 {
2777   int i;
2778   for (i=0;i<iNumServices;i++)
2779     if (VALID(i) && (!snumused || !snumused(i)))
2780       {
2781         iSERVICE(i).valid = False;
2782         free_service(pSERVICE(i));
2783       }
2784 }
2785
2786
2787 /***************************************************************************
2788 save the curent values of all global and sDefault parameters into the 
2789 defaults union. This allows swat and testparm to show only the
2790 changed (ie. non-default) parameters.
2791 ***************************************************************************/
2792 static void lp_save_defaults(void)
2793 {
2794         int i;
2795         for (i = 0; parm_table[i].label; i++) {
2796                 if (i>0 && parm_table[i].ptr == parm_table[i-1].ptr) continue;
2797                 switch (parm_table[i].type) {
2798                 case P_STRING:
2799                 case P_USTRING:
2800                         parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2801                         break;
2802                 case P_GSTRING:
2803                 case P_UGSTRING:
2804                         parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
2805                         break;
2806                 case P_BOOL:
2807                 case P_BOOLREV:
2808                         parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr;
2809                         break;
2810                 case P_CHAR:
2811                         parm_table[i].def.cvalue = *(char *)parm_table[i].ptr;
2812                         break;
2813                 case P_INTEGER:
2814                 case P_OCTAL:
2815                 case P_ENUM:
2816                         parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
2817                         break;
2818                 case P_SEP:
2819                         break;
2820                 }
2821         }
2822         defaults_saved = True;
2823 }
2824
2825
2826 /***************************************************************************
2827 Load the services array from the services file. Return True on success, 
2828 False on failure.
2829 ***************************************************************************/
2830 BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
2831 {
2832   pstring n2;
2833   BOOL bRetval;
2834
2835   add_to_file_list(pszFname);
2836
2837   bRetval = False;
2838
2839   bInGlobalSection = True;
2840   bGlobalOnly = global_only;
2841   
2842   init_globals();
2843
2844   if (save_defaults) {
2845           init_locals();
2846           lp_save_defaults();
2847   }
2848   
2849   pstrcpy(n2,pszFname);
2850   standard_sub_basic(n2);
2851
2852   /* We get sections first, so have to start 'behind' to make up */
2853   iServiceIndex = -1;
2854   bRetval = pm_process(n2, do_section, do_parameter);
2855   
2856   /* finish up the last section */
2857   DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2858   if (bRetval)
2859     if (iServiceIndex >= 0)
2860       bRetval = service_ok(iServiceIndex);         
2861
2862   lp_add_auto_services(lp_auto_services());
2863
2864   if (add_ipc)
2865           lp_add_ipc();
2866
2867   set_default_server_announce_type();
2868
2869   bLoaded = True;
2870
2871   /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
2872   /* if bWINSsupport is true and we are in the client            */
2873
2874   if (in_client && Globals.bWINSsupport) {
2875
2876     string_set(&Globals.szWINSserver, "127.0.0.1");
2877
2878   }
2879
2880   return (bRetval);
2881 }
2882
2883
2884 /***************************************************************************
2885 reset the max number of services
2886 ***************************************************************************/
2887 void lp_resetnumservices(void)
2888 {
2889   iNumServices = 0;
2890 }
2891
2892 /***************************************************************************
2893 return the max number of services
2894 ***************************************************************************/
2895 int lp_numservices(void)
2896 {
2897   return(iNumServices);
2898 }
2899
2900 /***************************************************************************
2901 Display the contents of the services array in human-readable form.
2902 ***************************************************************************/
2903 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2904 {
2905    int iService;
2906
2907    if (show_defaults) {
2908            defaults_saved = False;
2909    }
2910
2911    dump_globals(f);
2912    
2913    dump_a_service(&sDefault, f);
2914
2915    for (iService = 0; iService < maxtoprint; iService++)
2916      lp_dump_one(f, show_defaults, iService);
2917 }
2918
2919 /***************************************************************************
2920 Display the contents of one service in human-readable form.
2921 ***************************************************************************/
2922 void lp_dump_one(FILE *f, BOOL show_defaults, int snum)
2923 {
2924    if (VALID(snum))
2925      {
2926        if (iSERVICE(snum).szService[0] == '\0')
2927          return;
2928        dump_a_service(pSERVICE(snum), f);
2929      }
2930 }
2931
2932
2933 /***************************************************************************
2934 Return the number of the service with the given name, or -1 if it doesn't
2935 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2936 getservicebyname()! This works ONLY if all services have been loaded, and
2937 does not copy the found service.
2938 ***************************************************************************/
2939 int lp_servicenumber(char *pszServiceName)
2940 {
2941    int iService;
2942
2943    for (iService = iNumServices - 1; iService >= 0; iService--)
2944       if (VALID(iService) &&
2945           strequal(lp_servicename(iService), pszServiceName)) 
2946          break;
2947
2948    if (iService < 0)
2949      DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2950    
2951    return (iService);
2952 }
2953
2954 /*******************************************************************
2955   a useful volume label function
2956   ******************************************************************/
2957 char *volume_label(int snum)
2958 {
2959   char *ret = lp_volume(snum);
2960   if (!*ret) return(lp_servicename(snum));
2961   return(ret);
2962 }
2963
2964
2965 /*******************************************************************
2966  Set the server type we will announce as via nmbd.
2967 ********************************************************************/
2968 static void set_default_server_announce_type(void)
2969 {
2970   default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2971                               SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2972   if(lp_announce_as() == ANNOUNCE_AS_NT_SERVER)
2973     default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2974   if(lp_announce_as() == ANNOUNCE_AS_NT_WORKSTATION)
2975     default_server_announce |= SV_TYPE_NT;
2976   else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2977     default_server_announce |= SV_TYPE_WIN95_PLUS;
2978   else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2979     default_server_announce |= SV_TYPE_WFW;
2980   default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2981 }
2982
2983
2984 /*******************************************************************
2985 remove a service
2986 ********************************************************************/
2987 void lp_remove_service(int snum)
2988 {
2989         pSERVICE(snum)->valid = False;
2990 }
2991
2992 /*******************************************************************
2993 copy a service
2994 ********************************************************************/
2995 void lp_copy_service(int snum, char *new_name)
2996 {
2997         char *oldname = lp_servicename(snum);
2998         do_section(new_name);
2999         if (snum >= 0) {
3000                 snum = lp_servicenumber(new_name);
3001                 if (snum >= 0)
3002                         lp_do_parameter(snum, "copy", oldname);
3003         }
3004 }
3005
3006
3007 /*******************************************************************
3008  Get the default server type we will announce as via nmbd.
3009 ********************************************************************/
3010 int lp_default_server_announce(void)
3011 {
3012   return default_server_announce;
3013 }
3014
3015 /*******************************************************************
3016  Split the announce version into major and minor numbers.
3017 ********************************************************************/
3018 int lp_major_announce_version(void)
3019 {
3020   static BOOL got_major = False;
3021   static int major_version = DEFAULT_MAJOR_VERSION;
3022   char *vers;
3023   char *p;
3024
3025   if(got_major)
3026     return major_version;
3027
3028   got_major = True;
3029   if((vers = lp_announce_version()) == NULL)
3030     return major_version;
3031   
3032   if((p = strchr(vers, '.')) == 0)
3033     return major_version;
3034
3035   *p = '\0';
3036   major_version = atoi(vers);
3037   return major_version;
3038 }
3039
3040 int lp_minor_announce_version(void)
3041 {
3042   static BOOL got_minor = False;
3043   static int minor_version = DEFAULT_MINOR_VERSION;
3044   char *vers;
3045   char *p;
3046
3047   if(got_minor)
3048     return minor_version;
3049
3050   got_minor = True;
3051   if((vers = lp_announce_version()) == NULL)
3052     return minor_version;
3053   
3054   if((p = strchr(vers, '.')) == 0)              
3055     return minor_version;
3056     
3057   p++;
3058   minor_version = atoi(p);
3059   return minor_version;
3060 }  
3061
3062 /***********************************************************
3063  Set the global name resolution order (used in smbclient).
3064 ************************************************************/
3065
3066 void lp_set_name_resolve_order(char *new_order)
3067
3068   Globals.szNameResolveOrder = new_order;
3069 }
3070
3071 /***********************************************************
3072  Set the flag that says if kernel oplocks are available 
3073  (called by smbd).
3074 ************************************************************/
3075
3076 static BOOL kernel_oplocks_available = False;
3077
3078 void lp_set_kernel_oplocks(BOOL val)
3079 {
3080   /*
3081    * Only set this to True if kerenl
3082    * oplocks are really available and were
3083    * turned on in the smb.conf file.
3084    */
3085
3086   if(Globals.bKernelOplocks && val)
3087     kernel_oplocks_available = True;
3088   else
3089     kernel_oplocks_available = False;
3090 }
3091
3092 /***********************************************************
3093  Return True if kernel oplocks are available and were turned
3094  on in smb.conf.
3095 ************************************************************/
3096
3097 BOOL lp_kernel_oplocks(void)
3098 {
3099   return kernel_oplocks_available;
3100 }
3101
3102 /***********************************************************
3103  Functions to return the current security masks/modes. If
3104  set to -1 then return the create mask/mode instead.
3105 ************************************************************/
3106
3107 int lp_security_mask(int snum)
3108 {
3109   int val = _lp_security_mask(snum);
3110   if(val == -1)
3111     return lp_create_mask(snum);
3112   return val;
3113 }
3114
3115 int lp_force_security_mode(int snum)
3116 {
3117   int val = _lp_force_security_mode(snum);
3118   if(val == -1)
3119     return lp_force_create_mode(snum);
3120   return val;
3121 }
3122
3123 int lp_dir_security_mask(int snum)
3124 {
3125   int val = _lp_dir_security_mask(snum);
3126   if(val == -1)
3127     return lp_dir_mask(snum);
3128   return val;
3129 }
3130
3131 int lp_force_dir_security_mode(int snum)
3132 {
3133   int val = _lp_force_dir_security_mode(snum);
3134   if(val == -1)
3135     return lp_force_dir_mode(snum);
3136   return val;
3137 }
3138
3139