2 Unix SMB/Netbios implementation.
4 Parameter loading functions
5 Copyright (C) Karl Auer 1993-1998
7 Largely re-written by Andrew Tridgell, September 1994
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * This module provides suitable callback functions for the params
28 * module. It builds the internal table of service details which is
29 * then used by the rest of the server.
33 * 1) add it to the global or service structure definition
34 * 2) add it to the parm_table
35 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
36 * 4) If it's a global then initialise it in init_globals. If a local
37 * (ie. service) parameter then initialise it in the sDefault structure
41 * The configuration file is processed sequentially for speed. It is NOT
42 * accessed randomly as happens in 'real' Windows. For this reason, there
43 * is a fair bit of sequence-dependent code here - ie., code which assumes
44 * that certain things happen before others. In particular, the code which
45 * happens at the boundary between sections is delicately poised, so be
52 /* Set default coding system for KANJI if none specified in Makefile. */
54 * We treat KANJI specially due to historical precedent (it was the
55 * first non-english codepage added to Samba). With the new dynamic
56 * codepage support this is not needed anymore.
58 * The define 'KANJI' is being overloaded to mean 'use kanji codepage
59 * by default' and also 'this is the filename-to-disk conversion
60 * method to use'. This really should be removed and all control
61 * over this left in the smb.conf parameters 'client codepage'
62 * and 'coding system'.
68 BOOL in_client = False; /* Not in the client by default */
71 extern int DEBUGLEVEL;
72 extern pstring user_socket_options;
73 extern pstring global_myname;
76 #define GLOBAL_NAME "global"
80 #define PRINTERS_NAME "printers"
84 #define HOMES_NAME "homes"
87 /* some helpful bits */
88 #define pSERVICE(i) ServicePtrs[i]
89 #define iSERVICE(i) (*pSERVICE(i))
90 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
91 #define VALID(i) iSERVICE(i).valid
93 int keepalive=DEFAULT_KEEPALIVE;
94 extern BOOL use_getwd_cache;
96 extern int extra_time_offset;
98 static BOOL defaults_saved=False;
101 * This structure describes global (ie., server-wide) parameters.
105 char *szPrintcapname;
108 char *szDefaultService;
112 char *szServerString;
113 char *szAutoServices;
114 char *szPasswdProgram;
118 char *szSMBPasswdFile;
119 char *szPasswordServer;
120 char *szSocketOptions;
123 char *szDomainAdminGroup;
124 char *szDomainGuestGroup;
125 char *szDomainAdminUsers;
126 char *szDomainGuestUsers;
127 char *szDomainHostsallow;
128 char *szDomainHostsdeny;
130 #ifdef USING_GROUPNAME_MAP
131 char *szGroupnameMap;
132 #endif /* USING_GROUPNAME_MAP */
133 char *szCharacterSet;
140 char *szCodingSystem;
142 char *szRemoteAnnounce;
143 char *szRemoteBrowseSync;
144 char *szSocketAddress;
145 char *szNISHomeMapName;
146 char *szAnnounceVersion; /* This is initialised in init_globals */
147 char *szNetbiosAliases;
148 char *szDomainOtherSIDs;
149 char *szDomainGroups;
151 char *szNameResolveOrder;
156 char *szLdapRootPassword;
180 int client_code_page;
181 int announce_as; /* This is initialised in init_globals */
182 int machine_password_timeout;
183 int change_notify_timeout;
187 #endif /* WITH_LDAP */
190 char *sslHostsRequire;
191 char *sslHostsResign;
197 char *sslClientPrivKey;
200 BOOL sslReqClientCert;
201 BOOL sslReqServerCert;
202 BOOL sslCompatibility;
203 #endif /* WITH_SSL */
208 BOOL bPreferredMaster;
211 BOOL bEncryptPasswords;
219 BOOL bReadPrediction;
226 BOOL bBindInterfacesOnly;
227 BOOL bUnixPasswdSync;
228 BOOL bPasswdChatDebug;
229 BOOL bOleLockingCompat;
237 static global Globals;
242 * This structure describes a single service.
250 char *szGuestaccount;
251 char *szInvalidUsers;
259 char *szRootPostExec;
260 char *szPrintcommand;
263 char *szLppausecommand;
264 char *szLpresumecommand;
265 char *szQueuepausecommand;
266 char *szQueueresumecommand;
268 char *szPrinterDriver;
269 char *szPrinterDriverLocation;
278 char *szVetoOplockFiles;
288 int iCreate_force_mode;
298 BOOL bShortCasePreserve;
325 BOOL bDeleteReadonly;
327 BOOL bDeleteVetoFiles;
329 BOOL bDosFiletimeResolution;
330 BOOL bFakeDirCreateTimes;
332 char dummy[3]; /* for alignment */
336 /* This is a default service used to prime a services structure */
337 static service sDefault =
340 NULL, /* szService */
342 NULL, /* szUsername */
343 NULL, /* szGuestAccount - this is set in init_globals() */
344 NULL, /* szInvalidUsers */
345 NULL, /* szValidUsers */
346 NULL, /* szAdminUsers */
348 NULL, /* szInclude */
349 NULL, /* szPreExec */
350 NULL, /* szPostExec */
351 NULL, /* szRootPreExec */
352 NULL, /* szRootPostExec */
353 NULL, /* szPrintcommand */
354 NULL, /* szLpqcommand */
355 NULL, /* szLprmcommand */
356 NULL, /* szLppausecommand */
357 NULL, /* szLpresumecommand */
358 NULL, /* szQueuepausecommand */
359 NULL, /* szQueueresumecommand */
360 NULL, /* szPrintername */
361 NULL, /* szPrinterDriver - this is set in init_globals() */
362 NULL, /* szPrinterDriverLocation */
363 NULL, /* szDontdescend */
364 NULL, /* szHostsallow */
365 NULL, /* szHostsdeny */
366 NULL, /* szMagicScript */
367 NULL, /* szMagicOutput */
368 NULL, /* szMangledMap */
369 NULL, /* szVetoFiles */
370 NULL, /* szHideFiles */
371 NULL, /* szVetoOplockFiles */
373 NULL, /* force user */
374 NULL, /* force group */
376 NULL, /* writelist */
379 0, /* iMinPrintSpace */
380 0744, /* iCreate_mask */
381 0000, /* iCreate_force_mode */
382 0755, /* iDir_mask */
383 0000, /* iDir_force_mode */
384 0, /* iMaxConnections */
385 CASE_LOWER, /* iDefaultCase */
386 DEFAULT_PRINTING, /* iPrinting */
387 False, /* bAlternatePerm */
388 False, /* revalidate */
389 False, /* case sensitive */
390 True, /* case preserve */
391 True, /* short case preserve */
392 False, /* case mangle */
394 True, /* bHideDotFiles */
395 True, /* bBrowseable */
396 True, /* bAvailable */
397 True, /* bRead_only */
398 True, /* bNo_set_dir */
399 False, /* bGuest_only */
400 False, /* bGuest_ok */
401 False, /* bPrint_ok */
402 False, /* bPostscript */
403 False, /* bMap_system */
404 False, /* bMap_hidden */
405 True, /* bMap_archive */
407 False, /* bStrictLocking */
408 True, /* bShareModes */
410 False, /* bOnlyUser */
411 True, /* bMangledNames */
412 True, /* bWidelinks */
413 True, /* bSymlinks */
414 False, /* bSyncAlways */
415 False, /* bStrictSync */
416 '~', /* magic char */
418 False, /* bDeleteReadonly */
419 False, /* bFakeOplocks */
420 False, /* bDeleteVetoFiles */
421 False, /* bDosFiletimes */
422 False, /* bDosFiletimeResolution */
423 False, /* bFakeDirCreateTimes */
424 True, /* bBlockingLocks */
430 /* local variables */
431 static service **ServicePtrs = NULL;
432 static int iNumServices = 0;
433 static int iServiceIndex = 0;
434 static BOOL bInGlobalSection = True;
435 static BOOL bGlobalOnly = False;
436 static int default_server_announce;
438 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
440 /* prototypes for the special type handlers */
441 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
442 static BOOL handle_include(char *pszParmValue, char **ptr);
443 static BOOL handle_copy(char *pszParmValue, char **ptr);
444 static BOOL handle_character_set(char *pszParmValue,char **ptr);
445 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
447 static void set_default_server_announce_type(void);
449 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
450 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"},
451 {PROTOCOL_COREPLUS, "COREPLUS"},
452 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
454 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
455 {SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"},
458 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
459 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
460 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
461 {PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"},
464 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
465 {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
467 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
469 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
472 static struct enum_list enum_ssl_version[] = {{SMB_SSL_V2, "ssl2"}, {SMB_SSL_V3, "ssl3"},
473 {SMB_SSL_V23, "ssl2or3"}, {SMB_SSL_TLS1, "tls1"}, {-1, NULL}};
476 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
477 static struct parm_struct parm_table[] =
479 {"Base Options", P_SEP, P_SEPARATOR},
480 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
481 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
482 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
483 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
484 {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, NULL, NULL, FLAG_BASIC},
485 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
486 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC},
487 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
488 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0},
490 {"Security Options", P_SEP, P_SEPARATOR},
491 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
492 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
493 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC},
494 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
495 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
496 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
497 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
498 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
499 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
500 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
501 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
502 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0},
503 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
504 {"passwd chat debug",P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0},
505 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
506 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
507 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
508 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0},
509 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL|FLAG_DEPRECATED},
510 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL},
511 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL},
512 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
513 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
514 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
515 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL},
516 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL},
517 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL},
518 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL},
519 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL},
520 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, 0},
521 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
522 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
523 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC},
524 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
525 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
526 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
527 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
528 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
529 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL},
530 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
531 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
532 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL},
533 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
534 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
535 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
536 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
537 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, 0},
538 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
539 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
540 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
541 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
544 {"Secure Socket Layer Options", P_SEP, P_SEPARATOR},
545 {"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0 },
546 {"ssl hosts", P_STRING, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0 },
547 {"ssl hosts resign", P_STRING, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0} ,
548 {"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0 },
549 {"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0 },
550 {"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslCert, NULL, NULL, 0 },
551 {"ssl server key", P_STRING, P_GLOBAL, &Globals.sslPrivKey, NULL, NULL, 0 },
552 {"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0 },
553 {"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0 },
554 {"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL , 0},
555 {"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL , 0},
556 {"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0 },
557 {"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0},
558 {"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0 },
559 #endif /* WITH_SSL */
561 {"Logging Options", P_SEP, P_SEPARATOR},
562 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
563 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
564 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
565 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
566 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
567 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
568 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
569 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
570 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
572 {"Protocol Options", P_SEP, P_SEPARATOR},
573 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
574 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
575 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
576 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
577 {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0},
578 {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0},
579 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
580 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
581 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
582 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
583 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0},
584 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
585 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
586 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0},
587 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
588 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
589 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
591 {"Tuning Options", P_SEP, P_SEPARATOR},
592 {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0},
593 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
594 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
595 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
596 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
597 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0},
598 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
599 {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0},
600 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0},
601 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0},
602 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
603 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0},
604 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
605 {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0},
606 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, 0},
607 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0},
609 {"Printing Options", P_SEP, P_SEPARATOR},
610 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0},
611 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
612 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
613 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, 0},
614 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
615 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
616 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
617 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL},
618 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
619 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
620 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
621 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_GLOBAL},
622 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_GLOBAL},
623 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_GLOBAL},
624 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_GLOBAL},
626 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
627 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
628 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
629 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_GLOBAL},
632 {"Filename Handling", P_SEP, P_SEPARATOR},
633 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
634 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
635 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
636 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
637 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0},
638 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, 0},
639 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_GLOBAL},
640 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
641 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_GLOBAL},
642 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_GLOBAL},
643 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_GLOBAL},
644 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_GLOBAL},
645 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_GLOBAL},
646 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_GLOBAL},
647 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_GLOBAL},
648 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_GLOBAL},
649 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_GLOBAL},
650 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_GLOBAL},
651 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_GLOBAL},
652 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_GLOBAL},
653 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_GLOBAL},
654 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_GLOBAL},
655 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0},
657 {"Domain Options", P_SEP, P_SEPARATOR},
658 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
659 {"domain admin group",P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0},
660 {"domain guest group",P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0},
661 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0},
662 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0},
663 #ifdef USING_GROUPNAME_MAP
664 {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0},
665 #endif /* USING_GROUPNAME_MAP */
666 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0},
668 {"Logon Options", P_SEP, P_SEPARATOR},
669 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
670 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0},
671 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
672 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0},
673 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
675 {"Browse Options", P_SEP, P_SEPARATOR},
676 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC},
677 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0},
678 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
679 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, FLAG_BASIC},
680 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
681 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC},
682 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, FLAG_BASIC},
683 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
684 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
685 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
687 {"WINS Options", P_SEP, P_SEPARATOR},
688 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
689 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0},
690 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC},
691 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC},
693 {"Locking Options", P_SEP, P_SEPARATOR},
694 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, 0},
695 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
696 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
697 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_GLOBAL},
698 {"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, FLAG_GLOBAL},
699 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
700 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_GLOBAL},
701 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_GLOBAL},
704 {"Ldap Options", P_SEP, P_SEPARATOR},
705 {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
706 {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
707 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0},
708 {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0},
709 {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0},
710 {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword,NULL, NULL, 0},
711 #endif /* WITH_LDAP */
714 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
715 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
716 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
717 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
718 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
719 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
720 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
721 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
722 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
723 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
724 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
725 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
726 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0},
727 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL, 0},
728 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
729 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
730 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
731 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0},
732 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
733 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
734 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
735 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
736 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
737 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
738 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, 0},
739 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, 0},
740 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, 0},
741 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, 0},
742 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, 0},
743 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, 0},
744 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, 0},
745 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_GLOBAL},
746 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_GLOBAL},
747 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, 0},
748 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, 0},
749 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, 0},
750 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_GLOBAL},
751 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_GLOBAL},
752 {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_GLOBAL},
754 {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_GLOBAL},
755 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0},
757 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
762 /***************************************************************************
763 Initialise the global parameter structure.
764 ***************************************************************************/
765 static void init_globals(void)
767 static BOOL done_init = False;
773 bzero((void *)&Globals,sizeof(Globals));
775 for (i = 0; parm_table[i].label; i++)
776 if ((parm_table[i].type == P_STRING ||
777 parm_table[i].type == P_USTRING) &&
779 string_init(parm_table[i].ptr,"");
781 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
782 string_set(&sDefault.szPrinterDriver, "NULL");
783 string_set(&sDefault.fstype, FSTYPE_STRING);
789 DEBUG(3,("Initialising global parameters\n"));
791 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
792 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
793 string_set(&Globals.szWorkGroup, WORKGROUP);
794 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
795 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
796 string_set(&Globals.szDriverFile, DRIVERFILE);
797 string_set(&Globals.szLockDir, LOCKDIR);
798 string_set(&Globals.szRootdir, "/");
799 string_set(&Globals.szSmbrun, SMBRUN);
800 string_set(&Globals.szSocketAddress, "0.0.0.0");
801 pstrcpy(s, "Samba ");
803 string_set(&Globals.szServerString,s);
804 slprintf(s,sizeof(s)-1, "%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
805 string_set(&Globals.szAnnounceVersion,s);
807 pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
809 string_set(&Globals.szLogonDrive, "");
810 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
811 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
812 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
814 string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast");
816 Globals.bLoadPrinters = True;
817 Globals.bUseRhosts = False;
818 Globals.max_packet = 65535;
819 Globals.mangled_stack = 50;
820 Globals.max_xmit = 65535;
821 Globals.max_mux = 50; /* This is *needed* for profile support. */
822 Globals.lpqcachetime = 10;
823 Globals.pwordlevel = 0;
824 Globals.unamelevel = 0;
825 Globals.deadtime = 0;
826 Globals.max_log_size = 5000;
827 Globals.max_open_files = MAX_OPEN_FILES;
828 Globals.maxprotocol = PROTOCOL_NT1;
829 Globals.security = SEC_USER;
830 Globals.bEncryptPasswords = False;
831 Globals.bUpdateEncrypt = False;
832 Globals.bReadRaw = True;
833 Globals.bWriteRaw = True;
834 Globals.bReadPrediction = False;
835 Globals.bReadbmpx = True;
836 Globals.bNullPasswords = False;
837 Globals.bStripDot = False;
839 Globals.bSyslogOnly = False;
840 Globals.bTimestampLogs = True;
841 Globals.os_level = 0;
842 Globals.max_ttl = 60*60*24*3; /* 3 days default. */
843 Globals.max_wins_ttl = 60*60*24*6; /* 6 days default. */
844 Globals.min_wins_ttl = 60*60*6; /* 6 hours default. */
845 Globals.machine_password_timeout = 60*60*24*7; /* 7 days default. */
846 Globals.change_notify_timeout = 60; /* 1 minute default. */
847 Globals.ReadSize = 16*1024;
848 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
849 Globals.lm_interval = 60;
850 Globals.shmem_size = SHMEM_SIZE;
851 Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */
852 Globals.announce_as = ANNOUNCE_AS_NT;
853 Globals.bUnixRealname = False;
854 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
855 Globals.bNISHomeMap = False;
856 #ifdef WITH_NISPLUS_HOME
857 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
859 string_set(&Globals.szNISHomeMapName, "auto.home");
862 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
863 Globals.bTimeServer = False;
864 Globals.bBindInterfacesOnly = False;
865 Globals.bUnixPasswdSync = False;
866 Globals.bPasswdChatDebug = False;
867 Globals.bOleLockingCompat = True;
868 Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */
869 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
870 Globals.bStatCache = True; /* use stat cache by default */
873 /* default values for ldap */
874 string_set(&Globals.szLdapServer, "localhost");
875 Globals.ldap_port=389;
876 #endif /* WITH_LDAP */
879 Globals.sslVersion = SMB_SSL_V23;
880 Globals.sslHostsRequire = NULL;
881 Globals.sslHostsResign = NULL;
882 Globals.sslCaCertDir = NULL;
883 Globals.sslCaCertFile = NULL;
884 Globals.sslCert = NULL;
885 Globals.sslPrivKey = NULL;
886 Globals.sslClientCert = NULL;
887 Globals.sslClientPrivKey = NULL;
888 Globals.sslCiphers = NULL;
889 Globals.sslEnabled = False;
890 Globals.sslReqClientCert = False;
891 Globals.sslReqServerCert = False;
892 Globals.sslCompatibility = False;
893 #endif /* WITH_SSL */
895 /* these parameters are set to defaults that are more appropriate
896 for the increasing samba install base:
898 as a member of the workgroup, that will possibly become a
899 _local_ master browser (lm = True). this is opposed to a forced
900 local master browser startup (pm = True).
902 doesn't provide WINS server service by default (wsupp = False),
903 and doesn't provide domain master browser services by default, either.
907 Globals.bPreferredMaster = False;
908 Globals.bLocalMaster = True;
909 Globals.bDomainMaster = False;
910 Globals.bDomainLogons = False;
911 Globals.bBrowseList = True;
912 Globals.bWINSsupport = False;
913 Globals.bWINSproxy = False;
915 Globals.bDNSproxy = True;
918 * smbd will check at runtime to see if this value
919 * will really be used or not.
921 Globals.bKernelOplocks = True;
924 * This must be done last as it checks the value in
928 interpret_coding_system(KANJI);
931 /***************************************************************************
932 check if a string is initialised and if not then initialise it
933 ***************************************************************************/
934 static void string_initial(char **s,char *v)
941 /***************************************************************************
942 Initialise the sDefault parameter structure.
943 ***************************************************************************/
944 static void init_locals(void)
946 /* choose defaults depending on the type of printing */
947 switch (sDefault.iPrinting)
953 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
954 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
955 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
960 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
961 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
962 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
964 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
965 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
966 string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
967 string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
969 string_initial(&sDefault.szQueuepausecommand, "disable %p");
970 string_initial(&sDefault.szQueueresumecommand, "enable %p");
975 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
976 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
977 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
981 string_initial(&sDefault.szLpqcommand,"qstat -l -d%p");
982 string_initial(&sDefault.szLprmcommand,"qstat -s -j%j -c");
983 string_initial(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
984 string_initial(&sDefault.szLppausecommand,"qstat -s -j%j -h");
985 string_initial(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
992 /******************************************************************* a
993 convenience routine to grab string parameters into a rotating buffer,
994 and run standard_sub_basic on them. The buffers can be written to by
995 callers without affecting the source string.
996 ********************************************************************/
997 static char *lp_string(char *s)
999 static char *bufs[10];
1000 static int buflen[10];
1001 static int next = -1;
1004 int len = s?strlen(s):0;
1007 /* initialisation */
1008 for (i=0;i<10;i++) {
1015 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
1016 substitution room */
1018 if (buflen[next] != len) {
1020 if (bufs[next]) free(bufs[next]);
1021 bufs[next] = (char *)malloc(len);
1023 DEBUG(0,("out of memory in lp_string()"));
1028 ret = &bufs[next][0];
1036 trim_string(ret, "\"", "\"");
1038 standard_sub_basic(ret);
1044 In this section all the functions that are used to access the
1045 parameters from the rest of the program are defined
1048 #define FN_GLOBAL_STRING(fn_name,ptr) \
1049 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1050 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1051 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1052 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1053 char fn_name(void) {return(*(char *)(ptr));}
1054 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1055 int fn_name(void) {return(*(int *)(ptr));}
1057 #define FN_LOCAL_STRING(fn_name,val) \
1058 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
1059 #define FN_LOCAL_BOOL(fn_name,val) \
1060 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1061 #define FN_LOCAL_CHAR(fn_name,val) \
1062 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1063 #define FN_LOCAL_INTEGER(fn_name,val) \
1064 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1066 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
1067 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
1068 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
1069 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
1070 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
1071 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
1072 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
1073 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
1074 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
1075 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
1076 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
1077 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
1078 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
1079 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
1080 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
1081 FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder)
1082 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
1083 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
1084 #ifdef USING_GROUPNAME_MAP
1085 FN_GLOBAL_STRING(lp_groupname_map,&Globals.szGroupnameMap)
1086 #endif /* USING_GROUPNAME_MAP */
1087 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
1088 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
1089 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
1090 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
1091 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
1092 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
1093 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
1094 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
1095 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
1096 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
1097 static FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
1098 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
1099 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
1100 FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction)
1102 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
1103 FN_GLOBAL_STRING(lp_domain_admin_group,&Globals.szDomainAdminGroup)
1104 FN_GLOBAL_STRING(lp_domain_guest_group,&Globals.szDomainGuestGroup)
1105 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
1106 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
1109 FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer);
1110 FN_GLOBAL_STRING(lp_ldap_suffix,&Globals.szLdapSuffix);
1111 FN_GLOBAL_STRING(lp_ldap_filter,&Globals.szLdapFilter);
1112 FN_GLOBAL_STRING(lp_ldap_root,&Globals.szLdapRoot);
1113 FN_GLOBAL_STRING(lp_ldap_rootpasswd,&Globals.szLdapRootPassword);
1114 #endif /* WITH_LDAP */
1117 FN_GLOBAL_INTEGER(lp_ssl_version,&Globals.sslVersion);
1118 FN_GLOBAL_STRING(lp_ssl_hosts,&Globals.sslHostsRequire);
1119 FN_GLOBAL_STRING(lp_ssl_hosts_resign,&Globals.sslHostsResign);
1120 FN_GLOBAL_STRING(lp_ssl_cacertdir,&Globals.sslCaCertDir);
1121 FN_GLOBAL_STRING(lp_ssl_cacertfile,&Globals.sslCaCertFile);
1122 FN_GLOBAL_STRING(lp_ssl_cert,&Globals.sslCert);
1123 FN_GLOBAL_STRING(lp_ssl_privkey,&Globals.sslPrivKey);
1124 FN_GLOBAL_STRING(lp_ssl_client_cert,&Globals.sslClientCert);
1125 FN_GLOBAL_STRING(lp_ssl_client_privkey,&Globals.sslClientPrivKey);
1126 FN_GLOBAL_STRING(lp_ssl_ciphers,&Globals.sslCiphers);
1127 FN_GLOBAL_BOOL(lp_ssl_enabled,&Globals.sslEnabled);
1128 FN_GLOBAL_BOOL(lp_ssl_reqClientCert,&Globals.sslReqClientCert);
1129 FN_GLOBAL_BOOL(lp_ssl_reqServerCert,&Globals.sslReqServerCert);
1130 FN_GLOBAL_BOOL(lp_ssl_compatibility,&Globals.sslCompatibility);
1131 #endif /* WITH_SSL */
1133 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
1134 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
1135 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
1136 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
1137 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
1138 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
1139 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
1140 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
1141 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
1142 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
1143 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
1144 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
1145 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
1146 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
1147 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
1148 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
1149 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
1150 FN_GLOBAL_BOOL(lp_update_encrypted,&Globals.bUpdateEncrypt)
1151 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
1152 FN_GLOBAL_BOOL(lp_timestamp_logs,&Globals.bTimestampLogs)
1153 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
1154 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
1155 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
1156 static FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
1157 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
1158 FN_GLOBAL_BOOL(lp_unix_password_sync,&Globals.bUnixPasswdSync)
1159 FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug)
1160 FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat)
1161 FN_GLOBAL_BOOL(lp_nt_smb_support,&Globals.bNTSmbSupport)
1162 FN_GLOBAL_BOOL(lp_nt_pipe_support,&Globals.bNTPipeSupport)
1163 FN_GLOBAL_BOOL(lp_stat_cache,&Globals.bStatCache)
1165 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
1166 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
1167 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
1168 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
1169 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
1170 FN_GLOBAL_INTEGER(lp_max_open_files,&Globals.max_open_files)
1171 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
1172 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
1173 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
1174 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
1175 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
1176 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
1177 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
1178 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
1179 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
1180 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
1181 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
1182 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
1183 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
1184 static FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
1185 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
1186 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
1187 FN_GLOBAL_INTEGER(lp_machine_password_timeout,&Globals.machine_password_timeout)
1188 FN_GLOBAL_INTEGER(lp_change_notify_timeout,&Globals.change_notify_timeout)
1189 FN_GLOBAL_INTEGER(lp_stat_cache_size,&Globals.stat_cache_size)
1192 FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port)
1193 #endif /* WITH_LDAP */
1195 FN_LOCAL_STRING(lp_preexec,szPreExec)
1196 FN_LOCAL_STRING(lp_postexec,szPostExec)
1197 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
1198 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
1199 FN_LOCAL_STRING(lp_servicename,szService)
1200 FN_LOCAL_STRING(lp_pathname,szPath)
1201 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
1202 FN_LOCAL_STRING(lp_username,szUsername)
1203 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
1204 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
1205 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
1206 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
1207 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
1208 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
1209 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
1210 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
1211 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
1212 FN_LOCAL_STRING(lp_queuepausecommand,szQueuepausecommand)
1213 FN_LOCAL_STRING(lp_queueresumecommand,szQueueresumecommand)
1214 FN_LOCAL_STRING(lp_printername,szPrintername)
1215 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
1216 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
1217 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
1218 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
1219 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
1220 FN_LOCAL_STRING(lp_comment,comment)
1221 FN_LOCAL_STRING(lp_force_user,force_user)
1222 FN_LOCAL_STRING(lp_force_group,force_group)
1223 FN_LOCAL_STRING(lp_readlist,readlist)
1224 FN_LOCAL_STRING(lp_writelist,writelist)
1225 FN_LOCAL_STRING(lp_fstype,fstype)
1226 static FN_LOCAL_STRING(lp_volume,volume)
1227 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
1228 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
1229 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
1230 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
1231 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
1233 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
1234 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
1235 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1236 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1237 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1238 FN_LOCAL_BOOL(lp_status,status)
1239 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1240 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1241 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1242 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1243 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1244 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1245 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1246 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1247 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1248 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1249 FN_LOCAL_BOOL(lp_locking,bLocking)
1250 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1251 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1252 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1253 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1254 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1255 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1256 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1257 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1258 FN_LOCAL_BOOL(lp_strict_sync,bStrictSync)
1259 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1260 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1261 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1262 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1263 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1264 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
1265 FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
1266 FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks)
1268 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1269 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1270 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1271 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1272 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1273 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1274 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1275 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1277 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1281 /* local prototypes */
1282 static int strwicmp( char *psz1, char *psz2 );
1283 static int map_parameter( char *pszParmName);
1284 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1285 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1286 static void copy_service( service *pserviceDest,
1287 service *pserviceSource,
1288 BOOL *pcopymapDest );
1289 static BOOL service_ok(int iService);
1290 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1291 static BOOL do_section(char *pszSectionName);
1292 static void init_copymap(service *pservice);
1295 /***************************************************************************
1296 initialise a service to the defaults
1297 ***************************************************************************/
1298 static void init_service(service *pservice)
1300 bzero((char *)pservice,sizeof(service));
1301 copy_service(pservice,&sDefault,NULL);
1305 /***************************************************************************
1306 free the dynamically allocated parts of a service struct
1307 ***************************************************************************/
1308 static void free_service(service *pservice)
1314 if(pservice->szService)
1315 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1317 string_free(&pservice->szService);
1318 if (pservice->copymap)
1320 free(pservice->copymap);
1321 pservice->copymap = NULL;
1324 for (i=0;parm_table[i].label;i++)
1325 if ((parm_table[i].type == P_STRING ||
1326 parm_table[i].type == P_USTRING) &&
1327 parm_table[i].class == P_LOCAL)
1328 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1331 /***************************************************************************
1332 add a new service to the services array initialising it with the given
1334 ***************************************************************************/
1335 static int add_a_service(service *pservice, char *name)
1339 int num_to_alloc = iNumServices+1;
1341 tservice = *pservice;
1343 /* it might already exist */
1346 i = getservicebyname(name,NULL);
1351 /* find an invalid one */
1352 for (i=0;i<iNumServices;i++)
1353 if (!pSERVICE(i)->valid)
1356 /* if not, then create one */
1357 if (i == iNumServices)
1359 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1361 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1363 if (!ServicePtrs || !pSERVICE(iNumServices))
1369 free_service(pSERVICE(i));
1371 pSERVICE(i)->valid = True;
1373 init_service(pSERVICE(i));
1374 copy_service(pSERVICE(i),&tservice,NULL);
1376 string_set(&iSERVICE(i).szService,name);
1381 /***************************************************************************
1382 add a new home service, with the specified home directory, defaults coming
1384 ***************************************************************************/
1385 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1387 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1392 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1393 string_set(&iSERVICE(i).szPath,pszHomedir);
1394 if (!(*(iSERVICE(i).comment)))
1397 slprintf(comment,sizeof(comment)-1,
1398 "Home directory of %s",pszHomename);
1399 string_set(&iSERVICE(i).comment,comment);
1401 iSERVICE(i).bAvailable = sDefault.bAvailable;
1402 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1404 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1409 /***************************************************************************
1410 add a new service, based on an old one
1411 ***************************************************************************/
1412 int lp_add_service(char *pszService, int iDefaultService)
1414 return(add_a_service(pSERVICE(iDefaultService),pszService));
1418 /***************************************************************************
1420 ***************************************************************************/
1421 static BOOL lp_add_ipc(void)
1424 int i = add_a_service(&sDefault,"IPC$");
1429 slprintf(comment,sizeof(comment)-1,
1430 "IPC Service (%s)", Globals.szServerString );
1432 string_set(&iSERVICE(i).szPath,tmpdir());
1433 string_set(&iSERVICE(i).szUsername,"");
1434 string_set(&iSERVICE(i).comment,comment);
1435 string_set(&iSERVICE(i).fstype,"IPC");
1436 iSERVICE(i).status = False;
1437 iSERVICE(i).iMaxConnections = 0;
1438 iSERVICE(i).bAvailable = True;
1439 iSERVICE(i).bRead_only = True;
1440 iSERVICE(i).bGuest_only = False;
1441 iSERVICE(i).bGuest_ok = True;
1442 iSERVICE(i).bPrint_ok = False;
1443 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1445 DEBUG(3,("adding IPC service\n"));
1451 /***************************************************************************
1452 add a new printer service, with defaults coming from service iFrom
1453 ***************************************************************************/
1454 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1456 char *comment = "From Printcap";
1457 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1462 /* note that we do NOT default the availability flag to True - */
1463 /* we take it from the default service passed. This allows all */
1464 /* dynamic printers to be disabled by disabling the [printers] */
1465 /* entry (if/when the 'available' keyword is implemented!). */
1467 /* the printer name is set to the service name. */
1468 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1469 string_set(&iSERVICE(i).comment,comment);
1470 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1471 /* Printers cannot be read_only. */
1472 iSERVICE(i).bRead_only = False;
1473 /* No share modes on printer services. */
1474 iSERVICE(i).bShareModes = False;
1475 /* No oplocks on printer services. */
1476 iSERVICE(i).bOpLocks = False;
1477 /* Printer services must be printable. */
1478 iSERVICE(i).bPrint_ok = True;
1480 DEBUG(3,("adding printer service %s\n",pszPrintername));
1486 /***************************************************************************
1487 Do a case-insensitive, whitespace-ignoring string compare.
1488 ***************************************************************************/
1489 static int strwicmp(char *psz1, char *psz2)
1491 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1492 /* appropriate value. */
1502 /* sync the strings on first non-whitespace */
1505 while (isspace(*psz1))
1507 while (isspace(*psz2))
1509 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1514 return (*psz1 - *psz2);
1517 /***************************************************************************
1518 Map a parameter's string representation to something we can use.
1519 Returns False if the parameter string is not recognised, else TRUE.
1520 ***************************************************************************/
1521 static int map_parameter(char *pszParmName)
1525 if (*pszParmName == '-')
1528 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1529 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1532 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1537 /***************************************************************************
1538 Set a boolean variable from the text value stored in the passed string.
1539 Returns True in success, False if the passed string does not correctly
1540 represent a boolean.
1541 ***************************************************************************/
1542 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1547 if (strwicmp(pszParmValue, "yes") == 0 ||
1548 strwicmp(pszParmValue, "true") == 0 ||
1549 strwicmp(pszParmValue, "1") == 0)
1552 if (strwicmp(pszParmValue, "no") == 0 ||
1553 strwicmp(pszParmValue, "False") == 0 ||
1554 strwicmp(pszParmValue, "0") == 0)
1558 DEBUG(0,("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1565 /***************************************************************************
1566 Find a service by name. Otherwise works like get_service.
1567 ***************************************************************************/
1568 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1572 for (iService = iNumServices - 1; iService >= 0; iService--)
1573 if (VALID(iService) &&
1574 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1576 if (pserviceDest != NULL)
1577 copy_service(pserviceDest, pSERVICE(iService), NULL);
1586 /***************************************************************************
1587 Copy a service structure to another
1589 If pcopymapDest is NULL then copy all fields
1590 ***************************************************************************/
1591 static void copy_service(service *pserviceDest,
1592 service *pserviceSource,
1596 BOOL bcopyall = (pcopymapDest == NULL);
1598 for (i=0;parm_table[i].label;i++)
1599 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1600 (bcopyall || pcopymapDest[i]))
1602 void *def_ptr = parm_table[i].ptr;
1604 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1606 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1608 switch (parm_table[i].type)
1612 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1618 *(int *)dest_ptr = *(int *)src_ptr;
1622 *(char *)dest_ptr = *(char *)src_ptr;
1626 string_set(dest_ptr,*(char **)src_ptr);
1630 string_set(dest_ptr,*(char **)src_ptr);
1631 strupper(*(char **)dest_ptr);
1640 init_copymap(pserviceDest);
1641 if (pserviceSource->copymap)
1642 memcpy((void *)pserviceDest->copymap,
1643 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1647 /***************************************************************************
1648 Check a service for consistency. Return False if the service is in any way
1649 incomplete or faulty, else True.
1650 ***************************************************************************/
1651 static BOOL service_ok(int iService)
1656 if (iSERVICE(iService).szService[0] == '\0')
1658 DEBUG(0,( "The following message indicates an internal error:\n"));
1659 DEBUG(0,( "No service name in service entry.\n"));
1663 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1664 /* I can't see why you'd want a non-printable printer service... */
1665 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1666 if (!iSERVICE(iService).bPrint_ok)
1668 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1669 iSERVICE(iService).szService));
1670 iSERVICE(iService).bPrint_ok = True;
1673 if (iSERVICE(iService).szPath[0] == '\0' &&
1674 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1676 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1677 string_set(&iSERVICE(iService).szPath,tmpdir());
1680 /* If a service is flagged unavailable, log the fact at level 0. */
1681 if (!iSERVICE(iService).bAvailable)
1682 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1683 iSERVICE(iService).szService));
1688 static struct file_lists {
1689 struct file_lists *next;
1692 } *file_lists = NULL;
1694 /*******************************************************************
1695 keep a linked list of all config files so we know when one has changed
1696 it's date and needs to be reloaded
1697 ********************************************************************/
1698 static void add_to_file_list(char *fname)
1700 struct file_lists *f=file_lists;
1703 if (f->name && !strcmp(f->name,fname)) break;
1708 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1710 f->next = file_lists;
1711 f->name = strdup(fname);
1722 standard_sub_basic(n2);
1723 f->modtime = file_modtime(n2);
1728 /*******************************************************************
1729 check if a config file has changed date
1730 ********************************************************************/
1731 BOOL lp_file_list_changed(void)
1733 struct file_lists *f = file_lists;
1734 DEBUG(6,("lp_file_list_changed()\n"));
1741 pstrcpy(n2,f->name);
1742 standard_sub_basic(n2);
1744 DEBUGADD( 6, ( "file %s -> %s last mod_time: %s\n",
1745 f->name, n2, ctime(&f->modtime) ) );
1747 mod_time = file_modtime(n2);
1749 if (f->modtime != mod_time) {
1750 DEBUGADD(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1751 f->modtime = mod_time;
1759 /***************************************************************************
1760 handle the interpretation of the coding system parameter
1761 *************************************************************************/
1762 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1764 string_set(ptr,pszParmValue);
1765 interpret_coding_system(pszParmValue);
1769 /***************************************************************************
1770 handle the interpretation of the character set system parameter
1771 ***************************************************************************/
1772 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1774 string_set(ptr,pszParmValue);
1775 interpret_character_set(pszParmValue);
1780 /***************************************************************************
1781 handle the valid chars lines
1782 ***************************************************************************/
1783 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1785 string_set(ptr,pszParmValue);
1787 /* A dependency here is that the parameter client code page must be
1788 set before this is called - as calling codepage_initialise()
1789 would overwrite the valid char lines.
1791 codepage_initialise(lp_client_code_page());
1793 add_char_string(pszParmValue);
1798 /***************************************************************************
1799 handle the include operation
1800 ***************************************************************************/
1801 static BOOL handle_include(char *pszParmValue,char **ptr)
1804 pstrcpy(fname,pszParmValue);
1806 add_to_file_list(fname);
1808 standard_sub_basic(fname);
1810 string_set(ptr,fname);
1812 if (file_exist(fname,NULL))
1813 return(pm_process(fname, do_section, do_parameter));
1815 DEBUG(2,("Can't find include file %s\n",fname));
1821 /***************************************************************************
1822 handle the interpretation of the copy parameter
1823 ***************************************************************************/
1824 static BOOL handle_copy(char *pszParmValue,char **ptr)
1828 service serviceTemp;
1830 string_set(ptr,pszParmValue);
1832 init_service(&serviceTemp);
1836 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1838 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1840 if (iTemp == iServiceIndex)
1842 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1847 copy_service(pSERVICE(iServiceIndex),
1849 iSERVICE(iServiceIndex).copymap);
1855 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1860 free_service(&serviceTemp);
1865 /***************************************************************************
1866 initialise a copymap
1867 ***************************************************************************/
1868 static void init_copymap(service *pservice)
1871 if (pservice->copymap) free(pservice->copymap);
1872 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1873 if (!pservice->copymap)
1874 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1876 for (i=0;i<NUMPARAMETERS;i++)
1877 pservice->copymap[i] = True;
1881 /***************************************************************************
1882 return the local pointer to a parameter given the service number and the
1883 pointer into the default structure
1884 ***************************************************************************/
1885 void *lp_local_ptr(int snum, void *ptr)
1887 return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
1890 /***************************************************************************
1891 Process a parameter for a particular service number. If snum < 0
1892 then assume we are in the globals
1893 ***************************************************************************/
1894 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1897 void *parm_ptr=NULL; /* where we are going to store the result */
1900 parmnum = map_parameter(pszParmName);
1904 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1908 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1909 DEBUG(1,("WARNING: The \"%s\"option is deprecated\n",
1913 def_ptr = parm_table[parmnum].ptr;
1915 /* we might point at a service, the default service or a global */
1919 if (parm_table[parmnum].class == P_GLOBAL) {
1920 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1923 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1927 if (!iSERVICE(snum).copymap)
1928 init_copymap(pSERVICE(snum));
1930 /* this handles the aliases - set the copymap for other entries with
1931 the same data pointer */
1932 for (i=0;parm_table[i].label;i++)
1933 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1934 iSERVICE(snum).copymap[i] = False;
1937 /* if it is a special case then go ahead */
1938 if (parm_table[parmnum].special) {
1939 parm_table[parmnum].special(pszParmValue,(char **)parm_ptr);
1943 /* now switch on the type of variable it is */
1944 switch (parm_table[parmnum].type)
1947 set_boolean(parm_ptr,pszParmValue);
1951 set_boolean(parm_ptr,pszParmValue);
1952 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1956 *(int *)parm_ptr = atoi(pszParmValue);
1960 *(char *)parm_ptr = *pszParmValue;
1964 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1968 string_set(parm_ptr,pszParmValue);
1972 string_set(parm_ptr,pszParmValue);
1973 strupper(*(char **)parm_ptr);
1977 pstrcpy((char *)parm_ptr,pszParmValue);
1981 pstrcpy((char *)parm_ptr,pszParmValue);
1982 strupper((char *)parm_ptr);
1986 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1987 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1988 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
2000 /***************************************************************************
2001 Process a parameter.
2002 ***************************************************************************/
2003 static BOOL do_parameter( char *pszParmName, char *pszParmValue )
2005 if( !bInGlobalSection && bGlobalOnly )
2008 DEBUGADD( 3, ( "doing parameter %s = %s\n", pszParmName, pszParmValue ) );
2010 return( lp_do_parameter( bInGlobalSection ? -2 : iServiceIndex,
2016 /***************************************************************************
2017 print a parameter of the specified type
2018 ***************************************************************************/
2019 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
2024 for (i=0;p->enum_list[i].name;i++) {
2025 if (*(int *)ptr == p->enum_list[i].value) {
2026 fprintf(f,"%s",p->enum_list[i].name);
2033 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
2037 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
2041 fprintf(f,"%d",*(int *)ptr);
2045 fprintf(f,"%c",*(char *)ptr);
2049 fprintf(f,"0%o",*(int *)ptr);
2055 fprintf(f,"%s",(char *)ptr);
2061 fprintf(f,"%s",*(char **)ptr);
2069 /***************************************************************************
2070 check if two parameters are equal
2071 ***************************************************************************/
2072 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
2078 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
2083 return(*((int *)ptr1) == *((int *)ptr2));
2086 return(*((char *)ptr1) == *((char *)ptr2));
2091 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
2092 if (p1 && !*p1) p1 = NULL;
2093 if (p2 && !*p2) p2 = NULL;
2094 return(p1==p2 || strequal(p1,p2));
2099 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2100 if (p1 && !*p1) p1 = NULL;
2101 if (p2 && !*p2) p2 = NULL;
2102 return(p1==p2 || strequal(p1,p2));
2110 /***************************************************************************
2111 Process a new section (service). At this stage all sections are services.
2112 Later we'll have special sections that permit server parameters to be set.
2113 Returns True on success, False on failure.
2114 ***************************************************************************/
2115 static BOOL do_section(char *pszSectionName)
2118 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2119 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2122 /* if we were in a global section then do the local inits */
2123 if (bInGlobalSection && !isglobal)
2126 /* if we've just struck a global section, note the fact. */
2127 bInGlobalSection = isglobal;
2129 /* check for multiple global sections */
2130 if (bInGlobalSection)
2132 DEBUG( 3, ( "Processing section \"[%s]\"\n", pszSectionName ) );
2136 if (!bInGlobalSection && bGlobalOnly) return(True);
2138 /* if we have a current service, tidy it up before moving on */
2141 if (iServiceIndex >= 0)
2142 bRetval = service_ok(iServiceIndex);
2144 /* if all is still well, move to the next record in the services array */
2147 /* We put this here to avoid an odd message order if messages are */
2148 /* issued by the post-processing of a previous section. */
2149 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
2151 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
2153 DEBUG(0,("Failed to add a new service\n"));
2162 /***************************************************************************
2163 determine if a partcular base parameter is currently set to the default value.
2164 ***************************************************************************/
2165 static BOOL is_default(int i)
2167 if (!defaults_saved) return False;
2168 switch (parm_table[i].type) {
2171 return strequal(parm_table[i].def.svalue,*(char **)parm_table[i].ptr);
2174 return strequal(parm_table[i].def.svalue,(char *)parm_table[i].ptr);
2177 return parm_table[i].def.bvalue == *(BOOL *)parm_table[i].ptr;
2179 return parm_table[i].def.cvalue == *(char *)parm_table[i].ptr;
2183 return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
2191 /***************************************************************************
2192 Display the contents of the global structure.
2193 ***************************************************************************/
2194 static void dump_globals(FILE *f)
2197 fprintf(f, "# Global parameters\n");
2199 for (i=0;parm_table[i].label;i++)
2200 if (parm_table[i].class == P_GLOBAL &&
2201 parm_table[i].ptr &&
2202 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2203 if (defaults_saved && is_default(i)) continue;
2204 fprintf(f,"\t%s = ",parm_table[i].label);
2205 print_parameter(&parm_table[i],parm_table[i].ptr, f);
2210 /***************************************************************************
2211 return True if a local parameter is currently set to the global default
2212 ***************************************************************************/
2213 BOOL lp_is_default(int snum, struct parm_struct *parm)
2215 int pdiff = PTR_DIFF(parm->ptr,&sDefault);
2217 return equal_parameter(parm->type,
2218 ((char *)pSERVICE(snum)) + pdiff,
2219 ((char *)&sDefault) + pdiff);
2223 /***************************************************************************
2224 Display the contents of a single services record.
2225 ***************************************************************************/
2226 static void dump_a_service(service *pService, FILE *f)
2229 if (pService != &sDefault)
2230 fprintf(f,"\n[%s]\n",pService->szService);
2232 for (i=0;parm_table[i].label;i++)
2233 if (parm_table[i].class == P_LOCAL &&
2234 parm_table[i].ptr &&
2235 (*parm_table[i].label != '-') &&
2236 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2237 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
2239 if (pService == &sDefault) {
2240 if (defaults_saved && is_default(i)) continue;
2242 if (equal_parameter(parm_table[i].type,
2243 ((char *)pService) + pdiff,
2244 ((char *)&sDefault) + pdiff))
2248 fprintf(f,"\t%s = ",parm_table[i].label);
2249 print_parameter(&parm_table[i],
2250 ((char *)pService) + pdiff, f);
2256 /***************************************************************************
2257 return info about the next service in a service. snum==-1 gives the globals
2259 return NULL when out of parameters
2260 ***************************************************************************/
2261 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2264 /* do the globals */
2265 for (;parm_table[*i].label;(*i)++) {
2266 if (parm_table[*i].class == P_SEPARATOR)
2267 return &parm_table[(*i)++];
2269 if (!parm_table[*i].ptr || (*parm_table[*i].label == '-'))
2272 if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr))
2275 return &parm_table[(*i)++];
2278 service *pService = pSERVICE(snum);
2280 for (;parm_table[*i].label;(*i)++) {
2281 if (parm_table[*i].class == P_SEPARATOR)
2282 return &parm_table[(*i)++];
2284 if (parm_table[*i].class == P_LOCAL &&
2285 parm_table[*i].ptr &&
2286 (*parm_table[*i].label != '-') &&
2288 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2289 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2291 if (allparameters ||
2292 !equal_parameter(parm_table[*i].type,
2293 ((char *)pService) + pdiff,
2294 ((char *)&sDefault) + pdiff)) {
2295 return &parm_table[(*i)++];
2306 /***************************************************************************
2307 Display the contents of a single copy structure.
2308 ***************************************************************************/
2309 static void dump_copy_map(BOOL *pcopymap)
2312 if (!pcopymap) return;
2314 printf("\n\tNon-Copied parameters:\n");
2316 for (i=0;parm_table[i].label;i++)
2317 if (parm_table[i].class == P_LOCAL &&
2318 parm_table[i].ptr && !pcopymap[i] &&
2319 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2321 printf("\t\t%s\n",parm_table[i].label);
2326 /***************************************************************************
2327 Return TRUE if the passed service number is within range.
2328 ***************************************************************************/
2329 BOOL lp_snum_ok(int iService)
2331 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2335 /***************************************************************************
2336 auto-load some home services
2337 ***************************************************************************/
2338 static void lp_add_auto_services(char *str)
2349 homes = lp_servicenumber(HOMES_NAME);
2351 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
2352 char *home = get_home_dir(p);
2354 if (lp_servicenumber(p) >= 0) continue;
2356 if (home && homes >= 0) {
2357 lp_add_home(p,homes,home);
2363 /***************************************************************************
2364 auto-load one printer
2365 ***************************************************************************/
2366 void lp_add_one_printer(char *name,char *comment)
2368 int printers = lp_servicenumber(PRINTERS_NAME);
2371 if (lp_servicenumber(name) < 0) {
2372 lp_add_printer(name,printers);
2373 if ((i=lp_servicenumber(name)) >= 0)
2374 string_set(&iSERVICE(i).comment,comment);
2378 /***************************************************************************
2379 have we loaded a services file yet?
2380 ***************************************************************************/
2381 BOOL lp_loaded(void)
2386 /***************************************************************************
2387 unload unused services
2388 ***************************************************************************/
2389 void lp_killunused(BOOL (*snumused)(int ))
2392 for (i=0;i<iNumServices;i++)
2393 if (VALID(i) && (!snumused || !snumused(i)))
2395 iSERVICE(i).valid = False;
2396 free_service(pSERVICE(i));
2401 /***************************************************************************
2402 save the curent values of all global and sDefault parameters into the
2403 defaults union. This allows swat and testparm to show only the
2404 changed (ie. non-default) parameters.
2405 ***************************************************************************/
2406 static void lp_save_defaults(void)
2409 for (i = 0; parm_table[i].label; i++) {
2410 if (i>0 && parm_table[i].ptr == parm_table[i-1].ptr) continue;
2411 switch (parm_table[i].type) {
2414 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2418 parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
2422 parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr;
2425 parm_table[i].def.cvalue = *(char *)parm_table[i].ptr;
2430 parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
2436 defaults_saved = True;
2440 /***************************************************************************
2441 Load the services array from the services file. Return True on success,
2443 ***************************************************************************/
2444 BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
2449 add_to_file_list(pszFname);
2453 bInGlobalSection = True;
2454 bGlobalOnly = global_only;
2458 if (save_defaults) {
2463 pstrcpy(n2,pszFname);
2464 standard_sub_basic(n2);
2466 /* We get sections first, so have to start 'behind' to make up */
2468 bRetval = pm_process(n2, do_section, do_parameter);
2470 /* finish up the last section */
2471 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2473 if (iServiceIndex >= 0)
2474 bRetval = service_ok(iServiceIndex);
2476 lp_add_auto_services(lp_auto_services());
2481 set_default_server_announce_type();
2485 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
2486 /* if bWINSsupport is true and we are in the client */
2488 if (in_client && Globals.bWINSsupport) {
2490 string_set(&Globals.szWINSserver, "127.0.0.1");
2498 /***************************************************************************
2499 return the max number of services
2500 ***************************************************************************/
2501 int lp_numservices(void)
2503 return(iNumServices);
2506 /***************************************************************************
2507 Display the contents of the services array in human-readable form.
2508 ***************************************************************************/
2509 void lp_dump(FILE *f, BOOL show_defaults)
2513 if (show_defaults) {
2514 defaults_saved = False;
2519 dump_a_service(&sDefault, f);
2521 for (iService = 0; iService < iNumServices; iService++)
2523 if (VALID(iService))
2525 if (iSERVICE(iService).szService[0] == '\0')
2527 dump_a_service(pSERVICE(iService), f);
2533 /***************************************************************************
2534 Return the number of the service with the given name, or -1 if it doesn't
2535 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2536 getservicebyname()! This works ONLY if all services have been loaded, and
2537 does not copy the found service.
2538 ***************************************************************************/
2539 int lp_servicenumber(char *pszServiceName)
2543 for (iService = iNumServices - 1; iService >= 0; iService--)
2544 if (VALID(iService) &&
2545 strequal(lp_servicename(iService), pszServiceName))
2549 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2554 /*******************************************************************
2555 a useful volume label function
2556 ******************************************************************/
2557 char *volume_label(int snum)
2559 char *ret = lp_volume(snum);
2560 if (!*ret) return(lp_servicename(snum));
2565 /*******************************************************************
2566 Set the server type we will announce as via nmbd.
2567 ********************************************************************/
2568 static void set_default_server_announce_type(void)
2570 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2571 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2572 if(lp_announce_as() == ANNOUNCE_AS_NT)
2573 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2574 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2575 default_server_announce |= SV_TYPE_WIN95_PLUS;
2576 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2577 default_server_announce |= SV_TYPE_WFW;
2578 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2582 /*******************************************************************
2584 ********************************************************************/
2585 void lp_remove_service(int snum)
2587 pSERVICE(snum)->valid = False;
2590 /*******************************************************************
2592 ********************************************************************/
2593 void lp_copy_service(int snum, char *new_name)
2595 char *oldname = lp_servicename(snum);
2596 do_section(new_name);
2598 snum = lp_servicenumber(new_name);
2600 lp_do_parameter(snum, "copy", oldname);
2605 /*******************************************************************
2606 Get the default server type we will announce as via nmbd.
2607 ********************************************************************/
2608 int lp_default_server_announce(void)
2610 return default_server_announce;
2613 /*******************************************************************
2614 Split the announce version into major and minor numbers.
2615 ********************************************************************/
2616 int lp_major_announce_version(void)
2618 static BOOL got_major = False;
2619 static int major_version = DEFAULT_MAJOR_VERSION;
2624 return major_version;
2627 if((vers = lp_announce_version()) == NULL)
2628 return major_version;
2630 if((p = strchr(vers, '.')) == 0)
2631 return major_version;
2634 major_version = atoi(vers);
2635 return major_version;
2638 int lp_minor_announce_version(void)
2640 static BOOL got_minor = False;
2641 static int minor_version = DEFAULT_MINOR_VERSION;
2646 return minor_version;
2649 if((vers = lp_announce_version()) == NULL)
2650 return minor_version;
2652 if((p = strchr(vers, '.')) == 0)
2653 return minor_version;
2656 minor_version = atoi(p);
2657 return minor_version;
2660 /***********************************************************
2661 Set the global name resolution order (used in smbclient).
2662 ************************************************************/
2664 void lp_set_name_resolve_order(char *new_order)
2666 Globals.szNameResolveOrder = new_order;
2669 /***********************************************************
2670 Set the flag that says if kernel oplocks are available
2672 ************************************************************/
2674 static BOOL kernel_oplocks_available = False;
2676 void lp_set_kernel_oplocks(BOOL val)
2679 * Only set this to True if kerenl
2680 * oplocks are really available and were
2681 * turned on in the smb.conf file.
2684 if(Globals.bKernelOplocks && val)
2685 kernel_oplocks_available = True;
2687 kernel_oplocks_available = False;
2690 /***********************************************************
2691 Return True if kernel oplocks are available and were turned
2693 ************************************************************/
2695 BOOL lp_kernel_oplocks(void)
2697 return kernel_oplocks_available;