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