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
58 extern int DEBUGLEVEL
;
60 extern pstring user_socket_options
;
61 extern pstring smbrun_path
;
64 #define GLOBAL_NAME "global"
69 #define PRINTCAP_NAME "/etc/qconfig"
71 #define PRINTCAP_NAME "/etc/printcap"
76 #define PRINTERS_NAME "printers"
80 #define HOMES_NAME "homes"
83 /* some helpful bits */
84 #define pSERVICE(i) ServicePtrs[i]
85 #define iSERVICE(i) (*pSERVICE(i))
86 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
87 #define VALID(i) iSERVICE(i).valid
89 /* these are the types of parameter we have */
92 P_BOOL
,P_BOOLREV
,P_CHAR
,P_INTEGER
,P_OCTAL
,P_STRING
,P_GSTRING
97 P_LOCAL
,P_GLOBAL
,P_NONE
101 extern BOOL use_getwd_cache
;
103 extern int extra_time_offset
;
105 extern int coding_system
;
109 * This structure describes global (ie., server-wide) parameters.
113 char *szPrintcapname
;
116 char *szDefaultService
;
120 char *szServerString
;
121 char *szAutoServices
;
122 char *szPasswdProgram
;
126 char *szSMBPasswdFile
;
127 char *szPasswordServer
;
128 char *szSocketOptions
;
131 char *szDomainController
;
133 char *szCharacterSet
;
150 BOOL bPreferredMaster
;
153 BOOL bEncryptPasswords
;
160 BOOL bReadPrediction
;
166 static global Globals
;
171 * This structure describes a single service.
179 char *szGuestaccount
;
180 char *szInvalidUsers
;
188 char *szRootPostExec
;
189 char *szPrintcommand
;
192 char *szLppausecommand
;
193 char *szLpresumecommand
;
215 BOOL bShortCasePreserve
;
239 char dummy
[3]; /* for alignment */
243 /* This is a default service used to prime a services structure */
244 static service sDefault
=
247 NULL
, /* szService */
249 NULL
, /* szUsername */
250 NULL
, /* szGuestAccount */
251 NULL
, /* szInvalidUsers */
252 NULL
, /* szValidUsers */
253 NULL
, /* szAdminUsers */
255 NULL
, /* szInclude */
256 NULL
, /* szPreExec */
257 NULL
, /* szPostExec */
258 NULL
, /* szRootPreExec */
259 NULL
, /* szRootPostExec */
260 NULL
, /* szPrintcommand */
261 NULL
, /* szLpqcommand */
262 NULL
, /* szLprmcommand */
263 NULL
, /* szLppausecommand */
264 NULL
, /* szLpresumecommand */
265 NULL
, /* szPrintername */
266 NULL
, /* szDontdescend */
267 NULL
, /* szHostsallow */
268 NULL
, /* szHostsdeny */
269 NULL
, /* szMagicScript */
270 NULL
, /* szMagicOutput */
271 NULL
, /* szMangledMap */
273 NULL
, /* force user */
274 NULL
, /* force group */
276 NULL
, /* writelist */
278 0, /* iMinPrintSpace */
279 0755, /* iCreate_mode */
280 0, /* iMaxConnections */
281 CASE_LOWER
, /* iDefaultCase */
282 False
, /* bAlternatePerm */
283 False
, /* revalidate */
284 False
, /* case sensitive */
285 False
, /* case preserve */
286 False
, /* short case preserve */
287 False
, /* case mangle */
289 True
, /* bHideDotFiles */
290 True
, /* bBrowseable */
291 True
, /* bAvailable */
292 True
, /* bRead_only */
293 True
, /* bNo_set_dir */
294 False
, /* bGuest_only */
295 False
, /* bGuest_ok */
296 False
, /* bPrint_ok */
297 False
, /* bPostscript */
298 False
, /* bMap_system */
299 False
, /* bMap_hidden */
300 True
, /* bMap_archive */
302 False
, /* bStrictLocking */
303 True
, /* bShareModes */
304 False
, /* bOnlyUser */
305 True
, /* bMangledNames */
306 True
, /* bWidelinks */
307 False
, /* bSyncAlways */
308 '~', /* magic char */
315 /* local variables */
316 static service
**ServicePtrs
= NULL
;
317 static int iNumServices
= 0;
318 static int iServiceIndex
= 0;
319 static BOOL bInGlobalSection
= True
;
320 static BOOL bGlobalOnly
= False
;
323 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
325 /* prototypes for the special type handlers */
326 static BOOL
handle_valid_chars(char *pszParmValue
, char **ptr
);
327 static BOOL
handle_include(char *pszParmValue
, char **ptr
);
328 static BOOL
handle_copy(char *pszParmValue
, char **ptr
);
329 static BOOL
handle_protocol(char *pszParmValue
,int *val
);
330 static BOOL
handle_security(char *pszParmValue
,int *val
);
331 static BOOL
handle_case(char *pszParmValue
,int *val
);
332 static BOOL
handle_printing(char *pszParmValue
,int *val
);
333 static BOOL
handle_character_set(char *pszParmValue
,int *val
);
335 static BOOL
handle_coding_system(char *pszParmValue
,int *val
);
347 {"debuglevel", P_INTEGER
, P_GLOBAL
, &DEBUGLEVEL
, NULL
},
348 {"log level", P_INTEGER
, P_GLOBAL
, &DEBUGLEVEL
, NULL
},
349 {"syslog", P_INTEGER
, P_GLOBAL
, &Globals
.syslog
, NULL
},
350 {"syslog only", P_BOOL
, P_GLOBAL
, &Globals
.bSyslogOnly
, NULL
},
351 {"protocol", P_INTEGER
, P_GLOBAL
, &Globals
.maxprotocol
,handle_protocol
},
352 {"security", P_INTEGER
, P_GLOBAL
, &Globals
.security
,handle_security
},
353 {"printing", P_INTEGER
, P_GLOBAL
, &Globals
.printing
,handle_printing
},
354 {"max disk size", P_INTEGER
, P_GLOBAL
, &Globals
.maxdisksize
, NULL
},
355 {"lpq cache time", P_INTEGER
, P_GLOBAL
, &Globals
.lpqcachetime
, NULL
},
356 {"encrypt passwords",P_BOOL
, P_GLOBAL
, &Globals
.bEncryptPasswords
, NULL
},
357 {"getwd cache", P_BOOL
, P_GLOBAL
, &use_getwd_cache
, NULL
},
358 {"read prediction", P_BOOL
, P_GLOBAL
, &Globals
.bReadPrediction
, NULL
},
359 {"read bmpx", P_BOOL
, P_GLOBAL
, &Globals
.bReadbmpx
, NULL
},
360 {"read raw", P_BOOL
, P_GLOBAL
, &Globals
.bReadRaw
, NULL
},
361 {"write raw", P_BOOL
, P_GLOBAL
, &Globals
.bWriteRaw
, NULL
},
362 {"use rhosts", P_BOOL
, P_GLOBAL
, &Globals
.bUseRhosts
, NULL
},
363 {"load printers", P_BOOL
, P_GLOBAL
, &Globals
.bLoadPrinters
, NULL
},
364 {"null passwords", P_BOOL
, P_GLOBAL
, &Globals
.bNullPasswords
, NULL
},
365 {"strip dot", P_BOOL
, P_GLOBAL
, &Globals
.bStripDot
, NULL
},
366 {"password server", P_STRING
, P_GLOBAL
, &Globals
.szPasswordServer
, NULL
},
367 {"socket options", P_GSTRING
, P_GLOBAL
, user_socket_options
, NULL
},
368 {"smbrun", P_GSTRING
, P_GLOBAL
, smbrun_path
, NULL
},
369 {"log file", P_STRING
, P_GLOBAL
, &Globals
.szLogFile
, NULL
},
370 {"config file", P_STRING
, P_GLOBAL
, &Globals
.szConfigFile
, NULL
},
371 {"smb passwd file", P_STRING
, P_GLOBAL
, &Globals
.szSMBPasswdFile
, NULL
},
372 {"hosts equiv", P_STRING
, P_GLOBAL
, &Globals
.szHostsEquiv
, NULL
},
373 {"preload", P_STRING
, P_GLOBAL
, &Globals
.szAutoServices
, NULL
},
374 {"auto services", P_STRING
, P_GLOBAL
, &Globals
.szAutoServices
, NULL
},
375 {"server string", P_STRING
, P_GLOBAL
, &Globals
.szServerString
, NULL
},
376 {"printcap name", P_STRING
, P_GLOBAL
, &Globals
.szPrintcapname
, NULL
},
377 {"printcap", P_STRING
, P_GLOBAL
, &Globals
.szPrintcapname
, NULL
},
378 {"lock dir", P_STRING
, P_GLOBAL
, &Globals
.szLockDir
, NULL
},
379 {"lock directory", P_STRING
, P_GLOBAL
, &Globals
.szLockDir
, NULL
},
380 {"root directory", P_STRING
, P_GLOBAL
, &Globals
.szRootdir
, NULL
},
381 {"root dir", P_STRING
, P_GLOBAL
, &Globals
.szRootdir
, NULL
},
382 {"root", P_STRING
, P_GLOBAL
, &Globals
.szRootdir
, NULL
},
383 {"default service", P_STRING
, P_GLOBAL
, &Globals
.szDefaultService
, NULL
},
384 {"default", P_STRING
, P_GLOBAL
, &Globals
.szDefaultService
, NULL
},
385 {"message command", P_STRING
, P_GLOBAL
, &Globals
.szMsgCommand
, NULL
},
386 {"dfree command", P_STRING
, P_GLOBAL
, &Globals
.szDfree
, NULL
},
387 {"passwd program", P_STRING
, P_GLOBAL
, &Globals
.szPasswdProgram
, NULL
},
388 {"passwd chat", P_STRING
, P_GLOBAL
, &Globals
.szPasswdChat
, NULL
},
389 {"valid chars", P_STRING
, P_GLOBAL
, &Globals
.szValidChars
, handle_valid_chars
},
390 {"workgroup", P_STRING
, P_GLOBAL
, &Globals
.szWorkGroup
, NULL
},
391 {"domain controller",P_STRING
, P_GLOBAL
, &Globals
.szDomainController
,NULL
},
392 {"username map", P_STRING
, P_GLOBAL
, &Globals
.szUsernameMap
, NULL
},
393 {"character set", P_STRING
, P_GLOBAL
, &Globals
.szCharacterSet
, handle_character_set
},
394 {"logon script", P_STRING
, P_GLOBAL
, &Globals
.szLogonScript
, NULL
},
395 {"max log size", P_INTEGER
, P_GLOBAL
, &Globals
.max_log_size
, NULL
},
396 {"mangled stack", P_INTEGER
, P_GLOBAL
, &Globals
.mangled_stack
, NULL
},
397 {"max mux", P_INTEGER
, P_GLOBAL
, &Globals
.max_mux
, NULL
},
398 {"max xmit", P_INTEGER
, P_GLOBAL
, &Globals
.max_xmit
, NULL
},
399 {"max packet", P_INTEGER
, P_GLOBAL
, &Globals
.max_packet
, NULL
},
400 {"packet size", P_INTEGER
, P_GLOBAL
, &Globals
.max_packet
, NULL
},
401 {"password level", P_INTEGER
, P_GLOBAL
, &Globals
.pwordlevel
, NULL
},
402 {"keepalive", P_INTEGER
, P_GLOBAL
, &keepalive
, NULL
},
403 {"deadtime", P_INTEGER
, P_GLOBAL
, &Globals
.deadtime
, NULL
},
404 {"time offset", P_INTEGER
, P_GLOBAL
, &extra_time_offset
, NULL
},
405 {"read size", P_INTEGER
, P_GLOBAL
, &ReadSize
, NULL
},
407 {"coding system", P_INTEGER
, P_GLOBAL
, &coding_system
, handle_coding_system
},
409 {"os level", P_INTEGER
, P_GLOBAL
, &Globals
.os_level
, NULL
},
410 {"max ttl", P_INTEGER
, P_GLOBAL
, &Globals
.max_ttl
, NULL
},
411 {"preferred master", P_BOOL
, P_GLOBAL
, &Globals
.bPreferredMaster
, NULL
},
412 {"prefered master", P_BOOL
, P_GLOBAL
, &Globals
.bPreferredMaster
, NULL
},
413 {"domain master", P_BOOL
, P_GLOBAL
, &Globals
.bDomainMaster
, NULL
},
414 {"domain logons", P_BOOL
, P_GLOBAL
, &Globals
.bDomainLogons
, NULL
},
415 {"browse list", P_BOOL
, P_GLOBAL
, &Globals
.bBrowseList
, NULL
},
417 {"-valid", P_BOOL
, P_LOCAL
, &sDefault
.valid
, NULL
},
418 {"comment", P_STRING
, P_LOCAL
, &sDefault
.comment
, NULL
},
419 {"copy", P_STRING
, P_LOCAL
, &sDefault
.szCopy
, handle_copy
},
420 {"include", P_STRING
, P_LOCAL
, &sDefault
.szInclude
, handle_include
},
421 {"exec", P_STRING
, P_LOCAL
, &sDefault
.szPreExec
, NULL
},
422 {"preexec", P_STRING
, P_LOCAL
, &sDefault
.szPreExec
, NULL
},
423 {"postexec", P_STRING
, P_LOCAL
, &sDefault
.szPostExec
, NULL
},
424 {"root preexec", P_STRING
, P_LOCAL
, &sDefault
.szRootPreExec
, NULL
},
425 {"root postexec", P_STRING
, P_LOCAL
, &sDefault
.szRootPostExec
, NULL
},
426 {"alternate permissions",P_BOOL
,P_LOCAL
, &sDefault
.bAlternatePerm
, NULL
},
427 {"revalidate", P_BOOL
, P_LOCAL
, &sDefault
.bRevalidate
, NULL
},
428 {"default case", P_INTEGER
, P_LOCAL
, &sDefault
.iDefaultCase
, handle_case
},
429 {"case sensitive", P_BOOL
, P_LOCAL
, &sDefault
.bCaseSensitive
, NULL
},
430 {"casesignames", P_BOOL
, P_LOCAL
, &sDefault
.bCaseSensitive
, NULL
},
431 {"preserve case", P_BOOL
, P_LOCAL
, &sDefault
.bCasePreserve
, NULL
},
432 {"short preserve case",P_BOOL
, P_LOCAL
, &sDefault
.bShortCasePreserve
,NULL
},
433 {"mangle case", P_BOOL
, P_LOCAL
, &sDefault
.bCaseMangle
, NULL
},
434 {"mangling char", P_CHAR
, P_LOCAL
, &sDefault
.magic_char
, NULL
},
435 {"browseable", P_BOOL
, P_LOCAL
, &sDefault
.bBrowseable
, NULL
},
436 {"browsable", P_BOOL
, P_LOCAL
, &sDefault
.bBrowseable
, NULL
},
437 {"available", P_BOOL
, P_LOCAL
, &sDefault
.bAvailable
, NULL
},
438 {"path", P_STRING
, P_LOCAL
, &sDefault
.szPath
, NULL
},
439 {"directory", P_STRING
, P_LOCAL
, &sDefault
.szPath
, NULL
},
440 {"username", P_STRING
, P_LOCAL
, &sDefault
.szUsername
, NULL
},
441 {"user", P_STRING
, P_LOCAL
, &sDefault
.szUsername
, NULL
},
442 {"users", P_STRING
, P_LOCAL
, &sDefault
.szUsername
, NULL
},
443 {"guest account", P_STRING
, P_LOCAL
, &sDefault
.szGuestaccount
, NULL
},
444 {"invalid users", P_STRING
, P_LOCAL
, &sDefault
.szInvalidUsers
, NULL
},
445 {"valid users", P_STRING
, P_LOCAL
, &sDefault
.szValidUsers
, NULL
},
446 {"admin users", P_STRING
, P_LOCAL
, &sDefault
.szAdminUsers
, NULL
},
447 {"read list", P_STRING
, P_LOCAL
, &sDefault
.readlist
, NULL
},
448 {"write list", P_STRING
, P_LOCAL
, &sDefault
.writelist
, NULL
},
449 {"volume", P_STRING
, P_LOCAL
, &sDefault
.volume
, NULL
},
450 {"force user", P_STRING
, P_LOCAL
, &sDefault
.force_user
, NULL
},
451 {"force group", P_STRING
, P_LOCAL
, &sDefault
.force_group
, NULL
},
452 {"group", P_STRING
, P_LOCAL
, &sDefault
.force_group
, NULL
},
453 {"read only", P_BOOL
, P_LOCAL
, &sDefault
.bRead_only
, NULL
},
454 {"write ok", P_BOOLREV
, P_LOCAL
, &sDefault
.bRead_only
, NULL
},
455 {"writeable", P_BOOLREV
, P_LOCAL
, &sDefault
.bRead_only
, NULL
},
456 {"writable", P_BOOLREV
, P_LOCAL
, &sDefault
.bRead_only
, NULL
},
457 {"max connections", P_INTEGER
, P_LOCAL
, &sDefault
.iMaxConnections
, NULL
},
458 {"min print space", P_INTEGER
, P_LOCAL
, &sDefault
.iMinPrintSpace
, NULL
},
459 {"create mask", P_OCTAL
, P_LOCAL
, &sDefault
.iCreate_mode
, NULL
},
460 {"create mode", P_OCTAL
, P_LOCAL
, &sDefault
.iCreate_mode
, NULL
},
461 {"set directory", P_BOOLREV
, P_LOCAL
, &sDefault
.bNo_set_dir
, NULL
},
462 {"status", P_BOOL
, P_LOCAL
, &sDefault
.status
, NULL
},
463 {"hide dot files", P_BOOL
, P_LOCAL
, &sDefault
.bHideDotFiles
, NULL
},
464 {"guest only", P_BOOL
, P_LOCAL
, &sDefault
.bGuest_only
, NULL
},
465 {"only guest", P_BOOL
, P_LOCAL
, &sDefault
.bGuest_only
, NULL
},
466 {"guest ok", P_BOOL
, P_LOCAL
, &sDefault
.bGuest_ok
, NULL
},
467 {"public", P_BOOL
, P_LOCAL
, &sDefault
.bGuest_ok
, NULL
},
468 {"print ok", P_BOOL
, P_LOCAL
, &sDefault
.bPrint_ok
, NULL
},
469 {"printable", P_BOOL
, P_LOCAL
, &sDefault
.bPrint_ok
, NULL
},
470 {"postscript", P_BOOL
, P_LOCAL
, &sDefault
.bPostscript
, NULL
},
471 {"map system", P_BOOL
, P_LOCAL
, &sDefault
.bMap_system
, NULL
},
472 {"map hidden", P_BOOL
, P_LOCAL
, &sDefault
.bMap_hidden
, NULL
},
473 {"map archive", P_BOOL
, P_LOCAL
, &sDefault
.bMap_archive
, NULL
},
474 {"locking", P_BOOL
, P_LOCAL
, &sDefault
.bLocking
, NULL
},
475 {"strict locking", P_BOOL
, P_LOCAL
, &sDefault
.bStrictLocking
, NULL
},
476 {"share modes", P_BOOL
, P_LOCAL
, &sDefault
.bShareModes
, NULL
},
477 {"only user", P_BOOL
, P_LOCAL
, &sDefault
.bOnlyUser
, NULL
},
478 {"wide links", P_BOOL
, P_LOCAL
, &sDefault
.bWidelinks
, NULL
},
479 {"sync always", P_BOOL
, P_LOCAL
, &sDefault
.bSyncAlways
, NULL
},
480 {"mangled names", P_BOOL
, P_LOCAL
, &sDefault
.bMangledNames
, NULL
},
481 {"print command", P_STRING
, P_LOCAL
, &sDefault
.szPrintcommand
, NULL
},
482 {"lpq command", P_STRING
, P_LOCAL
, &sDefault
.szLpqcommand
, NULL
},
483 {"lprm command", P_STRING
, P_LOCAL
, &sDefault
.szLprmcommand
, NULL
},
484 {"lppause command", P_STRING
, P_LOCAL
, &sDefault
.szLppausecommand
, NULL
},
485 {"lpresume command", P_STRING
, P_LOCAL
, &sDefault
.szLpresumecommand
,NULL
},
486 {"printer", P_STRING
, P_LOCAL
, &sDefault
.szPrintername
, NULL
},
487 {"printer name", P_STRING
, P_LOCAL
, &sDefault
.szPrintername
, NULL
},
488 {"hosts allow", P_STRING
, P_LOCAL
, &sDefault
.szHostsallow
, NULL
},
489 {"allow hosts", P_STRING
, P_LOCAL
, &sDefault
.szHostsallow
, NULL
},
490 {"hosts deny", P_STRING
, P_LOCAL
, &sDefault
.szHostsdeny
, NULL
},
491 {"deny hosts", P_STRING
, P_LOCAL
, &sDefault
.szHostsdeny
, NULL
},
492 {"dont descend", P_STRING
, P_LOCAL
, &sDefault
.szDontdescend
, NULL
},
493 {"magic script", P_STRING
, P_LOCAL
, &sDefault
.szMagicScript
, NULL
},
494 {"magic output", P_STRING
, P_LOCAL
, &sDefault
.szMagicOutput
, NULL
},
495 {"mangled map", P_STRING
, P_LOCAL
, &sDefault
.szMangledMap
, NULL
},
497 {NULL
, P_BOOL
, P_NONE
, NULL
, NULL
}
502 /***************************************************************************
503 Initialise the global parameter structure.
504 ***************************************************************************/
505 static void init_globals(void)
507 static BOOL done_init
= False
;
513 bzero((void *)&Globals
,sizeof(Globals
));
515 for (i
= 0; parm_table
[i
].label
; i
++)
516 if (parm_table
[i
].type
== P_STRING
&&
518 string_init(parm_table
[i
].ptr
,"");
520 string_set(&sDefault
.szGuestaccount
, GUEST_ACCOUNT
);
526 DEBUG(3,("Initialising global parameters\n"));
528 #ifdef SMB_PASSWD_FILE
529 string_set(&Globals
.szSMBPasswdFile
, SMB_PASSWD_FILE
);
531 string_set(&Globals
.szPasswdChat
,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
532 string_set(&Globals
.szWorkGroup
, WORKGROUP
);
534 string_set(&Globals
.szPasswdProgram
, SMB_PASSWD
);
536 string_set(&Globals
.szPasswdProgram
, "/bin/passwd");
538 string_set(&Globals
.szPrintcapname
, PRINTCAP_NAME
);
539 string_set(&Globals
.szLockDir
, LOCKDIR
);
540 string_set(&Globals
.szRootdir
, "/");
541 sprintf(s
,"Samba %s",VERSION
);
542 string_set(&Globals
.szServerString
,s
);
543 Globals
.bLoadPrinters
= True
;
544 Globals
.bUseRhosts
= False
;
545 Globals
.max_packet
= 65535;
546 Globals
.mangled_stack
= 50;
547 Globals
.max_xmit
= Globals
.max_packet
;
549 Globals
.lpqcachetime
= 10;
550 Globals
.pwordlevel
= 0;
551 Globals
.deadtime
= 0;
552 Globals
.max_log_size
= 5000;
553 Globals
.maxprotocol
= PROTOCOL_NT1
;
554 Globals
.security
= SEC_SHARE
;
555 Globals
.bEncryptPasswords
= False
;
556 Globals
.printing
= DEFAULT_PRINTING
;
557 Globals
.bReadRaw
= True
;
558 Globals
.bWriteRaw
= True
;
559 Globals
.bReadPrediction
= False
;
560 Globals
.bReadbmpx
= True
;
561 Globals
.bNullPasswords
= False
;
562 Globals
.bStripDot
= False
;
564 Globals
.bSyslogOnly
= False
;
565 Globals
.os_level
= 0;
566 Globals
.max_ttl
= 60*60*4; /* 2 hours default */
567 Globals
.bPreferredMaster
= True
;
568 Globals
.bDomainMaster
= False
;
569 Globals
.bDomainLogons
= False
;
570 Globals
.bBrowseList
= True
;
573 coding_system
= interpret_coding_system (KANJI
, SJIS_CODE
);
578 /***************************************************************************
579 check if a string is initialised and if not then initialise it
580 ***************************************************************************/
581 static void string_initial(char **s
,char *v
)
588 /***************************************************************************
589 Initialise the sDefault parameter structure.
590 ***************************************************************************/
591 static void init_locals(void)
593 /* choose defaults depending on the type of printing */
594 switch (Globals
.printing
)
598 string_initial(&sDefault
.szLpqcommand
,"lpq -P%p");
599 string_initial(&sDefault
.szLprmcommand
,"lprm -P%p %j");
600 string_initial(&sDefault
.szPrintcommand
,"lpr -r -P%p %s");
605 string_initial(&sDefault
.szLpqcommand
,"lpstat -o%p");
606 string_initial(&sDefault
.szLprmcommand
,"cancel %p-%j");
607 string_initial(&sDefault
.szPrintcommand
,"lp -c -d%p %s; rm %s");
609 string_initial(&sDefault
.szLppausecommand
,"lp -i %p-%j -H hold");
610 string_initial(&sDefault
.szLpresumecommand
,"lp -i %p-%j -H resume");
615 string_initial(&sDefault
.szLpqcommand
,"lpq -P%p");
616 string_initial(&sDefault
.szLprmcommand
,"lprm -P%p %j");
617 string_initial(&sDefault
.szPrintcommand
,"lp -r -P%p %s");
625 /*******************************************************************
626 a convenience rooutine to grab string parameters into a rotating
627 static buffer, and run standard_sub_basic on them. The buffers
628 can be written to by callers
629 ********************************************************************/
630 char *lp_string(char *s
)
632 static pstring bufs
[10];
636 ret
= &bufs
[next
][0];
642 StrnCpy(ret
,s
,sizeof(pstring
)-1);
644 standard_sub_basic(ret
);
650 In this section all the functions that are used to access the
651 parameters from the rest of the program are defined
654 #define FN_GLOBAL_STRING(fn_name,ptr) \
655 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
656 #define FN_GLOBAL_BOOL(fn_name,ptr) \
657 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
658 #define FN_GLOBAL_CHAR(fn_name,ptr) \
659 char fn_name(void) {return(*(char *)(ptr));}
660 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
661 int fn_name(void) {return(*(int *)(ptr));}
663 #define FN_LOCAL_STRING(fn_name,val) \
664 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
665 #define FN_LOCAL_BOOL(fn_name,val) \
666 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
667 #define FN_LOCAL_CHAR(fn_name,val) \
668 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
669 #define FN_LOCAL_INTEGER(fn_name,val) \
670 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
672 FN_GLOBAL_STRING(lp_logfile
,&Globals
.szLogFile
)
673 FN_GLOBAL_STRING(lp_configfile
,&Globals
.szConfigFile
)
674 FN_GLOBAL_STRING(lp_smb_passwd_file
,&Globals
.szSMBPasswdFile
)
675 FN_GLOBAL_STRING(lp_serverstring
,&Globals
.szServerString
)
676 FN_GLOBAL_STRING(lp_printcapname
,&Globals
.szPrintcapname
)
677 FN_GLOBAL_STRING(lp_lockdir
,&Globals
.szLockDir
)
678 FN_GLOBAL_STRING(lp_rootdir
,&Globals
.szRootdir
)
679 FN_GLOBAL_STRING(lp_defaultservice
,&Globals
.szDefaultService
)
680 FN_GLOBAL_STRING(lp_msg_command
,&Globals
.szMsgCommand
)
681 FN_GLOBAL_STRING(lp_dfree_command
,&Globals
.szDfree
)
682 FN_GLOBAL_STRING(lp_hosts_equiv
,&Globals
.szHostsEquiv
)
683 FN_GLOBAL_STRING(lp_auto_services
,&Globals
.szAutoServices
)
684 FN_GLOBAL_STRING(lp_passwd_program
,&Globals
.szPasswdProgram
)
685 FN_GLOBAL_STRING(lp_passwd_chat
,&Globals
.szPasswdChat
)
686 FN_GLOBAL_STRING(lp_passwordserver
,&Globals
.szPasswordServer
)
687 FN_GLOBAL_STRING(lp_workgroup
,&Globals
.szWorkGroup
)
688 FN_GLOBAL_STRING(lp_domain_controller
,&Globals
.szDomainController
)
689 FN_GLOBAL_STRING(lp_username_map
,&Globals
.szUsernameMap
)
690 FN_GLOBAL_STRING(lp_character_set
,&Globals
.szCharacterSet
)
691 FN_GLOBAL_STRING(lp_logon_script
,&Globals
.szLogonScript
)
693 FN_GLOBAL_BOOL(lp_domain_master
,&Globals
.bDomainMaster
)
694 FN_GLOBAL_BOOL(lp_domain_logons
,&Globals
.bDomainLogons
)
695 FN_GLOBAL_BOOL(lp_preferred_master
,&Globals
.bPreferredMaster
)
696 FN_GLOBAL_BOOL(lp_load_printers
,&Globals
.bLoadPrinters
)
697 FN_GLOBAL_BOOL(lp_use_rhosts
,&Globals
.bUseRhosts
)
698 FN_GLOBAL_BOOL(lp_getwdcache
,&use_getwd_cache
)
699 FN_GLOBAL_BOOL(lp_readprediction
,&Globals
.bReadPrediction
)
700 FN_GLOBAL_BOOL(lp_readbmpx
,&Globals
.bReadbmpx
)
701 FN_GLOBAL_BOOL(lp_readraw
,&Globals
.bReadRaw
)
702 FN_GLOBAL_BOOL(lp_writeraw
,&Globals
.bWriteRaw
)
703 FN_GLOBAL_BOOL(lp_null_passwords
,&Globals
.bNullPasswords
)
704 FN_GLOBAL_BOOL(lp_strip_dot
,&Globals
.bStripDot
)
705 FN_GLOBAL_BOOL(lp_encrypted_passwords
,&Globals
.bEncryptPasswords
)
706 FN_GLOBAL_BOOL(lp_syslog_only
,&Globals
.bSyslogOnly
)
707 FN_GLOBAL_BOOL(lp_browse_list
,&Globals
.bBrowseList
)
709 FN_GLOBAL_INTEGER(lp_os_level
,&Globals
.os_level
)
710 FN_GLOBAL_INTEGER(lp_max_ttl
,&Globals
.max_ttl
)
711 FN_GLOBAL_INTEGER(lp_max_log_size
,&Globals
.max_log_size
)
712 FN_GLOBAL_INTEGER(lp_mangledstack
,&Globals
.mangled_stack
)
713 FN_GLOBAL_INTEGER(lp_maxxmit
,&Globals
.max_xmit
)
714 FN_GLOBAL_INTEGER(lp_maxmux
,&Globals
.max_mux
)
715 FN_GLOBAL_INTEGER(lp_maxpacket
,&Globals
.max_packet
)
716 FN_GLOBAL_INTEGER(lp_keepalive
,&keepalive
)
717 FN_GLOBAL_INTEGER(lp_passwordlevel
,&Globals
.pwordlevel
)
718 FN_GLOBAL_INTEGER(lp_deadtime
,&Globals
.deadtime
)
719 FN_GLOBAL_INTEGER(lp_maxprotocol
,&Globals
.maxprotocol
)
720 FN_GLOBAL_INTEGER(lp_security
,&Globals
.security
)
721 FN_GLOBAL_INTEGER(lp_printing
,&Globals
.printing
)
722 FN_GLOBAL_INTEGER(lp_maxdisksize
,&Globals
.maxdisksize
)
723 FN_GLOBAL_INTEGER(lp_lpqcachetime
,&Globals
.lpqcachetime
)
724 FN_GLOBAL_INTEGER(lp_syslog
,&Globals
.syslog
)
726 FN_LOCAL_STRING(lp_preexec
,szPreExec
)
727 FN_LOCAL_STRING(lp_postexec
,szPostExec
)
728 FN_LOCAL_STRING(lp_rootpreexec
,szRootPreExec
)
729 FN_LOCAL_STRING(lp_rootpostexec
,szRootPostExec
)
730 FN_LOCAL_STRING(lp_servicename
,szService
)
731 FN_LOCAL_STRING(lp_pathname
,szPath
)
732 FN_LOCAL_STRING(lp_dontdescend
,szDontdescend
)
733 FN_LOCAL_STRING(lp_username
,szUsername
)
734 FN_LOCAL_STRING(lp_guestaccount
,szGuestaccount
)
735 FN_LOCAL_STRING(lp_invalid_users
,szInvalidUsers
)
736 FN_LOCAL_STRING(lp_valid_users
,szValidUsers
)
737 FN_LOCAL_STRING(lp_admin_users
,szAdminUsers
)
738 FN_LOCAL_STRING(lp_printcommand
,szPrintcommand
)
739 FN_LOCAL_STRING(lp_lpqcommand
,szLpqcommand
)
740 FN_LOCAL_STRING(lp_lprmcommand
,szLprmcommand
)
741 FN_LOCAL_STRING(lp_lppausecommand
,szLppausecommand
)
742 FN_LOCAL_STRING(lp_lpresumecommand
,szLpresumecommand
)
743 FN_LOCAL_STRING(lp_printername
,szPrintername
)
744 FN_LOCAL_STRING(lp_hostsallow
,szHostsallow
)
745 FN_LOCAL_STRING(lp_hostsdeny
,szHostsdeny
)
746 FN_LOCAL_STRING(lp_magicscript
,szMagicScript
)
747 FN_LOCAL_STRING(lp_magicoutput
,szMagicOutput
)
748 FN_LOCAL_STRING(lp_comment
,comment
)
749 FN_LOCAL_STRING(lp_force_user
,force_user
)
750 FN_LOCAL_STRING(lp_force_group
,force_group
)
751 FN_LOCAL_STRING(lp_readlist
,readlist
)
752 FN_LOCAL_STRING(lp_writelist
,writelist
)
753 FN_LOCAL_STRING(lp_volume
,volume
)
754 FN_LOCAL_STRING(lp_mangled_map
,szMangledMap
)
756 FN_LOCAL_BOOL(lp_alternate_permissions
,bAlternatePerm
)
757 FN_LOCAL_BOOL(lp_revalidate
,bRevalidate
)
758 FN_LOCAL_BOOL(lp_casesensitive
,bCaseSensitive
)
759 FN_LOCAL_BOOL(lp_preservecase
,bCasePreserve
)
760 FN_LOCAL_BOOL(lp_shortpreservecase
,bShortCasePreserve
)
761 FN_LOCAL_BOOL(lp_casemangle
,bCaseMangle
)
762 FN_LOCAL_BOOL(lp_status
,status
)
763 FN_LOCAL_BOOL(lp_hide_dot_files
,bHideDotFiles
)
764 FN_LOCAL_BOOL(lp_browseable
,bBrowseable
)
765 FN_LOCAL_BOOL(lp_readonly
,bRead_only
)
766 FN_LOCAL_BOOL(lp_no_set_dir
,bNo_set_dir
)
767 FN_LOCAL_BOOL(lp_guest_ok
,bGuest_ok
)
768 FN_LOCAL_BOOL(lp_guest_only
,bGuest_only
)
769 FN_LOCAL_BOOL(lp_print_ok
,bPrint_ok
)
770 FN_LOCAL_BOOL(lp_postscript
,bPostscript
)
771 FN_LOCAL_BOOL(lp_map_hidden
,bMap_hidden
)
772 FN_LOCAL_BOOL(lp_map_archive
,bMap_archive
)
773 FN_LOCAL_BOOL(lp_locking
,bLocking
)
774 FN_LOCAL_BOOL(lp_strict_locking
,bStrictLocking
)
775 FN_LOCAL_BOOL(lp_share_modes
,bShareModes
)
776 FN_LOCAL_BOOL(lp_onlyuser
,bOnlyUser
)
777 FN_LOCAL_BOOL(lp_manglednames
,bMangledNames
)
778 FN_LOCAL_BOOL(lp_widelinks
,bWidelinks
)
779 FN_LOCAL_BOOL(lp_syncalways
,bSyncAlways
)
780 FN_LOCAL_BOOL(lp_map_system
,bMap_system
)
782 FN_LOCAL_INTEGER(lp_create_mode
,iCreate_mode
)
783 FN_LOCAL_INTEGER(lp_max_connections
,iMaxConnections
)
784 FN_LOCAL_INTEGER(lp_defaultcase
,iDefaultCase
)
785 FN_LOCAL_INTEGER(lp_minprintspace
,iMinPrintSpace
)
787 FN_LOCAL_CHAR(lp_magicchar
,magic_char
)
791 /* local prototypes */
792 static int strwicmp( char *psz1
, char *psz2
);
793 static int map_parameter( char *pszParmName
);
794 static BOOL
set_boolean( BOOL
*pb
, char *pszParmValue
);
795 static int getservicebyname(char *pszServiceName
, service
*pserviceDest
);
796 static void copy_service( service
*pserviceDest
,
797 service
*pserviceSource
,
798 BOOL
*pcopymapDest
);
799 static BOOL
service_ok(int iService
);
800 static BOOL
do_parameter(char *pszParmName
, char *pszParmValue
);
801 static BOOL
do_section(char *pszSectionName
);
802 static void dump_globals(void);
803 static void dump_a_service(service
*pService
);
804 static void init_copymap(service
*pservice
);
807 /***************************************************************************
808 initialise a service to the defaults
809 ***************************************************************************/
810 static void init_service(service
*pservice
)
812 bzero((char *)pservice
,sizeof(service
));
813 copy_service(pservice
,&sDefault
,NULL
);
817 /***************************************************************************
818 free the dynamically allocated parts of a service struct
819 ***************************************************************************/
820 static void free_service(service
*pservice
)
826 for (i
=0;parm_table
[i
].label
;i
++)
827 if (parm_table
[i
].type
== P_STRING
&& parm_table
[i
].class == P_LOCAL
)
828 string_free((char **)(((char *)pservice
) + PTR_DIFF(parm_table
[i
].ptr
,&sDefault
)));
831 /***************************************************************************
832 add a new service to the services array initialising it with the given
834 ***************************************************************************/
835 static int add_a_service(service
*pservice
, char *name
)
839 int num_to_alloc
= iNumServices
+1;
841 tservice
= *pservice
;
843 /* it might already exist */
846 i
= getservicebyname(name
,NULL
);
851 /* find an invalid one */
852 for (i
=0;i
<iNumServices
;i
++)
853 if (!pSERVICE(i
)->valid
)
856 /* if not, then create one */
857 if (i
== iNumServices
)
859 ServicePtrs
= (service
**)Realloc(ServicePtrs
,sizeof(service
*)*num_to_alloc
);
861 pSERVICE(iNumServices
) = (service
*)malloc(sizeof(service
));
863 if (!ServicePtrs
|| !pSERVICE(iNumServices
))
869 free_service(pSERVICE(i
));
871 pSERVICE(i
)->valid
= True
;
873 init_service(pSERVICE(i
));
874 copy_service(pSERVICE(i
),&tservice
,NULL
);
876 string_set(&iSERVICE(i
).szService
,name
);
881 /***************************************************************************
882 add a new home service, with the specified home directory, defaults coming
884 ***************************************************************************/
885 BOOL
lp_add_home(char *pszHomename
, int iDefaultService
, char *pszHomedir
)
887 int i
= add_a_service(pSERVICE(iDefaultService
),pszHomename
);
892 if (!(*(iSERVICE(i
).szPath
)) || strequal(iSERVICE(i
).szPath
,lp_pathname(-1)))
893 string_set(&iSERVICE(i
).szPath
,pszHomedir
);
894 if (!(*(iSERVICE(i
).comment
)))
897 sprintf(comment
,"Home directory of %s",pszHomename
);
898 string_set(&iSERVICE(i
).comment
,comment
);
900 iSERVICE(i
).bAvailable
= sDefault
.bAvailable
;
901 iSERVICE(i
).bBrowseable
= sDefault
.bBrowseable
;
903 DEBUG(3,("adding home directory %s at %s\n", pszHomename
, pszHomedir
));
908 /***************************************************************************
909 add a new service, based on an old one
910 ***************************************************************************/
911 int lp_add_service(char *pszService
, int iDefaultService
)
913 return(add_a_service(pSERVICE(iDefaultService
),pszService
));
917 /***************************************************************************
919 ***************************************************************************/
920 static BOOL
lp_add_ipc(void)
923 int i
= add_a_service(&sDefault
,"IPC$");
928 sprintf(comment
,"IPC Service (%s)",lp_serverstring());
930 string_set(&iSERVICE(i
).szPath
,"/tmp");
931 string_set(&iSERVICE(i
).szUsername
,"");
932 string_set(&iSERVICE(i
).comment
,comment
);
933 iSERVICE(i
).status
= False
;
934 iSERVICE(i
).iMaxConnections
= 0;
935 iSERVICE(i
).bAvailable
= True
;
936 iSERVICE(i
).bRead_only
= True
;
937 iSERVICE(i
).bGuest_only
= False
;
938 iSERVICE(i
).bGuest_ok
= True
;
939 iSERVICE(i
).bPrint_ok
= False
;
940 iSERVICE(i
).bBrowseable
= sDefault
.bBrowseable
;
942 DEBUG(3,("adding IPC service\n"));
948 /***************************************************************************
949 add a new printer service, with defaults coming from service iFrom
950 ***************************************************************************/
951 BOOL
lp_add_printer(char *pszPrintername
, int iDefaultService
)
953 char *comment
= "From Printcap";
954 int i
= add_a_service(pSERVICE(iDefaultService
),pszPrintername
);
959 /* note that we do NOT default the availability flag to True - */
960 /* we take it from the default service passed. This allows all */
961 /* dynamic printers to be disabled by disabling the [printers] */
962 /* entry (if/when the 'available' keyword is implemented!). */
964 /* the printer name is set to the service name. */
965 string_set(&iSERVICE(i
).szPrintername
,pszPrintername
);
966 string_set(&iSERVICE(i
).comment
,comment
);
967 iSERVICE(i
).bBrowseable
= sDefault
.bBrowseable
;
969 DEBUG(3,("adding printer service %s\n",pszPrintername
));
975 /***************************************************************************
976 Do a case-insensitive, whitespace-ignoring string compare.
977 ***************************************************************************/
978 static int strwicmp(char *psz1
, char *psz2
)
980 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
981 /* appropriate value. */
991 /* sync the strings on first non-whitespace */
994 while (isspace(*psz1
))
996 while (isspace(*psz2
))
998 if (toupper(*psz1
) != toupper(*psz2
) || *psz1
== '\0' || *psz2
== '\0')
1003 return (*psz1
- *psz2
);
1006 /***************************************************************************
1007 Map a parameter's string representation to something we can use.
1008 Returns False if the parameter string is not recognised, else TRUE.
1009 ***************************************************************************/
1010 static int map_parameter(char *pszParmName
)
1014 if (*pszParmName
== '-')
1017 for (iIndex
= 0; parm_table
[iIndex
].label
; iIndex
++)
1018 if (strwicmp(parm_table
[iIndex
].label
, pszParmName
) == 0)
1021 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName
));
1026 /***************************************************************************
1027 Set a boolean variable from the text value stored in the passed string.
1028 Returns True in success, False if the passed string does not correctly
1029 represent a boolean.
1030 ***************************************************************************/
1031 static BOOL
set_boolean(BOOL
*pb
, char *pszParmValue
)
1036 if (strwicmp(pszParmValue
, "yes") == 0 ||
1037 strwicmp(pszParmValue
, "true") == 0 ||
1038 strwicmp(pszParmValue
, "1") == 0)
1041 if (strwicmp(pszParmValue
, "no") == 0 ||
1042 strwicmp(pszParmValue
, "False") == 0 ||
1043 strwicmp(pszParmValue
, "0") == 0)
1047 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1054 /***************************************************************************
1055 Find a service by name. Otherwise works like get_service.
1056 ***************************************************************************/
1057 static int getservicebyname(char *pszServiceName
, service
*pserviceDest
)
1061 for (iService
= iNumServices
- 1; iService
>= 0; iService
--)
1062 if (VALID(iService
) &&
1063 strwicmp(iSERVICE(iService
).szService
, pszServiceName
) == 0)
1065 if (pserviceDest
!= NULL
)
1066 copy_service(pserviceDest
, pSERVICE(iService
), NULL
);
1075 /***************************************************************************
1076 Copy a service structure to another
1078 If pcopymapDest is NULL then copy all fields
1079 ***************************************************************************/
1080 static void copy_service(service
*pserviceDest
,
1081 service
*pserviceSource
,
1085 BOOL bcopyall
= (pcopymapDest
== NULL
);
1087 for (i
=0;parm_table
[i
].label
;i
++)
1088 if (parm_table
[i
].ptr
&& parm_table
[i
].class == P_LOCAL
&&
1089 (bcopyall
|| pcopymapDest
[i
]))
1091 void *def_ptr
= parm_table
[i
].ptr
;
1093 ((char *)pserviceSource
) + PTR_DIFF(def_ptr
,&sDefault
);
1095 ((char *)pserviceDest
) + PTR_DIFF(def_ptr
,&sDefault
);
1097 switch (parm_table
[i
].type
)
1101 *(BOOL
*)dest_ptr
= *(BOOL
*)src_ptr
;
1106 *(int *)dest_ptr
= *(int *)src_ptr
;
1110 *(char *)dest_ptr
= *(char *)src_ptr
;
1114 string_set(dest_ptr
,*(char **)src_ptr
);
1123 init_copymap(pserviceDest
);
1124 if (pserviceSource
->copymap
)
1125 memcpy((void *)pserviceDest
->copymap
,
1126 (void *)pserviceSource
->copymap
,sizeof(BOOL
)*NUMPARAMETERS
);
1130 /***************************************************************************
1131 Check a service for consistency. Return False if the service is in any way
1132 incomplete or faulty, else True.
1133 ***************************************************************************/
1134 static BOOL
service_ok(int iService
)
1139 if (iSERVICE(iService
).szService
[0] == '\0')
1141 DEBUG(0,( "The following message indicates an internal error:\n"));
1142 DEBUG(0,( "No service name in service entry.\n"));
1146 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1147 /* I can't see why you'd want a non-printable printer service... */
1148 if (strwicmp(iSERVICE(iService
).szService
,PRINTERS_NAME
) == 0)
1149 if (!iSERVICE(iService
).bPrint_ok
)
1151 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1152 iSERVICE(iService
).szService
));
1153 iSERVICE(iService
).bPrint_ok
= True
;
1156 if (iSERVICE(iService
).szPath
[0] == '\0' &&
1157 strwicmp(iSERVICE(iService
).szService
,HOMES_NAME
) != 0)
1159 DEBUG(0,("No path in service %s - using /tmp\n",iSERVICE(iService
).szService
));
1160 string_set(&iSERVICE(iService
).szPath
,"/tmp");
1163 /* If a service is flagged unavailable, log the fact at level 0. */
1164 if (!iSERVICE(iService
).bAvailable
)
1165 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1166 iSERVICE(iService
).szService
));
1171 static struct file_lists
{
1172 struct file_lists
*next
;
1175 } *file_lists
= NULL
;
1177 /*******************************************************************
1178 keep a linked list of all config files so we know when one has changed
1179 it's date and needs to be reloaded
1180 ********************************************************************/
1181 static void add_to_file_list(char *fname
)
1183 struct file_lists
*f
=file_lists
;
1186 if (f
->name
&& !strcmp(f
->name
,fname
)) break;
1191 f
= (struct file_lists
*)malloc(sizeof(file_lists
[0]));
1193 f
->next
= file_lists
;
1194 f
->name
= strdup(fname
);
1205 standard_sub_basic(n2
);
1206 f
->modtime
= file_modtime(n2
);
1211 /*******************************************************************
1212 check if a config file has changed date
1213 ********************************************************************/
1214 BOOL
lp_file_list_changed(void)
1216 struct file_lists
*f
= file_lists
;
1220 standard_sub_basic(n2
);
1221 if (f
->modtime
!= file_modtime(n2
)) return(True
);
1228 /***************************************************************************
1229 handle the interpretation of the coding system parameter
1230 *************************************************************************/
1231 static BOOL
handle_coding_system(char *pszParmValue
,int *val
)
1233 *val
= interpret_coding_system(pszParmValue
,*val
);
1238 /***************************************************************************
1239 handle the interpretation of the character set system parameter
1240 ***************************************************************************/
1241 static BOOL
handle_character_set(char *pszParmValue
,int *val
)
1243 string_set(&Globals
.szCharacterSet
,pszParmValue
);
1244 *val
= interpret_character_set(pszParmValue
,*val
);
1249 /***************************************************************************
1250 handle the interpretation of the protocol parameter
1251 ***************************************************************************/
1252 static BOOL
handle_protocol(char *pszParmValue
,int *val
)
1254 *val
= interpret_protocol(pszParmValue
,*val
);
1258 /***************************************************************************
1259 handle the interpretation of the security parameter
1260 ***************************************************************************/
1261 static BOOL
handle_security(char *pszParmValue
,int *val
)
1263 *val
= interpret_security(pszParmValue
,*val
);
1267 /***************************************************************************
1268 handle the interpretation of the default case
1269 ***************************************************************************/
1270 static BOOL
handle_case(char *pszParmValue
,int *val
)
1272 if (strequal(pszParmValue
,"LOWER"))
1274 else if (strequal(pszParmValue
,"UPPER"))
1279 /***************************************************************************
1280 handle the interpretation of the printing system
1281 ***************************************************************************/
1282 static BOOL
handle_printing(char *pszParmValue
,int *val
)
1284 if (strequal(pszParmValue
,"sysv"))
1286 else if (strequal(pszParmValue
,"aix"))
1288 else if (strequal(pszParmValue
,"hpux"))
1290 else if (strequal(pszParmValue
,"bsd"))
1292 else if (strequal(pszParmValue
,"qnx"))
1297 /***************************************************************************
1298 handle the valid chars lines
1299 ***************************************************************************/
1300 static BOOL
handle_valid_chars(char *pszParmValue
,char **ptr
)
1302 string_set(ptr
,pszParmValue
);
1304 add_char_string(pszParmValue
);
1309 /***************************************************************************
1310 handle the include operation
1311 ***************************************************************************/
1312 static BOOL
handle_include(char *pszParmValue
,char **ptr
)
1315 strcpy(fname
,pszParmValue
);
1317 add_to_file_list(fname
);
1319 standard_sub_basic(fname
);
1321 string_set(ptr
,fname
);
1323 if (file_exist(fname
,NULL
))
1324 return(pm_process(fname
, do_section
, do_parameter
));
1326 DEBUG(2,("Can't find include file %s\n",fname
));
1332 /***************************************************************************
1333 handle the interpretation of the copy parameter
1334 ***************************************************************************/
1335 static BOOL
handle_copy(char *pszParmValue
,char **ptr
)
1339 service serviceTemp
;
1341 string_set(ptr
,pszParmValue
);
1343 init_service(&serviceTemp
);
1347 DEBUG(3,("Copying service from service %s\n",pszParmValue
));
1349 if ((iTemp
= getservicebyname(pszParmValue
, &serviceTemp
)) >= 0)
1351 if (iTemp
== iServiceIndex
)
1353 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1358 copy_service(pSERVICE(iServiceIndex
),
1360 iSERVICE(iServiceIndex
).copymap
);
1366 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1371 free_service(&serviceTemp
);
1376 /***************************************************************************
1377 initialise a copymap
1378 ***************************************************************************/
1379 static void init_copymap(service
*pservice
)
1382 if (pservice
->copymap
) free(pservice
->copymap
);
1383 pservice
->copymap
= (BOOL
*)malloc(sizeof(BOOL
)*NUMPARAMETERS
);
1384 if (!pservice
->copymap
)
1385 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS
));
1387 for (i
=0;i
<NUMPARAMETERS
;i
++)
1388 pservice
->copymap
[i
] = True
;
1392 /***************************************************************************
1393 Process a parameter.
1394 ***************************************************************************/
1395 static BOOL
do_parameter(char *pszParmName
, char *pszParmValue
)
1398 void *parm_ptr
=NULL
; /* where we are going to store the result */
1401 if (!bInGlobalSection
&& bGlobalOnly
) return(True
);
1403 DEBUG(3,("doing parameter %s = %s\n",pszParmName
,pszParmValue
));
1405 parmnum
= map_parameter(pszParmName
);
1409 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName
));
1413 def_ptr
= parm_table
[parmnum
].ptr
;
1415 /* we might point at a service, the default service or a global */
1416 if (bInGlobalSection
)
1420 if (parm_table
[parmnum
].class == P_GLOBAL
)
1422 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName
));
1425 parm_ptr
= ((char *)pSERVICE(iServiceIndex
)) + PTR_DIFF(def_ptr
,&sDefault
);
1428 if (!bInGlobalSection
)
1431 if (!iSERVICE(iServiceIndex
).copymap
)
1432 init_copymap(pSERVICE(iServiceIndex
));
1434 /* this handles the aliases - set the copymap for other entries with
1435 the same data pointer */
1436 for (i
=0;parm_table
[i
].label
;i
++)
1437 if (parm_table
[i
].ptr
== parm_table
[parmnum
].ptr
)
1438 iSERVICE(iServiceIndex
).copymap
[i
] = False
;
1441 /* if it is a special case then go ahead */
1442 if (parm_table
[parmnum
].special
)
1444 parm_table
[parmnum
].special(pszParmValue
,parm_ptr
);
1448 /* now switch on the type of variable it is */
1449 switch (parm_table
[parmnum
].type
)
1452 set_boolean(parm_ptr
,pszParmValue
);
1456 set_boolean(parm_ptr
,pszParmValue
);
1457 *(BOOL
*)parm_ptr
= ! *(BOOL
*)parm_ptr
;
1461 *(int *)parm_ptr
= atoi(pszParmValue
);
1465 *(char *)parm_ptr
= *pszParmValue
;
1469 sscanf(pszParmValue
,"%o",(int *)parm_ptr
);
1473 string_set(parm_ptr
,pszParmValue
);
1477 strcpy((char *)parm_ptr
,pszParmValue
);
1484 /***************************************************************************
1485 print a parameter of the specified type
1486 ***************************************************************************/
1487 static void print_parameter(parm_type type
,void *ptr
)
1492 printf("%s",BOOLSTR(*(BOOL
*)ptr
));
1496 printf("%s",BOOLSTR(! *(BOOL
*)ptr
));
1500 printf("%d",*(int *)ptr
);
1504 printf("%c",*(char *)ptr
);
1508 printf("0%o",*(int *)ptr
);
1513 printf("%s",(char *)ptr
);
1518 printf("%s",*(char **)ptr
);
1524 /***************************************************************************
1525 check if two parameters are equal
1526 ***************************************************************************/
1527 static BOOL
equal_parameter(parm_type type
,void *ptr1
,void *ptr2
)
1533 return(*((BOOL
*)ptr1
) == *((BOOL
*)ptr2
));
1537 return(*((int *)ptr1
) == *((int *)ptr2
));
1540 return(*((char *)ptr1
) == *((char *)ptr2
));
1544 char *p1
= (char *)ptr1
, *p2
= (char *)ptr2
;
1545 if (p1
&& !*p1
) p1
= NULL
;
1546 if (p2
&& !*p2
) p2
= NULL
;
1547 return(p1
==p2
|| strequal(p1
,p2
));
1551 char *p1
= *(char **)ptr1
, *p2
= *(char **)ptr2
;
1552 if (p1
&& !*p1
) p1
= NULL
;
1553 if (p2
&& !*p2
) p2
= NULL
;
1554 return(p1
==p2
|| strequal(p1
,p2
));
1560 /***************************************************************************
1561 Process a new section (service). At this stage all sections are services.
1562 Later we'll have special sections that permit server parameters to be set.
1563 Returns True on success, False on failure.
1564 ***************************************************************************/
1565 static BOOL
do_section(char *pszSectionName
)
1568 BOOL isglobal
= ((strwicmp(pszSectionName
, GLOBAL_NAME
) == 0) ||
1569 (strwicmp(pszSectionName
, GLOBAL_NAME2
) == 0));
1572 /* if we were in a global section then do the local inits */
1573 if (bInGlobalSection
&& !isglobal
)
1576 /* if we've just struck a global section, note the fact. */
1577 bInGlobalSection
= isglobal
;
1579 /* check for multiple global sections */
1580 if (bInGlobalSection
)
1582 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName
));
1586 if (!bInGlobalSection
&& bGlobalOnly
) return(True
);
1588 /* if we have a current service, tidy it up before moving on */
1591 if (iServiceIndex
>= 0)
1592 bRetval
= service_ok(iServiceIndex
);
1594 /* if all is still well, move to the next record in the services array */
1597 /* We put this here to avoid an odd message order if messages are */
1598 /* issued by the post-processing of a previous section. */
1599 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName
));
1601 if ((iServiceIndex
=add_a_service(&sDefault
,pszSectionName
)) < 0)
1603 DEBUG(0,("Failed to add a new service\n"));
1611 /***************************************************************************
1612 Display the contents of the global structure.
1613 ***************************************************************************/
1614 static void dump_globals(void)
1617 printf("Global parameters:\n");
1619 for (i
=0;parm_table
[i
].label
;i
++)
1620 if (parm_table
[i
].class == P_GLOBAL
&&
1621 parm_table
[i
].ptr
&&
1622 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
-1].ptr
)))
1624 printf("\t%s: ",parm_table
[i
].label
);
1625 print_parameter(parm_table
[i
].type
,parm_table
[i
].ptr
);
1630 /***************************************************************************
1631 Display the contents of a single services record.
1632 ***************************************************************************/
1633 static void dump_a_service(service
*pService
)
1636 if (pService
== &sDefault
)
1637 printf("\nDefault service parameters:\n");
1639 printf("\nService parameters [%s]:\n",pService
->szService
);
1641 for (i
=0;parm_table
[i
].label
;i
++)
1642 if (parm_table
[i
].class == P_LOCAL
&&
1643 parm_table
[i
].ptr
&&
1644 (*parm_table
[i
].label
!= '-') &&
1645 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
-1].ptr
)))
1647 int pdiff
= PTR_DIFF(parm_table
[i
].ptr
,&sDefault
);
1649 if (pService
== &sDefault
|| !equal_parameter(parm_table
[i
].type
,
1650 ((char *)pService
) + pdiff
,
1651 ((char *)&sDefault
) + pdiff
))
1653 printf("\t%s: ",parm_table
[i
].label
);
1654 print_parameter(parm_table
[i
].type
,
1655 ((char *)pService
) + pdiff
);
1662 /***************************************************************************
1663 Display the contents of a single copy structure.
1664 ***************************************************************************/
1665 static void dump_copy_map(BOOL
*pcopymap
)
1668 if (!pcopymap
) return;
1670 printf("\n\tNon-Copied parameters:\n");
1672 for (i
=0;parm_table
[i
].label
;i
++)
1673 if (parm_table
[i
].class == P_LOCAL
&&
1674 parm_table
[i
].ptr
&& !pcopymap
[i
] &&
1675 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
-1].ptr
)))
1677 printf("\t\t%s\n",parm_table
[i
].label
);
1682 /***************************************************************************
1683 Return TRUE if the passed service number is within range.
1684 ***************************************************************************/
1685 BOOL
lp_snum_ok(int iService
)
1687 return (LP_SNUM_OK(iService
) && iSERVICE(iService
).bAvailable
);
1691 /***************************************************************************
1692 auto-load some homes and printer services
1693 ***************************************************************************/
1694 static void lp_add_auto_services(char *str
)
1698 int homes
= lp_servicenumber(HOMES_NAME
);
1699 int printers
= lp_servicenumber(PRINTERS_NAME
);
1707 for (p
=strtok(s
,LIST_SEP
);p
;p
=strtok(NULL
,LIST_SEP
))
1709 char *home
= get_home_dir(p
);
1711 if (lp_servicenumber(p
) >= 0) continue;
1713 if (home
&& homes
>= 0)
1715 lp_add_home(p
,homes
,home
);
1719 if (printers
>= 0 && pcap_printername_ok(p
,NULL
))
1720 lp_add_printer(p
,printers
);
1725 /***************************************************************************
1726 auto-load one printer
1727 ***************************************************************************/
1728 static void lp_add_one_printer(char *name
,char *comment
)
1730 int printers
= lp_servicenumber(PRINTERS_NAME
);
1733 if (lp_servicenumber(name
) < 0)
1735 lp_add_printer(name
,printers
);
1736 if ((i
=lp_servicenumber(name
)) >= 0)
1737 string_set(&iSERVICE(i
).comment
,comment
);
1742 /***************************************************************************
1743 auto-load printer services
1744 ***************************************************************************/
1745 static void lp_add_all_printers(void)
1747 int printers
= lp_servicenumber(PRINTERS_NAME
);
1749 if (printers
< 0) return;
1751 pcap_printer_fn(lp_add_one_printer
);
1754 /***************************************************************************
1755 have we loaded a services file yet?
1756 ***************************************************************************/
1757 BOOL
lp_loaded(void)
1762 /***************************************************************************
1763 unload unused services
1764 ***************************************************************************/
1765 void lp_killunused(BOOL (*snumused
)(int ))
1768 for (i
=0;i
<iNumServices
;i
++)
1769 if (VALID(i
) && !snumused(i
))
1771 iSERVICE(i
).valid
= False
;
1772 free_service(pSERVICE(i
));
1776 /***************************************************************************
1777 Load the services array from the services file. Return True on success,
1779 ***************************************************************************/
1780 BOOL
lp_load(char *pszFname
,BOOL global_only
)
1785 add_to_file_list(pszFname
);
1789 bInGlobalSection
= True
;
1790 bGlobalOnly
= global_only
;
1794 strcpy(n2
,pszFname
);
1795 standard_sub_basic(n2
);
1797 /* We get sections first, so have to start 'behind' to make up */
1799 bRetval
= pm_process(n2
, do_section
, do_parameter
);
1801 /* finish up the last section */
1802 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval
)));
1804 if (iServiceIndex
>= 0)
1805 bRetval
= service_ok(iServiceIndex
);
1807 lp_add_auto_services(lp_auto_services());
1808 if (lp_load_printers())
1809 lp_add_all_printers();
1819 /***************************************************************************
1820 return the max number of services
1821 ***************************************************************************/
1822 int lp_numservices(void)
1824 return(iNumServices
);
1827 /***************************************************************************
1828 Display the contents of the services array in human-readable form.
1829 ***************************************************************************/
1836 dump_a_service(&sDefault
);
1838 for (iService
= 0; iService
< iNumServices
; iService
++)
1840 if (VALID(iService
))
1842 if (iSERVICE(iService
).szService
[0] == '\0')
1844 dump_a_service(pSERVICE(iService
));
1849 /***************************************************************************
1850 Return the number of the service with the given name, or -1 if it doesn't
1851 exist. Note that this is a DIFFERENT ANIMAL from the internal function
1852 getservicebyname()! This works ONLY if all services have been loaded, and
1853 does not copy the found service.
1854 ***************************************************************************/
1855 int lp_servicenumber(char *pszServiceName
)
1859 for (iService
= iNumServices
- 1; iService
>= 0; iService
--)
1860 if (VALID(iService
) &&
1861 strwicmp(iSERVICE(iService
).szService
, pszServiceName
) == 0)
1865 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName
));
1873 /*******************************************************************
1874 get a workgroup - but map to standalone if '*'
1875 ******************************************************************/
1876 char *my_workgroup(void)
1878 char *res
= lp_workgroup();
1879 if (*res
== '*') return("STANDALONE");
1883 /*******************************************************************
1884 a useful volume label function
1885 ******************************************************************/
1886 char *volume_label(int snum
)
1888 char *ret
= lp_volume(snum
);
1889 if (!*ret
) return(lp_servicename(snum
));