2 Unix SMB/Netbios implementation.
4 Parameter loading functions
5 Copyright (C) Karl Auer 1993,1994
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.
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.
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
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
54 extern int DEBUGLEVEL
;
55 extern pstring user_socket_options
;
56 extern pstring myname
;
59 #define GLOBAL_NAME "global"
64 #define PRINTCAP_NAME "/etc/qconfig"
66 #define PRINTCAP_NAME "/etc/printcap"
71 #define PRINTERS_NAME "printers"
75 #define HOMES_NAME "homes"
78 /* some helpful bits */
79 #define pSERVICE(i) ServicePtrs[i]
80 #define iSERVICE(i) (*pSERVICE(i))
81 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
82 #define VALID(i) iSERVICE(i).valid
84 /* these are the types of parameter we have */
87 P_BOOL
,P_BOOLREV
,P_CHAR
,P_INTEGER
,P_OCTAL
,
88 P_STRING
,P_USTRING
,P_GSTRING
,P_UGSTRING
93 P_LOCAL
,P_GLOBAL
,P_NONE
97 extern BOOL use_getwd_cache
;
99 extern int extra_time_offset
;
101 extern int coding_system
;
105 * This structure describes global (ie., server-wide) parameters.
109 char *szPrintcapname
;
112 char *szDefaultService
;
116 char *szServerString
;
117 char *szAutoServices
;
118 char *szPasswdProgram
;
122 char *szSMBPasswdFile
;
123 char *szPasswordServer
;
124 char *szSocketOptions
;
127 char *szDomainController
;
129 char *szCharacterSet
;
136 char *szRemoteAnnounce
;
137 char *szSocketAddress
;
156 BOOL bPreferredMaster
;
159 BOOL bEncryptPasswords
;
166 BOOL bReadPrediction
;
172 static global Globals
;
177 * This structure describes a single service.
185 char *szGuestaccount
;
186 char *szInvalidUsers
;
194 char *szRootPostExec
;
195 char *szPrintcommand
;
198 char *szLppausecommand
;
199 char *szLpresumecommand
;
201 char *szPrinterDriver
;
223 BOOL bShortCasePreserve
;
247 BOOL bDeleteReadonly
;
249 char dummy
[3]; /* for alignment */
253 /* This is a default service used to prime a services structure */
254 static service sDefault
=
257 NULL
, /* szService */
259 NULL
, /* szUsername */
260 NULL
, /* szGuestAccount */
261 NULL
, /* szInvalidUsers */
262 NULL
, /* szValidUsers */
263 NULL
, /* szAdminUsers */
265 NULL
, /* szInclude */
266 NULL
, /* szPreExec */
267 NULL
, /* szPostExec */
268 NULL
, /* szRootPreExec */
269 NULL
, /* szRootPostExec */
270 NULL
, /* szPrintcommand */
271 NULL
, /* szLpqcommand */
272 NULL
, /* szLprmcommand */
273 NULL
, /* szLppausecommand */
274 NULL
, /* szLpresumecommand */
275 NULL
, /* szPrintername */
276 NULL
, /* szPrinterDriver */
277 NULL
, /* szDontdescend */
278 NULL
, /* szHostsallow */
279 NULL
, /* szHostsdeny */
280 NULL
, /* szMagicScript */
281 NULL
, /* szMagicOutput */
282 NULL
, /* szMangledMap */
284 NULL
, /* force user */
285 NULL
, /* force group */
287 NULL
, /* writelist */
289 0, /* iMinPrintSpace */
290 0644, /* iCreate_mode */
291 0755, /* iDir_mode */
292 0, /* iMaxConnections */
293 CASE_LOWER
, /* iDefaultCase */
294 False
, /* bAlternatePerm */
295 False
, /* revalidate */
296 False
, /* case sensitive */
297 False
, /* case preserve */
298 False
, /* short case preserve */
299 False
, /* case mangle */
301 True
, /* bHideDotFiles */
302 True
, /* bBrowseable */
303 True
, /* bAvailable */
304 True
, /* bRead_only */
305 True
, /* bNo_set_dir */
306 False
, /* bGuest_only */
307 False
, /* bGuest_ok */
308 False
, /* bPrint_ok */
309 False
, /* bPostscript */
310 False
, /* bMap_system */
311 False
, /* bMap_hidden */
312 True
, /* bMap_archive */
314 False
, /* bStrictLocking */
315 True
, /* bShareModes */
316 False
, /* bOnlyUser */
317 True
, /* bMangledNames */
318 True
, /* bWidelinks */
319 False
, /* bSyncAlways */
320 '~', /* magic char */
322 False
, /* bDeleteReadonly */
323 False
, /* bFakeOplocks */
329 /* local variables */
330 static service
**ServicePtrs
= NULL
;
331 static int iNumServices
= 0;
332 static int iServiceIndex
= 0;
333 static BOOL bInGlobalSection
= True
;
334 static BOOL bGlobalOnly
= False
;
337 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
339 /* prototypes for the special type handlers */
340 static BOOL
handle_valid_chars(char *pszParmValue
, char **ptr
);
341 static BOOL
handle_include(char *pszParmValue
, char **ptr
);
342 static BOOL
handle_copy(char *pszParmValue
, char **ptr
);
343 static BOOL
handle_protocol(char *pszParmValue
,int *val
);
344 static BOOL
handle_security(char *pszParmValue
,int *val
);
345 static BOOL
handle_case(char *pszParmValue
,int *val
);
346 static BOOL
handle_printing(char *pszParmValue
,int *val
);
347 static BOOL
handle_character_set(char *pszParmValue
,int *val
);
349 static BOOL
handle_coding_system(char *pszParmValue
,int *val
);
361 {"debuglevel", P_INTEGER
, P_GLOBAL
, &DEBUGLEVEL
, NULL
},
362 {"log level", P_INTEGER
, P_GLOBAL
, &DEBUGLEVEL
, NULL
},
363 {"syslog", P_INTEGER
, P_GLOBAL
, &Globals
.syslog
, NULL
},
364 {"syslog only", P_BOOL
, P_GLOBAL
, &Globals
.bSyslogOnly
, NULL
},
365 {"protocol", P_INTEGER
, P_GLOBAL
, &Globals
.maxprotocol
,handle_protocol
},
366 {"security", P_INTEGER
, P_GLOBAL
, &Globals
.security
,handle_security
},
367 {"printing", P_INTEGER
, P_GLOBAL
, &Globals
.printing
,handle_printing
},
368 {"max disk size", P_INTEGER
, P_GLOBAL
, &Globals
.maxdisksize
, NULL
},
369 {"lpq cache time", P_INTEGER
, P_GLOBAL
, &Globals
.lpqcachetime
, NULL
},
370 {"encrypt passwords",P_BOOL
, P_GLOBAL
, &Globals
.bEncryptPasswords
, NULL
},
371 {"getwd cache", P_BOOL
, P_GLOBAL
, &use_getwd_cache
, NULL
},
372 {"read prediction", P_BOOL
, P_GLOBAL
, &Globals
.bReadPrediction
, NULL
},
373 {"read bmpx", P_BOOL
, P_GLOBAL
, &Globals
.bReadbmpx
, NULL
},
374 {"read raw", P_BOOL
, P_GLOBAL
, &Globals
.bReadRaw
, NULL
},
375 {"write raw", P_BOOL
, P_GLOBAL
, &Globals
.bWriteRaw
, NULL
},
376 {"use rhosts", P_BOOL
, P_GLOBAL
, &Globals
.bUseRhosts
, NULL
},
377 {"load printers", P_BOOL
, P_GLOBAL
, &Globals
.bLoadPrinters
, NULL
},
378 {"null passwords", P_BOOL
, P_GLOBAL
, &Globals
.bNullPasswords
, NULL
},
379 {"strip dot", P_BOOL
, P_GLOBAL
, &Globals
.bStripDot
, NULL
},
380 {"interfaces", P_STRING
, P_GLOBAL
, &Globals
.szInterfaces
, NULL
},
381 {"password server", P_STRING
, P_GLOBAL
, &Globals
.szPasswordServer
, NULL
},
382 {"socket options", P_GSTRING
, P_GLOBAL
, user_socket_options
, NULL
},
383 {"netbios name", P_UGSTRING
,P_GLOBAL
, myname
, NULL
},
384 {"smbrun", P_STRING
, P_GLOBAL
, &Globals
.szSmbrun
, NULL
},
385 {"veto files", P_STRING
, P_GLOBAL
, &Globals
.szVetoFiles
, NULL
},
386 {"log file", P_STRING
, P_GLOBAL
, &Globals
.szLogFile
, NULL
},
387 {"config file", P_STRING
, P_GLOBAL
, &Globals
.szConfigFile
, NULL
},
388 {"smb passwd file", P_STRING
, P_GLOBAL
, &Globals
.szSMBPasswdFile
, NULL
},
389 {"hosts equiv", P_STRING
, P_GLOBAL
, &Globals
.szHostsEquiv
, NULL
},
390 {"preload", P_STRING
, P_GLOBAL
, &Globals
.szAutoServices
, NULL
},
391 {"auto services", P_STRING
, P_GLOBAL
, &Globals
.szAutoServices
, NULL
},
392 {"server string", P_STRING
, P_GLOBAL
, &Globals
.szServerString
, NULL
},
393 {"printcap name", P_STRING
, P_GLOBAL
, &Globals
.szPrintcapname
, NULL
},
394 {"printcap", P_STRING
, P_GLOBAL
, &Globals
.szPrintcapname
, NULL
},
395 {"lock dir", P_STRING
, P_GLOBAL
, &Globals
.szLockDir
, NULL
},
396 {"lock directory", P_STRING
, P_GLOBAL
, &Globals
.szLockDir
, NULL
},
397 {"root directory", P_STRING
, P_GLOBAL
, &Globals
.szRootdir
, NULL
},
398 {"root dir", P_STRING
, P_GLOBAL
, &Globals
.szRootdir
, NULL
},
399 {"root", P_STRING
, P_GLOBAL
, &Globals
.szRootdir
, NULL
},
400 {"default service", P_STRING
, P_GLOBAL
, &Globals
.szDefaultService
, NULL
},
401 {"default", P_STRING
, P_GLOBAL
, &Globals
.szDefaultService
, NULL
},
402 {"message command", P_STRING
, P_GLOBAL
, &Globals
.szMsgCommand
, NULL
},
403 {"dfree command", P_STRING
, P_GLOBAL
, &Globals
.szDfree
, NULL
},
404 {"passwd program", P_STRING
, P_GLOBAL
, &Globals
.szPasswdProgram
, NULL
},
405 {"passwd chat", P_STRING
, P_GLOBAL
, &Globals
.szPasswdChat
, NULL
},
406 {"valid chars", P_STRING
, P_GLOBAL
, &Globals
.szValidChars
, handle_valid_chars
},
407 {"workgroup", P_USTRING
, P_GLOBAL
, &Globals
.szWorkGroup
, NULL
},
408 {"domain controller",P_STRING
, P_GLOBAL
, &Globals
.szDomainController
,NULL
},
409 {"username map", P_STRING
, P_GLOBAL
, &Globals
.szUsernameMap
, NULL
},
410 {"character set", P_STRING
, P_GLOBAL
, &Globals
.szCharacterSet
, handle_character_set
},
411 {"logon script", P_STRING
, P_GLOBAL
, &Globals
.szLogonScript
, NULL
},
412 {"logon path", P_STRING
, P_GLOBAL
, &Globals
.szLogonPath
, NULL
},
413 {"remote announce", P_STRING
, P_GLOBAL
, &Globals
.szRemoteAnnounce
, NULL
},
414 {"socket address", P_STRING
, P_GLOBAL
, &Globals
.szSocketAddress
, NULL
},
415 {"max log size", P_INTEGER
, P_GLOBAL
, &Globals
.max_log_size
, NULL
},
416 {"mangled stack", P_INTEGER
, P_GLOBAL
, &Globals
.mangled_stack
, NULL
},
417 {"max mux", P_INTEGER
, P_GLOBAL
, &Globals
.max_mux
, NULL
},
418 {"max xmit", P_INTEGER
, P_GLOBAL
, &Globals
.max_xmit
, NULL
},
419 {"max packet", P_INTEGER
, P_GLOBAL
, &Globals
.max_packet
, NULL
},
420 {"packet size", P_INTEGER
, P_GLOBAL
, &Globals
.max_packet
, NULL
},
421 {"password level", P_INTEGER
, P_GLOBAL
, &Globals
.pwordlevel
, NULL
},
422 {"keepalive", P_INTEGER
, P_GLOBAL
, &keepalive
, NULL
},
423 {"deadtime", P_INTEGER
, P_GLOBAL
, &Globals
.deadtime
, NULL
},
424 {"time offset", P_INTEGER
, P_GLOBAL
, &extra_time_offset
, NULL
},
425 {"read size", P_INTEGER
, P_GLOBAL
, &Globals
.ReadSize
, NULL
},
427 {"coding system", P_INTEGER
, P_GLOBAL
, &coding_system
, handle_coding_system
},
429 {"os level", P_INTEGER
, P_GLOBAL
, &Globals
.os_level
, NULL
},
430 {"max ttl", P_INTEGER
, P_GLOBAL
, &Globals
.max_ttl
, NULL
},
431 {"wins support", P_BOOL
, P_GLOBAL
, &Globals
.bWINSsupport
, NULL
},
432 {"wins proxy", P_BOOL
, P_GLOBAL
, &Globals
.bWINSproxy
, NULL
},
433 {"wins server", P_STRING
, P_GLOBAL
, &Globals
.szWINSserver
, NULL
},
434 {"preferred master", P_BOOL
, P_GLOBAL
, &Globals
.bPreferredMaster
, NULL
},
435 {"prefered master", P_BOOL
, P_GLOBAL
, &Globals
.bPreferredMaster
, NULL
},
436 {"domain master", P_BOOL
, P_GLOBAL
, &Globals
.bDomainMaster
, NULL
},
437 {"domain logons", P_BOOL
, P_GLOBAL
, &Globals
.bDomainLogons
, NULL
},
438 {"browse list", P_BOOL
, P_GLOBAL
, &Globals
.bBrowseList
, NULL
},
440 {"-valid", P_BOOL
, P_LOCAL
, &sDefault
.valid
, NULL
},
441 {"comment", P_STRING
, P_LOCAL
, &sDefault
.comment
, NULL
},
442 {"copy", P_STRING
, P_LOCAL
, &sDefault
.szCopy
, handle_copy
},
443 {"include", P_STRING
, P_LOCAL
, &sDefault
.szInclude
, handle_include
},
444 {"exec", P_STRING
, P_LOCAL
, &sDefault
.szPreExec
, NULL
},
445 {"preexec", P_STRING
, P_LOCAL
, &sDefault
.szPreExec
, NULL
},
446 {"postexec", P_STRING
, P_LOCAL
, &sDefault
.szPostExec
, NULL
},
447 {"root preexec", P_STRING
, P_LOCAL
, &sDefault
.szRootPreExec
, NULL
},
448 {"root postexec", P_STRING
, P_LOCAL
, &sDefault
.szRootPostExec
, NULL
},
449 {"alternate permissions",P_BOOL
,P_LOCAL
, &sDefault
.bAlternatePerm
, NULL
},
450 {"revalidate", P_BOOL
, P_LOCAL
, &sDefault
.bRevalidate
, NULL
},
451 {"default case", P_INTEGER
, P_LOCAL
, &sDefault
.iDefaultCase
, handle_case
},
452 {"case sensitive", P_BOOL
, P_LOCAL
, &sDefault
.bCaseSensitive
, NULL
},
453 {"casesignames", P_BOOL
, P_LOCAL
, &sDefault
.bCaseSensitive
, NULL
},
454 {"preserve case", P_BOOL
, P_LOCAL
, &sDefault
.bCasePreserve
, NULL
},
455 {"short preserve case",P_BOOL
, P_LOCAL
, &sDefault
.bShortCasePreserve
,NULL
},
456 {"mangle case", P_BOOL
, P_LOCAL
, &sDefault
.bCaseMangle
, NULL
},
457 {"mangling char", P_CHAR
, P_LOCAL
, &sDefault
.magic_char
, NULL
},
458 {"browseable", P_BOOL
, P_LOCAL
, &sDefault
.bBrowseable
, NULL
},
459 {"browsable", P_BOOL
, P_LOCAL
, &sDefault
.bBrowseable
, NULL
},
460 {"available", P_BOOL
, P_LOCAL
, &sDefault
.bAvailable
, NULL
},
461 {"path", P_STRING
, P_LOCAL
, &sDefault
.szPath
, NULL
},
462 {"directory", P_STRING
, P_LOCAL
, &sDefault
.szPath
, NULL
},
463 {"username", P_STRING
, P_LOCAL
, &sDefault
.szUsername
, NULL
},
464 {"user", P_STRING
, P_LOCAL
, &sDefault
.szUsername
, NULL
},
465 {"users", P_STRING
, P_LOCAL
, &sDefault
.szUsername
, NULL
},
466 {"guest account", P_STRING
, P_LOCAL
, &sDefault
.szGuestaccount
, NULL
},
467 {"invalid users", P_STRING
, P_LOCAL
, &sDefault
.szInvalidUsers
, NULL
},
468 {"valid users", P_STRING
, P_LOCAL
, &sDefault
.szValidUsers
, NULL
},
469 {"admin users", P_STRING
, P_LOCAL
, &sDefault
.szAdminUsers
, NULL
},
470 {"read list", P_STRING
, P_LOCAL
, &sDefault
.readlist
, NULL
},
471 {"write list", P_STRING
, P_LOCAL
, &sDefault
.writelist
, NULL
},
472 {"volume", P_STRING
, P_LOCAL
, &sDefault
.volume
, NULL
},
473 {"force user", P_STRING
, P_LOCAL
, &sDefault
.force_user
, NULL
},
474 {"force group", P_STRING
, P_LOCAL
, &sDefault
.force_group
, NULL
},
475 {"group", P_STRING
, P_LOCAL
, &sDefault
.force_group
, NULL
},
476 {"read only", P_BOOL
, P_LOCAL
, &sDefault
.bRead_only
, NULL
},
477 {"write ok", P_BOOLREV
, P_LOCAL
, &sDefault
.bRead_only
, NULL
},
478 {"writeable", P_BOOLREV
, P_LOCAL
, &sDefault
.bRead_only
, NULL
},
479 {"writable", P_BOOLREV
, P_LOCAL
, &sDefault
.bRead_only
, NULL
},
480 {"max connections", P_INTEGER
, P_LOCAL
, &sDefault
.iMaxConnections
, NULL
},
481 {"min print space", P_INTEGER
, P_LOCAL
, &sDefault
.iMinPrintSpace
, NULL
},
482 {"create mask", P_OCTAL
, P_LOCAL
, &sDefault
.iCreate_mode
, NULL
},
483 {"create mode", P_OCTAL
, P_LOCAL
, &sDefault
.iCreate_mode
, NULL
},
484 {"directory mask", P_OCTAL
, P_LOCAL
, &sDefault
.iDir_mode
, NULL
},
485 {"directory mode", P_OCTAL
, P_LOCAL
, &sDefault
.iDir_mode
, NULL
},
486 {"set directory", P_BOOLREV
, P_LOCAL
, &sDefault
.bNo_set_dir
, NULL
},
487 {"status", P_BOOL
, P_LOCAL
, &sDefault
.status
, NULL
},
488 {"hide dot files", P_BOOL
, P_LOCAL
, &sDefault
.bHideDotFiles
, NULL
},
489 {"guest only", P_BOOL
, P_LOCAL
, &sDefault
.bGuest_only
, NULL
},
490 {"only guest", P_BOOL
, P_LOCAL
, &sDefault
.bGuest_only
, NULL
},
491 {"guest ok", P_BOOL
, P_LOCAL
, &sDefault
.bGuest_ok
, NULL
},
492 {"public", P_BOOL
, P_LOCAL
, &sDefault
.bGuest_ok
, NULL
},
493 {"print ok", P_BOOL
, P_LOCAL
, &sDefault
.bPrint_ok
, NULL
},
494 {"printable", P_BOOL
, P_LOCAL
, &sDefault
.bPrint_ok
, NULL
},
495 {"postscript", P_BOOL
, P_LOCAL
, &sDefault
.bPostscript
, NULL
},
496 {"map system", P_BOOL
, P_LOCAL
, &sDefault
.bMap_system
, NULL
},
497 {"map hidden", P_BOOL
, P_LOCAL
, &sDefault
.bMap_hidden
, NULL
},
498 {"map archive", P_BOOL
, P_LOCAL
, &sDefault
.bMap_archive
, NULL
},
499 {"locking", P_BOOL
, P_LOCAL
, &sDefault
.bLocking
, NULL
},
500 {"strict locking", P_BOOL
, P_LOCAL
, &sDefault
.bStrictLocking
, NULL
},
501 {"share modes", P_BOOL
, P_LOCAL
, &sDefault
.bShareModes
, NULL
},
502 {"only user", P_BOOL
, P_LOCAL
, &sDefault
.bOnlyUser
, NULL
},
503 {"wide links", P_BOOL
, P_LOCAL
, &sDefault
.bWidelinks
, NULL
},
504 {"sync always", P_BOOL
, P_LOCAL
, &sDefault
.bSyncAlways
, NULL
},
505 {"mangled names", P_BOOL
, P_LOCAL
, &sDefault
.bMangledNames
, NULL
},
506 {"fake oplocks", P_BOOL
, P_LOCAL
, &sDefault
.bFakeOplocks
, NULL
},
507 {"print command", P_STRING
, P_LOCAL
, &sDefault
.szPrintcommand
, NULL
},
508 {"lpq command", P_STRING
, P_LOCAL
, &sDefault
.szLpqcommand
, NULL
},
509 {"lprm command", P_STRING
, P_LOCAL
, &sDefault
.szLprmcommand
, NULL
},
510 {"lppause command", P_STRING
, P_LOCAL
, &sDefault
.szLppausecommand
, NULL
},
511 {"lpresume command", P_STRING
, P_LOCAL
, &sDefault
.szLpresumecommand
,NULL
},
512 {"printer", P_STRING
, P_LOCAL
, &sDefault
.szPrintername
, NULL
},
513 {"printer name", P_STRING
, P_LOCAL
, &sDefault
.szPrintername
, NULL
},
514 {"printer driver", P_STRING
, P_LOCAL
, &sDefault
.szPrinterDriver
, NULL
},
515 {"hosts allow", P_STRING
, P_LOCAL
, &sDefault
.szHostsallow
, NULL
},
516 {"allow hosts", P_STRING
, P_LOCAL
, &sDefault
.szHostsallow
, NULL
},
517 {"hosts deny", P_STRING
, P_LOCAL
, &sDefault
.szHostsdeny
, NULL
},
518 {"deny hosts", P_STRING
, P_LOCAL
, &sDefault
.szHostsdeny
, NULL
},
519 {"dont descend", P_STRING
, P_LOCAL
, &sDefault
.szDontdescend
, NULL
},
520 {"magic script", P_STRING
, P_LOCAL
, &sDefault
.szMagicScript
, NULL
},
521 {"magic output", P_STRING
, P_LOCAL
, &sDefault
.szMagicOutput
, NULL
},
522 {"mangled map", P_STRING
, P_LOCAL
, &sDefault
.szMangledMap
, NULL
},
523 {"delete readonly", P_BOOL
, P_LOCAL
, &sDefault
.bDeleteReadonly
, NULL
},
525 {NULL
, P_BOOL
, P_NONE
, NULL
, NULL
}
530 /***************************************************************************
531 Initialise the global parameter structure.
532 ***************************************************************************/
533 static void init_globals(void)
535 static BOOL done_init
= False
;
541 bzero((void *)&Globals
,sizeof(Globals
));
543 for (i
= 0; parm_table
[i
].label
; i
++)
544 if ((parm_table
[i
].type
== P_STRING
||
545 parm_table
[i
].type
== P_USTRING
) &&
547 string_init(parm_table
[i
].ptr
,"");
549 string_set(&sDefault
.szGuestaccount
, GUEST_ACCOUNT
);
550 string_set(&sDefault
.szPrinterDriver
, "NULL");
556 DEBUG(3,("Initialising global parameters\n"));
558 #ifdef SMB_PASSWD_FILE
559 string_set(&Globals
.szSMBPasswdFile
, SMB_PASSWD_FILE
);
561 string_set(&Globals
.szPasswdChat
,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
562 string_set(&Globals
.szWorkGroup
, WORKGROUP
);
564 string_set(&Globals
.szPasswdProgram
, SMB_PASSWD
);
566 string_set(&Globals
.szPasswdProgram
, "/bin/passwd");
568 string_set(&Globals
.szPrintcapname
, PRINTCAP_NAME
);
569 string_set(&Globals
.szLockDir
, LOCKDIR
);
570 string_set(&Globals
.szRootdir
, "/");
571 string_set(&Globals
.szSmbrun
, SMBRUN
);
572 string_set(&Globals
.szSocketAddress
, "0.0.0.0");
573 sprintf(s
,"Samba %s",VERSION
);
574 string_set(&Globals
.szServerString
,s
);
575 Globals
.bLoadPrinters
= True
;
576 Globals
.bUseRhosts
= False
;
577 Globals
.max_packet
= 65535;
578 Globals
.mangled_stack
= 50;
579 Globals
.max_xmit
= Globals
.max_packet
;
581 Globals
.lpqcachetime
= 10;
582 Globals
.pwordlevel
= 0;
583 Globals
.deadtime
= 0;
584 Globals
.max_log_size
= 5000;
585 Globals
.maxprotocol
= PROTOCOL_NT1
;
586 Globals
.security
= SEC_SHARE
;
587 Globals
.bEncryptPasswords
= False
;
588 Globals
.printing
= DEFAULT_PRINTING
;
589 Globals
.bReadRaw
= True
;
590 Globals
.bWriteRaw
= True
;
591 Globals
.bReadPrediction
= False
;
592 Globals
.bReadbmpx
= True
;
593 Globals
.bNullPasswords
= False
;
594 Globals
.bStripDot
= False
;
596 Globals
.bSyslogOnly
= False
;
597 Globals
.os_level
= 0;
598 Globals
.max_ttl
= 60*60*4; /* 2 hours default */
599 Globals
.bPreferredMaster
= True
;
600 Globals
.bDomainMaster
= False
;
601 Globals
.bDomainLogons
= False
;
602 Globals
.bBrowseList
= True
;
603 Globals
.bWINSsupport
= False
;
604 Globals
.bWINSproxy
= False
;
605 Globals
.ReadSize
= 16*1024;
608 coding_system
= interpret_coding_system (KANJI
, SJIS_CODE
);
613 /***************************************************************************
614 check if a string is initialised and if not then initialise it
615 ***************************************************************************/
616 static void string_initial(char **s
,char *v
)
623 /***************************************************************************
624 Initialise the sDefault parameter structure.
625 ***************************************************************************/
626 static void init_locals(void)
628 /* choose defaults depending on the type of printing */
629 switch (Globals
.printing
)
635 string_initial(&sDefault
.szLpqcommand
,"lpq -P%p");
636 string_initial(&sDefault
.szLprmcommand
,"lprm -P%p %j");
637 string_initial(&sDefault
.szPrintcommand
,"lpr -r -P%p %s");
642 string_initial(&sDefault
.szLpqcommand
,"lpstat -o%p");
643 string_initial(&sDefault
.szLprmcommand
,"cancel %p-%j");
644 string_initial(&sDefault
.szPrintcommand
,"lp -c -d%p %s; rm %s");
646 string_initial(&sDefault
.szLppausecommand
,"lp -i %p-%j -H hold");
647 string_initial(&sDefault
.szLpresumecommand
,"lp -i %p-%j -H resume");
652 string_initial(&sDefault
.szLpqcommand
,"lpq -P%p");
653 string_initial(&sDefault
.szLprmcommand
,"lprm -P%p %j");
654 string_initial(&sDefault
.szPrintcommand
,"lp -r -P%p %s");
662 /******************************************************************* a
663 convenience routine to grab string parameters into a rotating buffer,
664 and run standard_sub_basic on them. The buffers can be written to by
665 callers without affecting the source string.
666 ********************************************************************/
667 char *lp_string(char *s
)
669 static char *bufs
[10];
670 static int buflen
[10];
671 static int next
= -1;
674 int len
= s
?strlen(s
):0;
685 len
= MAX(len
+100,sizeof(pstring
)); /* the +100 is for some
688 if (buflen
[next
] != len
) {
690 if (bufs
[next
]) free(bufs
[next
]);
691 bufs
[next
] = (char *)malloc(len
);
693 DEBUG(0,("out of memory in lp_string()"));
698 ret
= &bufs
[next
][0];
706 standard_sub_basic(ret
);
712 In this section all the functions that are used to access the
713 parameters from the rest of the program are defined
716 #define FN_GLOBAL_STRING(fn_name,ptr) \
717 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
718 #define FN_GLOBAL_BOOL(fn_name,ptr) \
719 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
720 #define FN_GLOBAL_CHAR(fn_name,ptr) \
721 char fn_name(void) {return(*(char *)(ptr));}
722 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
723 int fn_name(void) {return(*(int *)(ptr));}
725 #define FN_LOCAL_STRING(fn_name,val) \
726 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
727 #define FN_LOCAL_BOOL(fn_name,val) \
728 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
729 #define FN_LOCAL_CHAR(fn_name,val) \
730 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
731 #define FN_LOCAL_INTEGER(fn_name,val) \
732 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
734 FN_GLOBAL_STRING(lp_logfile
,&Globals
.szLogFile
)
735 FN_GLOBAL_STRING(lp_smbrun
,&Globals
.szSmbrun
)
736 FN_GLOBAL_STRING(lp_configfile
,&Globals
.szConfigFile
)
737 FN_GLOBAL_STRING(lp_smb_passwd_file
,&Globals
.szSMBPasswdFile
)
738 FN_GLOBAL_STRING(lp_serverstring
,&Globals
.szServerString
)
739 FN_GLOBAL_STRING(lp_printcapname
,&Globals
.szPrintcapname
)
740 FN_GLOBAL_STRING(lp_lockdir
,&Globals
.szLockDir
)
741 FN_GLOBAL_STRING(lp_rootdir
,&Globals
.szRootdir
)
742 FN_GLOBAL_STRING(lp_defaultservice
,&Globals
.szDefaultService
)
743 FN_GLOBAL_STRING(lp_msg_command
,&Globals
.szMsgCommand
)
744 FN_GLOBAL_STRING(lp_dfree_command
,&Globals
.szDfree
)
745 FN_GLOBAL_STRING(lp_hosts_equiv
,&Globals
.szHostsEquiv
)
746 FN_GLOBAL_STRING(lp_auto_services
,&Globals
.szAutoServices
)
747 FN_GLOBAL_STRING(lp_passwd_program
,&Globals
.szPasswdProgram
)
748 FN_GLOBAL_STRING(lp_passwd_chat
,&Globals
.szPasswdChat
)
749 FN_GLOBAL_STRING(lp_passwordserver
,&Globals
.szPasswordServer
)
750 FN_GLOBAL_STRING(lp_workgroup
,&Globals
.szWorkGroup
)
751 FN_GLOBAL_STRING(lp_domain_controller
,&Globals
.szDomainController
)
752 FN_GLOBAL_STRING(lp_username_map
,&Globals
.szUsernameMap
)
753 FN_GLOBAL_STRING(lp_character_set
,&Globals
.szCharacterSet
)
754 FN_GLOBAL_STRING(lp_logon_script
,&Globals
.szLogonScript
)
755 FN_GLOBAL_STRING(lp_logon_path
,&Globals
.szLogonPath
)
756 FN_GLOBAL_STRING(lp_veto_files
,&Globals
.szVetoFiles
)
757 FN_GLOBAL_STRING(lp_remote_announce
,&Globals
.szRemoteAnnounce
)
758 FN_GLOBAL_STRING(lp_wins_server
,&Globals
.szWINSserver
)
759 FN_GLOBAL_STRING(lp_interfaces
,&Globals
.szInterfaces
)
760 FN_GLOBAL_STRING(lp_socket_address
,&Globals
.szSocketAddress
)
762 FN_GLOBAL_BOOL(lp_wins_support
,&Globals
.bWINSsupport
)
763 FN_GLOBAL_BOOL(lp_wins_proxy
,&Globals
.bWINSproxy
)
764 FN_GLOBAL_BOOL(lp_domain_master
,&Globals
.bDomainMaster
)
765 FN_GLOBAL_BOOL(lp_domain_logons
,&Globals
.bDomainLogons
)
766 FN_GLOBAL_BOOL(lp_preferred_master
,&Globals
.bPreferredMaster
)
767 FN_GLOBAL_BOOL(lp_load_printers
,&Globals
.bLoadPrinters
)
768 FN_GLOBAL_BOOL(lp_use_rhosts
,&Globals
.bUseRhosts
)
769 FN_GLOBAL_BOOL(lp_getwdcache
,&use_getwd_cache
)
770 FN_GLOBAL_BOOL(lp_readprediction
,&Globals
.bReadPrediction
)
771 FN_GLOBAL_BOOL(lp_readbmpx
,&Globals
.bReadbmpx
)
772 FN_GLOBAL_BOOL(lp_readraw
,&Globals
.bReadRaw
)
773 FN_GLOBAL_BOOL(lp_writeraw
,&Globals
.bWriteRaw
)
774 FN_GLOBAL_BOOL(lp_null_passwords
,&Globals
.bNullPasswords
)
775 FN_GLOBAL_BOOL(lp_strip_dot
,&Globals
.bStripDot
)
776 FN_GLOBAL_BOOL(lp_encrypted_passwords
,&Globals
.bEncryptPasswords
)
777 FN_GLOBAL_BOOL(lp_syslog_only
,&Globals
.bSyslogOnly
)
778 FN_GLOBAL_BOOL(lp_browse_list
,&Globals
.bBrowseList
)
780 FN_GLOBAL_INTEGER(lp_os_level
,&Globals
.os_level
)
781 FN_GLOBAL_INTEGER(lp_max_ttl
,&Globals
.max_ttl
)
782 FN_GLOBAL_INTEGER(lp_max_log_size
,&Globals
.max_log_size
)
783 FN_GLOBAL_INTEGER(lp_mangledstack
,&Globals
.mangled_stack
)
784 FN_GLOBAL_INTEGER(lp_maxxmit
,&Globals
.max_xmit
)
785 FN_GLOBAL_INTEGER(lp_maxmux
,&Globals
.max_mux
)
786 FN_GLOBAL_INTEGER(lp_maxpacket
,&Globals
.max_packet
)
787 FN_GLOBAL_INTEGER(lp_keepalive
,&keepalive
)
788 FN_GLOBAL_INTEGER(lp_passwordlevel
,&Globals
.pwordlevel
)
789 FN_GLOBAL_INTEGER(lp_readsize
,&Globals
.ReadSize
)
790 FN_GLOBAL_INTEGER(lp_deadtime
,&Globals
.deadtime
)
791 FN_GLOBAL_INTEGER(lp_maxprotocol
,&Globals
.maxprotocol
)
792 FN_GLOBAL_INTEGER(lp_security
,&Globals
.security
)
793 FN_GLOBAL_INTEGER(lp_printing
,&Globals
.printing
)
794 FN_GLOBAL_INTEGER(lp_maxdisksize
,&Globals
.maxdisksize
)
795 FN_GLOBAL_INTEGER(lp_lpqcachetime
,&Globals
.lpqcachetime
)
796 FN_GLOBAL_INTEGER(lp_syslog
,&Globals
.syslog
)
798 FN_LOCAL_STRING(lp_preexec
,szPreExec
)
799 FN_LOCAL_STRING(lp_postexec
,szPostExec
)
800 FN_LOCAL_STRING(lp_rootpreexec
,szRootPreExec
)
801 FN_LOCAL_STRING(lp_rootpostexec
,szRootPostExec
)
802 FN_LOCAL_STRING(lp_servicename
,szService
)
803 FN_LOCAL_STRING(lp_pathname
,szPath
)
804 FN_LOCAL_STRING(lp_dontdescend
,szDontdescend
)
805 FN_LOCAL_STRING(lp_username
,szUsername
)
806 FN_LOCAL_STRING(lp_guestaccount
,szGuestaccount
)
807 FN_LOCAL_STRING(lp_invalid_users
,szInvalidUsers
)
808 FN_LOCAL_STRING(lp_valid_users
,szValidUsers
)
809 FN_LOCAL_STRING(lp_admin_users
,szAdminUsers
)
810 FN_LOCAL_STRING(lp_printcommand
,szPrintcommand
)
811 FN_LOCAL_STRING(lp_lpqcommand
,szLpqcommand
)
812 FN_LOCAL_STRING(lp_lprmcommand
,szLprmcommand
)
813 FN_LOCAL_STRING(lp_lppausecommand
,szLppausecommand
)
814 FN_LOCAL_STRING(lp_lpresumecommand
,szLpresumecommand
)
815 FN_LOCAL_STRING(lp_printername
,szPrintername
)
816 FN_LOCAL_STRING(lp_printerdriver
,szPrinterDriver
)
817 FN_LOCAL_STRING(lp_hostsallow
,szHostsallow
)
818 FN_LOCAL_STRING(lp_hostsdeny
,szHostsdeny
)
819 FN_LOCAL_STRING(lp_magicscript
,szMagicScript
)
820 FN_LOCAL_STRING(lp_magicoutput
,szMagicOutput
)
821 FN_LOCAL_STRING(lp_comment
,comment
)
822 FN_LOCAL_STRING(lp_force_user
,force_user
)
823 FN_LOCAL_STRING(lp_force_group
,force_group
)
824 FN_LOCAL_STRING(lp_readlist
,readlist
)
825 FN_LOCAL_STRING(lp_writelist
,writelist
)
826 FN_LOCAL_STRING(lp_volume
,volume
)
827 FN_LOCAL_STRING(lp_mangled_map
,szMangledMap
)
829 FN_LOCAL_BOOL(lp_alternate_permissions
,bAlternatePerm
)
830 FN_LOCAL_BOOL(lp_revalidate
,bRevalidate
)
831 FN_LOCAL_BOOL(lp_casesensitive
,bCaseSensitive
)
832 FN_LOCAL_BOOL(lp_preservecase
,bCasePreserve
)
833 FN_LOCAL_BOOL(lp_shortpreservecase
,bShortCasePreserve
)
834 FN_LOCAL_BOOL(lp_casemangle
,bCaseMangle
)
835 FN_LOCAL_BOOL(lp_status
,status
)
836 FN_LOCAL_BOOL(lp_hide_dot_files
,bHideDotFiles
)
837 FN_LOCAL_BOOL(lp_browseable
,bBrowseable
)
838 FN_LOCAL_BOOL(lp_readonly
,bRead_only
)
839 FN_LOCAL_BOOL(lp_no_set_dir
,bNo_set_dir
)
840 FN_LOCAL_BOOL(lp_guest_ok
,bGuest_ok
)
841 FN_LOCAL_BOOL(lp_guest_only
,bGuest_only
)
842 FN_LOCAL_BOOL(lp_print_ok
,bPrint_ok
)
843 FN_LOCAL_BOOL(lp_postscript
,bPostscript
)
844 FN_LOCAL_BOOL(lp_map_hidden
,bMap_hidden
)
845 FN_LOCAL_BOOL(lp_map_archive
,bMap_archive
)
846 FN_LOCAL_BOOL(lp_locking
,bLocking
)
847 FN_LOCAL_BOOL(lp_strict_locking
,bStrictLocking
)
848 FN_LOCAL_BOOL(lp_share_modes
,bShareModes
)
849 FN_LOCAL_BOOL(lp_onlyuser
,bOnlyUser
)
850 FN_LOCAL_BOOL(lp_manglednames
,bMangledNames
)
851 FN_LOCAL_BOOL(lp_widelinks
,bWidelinks
)
852 FN_LOCAL_BOOL(lp_syncalways
,bSyncAlways
)
853 FN_LOCAL_BOOL(lp_map_system
,bMap_system
)
854 FN_LOCAL_BOOL(lp_delete_readonly
,bDeleteReadonly
)
855 FN_LOCAL_BOOL(lp_fake_oplocks
,bFakeOplocks
)
857 FN_LOCAL_INTEGER(lp_create_mode
,iCreate_mode
)
858 FN_LOCAL_INTEGER(lp_dir_mode
,iDir_mode
)
859 FN_LOCAL_INTEGER(lp_max_connections
,iMaxConnections
)
860 FN_LOCAL_INTEGER(lp_defaultcase
,iDefaultCase
)
861 FN_LOCAL_INTEGER(lp_minprintspace
,iMinPrintSpace
)
863 FN_LOCAL_CHAR(lp_magicchar
,magic_char
)
867 /* local prototypes */
868 static int strwicmp( char *psz1
, char *psz2
);
869 static int map_parameter( char *pszParmName
);
870 static BOOL
set_boolean( BOOL
*pb
, char *pszParmValue
);
871 static int getservicebyname(char *pszServiceName
, service
*pserviceDest
);
872 static void copy_service( service
*pserviceDest
,
873 service
*pserviceSource
,
874 BOOL
*pcopymapDest
);
875 static BOOL
service_ok(int iService
);
876 static BOOL
do_parameter(char *pszParmName
, char *pszParmValue
);
877 static BOOL
do_section(char *pszSectionName
);
878 static void dump_globals(void);
879 static void dump_a_service(service
*pService
);
880 static void init_copymap(service
*pservice
);
883 /***************************************************************************
884 initialise a service to the defaults
885 ***************************************************************************/
886 static void init_service(service
*pservice
)
888 bzero((char *)pservice
,sizeof(service
));
889 copy_service(pservice
,&sDefault
,NULL
);
893 /***************************************************************************
894 free the dynamically allocated parts of a service struct
895 ***************************************************************************/
896 static void free_service(service
*pservice
)
902 for (i
=0;parm_table
[i
].label
;i
++)
903 if ((parm_table
[i
].type
== P_STRING
||
904 parm_table
[i
].type
== P_STRING
) &&
905 parm_table
[i
].class == P_LOCAL
)
906 string_free((char **)(((char *)pservice
) + PTR_DIFF(parm_table
[i
].ptr
,&sDefault
)));
909 /***************************************************************************
910 add a new service to the services array initialising it with the given
912 ***************************************************************************/
913 static int add_a_service(service
*pservice
, char *name
)
917 int num_to_alloc
= iNumServices
+1;
919 tservice
= *pservice
;
921 /* it might already exist */
924 i
= getservicebyname(name
,NULL
);
929 /* find an invalid one */
930 for (i
=0;i
<iNumServices
;i
++)
931 if (!pSERVICE(i
)->valid
)
934 /* if not, then create one */
935 if (i
== iNumServices
)
937 ServicePtrs
= (service
**)Realloc(ServicePtrs
,sizeof(service
*)*num_to_alloc
);
939 pSERVICE(iNumServices
) = (service
*)malloc(sizeof(service
));
941 if (!ServicePtrs
|| !pSERVICE(iNumServices
))
947 free_service(pSERVICE(i
));
949 pSERVICE(i
)->valid
= True
;
951 init_service(pSERVICE(i
));
952 copy_service(pSERVICE(i
),&tservice
,NULL
);
954 string_set(&iSERVICE(i
).szService
,name
);
959 /***************************************************************************
960 add a new home service, with the specified home directory, defaults coming
962 ***************************************************************************/
963 BOOL
lp_add_home(char *pszHomename
, int iDefaultService
, char *pszHomedir
)
965 int i
= add_a_service(pSERVICE(iDefaultService
),pszHomename
);
970 if (!(*(iSERVICE(i
).szPath
)) || strequal(iSERVICE(i
).szPath
,lp_pathname(-1)))
971 string_set(&iSERVICE(i
).szPath
,pszHomedir
);
972 if (!(*(iSERVICE(i
).comment
)))
975 sprintf(comment
,"Home directory of %s",pszHomename
);
976 string_set(&iSERVICE(i
).comment
,comment
);
978 iSERVICE(i
).bAvailable
= sDefault
.bAvailable
;
979 iSERVICE(i
).bBrowseable
= sDefault
.bBrowseable
;
981 DEBUG(3,("adding home directory %s at %s\n", pszHomename
, pszHomedir
));
986 /***************************************************************************
987 add a new service, based on an old one
988 ***************************************************************************/
989 int lp_add_service(char *pszService
, int iDefaultService
)
991 return(add_a_service(pSERVICE(iDefaultService
),pszService
));
995 /***************************************************************************
997 ***************************************************************************/
998 static BOOL
lp_add_ipc(void)
1001 int i
= add_a_service(&sDefault
,"IPC$");
1006 sprintf(comment
,"IPC Service (%s)",lp_serverstring());
1008 string_set(&iSERVICE(i
).szPath
,tmpdir());
1009 string_set(&iSERVICE(i
).szUsername
,"");
1010 string_set(&iSERVICE(i
).comment
,comment
);
1011 iSERVICE(i
).status
= False
;
1012 iSERVICE(i
).iMaxConnections
= 0;
1013 iSERVICE(i
).bAvailable
= True
;
1014 iSERVICE(i
).bRead_only
= True
;
1015 iSERVICE(i
).bGuest_only
= False
;
1016 iSERVICE(i
).bGuest_ok
= True
;
1017 iSERVICE(i
).bPrint_ok
= False
;
1018 iSERVICE(i
).bBrowseable
= sDefault
.bBrowseable
;
1020 DEBUG(3,("adding IPC service\n"));
1026 /***************************************************************************
1027 add a new printer service, with defaults coming from service iFrom
1028 ***************************************************************************/
1029 BOOL
lp_add_printer(char *pszPrintername
, int iDefaultService
)
1031 char *comment
= "From Printcap";
1032 int i
= add_a_service(pSERVICE(iDefaultService
),pszPrintername
);
1037 /* note that we do NOT default the availability flag to True - */
1038 /* we take it from the default service passed. This allows all */
1039 /* dynamic printers to be disabled by disabling the [printers] */
1040 /* entry (if/when the 'available' keyword is implemented!). */
1042 /* the printer name is set to the service name. */
1043 string_set(&iSERVICE(i
).szPrintername
,pszPrintername
);
1044 string_set(&iSERVICE(i
).comment
,comment
);
1045 iSERVICE(i
).bBrowseable
= sDefault
.bBrowseable
;
1047 DEBUG(3,("adding printer service %s\n",pszPrintername
));
1053 /***************************************************************************
1054 Do a case-insensitive, whitespace-ignoring string compare.
1055 ***************************************************************************/
1056 static int strwicmp(char *psz1
, char *psz2
)
1058 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1059 /* appropriate value. */
1069 /* sync the strings on first non-whitespace */
1072 while (isspace(*psz1
))
1074 while (isspace(*psz2
))
1076 if (toupper(*psz1
) != toupper(*psz2
) || *psz1
== '\0' || *psz2
== '\0')
1081 return (*psz1
- *psz2
);
1084 /***************************************************************************
1085 Map a parameter's string representation to something we can use.
1086 Returns False if the parameter string is not recognised, else TRUE.
1087 ***************************************************************************/
1088 static int map_parameter(char *pszParmName
)
1092 if (*pszParmName
== '-')
1095 for (iIndex
= 0; parm_table
[iIndex
].label
; iIndex
++)
1096 if (strwicmp(parm_table
[iIndex
].label
, pszParmName
) == 0)
1099 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName
));
1104 /***************************************************************************
1105 Set a boolean variable from the text value stored in the passed string.
1106 Returns True in success, False if the passed string does not correctly
1107 represent a boolean.
1108 ***************************************************************************/
1109 static BOOL
set_boolean(BOOL
*pb
, char *pszParmValue
)
1114 if (strwicmp(pszParmValue
, "yes") == 0 ||
1115 strwicmp(pszParmValue
, "true") == 0 ||
1116 strwicmp(pszParmValue
, "1") == 0)
1119 if (strwicmp(pszParmValue
, "no") == 0 ||
1120 strwicmp(pszParmValue
, "False") == 0 ||
1121 strwicmp(pszParmValue
, "0") == 0)
1125 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1132 /***************************************************************************
1133 Find a service by name. Otherwise works like get_service.
1134 ***************************************************************************/
1135 static int getservicebyname(char *pszServiceName
, service
*pserviceDest
)
1139 for (iService
= iNumServices
- 1; iService
>= 0; iService
--)
1140 if (VALID(iService
) &&
1141 strwicmp(iSERVICE(iService
).szService
, pszServiceName
) == 0)
1143 if (pserviceDest
!= NULL
)
1144 copy_service(pserviceDest
, pSERVICE(iService
), NULL
);
1153 /***************************************************************************
1154 Copy a service structure to another
1156 If pcopymapDest is NULL then copy all fields
1157 ***************************************************************************/
1158 static void copy_service(service
*pserviceDest
,
1159 service
*pserviceSource
,
1163 BOOL bcopyall
= (pcopymapDest
== NULL
);
1165 for (i
=0;parm_table
[i
].label
;i
++)
1166 if (parm_table
[i
].ptr
&& parm_table
[i
].class == P_LOCAL
&&
1167 (bcopyall
|| pcopymapDest
[i
]))
1169 void *def_ptr
= parm_table
[i
].ptr
;
1171 ((char *)pserviceSource
) + PTR_DIFF(def_ptr
,&sDefault
);
1173 ((char *)pserviceDest
) + PTR_DIFF(def_ptr
,&sDefault
);
1175 switch (parm_table
[i
].type
)
1179 *(BOOL
*)dest_ptr
= *(BOOL
*)src_ptr
;
1184 *(int *)dest_ptr
= *(int *)src_ptr
;
1188 *(char *)dest_ptr
= *(char *)src_ptr
;
1192 string_set(dest_ptr
,*(char **)src_ptr
);
1196 string_set(dest_ptr
,*(char **)src_ptr
);
1197 strupper(*(char **)dest_ptr
);
1206 init_copymap(pserviceDest
);
1207 if (pserviceSource
->copymap
)
1208 memcpy((void *)pserviceDest
->copymap
,
1209 (void *)pserviceSource
->copymap
,sizeof(BOOL
)*NUMPARAMETERS
);
1213 /***************************************************************************
1214 Check a service for consistency. Return False if the service is in any way
1215 incomplete or faulty, else True.
1216 ***************************************************************************/
1217 static BOOL
service_ok(int iService
)
1222 if (iSERVICE(iService
).szService
[0] == '\0')
1224 DEBUG(0,( "The following message indicates an internal error:\n"));
1225 DEBUG(0,( "No service name in service entry.\n"));
1229 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1230 /* I can't see why you'd want a non-printable printer service... */
1231 if (strwicmp(iSERVICE(iService
).szService
,PRINTERS_NAME
) == 0)
1232 if (!iSERVICE(iService
).bPrint_ok
)
1234 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1235 iSERVICE(iService
).szService
));
1236 iSERVICE(iService
).bPrint_ok
= True
;
1239 if (iSERVICE(iService
).szPath
[0] == '\0' &&
1240 strwicmp(iSERVICE(iService
).szService
,HOMES_NAME
) != 0)
1242 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService
).szService
,tmpdir()));
1243 string_set(&iSERVICE(iService
).szPath
,tmpdir());
1246 /* If a service is flagged unavailable, log the fact at level 0. */
1247 if (!iSERVICE(iService
).bAvailable
)
1248 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1249 iSERVICE(iService
).szService
));
1254 static struct file_lists
{
1255 struct file_lists
*next
;
1258 } *file_lists
= NULL
;
1260 /*******************************************************************
1261 keep a linked list of all config files so we know when one has changed
1262 it's date and needs to be reloaded
1263 ********************************************************************/
1264 static void add_to_file_list(char *fname
)
1266 struct file_lists
*f
=file_lists
;
1269 if (f
->name
&& !strcmp(f
->name
,fname
)) break;
1274 f
= (struct file_lists
*)malloc(sizeof(file_lists
[0]));
1276 f
->next
= file_lists
;
1277 f
->name
= strdup(fname
);
1288 standard_sub_basic(n2
);
1289 f
->modtime
= file_modtime(n2
);
1294 /*******************************************************************
1295 check if a config file has changed date
1296 ********************************************************************/
1297 BOOL
lp_file_list_changed(void)
1299 struct file_lists
*f
= file_lists
;
1303 standard_sub_basic(n2
);
1304 if (f
->modtime
!= file_modtime(n2
)) return(True
);
1311 /***************************************************************************
1312 handle the interpretation of the coding system parameter
1313 *************************************************************************/
1314 static BOOL
handle_coding_system(char *pszParmValue
,int *val
)
1316 *val
= interpret_coding_system(pszParmValue
,*val
);
1321 /***************************************************************************
1322 handle the interpretation of the character set system parameter
1323 ***************************************************************************/
1324 static BOOL
handle_character_set(char *pszParmValue
,int *val
)
1326 string_set(&Globals
.szCharacterSet
,pszParmValue
);
1327 *val
= interpret_character_set(pszParmValue
,*val
);
1332 /***************************************************************************
1333 handle the interpretation of the protocol parameter
1334 ***************************************************************************/
1335 static BOOL
handle_protocol(char *pszParmValue
,int *val
)
1337 *val
= interpret_protocol(pszParmValue
,*val
);
1341 /***************************************************************************
1342 handle the interpretation of the security parameter
1343 ***************************************************************************/
1344 static BOOL
handle_security(char *pszParmValue
,int *val
)
1346 *val
= interpret_security(pszParmValue
,*val
);
1350 /***************************************************************************
1351 handle the interpretation of the default case
1352 ***************************************************************************/
1353 static BOOL
handle_case(char *pszParmValue
,int *val
)
1355 if (strequal(pszParmValue
,"LOWER"))
1357 else if (strequal(pszParmValue
,"UPPER"))
1362 /***************************************************************************
1363 handle the interpretation of the printing system
1364 ***************************************************************************/
1365 static BOOL
handle_printing(char *pszParmValue
,int *val
)
1367 if (strequal(pszParmValue
,"sysv"))
1369 else if (strequal(pszParmValue
,"aix"))
1371 else if (strequal(pszParmValue
,"hpux"))
1373 else if (strequal(pszParmValue
,"bsd"))
1375 else if (strequal(pszParmValue
,"qnx"))
1377 else if (strequal(pszParmValue
,"plp"))
1379 else if (strequal(pszParmValue
,"lprng"))
1384 /***************************************************************************
1385 handle the valid chars lines
1386 ***************************************************************************/
1387 static BOOL
handle_valid_chars(char *pszParmValue
,char **ptr
)
1389 string_set(ptr
,pszParmValue
);
1391 add_char_string(pszParmValue
);
1396 /***************************************************************************
1397 handle the include operation
1398 ***************************************************************************/
1399 static BOOL
handle_include(char *pszParmValue
,char **ptr
)
1402 strcpy(fname
,pszParmValue
);
1404 add_to_file_list(fname
);
1406 standard_sub_basic(fname
);
1408 string_set(ptr
,fname
);
1410 if (file_exist(fname
,NULL
))
1411 return(pm_process(fname
, do_section
, do_parameter
));
1413 DEBUG(2,("Can't find include file %s\n",fname
));
1419 /***************************************************************************
1420 handle the interpretation of the copy parameter
1421 ***************************************************************************/
1422 static BOOL
handle_copy(char *pszParmValue
,char **ptr
)
1426 service serviceTemp
;
1428 string_set(ptr
,pszParmValue
);
1430 init_service(&serviceTemp
);
1434 DEBUG(3,("Copying service from service %s\n",pszParmValue
));
1436 if ((iTemp
= getservicebyname(pszParmValue
, &serviceTemp
)) >= 0)
1438 if (iTemp
== iServiceIndex
)
1440 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1445 copy_service(pSERVICE(iServiceIndex
),
1447 iSERVICE(iServiceIndex
).copymap
);
1453 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1458 free_service(&serviceTemp
);
1463 /***************************************************************************
1464 initialise a copymap
1465 ***************************************************************************/
1466 static void init_copymap(service
*pservice
)
1469 if (pservice
->copymap
) free(pservice
->copymap
);
1470 pservice
->copymap
= (BOOL
*)malloc(sizeof(BOOL
)*NUMPARAMETERS
);
1471 if (!pservice
->copymap
)
1472 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS
));
1474 for (i
=0;i
<NUMPARAMETERS
;i
++)
1475 pservice
->copymap
[i
] = True
;
1479 /***************************************************************************
1480 Process a parameter.
1481 ***************************************************************************/
1482 static BOOL
do_parameter(char *pszParmName
, char *pszParmValue
)
1485 void *parm_ptr
=NULL
; /* where we are going to store the result */
1488 if (!bInGlobalSection
&& bGlobalOnly
) return(True
);
1490 DEBUG(3,("doing parameter %s = %s\n",pszParmName
,pszParmValue
));
1492 parmnum
= map_parameter(pszParmName
);
1496 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName
));
1500 def_ptr
= parm_table
[parmnum
].ptr
;
1502 /* we might point at a service, the default service or a global */
1503 if (bInGlobalSection
)
1507 if (parm_table
[parmnum
].class == P_GLOBAL
)
1509 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName
));
1512 parm_ptr
= ((char *)pSERVICE(iServiceIndex
)) + PTR_DIFF(def_ptr
,&sDefault
);
1515 if (!bInGlobalSection
)
1518 if (!iSERVICE(iServiceIndex
).copymap
)
1519 init_copymap(pSERVICE(iServiceIndex
));
1521 /* this handles the aliases - set the copymap for other entries with
1522 the same data pointer */
1523 for (i
=0;parm_table
[i
].label
;i
++)
1524 if (parm_table
[i
].ptr
== parm_table
[parmnum
].ptr
)
1525 iSERVICE(iServiceIndex
).copymap
[i
] = False
;
1528 /* if it is a special case then go ahead */
1529 if (parm_table
[parmnum
].special
)
1531 parm_table
[parmnum
].special(pszParmValue
,parm_ptr
);
1535 /* now switch on the type of variable it is */
1536 switch (parm_table
[parmnum
].type
)
1539 set_boolean(parm_ptr
,pszParmValue
);
1543 set_boolean(parm_ptr
,pszParmValue
);
1544 *(BOOL
*)parm_ptr
= ! *(BOOL
*)parm_ptr
;
1548 *(int *)parm_ptr
= atoi(pszParmValue
);
1552 *(char *)parm_ptr
= *pszParmValue
;
1556 sscanf(pszParmValue
,"%o",(int *)parm_ptr
);
1560 string_set(parm_ptr
,pszParmValue
);
1564 string_set(parm_ptr
,pszParmValue
);
1565 strupper(*(char **)parm_ptr
);
1569 strcpy((char *)parm_ptr
,pszParmValue
);
1573 strcpy((char *)parm_ptr
,pszParmValue
);
1574 strupper((char *)parm_ptr
);
1581 /***************************************************************************
1582 print a parameter of the specified type
1583 ***************************************************************************/
1584 static void print_parameter(parm_type type
,void *ptr
)
1589 printf("%s",BOOLSTR(*(BOOL
*)ptr
));
1593 printf("%s",BOOLSTR(! *(BOOL
*)ptr
));
1597 printf("%d",*(int *)ptr
);
1601 printf("%c",*(char *)ptr
);
1605 printf("0%o",*(int *)ptr
);
1611 printf("%s",(char *)ptr
);
1617 printf("%s",*(char **)ptr
);
1623 /***************************************************************************
1624 check if two parameters are equal
1625 ***************************************************************************/
1626 static BOOL
equal_parameter(parm_type type
,void *ptr1
,void *ptr2
)
1632 return(*((BOOL
*)ptr1
) == *((BOOL
*)ptr2
));
1636 return(*((int *)ptr1
) == *((int *)ptr2
));
1639 return(*((char *)ptr1
) == *((char *)ptr2
));
1644 char *p1
= (char *)ptr1
, *p2
= (char *)ptr2
;
1645 if (p1
&& !*p1
) p1
= NULL
;
1646 if (p2
&& !*p2
) p2
= NULL
;
1647 return(p1
==p2
|| strequal(p1
,p2
));
1652 char *p1
= *(char **)ptr1
, *p2
= *(char **)ptr2
;
1653 if (p1
&& !*p1
) p1
= NULL
;
1654 if (p2
&& !*p2
) p2
= NULL
;
1655 return(p1
==p2
|| strequal(p1
,p2
));
1661 /***************************************************************************
1662 Process a new section (service). At this stage all sections are services.
1663 Later we'll have special sections that permit server parameters to be set.
1664 Returns True on success, False on failure.
1665 ***************************************************************************/
1666 static BOOL
do_section(char *pszSectionName
)
1669 BOOL isglobal
= ((strwicmp(pszSectionName
, GLOBAL_NAME
) == 0) ||
1670 (strwicmp(pszSectionName
, GLOBAL_NAME2
) == 0));
1673 /* if we were in a global section then do the local inits */
1674 if (bInGlobalSection
&& !isglobal
)
1677 /* if we've just struck a global section, note the fact. */
1678 bInGlobalSection
= isglobal
;
1680 /* check for multiple global sections */
1681 if (bInGlobalSection
)
1683 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName
));
1687 if (!bInGlobalSection
&& bGlobalOnly
) return(True
);
1689 /* if we have a current service, tidy it up before moving on */
1692 if (iServiceIndex
>= 0)
1693 bRetval
= service_ok(iServiceIndex
);
1695 /* if all is still well, move to the next record in the services array */
1698 /* We put this here to avoid an odd message order if messages are */
1699 /* issued by the post-processing of a previous section. */
1700 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName
));
1702 if ((iServiceIndex
=add_a_service(&sDefault
,pszSectionName
)) < 0)
1704 DEBUG(0,("Failed to add a new service\n"));
1712 /***************************************************************************
1713 Display the contents of the global structure.
1714 ***************************************************************************/
1715 static void dump_globals(void)
1718 printf("Global parameters:\n");
1720 for (i
=0;parm_table
[i
].label
;i
++)
1721 if (parm_table
[i
].class == P_GLOBAL
&&
1722 parm_table
[i
].ptr
&&
1723 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
-1].ptr
)))
1725 printf("\t%s: ",parm_table
[i
].label
);
1726 print_parameter(parm_table
[i
].type
,parm_table
[i
].ptr
);
1731 /***************************************************************************
1732 Display the contents of a single services record.
1733 ***************************************************************************/
1734 static void dump_a_service(service
*pService
)
1737 if (pService
== &sDefault
)
1738 printf("\nDefault service parameters:\n");
1740 printf("\nService parameters [%s]:\n",pService
->szService
);
1742 for (i
=0;parm_table
[i
].label
;i
++)
1743 if (parm_table
[i
].class == P_LOCAL
&&
1744 parm_table
[i
].ptr
&&
1745 (*parm_table
[i
].label
!= '-') &&
1746 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
-1].ptr
)))
1748 int pdiff
= PTR_DIFF(parm_table
[i
].ptr
,&sDefault
);
1750 if (pService
== &sDefault
|| !equal_parameter(parm_table
[i
].type
,
1751 ((char *)pService
) + pdiff
,
1752 ((char *)&sDefault
) + pdiff
))
1754 printf("\t%s: ",parm_table
[i
].label
);
1755 print_parameter(parm_table
[i
].type
,
1756 ((char *)pService
) + pdiff
);
1763 /***************************************************************************
1764 Display the contents of a single copy structure.
1765 ***************************************************************************/
1766 static void dump_copy_map(BOOL
*pcopymap
)
1769 if (!pcopymap
) return;
1771 printf("\n\tNon-Copied parameters:\n");
1773 for (i
=0;parm_table
[i
].label
;i
++)
1774 if (parm_table
[i
].class == P_LOCAL
&&
1775 parm_table
[i
].ptr
&& !pcopymap
[i
] &&
1776 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
-1].ptr
)))
1778 printf("\t\t%s\n",parm_table
[i
].label
);
1783 /***************************************************************************
1784 Return TRUE if the passed service number is within range.
1785 ***************************************************************************/
1786 BOOL
lp_snum_ok(int iService
)
1788 return (LP_SNUM_OK(iService
) && iSERVICE(iService
).bAvailable
);
1792 /***************************************************************************
1793 auto-load some homes and printer services
1794 ***************************************************************************/
1795 static void lp_add_auto_services(char *str
)
1799 int homes
= lp_servicenumber(HOMES_NAME
);
1800 int printers
= lp_servicenumber(PRINTERS_NAME
);
1808 for (p
=strtok(s
,LIST_SEP
);p
;p
=strtok(NULL
,LIST_SEP
))
1810 char *home
= get_home_dir(p
);
1812 if (lp_servicenumber(p
) >= 0) continue;
1814 if (home
&& homes
>= 0)
1816 lp_add_home(p
,homes
,home
);
1820 if (printers
>= 0 && pcap_printername_ok(p
,NULL
))
1821 lp_add_printer(p
,printers
);
1826 /***************************************************************************
1827 auto-load one printer
1828 ***************************************************************************/
1829 static void lp_add_one_printer(char *name
,char *comment
)
1831 int printers
= lp_servicenumber(PRINTERS_NAME
);
1834 if (lp_servicenumber(name
) < 0)
1836 lp_add_printer(name
,printers
);
1837 if ((i
=lp_servicenumber(name
)) >= 0)
1838 string_set(&iSERVICE(i
).comment
,comment
);
1843 /***************************************************************************
1844 auto-load printer services
1845 ***************************************************************************/
1846 static void lp_add_all_printers(void)
1848 int printers
= lp_servicenumber(PRINTERS_NAME
);
1850 if (printers
< 0) return;
1852 pcap_printer_fn(lp_add_one_printer
);
1855 /***************************************************************************
1856 have we loaded a services file yet?
1857 ***************************************************************************/
1858 BOOL
lp_loaded(void)
1863 /***************************************************************************
1864 unload unused services
1865 ***************************************************************************/
1866 void lp_killunused(BOOL (*snumused
)(int ))
1869 for (i
=0;i
<iNumServices
;i
++)
1870 if (VALID(i
) && !snumused(i
))
1872 iSERVICE(i
).valid
= False
;
1873 free_service(pSERVICE(i
));
1877 /***************************************************************************
1878 Load the services array from the services file. Return True on success,
1880 ***************************************************************************/
1881 BOOL
lp_load(char *pszFname
,BOOL global_only
)
1886 add_to_file_list(pszFname
);
1890 bInGlobalSection
= True
;
1891 bGlobalOnly
= global_only
;
1895 strcpy(n2
,pszFname
);
1896 standard_sub_basic(n2
);
1898 /* We get sections first, so have to start 'behind' to make up */
1900 bRetval
= pm_process(n2
, do_section
, do_parameter
);
1902 /* finish up the last section */
1903 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval
)));
1905 if (iServiceIndex
>= 0)
1906 bRetval
= service_ok(iServiceIndex
);
1908 lp_add_auto_services(lp_auto_services());
1909 if (lp_load_printers())
1910 lp_add_all_printers();
1920 /***************************************************************************
1921 return the max number of services
1922 ***************************************************************************/
1923 int lp_numservices(void)
1925 return(iNumServices
);
1928 /***************************************************************************
1929 Display the contents of the services array in human-readable form.
1930 ***************************************************************************/
1937 dump_a_service(&sDefault
);
1939 for (iService
= 0; iService
< iNumServices
; iService
++)
1941 if (VALID(iService
))
1943 if (iSERVICE(iService
).szService
[0] == '\0')
1945 dump_a_service(pSERVICE(iService
));
1950 /***************************************************************************
1951 Return the number of the service with the given name, or -1 if it doesn't
1952 exist. Note that this is a DIFFERENT ANIMAL from the internal function
1953 getservicebyname()! This works ONLY if all services have been loaded, and
1954 does not copy the found service.
1955 ***************************************************************************/
1956 int lp_servicenumber(char *pszServiceName
)
1960 for (iService
= iNumServices
- 1; iService
>= 0; iService
--)
1961 if (VALID(iService
) &&
1962 strwicmp(iSERVICE(iService
).szService
, pszServiceName
) == 0)
1966 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName
));
1971 /*******************************************************************
1972 a useful volume label function
1973 ******************************************************************/
1974 char *volume_label(int snum
)
1976 char *ret
= lp_volume(snum
);
1977 if (!*ret
) return(lp_servicename(snum
));