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'.
70 extern int DEBUGLEVEL;
71 extern pstring user_socket_options;
72 extern pstring global_myname;
75 #define GLOBAL_NAME "global"
79 #define PRINTERS_NAME "printers"
83 #define HOMES_NAME "homes"
86 /* some helpful bits */
87 #define pSERVICE(i) ServicePtrs[i]
88 #define iSERVICE(i) (*pSERVICE(i))
89 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
90 #define VALID(i) iSERVICE(i).valid
92 int keepalive=DEFAULT_KEEPALIVE;
93 extern BOOL use_getwd_cache;
95 extern int extra_time_offset;
97 static BOOL defaults_saved=False;
100 * This structure describes global (ie., server-wide) parameters.
104 char *szPrintcapname;
107 char *szDefaultService;
111 char *szServerString;
112 char *szAutoServices;
113 char *szPasswdProgram;
117 char *szSMBPasswdFile;
118 char *szPasswordServer;
119 char *szSocketOptions;
122 char *szDomainAdminGroup;
123 char *szDomainGuestGroup;
124 char *szDomainAdminUsers;
125 char *szDomainGuestUsers;
126 char *szDomainHostsallow;
127 char *szDomainHostsdeny;
129 char *szGroupnameMap;
130 char *szCharacterSet;
137 char *szCodingSystem;
139 char *szRemoteAnnounce;
140 char *szRemoteBrowseSync;
141 char *szSocketAddress;
142 char *szNISHomeMapName;
143 char *szAnnounceVersion; /* This is initialised in init_globals */
144 char *szNetbiosAliases;
146 char *szDomainOtherSIDs;
147 char *szDomainGroups;
149 char *szNameResolveOrder;
154 char *szLdapRootPassword;
177 int client_code_page;
178 int announce_as; /* This is initialised in init_globals */
179 int machine_password_timeout;
180 int change_notify_timeout;
184 #endif /* WITH_LDAP */
187 char *sslHostsRequire;
188 char *sslHostsResign;
194 char *sslClientPrivKey;
197 BOOL sslReqClientCert;
198 BOOL sslReqServerCert;
199 BOOL sslCompatibility;
200 #endif /* WITH_SSL */
205 BOOL bPreferredMaster;
206 BOOL bDomainController;
209 BOOL bEncryptPasswords;
217 BOOL bReadPrediction;
224 BOOL bBindInterfacesOnly;
225 BOOL bNetWkstaUserLogon;
226 BOOL bUnixPasswdSync;
227 BOOL bPasswdChatDebug;
228 BOOL bOleLockingCompat;
233 static global Globals;
238 * This structure describes a single service.
246 char *szGuestaccount;
247 char *szInvalidUsers;
255 char *szRootPostExec;
256 char *szPrintcommand;
259 char *szLppausecommand;
260 char *szLpresumecommand;
261 char *szQueuepausecommand;
262 char *szQueueresumecommand;
264 char *szPrinterDriver;
265 char *szPrinterDriverLocation;
274 char *szVetoOplockFiles;
283 int iCreate_force_mode;
293 BOOL bShortCasePreserve;
320 BOOL bDeleteReadonly;
322 BOOL bDeleteVetoFiles;
324 BOOL bDosFiletimeResolution;
325 BOOL bFakeDirCreateTimes;
326 char dummy[3]; /* for alignment */
330 /* This is a default service used to prime a services structure */
331 static service sDefault =
334 NULL, /* szService */
336 NULL, /* szUsername */
337 NULL, /* szGuestAccount - this is set in init_globals() */
338 NULL, /* szInvalidUsers */
339 NULL, /* szValidUsers */
340 NULL, /* szAdminUsers */
342 NULL, /* szInclude */
343 NULL, /* szPreExec */
344 NULL, /* szPostExec */
345 NULL, /* szRootPreExec */
346 NULL, /* szRootPostExec */
347 NULL, /* szPrintcommand */
348 NULL, /* szLpqcommand */
349 NULL, /* szLprmcommand */
350 NULL, /* szLppausecommand */
351 NULL, /* szLpresumecommand */
352 NULL, /* szQueuepausecommand */
353 NULL, /* szQueueresumecommand */
354 NULL, /* szPrintername */
355 NULL, /* szPrinterDriver - this is set in init_globals() */
356 NULL, /* szPrinterDriverLocation */
357 NULL, /* szDontdescend */
358 NULL, /* szHostsallow */
359 NULL, /* szHostsdeny */
360 NULL, /* szMagicScript */
361 NULL, /* szMagicOutput */
362 NULL, /* szMangledMap */
363 NULL, /* szVetoFiles */
364 NULL, /* szHideFiles */
365 NULL, /* szVetoOplockFiles */
367 NULL, /* force user */
368 NULL, /* force group */
370 NULL, /* writelist */
372 0, /* iMinPrintSpace */
373 0744, /* iCreate_mask */
374 0000, /* iCreate_force_mode */
375 0755, /* iDir_mask */
376 0000, /* iDir_force_mode */
377 0, /* iMaxConnections */
378 CASE_LOWER, /* iDefaultCase */
379 DEFAULT_PRINTING, /* iPrinting */
380 False, /* bAlternatePerm */
381 False, /* revalidate */
382 False, /* case sensitive */
383 True, /* case preserve */
384 True, /* short case preserve */
385 False, /* case mangle */
387 True, /* bHideDotFiles */
388 True, /* bBrowseable */
389 True, /* bAvailable */
390 True, /* bRead_only */
391 True, /* bNo_set_dir */
392 False, /* bGuest_only */
393 False, /* bGuest_ok */
394 False, /* bPrint_ok */
395 False, /* bPostscript */
396 False, /* bMap_system */
397 False, /* bMap_hidden */
398 True, /* bMap_archive */
400 False, /* bStrictLocking */
401 True, /* bShareModes */
403 False, /* bOnlyUser */
404 True, /* bMangledNames */
405 True, /* bWidelinks */
406 True, /* bSymlinks */
407 False, /* bSyncAlways */
408 False, /* bStrictSync */
409 '~', /* magic char */
411 False, /* bDeleteReadonly */
412 False, /* bFakeOplocks */
413 False, /* bDeleteVetoFiles */
414 False, /* bDosFiletimes */
415 False, /* bDosFiletimeResolution */
416 False, /* bFakeDirCreateTimes */
422 /* local variables */
423 static service **ServicePtrs = NULL;
424 static int iNumServices = 0;
425 static int iServiceIndex = 0;
426 static BOOL bInGlobalSection = True;
427 static BOOL bGlobalOnly = False;
428 static int default_server_announce;
430 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
432 /* prototypes for the special type handlers */
433 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
434 static BOOL handle_include(char *pszParmValue, char **ptr);
435 static BOOL handle_copy(char *pszParmValue, char **ptr);
436 static BOOL handle_character_set(char *pszParmValue,char **ptr);
437 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
439 static void set_default_server_announce_type(void);
441 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
442 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"},
443 {PROTOCOL_COREPLUS, "COREPLUS"},
444 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
446 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
447 {SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"},
450 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
451 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
452 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
453 {PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"},
456 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
457 {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
459 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
461 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
464 static struct enum_list enum_ssl_version[] = {{SMB_SSL_V2, "ssl2"}, {SMB_SSL_V3, "ssl3"},
465 {SMB_SSL_V23, "ssl2or3"}, {SMB_SSL_TLS1, "tls1"}, {-1, NULL}};
468 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
469 static struct parm_struct parm_table[] =
471 {"Base Options", P_SEP, P_SEPARATOR},
472 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
473 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
474 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
475 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
476 {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, NULL, NULL, FLAG_BASIC},
477 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
478 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC},
479 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
480 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0},
482 {"Security Options", P_SEP, P_SEPARATOR},
483 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
484 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
485 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC},
486 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
487 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
488 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
489 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
490 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
491 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
492 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
493 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
494 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0},
495 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
496 {"passwd chat debug",P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0},
497 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
498 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
499 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
500 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0},
501 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL|FLAG_DEPRECATED},
502 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL},
503 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL},
504 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
505 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
506 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
507 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL},
508 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL},
509 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL},
510 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL},
511 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL},
512 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, 0},
513 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
514 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
515 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC},
516 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
517 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
518 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
519 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
520 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
521 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL},
522 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
523 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
524 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL},
525 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
526 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
527 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
528 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
529 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, 0},
530 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
531 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
532 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
533 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
536 {"Secure Socket Layer Options", P_SEP, P_SEPARATOR},
537 {"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0 },
538 {"ssl hosts", P_STRING, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0 },
539 {"ssl hosts resign", P_STRING, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0} ,
540 {"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0 },
541 {"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0 },
542 {"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslCert, NULL, NULL, 0 },
543 {"ssl server key", P_STRING, P_GLOBAL, &Globals.sslPrivKey, NULL, NULL, 0 },
544 {"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0 },
545 {"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0 },
546 {"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL , 0},
547 {"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL , 0},
548 {"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0 },
549 {"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0},
550 {"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0 },
551 #endif /* WITH_SSL */
553 {"Logging Options", P_SEP, P_SEPARATOR},
554 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
555 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
556 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
557 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
558 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
559 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
560 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
561 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
562 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
564 {"Protocol Options", P_SEP, P_SEPARATOR},
565 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
566 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
567 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
568 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
569 {"networkstation user login", P_BOOL,P_GLOBAL, &Globals.bNetWkstaUserLogon,NULL, NULL, 0},
570 {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0},
571 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
572 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
573 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
574 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
575 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0},
576 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
577 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
578 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0},
579 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
580 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
581 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
583 {"Tuning Options", P_SEP, P_SEPARATOR},
584 {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0},
585 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
586 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
587 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
588 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
589 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0},
590 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
591 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0},
592 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0},
593 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
594 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0},
595 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
596 {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0},
597 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, 0},
598 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0},
600 {"Printing Options", P_SEP, P_SEPARATOR},
601 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0},
602 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
603 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
604 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, 0},
605 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
606 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
607 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
608 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL},
609 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
610 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
611 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
612 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_GLOBAL},
613 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_GLOBAL},
614 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_GLOBAL},
615 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_GLOBAL},
617 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
618 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
619 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
620 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_GLOBAL},
623 {"Filename Handling", P_SEP, P_SEPARATOR},
624 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
625 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
626 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
627 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
628 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0},
629 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, 0},
630 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_GLOBAL},
631 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
632 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_GLOBAL},
633 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_GLOBAL},
634 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_GLOBAL},
635 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_GLOBAL},
636 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_GLOBAL},
637 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_GLOBAL},
638 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_GLOBAL},
639 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_GLOBAL},
640 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_GLOBAL},
641 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_GLOBAL},
642 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_GLOBAL},
643 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_GLOBAL},
644 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_GLOBAL},
645 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_GLOBAL},
647 {"Domain Options", P_SEP, P_SEPARATOR},
648 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL, NULL, 0},
649 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
650 {"domain controller",P_BOOL , P_GLOBAL, &Globals.bDomainController,NULL, NULL, 0},
651 {"domain admin group",P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0},
652 {"domain guest group",P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0},
653 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0},
654 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0},
655 {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0},
656 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0},
658 {"Logon Options", P_SEP, P_SEPARATOR},
659 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
660 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0},
661 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
662 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0},
663 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
665 {"Browse Options", P_SEP, P_SEPARATOR},
666 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC},
667 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0},
668 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
669 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, FLAG_BASIC},
670 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
671 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC},
672 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, FLAG_BASIC},
673 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
674 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
675 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
677 {"WINS Options", P_SEP, P_SEPARATOR},
678 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
679 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC},
680 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0},
681 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC},
683 {"Locking Options", P_SEP, P_SEPARATOR},
684 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_GLOBAL},
685 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_GLOBAL},
686 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_GLOBAL},
687 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
688 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
689 {"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, FLAG_GLOBAL},
692 {"Ldap Options", P_SEP, P_SEPARATOR},
693 {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
694 {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
695 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0},
696 {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0},
697 {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0},
698 {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword,NULL, NULL, 0},
699 #endif /* WITH_LDAP */
702 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
703 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
704 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
705 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
706 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
707 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
708 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
709 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
710 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
711 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
712 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
713 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
714 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0},
715 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL, 0},
716 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
717 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
718 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
719 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0},
720 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
721 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
722 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
723 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
724 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
725 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
726 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, 0},
727 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, 0},
728 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, 0},
729 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, 0},
730 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, 0},
731 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, 0},
732 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_GLOBAL},
733 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_GLOBAL},
734 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, 0},
735 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, 0},
736 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, 0},
737 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_GLOBAL},
738 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_GLOBAL},
739 {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_GLOBAL},
741 {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_GLOBAL},
742 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0},
744 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
749 /***************************************************************************
750 Initialise the global parameter structure.
751 ***************************************************************************/
752 static void init_globals(void)
754 static BOOL done_init = False;
760 bzero((void *)&Globals,sizeof(Globals));
762 for (i = 0; parm_table[i].label; i++)
763 if ((parm_table[i].type == P_STRING ||
764 parm_table[i].type == P_USTRING) &&
766 string_init(parm_table[i].ptr,"");
768 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
769 string_set(&sDefault.szPrinterDriver, "NULL");
775 DEBUG(3,("Initialising global parameters\n"));
777 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
778 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
779 string_set(&Globals.szWorkGroup, WORKGROUP);
780 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
781 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
782 string_set(&Globals.szDriverFile, DRIVERFILE);
783 string_set(&Globals.szLockDir, LOCKDIR);
784 string_set(&Globals.szRootdir, "/");
785 string_set(&Globals.szSmbrun, SMBRUN);
786 string_set(&Globals.szSocketAddress, "0.0.0.0");
787 pstrcpy(s, "Samba ");
789 string_set(&Globals.szServerString,s);
790 slprintf(s,sizeof(s)-1, "%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
791 string_set(&Globals.szAnnounceVersion,s);
793 string_set(&Globals.szLogonDrive, "");
794 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
795 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
796 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
798 string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast");
800 Globals.bLoadPrinters = True;
801 Globals.bUseRhosts = False;
802 Globals.max_packet = 65535;
803 Globals.mangled_stack = 50;
804 Globals.max_xmit = 65535;
805 Globals.max_mux = 50; /* This is *needed* for profile support. */
806 Globals.lpqcachetime = 10;
807 Globals.pwordlevel = 0;
808 Globals.unamelevel = 0;
809 Globals.deadtime = 0;
810 Globals.max_log_size = 5000;
811 Globals.maxprotocol = PROTOCOL_NT1;
812 Globals.security = SEC_USER;
813 Globals.bEncryptPasswords = False;
814 Globals.bUpdateEncrypt = False;
815 Globals.bReadRaw = True;
816 Globals.bWriteRaw = True;
817 Globals.bReadPrediction = False;
818 Globals.bReadbmpx = True;
819 Globals.bNullPasswords = False;
820 Globals.bStripDot = False;
822 Globals.bSyslogOnly = False;
823 Globals.bTimestampLogs = True;
824 Globals.os_level = 0;
825 Globals.max_ttl = 60*60*24*3; /* 3 days default. */
826 Globals.max_wins_ttl = 60*60*24*6; /* 6 days default. */
827 Globals.min_wins_ttl = 60*60*6; /* 6 hours default. */
828 Globals.machine_password_timeout = 60*60*24*7; /* 7 days default. */
829 Globals.change_notify_timeout = 60; /* 1 minute default. */
830 Globals.ReadSize = 16*1024;
831 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
832 Globals.lm_interval = 60;
833 Globals.shmem_size = SHMEM_SIZE;
834 Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */
835 Globals.announce_as = ANNOUNCE_AS_NT;
836 Globals.bUnixRealname = False;
837 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
838 Globals.bNISHomeMap = False;
839 #ifdef WITH_NISPLUS_HOME
840 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
842 string_set(&Globals.szNISHomeMapName, "auto.home");
845 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
846 Globals.bTimeServer = False;
847 Globals.bBindInterfacesOnly = False;
848 Globals.bNetWkstaUserLogon = False; /* This is now set to false by default as
849 the code in password.c protects us from this bug. */
850 Globals.bUnixPasswdSync = False;
851 Globals.bPasswdChatDebug = False;
852 Globals.bOleLockingCompat = True;
853 Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */
856 /* default values for ldap */
857 string_set(&Globals.szLdapServer, "localhost");
858 Globals.ldap_port=389;
859 #endif /* WITH_LDAP */
862 Globals.sslVersion = SMB_SSL_V23;
863 Globals.sslHostsRequire = NULL;
864 Globals.sslHostsResign = NULL;
865 Globals.sslCaCertDir = NULL;
866 Globals.sslCaCertFile = NULL;
867 Globals.sslCert = NULL;
868 Globals.sslPrivKey = NULL;
869 Globals.sslClientCert = NULL;
870 Globals.sslClientPrivKey = NULL;
871 Globals.sslCiphers = NULL;
872 Globals.sslEnabled = False;
873 Globals.sslReqClientCert = False;
874 Globals.sslReqServerCert = False;
875 Globals.sslCompatibility = False;
876 #endif /* WITH_SSL */
878 /* these parameters are set to defaults that are more appropriate
879 for the increasing samba install base:
881 as a member of the workgroup, that will possibly become a
882 _local_ master browser (lm = True). this is opposed to a forced
883 local master browser startup (pm = True).
885 doesn't provide WINS server service by default (wsupp = False),
886 and doesn't provide domain master browser services by default, either.
890 Globals.bPreferredMaster = False;
891 Globals.bLocalMaster = True;
892 Globals.bDomainMaster = False;
893 Globals.bDomainLogons = False;
894 Globals.bBrowseList = True;
895 Globals.bWINSsupport = False;
896 Globals.bWINSproxy = False;
898 Globals.bDNSproxy = True;
901 * This must be done last as it checks the value in
905 interpret_coding_system(KANJI);
908 /***************************************************************************
909 check if a string is initialised and if not then initialise it
910 ***************************************************************************/
911 static void string_initial(char **s,char *v)
918 /***************************************************************************
919 Initialise the sDefault parameter structure.
920 ***************************************************************************/
921 static void init_locals(void)
923 /* choose defaults depending on the type of printing */
924 switch (sDefault.iPrinting)
930 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
931 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
932 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
937 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
938 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
939 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
941 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
942 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
943 string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
944 string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
946 string_initial(&sDefault.szQueuepausecommand, "disable %p");
947 string_initial(&sDefault.szQueueresumecommand, "enable %p");
952 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
953 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
954 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
958 string_initial(&sDefault.szLpqcommand,"qstat -l -d%p");
959 string_initial(&sDefault.szLprmcommand,"qstat -s -j%j -c");
960 string_initial(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
961 string_initial(&sDefault.szLppausecommand,"qstat -s -j%j -h");
962 string_initial(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
969 /******************************************************************* a
970 convenience routine to grab string parameters into a rotating buffer,
971 and run standard_sub_basic on them. The buffers can be written to by
972 callers without affecting the source string.
973 ********************************************************************/
974 char *lp_string(char *s)
976 static char *bufs[10];
977 static int buflen[10];
978 static int next = -1;
981 int len = s?strlen(s):0;
992 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
995 if (buflen[next] != len) {
997 if (bufs[next]) free(bufs[next]);
998 bufs[next] = (char *)malloc(len);
1000 DEBUG(0,("out of memory in lp_string()"));
1005 ret = &bufs[next][0];
1013 trim_string(ret, "\"", "\"");
1015 standard_sub_basic(ret);
1021 In this section all the functions that are used to access the
1022 parameters from the rest of the program are defined
1025 #define FN_GLOBAL_STRING(fn_name,ptr) \
1026 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1027 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1028 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1029 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1030 char fn_name(void) {return(*(char *)(ptr));}
1031 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1032 int fn_name(void) {return(*(int *)(ptr));}
1034 #define FN_LOCAL_STRING(fn_name,val) \
1035 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
1036 #define FN_LOCAL_BOOL(fn_name,val) \
1037 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1038 #define FN_LOCAL_CHAR(fn_name,val) \
1039 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1040 #define FN_LOCAL_INTEGER(fn_name,val) \
1041 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1043 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
1044 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
1045 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
1046 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
1047 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
1048 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
1049 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
1050 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
1051 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
1052 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
1053 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
1054 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
1055 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
1056 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
1057 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
1058 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
1059 FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder)
1060 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
1061 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
1062 FN_GLOBAL_STRING(lp_groupname_map,&Globals.szGroupnameMap)
1063 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
1064 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
1065 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
1066 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
1067 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
1068 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
1069 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
1070 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
1071 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
1072 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
1073 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
1074 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
1075 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
1076 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
1077 FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction)
1079 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
1080 FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
1081 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
1082 FN_GLOBAL_STRING(lp_domain_admin_group,&Globals.szDomainAdminGroup)
1083 FN_GLOBAL_STRING(lp_domain_guest_group,&Globals.szDomainGuestGroup)
1084 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
1085 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
1086 FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
1087 FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
1090 FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer);
1091 FN_GLOBAL_STRING(lp_ldap_suffix,&Globals.szLdapSuffix);
1092 FN_GLOBAL_STRING(lp_ldap_filter,&Globals.szLdapFilter);
1093 FN_GLOBAL_STRING(lp_ldap_root,&Globals.szLdapRoot);
1094 FN_GLOBAL_STRING(lp_ldap_rootpasswd,&Globals.szLdapRootPassword);
1095 #endif /* WITH_LDAP */
1098 FN_GLOBAL_INTEGER(lp_ssl_version,&Globals.sslVersion);
1099 FN_GLOBAL_STRING(lp_ssl_hosts,&Globals.sslHostsRequire);
1100 FN_GLOBAL_STRING(lp_ssl_hosts_resign,&Globals.sslHostsResign);
1101 FN_GLOBAL_STRING(lp_ssl_cacertdir,&Globals.sslCaCertDir);
1102 FN_GLOBAL_STRING(lp_ssl_cacertfile,&Globals.sslCaCertFile);
1103 FN_GLOBAL_STRING(lp_ssl_cert,&Globals.sslCert);
1104 FN_GLOBAL_STRING(lp_ssl_privkey,&Globals.sslPrivKey);
1105 FN_GLOBAL_STRING(lp_ssl_client_cert,&Globals.sslClientCert);
1106 FN_GLOBAL_STRING(lp_ssl_client_privkey,&Globals.sslClientPrivKey);
1107 FN_GLOBAL_STRING(lp_ssl_ciphers,&Globals.sslCiphers);
1108 FN_GLOBAL_BOOL(lp_ssl_enabled,&Globals.sslEnabled);
1109 FN_GLOBAL_BOOL(lp_ssl_reqClientCert,&Globals.sslReqClientCert);
1110 FN_GLOBAL_BOOL(lp_ssl_reqServerCert,&Globals.sslReqServerCert);
1111 FN_GLOBAL_BOOL(lp_ssl_compatibility,&Globals.sslCompatibility);
1112 #endif /* WITH_SSL */
1114 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
1115 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
1116 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
1117 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
1118 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
1119 FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController)
1120 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
1121 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
1122 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
1123 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
1124 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
1125 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
1126 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
1127 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
1128 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
1129 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
1130 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
1131 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
1132 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
1133 FN_GLOBAL_BOOL(lp_update_encrypted,&Globals.bUpdateEncrypt)
1134 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
1135 FN_GLOBAL_BOOL(lp_timestamp_logs,&Globals.bTimestampLogs)
1136 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
1137 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
1138 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
1139 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
1140 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
1141 FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
1142 FN_GLOBAL_BOOL(lp_unix_password_sync,&Globals.bUnixPasswdSync)
1143 FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug)
1144 FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat)
1145 FN_GLOBAL_BOOL(lp_nt_smb_support,&Globals.bNTSmbSupport)
1147 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
1148 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
1149 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
1150 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
1151 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
1152 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
1153 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
1154 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
1155 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
1156 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
1157 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
1158 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
1159 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
1160 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
1161 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
1162 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
1163 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
1164 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
1165 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
1166 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
1167 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
1168 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
1169 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
1170 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
1171 FN_GLOBAL_INTEGER(lp_machine_password_timeout,&Globals.machine_password_timeout)
1172 FN_GLOBAL_INTEGER(lp_change_notify_timeout,&Globals.change_notify_timeout)
1173 FN_GLOBAL_INTEGER(lp_stat_cache_size,&Globals.stat_cache_size)
1176 FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port)
1177 #endif /* WITH_LDAP */
1179 FN_LOCAL_STRING(lp_preexec,szPreExec)
1180 FN_LOCAL_STRING(lp_postexec,szPostExec)
1181 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
1182 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
1183 FN_LOCAL_STRING(lp_servicename,szService)
1184 FN_LOCAL_STRING(lp_pathname,szPath)
1185 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
1186 FN_LOCAL_STRING(lp_username,szUsername)
1187 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
1188 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
1189 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
1190 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
1191 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
1192 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
1193 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
1194 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
1195 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
1196 FN_LOCAL_STRING(lp_queuepausecommand,szQueuepausecommand)
1197 FN_LOCAL_STRING(lp_queueresumecommand,szQueueresumecommand)
1198 FN_LOCAL_STRING(lp_printername,szPrintername)
1199 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
1200 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
1201 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
1202 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
1203 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
1204 FN_LOCAL_STRING(lp_comment,comment)
1205 FN_LOCAL_STRING(lp_force_user,force_user)
1206 FN_LOCAL_STRING(lp_force_group,force_group)
1207 FN_LOCAL_STRING(lp_readlist,readlist)
1208 FN_LOCAL_STRING(lp_writelist,writelist)
1209 FN_LOCAL_STRING(lp_volume,volume)
1210 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
1211 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
1212 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
1213 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
1214 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
1216 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
1217 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
1218 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1219 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1220 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1221 FN_LOCAL_BOOL(lp_status,status)
1222 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1223 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1224 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1225 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1226 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1227 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1228 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1229 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1230 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1231 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1232 FN_LOCAL_BOOL(lp_locking,bLocking)
1233 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1234 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1235 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1236 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1237 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1238 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1239 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1240 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1241 FN_LOCAL_BOOL(lp_strict_sync,bStrictSync)
1242 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1243 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1244 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1245 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1246 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1247 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
1248 FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
1250 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1251 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1252 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1253 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1254 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1255 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1256 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1257 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1259 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1263 /* local prototypes */
1264 static int strwicmp( char *psz1, char *psz2 );
1265 static int map_parameter( char *pszParmName);
1266 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1267 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1268 static void copy_service( service *pserviceDest,
1269 service *pserviceSource,
1270 BOOL *pcopymapDest );
1271 static BOOL service_ok(int iService);
1272 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1273 static BOOL do_section(char *pszSectionName);
1274 static void init_copymap(service *pservice);
1277 /***************************************************************************
1278 initialise a service to the defaults
1279 ***************************************************************************/
1280 static void init_service(service *pservice)
1282 bzero((char *)pservice,sizeof(service));
1283 copy_service(pservice,&sDefault,NULL);
1287 /***************************************************************************
1288 free the dynamically allocated parts of a service struct
1289 ***************************************************************************/
1290 static void free_service(service *pservice)
1296 if(pservice->szService)
1297 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1299 string_free(&pservice->szService);
1300 if (pservice->copymap)
1302 free(pservice->copymap);
1303 pservice->copymap = NULL;
1306 for (i=0;parm_table[i].label;i++)
1307 if ((parm_table[i].type == P_STRING ||
1308 parm_table[i].type == P_USTRING) &&
1309 parm_table[i].class == P_LOCAL)
1310 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1313 /***************************************************************************
1314 add a new service to the services array initialising it with the given
1316 ***************************************************************************/
1317 static int add_a_service(service *pservice, char *name)
1321 int num_to_alloc = iNumServices+1;
1323 tservice = *pservice;
1325 /* it might already exist */
1328 i = getservicebyname(name,NULL);
1333 /* find an invalid one */
1334 for (i=0;i<iNumServices;i++)
1335 if (!pSERVICE(i)->valid)
1338 /* if not, then create one */
1339 if (i == iNumServices)
1341 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1343 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1345 if (!ServicePtrs || !pSERVICE(iNumServices))
1351 free_service(pSERVICE(i));
1353 pSERVICE(i)->valid = True;
1355 init_service(pSERVICE(i));
1356 copy_service(pSERVICE(i),&tservice,NULL);
1358 string_set(&iSERVICE(i).szService,name);
1363 /***************************************************************************
1364 add a new home service, with the specified home directory, defaults coming
1366 ***************************************************************************/
1367 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1369 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1374 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1375 string_set(&iSERVICE(i).szPath,pszHomedir);
1376 if (!(*(iSERVICE(i).comment)))
1379 slprintf(comment,sizeof(comment)-1,
1380 "Home directory of %s",pszHomename);
1381 string_set(&iSERVICE(i).comment,comment);
1383 iSERVICE(i).bAvailable = sDefault.bAvailable;
1384 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1386 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1391 /***************************************************************************
1392 add a new service, based on an old one
1393 ***************************************************************************/
1394 int lp_add_service(char *pszService, int iDefaultService)
1396 return(add_a_service(pSERVICE(iDefaultService),pszService));
1400 /***************************************************************************
1402 ***************************************************************************/
1403 static BOOL lp_add_ipc(void)
1406 int i = add_a_service(&sDefault,"IPC$");
1411 slprintf(comment,sizeof(comment)-1,
1412 "IPC Service (%s)", Globals.szServerString );
1414 string_set(&iSERVICE(i).szPath,tmpdir());
1415 string_set(&iSERVICE(i).szUsername,"");
1416 string_set(&iSERVICE(i).comment,comment);
1417 iSERVICE(i).status = False;
1418 iSERVICE(i).iMaxConnections = 0;
1419 iSERVICE(i).bAvailable = True;
1420 iSERVICE(i).bRead_only = True;
1421 iSERVICE(i).bGuest_only = False;
1422 iSERVICE(i).bGuest_ok = True;
1423 iSERVICE(i).bPrint_ok = False;
1424 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1426 DEBUG(3,("adding IPC service\n"));
1432 /***************************************************************************
1433 add a new printer service, with defaults coming from service iFrom
1434 ***************************************************************************/
1435 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1437 char *comment = "From Printcap";
1438 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1443 /* note that we do NOT default the availability flag to True - */
1444 /* we take it from the default service passed. This allows all */
1445 /* dynamic printers to be disabled by disabling the [printers] */
1446 /* entry (if/when the 'available' keyword is implemented!). */
1448 /* the printer name is set to the service name. */
1449 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1450 string_set(&iSERVICE(i).comment,comment);
1451 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1452 /* Printers cannot be read_only. */
1453 iSERVICE(i).bRead_only = False;
1454 /* No share modes on printer services. */
1455 iSERVICE(i).bShareModes = False;
1456 /* No oplocks on printer services. */
1457 iSERVICE(i).bOpLocks = False;
1458 /* Printer services must be printable. */
1459 iSERVICE(i).bPrint_ok = True;
1461 DEBUG(3,("adding printer service %s\n",pszPrintername));
1467 /***************************************************************************
1468 Do a case-insensitive, whitespace-ignoring string compare.
1469 ***************************************************************************/
1470 static int strwicmp(char *psz1, char *psz2)
1472 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1473 /* appropriate value. */
1483 /* sync the strings on first non-whitespace */
1486 while (isspace(*psz1))
1488 while (isspace(*psz2))
1490 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1495 return (*psz1 - *psz2);
1498 /***************************************************************************
1499 Map a parameter's string representation to something we can use.
1500 Returns False if the parameter string is not recognised, else TRUE.
1501 ***************************************************************************/
1502 static int map_parameter(char *pszParmName)
1506 if (*pszParmName == '-')
1509 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1510 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1513 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1518 /***************************************************************************
1519 Set a boolean variable from the text value stored in the passed string.
1520 Returns True in success, False if the passed string does not correctly
1521 represent a boolean.
1522 ***************************************************************************/
1523 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1528 if (strwicmp(pszParmValue, "yes") == 0 ||
1529 strwicmp(pszParmValue, "true") == 0 ||
1530 strwicmp(pszParmValue, "1") == 0)
1533 if (strwicmp(pszParmValue, "no") == 0 ||
1534 strwicmp(pszParmValue, "False") == 0 ||
1535 strwicmp(pszParmValue, "0") == 0)
1539 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1546 /***************************************************************************
1547 Find a service by name. Otherwise works like get_service.
1548 ***************************************************************************/
1549 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1553 for (iService = iNumServices - 1; iService >= 0; iService--)
1554 if (VALID(iService) &&
1555 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1557 if (pserviceDest != NULL)
1558 copy_service(pserviceDest, pSERVICE(iService), NULL);
1567 /***************************************************************************
1568 Copy a service structure to another
1570 If pcopymapDest is NULL then copy all fields
1571 ***************************************************************************/
1572 static void copy_service(service *pserviceDest,
1573 service *pserviceSource,
1577 BOOL bcopyall = (pcopymapDest == NULL);
1579 for (i=0;parm_table[i].label;i++)
1580 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1581 (bcopyall || pcopymapDest[i]))
1583 void *def_ptr = parm_table[i].ptr;
1585 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1587 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1589 switch (parm_table[i].type)
1593 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1599 *(int *)dest_ptr = *(int *)src_ptr;
1603 *(char *)dest_ptr = *(char *)src_ptr;
1607 string_set(dest_ptr,*(char **)src_ptr);
1611 string_set(dest_ptr,*(char **)src_ptr);
1612 strupper(*(char **)dest_ptr);
1621 init_copymap(pserviceDest);
1622 if (pserviceSource->copymap)
1623 memcpy((void *)pserviceDest->copymap,
1624 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1628 /***************************************************************************
1629 Check a service for consistency. Return False if the service is in any way
1630 incomplete or faulty, else True.
1631 ***************************************************************************/
1632 static BOOL service_ok(int iService)
1637 if (iSERVICE(iService).szService[0] == '\0')
1639 DEBUG(0,( "The following message indicates an internal error:\n"));
1640 DEBUG(0,( "No service name in service entry.\n"));
1644 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1645 /* I can't see why you'd want a non-printable printer service... */
1646 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1647 if (!iSERVICE(iService).bPrint_ok)
1649 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1650 iSERVICE(iService).szService));
1651 iSERVICE(iService).bPrint_ok = True;
1654 if (iSERVICE(iService).szPath[0] == '\0' &&
1655 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1657 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1658 string_set(&iSERVICE(iService).szPath,tmpdir());
1661 /* If a service is flagged unavailable, log the fact at level 0. */
1662 if (!iSERVICE(iService).bAvailable)
1663 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1664 iSERVICE(iService).szService));
1669 static struct file_lists {
1670 struct file_lists *next;
1673 } *file_lists = NULL;
1675 /*******************************************************************
1676 keep a linked list of all config files so we know when one has changed
1677 it's date and needs to be reloaded
1678 ********************************************************************/
1679 static void add_to_file_list(char *fname)
1681 struct file_lists *f=file_lists;
1684 if (f->name && !strcmp(f->name,fname)) break;
1689 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1691 f->next = file_lists;
1692 f->name = strdup(fname);
1703 standard_sub_basic(n2);
1704 f->modtime = file_modtime(n2);
1709 /*******************************************************************
1710 check if a config file has changed date
1711 ********************************************************************/
1712 BOOL lp_file_list_changed(void)
1714 struct file_lists *f = file_lists;
1715 DEBUG(6,("lp_file_list_changed()\n"));
1722 pstrcpy(n2,f->name);
1723 standard_sub_basic(n2);
1725 DEBUGADD( 6, ( "file %s -> %s last mod_time: %s\n",
1726 f->name, n2, ctime(&f->modtime) ) );
1728 mod_time = file_modtime(n2);
1730 if (f->modtime != mod_time) {
1731 DEBUGADD(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1732 f->modtime = mod_time;
1740 /***************************************************************************
1741 handle the interpretation of the coding system parameter
1742 *************************************************************************/
1743 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1745 string_set(ptr,pszParmValue);
1746 interpret_coding_system(pszParmValue);
1750 /***************************************************************************
1751 handle the interpretation of the character set system parameter
1752 ***************************************************************************/
1753 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1755 string_set(ptr,pszParmValue);
1756 interpret_character_set(pszParmValue);
1761 /***************************************************************************
1762 handle the valid chars lines
1763 ***************************************************************************/
1764 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1766 string_set(ptr,pszParmValue);
1768 /* A dependency here is that the parameter client code page must be
1769 set before this is called - as calling codepage_initialise()
1770 would overwrite the valid char lines.
1772 codepage_initialise(lp_client_code_page());
1774 add_char_string(pszParmValue);
1779 /***************************************************************************
1780 handle the include operation
1781 ***************************************************************************/
1782 static BOOL handle_include(char *pszParmValue,char **ptr)
1785 pstrcpy(fname,pszParmValue);
1787 add_to_file_list(fname);
1789 standard_sub_basic(fname);
1791 string_set(ptr,fname);
1793 if (file_exist(fname,NULL))
1794 return(pm_process(fname, do_section, do_parameter));
1796 DEBUG(2,("Can't find include file %s\n",fname));
1802 /***************************************************************************
1803 handle the interpretation of the copy parameter
1804 ***************************************************************************/
1805 static BOOL handle_copy(char *pszParmValue,char **ptr)
1809 service serviceTemp;
1811 string_set(ptr,pszParmValue);
1813 init_service(&serviceTemp);
1817 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1819 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1821 if (iTemp == iServiceIndex)
1823 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1828 copy_service(pSERVICE(iServiceIndex),
1830 iSERVICE(iServiceIndex).copymap);
1836 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1841 free_service(&serviceTemp);
1846 /***************************************************************************
1847 initialise a copymap
1848 ***************************************************************************/
1849 static void init_copymap(service *pservice)
1852 if (pservice->copymap) free(pservice->copymap);
1853 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1854 if (!pservice->copymap)
1855 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1857 for (i=0;i<NUMPARAMETERS;i++)
1858 pservice->copymap[i] = True;
1862 /***************************************************************************
1863 return the local pointer to a parameter given the service number and the
1864 pointer into the default structure
1865 ***************************************************************************/
1866 void *lp_local_ptr(int snum, void *ptr)
1868 return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
1871 /***************************************************************************
1872 Process a parameter for a particular service number. If snum < 0
1873 then assume we are in the globals
1874 ***************************************************************************/
1875 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1878 void *parm_ptr=NULL; /* where we are going to store the result */
1881 parmnum = map_parameter(pszParmName);
1885 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1889 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1890 DEBUG(1,("WARNING: The \"%s\"option is deprecated\n",
1894 def_ptr = parm_table[parmnum].ptr;
1896 /* we might point at a service, the default service or a global */
1900 if (parm_table[parmnum].class == P_GLOBAL) {
1901 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1904 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1908 if (!iSERVICE(snum).copymap)
1909 init_copymap(pSERVICE(snum));
1911 /* this handles the aliases - set the copymap for other entries with
1912 the same data pointer */
1913 for (i=0;parm_table[i].label;i++)
1914 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1915 iSERVICE(snum).copymap[i] = False;
1918 /* if it is a special case then go ahead */
1919 if (parm_table[parmnum].special) {
1920 parm_table[parmnum].special(pszParmValue,(char **)parm_ptr);
1924 /* now switch on the type of variable it is */
1925 switch (parm_table[parmnum].type)
1928 set_boolean(parm_ptr,pszParmValue);
1932 set_boolean(parm_ptr,pszParmValue);
1933 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1937 *(int *)parm_ptr = atoi(pszParmValue);
1941 *(char *)parm_ptr = *pszParmValue;
1945 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1949 string_set(parm_ptr,pszParmValue);
1953 string_set(parm_ptr,pszParmValue);
1954 strupper(*(char **)parm_ptr);
1958 pstrcpy((char *)parm_ptr,pszParmValue);
1962 pstrcpy((char *)parm_ptr,pszParmValue);
1963 strupper((char *)parm_ptr);
1967 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1968 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1969 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
1981 /***************************************************************************
1982 Process a parameter.
1983 ***************************************************************************/
1984 static BOOL do_parameter( char *pszParmName, char *pszParmValue )
1986 if( !bInGlobalSection && bGlobalOnly )
1989 DEBUGADD( 3, ( "doing parameter %s = %s\n", pszParmName, pszParmValue ) );
1991 return( lp_do_parameter( bInGlobalSection ? -2 : iServiceIndex,
1997 /***************************************************************************
1998 print a parameter of the specified type
1999 ***************************************************************************/
2000 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
2005 for (i=0;p->enum_list[i].name;i++) {
2006 if (*(int *)ptr == p->enum_list[i].value) {
2007 fprintf(f,"%s",p->enum_list[i].name);
2014 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
2018 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
2022 fprintf(f,"%d",*(int *)ptr);
2026 fprintf(f,"%c",*(char *)ptr);
2030 fprintf(f,"0%o",*(int *)ptr);
2036 fprintf(f,"%s",(char *)ptr);
2042 fprintf(f,"%s",*(char **)ptr);
2050 /***************************************************************************
2051 check if two parameters are equal
2052 ***************************************************************************/
2053 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
2059 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
2064 return(*((int *)ptr1) == *((int *)ptr2));
2067 return(*((char *)ptr1) == *((char *)ptr2));
2072 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
2073 if (p1 && !*p1) p1 = NULL;
2074 if (p2 && !*p2) p2 = NULL;
2075 return(p1==p2 || strequal(p1,p2));
2080 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2081 if (p1 && !*p1) p1 = NULL;
2082 if (p2 && !*p2) p2 = NULL;
2083 return(p1==p2 || strequal(p1,p2));
2091 /***************************************************************************
2092 Process a new section (service). At this stage all sections are services.
2093 Later we'll have special sections that permit server parameters to be set.
2094 Returns True on success, False on failure.
2095 ***************************************************************************/
2096 static BOOL do_section(char *pszSectionName)
2099 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2100 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2103 /* if we were in a global section then do the local inits */
2104 if (bInGlobalSection && !isglobal)
2107 /* if we've just struck a global section, note the fact. */
2108 bInGlobalSection = isglobal;
2110 /* check for multiple global sections */
2111 if (bInGlobalSection)
2113 DEBUG( 3, ( "Processing section \"[%s]\"\n", pszSectionName ) );
2117 if (!bInGlobalSection && bGlobalOnly) return(True);
2119 /* if we have a current service, tidy it up before moving on */
2122 if (iServiceIndex >= 0)
2123 bRetval = service_ok(iServiceIndex);
2125 /* if all is still well, move to the next record in the services array */
2128 /* We put this here to avoid an odd message order if messages are */
2129 /* issued by the post-processing of a previous section. */
2130 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
2132 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
2134 DEBUG(0,("Failed to add a new service\n"));
2143 /***************************************************************************
2144 determine if a partcular base parameter is currently set to the default value.
2145 ***************************************************************************/
2146 static BOOL is_default(int i)
2148 if (!defaults_saved) return False;
2149 switch (parm_table[i].type) {
2152 return strequal(parm_table[i].def.svalue,*(char **)parm_table[i].ptr);
2155 return strequal(parm_table[i].def.svalue,(char *)parm_table[i].ptr);
2158 return parm_table[i].def.bvalue == *(BOOL *)parm_table[i].ptr;
2160 return parm_table[i].def.cvalue == *(char *)parm_table[i].ptr;
2164 return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
2172 /***************************************************************************
2173 Display the contents of the global structure.
2174 ***************************************************************************/
2175 static void dump_globals(FILE *f)
2178 fprintf(f, "# Global parameters\n");
2180 for (i=0;parm_table[i].label;i++)
2181 if (parm_table[i].class == P_GLOBAL &&
2182 parm_table[i].ptr &&
2183 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2184 if (defaults_saved && is_default(i)) continue;
2185 fprintf(f,"\t%s = ",parm_table[i].label);
2186 print_parameter(&parm_table[i],parm_table[i].ptr, f);
2191 /***************************************************************************
2192 return True if a local parameter is currently set to the global default
2193 ***************************************************************************/
2194 BOOL lp_is_default(int snum, struct parm_struct *parm)
2196 int pdiff = PTR_DIFF(parm->ptr,&sDefault);
2198 return equal_parameter(parm->type,
2199 ((char *)pSERVICE(snum)) + pdiff,
2200 ((char *)&sDefault) + pdiff);
2204 /***************************************************************************
2205 Display the contents of a single services record.
2206 ***************************************************************************/
2207 static void dump_a_service(service *pService, FILE *f)
2210 if (pService != &sDefault)
2211 fprintf(f,"\n[%s]\n",pService->szService);
2213 for (i=0;parm_table[i].label;i++)
2214 if (parm_table[i].class == P_LOCAL &&
2215 parm_table[i].ptr &&
2216 (*parm_table[i].label != '-') &&
2217 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2218 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
2220 if (pService == &sDefault) {
2221 if (defaults_saved && is_default(i)) continue;
2223 if (equal_parameter(parm_table[i].type,
2224 ((char *)pService) + pdiff,
2225 ((char *)&sDefault) + pdiff))
2229 fprintf(f,"\t%s = ",parm_table[i].label);
2230 print_parameter(&parm_table[i],
2231 ((char *)pService) + pdiff, f);
2237 /***************************************************************************
2238 return info about the next service in a service. snum==-1 gives the globals
2240 return NULL when out of parameters
2241 ***************************************************************************/
2242 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2245 /* do the globals */
2246 for (;parm_table[*i].label;(*i)++) {
2247 if (parm_table[*i].class == P_SEPARATOR)
2248 return &parm_table[(*i)++];
2250 if (!parm_table[*i].ptr || (*parm_table[*i].label == '-'))
2253 if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr))
2256 return &parm_table[(*i)++];
2259 service *pService = pSERVICE(snum);
2261 for (;parm_table[*i].label;(*i)++) {
2262 if (parm_table[*i].class == P_SEPARATOR)
2263 return &parm_table[(*i)++];
2265 if (parm_table[*i].class == P_LOCAL &&
2266 parm_table[*i].ptr &&
2267 (*parm_table[*i].label != '-') &&
2269 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2270 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2272 if (allparameters ||
2273 !equal_parameter(parm_table[*i].type,
2274 ((char *)pService) + pdiff,
2275 ((char *)&sDefault) + pdiff)) {
2276 return &parm_table[(*i)++];
2287 /***************************************************************************
2288 Display the contents of a single copy structure.
2289 ***************************************************************************/
2290 static void dump_copy_map(BOOL *pcopymap)
2293 if (!pcopymap) return;
2295 printf("\n\tNon-Copied parameters:\n");
2297 for (i=0;parm_table[i].label;i++)
2298 if (parm_table[i].class == P_LOCAL &&
2299 parm_table[i].ptr && !pcopymap[i] &&
2300 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2302 printf("\t\t%s\n",parm_table[i].label);
2307 /***************************************************************************
2308 Return TRUE if the passed service number is within range.
2309 ***************************************************************************/
2310 BOOL lp_snum_ok(int iService)
2312 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2316 /***************************************************************************
2317 auto-load some home services
2318 ***************************************************************************/
2319 static void lp_add_auto_services(char *str)
2330 homes = lp_servicenumber(HOMES_NAME);
2332 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
2333 char *home = get_home_dir(p);
2335 if (lp_servicenumber(p) >= 0) continue;
2337 if (home && homes >= 0) {
2338 lp_add_home(p,homes,home);
2344 /***************************************************************************
2345 auto-load one printer
2346 ***************************************************************************/
2347 void lp_add_one_printer(char *name,char *comment)
2349 int printers = lp_servicenumber(PRINTERS_NAME);
2352 if (lp_servicenumber(name) < 0) {
2353 lp_add_printer(name,printers);
2354 if ((i=lp_servicenumber(name)) >= 0)
2355 string_set(&iSERVICE(i).comment,comment);
2359 /***************************************************************************
2360 have we loaded a services file yet?
2361 ***************************************************************************/
2362 BOOL lp_loaded(void)
2367 /***************************************************************************
2368 unload unused services
2369 ***************************************************************************/
2370 void lp_killunused(BOOL (*snumused)(int ))
2373 for (i=0;i<iNumServices;i++)
2374 if (VALID(i) && (!snumused || !snumused(i)))
2376 iSERVICE(i).valid = False;
2377 free_service(pSERVICE(i));
2382 /***************************************************************************
2383 save the curent values of all global and sDefault parameters into the
2384 defaults union. This allows swat and testparm to show only the
2385 changed (ie. non-default) parameters.
2386 ***************************************************************************/
2387 static void lp_save_defaults(void)
2390 for (i = 0; parm_table[i].label; i++) {
2391 if (i>0 && parm_table[i].ptr == parm_table[i-1].ptr) continue;
2392 switch (parm_table[i].type) {
2395 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2399 parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
2403 parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr;
2406 parm_table[i].def.cvalue = *(char *)parm_table[i].ptr;
2411 parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
2417 defaults_saved = True;
2421 /***************************************************************************
2422 Load the services array from the services file. Return True on success,
2424 ***************************************************************************/
2425 BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
2430 add_to_file_list(pszFname);
2434 bInGlobalSection = True;
2435 bGlobalOnly = global_only;
2439 if (save_defaults) {
2444 pstrcpy(n2,pszFname);
2445 standard_sub_basic(n2);
2447 /* We get sections first, so have to start 'behind' to make up */
2449 bRetval = pm_process(n2, do_section, do_parameter);
2451 /* finish up the last section */
2452 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2454 if (iServiceIndex >= 0)
2455 bRetval = service_ok(iServiceIndex);
2457 lp_add_auto_services(lp_auto_services());
2462 set_default_server_announce_type();
2470 /***************************************************************************
2471 return the max number of services
2472 ***************************************************************************/
2473 int lp_numservices(void)
2475 return(iNumServices);
2478 /***************************************************************************
2479 Display the contents of the services array in human-readable form.
2480 ***************************************************************************/
2481 void lp_dump(FILE *f, BOOL show_defaults)
2485 if (show_defaults) {
2486 defaults_saved = False;
2491 dump_a_service(&sDefault, f);
2493 for (iService = 0; iService < iNumServices; iService++)
2495 if (VALID(iService))
2497 if (iSERVICE(iService).szService[0] == '\0')
2499 dump_a_service(pSERVICE(iService), f);
2505 /***************************************************************************
2506 Return the number of the service with the given name, or -1 if it doesn't
2507 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2508 getservicebyname()! This works ONLY if all services have been loaded, and
2509 does not copy the found service.
2510 ***************************************************************************/
2511 int lp_servicenumber(char *pszServiceName)
2515 for (iService = iNumServices - 1; iService >= 0; iService--)
2516 if (VALID(iService) &&
2517 strequal(lp_servicename(iService), pszServiceName))
2521 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2526 /*******************************************************************
2527 a useful volume label function
2528 ******************************************************************/
2529 char *volume_label(int snum)
2531 char *ret = lp_volume(snum);
2532 if (!*ret) return(lp_servicename(snum));
2537 /*******************************************************************
2538 Set the server type we will announce as via nmbd.
2539 ********************************************************************/
2540 static void set_default_server_announce_type()
2542 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2543 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2544 if(lp_announce_as() == ANNOUNCE_AS_NT)
2545 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2546 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2547 default_server_announce |= SV_TYPE_WIN95_PLUS;
2548 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2549 default_server_announce |= SV_TYPE_WFW;
2550 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2554 /*******************************************************************
2556 ********************************************************************/
2557 void lp_rename_service(int snum, char *new_name)
2559 string_set(&pSERVICE(snum)->szService, new_name);
2562 /*******************************************************************
2564 ********************************************************************/
2565 void lp_remove_service(int snum)
2567 pSERVICE(snum)->valid = False;
2570 /*******************************************************************
2572 ********************************************************************/
2573 void lp_copy_service(int snum, char *new_name)
2575 char *oldname = lp_servicename(snum);
2576 do_section(new_name);
2578 snum = lp_servicenumber(new_name);
2580 lp_do_parameter(snum, "copy", oldname);
2585 /*******************************************************************
2586 Get the default server type we will announce as via nmbd.
2587 ********************************************************************/
2588 int lp_default_server_announce(void)
2590 return default_server_announce;
2593 /*******************************************************************
2594 Split the announce version into major and minor numbers.
2595 ********************************************************************/
2596 int lp_major_announce_version(void)
2598 static BOOL got_major = False;
2599 static int major_version = DEFAULT_MAJOR_VERSION;
2604 return major_version;
2607 if((vers = lp_announce_version()) == NULL)
2608 return major_version;
2610 if((p = strchr(vers, '.')) == 0)
2611 return major_version;
2614 major_version = atoi(vers);
2615 return major_version;
2618 int lp_minor_announce_version(void)
2620 static BOOL got_minor = False;
2621 static int minor_version = DEFAULT_MINOR_VERSION;
2626 return minor_version;
2629 if((vers = lp_announce_version()) == NULL)
2630 return minor_version;
2632 if((p = strchr(vers, '.')) == 0)
2633 return minor_version;
2636 minor_version = atoi(p);
2637 return minor_version;
2640 /***********************************************************
2641 Set the global name resolution order (used in smbclient).
2642 ************************************************************/
2644 void lp_set_name_resolve_order(char *new_order)
2646 Globals.szNameResolveOrder = new_order;