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