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