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