1/* 2 Unix SMB/Netbios implementation. 3 Version 1.9. 4 Parameter loading functions 5 Copyright (C) Karl Auer 1993-1998 6 7 Largely re-written by Andrew Tridgell, September 1994 8 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. 13 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. 18 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. 22*/ 23 24/* 25 * Load parameters. 26 * 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. 30 * 31 * To add a parameter: 32 * 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 38 * 39 * 40 * Notes: 41 * The configuration file is processed sequentially for speed. It is NOT 42 * accessed randomly as happens in 'real' Windows. For this reason, there 43 * is a fair bit of sequence-dependent code here - ie., code which assumes 44 * that certain things happen before others. In particular, the code which 45 * happens at the boundary between sections is delicately poised, so be 46 * careful! 47 * 48 */ 49 50#include "includes.h" 51 52/* Set default coding system for KANJI if none specified in Makefile. */ 53/* 54 * We treat KANJI specially due to historical precedent (it was the 55 * first non-english codepage added to Samba). With the new dynamic 56 * codepage support this is not needed anymore. 57 * 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'. 63 */ 64#ifndef KANJI 65#define KANJI "sbcs" 66#endif /* KANJI */ 67 68BOOL in_client = False; /* Not in the client by default */ 69BOOL bLoaded = False; 70 71extern int DEBUGLEVEL; 72extern pstring user_socket_options; 73extern pstring global_myname; 74pstring global_scope = ""; 75 76#ifndef GLOBAL_NAME 77#define GLOBAL_NAME "global" 78#endif 79 80#ifndef PRINTERS_NAME 81#define PRINTERS_NAME "printers" 82#endif 83 84#ifndef HOMES_NAME 85#define HOMES_NAME "homes" 86#endif 87 88/* some helpful bits */ 89#define pSERVICE(i) ServicePtrs[i] 90#define iSERVICE(i) (*pSERVICE(i)) 91#define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid) 92#define VALID(i) iSERVICE(i).valid 93 94int keepalive=DEFAULT_KEEPALIVE; 95extern BOOL use_getwd_cache; 96 97extern int extra_time_offset; 98 99static BOOL defaults_saved=False; 100 101/* 102 * This structure describes global (ie., server-wide) parameters. 103 */ 104typedef struct 105{ 106 char *szPrintcapname; 107 char *szLockDir; 108 char *szRootdir; 109 char *szDefaultService; 110 char *szDfree; 111 char *szMsgCommand; 112 char *szHostsEquiv; 113 char *szServerString; 114 char *szAutoServices; 115 char *szPasswdProgram; 116 char *szPasswdChat; 117 char *szLogFile; 118 char *szConfigFile; 119 char *szSMBPasswdFile; 120 char *szPasswordServer; 121 char *szSocketOptions; 122 char *szValidChars; 123 char *szWorkGroup; 124 char *szDomainAdminGroup; 125 char *szDomainGuestGroup; 126 char *szDomainAdminUsers; 127 char *szDomainGuestUsers; 128 char *szDomainHostsallow; 129 char *szDomainHostsdeny; 130 char *szUsernameMap; 131#ifdef USING_GROUPNAME_MAP 132 char *szGroupnameMap; 133#endif /* USING_GROUPNAME_MAP */ 134 char *szCharacterSet; 135 char *szLogonScript; 136 char *szLogonPath; 137 char *szLogonDrive; 138 char *szLogonHome; 139 char *szSmbrun; 140 char *szWINSserver; 141 char *szCodingSystem; 142 char *szInterfaces; 143 char *szRemoteAnnounce; 144 char *szRemoteBrowseSync; 145 char *szSocketAddress; 146 char *szNISHomeMapName; 147 char *szAnnounceVersion; /* This is initialised in init_globals */ 148 char *szNetbiosAliases; 149 char *szDomainOtherSIDs; 150 char *szDomainGroups; 151 char *szDriverFile; 152 char *szNameResolveOrder; 153 char *szLdapServer; 154 char *szLdapSuffix; 155 char *szLdapFilter; 156 char *szLdapRoot; 157 char *szLdapRootPassword; 158 char *szPanicAction; 159 char *szAddUserScript; 160 char *szDelUserScript; 161 char *szWINSHook; 162#ifdef WITH_UTMP 163 char *szUtmpDir; 164 char *szWtmpDir; 165 char *szUtmpHostname; 166 BOOL bUtmpConsolidate; 167#endif /* WITH_UTMP */ 168 char *szSourceEnv; 169 int max_log_size; 170 int mangled_stack; 171 int max_xmit; 172 int max_mux; 173 int max_open_files; 174 int max_packet; 175 int pwordlevel; 176 int unamelevel; 177 int deadtime; 178 int maxprotocol; 179 int security; 180 int maxdisksize; 181 int lpqcachetime; 182 int syslog; 183 int os_level; 184 int max_ttl; 185 int max_wins_ttl; 186 int min_wins_ttl; 187 int ReadSize; 188 int lm_announce; 189 int lm_interval; 190 int shmem_size; 191 int client_code_page; 192 int announce_as; /* This is initialised in init_globals */ 193 int machine_password_timeout; 194 int change_notify_timeout; 195 int stat_cache_size; 196 int map_to_guest; 197 int min_passwd_length; 198 int oplock_break_wait_time; 199#ifdef WITH_LDAP 200 int ldap_port; 201#endif /* WITH_LDAP */ 202#ifdef WITH_SSL 203 int sslVersion; 204 char *sslHostsRequire; 205 char *sslHostsResign; 206 char *sslCaCertDir; 207 char *sslCaCertFile; 208 char *sslCert; 209 char *sslPrivKey; 210 char *sslClientCert; 211 char *sslClientPrivKey; 212 char *sslCiphers; 213 BOOL sslEnabled; 214 BOOL sslReqClientCert; 215 BOOL sslReqServerCert; 216 BOOL sslCompatibility; 217#endif /* WITH_SSL */ 218 BOOL bDNSproxy; 219 BOOL bWINSsupport; 220 BOOL bWINSproxy; 221 BOOL bLocalMaster; 222 BOOL bPreferredMaster; 223 BOOL bDomainMaster; 224 BOOL bDomainLogons; 225 BOOL bEncryptPasswords; 226 BOOL bUpdateEncrypt; 227 BOOL bStripDot; 228 BOOL bNullPasswords; 229 BOOL bLoadPrinters; 230 BOOL bUseRhosts; 231 BOOL bReadRaw; 232 BOOL bWriteRaw; 233 BOOL bReadPrediction; 234 BOOL bReadbmpx; 235 BOOL bSyslogOnly; 236 BOOL bBrowseList; 237 BOOL bUnixRealname; 238 BOOL bNISHomeMap; 239 BOOL bTimeServer; 240 BOOL bBindInterfacesOnly; 241 BOOL bUnixPasswdSync; 242 BOOL bPasswdChatDebug; 243 BOOL bOleLockingCompat; 244 BOOL bTimestampLogs; 245 BOOL bNTSmbSupport; 246 BOOL bNTPipeSupport; 247 BOOL bNTAclSupport; 248 BOOL bStatCache; 249 BOOL bKernelOplocks; 250 BOOL bAllowTrustedDomains; 251 BOOL bRestrictAnonymous; 252 BOOL bDebugHiresTimestamp; 253 BOOL bDebugPid; 254 BOOL bDebugUid; 255} global; 256 257static global Globals; 258 259 260 261/* 262 * This structure describes a single service. 263 */ 264typedef struct 265{ 266 BOOL valid; 267 char *szService; 268 char *szPath; 269 char *szUsername; 270 char *szGuestaccount; 271 char *szInvalidUsers; 272 char *szValidUsers; 273 char *szAdminUsers; 274 char *szCopy; 275 char *szInclude; 276 char *szPreExec; 277 char *szPostExec; 278 char *szRootPreExec; 279 char *szRootPostExec; 280 char *szPrintcommand; 281 char *szLpqcommand; 282 char *szLprmcommand; 283 char *szLppausecommand; 284 char *szLpresumecommand; 285 char *szQueuepausecommand; 286 char *szQueueresumecommand; 287 char *szPrintername; 288 char *szPrinterDriver; 289 char *szPrinterDriverLocation; 290 char *szDontdescend; 291 char *szHostsallow; 292 char *szHostsdeny; 293 char *szMagicScript; 294 char *szMagicOutput; 295 char *szMangledMap; 296 char *szVetoFiles; 297 char *szHideFiles; 298 char *szVetoOplockFiles; 299 char *comment; 300 char *force_user; 301 char *force_group; 302 char *readlist; 303 char *writelist; 304 char *volume; 305 char *fstype; 306 int iMinPrintSpace; 307 int iWriteCacheSize; 308 int iCreate_mask; 309 int iCreate_force_mode; 310 int iSecurity_mask; 311 int iSecurity_force_mode; 312 int iDir_mask; 313 int iDir_force_mode; 314 int iDir_Security_mask; 315 int iDir_Security_force_mode; 316 int iMaxConnections; 317 int iDefaultCase; 318 int iPrinting; 319 int iOplockContentionLimit; 320 BOOL bAlternatePerm; 321 BOOL bPreexecClose; 322 BOOL bRootpreexecClose; 323 BOOL bRevalidate; 324 BOOL bCaseSensitive; 325 BOOL bCasePreserve; 326 BOOL bShortCasePreserve; 327 BOOL bCaseMangle; 328 BOOL status; 329 BOOL bHideDotFiles; 330 BOOL bBrowseable; 331 BOOL bAvailable; 332 BOOL bRead_only; 333 BOOL bNo_set_dir; 334 BOOL bGuest_only; 335 BOOL bGuest_ok; 336 BOOL bPrint_ok; 337 BOOL bPostscript; 338 BOOL bMap_system; 339 BOOL bMap_hidden; 340 BOOL bMap_archive; 341 BOOL bLocking; 342 BOOL bStrictLocking; 343#ifdef WITH_UTMP 344 BOOL bUtmp; 345#endif 346 BOOL bShareModes; 347 BOOL bOpLocks; 348 BOOL bLevel2OpLocks; 349 BOOL bOnlyUser; 350 BOOL bMangledNames; 351 BOOL bWidelinks; 352 BOOL bSymlinks; 353 BOOL bSyncAlways; 354 BOOL bStrictSync; 355 char magic_char; 356 BOOL *copymap; 357 BOOL bDeleteReadonly; 358 BOOL bFakeOplocks; 359 BOOL bDeleteVetoFiles; 360 BOOL bDosFiletimes; 361 BOOL bDosFiletimeResolution; 362 BOOL bFakeDirCreateTimes; 363 BOOL bBlockingLocks; 364 BOOL bInheritPerms; 365 char dummy[3]; /* for alignment */ 366} service; 367 368 369/* This is a default service used to prime a services structure */ 370static service sDefault = 371{ 372 True, /* valid */ 373 NULL, /* szService */ 374 NULL, /* szPath */ 375 NULL, /* szUsername */ 376 NULL, /* szGuestAccount - this is set in init_globals() */ 377 NULL, /* szInvalidUsers */ 378 NULL, /* szValidUsers */ 379 NULL, /* szAdminUsers */ 380 NULL, /* szCopy */ 381 NULL, /* szInclude */ 382 NULL, /* szPreExec */ 383 NULL, /* szPostExec */ 384 NULL, /* szRootPreExec */ 385 NULL, /* szRootPostExec */ 386 NULL, /* szPrintcommand */ 387 NULL, /* szLpqcommand */ 388 NULL, /* szLprmcommand */ 389 NULL, /* szLppausecommand */ 390 NULL, /* szLpresumecommand */ 391 NULL, /* szQueuepausecommand */ 392 NULL, /* szQueueresumecommand */ 393 NULL, /* szPrintername */ 394 NULL, /* szPrinterDriver - this is set in init_globals() */ 395 NULL, /* szPrinterDriverLocation */ 396 NULL, /* szDontdescend */ 397 NULL, /* szHostsallow */ 398 NULL, /* szHostsdeny */ 399 NULL, /* szMagicScript */ 400 NULL, /* szMagicOutput */ 401 NULL, /* szMangledMap */ 402 NULL, /* szVetoFiles */ 403 NULL, /* szHideFiles */ 404 NULL, /* szVetoOplockFiles */ 405 NULL, /* comment */ 406 NULL, /* force user */ 407 NULL, /* force group */ 408 NULL, /* readlist */ 409 NULL, /* writelist */ 410 NULL, /* volume */ 411 NULL, /* fstype */ 412 0, /* iMinPrintSpace */ 413 0, /* iWriteCacheSize */ 414 0744, /* iCreate_mask */ 415 0000, /* iCreate_force_mode */ 416 -1, /* iSecurity_mask */ 417 -1, /* iSecurity_force_mode */ 418 0755, /* iDir_mask */ 419 0000, /* iDir_force_mode */ 420 -1, /* iDir_Security_mask */ 421 -1, /* iDir_Security_force_mode */ 422 0, /* iMaxConnections */ 423 CASE_LOWER, /* iDefaultCase */ 424 DEFAULT_PRINTING, /* iPrinting */ 425 2, /* iOplockContentionLimit */ 426 False, /* bAlternatePerm */ 427 False, /* bPreexecClose */ 428 False, /* bRootpreexecClose */ 429 False, /* revalidate */ 430 False, /* case sensitive */ 431 True, /* case preserve */ 432 True, /* short case preserve */ 433 False, /* case mangle */ 434 True, /* status */ 435 True, /* bHideDotFiles */ 436 True, /* bBrowseable */ 437 True, /* bAvailable */ 438 True, /* bRead_only */ 439 True, /* bNo_set_dir */ 440 False, /* bGuest_only */ 441 False, /* bGuest_ok */ 442 False, /* bPrint_ok */ 443 False, /* bPostscript */ 444 False, /* bMap_system */ 445 False, /* bMap_hidden */ 446 True, /* bMap_archive */ 447 True, /* bLocking */ 448 False, /* bStrictLocking */ 449#ifdef WITH_UTMP 450 False, /* bUtmp */ 451#endif 452 True, /* bShareModes */ 453 True, /* bOpLocks */ 454 False, /* bLevel2OpLocks */ 455 False, /* bOnlyUser */ 456 True, /* bMangledNames */ 457 True, /* bWidelinks */ 458 True, /* bSymlinks */ 459 False, /* bSyncAlways */ 460 False, /* bStrictSync */ 461 '~', /* magic char */ 462 NULL, /* copymap */ 463 False, /* bDeleteReadonly */ 464 False, /* bFakeOplocks */ 465 False, /* bDeleteVetoFiles */ 466 False, /* bDosFiletimes */ 467 False, /* bDosFiletimeResolution */ 468 False, /* bFakeDirCreateTimes */ 469 True, /* bBlockingLocks */ 470 False, /* bInheritPerms */ 471 "" /* dummy */ 472}; 473 474 475 476/* local variables */ 477static service **ServicePtrs = NULL; 478static int iNumServices = 0; 479static int iServiceIndex = 0; 480static BOOL bInGlobalSection = True; 481static BOOL bGlobalOnly = False; 482static int default_server_announce; 483 484#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct)) 485 486/* prototypes for the special type handlers */ 487static BOOL handle_valid_chars(char *pszParmValue, char **ptr); 488static BOOL handle_include(char *pszParmValue, char **ptr); 489static BOOL handle_copy(char *pszParmValue, char **ptr); 490static BOOL handle_character_set(char *pszParmValue,char **ptr); 491static BOOL handle_coding_system(char *pszParmValue,char **ptr); 492static BOOL handle_client_code_page(char *pszParmValue,char **ptr); 493static BOOL handle_source_env(char *pszParmValue,char **ptr); 494static BOOL handle_netbios_name(char *pszParmValue,char **ptr); 495 496static void set_default_server_announce_type(void); 497 498static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"}, 499 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"}, 500 {PROTOCOL_COREPLUS, "COREPLUS"}, 501 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}}; 502 503static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"}, 504 {SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"}, 505 {-1, NULL}}; 506 507static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"}, 508 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"}, 509 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"}, 510 {PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"}, 511 {PRINT_CUPS, "cups"}, {-1, NULL}}; 512 513/* Types of machine we can announce as. */ 514#define ANNOUNCE_AS_NT_SERVER 1 515#define ANNOUNCE_AS_WIN95 2 516#define ANNOUNCE_AS_WFW 3 517#define ANNOUNCE_AS_NT_WORKSTATION 4 518 519static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT_SERVER, "NT"}, {ANNOUNCE_AS_NT_SERVER, "NT Server"}, {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"}, {ANNOUNCE_AS_WIN95, "win95"}, {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}}; 520 521static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}}; 522 523static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}}; 524 525/* 526 Do you want session setups at user level security with a invalid 527 password to be rejected or allowed in as guest? WinNT rejects them 528 but it can be a pain as it means "net view" needs to use a password 529 530 You have 3 choices in the setting of map_to_guest: 531 532 "Never" means session setups with an invalid password 533 are rejected. This is the default. 534 535 "Bad User" means session setups with an invalid password 536 are rejected, unless the username does not exist, in which case it 537 is treated as a guest login 538 539 "Bad Password" means session setups with an invalid password 540 are treated as a guest login 541 542 Note that map_to_guest only has an effect in user or server 543 level security. 544*/ 545 546static struct enum_list enum_map_to_guest[] = {{NEVER_MAP_TO_GUEST, "Never"}, {MAP_TO_GUEST_ON_BAD_USER, "Bad User"}, {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"}, {-1, NULL}}; 547 548#ifdef WITH_SSL 549static struct enum_list enum_ssl_version[] = {{SMB_SSL_V2, "ssl2"}, {SMB_SSL_V3, "ssl3"}, 550 {SMB_SSL_V23, "ssl2or3"}, {SMB_SSL_TLS1, "tls1"}, {-1, NULL}}; 551#endif 552 553/* note that we do not initialise the defaults union - it is not allowed in ANSI C */ 554static struct parm_struct parm_table[] = 555{ 556 {"Base Options", P_SEP, P_SEPARATOR}, 557 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0}, 558 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, handle_client_code_page, NULL, 0}, 559 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_DOS_STRING}, 560 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_DOS_STRING}, 561 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_DOS_STRING}, 562 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC|FLAG_DOS_STRING}, 563 {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC|FLAG_DOS_STRING}, 564 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_DOS_STRING}, 565 {"netbios scope", P_UGSTRING,P_GLOBAL, global_scope, NULL, NULL, FLAG_DOS_STRING}, 566 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC|FLAG_DOS_STRING}, 567 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC}, 568 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0}, 569 570 {"Security Options", P_SEP, P_SEPARATOR}, 571 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC}, 572 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC}, 573 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC}, 574 {"allow trusted domains",P_BOOL,P_GLOBAL, &Globals.bAllowTrustedDomains,NULL, NULL, 0}, 575 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL|FLAG_DEPRECATED}, 576 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0}, 577 {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0}, 578 {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0}, 579 {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, 0}, 580 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0}, 581 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0}, 582 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0}, 583 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0}, 584 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0}, 585 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0}, 586 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0}, 587 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0}, 588 {"passwd chat debug",P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0}, 589 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0}, 590 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0}, 591 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0}, 592 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0}, 593 {"restrict anonymous", P_BOOL, P_GLOBAL, &Globals.bRestrictAnonymous,NULL, NULL, 0}, 594 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 595 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0}, 596 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 597 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0}, 598 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0}, 599 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_GLOBAL}, 600 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 601 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 602 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 603 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 604 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 605 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE}, 606 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE}, 607 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0}, 608 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC|FLAG_SHARE}, 609 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0}, 610 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0}, 611 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0}, 612 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 613 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL}, 614 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 615 {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 616 {"force security mode",P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode,NULL,NULL, FLAG_GLOBAL|FLAG_SHARE}, 617 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 618 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL}, 619 {"force directory mode", P_OCTAL,P_LOCAL,&sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 620 {"directory security mask",P_OCTAL,P_LOCAL,&sDefault.iDir_Security_mask,NULL, NULL, FLAG_GLOBAL|FLAG_SHARE}, 621 {"force directory security mode",P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode,NULL,NULL,FLAG_GLOBAL|FLAG_SHARE}, 622 {"inherit permissions",P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE}, 623 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE}, 624 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0}, 625 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT}, 626 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0}, 627 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE}, 628 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_SHARE|FLAG_PRINT}, 629 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0}, 630 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_SHARE|FLAG_PRINT}, 631 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0}, 632 633#ifdef WITH_SSL 634 {"Secure Socket Layer Options", P_SEP, P_SEPARATOR}, 635 {"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0 }, 636 {"ssl hosts", P_STRING, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0 }, 637 {"ssl hosts resign", P_STRING, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0} , 638 {"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0 }, 639 {"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0 }, 640 {"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslCert, NULL, NULL, 0 }, 641 {"ssl server key", P_STRING, P_GLOBAL, &Globals.sslPrivKey, NULL, NULL, 0 }, 642 {"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0 }, 643 {"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0 }, 644 {"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL , 0}, 645 {"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL , 0}, 646 {"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0 }, 647 {"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0}, 648 {"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0 }, 649#endif /* WITH_SSL */ 650 651 {"Logging Options", P_SEP, P_SEPARATOR}, 652 {"debug level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC}, 653 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0}, 654 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0}, 655 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0}, 656 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0}, 657 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0}, 658 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0}, 659 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0}, 660 {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, 0}, 661 {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, 0}, 662 {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, 0}, 663 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE|FLAG_PRINT}, 664 665 {"Protocol Options", P_SEP, P_SEPARATOR}, 666 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0}, 667 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0}, 668 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0}, 669 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0}, 670 {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0}, 671 {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0}, 672 {"nt acl support", P_BOOL, P_GLOBAL, &Globals.bNTAclSupport, NULL, NULL, 0}, 673 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0}, 674 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0}, 675 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0}, 676 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0}, 677 {"name resolve order",P_STRING, P_GLOBAL, &Globals.szNameResolveOrder,NULL, NULL, 0}, 678 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, FLAG_DEPRECATED}, 679 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0}, 680 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0}, 681 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0}, 682 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0}, 683 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0}, 684 685 {"Tuning Options", P_SEP, P_SEPARATOR}, 686 {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0}, 687 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0}, 688 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0}, 689 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0}, 690 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0}, 691 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE}, 692 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0}, 693 {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0}, 694 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT}, 695 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0}, 696 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0}, 697 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0}, 698 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0}, 699 {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0}, 700 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE}, 701 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE}, 702 {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE}, 703 704 {"Printing Options", P_SEP, P_SEPARATOR}, 705 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT}, 706 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT}, 707 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0}, 708 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, FLAG_PRINT}, 709 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT}, 710 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0}, 711 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT}, 712 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL}, 713 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL}, 714 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL}, 715 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL}, 716 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL}, 717 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_PRINT|FLAG_GLOBAL}, 718 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL}, 719 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL}, 720 721 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT}, 722 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0}, 723 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT}, 724 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL}, 725 726 727 {"Filename Handling", P_SEP, P_SEPARATOR}, 728 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0}, 729 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0}, 730 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0}, 731 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE}, 732 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 733 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0}, 734 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 735 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 736 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 737 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 738 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 739 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 740 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING}, 741 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING}, 742 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING}, 743 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 744 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 745 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 746 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 747 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 748 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0}, 749 750 {"Domain Options", P_SEP, P_SEPARATOR}, 751 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0}, 752 {"domain admin group",P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0}, 753 {"domain guest group",P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0}, 754 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0}, 755 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0}, 756#ifdef USING_GROUPNAME_MAP 757 {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0}, 758#endif /* USING_GROUPNAME_MAP */ 759 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0}, 760 761 {"Logon Options", P_SEP, P_SEPARATOR}, 762 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, 0}, 763 {"delete user script",P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, 0}, 764 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_DOS_STRING}, 765 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_DOS_STRING}, 766 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0}, 767 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_DOS_STRING}, 768 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0}, 769 770 {"Browse Options", P_SEP, P_SEPARATOR}, 771 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC}, 772 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0}, 773 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0}, 774 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, FLAG_BASIC}, 775 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0}, 776 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC}, 777 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, FLAG_BASIC}, 778 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0}, 779 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT}, 780 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0}, 781 782 {"WINS Options", P_SEP, P_SEPARATOR}, 783 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0}, 784 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0}, 785 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC}, 786 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC}, 787 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, 0}, 788 789 {"Locking Options", P_SEP, P_SEPARATOR}, 790 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 791 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE}, 792 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL}, 793 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 794#ifdef WITH_UTMP 795 {"utmp", P_BOOL, P_LOCAL, &sDefault.bUtmp, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 796#endif 797 {"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, FLAG_GLOBAL}, 798 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 799 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 800 {"oplock break wait time",P_INTEGER,P_GLOBAL,&Globals.oplock_break_wait_time,NULL,NULL,FLAG_GLOBAL}, 801 {"oplock contention limit",P_INTEGER,P_LOCAL,&sDefault.iOplockContentionLimit,NULL,NULL,FLAG_SHARE|FLAG_GLOBAL}, 802 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 803 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 804 805#ifdef WITH_LDAP 806 {"Ldap Options", P_SEP, P_SEPARATOR}, 807 {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0}, 808 {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0}, 809 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0}, 810 {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0}, 811 {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0}, 812 {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword,NULL, NULL, 0}, 813#endif /* WITH_LDAP */ 814 815 816 {"Miscellaneous Options", P_SEP, P_SEPARATOR}, 817 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0}, 818 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE}, 819 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0}, 820 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0}, 821 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0}, 822 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0}, 823#ifdef WITH_UTMP 824 {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0}, 825 {"utmp dir", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0}, 826 {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, 0}, 827 {"wtmp dir", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, 0}, 828 {"utmp hostname", P_STRING, P_GLOBAL, &Globals.szUtmpHostname, NULL, NULL, 0}, 829 {"utmp consolidate", P_BOOL, P_GLOBAL, &Globals.bUtmpConsolidate, NULL, NULL, 0}, 830#endif /* WITH_UTMP */ 831 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0}, 832 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0}, 833 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0}, 834 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0}, 835 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0}, 836 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0}, 837 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL, 0}, 838 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0}, 839 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0}, 840 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0}, 841 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0}, 842 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0}, 843 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE}, 844 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE}, 845 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE}, 846 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT}, 847 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0}, 848 {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE}, 849 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT}, 850 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT}, 851 {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose,NULL, NULL, FLAG_SHARE}, 852 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT}, 853 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT}, 854 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE}, 855 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE}, 856 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE}, 857 {"source environment",P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env,NULL,0}, 858 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 859 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 860 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE}, 861 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE}, 862 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE}, 863 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 864 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 865 {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 866 867 {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, 868 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0}, 869 870 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0} 871}; 872 873 874 875/*************************************************************************** 876Initialise the global parameter structure. 877***************************************************************************/ 878static void init_globals(void) 879{ 880 static BOOL done_init = False; 881 pstring s; 882 883 if (!done_init) 884 { 885 int i; 886 memset((void *)&Globals,'\0',sizeof(Globals)); 887 888 for (i = 0; parm_table[i].label; i++) 889 if ((parm_table[i].type == P_STRING || 890 parm_table[i].type == P_USTRING) && 891 parm_table[i].ptr) 892 string_set(parm_table[i].ptr,""); 893 894 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT); 895 string_set(&sDefault.szPrinterDriver, "NULL"); 896 string_set(&sDefault.fstype, FSTYPE_STRING); 897 898 done_init = True; 899 } 900 901 902 DEBUG(3,("Initialising global parameters\n")); 903 904 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE); 905 /* 906 * Allow the default PASSWD_CHAT to be overridden in local.h. 907 */ 908 string_set(&Globals.szPasswdChat,DEFAULT_PASSWD_CHAT); 909 string_set(&Globals.szWorkGroup, WORKGROUP); 910 string_set(&Globals.szPasswdProgram, PASSWD_PROGRAM); 911 string_set(&Globals.szPrintcapname, PRINTCAP_NAME); 912 string_set(&Globals.szDriverFile, DRIVERFILE); 913 string_set(&Globals.szLockDir, LOCKDIR); 914 string_set(&Globals.szRootdir, "/"); 915#ifdef WITH_UTMP 916 string_set(&Globals.szUtmpDir, ""); 917 string_set(&Globals.szWtmpDir, ""); 918 string_set(&Globals.szUtmpHostname, "%m"); 919 Globals.bUtmpConsolidate = False; 920#endif /* WITH_UTMP */ 921 string_set(&Globals.szSmbrun, SMBRUN); 922 string_set(&Globals.szSocketAddress, "0.0.0.0"); 923 pstrcpy(s, "Samba "); 924 pstrcat(s, VERSION); 925 string_set(&Globals.szServerString,s); 926 slprintf(s,sizeof(s)-1, "%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION); 927 string_set(&Globals.szAnnounceVersion,s); 928 929 pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS); 930 931 string_set(&Globals.szLogonDrive, ""); 932 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */ 933 string_set(&Globals.szLogonHome, "\\\\%N\\%U"); 934 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile"); 935 936 string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast"); 937 938 Globals.bLoadPrinters = True; 939 Globals.bUseRhosts = False; 940 Globals.max_packet = 65535; 941 Globals.mangled_stack = 50; 942 Globals.max_xmit = 65535; 943 Globals.max_mux = 50; /* This is *needed* for profile support. */ 944 Globals.lpqcachetime = 10; 945 Globals.pwordlevel = 0; 946 Globals.unamelevel = 0; 947 Globals.deadtime = 0; 948 Globals.max_log_size = 5000; 949 Globals.max_open_files = MAX_OPEN_FILES; 950 Globals.maxprotocol = PROTOCOL_NT1; 951 Globals.security = SEC_USER; 952 Globals.bEncryptPasswords = False; 953 Globals.bUpdateEncrypt = False; 954 Globals.bReadRaw = True; 955 Globals.bWriteRaw = True; 956 Globals.bReadPrediction = False; 957 Globals.bReadbmpx = False; 958 Globals.bNullPasswords = False; 959 Globals.bStripDot = False; 960 Globals.syslog = 1; 961 Globals.bSyslogOnly = False; 962 Globals.bTimestampLogs = True; 963 Globals.bDebugHiresTimestamp = False; 964 Globals.bDebugPid = False; 965 Globals.bDebugUid = False; 966 Globals.max_ttl = 60*60*24*3; /* 3 days default. */ 967 Globals.max_wins_ttl = 60*60*24*6; /* 6 days default. */ 968 Globals.min_wins_ttl = 60*60*6; /* 6 hours default. */ 969 Globals.machine_password_timeout = 60*60*24*7; /* 7 days default. */ 970 Globals.change_notify_timeout = 60; /* 1 minute default. */ 971 Globals.ReadSize = 16*1024; 972 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */ 973 Globals.lm_interval = 60; 974 Globals.shmem_size = SHMEM_SIZE; 975 Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */ 976 Globals.announce_as = ANNOUNCE_AS_NT_SERVER; 977 Globals.bUnixRealname = False; 978#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT)) 979 Globals.bNISHomeMap = False; 980#ifdef WITH_NISPLUS_HOME 981 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir"); 982#else 983 string_set(&Globals.szNISHomeMapName, "auto.home"); 984#endif 985#endif 986 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE; 987 Globals.bTimeServer = False; 988 Globals.bBindInterfacesOnly = False; 989 Globals.bUnixPasswdSync = False; 990 Globals.bPasswdChatDebug = False; 991 Globals.bOleLockingCompat = True; 992 Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */ 993 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */ 994 Globals.bNTAclSupport = True; /* Use NT ACLs by default. */ 995 Globals.bStatCache = True; /* use stat cache by default */ 996 Globals.bRestrictAnonymous = False; 997 Globals.map_to_guest = 0; /* By Default, "Never" */ 998 Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */ 999 Globals.oplock_break_wait_time = 10; /* By Default, 10 msecs. */ 1000 1001#ifdef WITH_LDAP 1002 /* default values for ldap */ 1003 string_set(&Globals.szLdapServer, "localhost"); 1004 Globals.ldap_port=389; 1005#endif /* WITH_LDAP */ 1006 1007#ifdef WITH_SSL 1008 Globals.sslVersion = SMB_SSL_V23; 1009 string_set(&Globals.sslHostsRequire, ""); 1010 string_set(&Globals.sslHostsResign, ""); 1011 string_set(&Globals.sslCaCertDir, ""); 1012 string_set(&Globals.sslCaCertFile, ""); 1013 string_set(&Globals.sslCert, ""); 1014 string_set(&Globals.sslPrivKey, ""); 1015 string_set(&Globals.sslClientCert, ""); 1016 string_set(&Globals.sslClientPrivKey, ""); 1017 string_set(&Globals.sslCiphers, ""); 1018 Globals.sslEnabled = False; 1019 Globals.sslReqClientCert = False; 1020 Globals.sslReqServerCert = False; 1021 Globals.sslCompatibility = False; 1022#endif /* WITH_SSL */ 1023 1024/* these parameters are set to defaults that are more appropriate 1025 for the increasing samba install base: 1026 1027 as a member of the workgroup, that will possibly become a 1028 _local_ master browser (lm = True). this is opposed to a forced 1029 local master browser startup (pm = True). 1030 1031 doesn't provide WINS server service by default (wsupp = False), 1032 and doesn't provide domain master browser services by default, either. 1033 1034*/ 1035 1036 Globals.os_level = 20; 1037 Globals.bPreferredMaster = False; 1038 Globals.bLocalMaster = True; 1039 Globals.bDomainMaster = False; 1040 Globals.bDomainLogons = False; 1041 Globals.bBrowseList = True; 1042 Globals.bWINSsupport = False; 1043 Globals.bWINSproxy = False; 1044 1045 Globals.bDNSproxy = True; 1046 1047 /* 1048 * smbd will check at runtime to see if this value 1049 * will really be used or not. 1050 */ 1051 Globals.bKernelOplocks = True; 1052 1053 Globals.bAllowTrustedDomains = True; 1054 1055 /* 1056 * This must be done last as it checks the value in 1057 * client_code_page. 1058 */ 1059 1060 interpret_coding_system(KANJI); 1061} 1062 1063/*************************************************************************** 1064Initialise the sDefault parameter structure. 1065***************************************************************************/ 1066static void init_locals(void) 1067{ 1068 /* choose defaults depending on the type of printing */ 1069 switch (sDefault.iPrinting) 1070 { 1071 case PRINT_BSD: 1072 case PRINT_AIX: 1073 case PRINT_LPRNG: 1074 case PRINT_PLP: 1075 string_set(&sDefault.szLpqcommand,"lpq -P%p"); 1076 string_set(&sDefault.szLprmcommand,"lprm -P%p %j"); 1077 string_set(&sDefault.szPrintcommand,"lpr -r -P%p %s"); 1078 break; 1079 1080 case PRINT_CUPS: 1081 string_set(&sDefault.szLpqcommand,"/usr/bin/lpstat -o%p"); 1082 string_set(&sDefault.szLprmcommand,"/usr/bin/cancel %p-%j"); 1083 string_set(&sDefault.szPrintcommand,"/usr/bin/lp -d%p -oraw %s; rm %s"); 1084 string_set(&sDefault.szQueuepausecommand, "/usr/bin/disable %p"); 1085 string_set(&sDefault.szQueueresumecommand, "/usr/bin/enable %p"); 1086 break; 1087 1088 case PRINT_SYSV: 1089 case PRINT_HPUX: 1090 string_set(&sDefault.szLpqcommand,"lpstat -o%p"); 1091 string_set(&sDefault.szLprmcommand,"cancel %p-%j"); 1092 string_set(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s"); 1093 string_set(&sDefault.szQueuepausecommand, "disable %p"); 1094 string_set(&sDefault.szQueueresumecommand, "enable %p"); 1095#ifndef HPUX 1096 string_set(&sDefault.szLppausecommand,"lp -i %p-%j -H hold"); 1097 string_set(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume"); 1098#endif /* SYSV */ 1099 break; 1100 1101 case PRINT_QNX: 1102 string_set(&sDefault.szLpqcommand,"lpq -P%p"); 1103 string_set(&sDefault.szLprmcommand,"lprm -P%p %j"); 1104 string_set(&sDefault.szPrintcommand,"lp -r -P%p %s"); 1105 break; 1106 1107 case PRINT_SOFTQ: 1108 string_set(&sDefault.szLpqcommand,"qstat -l -d%p"); 1109 string_set(&sDefault.szLprmcommand,"qstat -s -j%j -c"); 1110 string_set(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s"); 1111 string_set(&sDefault.szLppausecommand,"qstat -s -j%j -h"); 1112 string_set(&sDefault.szLpresumecommand,"qstat -s -j%j -r"); 1113 break; 1114 1115 } 1116} 1117 1118static TALLOC_CTX *lp_talloc; 1119 1120/******************************************************************* a 1121free up temporary memory - called from the main loop 1122********************************************************************/ 1123void lp_talloc_free(void) 1124{ 1125 if (!lp_talloc) return; 1126 talloc_destroy(lp_talloc); 1127 lp_talloc = NULL; 1128} 1129 1130/******************************************************************* 1131convenience routine to grab string parameters into temporary memory 1132and run standard_sub_basic on them. The buffers can be written to by 1133callers without affecting the source string. 1134********************************************************************/ 1135static char *lp_string(const char *s) 1136{ 1137 size_t len = s?strlen(s):0; 1138 char *ret; 1139 1140 if (!lp_talloc) lp_talloc = talloc_init(); 1141 1142 ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */ 1143 1144 if (!ret) return NULL; 1145 1146 if (!s) 1147 *ret = 0; 1148 else 1149 StrnCpy(ret,s,len); 1150 1151 trim_string(ret, "\"", "\""); 1152 1153 standard_sub_basic(ret); 1154 return(ret); 1155} 1156 1157 1158/* 1159 In this section all the functions that are used to access the 1160 parameters from the rest of the program are defined 1161*/ 1162 1163#define FN_GLOBAL_STRING(fn_name,ptr) \ 1164 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));} 1165#define FN_GLOBAL_BOOL(fn_name,ptr) \ 1166 BOOL fn_name(void) {return(*(BOOL *)(ptr));} 1167#define FN_GLOBAL_CHAR(fn_name,ptr) \ 1168 char fn_name(void) {return(*(char *)(ptr));} 1169#define FN_GLOBAL_INTEGER(fn_name,ptr) \ 1170 int fn_name(void) {return(*(int *)(ptr));} 1171 1172#define FN_LOCAL_STRING(fn_name,val) \ 1173 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));} 1174#define FN_LOCAL_BOOL(fn_name,val) \ 1175 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} 1176#define FN_LOCAL_CHAR(fn_name,val) \ 1177 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} 1178#define FN_LOCAL_INTEGER(fn_name,val) \ 1179 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} 1180 1181FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile) 1182FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun) 1183FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile) 1184FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile) 1185FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString) 1186FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname) 1187FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir) 1188#ifdef WITH_UTMP 1189FN_GLOBAL_STRING(lp_utmpdir,&Globals.szUtmpDir) 1190FN_GLOBAL_STRING(lp_wtmpdir,&Globals.szWtmpDir) 1191FN_GLOBAL_STRING(lp_utmp_hostname,&Globals.szUtmpHostname) 1192FN_GLOBAL_BOOL(lp_utmp_consolidate,&Globals.bUtmpConsolidate) 1193#endif /* WITH_UTMP */ 1194FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir) 1195FN_GLOBAL_STRING(lp_source_environment,&Globals.szSourceEnv) 1196FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService) 1197FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand) 1198FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree) 1199FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv) 1200FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices) 1201FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram) 1202FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat) 1203FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer) 1204FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder) 1205FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup) 1206FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap) 1207#ifdef USING_GROUPNAME_MAP 1208FN_GLOBAL_STRING(lp_groupname_map,&Globals.szGroupnameMap) 1209#endif /* USING_GROUPNAME_MAP */ 1210FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript) 1211FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath) 1212FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive) 1213FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome) 1214FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce) 1215FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync) 1216FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver) 1217FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces) 1218FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress) 1219FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName) 1220static FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion) 1221FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases) 1222FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile) 1223FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction) 1224FN_GLOBAL_STRING(lp_adduser_script,&Globals.szAddUserScript) 1225FN_GLOBAL_STRING(lp_deluser_script,&Globals.szDelUserScript) 1226FN_GLOBAL_STRING(lp_wins_hook,&Globals.szWINSHook) 1227 1228FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups) 1229FN_GLOBAL_STRING(lp_domain_admin_group,&Globals.szDomainAdminGroup) 1230FN_GLOBAL_STRING(lp_domain_guest_group,&Globals.szDomainGuestGroup) 1231FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers) 1232FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers) 1233 1234#ifdef WITH_LDAP 1235FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer); 1236FN_GLOBAL_STRING(lp_ldap_suffix,&Globals.szLdapSuffix); 1237FN_GLOBAL_STRING(lp_ldap_filter,&Globals.szLdapFilter); 1238FN_GLOBAL_STRING(lp_ldap_root,&Globals.szLdapRoot); 1239FN_GLOBAL_STRING(lp_ldap_rootpasswd,&Globals.szLdapRootPassword); 1240#endif /* WITH_LDAP */ 1241 1242#ifdef WITH_SSL 1243FN_GLOBAL_INTEGER(lp_ssl_version,&Globals.sslVersion); 1244FN_GLOBAL_STRING(lp_ssl_hosts,&Globals.sslHostsRequire); 1245FN_GLOBAL_STRING(lp_ssl_hosts_resign,&Globals.sslHostsResign); 1246FN_GLOBAL_STRING(lp_ssl_cacertdir,&Globals.sslCaCertDir); 1247FN_GLOBAL_STRING(lp_ssl_cacertfile,&Globals.sslCaCertFile); 1248FN_GLOBAL_STRING(lp_ssl_cert,&Globals.sslCert); 1249FN_GLOBAL_STRING(lp_ssl_privkey,&Globals.sslPrivKey); 1250FN_GLOBAL_STRING(lp_ssl_client_cert,&Globals.sslClientCert); 1251FN_GLOBAL_STRING(lp_ssl_client_privkey,&Globals.sslClientPrivKey); 1252FN_GLOBAL_STRING(lp_ssl_ciphers,&Globals.sslCiphers); 1253FN_GLOBAL_BOOL(lp_ssl_enabled,&Globals.sslEnabled); 1254FN_GLOBAL_BOOL(lp_ssl_reqClientCert,&Globals.sslReqClientCert); 1255FN_GLOBAL_BOOL(lp_ssl_reqServerCert,&Globals.sslReqServerCert); 1256FN_GLOBAL_BOOL(lp_ssl_compatibility,&Globals.sslCompatibility); 1257#endif /* WITH_SSL */ 1258 1259FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy) 1260FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport) 1261FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport) 1262FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy) 1263FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster) 1264FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster) 1265FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons) 1266FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster) 1267FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters) 1268FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts) 1269FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction) 1270FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx) 1271FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw) 1272FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw) 1273FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords) 1274FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot) 1275FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords) 1276FN_GLOBAL_BOOL(lp_update_encrypted,&Globals.bUpdateEncrypt) 1277FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly) 1278FN_GLOBAL_BOOL(lp_timestamp_logs,&Globals.bTimestampLogs) 1279FN_GLOBAL_BOOL(lp_debug_hires_timestamp,&Globals.bDebugHiresTimestamp) 1280FN_GLOBAL_BOOL(lp_debug_pid,&Globals.bDebugPid) 1281FN_GLOBAL_BOOL(lp_debug_uid,&Globals.bDebugUid) 1282FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList) 1283FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname) 1284FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap) 1285static FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer) 1286FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly) 1287FN_GLOBAL_BOOL(lp_unix_password_sync,&Globals.bUnixPasswdSync) 1288FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug) 1289FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat) 1290FN_GLOBAL_BOOL(lp_nt_smb_support,&Globals.bNTSmbSupport) 1291FN_GLOBAL_BOOL(lp_nt_pipe_support,&Globals.bNTPipeSupport) 1292FN_GLOBAL_BOOL(lp_nt_acl_support,&Globals.bNTAclSupport) 1293FN_GLOBAL_BOOL(lp_stat_cache,&Globals.bStatCache) 1294FN_GLOBAL_BOOL(lp_allow_trusted_domains,&Globals.bAllowTrustedDomains) 1295FN_GLOBAL_BOOL(lp_restrict_anonymous,&Globals.bRestrictAnonymous) 1296 1297FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level) 1298FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl) 1299FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl) 1300FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl) 1301FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size) 1302FN_GLOBAL_INTEGER(lp_max_open_files,&Globals.max_open_files) 1303FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit) 1304FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux) 1305FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel) 1306FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel) 1307FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize) 1308FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size) 1309FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime) 1310FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol) 1311FN_GLOBAL_INTEGER(lp_security,&Globals.security) 1312FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize) 1313FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime) 1314FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog) 1315FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page) 1316static FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as) 1317FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce) 1318FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval) 1319FN_GLOBAL_INTEGER(lp_machine_password_timeout,&Globals.machine_password_timeout) 1320FN_GLOBAL_INTEGER(lp_change_notify_timeout,&Globals.change_notify_timeout) 1321FN_GLOBAL_INTEGER(lp_stat_cache_size,&Globals.stat_cache_size) 1322FN_GLOBAL_INTEGER(lp_map_to_guest,&Globals.map_to_guest) 1323FN_GLOBAL_INTEGER(lp_min_passwd_length,&Globals.min_passwd_length) 1324FN_GLOBAL_INTEGER(lp_oplock_break_wait_time,&Globals.oplock_break_wait_time) 1325 1326#ifdef WITH_LDAP 1327FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port) 1328#endif /* WITH_LDAP */ 1329 1330FN_LOCAL_STRING(lp_preexec,szPreExec) 1331FN_LOCAL_STRING(lp_postexec,szPostExec) 1332FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec) 1333FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec) 1334FN_LOCAL_STRING(lp_servicename,szService) 1335FN_LOCAL_STRING(lp_pathname,szPath) 1336FN_LOCAL_STRING(lp_dontdescend,szDontdescend) 1337FN_LOCAL_STRING(lp_username,szUsername) 1338FN_LOCAL_STRING(lp_guestaccount,szGuestaccount) 1339FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers) 1340FN_LOCAL_STRING(lp_valid_users,szValidUsers) 1341FN_LOCAL_STRING(lp_admin_users,szAdminUsers) 1342FN_LOCAL_STRING(lp_printcommand,szPrintcommand) 1343FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand) 1344FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand) 1345FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand) 1346FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand) 1347FN_LOCAL_STRING(lp_queuepausecommand,szQueuepausecommand) 1348FN_LOCAL_STRING(lp_queueresumecommand,szQueueresumecommand) 1349FN_LOCAL_STRING(lp_printername,szPrintername) 1350FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver) 1351FN_LOCAL_STRING(lp_hostsallow,szHostsallow) 1352FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny) 1353FN_LOCAL_STRING(lp_magicscript,szMagicScript) 1354FN_LOCAL_STRING(lp_magicoutput,szMagicOutput) 1355FN_LOCAL_STRING(lp_comment,comment) 1356FN_LOCAL_STRING(lp_force_user,force_user) 1357FN_LOCAL_STRING(lp_force_group,force_group) 1358FN_LOCAL_STRING(lp_readlist,readlist) 1359FN_LOCAL_STRING(lp_writelist,writelist) 1360FN_LOCAL_STRING(lp_fstype,fstype) 1361static FN_LOCAL_STRING(lp_volume,volume) 1362FN_LOCAL_STRING(lp_mangled_map,szMangledMap) 1363FN_LOCAL_STRING(lp_veto_files,szVetoFiles) 1364FN_LOCAL_STRING(lp_hide_files,szHideFiles) 1365FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles) 1366FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation) 1367 1368FN_LOCAL_BOOL(lp_preexec_close,bPreexecClose) 1369FN_LOCAL_BOOL(lp_rootpreexec_close,bRootpreexecClose) 1370FN_LOCAL_BOOL(lp_revalidate,bRevalidate) 1371FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive) 1372FN_LOCAL_BOOL(lp_preservecase,bCasePreserve) 1373FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve) 1374FN_LOCAL_BOOL(lp_casemangle,bCaseMangle) 1375FN_LOCAL_BOOL(lp_status,status) 1376FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles) 1377FN_LOCAL_BOOL(lp_browseable,bBrowseable) 1378FN_LOCAL_BOOL(lp_readonly,bRead_only) 1379FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir) 1380FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok) 1381FN_LOCAL_BOOL(lp_guest_only,bGuest_only) 1382FN_LOCAL_BOOL(lp_print_ok,bPrint_ok) 1383FN_LOCAL_BOOL(lp_postscript,bPostscript) 1384FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden) 1385FN_LOCAL_BOOL(lp_map_archive,bMap_archive) 1386FN_LOCAL_BOOL(lp_locking,bLocking) 1387FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking) 1388#ifdef WITH_UTMP 1389FN_LOCAL_BOOL(lp_utmp,bUtmp) 1390#endif 1391FN_LOCAL_BOOL(lp_share_modes,bShareModes) 1392FN_LOCAL_BOOL(lp_oplocks,bOpLocks) 1393FN_LOCAL_BOOL(lp_level2_oplocks,bLevel2OpLocks) 1394FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser) 1395FN_LOCAL_BOOL(lp_manglednames,bMangledNames) 1396FN_LOCAL_BOOL(lp_widelinks,bWidelinks) 1397FN_LOCAL_BOOL(lp_symlinks,bSymlinks) 1398FN_LOCAL_BOOL(lp_syncalways,bSyncAlways) 1399FN_LOCAL_BOOL(lp_strict_sync,bStrictSync) 1400FN_LOCAL_BOOL(lp_map_system,bMap_system) 1401FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly) 1402FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks) 1403FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles) 1404FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes) 1405FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution) 1406FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes) 1407FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks) 1408FN_LOCAL_BOOL(lp_inherit_perms,bInheritPerms) 1409 1410FN_LOCAL_INTEGER(lp_create_mask,iCreate_mask) 1411FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode) 1412FN_LOCAL_INTEGER(_lp_security_mask,iSecurity_mask) 1413FN_LOCAL_INTEGER(_lp_force_security_mode,iSecurity_force_mode) 1414FN_LOCAL_INTEGER(lp_dir_mask,iDir_mask) 1415FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode) 1416FN_LOCAL_INTEGER(_lp_dir_security_mask,iDir_Security_mask) 1417FN_LOCAL_INTEGER(_lp_force_dir_security_mode,iDir_Security_force_mode) 1418FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections) 1419FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase) 1420FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace) 1421FN_LOCAL_INTEGER(lp_printing,iPrinting) 1422FN_LOCAL_INTEGER(lp_oplock_contention_limit,iOplockContentionLimit) 1423FN_LOCAL_INTEGER(lp_write_cache_size,iWriteCacheSize) 1424 1425FN_LOCAL_CHAR(lp_magicchar,magic_char) 1426 1427 1428 1429/* local prototypes */ 1430static int strwicmp( char *psz1, char *psz2 ); 1431static int map_parameter( char *pszParmName); 1432static BOOL set_boolean( BOOL *pb, char *pszParmValue ); 1433static int getservicebyname(char *pszServiceName, service *pserviceDest); 1434static void copy_service( service *pserviceDest, 1435 service *pserviceSource, 1436 BOOL *pcopymapDest ); 1437static BOOL service_ok(int iService); 1438static BOOL do_parameter(char *pszParmName, char *pszParmValue); 1439static BOOL do_section(char *pszSectionName); 1440static void init_copymap(service *pservice); 1441 1442 1443/*************************************************************************** 1444initialise a service to the defaults 1445***************************************************************************/ 1446static void init_service(service *pservice) 1447{ 1448 memset((char *)pservice,'\0',sizeof(service)); 1449 copy_service(pservice,&sDefault,NULL); 1450} 1451 1452 1453/*************************************************************************** 1454free the dynamically allocated parts of a service struct 1455***************************************************************************/ 1456static void free_service(service *pservice) 1457{ 1458 int i; 1459 if (!pservice) 1460 return; 1461 1462 if(pservice->szService) 1463 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService)); 1464 1465 string_free(&pservice->szService); 1466 if (pservice->copymap) 1467 { 1468 free(pservice->copymap); 1469 pservice->copymap = NULL; 1470 } 1471 1472 for (i=0;parm_table[i].label;i++) 1473 if ((parm_table[i].type == P_STRING || 1474 parm_table[i].type == P_USTRING) && 1475 parm_table[i].class == P_LOCAL) 1476 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault))); 1477} 1478 1479/*************************************************************************** 1480add a new service to the services array initialising it with the given 1481service 1482***************************************************************************/ 1483static int add_a_service(service *pservice, char *name) 1484{ 1485 int i; 1486 service tservice; 1487 int num_to_alloc = iNumServices+1; 1488 1489 tservice = *pservice; 1490 1491 /* it might already exist */ 1492 if (name) 1493 { 1494 i = getservicebyname(name,NULL); 1495 if (i >= 0) 1496 return(i); 1497 } 1498 1499 /* find an invalid one */ 1500 for (i=0;i<iNumServices;i++) 1501 if (!pSERVICE(i)->valid) 1502 break; 1503 1504 /* if not, then create one */ 1505 if (i == iNumServices) 1506 { 1507 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc); 1508 if (ServicePtrs) 1509 pSERVICE(iNumServices) = (service *)malloc(sizeof(service)); 1510 1511 if (!ServicePtrs || !pSERVICE(iNumServices)) 1512 return(-1); 1513 1514 iNumServices++; 1515 } 1516 else 1517 free_service(pSERVICE(i)); 1518 1519 pSERVICE(i)->valid = True; 1520 1521 init_service(pSERVICE(i)); 1522 copy_service(pSERVICE(i),&tservice,NULL); 1523 if (name) { 1524 string_set(&iSERVICE(i).szService,name); 1525 unix_to_dos(iSERVICE(i).szService, True); 1526 } 1527 return(i); 1528} 1529 1530/*************************************************************************** 1531add a new home service, with the specified home directory, defaults coming 1532from service ifrom 1533***************************************************************************/ 1534BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir) 1535{ 1536 int i = add_a_service(pSERVICE(iDefaultService),pszHomename); 1537 1538 if (i < 0) 1539 return(False); 1540 1541 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1))) 1542 string_set(&iSERVICE(i).szPath,pszHomedir); 1543 if (!(*(iSERVICE(i).comment))) 1544 { 1545 pstring comment; 1546 slprintf(comment,sizeof(comment)-1, 1547 "Home directory of %s",pszHomename); 1548 string_set(&iSERVICE(i).comment,comment); 1549 } 1550 iSERVICE(i).bAvailable = sDefault.bAvailable; 1551 iSERVICE(i).bBrowseable = sDefault.bBrowseable; 1552 1553 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir)); 1554 1555 return(True); 1556} 1557 1558/*************************************************************************** 1559add a new service, based on an old one 1560***************************************************************************/ 1561int lp_add_service(char *pszService, int iDefaultService) 1562{ 1563 return(add_a_service(pSERVICE(iDefaultService),pszService)); 1564} 1565 1566 1567/*************************************************************************** 1568add the IPC service 1569***************************************************************************/ 1570static BOOL lp_add_ipc(void) 1571{ 1572 pstring comment; 1573 int i = add_a_service(&sDefault,"IPC$"); 1574 1575 if (i < 0) 1576 return(False); 1577 1578 slprintf(comment,sizeof(comment)-1, 1579 "IPC Service (%s)", Globals.szServerString ); 1580 1581 string_set(&iSERVICE(i).szPath,tmpdir()); 1582 string_set(&iSERVICE(i).szUsername,""); 1583 string_set(&iSERVICE(i).comment,comment); 1584 string_set(&iSERVICE(i).fstype,"IPC"); 1585 iSERVICE(i).status = False; 1586 iSERVICE(i).iMaxConnections = 0; 1587 iSERVICE(i).bAvailable = True; 1588 iSERVICE(i).bRead_only = True; 1589 iSERVICE(i).bGuest_only = False; 1590 iSERVICE(i).bGuest_ok = True; 1591 iSERVICE(i).bPrint_ok = False; 1592 iSERVICE(i).bBrowseable = sDefault.bBrowseable; 1593 1594 DEBUG(3,("adding IPC service\n")); 1595 1596 return(True); 1597} 1598 1599 1600/*************************************************************************** 1601add a new printer service, with defaults coming from service iFrom 1602***************************************************************************/ 1603BOOL lp_add_printer(char *pszPrintername, int iDefaultService) 1604{ 1605 char *comment = "From Printcap"; 1606 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername); 1607 1608 if (i < 0) 1609 return(False); 1610 1611 /* note that we do NOT default the availability flag to True - */ 1612 /* we take it from the default service passed. This allows all */ 1613 /* dynamic printers to be disabled by disabling the [printers] */ 1614 /* entry (if/when the 'available' keyword is implemented!). */ 1615 1616 /* the printer name is set to the service name. */ 1617 string_set(&iSERVICE(i).szPrintername,pszPrintername); 1618 string_set(&iSERVICE(i).comment,comment); 1619 iSERVICE(i).bBrowseable = sDefault.bBrowseable; 1620 /* Printers cannot be read_only. */ 1621 iSERVICE(i).bRead_only = False; 1622 /* No share modes on printer services. */ 1623 iSERVICE(i).bShareModes = False; 1624 /* No oplocks on printer services. */ 1625 iSERVICE(i).bOpLocks = False; 1626 /* Printer services must be printable. */ 1627 iSERVICE(i).bPrint_ok = True; 1628 1629 DEBUG(3,("adding printer service %s\n",pszPrintername)); 1630 1631 return(True); 1632} 1633 1634 1635/*************************************************************************** 1636Do a case-insensitive, whitespace-ignoring string compare. 1637***************************************************************************/ 1638static int strwicmp(char *psz1, char *psz2) 1639{ 1640 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */ 1641 /* appropriate value. */ 1642 if (psz1 == psz2) 1643 return (0); 1644 else 1645 if (psz1 == NULL) 1646 return (-1); 1647 else 1648 if (psz2 == NULL) 1649 return (1); 1650 1651 /* sync the strings on first non-whitespace */ 1652 while (1) 1653 { 1654 while (isspace(*psz1)) 1655 psz1++; 1656 while (isspace(*psz2)) 1657 psz2++; 1658 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0') 1659 break; 1660 psz1++; 1661 psz2++; 1662 } 1663 return (*psz1 - *psz2); 1664} 1665 1666/*************************************************************************** 1667Map a parameter's string representation to something we can use. 1668Returns False if the parameter string is not recognised, else TRUE. 1669***************************************************************************/ 1670static int map_parameter(char *pszParmName) 1671{ 1672 int iIndex; 1673 1674 if (*pszParmName == '-') 1675 return(-1); 1676 1677 for (iIndex = 0; parm_table[iIndex].label; iIndex++) 1678 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0) 1679 return(iIndex); 1680 1681 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName)); 1682 return(-1); 1683} 1684 1685 1686/*************************************************************************** 1687Set a boolean variable from the text value stored in the passed string. 1688Returns True in success, False if the passed string does not correctly 1689represent a boolean. 1690***************************************************************************/ 1691static BOOL set_boolean(BOOL *pb, char *pszParmValue) 1692{ 1693 BOOL bRetval; 1694 1695 bRetval = True; 1696 if (strwicmp(pszParmValue, "yes") == 0 || 1697 strwicmp(pszParmValue, "true") == 0 || 1698 strwicmp(pszParmValue, "1") == 0) 1699 *pb = True; 1700 else 1701 if (strwicmp(pszParmValue, "no") == 0 || 1702 strwicmp(pszParmValue, "False") == 0 || 1703 strwicmp(pszParmValue, "0") == 0) 1704 *pb = False; 1705 else 1706 { 1707 DEBUG(0,("ERROR: Badly formed boolean in configuration file: \"%s\".\n", 1708 pszParmValue)); 1709 bRetval = False; 1710 } 1711 return (bRetval); 1712} 1713 1714/*************************************************************************** 1715Find a service by name. Otherwise works like get_service. 1716***************************************************************************/ 1717static int getservicebyname(char *pszServiceName, service *pserviceDest) 1718{ 1719 int iService; 1720 1721 for (iService = iNumServices - 1; iService >= 0; iService--) 1722 if (VALID(iService) && 1723 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0) 1724 { 1725 if (pserviceDest != NULL) 1726 copy_service(pserviceDest, pSERVICE(iService), NULL); 1727 break; 1728 } 1729 1730 return (iService); 1731} 1732 1733 1734 1735/*************************************************************************** 1736Copy a service structure to another 1737 1738If pcopymapDest is NULL then copy all fields 1739***************************************************************************/ 1740static void copy_service(service *pserviceDest, 1741 service *pserviceSource, 1742 BOOL *pcopymapDest) 1743{ 1744 int i; 1745 BOOL bcopyall = (pcopymapDest == NULL); 1746 1747 for (i=0;parm_table[i].label;i++) 1748 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL && 1749 (bcopyall || pcopymapDest[i])) 1750 { 1751 void *def_ptr = parm_table[i].ptr; 1752 void *src_ptr = 1753 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault); 1754 void *dest_ptr = 1755 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault); 1756 1757 switch (parm_table[i].type) 1758 { 1759 case P_BOOL: 1760 case P_BOOLREV: 1761 *(BOOL *)dest_ptr = *(BOOL *)src_ptr; 1762 break; 1763 1764 case P_INTEGER: 1765 case P_ENUM: 1766 case P_OCTAL: 1767 *(int *)dest_ptr = *(int *)src_ptr; 1768 break; 1769 1770 case P_CHAR: 1771 *(char *)dest_ptr = *(char *)src_ptr; 1772 break; 1773 1774 case P_STRING: 1775 string_set(dest_ptr,*(char **)src_ptr); 1776 break; 1777 1778 case P_USTRING: 1779 string_set(dest_ptr,*(char **)src_ptr); 1780 strupper(*(char **)dest_ptr); 1781 break; 1782 default: 1783 break; 1784 } 1785 } 1786 1787 if (bcopyall) 1788 { 1789 init_copymap(pserviceDest); 1790 if (pserviceSource->copymap) 1791 memcpy((void *)pserviceDest->copymap, 1792 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS); 1793 } 1794} 1795 1796/*************************************************************************** 1797Check a service for consistency. Return False if the service is in any way 1798incomplete or faulty, else True. 1799***************************************************************************/ 1800static BOOL service_ok(int iService) 1801{ 1802 BOOL bRetval; 1803 1804 bRetval = True; 1805 if (iSERVICE(iService).szService[0] == '\0') 1806 { 1807 DEBUG(0,( "The following message indicates an internal error:\n")); 1808 DEBUG(0,( "No service name in service entry.\n")); 1809 bRetval = False; 1810 } 1811 1812 /* The [printers] entry MUST be printable. I'm all for flexibility, but */ 1813 /* I can't see why you'd want a non-printable printer service... */ 1814 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0) 1815 if (!iSERVICE(iService).bPrint_ok) 1816 { 1817 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n", 1818 iSERVICE(iService).szService)); 1819 iSERVICE(iService).bPrint_ok = True; 1820 } 1821 1822 if (iSERVICE(iService).szPath[0] == '\0' && 1823 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0) 1824 { 1825 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir())); 1826 string_set(&iSERVICE(iService).szPath,tmpdir()); 1827 } 1828 1829 /* If a service is flagged unavailable, log the fact at level 0. */ 1830 if (!iSERVICE(iService).bAvailable) 1831 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n", 1832 iSERVICE(iService).szService)); 1833 1834 return (bRetval); 1835} 1836 1837static struct file_lists { 1838 struct file_lists *next; 1839 char *name; 1840 time_t modtime; 1841} *file_lists = NULL; 1842 1843/******************************************************************* 1844keep a linked list of all config files so we know when one has changed 1845it's date and needs to be reloaded 1846********************************************************************/ 1847static void add_to_file_list(char *fname) 1848{ 1849 struct file_lists *f=file_lists; 1850 1851 while (f) { 1852 if (f->name && !strcmp(f->name,fname)) break; 1853 f = f->next; 1854 } 1855 1856 if (!f) { 1857 f = (struct file_lists *)malloc(sizeof(file_lists[0])); 1858 if (!f) return; 1859 f->next = file_lists; 1860 f->name = strdup(fname); 1861 if (!f->name) { 1862 free(f); 1863 return; 1864 } 1865 file_lists = f; 1866 } 1867 1868 { 1869 pstring n2; 1870 pstrcpy(n2,fname); 1871 standard_sub_basic(n2); 1872 f->modtime = file_modtime(n2); 1873 } 1874 1875} 1876 1877/******************************************************************* 1878check if a config file has changed date 1879********************************************************************/ 1880BOOL lp_file_list_changed(void) 1881{ 1882 struct file_lists *f = file_lists; 1883 DEBUG(6,("lp_file_list_changed()\n")); 1884 1885 while (f) 1886 { 1887 pstring n2; 1888 time_t mod_time; 1889 1890 pstrcpy(n2,f->name); 1891 standard_sub_basic(n2); 1892 1893 DEBUGADD( 6, ( "file %s -> %s last mod_time: %s\n", 1894 f->name, n2, ctime(&f->modtime) ) ); 1895 1896 mod_time = file_modtime(n2); 1897 1898 if (f->modtime != mod_time) { 1899 DEBUGADD(6,("file %s modified: %s\n", n2, ctime(&mod_time))); 1900 f->modtime = mod_time; 1901 return(True); 1902 } 1903 f = f->next; 1904 } 1905 return(False); 1906} 1907 1908/*************************************************************************** 1909 Run standard_sub_basic on netbios name... needed because global_myname 1910 is not accessed through any lp_ macro. 1911 Note: We must *NOT* use string_set() here as ptr points to global_myname. 1912***************************************************************************/ 1913 1914static BOOL handle_netbios_name(char *pszParmValue,char **ptr) 1915{ 1916 pstring netbios_name; 1917 1918 pstrcpy(netbios_name,pszParmValue); 1919 1920 standard_sub_basic(netbios_name); 1921 strupper(netbios_name); 1922 1923 /* 1924 * Convert from UNIX to DOS string - the UNIX to DOS converter 1925 * isn't called on the special handlers. 1926 */ 1927 unix_to_dos(netbios_name, True); 1928 pstrcpy(global_myname,netbios_name); 1929 1930 DEBUG(4,("handle_netbios_name: set global_myname to: %s\n", global_myname)); 1931 1932 return(True); 1933} 1934 1935/*************************************************************************** 1936 Do the work of sourcing in environment variable/value pairs. 1937***************************************************************************/ 1938 1939static BOOL source_env(FILE *fenv) 1940{ 1941 pstring line; 1942 char *varval; 1943 size_t len; 1944 char *p; 1945 1946 while (!feof(fenv)) { 1947 if (fgets(line, sizeof(line), fenv) == NULL) 1948 break; 1949 1950 if(feof(fenv)) 1951 break; 1952 1953 if((len = strlen(line)) == 0) 1954 continue; 1955 1956 if (line[len - 1] == '\n') 1957 line[--len] = '\0'; 1958 1959 if ((varval=malloc(len+1)) == NULL) { 1960 DEBUG(0,("source_env: Not enough memory!\n")); 1961 return(False); 1962 } 1963 1964 DEBUG(4,("source_env: Adding to environment: %s\n", line)); 1965 strncpy(varval, line, len); 1966 varval[len] = '\0'; 1967 1968 p=strchr(line, (int) '='); 1969 if (p == NULL) { 1970 DEBUG(4,("source_env: missing '=': %s\n", line)); 1971 continue; 1972 } 1973 1974 if (putenv(varval)) { 1975 DEBUG(0,("source_env: Failed to put environment variable %s\n", varval )); 1976 continue; 1977 } 1978 1979 *p='\0'; 1980 p++; 1981 DEBUG(4,("source_env: getting var %s = %s\n", line, getenv(line))); 1982 } 1983 1984 DEBUG(4,("source_env: returning successfully\n")); 1985 return(True); 1986} 1987 1988/*************************************************************************** 1989 Handle the source environment operation 1990***************************************************************************/ 1991 1992static BOOL handle_source_env(char *pszParmValue,char **ptr) 1993{ 1994 pstring fname; 1995 char *p = fname; 1996 FILE *env; 1997 BOOL result; 1998 1999 pstrcpy(fname,pszParmValue); 2000 2001 standard_sub_basic(fname); 2002 2003 string_set(ptr,pszParmValue); 2004 2005 DEBUG(4, ("handle_source_env: checking env type\n")); 2006 2007 /* 2008 * Filename starting with '|' means popen and read from stdin. 2009 */ 2010 2011 if (*p == '|') { 2012 2013 DEBUG(4, ("handle_source_env: source env from pipe\n")); 2014 p++; 2015 2016 if ((env = sys_popen(p, "r", True)) == NULL) { 2017 DEBUG(0,("handle_source_env: Failed to popen %s. Error was %s\n", p, strerror(errno) )); 2018 return(False); 2019 } 2020 2021 DEBUG(4, ("handle_source_env: calling source_env()\n")); 2022 result = source_env(env); 2023 sys_pclose(env); 2024 2025 } else { 2026 2027 struct stat st; 2028 2029 DEBUG(4, ("handle_source_env: source env from file %s\n", fname)); 2030 if ((env = sys_fopen(fname, "r")) == NULL) { 2031 DEBUG(0,("handle_source_env: Failed to open file %s, Error was %s\n", fname, strerror(errno) )); 2032 return(False); 2033 } 2034 2035 /* 2036 * Ensure this file is owned by root and not writable by world. 2037 */ 2038 if(fstat(fileno(env), &st) != 0) { 2039 DEBUG(0,("handle_source_env: Failed to stat file %s, Error was %s\n", fname, strerror(errno) )); 2040 fclose(env); 2041 return False; 2042 } 2043 2044 if((st.st_uid != (uid_t)0) || (st.st_mode & S_IWOTH)) { 2045 DEBUG(0,("handle_source_env: unsafe to source env file %s. Not owned by root or world writable\n", fname )); 2046 fclose(env); 2047 return False; 2048 } 2049 2050 result=source_env(env); 2051 fclose(env); 2052 } 2053 return(result); 2054} 2055 2056/*************************************************************************** 2057 handle the interpretation of the coding system parameter 2058 *************************************************************************/ 2059static BOOL handle_coding_system(char *pszParmValue,char **ptr) 2060{ 2061 string_set(ptr,pszParmValue); 2062 interpret_coding_system(pszParmValue); 2063 return(True); 2064} 2065 2066/*************************************************************************** 2067 Handle the interpretation of the character set system parameter. 2068***************************************************************************/ 2069 2070static char *saved_character_set = NULL; 2071 2072static BOOL handle_character_set(char *pszParmValue,char **ptr) 2073{ 2074 /* A dependency here is that the parameter client code page should be 2075 set before this is called. 2076 */ 2077 string_set(ptr,pszParmValue); 2078 strupper(*ptr); 2079 saved_character_set = strdup(*ptr); 2080 interpret_character_set(*ptr,lp_client_code_page()); 2081 return(True); 2082} 2083 2084/*************************************************************************** 2085 Handle the interpretation of the client code page parameter. 2086 We handle this separately so that we can reset the character set 2087 parameter in case this came before 'client code page' in the smb.conf. 2088***************************************************************************/ 2089 2090static BOOL handle_client_code_page(char *pszParmValue,char **ptr) 2091{ 2092 Globals.client_code_page = atoi(pszParmValue); 2093 if (saved_character_set != NULL) 2094 interpret_character_set(saved_character_set,lp_client_code_page()); 2095 return(True); 2096} 2097 2098/*************************************************************************** 2099handle the valid chars lines 2100***************************************************************************/ 2101 2102static BOOL handle_valid_chars(char *pszParmValue,char **ptr) 2103{ 2104 string_set(ptr,pszParmValue); 2105 2106 /* A dependency here is that the parameter client code page must be 2107 set before this is called - as calling codepage_initialise() 2108 would overwrite the valid char lines. 2109 */ 2110 codepage_initialise(lp_client_code_page()); 2111 2112 add_char_string(pszParmValue); 2113 return(True); 2114} 2115 2116/*************************************************************************** 2117handle the include operation 2118***************************************************************************/ 2119 2120static BOOL handle_include(char *pszParmValue,char **ptr) 2121{ 2122 pstring fname; 2123 pstrcpy(fname,pszParmValue); 2124 2125 add_to_file_list(fname); 2126 2127 standard_sub_basic(fname); 2128 2129 string_set(ptr,fname); 2130 2131 if (file_exist(fname,NULL)) 2132 return(pm_process(fname, do_section, do_parameter)); 2133 2134 DEBUG(2,("Can't find include file %s\n",fname)); 2135 2136 return(False); 2137} 2138 2139 2140/*************************************************************************** 2141handle the interpretation of the copy parameter 2142***************************************************************************/ 2143static BOOL handle_copy(char *pszParmValue,char **ptr) 2144{ 2145 BOOL bRetval; 2146 int iTemp; 2147 service serviceTemp; 2148 2149 string_set(ptr,pszParmValue); 2150 2151 init_service(&serviceTemp); 2152 2153 bRetval = False; 2154 2155 DEBUG(3,("Copying service from service %s\n",pszParmValue)); 2156 2157 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) 2158 { 2159 if (iTemp == iServiceIndex) 2160 { 2161 DEBUG(0,("Can't copy service %s - unable to copy self!\n", 2162 pszParmValue)); 2163 } 2164 else 2165 { 2166 copy_service(pSERVICE(iServiceIndex), 2167 &serviceTemp, 2168 iSERVICE(iServiceIndex).copymap); 2169 bRetval = True; 2170 } 2171 } 2172 else 2173 { 2174 DEBUG(0,( "Unable to copy service - source not found: %s\n", 2175 pszParmValue)); 2176 bRetval = False; 2177 } 2178 2179 free_service(&serviceTemp); 2180 return (bRetval); 2181} 2182 2183 2184/*************************************************************************** 2185initialise a copymap 2186***************************************************************************/ 2187static void init_copymap(service *pservice) 2188{ 2189 int i; 2190 if (pservice->copymap) free(pservice->copymap); 2191 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS); 2192 if (!pservice->copymap) 2193 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",(int)NUMPARAMETERS)); 2194 else 2195 for (i=0;i<NUMPARAMETERS;i++) 2196 pservice->copymap[i] = True; 2197} 2198 2199 2200/*************************************************************************** 2201 return the local pointer to a parameter given the service number and the 2202 pointer into the default structure 2203***************************************************************************/ 2204void *lp_local_ptr(int snum, void *ptr) 2205{ 2206 return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault)); 2207} 2208 2209/*************************************************************************** 2210Process a parameter for a particular service number. If snum < 0 2211then assume we are in the globals 2212***************************************************************************/ 2213BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue) 2214{ 2215 int parmnum, i; 2216 void *parm_ptr=NULL; /* where we are going to store the result */ 2217 void *def_ptr=NULL; 2218 2219 parmnum = map_parameter(pszParmName); 2220 2221 if (parmnum < 0) 2222 { 2223 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName)); 2224 return(True); 2225 } 2226 2227 if (parm_table[parmnum].flags & FLAG_DEPRECATED) { 2228 DEBUG(1,("WARNING: The \"%s\"option is deprecated\n", 2229 pszParmName)); 2230 } 2231 2232 def_ptr = parm_table[parmnum].ptr; 2233 2234 /* we might point at a service, the default service or a global */ 2235 if (snum < 0) { 2236 parm_ptr = def_ptr; 2237 } else { 2238 if (parm_table[parmnum].class == P_GLOBAL) { 2239 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName)); 2240 return(True); 2241 } 2242 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault); 2243 } 2244 2245 if (snum >= 0) { 2246 if (!iSERVICE(snum).copymap) 2247 init_copymap(pSERVICE(snum)); 2248 2249 /* this handles the aliases - set the copymap for other entries with 2250 the same data pointer */ 2251 for (i=0;parm_table[i].label;i++) 2252 if (parm_table[i].ptr == parm_table[parmnum].ptr) 2253 iSERVICE(snum).copymap[i] = False; 2254 } 2255 2256 /* if it is a special case then go ahead */ 2257 if (parm_table[parmnum].special) { 2258 parm_table[parmnum].special(pszParmValue,(char **)parm_ptr); 2259 return(True); 2260 } 2261 2262 /* now switch on the type of variable it is */ 2263 switch (parm_table[parmnum].type) 2264 { 2265 case P_BOOL: 2266 set_boolean(parm_ptr,pszParmValue); 2267 break; 2268 2269 case P_BOOLREV: 2270 set_boolean(parm_ptr,pszParmValue); 2271 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr; 2272 break; 2273 2274 case P_INTEGER: 2275 *(int *)parm_ptr = atoi(pszParmValue); 2276 break; 2277 2278 case P_CHAR: 2279 *(char *)parm_ptr = *pszParmValue; 2280 break; 2281 2282 case P_OCTAL: 2283 sscanf(pszParmValue,"%o",(int *)parm_ptr); 2284 break; 2285 2286 case P_STRING: 2287 string_set(parm_ptr,pszParmValue); 2288 if (parm_table[parmnum].flags & FLAG_DOS_STRING) 2289 unix_to_dos(*(char **)parm_ptr, True); 2290 break; 2291 2292 case P_USTRING: 2293 string_set(parm_ptr,pszParmValue); 2294 if (parm_table[parmnum].flags & FLAG_DOS_STRING) 2295 unix_to_dos(*(char **)parm_ptr, True); 2296 strupper(*(char **)parm_ptr); 2297 break; 2298 2299 case P_GSTRING: 2300 pstrcpy((char *)parm_ptr,pszParmValue); 2301 if (parm_table[parmnum].flags & FLAG_DOS_STRING) 2302 unix_to_dos((char *)parm_ptr, True); 2303 break; 2304 2305 case P_UGSTRING: 2306 pstrcpy((char *)parm_ptr,pszParmValue); 2307 if (parm_table[parmnum].flags & FLAG_DOS_STRING) 2308 unix_to_dos((char *)parm_ptr, True); 2309 strupper((char *)parm_ptr); 2310 break; 2311 2312 case P_ENUM: 2313 for (i=0;parm_table[parmnum].enum_list[i].name;i++) { 2314 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) { 2315 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value; 2316 break; 2317 } 2318 } 2319 break; 2320 case P_SEP: 2321 break; 2322 } 2323 2324 return(True); 2325} 2326 2327/*************************************************************************** 2328Process a parameter. 2329***************************************************************************/ 2330static BOOL do_parameter( char *pszParmName, char *pszParmValue ) 2331{ 2332 if( !bInGlobalSection && bGlobalOnly ) 2333 return(True); 2334 2335 DEBUGADD( 3, ( "doing parameter %s = %s\n", pszParmName, pszParmValue ) ); 2336 2337 return( lp_do_parameter( bInGlobalSection ? -2 : iServiceIndex, 2338 pszParmName, 2339 pszParmValue ) ); 2340} 2341 2342 2343/*************************************************************************** 2344print a parameter of the specified type 2345***************************************************************************/ 2346static void print_parameter(struct parm_struct *p,void *ptr, FILE *f) 2347{ 2348 int i; 2349 switch (p->type) { 2350 case P_ENUM: 2351 for (i=0;p->enum_list[i].name;i++) { 2352 if (*(int *)ptr == p->enum_list[i].value) { 2353 fprintf(f,"%s",p->enum_list[i].name); 2354 break; 2355 } 2356 } 2357 break; 2358 2359 case P_BOOL: 2360 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr)); 2361 break; 2362 2363 case P_BOOLREV: 2364 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr)); 2365 break; 2366 2367 case P_INTEGER: 2368 fprintf(f,"%d",*(int *)ptr); 2369 break; 2370 2371 case P_CHAR: 2372 fprintf(f,"%c",*(char *)ptr); 2373 break; 2374 2375 case P_OCTAL: 2376 fprintf(f,"%s",octal_string(*(int *)ptr)); 2377 break; 2378 2379 case P_GSTRING: 2380 case P_UGSTRING: 2381 if ((char *)ptr) 2382 fprintf(f,"%s",(char *)ptr); 2383 break; 2384 2385 case P_STRING: 2386 case P_USTRING: 2387 if (*(char **)ptr) 2388 fprintf(f,"%s",*(char **)ptr); 2389 break; 2390 case P_SEP: 2391 break; 2392 } 2393} 2394 2395 2396/*************************************************************************** 2397check if two parameters are equal 2398***************************************************************************/ 2399static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2) 2400{ 2401 switch (type) 2402 { 2403 case P_BOOL: 2404 case P_BOOLREV: 2405 return(*((BOOL *)ptr1) == *((BOOL *)ptr2)); 2406 2407 case P_INTEGER: 2408 case P_ENUM: 2409 case P_OCTAL: 2410 return(*((int *)ptr1) == *((int *)ptr2)); 2411 2412 case P_CHAR: 2413 return(*((char *)ptr1) == *((char *)ptr2)); 2414 2415 case P_GSTRING: 2416 case P_UGSTRING: 2417 { 2418 char *p1 = (char *)ptr1, *p2 = (char *)ptr2; 2419 if (p1 && !*p1) p1 = NULL; 2420 if (p2 && !*p2) p2 = NULL; 2421 return(p1==p2 || strequal(p1,p2)); 2422 } 2423 case P_STRING: 2424 case P_USTRING: 2425 { 2426 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2; 2427 if (p1 && !*p1) p1 = NULL; 2428 if (p2 && !*p2) p2 = NULL; 2429 return(p1==p2 || strequal(p1,p2)); 2430 } 2431 case P_SEP: 2432 break; 2433 } 2434 return(False); 2435} 2436 2437/*************************************************************************** 2438Process a new section (service). At this stage all sections are services. 2439Later we'll have special sections that permit server parameters to be set. 2440Returns True on success, False on failure. 2441***************************************************************************/ 2442static BOOL do_section(char *pszSectionName) 2443{ 2444 BOOL bRetval; 2445 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) || 2446 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0)); 2447 bRetval = False; 2448 2449 /* removed this because it broke setting printer commands in global 2450 * section. init_locals now uses string_set so it overwrites any 2451 * parameters you just changed with the defaults */ 2452#ifdef notdef 2453 /* if we were in a global section then do the local inits */ 2454 if (bInGlobalSection && !isglobal) 2455 init_locals(); 2456#endif 2457 2458 /* if we've just struck a global section, note the fact. */ 2459 bInGlobalSection = isglobal; 2460 2461 /* check for multiple global sections */ 2462 if (bInGlobalSection) 2463 { 2464 DEBUG( 3, ( "Processing section \"[%s]\"\n", pszSectionName ) ); 2465 return(True); 2466 } 2467 2468 if (!bInGlobalSection && bGlobalOnly) return(True); 2469 2470 /* if we have a current service, tidy it up before moving on */ 2471 bRetval = True; 2472 2473 if (iServiceIndex >= 0) 2474 bRetval = service_ok(iServiceIndex); 2475 2476 /* if all is still well, move to the next record in the services array */ 2477 if (bRetval) 2478 { 2479 /* We put this here to avoid an odd message order if messages are */ 2480 /* issued by the post-processing of a previous section. */ 2481 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName)); 2482 2483 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0) 2484 { 2485 DEBUG(0,("Failed to add a new service\n")); 2486 return(False); 2487 } 2488 } 2489 2490 return (bRetval); 2491} 2492 2493 2494/*************************************************************************** 2495determine if a partcular base parameter is currently set to the default value. 2496***************************************************************************/ 2497static BOOL is_default(int i) 2498{ 2499 if (!defaults_saved) return False; 2500 switch (parm_table[i].type) { 2501 case P_STRING: 2502 case P_USTRING: 2503 return strequal(parm_table[i].def.svalue,*(char **)parm_table[i].ptr); 2504 case P_GSTRING: 2505 case P_UGSTRING: 2506 return strequal(parm_table[i].def.svalue,(char *)parm_table[i].ptr); 2507 case P_BOOL: 2508 case P_BOOLREV: 2509 return parm_table[i].def.bvalue == *(BOOL *)parm_table[i].ptr; 2510 case P_CHAR: 2511 return parm_table[i].def.cvalue == *(char *)parm_table[i].ptr; 2512 case P_INTEGER: 2513 case P_OCTAL: 2514 case P_ENUM: 2515 return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr; 2516 case P_SEP: 2517 break; 2518 } 2519 return False; 2520} 2521 2522 2523/*************************************************************************** 2524Display the contents of the global structure. 2525***************************************************************************/ 2526static void dump_globals(FILE *f) 2527{ 2528 int i; 2529 fprintf(f, "# Global parameters\n[global]\n"); 2530 2531 for (i=0;parm_table[i].label;i++) 2532 if (parm_table[i].class == P_GLOBAL && 2533 parm_table[i].ptr && 2534 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) { 2535 if (parm_table[i].flags & FLAG_DEPRECATED) continue; 2536 if (defaults_saved && is_default(i)) continue; 2537 fprintf(f,"\t%s = ",parm_table[i].label); 2538 print_parameter(&parm_table[i],parm_table[i].ptr, f); 2539 fprintf(f,"\n"); 2540 } 2541} 2542 2543/*************************************************************************** 2544return True if a local parameter is currently set to the global default 2545***************************************************************************/ 2546BOOL lp_is_default(int snum, struct parm_struct *parm) 2547{ 2548 int pdiff = PTR_DIFF(parm->ptr,&sDefault); 2549 2550 return equal_parameter(parm->type, 2551 ((char *)pSERVICE(snum)) + pdiff, 2552 ((char *)&sDefault) + pdiff); 2553} 2554 2555 2556/*************************************************************************** 2557Display the contents of a single services record. 2558***************************************************************************/ 2559static void dump_a_service(service *pService, FILE *f) 2560{ 2561 int i; 2562 if (pService != &sDefault) 2563 fprintf(f,"\n[%s]\n",pService->szService); 2564 2565 for (i=0;parm_table[i].label;i++) 2566 if (parm_table[i].class == P_LOCAL && 2567 parm_table[i].ptr && 2568 (*parm_table[i].label != '-') && 2569 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) { 2570 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault); 2571 2572 if (parm_table[i].flags & FLAG_DEPRECATED) continue; 2573 if (pService == &sDefault) { 2574 if (defaults_saved && is_default(i)) continue; 2575 } else { 2576 if (equal_parameter(parm_table[i].type, 2577 ((char *)pService) + pdiff, 2578 ((char *)&sDefault) + pdiff)) 2579 continue; 2580 } 2581 2582 fprintf(f,"\t%s = ",parm_table[i].label); 2583 print_parameter(&parm_table[i], 2584 ((char *)pService) + pdiff, f); 2585 fprintf(f,"\n"); 2586 } 2587} 2588 2589 2590/*************************************************************************** 2591return info about the next service in a service. snum==-1 gives the globals 2592 2593return NULL when out of parameters 2594***************************************************************************/ 2595struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters) 2596{ 2597 if (snum == -1) { 2598 /* do the globals */ 2599 for (;parm_table[*i].label;(*i)++) { 2600 if (parm_table[*i].class == P_SEPARATOR) 2601 return &parm_table[(*i)++]; 2602 2603 if (!parm_table[*i].ptr || (*parm_table[*i].label == '-')) 2604 continue; 2605 2606 if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr)) 2607 continue; 2608 2609 return &parm_table[(*i)++]; 2610 } 2611 } else { 2612 service *pService = pSERVICE(snum); 2613 2614 for (;parm_table[*i].label;(*i)++) { 2615 if (parm_table[*i].class == P_SEPARATOR) 2616 return &parm_table[(*i)++]; 2617 2618 if (parm_table[*i].class == P_LOCAL && 2619 parm_table[*i].ptr && 2620 (*parm_table[*i].label != '-') && 2621 ((*i) == 0 || 2622 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) { 2623 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault); 2624 2625 if (allparameters || 2626 !equal_parameter(parm_table[*i].type, 2627 ((char *)pService) + pdiff, 2628 ((char *)&sDefault) + pdiff)) { 2629 return &parm_table[(*i)++]; 2630 } 2631 } 2632 } 2633 } 2634 2635 return NULL; 2636} 2637 2638 2639#if 0 2640/*************************************************************************** 2641Display the contents of a single copy structure. 2642***************************************************************************/ 2643static void dump_copy_map(BOOL *pcopymap) 2644{ 2645 int i; 2646 if (!pcopymap) return; 2647 2648 printf("\n\tNon-Copied parameters:\n"); 2649 2650 for (i=0;parm_table[i].label;i++) 2651 if (parm_table[i].class == P_LOCAL && 2652 parm_table[i].ptr && !pcopymap[i] && 2653 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) 2654 { 2655 printf("\t\t%s\n",parm_table[i].label); 2656 } 2657} 2658#endif 2659 2660/*************************************************************************** 2661Return TRUE if the passed service number is within range. 2662***************************************************************************/ 2663BOOL lp_snum_ok(int iService) 2664{ 2665 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable); 2666} 2667 2668 2669/*************************************************************************** 2670auto-load some home services 2671***************************************************************************/ 2672static void lp_add_auto_services(char *str) 2673{ 2674 char *s; 2675 char *p; 2676 int homes; 2677 2678 if (!str) return; 2679 2680 s = strdup(str); 2681 if (!s) return; 2682 2683 homes = lp_servicenumber(HOMES_NAME); 2684 2685 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) { 2686 char *home = get_user_home_dir(p); 2687 2688 if (lp_servicenumber(p) >= 0) continue; 2689 2690 if (home && homes >= 0) { 2691 lp_add_home(p,homes,home); 2692 } 2693 } 2694 free(s); 2695} 2696 2697/*************************************************************************** 2698auto-load one printer 2699***************************************************************************/ 2700void lp_add_one_printer(char *name,char *comment) 2701{ 2702 int printers = lp_servicenumber(PRINTERS_NAME); 2703 int i; 2704 2705 if (lp_servicenumber(name) < 0) { 2706 lp_add_printer(name,printers); 2707 if ((i=lp_servicenumber(name)) >= 0) 2708 string_set(&iSERVICE(i).comment,comment); 2709 } 2710} 2711 2712/*************************************************************************** 2713have we loaded a services file yet? 2714***************************************************************************/ 2715BOOL lp_loaded(void) 2716{ 2717 return(bLoaded); 2718} 2719 2720/*************************************************************************** 2721unload unused services 2722***************************************************************************/ 2723void lp_killunused(BOOL (*snumused)(int )) 2724{ 2725 int i; 2726 for (i=0;i<iNumServices;i++) 2727 if (VALID(i) && (!snumused || !snumused(i))) 2728 { 2729 iSERVICE(i).valid = False; 2730 free_service(pSERVICE(i)); 2731 } 2732} 2733 2734 2735/*************************************************************************** 2736save the curent values of all global and sDefault parameters into the 2737defaults union. This allows swat and testparm to show only the 2738changed (ie. non-default) parameters. 2739***************************************************************************/ 2740static void lp_save_defaults(void) 2741{ 2742 int i; 2743 for (i = 0; parm_table[i].label; i++) { 2744 if (i>0 && parm_table[i].ptr == parm_table[i-1].ptr) continue; 2745 switch (parm_table[i].type) { 2746 case P_STRING: 2747 case P_USTRING: 2748 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr); 2749 break; 2750 case P_GSTRING: 2751 case P_UGSTRING: 2752 parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr); 2753 break; 2754 case P_BOOL: 2755 case P_BOOLREV: 2756 parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr; 2757 break; 2758 case P_CHAR: 2759 parm_table[i].def.cvalue = *(char *)parm_table[i].ptr; 2760 break; 2761 case P_INTEGER: 2762 case P_OCTAL: 2763 case P_ENUM: 2764 parm_table[i].def.ivalue = *(int *)parm_table[i].ptr; 2765 break; 2766 case P_SEP: 2767 break; 2768 } 2769 } 2770 defaults_saved = True; 2771} 2772 2773 2774/*************************************************************************** 2775Load the services array from the services file. Return True on success, 2776False on failure. 2777***************************************************************************/ 2778BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc) 2779{ 2780 pstring n2; 2781 BOOL bRetval; 2782 2783 add_to_file_list(pszFname); 2784 2785 bRetval = False; 2786 2787 bInGlobalSection = True; 2788 bGlobalOnly = global_only; 2789 2790 init_globals(); 2791 2792 init_locals(); 2793 if (save_defaults) { 2794 lp_save_defaults(); 2795 } 2796 2797 pstrcpy(n2,pszFname); 2798 standard_sub_basic(n2); 2799 2800 /* We get sections first, so have to start 'behind' to make up */ 2801 iServiceIndex = -1; 2802 bRetval = pm_process(n2, do_section, do_parameter); 2803 2804 /* finish up the last section */ 2805 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval))); 2806 if (bRetval) 2807 if (iServiceIndex >= 0) 2808 bRetval = service_ok(iServiceIndex); 2809 2810 lp_add_auto_services(lp_auto_services()); 2811 2812 if (add_ipc) 2813 lp_add_ipc(); 2814 2815 set_default_server_announce_type(); 2816 2817 bLoaded = True; 2818 2819 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */ 2820 /* if bWINSsupport is true and we are in the client */ 2821 2822 if (in_client && Globals.bWINSsupport) { 2823 2824 string_set(&Globals.szWINSserver, "127.0.0.1"); 2825 2826 } 2827 2828 return (bRetval); 2829} 2830 2831 2832/*************************************************************************** 2833reset the max number of services 2834***************************************************************************/ 2835void lp_resetnumservices(void) 2836{ 2837 iNumServices = 0; 2838} 2839 2840/*************************************************************************** 2841return the max number of services 2842***************************************************************************/ 2843int lp_numservices(void) 2844{ 2845 return(iNumServices); 2846} 2847 2848/*************************************************************************** 2849Display the contents of the services array in human-readable form. 2850***************************************************************************/ 2851void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint) 2852{ 2853 int iService; 2854 2855 if (show_defaults) { 2856 defaults_saved = False; 2857 } 2858 2859 dump_globals(f); 2860 2861 dump_a_service(&sDefault, f); 2862 2863 for (iService = 0; iService < maxtoprint; iService++) 2864 lp_dump_one(f, show_defaults, iService); 2865} 2866 2867/*************************************************************************** 2868Display the contents of one service in human-readable form. 2869***************************************************************************/ 2870void lp_dump_one(FILE *f, BOOL show_defaults, int snum) 2871{ 2872 if (VALID(snum)) 2873 { 2874 if (iSERVICE(snum).szService[0] == '\0') 2875 return; 2876 dump_a_service(pSERVICE(snum), f); 2877 } 2878} 2879 2880 2881/*************************************************************************** 2882Return the number of the service with the given name, or -1 if it doesn't 2883exist. Note that this is a DIFFERENT ANIMAL from the internal function 2884getservicebyname()! This works ONLY if all services have been loaded, and 2885does not copy the found service. 2886***************************************************************************/ 2887int lp_servicenumber(char *pszServiceName) 2888{ 2889 int iService; 2890 2891 for (iService = iNumServices - 1; iService >= 0; iService--) 2892 if (VALID(iService) && 2893 strequal(lp_servicename(iService), pszServiceName)) 2894 break; 2895 2896 if (iService < 0) 2897 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName)); 2898 2899 return (iService); 2900} 2901 2902/******************************************************************* 2903 a useful volume label function 2904 ******************************************************************/ 2905char *volume_label(int snum) 2906{ 2907 char *ret = lp_volume(snum); 2908 if (!*ret) return(lp_servicename(snum)); 2909 return(ret); 2910} 2911 2912 2913/******************************************************************* 2914 Set the server type we will announce as via nmbd. 2915********************************************************************/ 2916static void set_default_server_announce_type(void) 2917{ 2918 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | 2919 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER); 2920 if(lp_announce_as() == ANNOUNCE_AS_NT_SERVER) 2921 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT); 2922 if(lp_announce_as() == ANNOUNCE_AS_NT_WORKSTATION) 2923 default_server_announce |= SV_TYPE_NT; 2924 else if(lp_announce_as() == ANNOUNCE_AS_WIN95) 2925 default_server_announce |= SV_TYPE_WIN95_PLUS; 2926 else if(lp_announce_as() == ANNOUNCE_AS_WFW) 2927 default_server_announce |= SV_TYPE_WFW; 2928 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0); 2929} 2930 2931 2932/******************************************************************* 2933remove a service 2934********************************************************************/ 2935void lp_remove_service(int snum) 2936{ 2937 pSERVICE(snum)->valid = False; 2938} 2939 2940/******************************************************************* 2941copy a service 2942********************************************************************/ 2943void lp_copy_service(int snum, char *new_name) 2944{ 2945 char *oldname = lp_servicename(snum); 2946 do_section(new_name); 2947 if (snum >= 0) { 2948 snum = lp_servicenumber(new_name); 2949 if (snum >= 0) 2950 lp_do_parameter(snum, "copy", oldname); 2951 } 2952} 2953 2954 2955/******************************************************************* 2956 Get the default server type we will announce as via nmbd. 2957********************************************************************/ 2958int lp_default_server_announce(void) 2959{ 2960 return default_server_announce; 2961} 2962 2963/******************************************************************* 2964 Split the announce version into major and minor numbers. 2965********************************************************************/ 2966int lp_major_announce_version(void) 2967{ 2968 static BOOL got_major = False; 2969 static int major_version = DEFAULT_MAJOR_VERSION; 2970 char *vers; 2971 char *p; 2972 2973 if(got_major) 2974 return major_version; 2975 2976 got_major = True; 2977 if((vers = lp_announce_version()) == NULL) 2978 return major_version; 2979 2980 if((p = strchr(vers, '.')) == 0) 2981 return major_version; 2982 2983 *p = '\0'; 2984 major_version = atoi(vers); 2985 return major_version; 2986} 2987 2988int lp_minor_announce_version(void) 2989{ 2990 static BOOL got_minor = False; 2991 static int minor_version = DEFAULT_MINOR_VERSION; 2992 char *vers; 2993 char *p; 2994 2995 if(got_minor) 2996 return minor_version; 2997 2998 got_minor = True; 2999 if((vers = lp_announce_version()) == NULL) 3000 return minor_version; 3001 3002 if((p = strchr(vers, '.')) == 0) 3003 return minor_version; 3004 3005 p++; 3006 minor_version = atoi(p); 3007 return minor_version; 3008} 3009 3010/*********************************************************** 3011 Set the global name resolution order (used in smbclient). 3012************************************************************/ 3013 3014void lp_set_name_resolve_order(char *new_order) 3015{ 3016 Globals.szNameResolveOrder = new_order; 3017} 3018 3019/*********************************************************** 3020 Set the flag that says if kernel oplocks are available 3021 (called by smbd). 3022************************************************************/ 3023 3024static BOOL kernel_oplocks_available = False; 3025 3026void lp_set_kernel_oplocks(BOOL val) 3027{ 3028 /* 3029 * Only set this to True if kerenl 3030 * oplocks are really available and were 3031 * turned on in the smb.conf file. 3032 */ 3033 3034 if(Globals.bKernelOplocks && val) 3035 kernel_oplocks_available = True; 3036 else 3037 kernel_oplocks_available = False; 3038} 3039 3040/*********************************************************** 3041 Return True if kernel oplocks are available and were turned 3042 on in smb.conf. 3043************************************************************/ 3044 3045BOOL lp_kernel_oplocks(void) 3046{ 3047 return kernel_oplocks_available; 3048} 3049 3050/*********************************************************** 3051 Functions to return the current security masks/modes. If 3052 set to -1 then return the create mask/mode instead. 3053************************************************************/ 3054 3055int lp_security_mask(int snum) 3056{ 3057 int val = _lp_security_mask(snum); 3058 if(val == -1) 3059 return lp_create_mask(snum); 3060 return val; 3061} 3062 3063int lp_force_security_mode(int snum) 3064{ 3065 int val = _lp_force_security_mode(snum); 3066 if(val == -1) 3067 return lp_force_create_mode(snum); 3068 return val; 3069} 3070 3071int lp_dir_security_mask(int snum) 3072{ 3073 int val = _lp_dir_security_mask(snum); 3074 if(val == -1) 3075 return lp_dir_mask(snum); 3076 return val; 3077} 3078 3079int lp_force_dir_security_mode(int snum) 3080{ 3081 int val = _lp_force_dir_security_mode(snum); 3082 if(val == -1) 3083 return lp_force_dir_mode(snum); 3084 return val; 3085} 3086