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. */
54 * We treat KANJI specially due to historical precedent (it was the
55 * first non-english codepage added to Samba). With the new dynamic
56 * codepage support this is not needed anymore.
58 * The define 'KANJI' is being overloaded to mean 'use kanji codepage
59 * by default' and also 'this is the filename-to-disk conversion
60 * method to use'. This really should be removed and all control
61 * over this left in the smb.conf parameters 'client codepage'
62 * and 'coding system'.
68 BOOL in_client = False; /* Not in the client by default */
71 extern int DEBUGLEVEL;
72 extern pstring user_socket_options;
73 extern pstring global_myname;
76 #define GLOBAL_NAME "global"
80 #define PRINTERS_NAME "printers"
84 #define HOMES_NAME "homes"
87 /* some helpful bits */
88 #define pSERVICE(i) ServicePtrs[i]
89 #define iSERVICE(i) (*pSERVICE(i))
90 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
91 #define VALID(i) iSERVICE(i).valid
93 int keepalive=DEFAULT_KEEPALIVE;
94 extern BOOL use_getwd_cache;
96 extern int extra_time_offset;
98 static BOOL defaults_saved=False;
101 * This structure describes global (ie., server-wide) parameters.
105 char *szPrintcapname;
108 char *szDefaultService;
112 char *szServerString;
113 char *szAutoServices;
114 char *szPasswdProgram;
118 char *szSMBPasswdFile;
119 char *szPasswordServer;
120 char *szSocketOptions;
123 char *szDomainAdminGroup;
124 char *szDomainGuestGroup;
125 char *szDomainAdminUsers;
126 char *szDomainGuestUsers;
127 char *szDomainHostsallow;
128 char *szDomainHostsdeny;
130 #ifdef USING_GROUPNAME_MAP
131 char *szGroupnameMap;
132 #endif /* USING_GROUPNAME_MAP */
133 char *szCharacterSet;
140 char *szCodingSystem;
142 char *szRemoteAnnounce;
143 char *szRemoteBrowseSync;
144 char *szSocketAddress;
145 char *szNISHomeMapName;
146 char *szAnnounceVersion; /* This is initialised in init_globals */
147 char *szNetbiosAliases;
149 char *szDomainOtherSIDs;
150 char *szDomainGroups;
152 char *szNameResolveOrder;
157 char *szLdapRootPassword;
180 int client_code_page;
181 int announce_as; /* This is initialised in init_globals */
182 int machine_password_timeout;
183 int change_notify_timeout;
187 #endif /* WITH_LDAP */
190 char *sslHostsRequire;
191 char *sslHostsResign;
197 char *sslClientPrivKey;
200 BOOL sslReqClientCert;
201 BOOL sslReqServerCert;
202 BOOL sslCompatibility;
203 #endif /* WITH_SSL */
208 BOOL bPreferredMaster;
209 BOOL bDomainController;
212 BOOL bEncryptPasswords;
220 BOOL bReadPrediction;
227 BOOL bBindInterfacesOnly;
228 BOOL bNetWkstaUserLogon;
229 BOOL bUnixPasswdSync;
230 BOOL bPasswdChatDebug;
231 BOOL bOleLockingCompat;
238 static global Globals;
243 * This structure describes a single service.
251 char *szGuestaccount;
252 char *szInvalidUsers;
260 char *szRootPostExec;
261 char *szPrintcommand;
264 char *szLppausecommand;
265 char *szLpresumecommand;
266 char *szQueuepausecommand;
267 char *szQueueresumecommand;
269 char *szPrinterDriver;
270 char *szPrinterDriverLocation;
279 char *szVetoOplockFiles;
289 int iCreate_force_mode;
299 BOOL bShortCasePreserve;
326 BOOL bDeleteReadonly;
328 BOOL bDeleteVetoFiles;
330 BOOL bDosFiletimeResolution;
331 BOOL bFakeDirCreateTimes;
333 char dummy[3]; /* for alignment */
337 /* This is a default service used to prime a services structure */
338 static service sDefault =
341 NULL, /* szService */
343 NULL, /* szUsername */
344 NULL, /* szGuestAccount - this is set in init_globals() */
345 NULL, /* szInvalidUsers */
346 NULL, /* szValidUsers */
347 NULL, /* szAdminUsers */
349 NULL, /* szInclude */
350 NULL, /* szPreExec */
351 NULL, /* szPostExec */
352 NULL, /* szRootPreExec */
353 NULL, /* szRootPostExec */
354 NULL, /* szPrintcommand */
355 NULL, /* szLpqcommand */
356 NULL, /* szLprmcommand */
357 NULL, /* szLppausecommand */
358 NULL, /* szLpresumecommand */
359 NULL, /* szQueuepausecommand */
360 NULL, /* szQueueresumecommand */
361 NULL, /* szPrintername */
362 NULL, /* szPrinterDriver - this is set in init_globals() */
363 NULL, /* szPrinterDriverLocation */
364 NULL, /* szDontdescend */
365 NULL, /* szHostsallow */
366 NULL, /* szHostsdeny */
367 NULL, /* szMagicScript */
368 NULL, /* szMagicOutput */
369 NULL, /* szMangledMap */
370 NULL, /* szVetoFiles */
371 NULL, /* szHideFiles */
372 NULL, /* szVetoOplockFiles */
374 NULL, /* force user */
375 NULL, /* force group */
377 NULL, /* writelist */
380 0, /* iMinPrintSpace */
381 0744, /* iCreate_mask */
382 0000, /* iCreate_force_mode */
383 0755, /* iDir_mask */
384 0000, /* iDir_force_mode */
385 0, /* iMaxConnections */
386 CASE_LOWER, /* iDefaultCase */
387 DEFAULT_PRINTING, /* iPrinting */
388 False, /* bAlternatePerm */
389 False, /* revalidate */
390 False, /* case sensitive */
391 True, /* case preserve */
392 True, /* short case preserve */
393 False, /* case mangle */
395 True, /* bHideDotFiles */
396 True, /* bBrowseable */
397 True, /* bAvailable */
398 True, /* bRead_only */
399 True, /* bNo_set_dir */
400 False, /* bGuest_only */
401 False, /* bGuest_ok */
402 False, /* bPrint_ok */
403 False, /* bPostscript */
404 False, /* bMap_system */
405 False, /* bMap_hidden */
406 True, /* bMap_archive */
408 False, /* bStrictLocking */
409 True, /* bShareModes */
411 False, /* bOnlyUser */
412 True, /* bMangledNames */
413 True, /* bWidelinks */
414 True, /* bSymlinks */
415 False, /* bSyncAlways */
416 False, /* bStrictSync */
417 '~', /* magic char */
419 False, /* bDeleteReadonly */
420 False, /* bFakeOplocks */
421 False, /* bDeleteVetoFiles */
422 False, /* bDosFiletimes */
423 False, /* bDosFiletimeResolution */
424 False, /* bFakeDirCreateTimes */
425 True, /* bBlockingLocks */
431 /* local variables */
432 static service **ServicePtrs = NULL;
433 static int iNumServices = 0;
434 static int iServiceIndex = 0;
435 static BOOL bInGlobalSection = True;
436 static BOOL bGlobalOnly = False;
437 static int default_server_announce;
439 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
441 /* prototypes for the special type handlers */
442 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
443 static BOOL handle_include(char *pszParmValue, char **ptr);
444 static BOOL handle_copy(char *pszParmValue, char **ptr);
445 static BOOL handle_character_set(char *pszParmValue,char **ptr);
446 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
448 static void set_default_server_announce_type(void);
450 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
451 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"},
452 {PROTOCOL_COREPLUS, "COREPLUS"},
453 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
455 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
456 {SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"},
459 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
460 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
461 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
462 {PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"},
465 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
466 {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
468 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
470 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
473 static struct enum_list enum_ssl_version[] = {{SMB_SSL_V2, "ssl2"}, {SMB_SSL_V3, "ssl3"},
474 {SMB_SSL_V23, "ssl2or3"}, {SMB_SSL_TLS1, "tls1"}, {-1, NULL}};
477 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
478 static struct parm_struct parm_table[] =
480 {"Base Options", P_SEP, P_SEPARATOR},
481 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
482 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
483 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
484 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
485 {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, NULL, NULL, FLAG_BASIC},
486 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
487 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC},
488 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
489 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0},
491 {"Security Options", P_SEP, P_SEPARATOR},
492 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
493 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
494 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC},
495 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
496 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
497 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
498 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
499 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
500 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
501 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
502 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
503 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0},
504 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
505 {"passwd chat debug",P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0},
506 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
507 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
508 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
509 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0},
510 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL|FLAG_DEPRECATED},
511 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL},
512 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL},
513 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
514 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
515 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
516 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL},
517 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL},
518 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL},
519 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL},
520 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL},
521 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, 0},
522 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
523 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
524 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC},
525 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
526 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
527 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
528 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
529 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
530 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL},
531 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
532 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
533 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL},
534 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
535 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
536 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
537 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
538 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, 0},
539 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
540 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
541 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
542 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
545 {"Secure Socket Layer Options", P_SEP, P_SEPARATOR},
546 {"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0 },
547 {"ssl hosts", P_STRING, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0 },
548 {"ssl hosts resign", P_STRING, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0} ,
549 {"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0 },
550 {"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0 },
551 {"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslCert, NULL, NULL, 0 },
552 {"ssl server key", P_STRING, P_GLOBAL, &Globals.sslPrivKey, NULL, NULL, 0 },
553 {"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0 },
554 {"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0 },
555 {"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL , 0},
556 {"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL , 0},
557 {"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0 },
558 {"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0},
559 {"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0 },
560 #endif /* WITH_SSL */
562 {"Logging Options", P_SEP, P_SEPARATOR},
563 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
564 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
565 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
566 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
567 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
568 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
569 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
570 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
571 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
573 {"Protocol Options", P_SEP, P_SEPARATOR},
574 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
575 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
576 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
577 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
578 {"networkstation user login", P_BOOL,P_GLOBAL, &Globals.bNetWkstaUserLogon,NULL, NULL, 0},
579 {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0},
580 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
581 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
582 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
583 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
584 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0},
585 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
586 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
587 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0},
588 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
589 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
590 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
592 {"Tuning Options", P_SEP, P_SEPARATOR},
593 {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0},
594 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
595 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
596 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
597 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
598 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0},
599 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
600 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0},
601 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0},
602 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
603 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0},
604 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
605 {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0},
606 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, 0},
607 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0},
609 {"Printing Options", P_SEP, P_SEPARATOR},
610 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0},
611 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
612 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
613 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, 0},
614 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
615 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
616 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
617 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL},
618 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
619 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
620 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
621 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_GLOBAL},
622 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_GLOBAL},
623 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_GLOBAL},
624 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_GLOBAL},
626 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
627 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
628 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
629 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_GLOBAL},
632 {"Filename Handling", P_SEP, P_SEPARATOR},
633 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
634 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
635 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
636 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
637 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0},
638 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, 0},
639 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_GLOBAL},
640 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
641 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_GLOBAL},
642 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_GLOBAL},
643 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_GLOBAL},
644 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_GLOBAL},
645 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_GLOBAL},
646 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_GLOBAL},
647 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_GLOBAL},
648 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_GLOBAL},
649 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_GLOBAL},
650 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_GLOBAL},
651 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_GLOBAL},
652 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_GLOBAL},
653 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_GLOBAL},
654 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_GLOBAL},
655 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0},
657 {"Domain Options", P_SEP, P_SEPARATOR},
658 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL, NULL, 0},
659 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
660 {"domain controller",P_BOOL , P_GLOBAL, &Globals.bDomainController,NULL, NULL, 0},
661 {"domain admin group",P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0},
662 {"domain guest group",P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0},
663 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0},
664 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0},
665 #ifdef USING_GROUPNAME_MAP
666 {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0},
667 #endif /* USING_GROUPNAME_MAP */
668 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0},
670 {"Logon Options", P_SEP, P_SEPARATOR},
671 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
672 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0},
673 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
674 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0},
675 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
677 {"Browse Options", P_SEP, P_SEPARATOR},
678 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC},
679 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0},
680 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
681 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, FLAG_BASIC},
682 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
683 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC},
684 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, FLAG_BASIC},
685 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
686 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
687 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
689 {"WINS Options", P_SEP, P_SEPARATOR},
690 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
691 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0},
692 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC},
693 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC},
695 {"Locking Options", P_SEP, P_SEPARATOR},
696 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, 0},
697 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
698 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
699 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_GLOBAL},
700 {"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, FLAG_GLOBAL},
701 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
702 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_GLOBAL},
703 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_GLOBAL},
706 {"Ldap Options", P_SEP, P_SEPARATOR},
707 {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
708 {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
709 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0},
710 {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0},
711 {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0},
712 {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword,NULL, NULL, 0},
713 #endif /* WITH_LDAP */
716 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
717 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
718 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
719 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
720 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
721 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
722 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
723 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
724 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
725 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
726 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
727 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
728 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0},
729 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL, 0},
730 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
731 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
732 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
733 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0},
734 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
735 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
736 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
737 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
738 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
739 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
740 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, 0},
741 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, 0},
742 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, 0},
743 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, 0},
744 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, 0},
745 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, 0},
746 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, 0},
747 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_GLOBAL},
748 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_GLOBAL},
749 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, 0},
750 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, 0},
751 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, 0},
752 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_GLOBAL},
753 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_GLOBAL},
754 {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_GLOBAL},
756 {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_GLOBAL},
757 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0},
759 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
764 /***************************************************************************
765 Initialise the global parameter structure.
766 ***************************************************************************/
767 static void init_globals(void)
769 static BOOL done_init = False;
775 bzero((void *)&Globals,sizeof(Globals));
777 for (i = 0; parm_table[i].label; i++)
778 if ((parm_table[i].type == P_STRING ||
779 parm_table[i].type == P_USTRING) &&
781 string_init(parm_table[i].ptr,"");
783 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
784 string_set(&sDefault.szPrinterDriver, "NULL");
785 string_set(&sDefault.fstype, FSTYPE_STRING);
791 DEBUG(3,("Initialising global parameters\n"));
793 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
794 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
795 string_set(&Globals.szWorkGroup, WORKGROUP);
796 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
797 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
798 string_set(&Globals.szDriverFile, DRIVERFILE);
799 string_set(&Globals.szLockDir, LOCKDIR);
800 string_set(&Globals.szRootdir, "/");
801 string_set(&Globals.szSmbrun, SMBRUN);
802 string_set(&Globals.szSocketAddress, "0.0.0.0");
803 pstrcpy(s, "Samba ");
805 string_set(&Globals.szServerString,s);
806 slprintf(s,sizeof(s)-1, "%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
807 string_set(&Globals.szAnnounceVersion,s);
809 string_set(&Globals.szLogonDrive, "");
810 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
811 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
812 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
814 string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast");
816 Globals.bLoadPrinters = True;
817 Globals.bUseRhosts = False;
818 Globals.max_packet = 65535;
819 Globals.mangled_stack = 50;
820 Globals.max_xmit = 65535;
821 Globals.max_mux = 50; /* This is *needed* for profile support. */
822 Globals.lpqcachetime = 10;
823 Globals.pwordlevel = 0;
824 Globals.unamelevel = 0;
825 Globals.deadtime = 0;
826 Globals.max_log_size = 5000;
827 Globals.maxprotocol = PROTOCOL_NT1;
828 Globals.security = SEC_USER;
829 Globals.bEncryptPasswords = False;
830 Globals.bUpdateEncrypt = False;
831 Globals.bReadRaw = True;
832 Globals.bWriteRaw = True;
833 Globals.bReadPrediction = False;
834 Globals.bReadbmpx = True;
835 Globals.bNullPasswords = False;
836 Globals.bStripDot = False;
838 Globals.bSyslogOnly = False;
839 Globals.bTimestampLogs = True;
840 Globals.os_level = 0;
841 Globals.max_ttl = 60*60*24*3; /* 3 days default. */
842 Globals.max_wins_ttl = 60*60*24*6; /* 6 days default. */
843 Globals.min_wins_ttl = 60*60*6; /* 6 hours default. */
844 Globals.machine_password_timeout = 60*60*24*7; /* 7 days default. */
845 Globals.change_notify_timeout = 60; /* 1 minute default. */
846 Globals.ReadSize = 16*1024;
847 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
848 Globals.lm_interval = 60;
849 Globals.shmem_size = SHMEM_SIZE;
850 Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */
851 Globals.announce_as = ANNOUNCE_AS_NT;
852 Globals.bUnixRealname = False;
853 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
854 Globals.bNISHomeMap = False;
855 #ifdef WITH_NISPLUS_HOME
856 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
858 string_set(&Globals.szNISHomeMapName, "auto.home");
861 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
862 Globals.bTimeServer = False;
863 Globals.bBindInterfacesOnly = False;
864 Globals.bNetWkstaUserLogon = False; /* This is now set to false by default as
865 the code in password.c protects us from this bug. */
866 Globals.bUnixPasswdSync = False;
867 Globals.bPasswdChatDebug = False;
868 Globals.bOleLockingCompat = True;
869 Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */
870 Globals.bStatCache = True; /* use stat cache by default */
873 /* default values for ldap */
874 string_set(&Globals.szLdapServer, "localhost");
875 Globals.ldap_port=389;
876 #endif /* WITH_LDAP */
879 Globals.sslVersion = SMB_SSL_V23;
880 Globals.sslHostsRequire = NULL;
881 Globals.sslHostsResign = NULL;
882 Globals.sslCaCertDir = NULL;
883 Globals.sslCaCertFile = NULL;
884 Globals.sslCert = NULL;
885 Globals.sslPrivKey = NULL;
886 Globals.sslClientCert = NULL;
887 Globals.sslClientPrivKey = NULL;
888 Globals.sslCiphers = NULL;
889 Globals.sslEnabled = False;
890 Globals.sslReqClientCert = False;
891 Globals.sslReqServerCert = False;
892 Globals.sslCompatibility = False;
893 #endif /* WITH_SSL */
895 /* these parameters are set to defaults that are more appropriate
896 for the increasing samba install base:
898 as a member of the workgroup, that will possibly become a
899 _local_ master browser (lm = True). this is opposed to a forced
900 local master browser startup (pm = True).
902 doesn't provide WINS server service by default (wsupp = False),
903 and doesn't provide domain master browser services by default, either.
907 Globals.bPreferredMaster = False;
908 Globals.bLocalMaster = True;
909 Globals.bDomainMaster = False;
910 Globals.bDomainLogons = False;
911 Globals.bBrowseList = True;
912 Globals.bWINSsupport = False;
913 Globals.bWINSproxy = False;
915 Globals.bDNSproxy = True;
918 * smbd will check after starting to see if this value
919 * should be set to "true" or not.
921 lp_set_kernel_oplocks(False);
924 * This must be done last as it checks the value in
928 interpret_coding_system(KANJI);
931 /***************************************************************************
932 check if a string is initialised and if not then initialise it
933 ***************************************************************************/
934 static void string_initial(char **s,char *v)
941 /***************************************************************************
942 Initialise the sDefault parameter structure.
943 ***************************************************************************/
944 static void init_locals(void)
946 /* choose defaults depending on the type of printing */
947 switch (sDefault.iPrinting)
953 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
954 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
955 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
960 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
961 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
962 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
964 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
965 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
966 string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
967 string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
969 string_initial(&sDefault.szQueuepausecommand, "disable %p");
970 string_initial(&sDefault.szQueueresumecommand, "enable %p");
975 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
976 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
977 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
981 string_initial(&sDefault.szLpqcommand,"qstat -l -d%p");
982 string_initial(&sDefault.szLprmcommand,"qstat -s -j%j -c");
983 string_initial(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
984 string_initial(&sDefault.szLppausecommand,"qstat -s -j%j -h");
985 string_initial(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
992 /******************************************************************* a
993 convenience routine to grab string parameters into a rotating buffer,
994 and run standard_sub_basic on them. The buffers can be written to by
995 callers without affecting the source string.
996 ********************************************************************/
997 static char *lp_string(char *s)
999 static char *bufs[10];
1000 static int buflen[10];
1001 static int next = -1;
1004 int len = s?strlen(s):0;
1007 /* initialisation */
1008 for (i=0;i<10;i++) {
1015 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
1016 substitution room */
1018 if (buflen[next] != len) {
1020 if (bufs[next]) free(bufs[next]);
1021 bufs[next] = (char *)malloc(len);
1023 DEBUG(0,("out of memory in lp_string()"));
1028 ret = &bufs[next][0];
1036 trim_string(ret, "\"", "\"");
1038 standard_sub_basic(ret);
1044 In this section all the functions that are used to access the
1045 parameters from the rest of the program are defined
1048 #define FN_GLOBAL_STRING(fn_name,ptr) \
1049 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1050 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1051 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1052 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1053 char fn_name(void) {return(*(char *)(ptr));}
1054 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1055 int fn_name(void) {return(*(int *)(ptr));}
1057 #define FN_LOCAL_STRING(fn_name,val) \
1058 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
1059 #define FN_LOCAL_BOOL(fn_name,val) \
1060 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1061 #define FN_LOCAL_CHAR(fn_name,val) \
1062 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1063 #define FN_LOCAL_INTEGER(fn_name,val) \
1064 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1066 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
1067 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
1068 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
1069 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
1070 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
1071 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
1072 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
1073 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
1074 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
1075 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
1076 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
1077 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
1078 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
1079 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
1080 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
1081 FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder)
1082 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
1083 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
1084 #ifdef USING_GROUPNAME_MAP
1085 FN_GLOBAL_STRING(lp_groupname_map,&Globals.szGroupnameMap)
1086 #endif /* USING_GROUPNAME_MAP */
1087 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
1088 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
1089 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
1090 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
1091 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
1092 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
1093 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
1094 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
1095 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
1096 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
1097 static FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
1098 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
1099 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
1100 FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction)
1102 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
1103 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
1104 FN_GLOBAL_STRING(lp_domain_admin_group,&Globals.szDomainAdminGroup)
1105 FN_GLOBAL_STRING(lp_domain_guest_group,&Globals.szDomainGuestGroup)
1106 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
1107 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
1110 FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer);
1111 FN_GLOBAL_STRING(lp_ldap_suffix,&Globals.szLdapSuffix);
1112 FN_GLOBAL_STRING(lp_ldap_filter,&Globals.szLdapFilter);
1113 FN_GLOBAL_STRING(lp_ldap_root,&Globals.szLdapRoot);
1114 FN_GLOBAL_STRING(lp_ldap_rootpasswd,&Globals.szLdapRootPassword);
1115 #endif /* WITH_LDAP */
1118 FN_GLOBAL_INTEGER(lp_ssl_version,&Globals.sslVersion);
1119 FN_GLOBAL_STRING(lp_ssl_hosts,&Globals.sslHostsRequire);
1120 FN_GLOBAL_STRING(lp_ssl_hosts_resign,&Globals.sslHostsResign);
1121 FN_GLOBAL_STRING(lp_ssl_cacertdir,&Globals.sslCaCertDir);
1122 FN_GLOBAL_STRING(lp_ssl_cacertfile,&Globals.sslCaCertFile);
1123 FN_GLOBAL_STRING(lp_ssl_cert,&Globals.sslCert);
1124 FN_GLOBAL_STRING(lp_ssl_privkey,&Globals.sslPrivKey);
1125 FN_GLOBAL_STRING(lp_ssl_client_cert,&Globals.sslClientCert);
1126 FN_GLOBAL_STRING(lp_ssl_client_privkey,&Globals.sslClientPrivKey);
1127 FN_GLOBAL_STRING(lp_ssl_ciphers,&Globals.sslCiphers);
1128 FN_GLOBAL_BOOL(lp_ssl_enabled,&Globals.sslEnabled);
1129 FN_GLOBAL_BOOL(lp_ssl_reqClientCert,&Globals.sslReqClientCert);
1130 FN_GLOBAL_BOOL(lp_ssl_reqServerCert,&Globals.sslReqServerCert);
1131 FN_GLOBAL_BOOL(lp_ssl_compatibility,&Globals.sslCompatibility);
1132 #endif /* WITH_SSL */
1134 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
1135 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
1136 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
1137 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
1138 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
1139 FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController)
1140 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
1141 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
1142 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
1143 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
1144 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
1145 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
1146 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
1147 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
1148 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
1149 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
1150 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
1151 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
1152 FN_GLOBAL_BOOL(lp_update_encrypted,&Globals.bUpdateEncrypt)
1153 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
1154 FN_GLOBAL_BOOL(lp_timestamp_logs,&Globals.bTimestampLogs)
1155 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
1156 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
1157 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
1158 static FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
1159 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
1160 FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
1161 FN_GLOBAL_BOOL(lp_unix_password_sync,&Globals.bUnixPasswdSync)
1162 FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug)
1163 FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat)
1164 FN_GLOBAL_BOOL(lp_nt_smb_support,&Globals.bNTSmbSupport)
1165 FN_GLOBAL_BOOL(lp_stat_cache,&Globals.bStatCache)
1166 FN_GLOBAL_BOOL(lp_kernel_oplocks,&Globals.bKernelOplocks)
1168 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
1169 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
1170 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
1171 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
1172 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
1173 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
1174 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
1175 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
1176 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
1177 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
1178 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
1179 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
1180 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
1181 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
1182 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
1183 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
1184 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
1185 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
1186 static FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
1187 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
1188 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
1189 FN_GLOBAL_INTEGER(lp_machine_password_timeout,&Globals.machine_password_timeout)
1190 FN_GLOBAL_INTEGER(lp_change_notify_timeout,&Globals.change_notify_timeout)
1191 FN_GLOBAL_INTEGER(lp_stat_cache_size,&Globals.stat_cache_size)
1194 FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port)
1195 #endif /* WITH_LDAP */
1197 FN_LOCAL_STRING(lp_preexec,szPreExec)
1198 FN_LOCAL_STRING(lp_postexec,szPostExec)
1199 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
1200 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
1201 FN_LOCAL_STRING(lp_servicename,szService)
1202 FN_LOCAL_STRING(lp_pathname,szPath)
1203 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
1204 FN_LOCAL_STRING(lp_username,szUsername)
1205 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
1206 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
1207 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
1208 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
1209 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
1210 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
1211 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
1212 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
1213 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
1214 FN_LOCAL_STRING(lp_queuepausecommand,szQueuepausecommand)
1215 FN_LOCAL_STRING(lp_queueresumecommand,szQueueresumecommand)
1216 FN_LOCAL_STRING(lp_printername,szPrintername)
1217 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
1218 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
1219 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
1220 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
1221 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
1222 FN_LOCAL_STRING(lp_comment,comment)
1223 FN_LOCAL_STRING(lp_force_user,force_user)
1224 FN_LOCAL_STRING(lp_force_group,force_group)
1225 FN_LOCAL_STRING(lp_readlist,readlist)
1226 FN_LOCAL_STRING(lp_writelist,writelist)
1227 FN_LOCAL_STRING(lp_fstype,fstype)
1228 static FN_LOCAL_STRING(lp_volume,volume)
1229 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
1230 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
1231 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
1232 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
1233 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
1235 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
1236 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
1237 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1238 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1239 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1240 FN_LOCAL_BOOL(lp_status,status)
1241 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1242 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1243 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1244 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1245 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1246 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1247 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1248 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1249 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1250 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1251 FN_LOCAL_BOOL(lp_locking,bLocking)
1252 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1253 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1254 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1255 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1256 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1257 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1258 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1259 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1260 FN_LOCAL_BOOL(lp_strict_sync,bStrictSync)
1261 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1262 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1263 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1264 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1265 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1266 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
1267 FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
1268 FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks)
1270 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1271 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1272 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1273 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1274 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1275 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1276 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1277 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1279 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1283 /* local prototypes */
1284 static int strwicmp( char *psz1, char *psz2 );
1285 static int map_parameter( char *pszParmName);
1286 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1287 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1288 static void copy_service( service *pserviceDest,
1289 service *pserviceSource,
1290 BOOL *pcopymapDest );
1291 static BOOL service_ok(int iService);
1292 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1293 static BOOL do_section(char *pszSectionName);
1294 static void init_copymap(service *pservice);
1297 /***************************************************************************
1298 initialise a service to the defaults
1299 ***************************************************************************/
1300 static void init_service(service *pservice)
1302 bzero((char *)pservice,sizeof(service));
1303 copy_service(pservice,&sDefault,NULL);
1307 /***************************************************************************
1308 free the dynamically allocated parts of a service struct
1309 ***************************************************************************/
1310 static void free_service(service *pservice)
1316 if(pservice->szService)
1317 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1319 string_free(&pservice->szService);
1320 if (pservice->copymap)
1322 free(pservice->copymap);
1323 pservice->copymap = NULL;
1326 for (i=0;parm_table[i].label;i++)
1327 if ((parm_table[i].type == P_STRING ||
1328 parm_table[i].type == P_USTRING) &&
1329 parm_table[i].class == P_LOCAL)
1330 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1333 /***************************************************************************
1334 add a new service to the services array initialising it with the given
1336 ***************************************************************************/
1337 static int add_a_service(service *pservice, char *name)
1341 int num_to_alloc = iNumServices+1;
1343 tservice = *pservice;
1345 /* it might already exist */
1348 i = getservicebyname(name,NULL);
1353 /* find an invalid one */
1354 for (i=0;i<iNumServices;i++)
1355 if (!pSERVICE(i)->valid)
1358 /* if not, then create one */
1359 if (i == iNumServices)
1361 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1363 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1365 if (!ServicePtrs || !pSERVICE(iNumServices))
1371 free_service(pSERVICE(i));
1373 pSERVICE(i)->valid = True;
1375 init_service(pSERVICE(i));
1376 copy_service(pSERVICE(i),&tservice,NULL);
1378 string_set(&iSERVICE(i).szService,name);
1383 /***************************************************************************
1384 add a new home service, with the specified home directory, defaults coming
1386 ***************************************************************************/
1387 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1389 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1394 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1395 string_set(&iSERVICE(i).szPath,pszHomedir);
1396 if (!(*(iSERVICE(i).comment)))
1399 slprintf(comment,sizeof(comment)-1,
1400 "Home directory of %s",pszHomename);
1401 string_set(&iSERVICE(i).comment,comment);
1403 iSERVICE(i).bAvailable = sDefault.bAvailable;
1404 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1406 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1411 /***************************************************************************
1412 add a new service, based on an old one
1413 ***************************************************************************/
1414 int lp_add_service(char *pszService, int iDefaultService)
1416 return(add_a_service(pSERVICE(iDefaultService),pszService));
1420 /***************************************************************************
1422 ***************************************************************************/
1423 static BOOL lp_add_ipc(void)
1426 int i = add_a_service(&sDefault,"IPC$");
1431 slprintf(comment,sizeof(comment)-1,
1432 "IPC Service (%s)", Globals.szServerString );
1434 string_set(&iSERVICE(i).szPath,tmpdir());
1435 string_set(&iSERVICE(i).szUsername,"");
1436 string_set(&iSERVICE(i).comment,comment);
1437 iSERVICE(i).status = False;
1438 iSERVICE(i).iMaxConnections = 0;
1439 iSERVICE(i).bAvailable = True;
1440 iSERVICE(i).bRead_only = True;
1441 iSERVICE(i).bGuest_only = False;
1442 iSERVICE(i).bGuest_ok = True;
1443 iSERVICE(i).bPrint_ok = False;
1444 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1446 DEBUG(3,("adding IPC service\n"));
1452 /***************************************************************************
1453 add a new printer service, with defaults coming from service iFrom
1454 ***************************************************************************/
1455 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1457 char *comment = "From Printcap";
1458 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1463 /* note that we do NOT default the availability flag to True - */
1464 /* we take it from the default service passed. This allows all */
1465 /* dynamic printers to be disabled by disabling the [printers] */
1466 /* entry (if/when the 'available' keyword is implemented!). */
1468 /* the printer name is set to the service name. */
1469 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1470 string_set(&iSERVICE(i).comment,comment);
1471 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1472 /* Printers cannot be read_only. */
1473 iSERVICE(i).bRead_only = False;
1474 /* No share modes on printer services. */
1475 iSERVICE(i).bShareModes = False;
1476 /* No oplocks on printer services. */
1477 iSERVICE(i).bOpLocks = False;
1478 /* Printer services must be printable. */
1479 iSERVICE(i).bPrint_ok = True;
1481 DEBUG(3,("adding printer service %s\n",pszPrintername));
1487 /***************************************************************************
1488 Do a case-insensitive, whitespace-ignoring string compare.
1489 ***************************************************************************/
1490 static int strwicmp(char *psz1, char *psz2)
1492 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1493 /* appropriate value. */
1503 /* sync the strings on first non-whitespace */
1506 while (isspace(*psz1))
1508 while (isspace(*psz2))
1510 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1515 return (*psz1 - *psz2);
1518 /***************************************************************************
1519 Map a parameter's string representation to something we can use.
1520 Returns False if the parameter string is not recognised, else TRUE.
1521 ***************************************************************************/
1522 static int map_parameter(char *pszParmName)
1526 if (*pszParmName == '-')
1529 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1530 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1533 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1538 /***************************************************************************
1539 Set a boolean variable from the text value stored in the passed string.
1540 Returns True in success, False if the passed string does not correctly
1541 represent a boolean.
1542 ***************************************************************************/
1543 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1548 if (strwicmp(pszParmValue, "yes") == 0 ||
1549 strwicmp(pszParmValue, "true") == 0 ||
1550 strwicmp(pszParmValue, "1") == 0)
1553 if (strwicmp(pszParmValue, "no") == 0 ||
1554 strwicmp(pszParmValue, "False") == 0 ||
1555 strwicmp(pszParmValue, "0") == 0)
1559 DEBUG(0,("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1566 /***************************************************************************
1567 Find a service by name. Otherwise works like get_service.
1568 ***************************************************************************/
1569 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1573 for (iService = iNumServices - 1; iService >= 0; iService--)
1574 if (VALID(iService) &&
1575 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1577 if (pserviceDest != NULL)
1578 copy_service(pserviceDest, pSERVICE(iService), NULL);
1587 /***************************************************************************
1588 Copy a service structure to another
1590 If pcopymapDest is NULL then copy all fields
1591 ***************************************************************************/
1592 static void copy_service(service *pserviceDest,
1593 service *pserviceSource,
1597 BOOL bcopyall = (pcopymapDest == NULL);
1599 for (i=0;parm_table[i].label;i++)
1600 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1601 (bcopyall || pcopymapDest[i]))
1603 void *def_ptr = parm_table[i].ptr;
1605 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1607 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1609 switch (parm_table[i].type)
1613 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1619 *(int *)dest_ptr = *(int *)src_ptr;
1623 *(char *)dest_ptr = *(char *)src_ptr;
1627 string_set(dest_ptr,*(char **)src_ptr);
1631 string_set(dest_ptr,*(char **)src_ptr);
1632 strupper(*(char **)dest_ptr);
1641 init_copymap(pserviceDest);
1642 if (pserviceSource->copymap)
1643 memcpy((void *)pserviceDest->copymap,
1644 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1648 /***************************************************************************
1649 Check a service for consistency. Return False if the service is in any way
1650 incomplete or faulty, else True.
1651 ***************************************************************************/
1652 static BOOL service_ok(int iService)
1657 if (iSERVICE(iService).szService[0] == '\0')
1659 DEBUG(0,( "The following message indicates an internal error:\n"));
1660 DEBUG(0,( "No service name in service entry.\n"));
1664 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1665 /* I can't see why you'd want a non-printable printer service... */
1666 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1667 if (!iSERVICE(iService).bPrint_ok)
1669 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1670 iSERVICE(iService).szService));
1671 iSERVICE(iService).bPrint_ok = True;
1674 if (iSERVICE(iService).szPath[0] == '\0' &&
1675 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1677 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1678 string_set(&iSERVICE(iService).szPath,tmpdir());
1681 /* If a service is flagged unavailable, log the fact at level 0. */
1682 if (!iSERVICE(iService).bAvailable)
1683 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1684 iSERVICE(iService).szService));
1689 static struct file_lists {
1690 struct file_lists *next;
1693 } *file_lists = NULL;
1695 /*******************************************************************
1696 keep a linked list of all config files so we know when one has changed
1697 it's date and needs to be reloaded
1698 ********************************************************************/
1699 static void add_to_file_list(char *fname)
1701 struct file_lists *f=file_lists;
1704 if (f->name && !strcmp(f->name,fname)) break;
1709 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1711 f->next = file_lists;
1712 f->name = strdup(fname);
1723 standard_sub_basic(n2);
1724 f->modtime = file_modtime(n2);
1729 /*******************************************************************
1730 check if a config file has changed date
1731 ********************************************************************/
1732 BOOL lp_file_list_changed(void)
1734 struct file_lists *f = file_lists;
1735 DEBUG(6,("lp_file_list_changed()\n"));
1742 pstrcpy(n2,f->name);
1743 standard_sub_basic(n2);
1745 DEBUGADD( 6, ( "file %s -> %s last mod_time: %s\n",
1746 f->name, n2, ctime(&f->modtime) ) );
1748 mod_time = file_modtime(n2);
1750 if (f->modtime != mod_time) {
1751 DEBUGADD(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1752 f->modtime = mod_time;
1760 /***************************************************************************
1761 handle the interpretation of the coding system parameter
1762 *************************************************************************/
1763 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1765 string_set(ptr,pszParmValue);
1766 interpret_coding_system(pszParmValue);
1770 /***************************************************************************
1771 handle the interpretation of the character set system parameter
1772 ***************************************************************************/
1773 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1775 string_set(ptr,pszParmValue);
1776 interpret_character_set(pszParmValue);
1781 /***************************************************************************
1782 handle the valid chars lines
1783 ***************************************************************************/
1784 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1786 string_set(ptr,pszParmValue);
1788 /* A dependency here is that the parameter client code page must be
1789 set before this is called - as calling codepage_initialise()
1790 would overwrite the valid char lines.
1792 codepage_initialise(lp_client_code_page());
1794 add_char_string(pszParmValue);
1799 /***************************************************************************
1800 handle the include operation
1801 ***************************************************************************/
1802 static BOOL handle_include(char *pszParmValue,char **ptr)
1805 pstrcpy(fname,pszParmValue);
1807 add_to_file_list(fname);
1809 standard_sub_basic(fname);
1811 string_set(ptr,fname);
1813 if (file_exist(fname,NULL))
1814 return(pm_process(fname, do_section, do_parameter));
1816 DEBUG(2,("Can't find include file %s\n",fname));
1822 /***************************************************************************
1823 handle the interpretation of the copy parameter
1824 ***************************************************************************/
1825 static BOOL handle_copy(char *pszParmValue,char **ptr)
1829 service serviceTemp;
1831 string_set(ptr,pszParmValue);
1833 init_service(&serviceTemp);
1837 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1839 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1841 if (iTemp == iServiceIndex)
1843 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1848 copy_service(pSERVICE(iServiceIndex),
1850 iSERVICE(iServiceIndex).copymap);
1856 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1861 free_service(&serviceTemp);
1866 /***************************************************************************
1867 initialise a copymap
1868 ***************************************************************************/
1869 static void init_copymap(service *pservice)
1872 if (pservice->copymap) free(pservice->copymap);
1873 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1874 if (!pservice->copymap)
1875 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1877 for (i=0;i<NUMPARAMETERS;i++)
1878 pservice->copymap[i] = True;
1882 /***************************************************************************
1883 return the local pointer to a parameter given the service number and the
1884 pointer into the default structure
1885 ***************************************************************************/
1886 void *lp_local_ptr(int snum, void *ptr)
1888 return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
1891 /***************************************************************************
1892 Process a parameter for a particular service number. If snum < 0
1893 then assume we are in the globals
1894 ***************************************************************************/
1895 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1898 void *parm_ptr=NULL; /* where we are going to store the result */
1901 parmnum = map_parameter(pszParmName);
1905 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1909 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1910 DEBUG(1,("WARNING: The \"%s\"option is deprecated\n",
1914 def_ptr = parm_table[parmnum].ptr;
1916 /* we might point at a service, the default service or a global */
1920 if (parm_table[parmnum].class == P_GLOBAL) {
1921 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1924 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1928 if (!iSERVICE(snum).copymap)
1929 init_copymap(pSERVICE(snum));
1931 /* this handles the aliases - set the copymap for other entries with
1932 the same data pointer */
1933 for (i=0;parm_table[i].label;i++)
1934 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1935 iSERVICE(snum).copymap[i] = False;
1938 /* if it is a special case then go ahead */
1939 if (parm_table[parmnum].special) {
1940 parm_table[parmnum].special(pszParmValue,(char **)parm_ptr);
1944 /* now switch on the type of variable it is */
1945 switch (parm_table[parmnum].type)
1948 set_boolean(parm_ptr,pszParmValue);
1952 set_boolean(parm_ptr,pszParmValue);
1953 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1957 *(int *)parm_ptr = atoi(pszParmValue);
1961 *(char *)parm_ptr = *pszParmValue;
1965 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1969 string_set(parm_ptr,pszParmValue);
1973 string_set(parm_ptr,pszParmValue);
1974 strupper(*(char **)parm_ptr);
1978 pstrcpy((char *)parm_ptr,pszParmValue);
1982 pstrcpy((char *)parm_ptr,pszParmValue);
1983 strupper((char *)parm_ptr);
1987 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1988 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1989 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
2001 /***************************************************************************
2002 Process a parameter.
2003 ***************************************************************************/
2004 static BOOL do_parameter( char *pszParmName, char *pszParmValue )
2006 if( !bInGlobalSection && bGlobalOnly )
2009 DEBUGADD( 3, ( "doing parameter %s = %s\n", pszParmName, pszParmValue ) );
2011 return( lp_do_parameter( bInGlobalSection ? -2 : iServiceIndex,
2017 /***************************************************************************
2018 print a parameter of the specified type
2019 ***************************************************************************/
2020 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
2025 for (i=0;p->enum_list[i].name;i++) {
2026 if (*(int *)ptr == p->enum_list[i].value) {
2027 fprintf(f,"%s",p->enum_list[i].name);
2034 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
2038 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
2042 fprintf(f,"%d",*(int *)ptr);
2046 fprintf(f,"%c",*(char *)ptr);
2050 fprintf(f,"0%o",*(int *)ptr);
2056 fprintf(f,"%s",(char *)ptr);
2062 fprintf(f,"%s",*(char **)ptr);
2070 /***************************************************************************
2071 check if two parameters are equal
2072 ***************************************************************************/
2073 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
2079 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
2084 return(*((int *)ptr1) == *((int *)ptr2));
2087 return(*((char *)ptr1) == *((char *)ptr2));
2092 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
2093 if (p1 && !*p1) p1 = NULL;
2094 if (p2 && !*p2) p2 = NULL;
2095 return(p1==p2 || strequal(p1,p2));
2100 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2101 if (p1 && !*p1) p1 = NULL;
2102 if (p2 && !*p2) p2 = NULL;
2103 return(p1==p2 || strequal(p1,p2));
2111 /***************************************************************************
2112 Process a new section (service). At this stage all sections are services.
2113 Later we'll have special sections that permit server parameters to be set.
2114 Returns True on success, False on failure.
2115 ***************************************************************************/
2116 static BOOL do_section(char *pszSectionName)
2119 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2120 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2123 /* if we were in a global section then do the local inits */
2124 if (bInGlobalSection && !isglobal)
2127 /* if we've just struck a global section, note the fact. */
2128 bInGlobalSection = isglobal;
2130 /* check for multiple global sections */
2131 if (bInGlobalSection)
2133 DEBUG( 3, ( "Processing section \"[%s]\"\n", pszSectionName ) );
2137 if (!bInGlobalSection && bGlobalOnly) return(True);
2139 /* if we have a current service, tidy it up before moving on */
2142 if (iServiceIndex >= 0)
2143 bRetval = service_ok(iServiceIndex);
2145 /* if all is still well, move to the next record in the services array */
2148 /* We put this here to avoid an odd message order if messages are */
2149 /* issued by the post-processing of a previous section. */
2150 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
2152 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
2154 DEBUG(0,("Failed to add a new service\n"));
2163 /***************************************************************************
2164 determine if a partcular base parameter is currently set to the default value.
2165 ***************************************************************************/
2166 static BOOL is_default(int i)
2168 if (!defaults_saved) return False;
2169 switch (parm_table[i].type) {
2172 return strequal(parm_table[i].def.svalue,*(char **)parm_table[i].ptr);
2175 return strequal(parm_table[i].def.svalue,(char *)parm_table[i].ptr);
2178 return parm_table[i].def.bvalue == *(BOOL *)parm_table[i].ptr;
2180 return parm_table[i].def.cvalue == *(char *)parm_table[i].ptr;
2184 return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
2192 /***************************************************************************
2193 Display the contents of the global structure.
2194 ***************************************************************************/
2195 static void dump_globals(FILE *f)
2198 fprintf(f, "# Global parameters\n");
2200 for (i=0;parm_table[i].label;i++)
2201 if (parm_table[i].class == P_GLOBAL &&
2202 parm_table[i].ptr &&
2203 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2204 if (defaults_saved && is_default(i)) continue;
2205 fprintf(f,"\t%s = ",parm_table[i].label);
2206 print_parameter(&parm_table[i],parm_table[i].ptr, f);
2211 /***************************************************************************
2212 return True if a local parameter is currently set to the global default
2213 ***************************************************************************/
2214 BOOL lp_is_default(int snum, struct parm_struct *parm)
2216 int pdiff = PTR_DIFF(parm->ptr,&sDefault);
2218 return equal_parameter(parm->type,
2219 ((char *)pSERVICE(snum)) + pdiff,
2220 ((char *)&sDefault) + pdiff);
2224 /***************************************************************************
2225 Display the contents of a single services record.
2226 ***************************************************************************/
2227 static void dump_a_service(service *pService, FILE *f)
2230 if (pService != &sDefault)
2231 fprintf(f,"\n[%s]\n",pService->szService);
2233 for (i=0;parm_table[i].label;i++)
2234 if (parm_table[i].class == P_LOCAL &&
2235 parm_table[i].ptr &&
2236 (*parm_table[i].label != '-') &&
2237 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2238 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
2240 if (pService == &sDefault) {
2241 if (defaults_saved && is_default(i)) continue;
2243 if (equal_parameter(parm_table[i].type,
2244 ((char *)pService) + pdiff,
2245 ((char *)&sDefault) + pdiff))
2249 fprintf(f,"\t%s = ",parm_table[i].label);
2250 print_parameter(&parm_table[i],
2251 ((char *)pService) + pdiff, f);
2257 /***************************************************************************
2258 return info about the next service in a service. snum==-1 gives the globals
2260 return NULL when out of parameters
2261 ***************************************************************************/
2262 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2265 /* do the globals */
2266 for (;parm_table[*i].label;(*i)++) {
2267 if (parm_table[*i].class == P_SEPARATOR)
2268 return &parm_table[(*i)++];
2270 if (!parm_table[*i].ptr || (*parm_table[*i].label == '-'))
2273 if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr))
2276 return &parm_table[(*i)++];
2279 service *pService = pSERVICE(snum);
2281 for (;parm_table[*i].label;(*i)++) {
2282 if (parm_table[*i].class == P_SEPARATOR)
2283 return &parm_table[(*i)++];
2285 if (parm_table[*i].class == P_LOCAL &&
2286 parm_table[*i].ptr &&
2287 (*parm_table[*i].label != '-') &&
2289 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2290 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2292 if (allparameters ||
2293 !equal_parameter(parm_table[*i].type,
2294 ((char *)pService) + pdiff,
2295 ((char *)&sDefault) + pdiff)) {
2296 return &parm_table[(*i)++];
2307 /***************************************************************************
2308 Display the contents of a single copy structure.
2309 ***************************************************************************/
2310 static void dump_copy_map(BOOL *pcopymap)
2313 if (!pcopymap) return;
2315 printf("\n\tNon-Copied parameters:\n");
2317 for (i=0;parm_table[i].label;i++)
2318 if (parm_table[i].class == P_LOCAL &&
2319 parm_table[i].ptr && !pcopymap[i] &&
2320 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2322 printf("\t\t%s\n",parm_table[i].label);
2327 /***************************************************************************
2328 Return TRUE if the passed service number is within range.
2329 ***************************************************************************/
2330 BOOL lp_snum_ok(int iService)
2332 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2336 /***************************************************************************
2337 auto-load some home services
2338 ***************************************************************************/
2339 static void lp_add_auto_services(char *str)
2350 homes = lp_servicenumber(HOMES_NAME);
2352 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
2353 char *home = get_home_dir(p);
2355 if (lp_servicenumber(p) >= 0) continue;
2357 if (home && homes >= 0) {
2358 lp_add_home(p,homes,home);
2364 /***************************************************************************
2365 auto-load one printer
2366 ***************************************************************************/
2367 void lp_add_one_printer(char *name,char *comment)
2369 int printers = lp_servicenumber(PRINTERS_NAME);
2372 if (lp_servicenumber(name) < 0) {
2373 lp_add_printer(name,printers);
2374 if ((i=lp_servicenumber(name)) >= 0)
2375 string_set(&iSERVICE(i).comment,comment);
2379 /***************************************************************************
2380 have we loaded a services file yet?
2381 ***************************************************************************/
2382 BOOL lp_loaded(void)
2387 /***************************************************************************
2388 unload unused services
2389 ***************************************************************************/
2390 void lp_killunused(BOOL (*snumused)(int ))
2393 for (i=0;i<iNumServices;i++)
2394 if (VALID(i) && (!snumused || !snumused(i)))
2396 iSERVICE(i).valid = False;
2397 free_service(pSERVICE(i));
2402 /***************************************************************************
2403 save the curent values of all global and sDefault parameters into the
2404 defaults union. This allows swat and testparm to show only the
2405 changed (ie. non-default) parameters.
2406 ***************************************************************************/
2407 static void lp_save_defaults(void)
2410 for (i = 0; parm_table[i].label; i++) {
2411 if (i>0 && parm_table[i].ptr == parm_table[i-1].ptr) continue;
2412 switch (parm_table[i].type) {
2415 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2419 parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
2423 parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr;
2426 parm_table[i].def.cvalue = *(char *)parm_table[i].ptr;
2431 parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
2437 defaults_saved = True;
2441 /***************************************************************************
2442 Load the services array from the services file. Return True on success,
2444 ***************************************************************************/
2445 BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
2450 add_to_file_list(pszFname);
2454 bInGlobalSection = True;
2455 bGlobalOnly = global_only;
2459 if (save_defaults) {
2464 pstrcpy(n2,pszFname);
2465 standard_sub_basic(n2);
2467 /* We get sections first, so have to start 'behind' to make up */
2469 bRetval = pm_process(n2, do_section, do_parameter);
2471 /* finish up the last section */
2472 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2474 if (iServiceIndex >= 0)
2475 bRetval = service_ok(iServiceIndex);
2477 lp_add_auto_services(lp_auto_services());
2482 set_default_server_announce_type();
2484 /* We set a WINS server address of 127.0.0.1 if we are in the client */
2485 /* and we have WINS support enabled */
2487 if (in_client && Globals.bWINSsupport) {
2489 string_set(&Globals.szWINSserver, "127.0.0.1");
2499 /***************************************************************************
2500 return the max number of services
2501 ***************************************************************************/
2502 int lp_numservices(void)
2504 return(iNumServices);
2507 /***************************************************************************
2508 Display the contents of the services array in human-readable form.
2509 ***************************************************************************/
2510 void lp_dump(FILE *f, BOOL show_defaults)
2514 if (show_defaults) {
2515 defaults_saved = False;
2520 dump_a_service(&sDefault, f);
2522 for (iService = 0; iService < iNumServices; iService++)
2524 if (VALID(iService))
2526 if (iSERVICE(iService).szService[0] == '\0')
2528 dump_a_service(pSERVICE(iService), f);
2534 /***************************************************************************
2535 Return the number of the service with the given name, or -1 if it doesn't
2536 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2537 getservicebyname()! This works ONLY if all services have been loaded, and
2538 does not copy the found service.
2539 ***************************************************************************/
2540 int lp_servicenumber(char *pszServiceName)
2544 for (iService = iNumServices - 1; iService >= 0; iService--)
2545 if (VALID(iService) &&
2546 strequal(lp_servicename(iService), pszServiceName))
2550 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2555 /*******************************************************************
2556 a useful volume label function
2557 ******************************************************************/
2558 char *volume_label(int snum)
2560 char *ret = lp_volume(snum);
2561 if (!*ret) return(lp_servicename(snum));
2566 /*******************************************************************
2567 Set the server type we will announce as via nmbd.
2568 ********************************************************************/
2569 static void set_default_server_announce_type(void)
2571 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2572 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2573 if(lp_announce_as() == ANNOUNCE_AS_NT)
2574 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2575 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2576 default_server_announce |= SV_TYPE_WIN95_PLUS;
2577 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2578 default_server_announce |= SV_TYPE_WFW;
2579 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2583 /*******************************************************************
2585 ********************************************************************/
2586 void lp_remove_service(int snum)
2588 pSERVICE(snum)->valid = False;
2591 /*******************************************************************
2593 ********************************************************************/
2594 void lp_copy_service(int snum, char *new_name)
2596 char *oldname = lp_servicename(snum);
2597 do_section(new_name);
2599 snum = lp_servicenumber(new_name);
2601 lp_do_parameter(snum, "copy", oldname);
2606 /*******************************************************************
2607 Get the default server type we will announce as via nmbd.
2608 ********************************************************************/
2609 int lp_default_server_announce(void)
2611 return default_server_announce;
2614 /*******************************************************************
2615 Split the announce version into major and minor numbers.
2616 ********************************************************************/
2617 int lp_major_announce_version(void)
2619 static BOOL got_major = False;
2620 static int major_version = DEFAULT_MAJOR_VERSION;
2625 return major_version;
2628 if((vers = lp_announce_version()) == NULL)
2629 return major_version;
2631 if((p = strchr(vers, '.')) == 0)
2632 return major_version;
2635 major_version = atoi(vers);
2636 return major_version;
2639 int lp_minor_announce_version(void)
2641 static BOOL got_minor = False;
2642 static int minor_version = DEFAULT_MINOR_VERSION;
2647 return minor_version;
2650 if((vers = lp_announce_version()) == NULL)
2651 return minor_version;
2653 if((p = strchr(vers, '.')) == 0)
2654 return minor_version;
2657 minor_version = atoi(p);
2658 return minor_version;
2661 /***********************************************************
2662 Set the global name resolution order (used in smbclient).
2663 ************************************************************/
2665 void lp_set_name_resolve_order(char *new_order)
2667 Globals.szNameResolveOrder = new_order;
2670 /***********************************************************
2671 Set the real value of kernel oplocks (called by smbd).
2672 ************************************************************/
2674 void lp_set_kernel_oplocks(BOOL val)
2676 Globals.bKernelOplocks = val;