2 Unix SMB/Netbios implementation.
4 Parameter loading functions
5 Copyright (C) Karl Auer 1993-1998
7 Largely re-written by Andrew Tridgell, September 1994
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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
52 /* Set default coding system for KANJI if none specified in Makefile. */
59 extern int DEBUGLEVEL;
60 extern pstring user_socket_options;
61 extern pstring myname;
64 #define GLOBAL_NAME "global"
68 #define PRINTERS_NAME "printers"
72 #define HOMES_NAME "homes"
75 /* some helpful bits */
76 #define pSERVICE(i) ServicePtrs[i]
77 #define iSERVICE(i) (*pSERVICE(i))
78 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
79 #define VALID(i) iSERVICE(i).valid
81 /* these are the types of parameter we have */
84 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
85 P_STRING,P_USTRING,P_GSTRING,P_UGSTRING,P_ENUM
90 P_LOCAL,P_GLOBAL,P_NONE
94 extern BOOL use_getwd_cache;
96 extern int extra_time_offset;
99 * This structure describes global (ie., server-wide) parameters.
103 char *szPrintcapname;
106 char *szDefaultService;
110 char *szServerString;
111 char *szAutoServices;
112 char *szPasswdProgram;
116 char *szSMBPasswdFile;
117 char *szPasswordServer;
118 char *szSocketOptions;
121 char *szDomainAdminUsers;
122 char *szDomainGuestUsers;
123 char *szDomainHostsallow;
124 char *szDomainHostsdeny;
126 char *szCharacterSet;
133 char *szCodingSystem;
135 char *szRemoteAnnounce;
136 char *szRemoteBrowseSync;
137 char *szSocketAddress;
138 char *szNISHomeMapName;
139 char *szAnnounceVersion; /* This is initialised in init_globals */
140 char *szNetbiosAliases;
142 char *szDomainOtherSIDs;
143 char *szDomainGroups;
166 int client_code_page;
167 int announce_as; /* This is initialised in init_globals */
172 BOOL bPreferredMaster;
173 BOOL bDomainController;
176 BOOL bEncryptPasswords;
183 BOOL bReadPrediction;
190 BOOL bBindInterfacesOnly;
191 BOOL bNetWkstaUserLogon;
192 BOOL bWin95BugCompatibility;
195 static global Globals;
200 * This structure describes a single service.
208 char *szGuestaccount;
209 char *szInvalidUsers;
217 char *szRootPostExec;
218 char *szPrintcommand;
221 char *szLppausecommand;
222 char *szLpresumecommand;
224 char *szPrinterDriver;
225 char *szPrinterDriverLocation;
234 char *szVetoOplockFiles;
243 int iCreate_force_mode;
253 BOOL bShortCasePreserve;
279 BOOL bDeleteReadonly;
281 BOOL bDeleteVetoFiles;
283 char dummy[3]; /* for alignment */
287 /* This is a default service used to prime a services structure */
288 static service sDefault =
291 NULL, /* szService */
293 NULL, /* szUsername */
294 NULL, /* szGuestAccount - this is set in init_globals() */
295 NULL, /* szInvalidUsers */
296 NULL, /* szValidUsers */
297 NULL, /* szAdminUsers */
299 NULL, /* szInclude */
300 NULL, /* szPreExec */
301 NULL, /* szPostExec */
302 NULL, /* szRootPreExec */
303 NULL, /* szRootPostExec */
304 NULL, /* szPrintcommand */
305 NULL, /* szLpqcommand */
306 NULL, /* szLprmcommand */
307 NULL, /* szLppausecommand */
308 NULL, /* szLpresumecommand */
309 NULL, /* szPrintername */
310 NULL, /* szPrinterDriver - this is set in init_globals() */
311 NULL, /* szPrinterDriverLocation */
312 NULL, /* szDontdescend */
313 NULL, /* szHostsallow */
314 NULL, /* szHostsdeny */
315 NULL, /* szMagicScript */
316 NULL, /* szMagicOutput */
317 NULL, /* szMangledMap */
318 NULL, /* szVetoFiles */
319 NULL, /* szHideFiles */
320 NULL, /* szVetoOplockFiles */
322 NULL, /* force user */
323 NULL, /* force group */
325 NULL, /* writelist */
327 0, /* iMinPrintSpace */
328 0744, /* iCreate_mask */
329 0000, /* iCreate_force_mode */
330 0755, /* iDir_mask */
331 0000, /* iDir_force_mode */
332 0, /* iMaxConnections */
333 CASE_LOWER, /* iDefaultCase */
334 DEFAULT_PRINTING, /* iPrinting */
335 False, /* bAlternatePerm */
336 False, /* revalidate */
337 False, /* case sensitive */
338 False, /* case preserve */
339 False, /* short case preserve */
340 False, /* case mangle */
342 True, /* bHideDotFiles */
343 True, /* bBrowseable */
344 True, /* bAvailable */
345 True, /* bRead_only */
346 True, /* bNo_set_dir */
347 False, /* bGuest_only */
348 False, /* bGuest_ok */
349 False, /* bPrint_ok */
350 False, /* bPostscript */
351 False, /* bMap_system */
352 False, /* bMap_hidden */
353 True, /* bMap_archive */
355 False, /* bStrictLocking */
356 True, /* bShareModes */
358 False, /* bOnlyUser */
359 True, /* bMangledNames */
360 True, /* bWidelinks */
361 True, /* bSymlinks */
362 False, /* bSyncAlways */
363 '~', /* magic char */
365 False, /* bDeleteReadonly */
366 False, /* bFakeOplocks */
367 False, /* bDeleteVetoFiles */
368 False, /* bDosFiletimes */
374 /* local variables */
375 static service **ServicePtrs = NULL;
376 static int iNumServices = 0;
377 static int iServiceIndex = 0;
378 static BOOL bInGlobalSection = True;
379 static BOOL bGlobalOnly = False;
380 static int default_server_announce;
382 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
384 /* prototypes for the special type handlers */
385 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
386 static BOOL handle_include(char *pszParmValue, char **ptr);
387 static BOOL handle_copy(char *pszParmValue, char **ptr);
388 static BOOL handle_character_set(char *pszParmValue,char **ptr);
389 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
391 static void set_default_server_announce_type(void);
398 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
399 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"},
400 {PROTOCOL_COREPLUS, "COREPLUS"},
401 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
403 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
404 {SEC_SERVER, "SERVER"}, {-1, NULL}};
406 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
407 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
408 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
409 {PRINT_LPRNG, "lprng"}, {-1, NULL}};
411 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
412 {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
414 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
416 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
418 static struct parm_struct
425 struct enum_list *enum_list;
428 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL},
429 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL},
430 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL},
431 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL},
432 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol},
433 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security},
434 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL},
435 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL},
436 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as},
437 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL},
438 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL},
439 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL},
440 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL},
441 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL},
442 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL},
443 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL},
444 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL},
445 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL},
446 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL},
447 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL},
448 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL},
449 {"networkstation user login", P_BOOL,P_GLOBAL, &Globals.bNetWkstaUserLogon,NULL, NULL},
450 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL},
451 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL},
452 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL, NULL},
453 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL},
454 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL},
455 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL},
456 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL},
457 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL},
458 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL},
459 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL},
460 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL},
461 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL},
462 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL},
463 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL},
464 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL},
465 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL},
466 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL},
467 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL},
468 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL},
469 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL},
470 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL},
471 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL},
472 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL},
473 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL},
474 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL},
475 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL},
476 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL},
478 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL, NULL},
479 {"domain other sids",P_STRING, P_GLOBAL, &Globals.szDomainOtherSIDs, NULL, NULL},
480 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL},
481 {"domain controller",P_BOOL , P_GLOBAL, &Globals.bDomainController,NULL, NULL},
482 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL},
483 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL},
484 {"domain hosts allow",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL},
485 {"domain allow hosts",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL},
486 {"domain hosts deny", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL},
487 {"domain deny hosts", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL},
488 #endif /* NTDOMAIN */
489 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL},
490 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL},
491 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL},
492 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL},
493 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL},
494 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL},
495 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL},
496 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL},
497 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL},
498 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL},
499 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL},
500 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL},
501 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL},
502 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL},
503 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL},
504 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL},
505 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL},
506 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL},
507 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL},
508 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL},
509 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL},
510 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL},
511 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL},
512 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL},
513 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL},
514 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL},
515 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL},
516 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL},
517 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL},
518 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL},
519 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce},
520 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL},
521 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL},
522 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL},
523 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL},
524 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL},
525 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL},
526 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL},
527 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL},
528 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL},
529 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL},
530 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL},
531 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL},
532 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL},
533 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL},
534 {"win95 bug compatibility", P_BOOL, P_GLOBAL, &Globals.bWin95BugCompatibility,NULL, NULL},
535 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL},
536 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL},
537 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL},
538 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL},
539 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL},
540 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL},
541 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL},
542 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL},
543 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL},
544 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL},
545 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL},
546 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL},
547 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case},
548 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL},
549 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL},
550 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL},
551 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL},
552 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL},
553 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL},
554 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL},
555 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL},
556 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL},
557 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL},
558 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL},
559 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL},
560 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL},
561 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL},
562 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL},
563 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL},
564 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL},
565 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL},
566 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL},
567 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL},
568 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL},
569 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL},
570 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL},
571 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL},
572 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL},
573 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL},
574 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL},
575 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL},
576 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL},
577 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL},
578 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL},
579 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL},
580 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL},
581 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL},
582 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL},
583 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL},
584 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL},
585 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL},
586 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL},
587 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL},
588 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL},
589 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL},
590 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL},
591 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL},
592 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL},
593 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL},
594 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL},
595 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL},
596 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL},
597 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL},
598 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL},
599 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL},
600 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL},
601 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL},
602 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL},
603 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL},
604 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL},
605 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL},
606 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL},
607 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL},
608 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL},
609 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL},
610 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL},
611 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing},
612 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL},
613 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL},
614 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL},
615 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL},
616 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL},
617 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL},
618 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL},
619 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL},
620 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL},
621 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL},
622 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL},
623 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL},
624 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL},
625 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL},
626 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL},
627 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL},
628 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL},
629 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL},
630 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL},
632 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL}
637 /***************************************************************************
638 Initialise the global parameter structure.
639 ***************************************************************************/
640 static void init_globals(void)
642 static BOOL done_init = False;
648 bzero((void *)&Globals,sizeof(Globals));
650 for (i = 0; parm_table[i].label; i++)
651 if ((parm_table[i].type == P_STRING ||
652 parm_table[i].type == P_USTRING) &&
654 string_init(parm_table[i].ptr,"");
656 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
657 string_set(&sDefault.szPrinterDriver, "NULL");
663 DEBUG(3,("Initialising global parameters\n"));
665 #ifdef SMB_PASSWD_FILE
666 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
668 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
669 string_set(&Globals.szWorkGroup, WORKGROUP);
670 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
671 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
672 string_set(&Globals.szDriverFile, DRIVERFILE);
673 string_set(&Globals.szLockDir, LOCKDIR);
674 string_set(&Globals.szRootdir, "/");
675 string_set(&Globals.szSmbrun, SMBRUN);
676 string_set(&Globals.szSocketAddress, "0.0.0.0");
677 sprintf(s,"Samba %s",VERSION);
678 string_set(&Globals.szServerString,s);
679 sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
680 string_set(&Globals.szAnnounceVersion,s);
682 string_set(&Globals.szLogonDrive, "");
683 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
684 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
685 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
687 Globals.bLoadPrinters = True;
688 Globals.bUseRhosts = False;
689 Globals.max_packet = 65535;
690 Globals.mangled_stack = 50;
691 Globals.max_xmit = 65535;
692 Globals.max_mux = 50; /* This is *needed* for profile support. */
693 Globals.lpqcachetime = 10;
694 Globals.pwordlevel = 0;
695 Globals.unamelevel = 0;
696 Globals.deadtime = 0;
697 Globals.max_log_size = 5000;
698 Globals.maxprotocol = PROTOCOL_NT1;
699 Globals.security = SEC_SHARE;
700 Globals.bEncryptPasswords = False;
701 Globals.bReadRaw = True;
702 Globals.bWriteRaw = True;
703 Globals.bReadPrediction = False;
704 Globals.bReadbmpx = True;
705 Globals.bNullPasswords = False;
706 Globals.bStripDot = False;
708 Globals.bSyslogOnly = False;
709 Globals.os_level = 0;
710 Globals.max_ttl = 60*60*4; /* 4 hours default */
711 Globals.max_wins_ttl = 60*60*24*3; /* 3 days default */
712 Globals.min_wins_ttl = 60*60*6; /* 6 hours default */
713 Globals.ReadSize = 16*1024;
714 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
715 Globals.lm_interval = 60;
716 Globals.shmem_size = SHMEM_SIZE;
717 Globals.announce_as = ANNOUNCE_AS_NT;
718 Globals.bUnixRealname = False;
719 #if (defined(NETGROUP) && defined(AUTOMOUNT))
720 Globals.bNISHomeMap = False;
721 string_set(&Globals.szNISHomeMapName, "auto.home");
723 interpret_coding_system(KANJI);
724 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
725 Globals.bTimeServer = False;
726 Globals.bBindInterfacesOnly = False;
727 Globals.bNetWkstaUserLogon = True;
728 Globals.bWin95BugCompatibility = False;
730 /* these parameters are set to defaults that are more appropriate
731 for the increasing samba install base:
733 as a member of the workgroup, that will possibly become a
734 _local_ master browser (lm = True). this is opposed to a forced
735 local master browser startup (pm = True).
737 doesn't provide WINS server service by default (wsupp = False),
738 and doesn't provide domain master browser services by default, either.
742 Globals.bPreferredMaster = False;
743 Globals.bLocalMaster = True;
744 Globals.bDomainMaster = False;
745 Globals.bDomainLogons = False;
746 Globals.bBrowseList = True;
747 Globals.bWINSsupport = False;
748 Globals.bWINSproxy = False;
750 Globals.bDNSproxy = True;
753 /***************************************************************************
754 check if a string is initialised and if not then initialise it
755 ***************************************************************************/
756 static void string_initial(char **s,char *v)
763 /***************************************************************************
764 Initialise the sDefault parameter structure.
765 ***************************************************************************/
766 static void init_locals(void)
768 /* choose defaults depending on the type of printing */
769 switch (sDefault.iPrinting)
775 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
776 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
777 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
782 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
783 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
784 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
786 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
787 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
792 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
793 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
794 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
802 /******************************************************************* a
803 convenience routine to grab string parameters into a rotating buffer,
804 and run standard_sub_basic on them. The buffers can be written to by
805 callers without affecting the source string.
806 ********************************************************************/
807 char *lp_string(char *s)
809 static char *bufs[10];
810 static int buflen[10];
811 static int next = -1;
814 int len = s?strlen(s):0;
825 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
828 if (buflen[next] != len) {
830 if (bufs[next]) free(bufs[next]);
831 bufs[next] = (char *)malloc(len);
833 DEBUG(0,("out of memory in lp_string()"));
838 ret = &bufs[next][0];
846 trim_string(ret, "\"", "\"");
848 standard_sub_basic(ret);
854 In this section all the functions that are used to access the
855 parameters from the rest of the program are defined
858 #define FN_GLOBAL_STRING(fn_name,ptr) \
859 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
860 #define FN_GLOBAL_BOOL(fn_name,ptr) \
861 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
862 #define FN_GLOBAL_CHAR(fn_name,ptr) \
863 char fn_name(void) {return(*(char *)(ptr));}
864 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
865 int fn_name(void) {return(*(int *)(ptr));}
867 #define FN_LOCAL_STRING(fn_name,val) \
868 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
869 #define FN_LOCAL_BOOL(fn_name,val) \
870 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
871 #define FN_LOCAL_CHAR(fn_name,val) \
872 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
873 #define FN_LOCAL_INTEGER(fn_name,val) \
874 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
876 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
877 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
878 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
879 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
880 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
881 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
882 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
883 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
884 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
885 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
886 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
887 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
888 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
889 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
890 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
891 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
892 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
893 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
894 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
895 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
896 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
897 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
898 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
899 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
900 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
901 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
902 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
903 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
904 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
905 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
906 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
907 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
910 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
911 FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
912 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
913 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
914 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
915 FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
916 FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
917 #endif /* NTDOMAIN */
919 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
920 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
921 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
922 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
923 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
924 FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController)
925 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
926 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
927 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
928 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
929 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
930 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
931 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
932 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
933 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
934 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
935 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
936 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
937 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
938 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
939 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
940 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
941 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
942 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
943 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
944 FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
945 FN_GLOBAL_BOOL(lp_win95_bug_compatibility,&Globals.bWin95BugCompatibility)
947 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
948 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
949 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
950 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
951 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
952 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
953 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
954 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
955 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
956 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
957 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
958 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
959 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
960 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
961 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
962 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
963 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
964 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
965 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
966 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
967 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
968 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
969 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
970 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
972 FN_LOCAL_STRING(lp_preexec,szPreExec)
973 FN_LOCAL_STRING(lp_postexec,szPostExec)
974 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
975 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
976 FN_LOCAL_STRING(lp_servicename,szService)
977 FN_LOCAL_STRING(lp_pathname,szPath)
978 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
979 FN_LOCAL_STRING(lp_username,szUsername)
980 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
981 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
982 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
983 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
984 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
985 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
986 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
987 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
988 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
989 FN_LOCAL_STRING(lp_printername,szPrintername)
990 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
991 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
992 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
993 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
994 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
995 FN_LOCAL_STRING(lp_comment,comment)
996 FN_LOCAL_STRING(lp_force_user,force_user)
997 FN_LOCAL_STRING(lp_force_group,force_group)
998 FN_LOCAL_STRING(lp_readlist,readlist)
999 FN_LOCAL_STRING(lp_writelist,writelist)
1000 FN_LOCAL_STRING(lp_volume,volume)
1001 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
1002 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
1003 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
1004 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
1005 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
1007 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
1008 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
1009 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
1010 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1011 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1012 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1013 FN_LOCAL_BOOL(lp_status,status)
1014 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1015 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1016 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1017 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1018 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1019 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1020 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1021 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1022 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1023 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1024 FN_LOCAL_BOOL(lp_locking,bLocking)
1025 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1026 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1027 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1028 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1029 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1030 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1031 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1032 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1033 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1034 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1035 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1036 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1037 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1039 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1040 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1041 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1042 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1043 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1044 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1045 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1046 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1048 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1052 /* local prototypes */
1053 static int strwicmp( char *psz1, char *psz2 );
1054 static int map_parameter( char *pszParmName);
1055 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1056 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1057 static void copy_service( service *pserviceDest,
1058 service *pserviceSource,
1059 BOOL *pcopymapDest );
1060 static BOOL service_ok(int iService);
1061 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1062 static BOOL do_section(char *pszSectionName);
1063 static void init_copymap(service *pservice);
1066 /***************************************************************************
1067 initialise a service to the defaults
1068 ***************************************************************************/
1069 static void init_service(service *pservice)
1071 bzero((char *)pservice,sizeof(service));
1072 copy_service(pservice,&sDefault,NULL);
1076 /***************************************************************************
1077 free the dynamically allocated parts of a service struct
1078 ***************************************************************************/
1079 static void free_service(service *pservice)
1085 if(pservice->szService)
1086 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1088 string_free(&pservice->szService);
1089 if (pservice->copymap)
1091 free(pservice->copymap);
1092 pservice->copymap = NULL;
1095 for (i=0;parm_table[i].label;i++)
1096 if ((parm_table[i].type == P_STRING ||
1097 parm_table[i].type == P_USTRING) &&
1098 parm_table[i].class == P_LOCAL)
1099 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1102 /***************************************************************************
1103 add a new service to the services array initialising it with the given
1105 ***************************************************************************/
1106 static int add_a_service(service *pservice, char *name)
1110 int num_to_alloc = iNumServices+1;
1112 tservice = *pservice;
1114 /* it might already exist */
1117 i = getservicebyname(name,NULL);
1122 /* find an invalid one */
1123 for (i=0;i<iNumServices;i++)
1124 if (!pSERVICE(i)->valid)
1127 /* if not, then create one */
1128 if (i == iNumServices)
1130 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1132 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1134 if (!ServicePtrs || !pSERVICE(iNumServices))
1140 free_service(pSERVICE(i));
1142 pSERVICE(i)->valid = True;
1144 init_service(pSERVICE(i));
1145 copy_service(pSERVICE(i),&tservice,NULL);
1147 string_set(&iSERVICE(i).szService,name);
1152 /***************************************************************************
1153 add a new home service, with the specified home directory, defaults coming
1155 ***************************************************************************/
1156 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1158 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1163 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1164 string_set(&iSERVICE(i).szPath,pszHomedir);
1165 if (!(*(iSERVICE(i).comment)))
1168 sprintf(comment,"Home directory of %s",pszHomename);
1169 string_set(&iSERVICE(i).comment,comment);
1171 iSERVICE(i).bAvailable = sDefault.bAvailable;
1172 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1174 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1179 /***************************************************************************
1180 add a new service, based on an old one
1181 ***************************************************************************/
1182 int lp_add_service(char *pszService, int iDefaultService)
1184 return(add_a_service(pSERVICE(iDefaultService),pszService));
1188 /***************************************************************************
1190 ***************************************************************************/
1191 static BOOL lp_add_ipc(void)
1194 int i = add_a_service(&sDefault,"IPC$");
1199 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1201 string_set(&iSERVICE(i).szPath,tmpdir());
1202 string_set(&iSERVICE(i).szUsername,"");
1203 string_set(&iSERVICE(i).comment,comment);
1204 iSERVICE(i).status = False;
1205 iSERVICE(i).iMaxConnections = 0;
1206 iSERVICE(i).bAvailable = True;
1207 iSERVICE(i).bRead_only = True;
1208 iSERVICE(i).bGuest_only = False;
1209 iSERVICE(i).bGuest_ok = True;
1210 iSERVICE(i).bPrint_ok = False;
1211 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1213 DEBUG(3,("adding IPC service\n"));
1219 /***************************************************************************
1220 add a new printer service, with defaults coming from service iFrom
1221 ***************************************************************************/
1222 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1224 char *comment = "From Printcap";
1225 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1230 /* note that we do NOT default the availability flag to True - */
1231 /* we take it from the default service passed. This allows all */
1232 /* dynamic printers to be disabled by disabling the [printers] */
1233 /* entry (if/when the 'available' keyword is implemented!). */
1235 /* the printer name is set to the service name. */
1236 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1237 string_set(&iSERVICE(i).comment,comment);
1238 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1239 /* Printers cannot be read_only. */
1240 iSERVICE(i).bRead_only = False;
1241 /* No share modes on printer services. */
1242 iSERVICE(i).bShareModes = False;
1243 /* No oplocks on printer services. */
1244 iSERVICE(i).bOpLocks = False;
1245 /* Printer services must be printable. */
1246 iSERVICE(i).bPrint_ok = True;
1248 DEBUG(3,("adding printer service %s\n",pszPrintername));
1254 /***************************************************************************
1255 Do a case-insensitive, whitespace-ignoring string compare.
1256 ***************************************************************************/
1257 static int strwicmp(char *psz1, char *psz2)
1259 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1260 /* appropriate value. */
1270 /* sync the strings on first non-whitespace */
1273 while (isspace(*psz1))
1275 while (isspace(*psz2))
1277 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1282 return (*psz1 - *psz2);
1285 /***************************************************************************
1286 Map a parameter's string representation to something we can use.
1287 Returns False if the parameter string is not recognised, else TRUE.
1288 ***************************************************************************/
1289 static int map_parameter(char *pszParmName)
1293 if (*pszParmName == '-')
1296 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1297 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1300 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1305 /***************************************************************************
1306 Set a boolean variable from the text value stored in the passed string.
1307 Returns True in success, False if the passed string does not correctly
1308 represent a boolean.
1309 ***************************************************************************/
1310 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1315 if (strwicmp(pszParmValue, "yes") == 0 ||
1316 strwicmp(pszParmValue, "true") == 0 ||
1317 strwicmp(pszParmValue, "1") == 0)
1320 if (strwicmp(pszParmValue, "no") == 0 ||
1321 strwicmp(pszParmValue, "False") == 0 ||
1322 strwicmp(pszParmValue, "0") == 0)
1326 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1333 /***************************************************************************
1334 Find a service by name. Otherwise works like get_service.
1335 ***************************************************************************/
1336 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1340 for (iService = iNumServices - 1; iService >= 0; iService--)
1341 if (VALID(iService) &&
1342 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1344 if (pserviceDest != NULL)
1345 copy_service(pserviceDest, pSERVICE(iService), NULL);
1354 /***************************************************************************
1355 Copy a service structure to another
1357 If pcopymapDest is NULL then copy all fields
1358 ***************************************************************************/
1359 static void copy_service(service *pserviceDest,
1360 service *pserviceSource,
1364 BOOL bcopyall = (pcopymapDest == NULL);
1366 for (i=0;parm_table[i].label;i++)
1367 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1368 (bcopyall || pcopymapDest[i]))
1370 void *def_ptr = parm_table[i].ptr;
1372 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1374 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1376 switch (parm_table[i].type)
1380 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1386 *(int *)dest_ptr = *(int *)src_ptr;
1390 *(char *)dest_ptr = *(char *)src_ptr;
1394 string_set(dest_ptr,*(char **)src_ptr);
1398 string_set(dest_ptr,*(char **)src_ptr);
1399 strupper(*(char **)dest_ptr);
1408 init_copymap(pserviceDest);
1409 if (pserviceSource->copymap)
1410 memcpy((void *)pserviceDest->copymap,
1411 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1415 /***************************************************************************
1416 Check a service for consistency. Return False if the service is in any way
1417 incomplete or faulty, else True.
1418 ***************************************************************************/
1419 static BOOL service_ok(int iService)
1424 if (iSERVICE(iService).szService[0] == '\0')
1426 DEBUG(0,( "The following message indicates an internal error:\n"));
1427 DEBUG(0,( "No service name in service entry.\n"));
1431 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1432 /* I can't see why you'd want a non-printable printer service... */
1433 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1434 if (!iSERVICE(iService).bPrint_ok)
1436 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1437 iSERVICE(iService).szService));
1438 iSERVICE(iService).bPrint_ok = True;
1441 if (iSERVICE(iService).szPath[0] == '\0' &&
1442 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1444 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1445 string_set(&iSERVICE(iService).szPath,tmpdir());
1448 /* If a service is flagged unavailable, log the fact at level 0. */
1449 if (!iSERVICE(iService).bAvailable)
1450 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1451 iSERVICE(iService).szService));
1456 static struct file_lists {
1457 struct file_lists *next;
1460 } *file_lists = NULL;
1462 /*******************************************************************
1463 keep a linked list of all config files so we know when one has changed
1464 it's date and needs to be reloaded
1465 ********************************************************************/
1466 static void add_to_file_list(char *fname)
1468 struct file_lists *f=file_lists;
1471 if (f->name && !strcmp(f->name,fname)) break;
1476 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1478 f->next = file_lists;
1479 f->name = strdup(fname);
1490 standard_sub_basic(n2);
1491 f->modtime = file_modtime(n2);
1496 /*******************************************************************
1497 check if a config file has changed date
1498 ********************************************************************/
1499 BOOL lp_file_list_changed(void)
1501 struct file_lists *f = file_lists;
1502 DEBUG(6,("lp_file_list_changed()\n"));
1509 pstrcpy(n2,f->name);
1510 standard_sub_basic(n2);
1512 DEBUG(6,("file %s -> %s last mod_time: %s\n",
1513 f->name, n2, ctime(&f->modtime)));
1515 mod_time = file_modtime(n2);
1517 if (f->modtime != mod_time) {
1518 DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1519 f->modtime = mod_time;
1527 /***************************************************************************
1528 handle the interpretation of the coding system parameter
1529 *************************************************************************/
1530 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1532 string_set(ptr,pszParmValue);
1533 interpret_coding_system(pszParmValue);
1537 /***************************************************************************
1538 handle the interpretation of the character set system parameter
1539 ***************************************************************************/
1540 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1542 string_set(ptr,pszParmValue);
1543 interpret_character_set(pszParmValue);
1548 /***************************************************************************
1549 handle the valid chars lines
1550 ***************************************************************************/
1551 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1553 string_set(ptr,pszParmValue);
1555 /* A dependency here is that the parameter client code page must be
1556 set before this is called - as calling codepage_initialise()
1557 would overwrite the valid char lines.
1559 codepage_initialise(lp_client_code_page());
1561 add_char_string(pszParmValue);
1566 /***************************************************************************
1567 handle the include operation
1568 ***************************************************************************/
1569 static BOOL handle_include(char *pszParmValue,char **ptr)
1572 pstrcpy(fname,pszParmValue);
1574 add_to_file_list(fname);
1576 standard_sub_basic(fname);
1578 string_set(ptr,fname);
1580 if (file_exist(fname,NULL))
1581 return(pm_process(fname, do_section, do_parameter));
1583 DEBUG(2,("Can't find include file %s\n",fname));
1589 /***************************************************************************
1590 handle the interpretation of the copy parameter
1591 ***************************************************************************/
1592 static BOOL handle_copy(char *pszParmValue,char **ptr)
1596 service serviceTemp;
1598 string_set(ptr,pszParmValue);
1600 init_service(&serviceTemp);
1604 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1606 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1608 if (iTemp == iServiceIndex)
1610 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1615 copy_service(pSERVICE(iServiceIndex),
1617 iSERVICE(iServiceIndex).copymap);
1623 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1628 free_service(&serviceTemp);
1633 /***************************************************************************
1634 initialise a copymap
1635 ***************************************************************************/
1636 static void init_copymap(service *pservice)
1639 if (pservice->copymap) free(pservice->copymap);
1640 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1641 if (!pservice->copymap)
1642 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1644 for (i=0;i<NUMPARAMETERS;i++)
1645 pservice->copymap[i] = True;
1649 /***************************************************************************
1650 Process a parameter for a particular service number. If snum < 0
1651 then assume we are in the globals
1652 ***************************************************************************/
1653 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1656 void *parm_ptr=NULL; /* where we are going to store the result */
1659 parmnum = map_parameter(pszParmName);
1663 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1667 def_ptr = parm_table[parmnum].ptr;
1669 /* we might point at a service, the default service or a global */
1673 if (parm_table[parmnum].class == P_GLOBAL) {
1674 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1677 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1681 if (!iSERVICE(snum).copymap)
1682 init_copymap(pSERVICE(snum));
1684 /* this handles the aliases - set the copymap for other entries with
1685 the same data pointer */
1686 for (i=0;parm_table[i].label;i++)
1687 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1688 iSERVICE(snum).copymap[i] = False;
1691 /* if it is a special case then go ahead */
1692 if (parm_table[parmnum].special) {
1693 parm_table[parmnum].special(pszParmValue,parm_ptr);
1697 /* now switch on the type of variable it is */
1698 switch (parm_table[parmnum].type)
1701 set_boolean(parm_ptr,pszParmValue);
1705 set_boolean(parm_ptr,pszParmValue);
1706 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1710 *(int *)parm_ptr = atoi(pszParmValue);
1714 *(char *)parm_ptr = *pszParmValue;
1718 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1722 string_set(parm_ptr,pszParmValue);
1726 string_set(parm_ptr,pszParmValue);
1727 strupper(*(char **)parm_ptr);
1731 strcpy((char *)parm_ptr,pszParmValue);
1735 strcpy((char *)parm_ptr,pszParmValue);
1736 strupper((char *)parm_ptr);
1740 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1741 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1742 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
1752 /***************************************************************************
1753 Process a parameter.
1754 ***************************************************************************/
1755 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1757 if (!bInGlobalSection && bGlobalOnly) return(True);
1759 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1761 return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
1765 /***************************************************************************
1766 print a parameter of the specified type
1767 ***************************************************************************/
1768 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
1773 for (i=0;p->enum_list[i].name;i++) {
1774 if (*(int *)ptr == p->enum_list[i].value) {
1775 fprintf(f,"%s",p->enum_list[i].name);
1782 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
1786 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
1790 fprintf(f,"%d",*(int *)ptr);
1794 fprintf(f,"%c",*(char *)ptr);
1798 fprintf(f,"0%o",*(int *)ptr);
1804 fprintf(f,"%s",(char *)ptr);
1810 fprintf(f,"%s",*(char **)ptr);
1816 /***************************************************************************
1817 print a parameter of the specified type
1818 ***************************************************************************/
1819 static void parameter_string(struct parm_struct *p,void *ptr,char *s)
1826 for (i=0;p->enum_list[i].name;i++) {
1827 if (*(int *)ptr == p->enum_list[i].value) {
1828 sprintf(s,"%s",p->enum_list[i].name);
1835 sprintf(s, "%s",BOOLSTR(*(BOOL *)ptr));
1839 sprintf(s, "%s",BOOLSTR(! *(BOOL *)ptr));
1843 sprintf(s, "%d",*(int *)ptr);
1847 sprintf(s, "%c",*(char *)ptr);
1851 sprintf(s, "0%o",*(int *)ptr);
1857 sprintf(s, "%s",(char *)ptr);
1863 sprintf(s, "%s",*(char **)ptr);
1869 /***************************************************************************
1870 check if two parameters are equal
1871 ***************************************************************************/
1872 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1878 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1883 return(*((int *)ptr1) == *((int *)ptr2));
1886 return(*((char *)ptr1) == *((char *)ptr2));
1891 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1892 if (p1 && !*p1) p1 = NULL;
1893 if (p2 && !*p2) p2 = NULL;
1894 return(p1==p2 || strequal(p1,p2));
1899 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1900 if (p1 && !*p1) p1 = NULL;
1901 if (p2 && !*p2) p2 = NULL;
1902 return(p1==p2 || strequal(p1,p2));
1908 /***************************************************************************
1909 Process a new section (service). At this stage all sections are services.
1910 Later we'll have special sections that permit server parameters to be set.
1911 Returns True on success, False on failure.
1912 ***************************************************************************/
1913 static BOOL do_section(char *pszSectionName)
1916 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1917 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1920 /* if we were in a global section then do the local inits */
1921 if (bInGlobalSection && !isglobal)
1924 /* if we've just struck a global section, note the fact. */
1925 bInGlobalSection = isglobal;
1927 /* check for multiple global sections */
1928 if (bInGlobalSection)
1930 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1934 if (!bInGlobalSection && bGlobalOnly) return(True);
1936 /* if we have a current service, tidy it up before moving on */
1939 if (iServiceIndex >= 0)
1940 bRetval = service_ok(iServiceIndex);
1942 /* if all is still well, move to the next record in the services array */
1945 /* We put this here to avoid an odd message order if messages are */
1946 /* issued by the post-processing of a previous section. */
1947 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1949 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1951 DEBUG(0,("Failed to add a new service\n"));
1959 /***************************************************************************
1960 Display the contents of the global structure.
1961 ***************************************************************************/
1962 static void dump_globals(FILE *f)
1965 fprintf(f, "# Global parameters\n");
1967 for (i=0;parm_table[i].label;i++)
1968 if (parm_table[i].class == P_GLOBAL &&
1969 parm_table[i].ptr &&
1970 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1972 fprintf(f,"\t%s = ",parm_table[i].label);
1973 print_parameter(&parm_table[i],parm_table[i].ptr, f);
1978 /***************************************************************************
1979 Display the contents of a single services record.
1980 ***************************************************************************/
1981 static void dump_a_service(service *pService, FILE *f)
1984 if (pService == &sDefault)
1985 fprintf(f,"\n\n# Default service parameters\n");
1987 fprintf(f,"\n[%s]\n",pService->szService);
1989 for (i=0;parm_table[i].label;i++)
1990 if (parm_table[i].class == P_LOCAL &&
1991 parm_table[i].ptr &&
1992 (*parm_table[i].label != '-') &&
1993 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1995 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
1997 if (pService == &sDefault || !equal_parameter(parm_table[i].type,
1998 ((char *)pService) + pdiff,
1999 ((char *)&sDefault) + pdiff))
2001 fprintf(f,"\t%s = ",parm_table[i].label);
2002 print_parameter(&parm_table[i],
2003 ((char *)pService) + pdiff, f);
2010 /***************************************************************************
2011 return info about the next service in a service. snum==-1 gives the default
2012 serice and snum==-2 gives the globals
2014 return 0 when out of parameters
2015 ***************************************************************************/
2016 int lp_next_parameter(int snum, int *i, char *label,
2017 char *value, int allparameters)
2020 /* do the globals */
2021 for (;parm_table[*i].label;(*i)++)
2022 if (parm_table[*i].class == P_GLOBAL &&
2023 parm_table[*i].ptr &&
2024 (*parm_table[*i].label != '-') &&
2026 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2027 strcpy(label, parm_table[*i].label);
2028 parameter_string(&parm_table[*i],
2036 service *pService = (snum==-1?&sDefault:pSERVICE(snum));
2038 for (;parm_table[*i].label;(*i)++)
2039 if (parm_table[*i].class == P_LOCAL &&
2040 parm_table[*i].ptr &&
2041 (*parm_table[*i].label != '-') &&
2043 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2044 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2046 if (snum == -1 || allparameters ||
2047 !equal_parameter(parm_table[*i].type,
2048 ((char *)pService) + pdiff,
2049 ((char *)&sDefault) + pdiff)) {
2050 strcpy(label, parm_table[*i].label);
2051 parameter_string(&parm_table[*i],
2052 ((char *)pService) + pdiff,
2065 /***************************************************************************
2066 Display the contents of a single copy structure.
2067 ***************************************************************************/
2068 static void dump_copy_map(BOOL *pcopymap)
2071 if (!pcopymap) return;
2073 printf("\n\tNon-Copied parameters:\n");
2075 for (i=0;parm_table[i].label;i++)
2076 if (parm_table[i].class == P_LOCAL &&
2077 parm_table[i].ptr && !pcopymap[i] &&
2078 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2080 printf("\t\t%s\n",parm_table[i].label);
2085 /***************************************************************************
2086 Return TRUE if the passed service number is within range.
2087 ***************************************************************************/
2088 BOOL lp_snum_ok(int iService)
2090 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2094 /***************************************************************************
2095 auto-load some homes and printer services
2096 ***************************************************************************/
2097 static void lp_add_auto_services(char *str)
2101 int homes = lp_servicenumber(HOMES_NAME);
2102 int printers = lp_servicenumber(PRINTERS_NAME);
2110 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
2112 char *home = get_home_dir(p);
2114 if (lp_servicenumber(p) >= 0) continue;
2116 if (home && homes >= 0)
2118 lp_add_home(p,homes,home);
2122 if (printers >= 0 && pcap_printername_ok(p,NULL))
2123 lp_add_printer(p,printers);
2128 /***************************************************************************
2129 auto-load one printer
2130 ***************************************************************************/
2131 static void lp_add_one_printer(char *name,char *comment)
2133 int printers = lp_servicenumber(PRINTERS_NAME);
2136 if (lp_servicenumber(name) < 0)
2138 lp_add_printer(name,printers);
2139 if ((i=lp_servicenumber(name)) >= 0)
2140 string_set(&iSERVICE(i).comment,comment);
2145 /***************************************************************************
2146 auto-load printer services
2147 ***************************************************************************/
2148 static void lp_add_all_printers(void)
2150 int printers = lp_servicenumber(PRINTERS_NAME);
2152 if (printers < 0) return;
2154 pcap_printer_fn(lp_add_one_printer);
2157 /***************************************************************************
2158 have we loaded a services file yet?
2159 ***************************************************************************/
2160 BOOL lp_loaded(void)
2165 /***************************************************************************
2166 unload unused services
2167 ***************************************************************************/
2168 void lp_killunused(BOOL (*snumused)(int ))
2171 for (i=0;i<iNumServices;i++)
2172 if (VALID(i) && (!snumused || !snumused(i)))
2174 iSERVICE(i).valid = False;
2175 free_service(pSERVICE(i));
2179 /***************************************************************************
2180 Load the services array from the services file. Return True on success,
2182 ***************************************************************************/
2183 BOOL lp_load(char *pszFname,BOOL global_only)
2188 add_to_file_list(pszFname);
2192 bInGlobalSection = True;
2193 bGlobalOnly = global_only;
2197 pstrcpy(n2,pszFname);
2198 standard_sub_basic(n2);
2200 /* We get sections first, so have to start 'behind' to make up */
2202 bRetval = pm_process(n2, do_section, do_parameter);
2204 /* finish up the last section */
2205 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2207 if (iServiceIndex >= 0)
2208 bRetval = service_ok(iServiceIndex);
2210 lp_add_auto_services(lp_auto_services());
2211 if (lp_load_printers())
2212 lp_add_all_printers();
2216 set_default_server_announce_type();
2224 /***************************************************************************
2225 return the max number of services
2226 ***************************************************************************/
2227 int lp_numservices(void)
2229 return(iNumServices);
2232 /***************************************************************************
2233 Display the contents of the services array in human-readable form.
2234 ***************************************************************************/
2235 void lp_dump(FILE *f)
2241 dump_a_service(&sDefault, f);
2243 for (iService = 0; iService < iNumServices; iService++)
2245 if (VALID(iService))
2247 if (iSERVICE(iService).szService[0] == '\0')
2249 dump_a_service(pSERVICE(iService), f);
2255 /***************************************************************************
2256 Return the number of the service with the given name, or -1 if it doesn't
2257 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2258 getservicebyname()! This works ONLY if all services have been loaded, and
2259 does not copy the found service.
2260 ***************************************************************************/
2261 int lp_servicenumber(char *pszServiceName)
2265 for (iService = iNumServices - 1; iService >= 0; iService--)
2266 if (VALID(iService) &&
2267 strequal(lp_servicename(iService), pszServiceName))
2271 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2276 /*******************************************************************
2277 a useful volume label function
2278 ******************************************************************/
2279 char *volume_label(int snum)
2281 char *ret = lp_volume(snum);
2282 if (!*ret) return(lp_servicename(snum));
2288 * nmbd only loads the global section. There seems to be no way to
2289 * determine exactly is a service is printable by only looking at the
2290 * [global] section so for now always announce as a print server. This
2291 * will need looking at in the future. Jeremy (jallison@whistle.com).
2293 /*******************************************************************
2294 Return true if any printer services are defined.
2295 ******************************************************************/
2296 static BOOL lp_printer_services(void)
2300 for (iService = iNumServices - 1; iService >= 0; iService--)
2301 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2307 /*******************************************************************
2308 Set the server type we will announce as via nmbd.
2309 ********************************************************************/
2310 static void set_default_server_announce_type()
2312 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2313 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2314 if(lp_announce_as() == ANNOUNCE_AS_NT)
2315 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2316 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2317 default_server_announce |= SV_TYPE_WIN95_PLUS;
2318 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2319 default_server_announce |= SV_TYPE_WFW;
2320 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2322 * nmbd only loads the [global] section. There seems to be no way to
2323 * determine exactly if any service is printable by only looking at the
2324 * [global] section so for now always announce as a print server. This
2325 * will need looking at in the future. Jeremy (jallison@whistle.com).
2328 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2333 /*******************************************************************
2335 ********************************************************************/
2336 void lp_rename_service(int snum, char *new_name)
2338 string_set(&pSERVICE(snum)->szService, new_name);
2341 /*******************************************************************
2343 ********************************************************************/
2344 void lp_remove_service(int snum)
2346 pSERVICE(snum)->valid = False;
2349 /*******************************************************************
2351 ********************************************************************/
2352 void lp_copy_service(int snum, char *new_name)
2354 char *oldname = lp_servicename(snum);
2355 do_section(new_name);
2357 snum = lp_servicenumber(new_name);
2359 lp_do_parameter(snum, "copy", oldname);
2364 /*******************************************************************
2365 Get the default server type we will announce as via nmbd.
2366 ********************************************************************/
2367 int lp_default_server_announce(void)
2369 return default_server_announce;
2372 /*******************************************************************
2373 Split the announce version into major and minor numbers.
2374 ********************************************************************/
2375 int lp_major_announce_version(void)
2377 static BOOL got_major = False;
2378 static int major_version = DEFAULT_MAJOR_VERSION;
2383 return major_version;
2386 if((vers = lp_announce_version()) == NULL)
2387 return major_version;
2389 if((p = strchr(vers, '.')) == 0)
2390 return major_version;
2393 major_version = atoi(vers);
2394 return major_version;
2397 int lp_minor_announce_version(void)
2399 static BOOL got_minor = False;
2400 static int minor_version = DEFAULT_MINOR_VERSION;
2405 return minor_version;
2408 if((vers = lp_announce_version()) == NULL)
2409 return minor_version;
2411 if((p = strchr(vers, '.')) == 0)
2412 return minor_version;
2415 minor_version = atoi(p);
2416 return minor_version;