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 #ifdef USING_GROUPNAME_MAP
130 char *szGroupnameMap;
131 #endif /* USING_GROUPNAME_MAP */
132 char *szCharacterSet;
139 char *szCodingSystem;
141 char *szRemoteAnnounce;
142 char *szRemoteBrowseSync;
143 char *szSocketAddress;
144 char *szNISHomeMapName;
145 char *szAnnounceVersion; /* This is initialised in init_globals */
146 char *szNetbiosAliases;
148 char *szDomainOtherSIDs;
149 char *szDomainGroups;
151 char *szNameResolveOrder;
156 char *szLdapRootPassword;
179 int client_code_page;
180 int announce_as; /* This is initialised in init_globals */
181 int machine_password_timeout;
182 int change_notify_timeout;
186 #endif /* WITH_LDAP */
189 char *sslHostsRequire;
190 char *sslHostsResign;
196 char *sslClientPrivKey;
199 BOOL sslReqClientCert;
200 BOOL sslReqServerCert;
201 BOOL sslCompatibility;
202 #endif /* WITH_SSL */
207 BOOL bPreferredMaster;
208 BOOL bDomainController;
211 BOOL bEncryptPasswords;
219 BOOL bReadPrediction;
226 BOOL bBindInterfacesOnly;
227 BOOL bNetWkstaUserLogon;
228 BOOL bUnixPasswdSync;
229 BOOL bPasswdChatDebug;
230 BOOL bOleLockingCompat;
236 static global Globals;
241 * This structure describes a single service.
249 char *szGuestaccount;
250 char *szInvalidUsers;
258 char *szRootPostExec;
259 char *szPrintcommand;
262 char *szLppausecommand;
263 char *szLpresumecommand;
264 char *szQueuepausecommand;
265 char *szQueueresumecommand;
267 char *szPrinterDriver;
268 char *szPrinterDriverLocation;
277 char *szVetoOplockFiles;
286 int iCreate_force_mode;
296 BOOL bShortCasePreserve;
323 BOOL bDeleteReadonly;
325 BOOL bDeleteVetoFiles;
327 BOOL bDosFiletimeResolution;
328 BOOL bFakeDirCreateTimes;
330 char dummy[3]; /* for alignment */
334 /* This is a default service used to prime a services structure */
335 static service sDefault =
338 NULL, /* szService */
340 NULL, /* szUsername */
341 NULL, /* szGuestAccount - this is set in init_globals() */
342 NULL, /* szInvalidUsers */
343 NULL, /* szValidUsers */
344 NULL, /* szAdminUsers */
346 NULL, /* szInclude */
347 NULL, /* szPreExec */
348 NULL, /* szPostExec */
349 NULL, /* szRootPreExec */
350 NULL, /* szRootPostExec */
351 NULL, /* szPrintcommand */
352 NULL, /* szLpqcommand */
353 NULL, /* szLprmcommand */
354 NULL, /* szLppausecommand */
355 NULL, /* szLpresumecommand */
356 NULL, /* szQueuepausecommand */
357 NULL, /* szQueueresumecommand */
358 NULL, /* szPrintername */
359 NULL, /* szPrinterDriver - this is set in init_globals() */
360 NULL, /* szPrinterDriverLocation */
361 NULL, /* szDontdescend */
362 NULL, /* szHostsallow */
363 NULL, /* szHostsdeny */
364 NULL, /* szMagicScript */
365 NULL, /* szMagicOutput */
366 NULL, /* szMangledMap */
367 NULL, /* szVetoFiles */
368 NULL, /* szHideFiles */
369 NULL, /* szVetoOplockFiles */
371 NULL, /* force user */
372 NULL, /* force group */
374 NULL, /* writelist */
376 0, /* iMinPrintSpace */
377 0744, /* iCreate_mask */
378 0000, /* iCreate_force_mode */
379 0755, /* iDir_mask */
380 0000, /* iDir_force_mode */
381 0, /* iMaxConnections */
382 CASE_LOWER, /* iDefaultCase */
383 DEFAULT_PRINTING, /* iPrinting */
384 False, /* bAlternatePerm */
385 False, /* revalidate */
386 False, /* case sensitive */
387 True, /* case preserve */
388 True, /* short case preserve */
389 False, /* case mangle */
391 True, /* bHideDotFiles */
392 True, /* bBrowseable */
393 True, /* bAvailable */
394 True, /* bRead_only */
395 True, /* bNo_set_dir */
396 False, /* bGuest_only */
397 False, /* bGuest_ok */
398 False, /* bPrint_ok */
399 False, /* bPostscript */
400 False, /* bMap_system */
401 False, /* bMap_hidden */
402 True, /* bMap_archive */
404 False, /* bStrictLocking */
405 True, /* bShareModes */
407 False, /* bOnlyUser */
408 True, /* bMangledNames */
409 True, /* bWidelinks */
410 True, /* bSymlinks */
411 False, /* bSyncAlways */
412 False, /* bStrictSync */
413 '~', /* magic char */
415 False, /* bDeleteReadonly */
416 False, /* bFakeOplocks */
417 False, /* bDeleteVetoFiles */
418 False, /* bDosFiletimes */
419 False, /* bDosFiletimeResolution */
420 False, /* bFakeDirCreateTimes */
421 True, /* bBlockingLocks */
427 /* local variables */
428 static service **ServicePtrs = NULL;
429 static int iNumServices = 0;
430 static int iServiceIndex = 0;
431 static BOOL bInGlobalSection = True;
432 static BOOL bGlobalOnly = False;
433 static int default_server_announce;
435 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
437 /* prototypes for the special type handlers */
438 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
439 static BOOL handle_include(char *pszParmValue, char **ptr);
440 static BOOL handle_copy(char *pszParmValue, char **ptr);
441 static BOOL handle_character_set(char *pszParmValue,char **ptr);
442 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
444 static void set_default_server_announce_type(void);
446 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
447 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"},
448 {PROTOCOL_COREPLUS, "COREPLUS"},
449 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
451 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
452 {SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"},
455 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
456 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
457 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
458 {PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"},
461 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
462 {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
464 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
466 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
469 static struct enum_list enum_ssl_version[] = {{SMB_SSL_V2, "ssl2"}, {SMB_SSL_V3, "ssl3"},
470 {SMB_SSL_V23, "ssl2or3"}, {SMB_SSL_TLS1, "tls1"}, {-1, NULL}};
473 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
474 static struct parm_struct parm_table[] =
476 {"Base Options", P_SEP, P_SEPARATOR},
477 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
478 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
479 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
480 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
481 {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, NULL, NULL, FLAG_BASIC},
482 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
483 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC},
484 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
485 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0},
487 {"Security Options", P_SEP, P_SEPARATOR},
488 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
489 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
490 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC},
491 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
492 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
493 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
494 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
495 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
496 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
497 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
498 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
499 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0},
500 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
501 {"passwd chat debug",P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0},
502 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
503 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
504 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
505 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0},
506 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL|FLAG_DEPRECATED},
507 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL},
508 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL},
509 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
510 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
511 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
512 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL},
513 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL},
514 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL},
515 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL},
516 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL},
517 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, 0},
518 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
519 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
520 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC},
521 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
522 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
523 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
524 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
525 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
526 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL},
527 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
528 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
529 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL},
530 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
531 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
532 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
533 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
534 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, 0},
535 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
536 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
537 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
538 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
541 {"Secure Socket Layer Options", P_SEP, P_SEPARATOR},
542 {"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0 },
543 {"ssl hosts", P_STRING, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0 },
544 {"ssl hosts resign", P_STRING, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0} ,
545 {"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0 },
546 {"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0 },
547 {"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslCert, NULL, NULL, 0 },
548 {"ssl server key", P_STRING, P_GLOBAL, &Globals.sslPrivKey, NULL, NULL, 0 },
549 {"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0 },
550 {"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0 },
551 {"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL , 0},
552 {"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL , 0},
553 {"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0 },
554 {"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0},
555 {"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0 },
556 #endif /* WITH_SSL */
558 {"Logging Options", P_SEP, P_SEPARATOR},
559 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
560 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
561 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
562 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
563 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
564 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
565 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
566 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
567 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
569 {"Protocol Options", P_SEP, P_SEPARATOR},
570 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
571 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
572 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
573 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
574 {"networkstation user login", P_BOOL,P_GLOBAL, &Globals.bNetWkstaUserLogon,NULL, NULL, 0},
575 {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0},
576 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
577 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
578 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
579 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
580 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0},
581 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
582 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
583 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0},
584 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
585 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
586 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
588 {"Tuning Options", P_SEP, P_SEPARATOR},
589 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, 0},
590 {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0},
591 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
592 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
593 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
594 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
595 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0},
596 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
597 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0},
598 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0},
599 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
600 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0},
601 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
602 {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0},
603 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, 0},
604 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0},
606 {"Printing Options", P_SEP, P_SEPARATOR},
607 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0},
608 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
609 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
610 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, 0},
611 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
612 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
613 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
614 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL},
615 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
616 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
617 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
618 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_GLOBAL},
619 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_GLOBAL},
620 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_GLOBAL},
621 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_GLOBAL},
623 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
624 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
625 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
626 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_GLOBAL},
629 {"Filename Handling", P_SEP, P_SEPARATOR},
630 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
631 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
632 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
633 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
634 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0},
635 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, 0},
636 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_GLOBAL},
637 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
638 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_GLOBAL},
639 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_GLOBAL},
640 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_GLOBAL},
641 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_GLOBAL},
642 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_GLOBAL},
643 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_GLOBAL},
644 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_GLOBAL},
645 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_GLOBAL},
646 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_GLOBAL},
647 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_GLOBAL},
648 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_GLOBAL},
649 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_GLOBAL},
650 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_GLOBAL},
651 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_GLOBAL},
652 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0},
654 {"Domain Options", P_SEP, P_SEPARATOR},
655 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL, NULL, 0},
656 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
657 {"domain controller",P_BOOL , P_GLOBAL, &Globals.bDomainController,NULL, NULL, 0},
658 {"domain admin group",P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0},
659 {"domain guest group",P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0},
660 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0},
661 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0},
662 #ifdef USING_GROUPNAME_MAP
663 {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0},
664 #endif /* USING_GROUPNAME_MAP */
665 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0},
667 {"Logon Options", P_SEP, P_SEPARATOR},
668 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
669 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0},
670 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
671 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0},
672 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
674 {"Browse Options", P_SEP, P_SEPARATOR},
675 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC},
676 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0},
677 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
678 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, FLAG_BASIC},
679 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
680 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC},
681 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, FLAG_BASIC},
682 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
683 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
684 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
686 {"WINS Options", P_SEP, P_SEPARATOR},
687 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
688 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC},
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},
692 {"Locking Options", P_SEP, P_SEPARATOR},
693 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_GLOBAL},
694 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_GLOBAL},
695 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_GLOBAL},
696 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
697 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
698 {"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, FLAG_GLOBAL},
701 {"Ldap Options", P_SEP, P_SEPARATOR},
702 {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
703 {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
704 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0},
705 {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0},
706 {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0},
707 {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword,NULL, NULL, 0},
708 #endif /* WITH_LDAP */
711 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
712 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
713 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
714 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
715 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
716 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
717 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
718 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
719 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
720 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
721 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
722 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
723 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0},
724 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL, 0},
725 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
726 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
727 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
728 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0},
729 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
730 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
731 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
732 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
733 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
734 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
735 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, 0},
736 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, 0},
737 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, 0},
738 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, 0},
739 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, 0},
740 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, 0},
741 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_GLOBAL},
742 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_GLOBAL},
743 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, 0},
744 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, 0},
745 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, 0},
746 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_GLOBAL},
747 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_GLOBAL},
748 {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_GLOBAL},
750 {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_GLOBAL},
751 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0},
753 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
758 /***************************************************************************
759 Initialise the global parameter structure.
760 ***************************************************************************/
761 static void init_globals(void)
763 static BOOL done_init = False;
769 bzero((void *)&Globals,sizeof(Globals));
771 for (i = 0; parm_table[i].label; i++)
772 if ((parm_table[i].type == P_STRING ||
773 parm_table[i].type == P_USTRING) &&
775 string_init(parm_table[i].ptr,"");
777 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
778 string_set(&sDefault.szPrinterDriver, "NULL");
784 DEBUG(3,("Initialising global parameters\n"));
786 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
787 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
788 string_set(&Globals.szWorkGroup, WORKGROUP);
789 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
790 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
791 string_set(&Globals.szDriverFile, DRIVERFILE);
792 string_set(&Globals.szLockDir, LOCKDIR);
793 string_set(&Globals.szRootdir, "/");
794 string_set(&Globals.szSmbrun, SMBRUN);
795 string_set(&Globals.szSocketAddress, "0.0.0.0");
796 pstrcpy(s, "Samba ");
798 string_set(&Globals.szServerString,s);
799 slprintf(s,sizeof(s)-1, "%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
800 string_set(&Globals.szAnnounceVersion,s);
802 string_set(&Globals.szLogonDrive, "");
803 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
804 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
805 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
807 string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast");
809 Globals.bLoadPrinters = True;
810 Globals.bUseRhosts = False;
811 Globals.max_packet = 65535;
812 Globals.mangled_stack = 50;
813 Globals.max_xmit = 65535;
814 Globals.max_mux = 50; /* This is *needed* for profile support. */
815 Globals.lpqcachetime = 10;
816 Globals.pwordlevel = 0;
817 Globals.unamelevel = 0;
818 Globals.deadtime = 0;
819 Globals.max_log_size = 5000;
820 Globals.maxprotocol = PROTOCOL_NT1;
821 Globals.security = SEC_USER;
822 Globals.bEncryptPasswords = False;
823 Globals.bUpdateEncrypt = False;
824 Globals.bReadRaw = True;
825 Globals.bWriteRaw = True;
826 Globals.bReadPrediction = False;
827 Globals.bReadbmpx = True;
828 Globals.bNullPasswords = False;
829 Globals.bStripDot = False;
831 Globals.bSyslogOnly = False;
832 Globals.bTimestampLogs = True;
833 Globals.os_level = 0;
834 Globals.max_ttl = 60*60*24*3; /* 3 days default. */
835 Globals.max_wins_ttl = 60*60*24*6; /* 6 days default. */
836 Globals.min_wins_ttl = 60*60*6; /* 6 hours default. */
837 Globals.machine_password_timeout = 60*60*24*7; /* 7 days default. */
838 Globals.change_notify_timeout = 60; /* 1 minute default. */
839 Globals.ReadSize = 16*1024;
840 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
841 Globals.lm_interval = 60;
842 Globals.shmem_size = SHMEM_SIZE;
843 Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */
844 Globals.announce_as = ANNOUNCE_AS_NT;
845 Globals.bUnixRealname = False;
846 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
847 Globals.bNISHomeMap = False;
848 #ifdef WITH_NISPLUS_HOME
849 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
851 string_set(&Globals.szNISHomeMapName, "auto.home");
854 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
855 Globals.bTimeServer = False;
856 Globals.bBindInterfacesOnly = False;
857 Globals.bNetWkstaUserLogon = False; /* This is now set to false by default as
858 the code in password.c protects us from this bug. */
859 Globals.bUnixPasswdSync = False;
860 Globals.bPasswdChatDebug = False;
861 Globals.bOleLockingCompat = True;
862 Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */
863 Globals.bStatCache = True; /* use stat cache by default */
866 /* default values for ldap */
867 string_set(&Globals.szLdapServer, "localhost");
868 Globals.ldap_port=389;
869 #endif /* WITH_LDAP */
872 Globals.sslVersion = SMB_SSL_V23;
873 Globals.sslHostsRequire = NULL;
874 Globals.sslHostsResign = NULL;
875 Globals.sslCaCertDir = NULL;
876 Globals.sslCaCertFile = NULL;
877 Globals.sslCert = NULL;
878 Globals.sslPrivKey = NULL;
879 Globals.sslClientCert = NULL;
880 Globals.sslClientPrivKey = NULL;
881 Globals.sslCiphers = NULL;
882 Globals.sslEnabled = False;
883 Globals.sslReqClientCert = False;
884 Globals.sslReqServerCert = False;
885 Globals.sslCompatibility = False;
886 #endif /* WITH_SSL */
888 /* these parameters are set to defaults that are more appropriate
889 for the increasing samba install base:
891 as a member of the workgroup, that will possibly become a
892 _local_ master browser (lm = True). this is opposed to a forced
893 local master browser startup (pm = True).
895 doesn't provide WINS server service by default (wsupp = False),
896 and doesn't provide domain master browser services by default, either.
900 Globals.bPreferredMaster = False;
901 Globals.bLocalMaster = True;
902 Globals.bDomainMaster = False;
903 Globals.bDomainLogons = False;
904 Globals.bBrowseList = True;
905 Globals.bWINSsupport = False;
906 Globals.bWINSproxy = False;
908 Globals.bDNSproxy = True;
911 * This must be done last as it checks the value in
915 interpret_coding_system(KANJI);
918 /***************************************************************************
919 check if a string is initialised and if not then initialise it
920 ***************************************************************************/
921 static void string_initial(char **s,char *v)
928 /***************************************************************************
929 Initialise the sDefault parameter structure.
930 ***************************************************************************/
931 static void init_locals(void)
933 /* choose defaults depending on the type of printing */
934 switch (sDefault.iPrinting)
940 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
941 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
942 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
947 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
948 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
949 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
951 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
952 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
953 string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
954 string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
956 string_initial(&sDefault.szQueuepausecommand, "disable %p");
957 string_initial(&sDefault.szQueueresumecommand, "enable %p");
962 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
963 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
964 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
968 string_initial(&sDefault.szLpqcommand,"qstat -l -d%p");
969 string_initial(&sDefault.szLprmcommand,"qstat -s -j%j -c");
970 string_initial(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
971 string_initial(&sDefault.szLppausecommand,"qstat -s -j%j -h");
972 string_initial(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
979 /******************************************************************* a
980 convenience routine to grab string parameters into a rotating buffer,
981 and run standard_sub_basic on them. The buffers can be written to by
982 callers without affecting the source string.
983 ********************************************************************/
984 static char *lp_string(char *s)
986 static char *bufs[10];
987 static int buflen[10];
988 static int next = -1;
991 int len = s?strlen(s):0;
1002 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
1003 substitution room */
1005 if (buflen[next] != len) {
1007 if (bufs[next]) free(bufs[next]);
1008 bufs[next] = (char *)malloc(len);
1010 DEBUG(0,("out of memory in lp_string()"));
1015 ret = &bufs[next][0];
1023 trim_string(ret, "\"", "\"");
1025 standard_sub_basic(ret);
1031 In this section all the functions that are used to access the
1032 parameters from the rest of the program are defined
1035 #define FN_GLOBAL_STRING(fn_name,ptr) \
1036 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1037 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1038 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1039 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1040 char fn_name(void) {return(*(char *)(ptr));}
1041 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1042 int fn_name(void) {return(*(int *)(ptr));}
1044 #define FN_LOCAL_STRING(fn_name,val) \
1045 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
1046 #define FN_LOCAL_BOOL(fn_name,val) \
1047 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1048 #define FN_LOCAL_CHAR(fn_name,val) \
1049 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1050 #define FN_LOCAL_INTEGER(fn_name,val) \
1051 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1053 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
1054 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
1055 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
1056 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
1057 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
1058 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
1059 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
1060 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
1061 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
1062 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
1063 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
1064 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
1065 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
1066 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
1067 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
1068 FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder)
1069 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
1070 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
1071 #ifdef USING_GROUPNAME_MAP
1072 FN_GLOBAL_STRING(lp_groupname_map,&Globals.szGroupnameMap)
1073 #endif /* USING_GROUPNAME_MAP */
1074 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
1075 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
1076 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
1077 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
1078 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
1079 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
1080 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
1081 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
1082 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
1083 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
1084 static FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
1085 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
1086 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
1087 FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction)
1089 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
1090 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
1091 FN_GLOBAL_STRING(lp_domain_admin_group,&Globals.szDomainAdminGroup)
1092 FN_GLOBAL_STRING(lp_domain_guest_group,&Globals.szDomainGuestGroup)
1093 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
1094 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
1097 FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer);
1098 FN_GLOBAL_STRING(lp_ldap_suffix,&Globals.szLdapSuffix);
1099 FN_GLOBAL_STRING(lp_ldap_filter,&Globals.szLdapFilter);
1100 FN_GLOBAL_STRING(lp_ldap_root,&Globals.szLdapRoot);
1101 FN_GLOBAL_STRING(lp_ldap_rootpasswd,&Globals.szLdapRootPassword);
1102 #endif /* WITH_LDAP */
1105 FN_GLOBAL_INTEGER(lp_ssl_version,&Globals.sslVersion);
1106 FN_GLOBAL_STRING(lp_ssl_hosts,&Globals.sslHostsRequire);
1107 FN_GLOBAL_STRING(lp_ssl_hosts_resign,&Globals.sslHostsResign);
1108 FN_GLOBAL_STRING(lp_ssl_cacertdir,&Globals.sslCaCertDir);
1109 FN_GLOBAL_STRING(lp_ssl_cacertfile,&Globals.sslCaCertFile);
1110 FN_GLOBAL_STRING(lp_ssl_cert,&Globals.sslCert);
1111 FN_GLOBAL_STRING(lp_ssl_privkey,&Globals.sslPrivKey);
1112 FN_GLOBAL_STRING(lp_ssl_client_cert,&Globals.sslClientCert);
1113 FN_GLOBAL_STRING(lp_ssl_client_privkey,&Globals.sslClientPrivKey);
1114 FN_GLOBAL_STRING(lp_ssl_ciphers,&Globals.sslCiphers);
1115 FN_GLOBAL_BOOL(lp_ssl_enabled,&Globals.sslEnabled);
1116 FN_GLOBAL_BOOL(lp_ssl_reqClientCert,&Globals.sslReqClientCert);
1117 FN_GLOBAL_BOOL(lp_ssl_reqServerCert,&Globals.sslReqServerCert);
1118 FN_GLOBAL_BOOL(lp_ssl_compatibility,&Globals.sslCompatibility);
1119 #endif /* WITH_SSL */
1121 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
1122 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
1123 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
1124 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
1125 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
1126 FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController)
1127 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
1128 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
1129 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
1130 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
1131 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
1132 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
1133 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
1134 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
1135 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
1136 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
1137 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
1138 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
1139 FN_GLOBAL_BOOL(lp_update_encrypted,&Globals.bUpdateEncrypt)
1140 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
1141 FN_GLOBAL_BOOL(lp_timestamp_logs,&Globals.bTimestampLogs)
1142 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
1143 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
1144 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
1145 static FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
1146 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
1147 FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
1148 FN_GLOBAL_BOOL(lp_unix_password_sync,&Globals.bUnixPasswdSync)
1149 FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug)
1150 FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat)
1151 FN_GLOBAL_BOOL(lp_nt_smb_support,&Globals.bNTSmbSupport)
1152 FN_GLOBAL_BOOL(lp_stat_cache,&Globals.bStatCache)
1154 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
1155 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
1156 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
1157 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
1158 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
1159 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
1160 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
1161 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
1162 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
1163 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
1164 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
1165 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
1166 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
1167 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
1168 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
1169 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
1170 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
1171 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
1172 static FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
1173 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
1174 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
1175 FN_GLOBAL_INTEGER(lp_machine_password_timeout,&Globals.machine_password_timeout)
1176 FN_GLOBAL_INTEGER(lp_change_notify_timeout,&Globals.change_notify_timeout)
1177 FN_GLOBAL_INTEGER(lp_stat_cache_size,&Globals.stat_cache_size)
1180 FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port)
1181 #endif /* WITH_LDAP */
1183 FN_LOCAL_STRING(lp_preexec,szPreExec)
1184 FN_LOCAL_STRING(lp_postexec,szPostExec)
1185 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
1186 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
1187 FN_LOCAL_STRING(lp_servicename,szService)
1188 FN_LOCAL_STRING(lp_pathname,szPath)
1189 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
1190 FN_LOCAL_STRING(lp_username,szUsername)
1191 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
1192 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
1193 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
1194 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
1195 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
1196 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
1197 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
1198 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
1199 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
1200 FN_LOCAL_STRING(lp_queuepausecommand,szQueuepausecommand)
1201 FN_LOCAL_STRING(lp_queueresumecommand,szQueueresumecommand)
1202 FN_LOCAL_STRING(lp_printername,szPrintername)
1203 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
1204 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
1205 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
1206 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
1207 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
1208 FN_LOCAL_STRING(lp_comment,comment)
1209 FN_LOCAL_STRING(lp_force_user,force_user)
1210 FN_LOCAL_STRING(lp_force_group,force_group)
1211 FN_LOCAL_STRING(lp_readlist,readlist)
1212 FN_LOCAL_STRING(lp_writelist,writelist)
1213 static FN_LOCAL_STRING(lp_volume,volume)
1214 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
1215 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
1216 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
1217 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
1218 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
1220 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
1221 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
1222 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1223 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1224 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1225 FN_LOCAL_BOOL(lp_status,status)
1226 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1227 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1228 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1229 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1230 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1231 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1232 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1233 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1234 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1235 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1236 FN_LOCAL_BOOL(lp_locking,bLocking)
1237 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1238 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1239 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1240 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1241 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1242 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1243 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1244 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1245 FN_LOCAL_BOOL(lp_strict_sync,bStrictSync)
1246 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1247 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1248 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1249 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1250 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1251 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
1252 FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
1253 FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks)
1255 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1256 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1257 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1258 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1259 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1260 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1261 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1262 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1264 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1268 /* local prototypes */
1269 static int strwicmp( char *psz1, char *psz2 );
1270 static int map_parameter( char *pszParmName);
1271 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1272 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1273 static void copy_service( service *pserviceDest,
1274 service *pserviceSource,
1275 BOOL *pcopymapDest );
1276 static BOOL service_ok(int iService);
1277 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1278 static BOOL do_section(char *pszSectionName);
1279 static void init_copymap(service *pservice);
1282 /***************************************************************************
1283 initialise a service to the defaults
1284 ***************************************************************************/
1285 static void init_service(service *pservice)
1287 bzero((char *)pservice,sizeof(service));
1288 copy_service(pservice,&sDefault,NULL);
1292 /***************************************************************************
1293 free the dynamically allocated parts of a service struct
1294 ***************************************************************************/
1295 static void free_service(service *pservice)
1301 if(pservice->szService)
1302 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1304 string_free(&pservice->szService);
1305 if (pservice->copymap)
1307 free(pservice->copymap);
1308 pservice->copymap = NULL;
1311 for (i=0;parm_table[i].label;i++)
1312 if ((parm_table[i].type == P_STRING ||
1313 parm_table[i].type == P_USTRING) &&
1314 parm_table[i].class == P_LOCAL)
1315 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1318 /***************************************************************************
1319 add a new service to the services array initialising it with the given
1321 ***************************************************************************/
1322 static int add_a_service(service *pservice, char *name)
1326 int num_to_alloc = iNumServices+1;
1328 tservice = *pservice;
1330 /* it might already exist */
1333 i = getservicebyname(name,NULL);
1338 /* find an invalid one */
1339 for (i=0;i<iNumServices;i++)
1340 if (!pSERVICE(i)->valid)
1343 /* if not, then create one */
1344 if (i == iNumServices)
1346 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1348 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1350 if (!ServicePtrs || !pSERVICE(iNumServices))
1356 free_service(pSERVICE(i));
1358 pSERVICE(i)->valid = True;
1360 init_service(pSERVICE(i));
1361 copy_service(pSERVICE(i),&tservice,NULL);
1363 string_set(&iSERVICE(i).szService,name);
1368 /***************************************************************************
1369 add a new home service, with the specified home directory, defaults coming
1371 ***************************************************************************/
1372 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1374 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1379 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1380 string_set(&iSERVICE(i).szPath,pszHomedir);
1381 if (!(*(iSERVICE(i).comment)))
1384 slprintf(comment,sizeof(comment)-1,
1385 "Home directory of %s",pszHomename);
1386 string_set(&iSERVICE(i).comment,comment);
1388 iSERVICE(i).bAvailable = sDefault.bAvailable;
1389 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1391 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1396 /***************************************************************************
1397 add a new service, based on an old one
1398 ***************************************************************************/
1399 int lp_add_service(char *pszService, int iDefaultService)
1401 return(add_a_service(pSERVICE(iDefaultService),pszService));
1405 /***************************************************************************
1407 ***************************************************************************/
1408 static BOOL lp_add_ipc(void)
1411 int i = add_a_service(&sDefault,"IPC$");
1416 slprintf(comment,sizeof(comment)-1,
1417 "IPC Service (%s)", Globals.szServerString );
1419 string_set(&iSERVICE(i).szPath,tmpdir());
1420 string_set(&iSERVICE(i).szUsername,"");
1421 string_set(&iSERVICE(i).comment,comment);
1422 iSERVICE(i).status = False;
1423 iSERVICE(i).iMaxConnections = 0;
1424 iSERVICE(i).bAvailable = True;
1425 iSERVICE(i).bRead_only = True;
1426 iSERVICE(i).bGuest_only = False;
1427 iSERVICE(i).bGuest_ok = True;
1428 iSERVICE(i).bPrint_ok = False;
1429 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1431 DEBUG(3,("adding IPC service\n"));
1437 /***************************************************************************
1438 add a new printer service, with defaults coming from service iFrom
1439 ***************************************************************************/
1440 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1442 char *comment = "From Printcap";
1443 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1448 /* note that we do NOT default the availability flag to True - */
1449 /* we take it from the default service passed. This allows all */
1450 /* dynamic printers to be disabled by disabling the [printers] */
1451 /* entry (if/when the 'available' keyword is implemented!). */
1453 /* the printer name is set to the service name. */
1454 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1455 string_set(&iSERVICE(i).comment,comment);
1456 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1457 /* Printers cannot be read_only. */
1458 iSERVICE(i).bRead_only = False;
1459 /* No share modes on printer services. */
1460 iSERVICE(i).bShareModes = False;
1461 /* No oplocks on printer services. */
1462 iSERVICE(i).bOpLocks = False;
1463 /* Printer services must be printable. */
1464 iSERVICE(i).bPrint_ok = True;
1466 DEBUG(3,("adding printer service %s\n",pszPrintername));
1472 /***************************************************************************
1473 Do a case-insensitive, whitespace-ignoring string compare.
1474 ***************************************************************************/
1475 static int strwicmp(char *psz1, char *psz2)
1477 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1478 /* appropriate value. */
1488 /* sync the strings on first non-whitespace */
1491 while (isspace(*psz1))
1493 while (isspace(*psz2))
1495 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1500 return (*psz1 - *psz2);
1503 /***************************************************************************
1504 Map a parameter's string representation to something we can use.
1505 Returns False if the parameter string is not recognised, else TRUE.
1506 ***************************************************************************/
1507 static int map_parameter(char *pszParmName)
1511 if (*pszParmName == '-')
1514 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1515 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1518 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1523 /***************************************************************************
1524 Set a boolean variable from the text value stored in the passed string.
1525 Returns True in success, False if the passed string does not correctly
1526 represent a boolean.
1527 ***************************************************************************/
1528 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1533 if (strwicmp(pszParmValue, "yes") == 0 ||
1534 strwicmp(pszParmValue, "true") == 0 ||
1535 strwicmp(pszParmValue, "1") == 0)
1538 if (strwicmp(pszParmValue, "no") == 0 ||
1539 strwicmp(pszParmValue, "False") == 0 ||
1540 strwicmp(pszParmValue, "0") == 0)
1544 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1551 /***************************************************************************
1552 Find a service by name. Otherwise works like get_service.
1553 ***************************************************************************/
1554 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1558 for (iService = iNumServices - 1; iService >= 0; iService--)
1559 if (VALID(iService) &&
1560 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1562 if (pserviceDest != NULL)
1563 copy_service(pserviceDest, pSERVICE(iService), NULL);
1572 /***************************************************************************
1573 Copy a service structure to another
1575 If pcopymapDest is NULL then copy all fields
1576 ***************************************************************************/
1577 static void copy_service(service *pserviceDest,
1578 service *pserviceSource,
1582 BOOL bcopyall = (pcopymapDest == NULL);
1584 for (i=0;parm_table[i].label;i++)
1585 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1586 (bcopyall || pcopymapDest[i]))
1588 void *def_ptr = parm_table[i].ptr;
1590 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1592 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1594 switch (parm_table[i].type)
1598 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1604 *(int *)dest_ptr = *(int *)src_ptr;
1608 *(char *)dest_ptr = *(char *)src_ptr;
1612 string_set(dest_ptr,*(char **)src_ptr);
1616 string_set(dest_ptr,*(char **)src_ptr);
1617 strupper(*(char **)dest_ptr);
1626 init_copymap(pserviceDest);
1627 if (pserviceSource->copymap)
1628 memcpy((void *)pserviceDest->copymap,
1629 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1633 /***************************************************************************
1634 Check a service for consistency. Return False if the service is in any way
1635 incomplete or faulty, else True.
1636 ***************************************************************************/
1637 static BOOL service_ok(int iService)
1642 if (iSERVICE(iService).szService[0] == '\0')
1644 DEBUG(0,( "The following message indicates an internal error:\n"));
1645 DEBUG(0,( "No service name in service entry.\n"));
1649 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1650 /* I can't see why you'd want a non-printable printer service... */
1651 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1652 if (!iSERVICE(iService).bPrint_ok)
1654 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1655 iSERVICE(iService).szService));
1656 iSERVICE(iService).bPrint_ok = True;
1659 if (iSERVICE(iService).szPath[0] == '\0' &&
1660 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1662 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1663 string_set(&iSERVICE(iService).szPath,tmpdir());
1666 /* If a service is flagged unavailable, log the fact at level 0. */
1667 if (!iSERVICE(iService).bAvailable)
1668 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1669 iSERVICE(iService).szService));
1674 static struct file_lists {
1675 struct file_lists *next;
1678 } *file_lists = NULL;
1680 /*******************************************************************
1681 keep a linked list of all config files so we know when one has changed
1682 it's date and needs to be reloaded
1683 ********************************************************************/
1684 static void add_to_file_list(char *fname)
1686 struct file_lists *f=file_lists;
1689 if (f->name && !strcmp(f->name,fname)) break;
1694 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1696 f->next = file_lists;
1697 f->name = strdup(fname);
1708 standard_sub_basic(n2);
1709 f->modtime = file_modtime(n2);
1714 /*******************************************************************
1715 check if a config file has changed date
1716 ********************************************************************/
1717 BOOL lp_file_list_changed(void)
1719 struct file_lists *f = file_lists;
1720 DEBUG(6,("lp_file_list_changed()\n"));
1727 pstrcpy(n2,f->name);
1728 standard_sub_basic(n2);
1730 DEBUGADD( 6, ( "file %s -> %s last mod_time: %s\n",
1731 f->name, n2, ctime(&f->modtime) ) );
1733 mod_time = file_modtime(n2);
1735 if (f->modtime != mod_time) {
1736 DEBUGADD(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1737 f->modtime = mod_time;
1745 /***************************************************************************
1746 handle the interpretation of the coding system parameter
1747 *************************************************************************/
1748 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1750 string_set(ptr,pszParmValue);
1751 interpret_coding_system(pszParmValue);
1755 /***************************************************************************
1756 handle the interpretation of the character set system parameter
1757 ***************************************************************************/
1758 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1760 string_set(ptr,pszParmValue);
1761 interpret_character_set(pszParmValue);
1766 /***************************************************************************
1767 handle the valid chars lines
1768 ***************************************************************************/
1769 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1771 string_set(ptr,pszParmValue);
1773 /* A dependency here is that the parameter client code page must be
1774 set before this is called - as calling codepage_initialise()
1775 would overwrite the valid char lines.
1777 codepage_initialise(lp_client_code_page());
1779 add_char_string(pszParmValue);
1784 /***************************************************************************
1785 handle the include operation
1786 ***************************************************************************/
1787 static BOOL handle_include(char *pszParmValue,char **ptr)
1790 pstrcpy(fname,pszParmValue);
1792 add_to_file_list(fname);
1794 standard_sub_basic(fname);
1796 string_set(ptr,fname);
1798 if (file_exist(fname,NULL))
1799 return(pm_process(fname, do_section, do_parameter));
1801 DEBUG(2,("Can't find include file %s\n",fname));
1807 /***************************************************************************
1808 handle the interpretation of the copy parameter
1809 ***************************************************************************/
1810 static BOOL handle_copy(char *pszParmValue,char **ptr)
1814 service serviceTemp;
1816 string_set(ptr,pszParmValue);
1818 init_service(&serviceTemp);
1822 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1824 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1826 if (iTemp == iServiceIndex)
1828 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1833 copy_service(pSERVICE(iServiceIndex),
1835 iSERVICE(iServiceIndex).copymap);
1841 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1846 free_service(&serviceTemp);
1851 /***************************************************************************
1852 initialise a copymap
1853 ***************************************************************************/
1854 static void init_copymap(service *pservice)
1857 if (pservice->copymap) free(pservice->copymap);
1858 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1859 if (!pservice->copymap)
1860 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1862 for (i=0;i<NUMPARAMETERS;i++)
1863 pservice->copymap[i] = True;
1867 /***************************************************************************
1868 return the local pointer to a parameter given the service number and the
1869 pointer into the default structure
1870 ***************************************************************************/
1871 void *lp_local_ptr(int snum, void *ptr)
1873 return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
1876 /***************************************************************************
1877 Process a parameter for a particular service number. If snum < 0
1878 then assume we are in the globals
1879 ***************************************************************************/
1880 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1883 void *parm_ptr=NULL; /* where we are going to store the result */
1886 parmnum = map_parameter(pszParmName);
1890 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1894 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1895 DEBUG(1,("WARNING: The \"%s\"option is deprecated\n",
1899 def_ptr = parm_table[parmnum].ptr;
1901 /* we might point at a service, the default service or a global */
1905 if (parm_table[parmnum].class == P_GLOBAL) {
1906 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1909 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1913 if (!iSERVICE(snum).copymap)
1914 init_copymap(pSERVICE(snum));
1916 /* this handles the aliases - set the copymap for other entries with
1917 the same data pointer */
1918 for (i=0;parm_table[i].label;i++)
1919 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1920 iSERVICE(snum).copymap[i] = False;
1923 /* if it is a special case then go ahead */
1924 if (parm_table[parmnum].special) {
1925 parm_table[parmnum].special(pszParmValue,(char **)parm_ptr);
1929 /* now switch on the type of variable it is */
1930 switch (parm_table[parmnum].type)
1933 set_boolean(parm_ptr,pszParmValue);
1937 set_boolean(parm_ptr,pszParmValue);
1938 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1942 *(int *)parm_ptr = atoi(pszParmValue);
1946 *(char *)parm_ptr = *pszParmValue;
1950 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1954 string_set(parm_ptr,pszParmValue);
1958 string_set(parm_ptr,pszParmValue);
1959 strupper(*(char **)parm_ptr);
1963 pstrcpy((char *)parm_ptr,pszParmValue);
1967 pstrcpy((char *)parm_ptr,pszParmValue);
1968 strupper((char *)parm_ptr);
1972 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1973 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1974 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
1986 /***************************************************************************
1987 Process a parameter.
1988 ***************************************************************************/
1989 static BOOL do_parameter( char *pszParmName, char *pszParmValue )
1991 if( !bInGlobalSection && bGlobalOnly )
1994 DEBUGADD( 3, ( "doing parameter %s = %s\n", pszParmName, pszParmValue ) );
1996 return( lp_do_parameter( bInGlobalSection ? -2 : iServiceIndex,
2002 /***************************************************************************
2003 print a parameter of the specified type
2004 ***************************************************************************/
2005 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
2010 for (i=0;p->enum_list[i].name;i++) {
2011 if (*(int *)ptr == p->enum_list[i].value) {
2012 fprintf(f,"%s",p->enum_list[i].name);
2019 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
2023 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
2027 fprintf(f,"%d",*(int *)ptr);
2031 fprintf(f,"%c",*(char *)ptr);
2035 fprintf(f,"0%o",*(int *)ptr);
2041 fprintf(f,"%s",(char *)ptr);
2047 fprintf(f,"%s",*(char **)ptr);
2055 /***************************************************************************
2056 check if two parameters are equal
2057 ***************************************************************************/
2058 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
2064 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
2069 return(*((int *)ptr1) == *((int *)ptr2));
2072 return(*((char *)ptr1) == *((char *)ptr2));
2077 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
2078 if (p1 && !*p1) p1 = NULL;
2079 if (p2 && !*p2) p2 = NULL;
2080 return(p1==p2 || strequal(p1,p2));
2085 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2086 if (p1 && !*p1) p1 = NULL;
2087 if (p2 && !*p2) p2 = NULL;
2088 return(p1==p2 || strequal(p1,p2));
2096 /***************************************************************************
2097 Process a new section (service). At this stage all sections are services.
2098 Later we'll have special sections that permit server parameters to be set.
2099 Returns True on success, False on failure.
2100 ***************************************************************************/
2101 static BOOL do_section(char *pszSectionName)
2104 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2105 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2108 /* if we were in a global section then do the local inits */
2109 if (bInGlobalSection && !isglobal)
2112 /* if we've just struck a global section, note the fact. */
2113 bInGlobalSection = isglobal;
2115 /* check for multiple global sections */
2116 if (bInGlobalSection)
2118 DEBUG( 3, ( "Processing section \"[%s]\"\n", pszSectionName ) );
2122 if (!bInGlobalSection && bGlobalOnly) return(True);
2124 /* if we have a current service, tidy it up before moving on */
2127 if (iServiceIndex >= 0)
2128 bRetval = service_ok(iServiceIndex);
2130 /* if all is still well, move to the next record in the services array */
2133 /* We put this here to avoid an odd message order if messages are */
2134 /* issued by the post-processing of a previous section. */
2135 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
2137 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
2139 DEBUG(0,("Failed to add a new service\n"));
2148 /***************************************************************************
2149 determine if a partcular base parameter is currently set to the default value.
2150 ***************************************************************************/
2151 static BOOL is_default(int i)
2153 if (!defaults_saved) return False;
2154 switch (parm_table[i].type) {
2157 return strequal(parm_table[i].def.svalue,*(char **)parm_table[i].ptr);
2160 return strequal(parm_table[i].def.svalue,(char *)parm_table[i].ptr);
2163 return parm_table[i].def.bvalue == *(BOOL *)parm_table[i].ptr;
2165 return parm_table[i].def.cvalue == *(char *)parm_table[i].ptr;
2169 return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
2177 /***************************************************************************
2178 Display the contents of the global structure.
2179 ***************************************************************************/
2180 static void dump_globals(FILE *f)
2183 fprintf(f, "# Global parameters\n");
2185 for (i=0;parm_table[i].label;i++)
2186 if (parm_table[i].class == P_GLOBAL &&
2187 parm_table[i].ptr &&
2188 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2189 if (defaults_saved && is_default(i)) continue;
2190 fprintf(f,"\t%s = ",parm_table[i].label);
2191 print_parameter(&parm_table[i],parm_table[i].ptr, f);
2196 /***************************************************************************
2197 return True if a local parameter is currently set to the global default
2198 ***************************************************************************/
2199 BOOL lp_is_default(int snum, struct parm_struct *parm)
2201 int pdiff = PTR_DIFF(parm->ptr,&sDefault);
2203 return equal_parameter(parm->type,
2204 ((char *)pSERVICE(snum)) + pdiff,
2205 ((char *)&sDefault) + pdiff);
2209 /***************************************************************************
2210 Display the contents of a single services record.
2211 ***************************************************************************/
2212 static void dump_a_service(service *pService, FILE *f)
2215 if (pService != &sDefault)
2216 fprintf(f,"\n[%s]\n",pService->szService);
2218 for (i=0;parm_table[i].label;i++)
2219 if (parm_table[i].class == P_LOCAL &&
2220 parm_table[i].ptr &&
2221 (*parm_table[i].label != '-') &&
2222 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2223 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
2225 if (pService == &sDefault) {
2226 if (defaults_saved && is_default(i)) continue;
2228 if (equal_parameter(parm_table[i].type,
2229 ((char *)pService) + pdiff,
2230 ((char *)&sDefault) + pdiff))
2234 fprintf(f,"\t%s = ",parm_table[i].label);
2235 print_parameter(&parm_table[i],
2236 ((char *)pService) + pdiff, f);
2242 /***************************************************************************
2243 return info about the next service in a service. snum==-1 gives the globals
2245 return NULL when out of parameters
2246 ***************************************************************************/
2247 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2250 /* do the globals */
2251 for (;parm_table[*i].label;(*i)++) {
2252 if (parm_table[*i].class == P_SEPARATOR)
2253 return &parm_table[(*i)++];
2255 if (!parm_table[*i].ptr || (*parm_table[*i].label == '-'))
2258 if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr))
2261 return &parm_table[(*i)++];
2264 service *pService = pSERVICE(snum);
2266 for (;parm_table[*i].label;(*i)++) {
2267 if (parm_table[*i].class == P_SEPARATOR)
2268 return &parm_table[(*i)++];
2270 if (parm_table[*i].class == P_LOCAL &&
2271 parm_table[*i].ptr &&
2272 (*parm_table[*i].label != '-') &&
2274 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2275 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2277 if (allparameters ||
2278 !equal_parameter(parm_table[*i].type,
2279 ((char *)pService) + pdiff,
2280 ((char *)&sDefault) + pdiff)) {
2281 return &parm_table[(*i)++];
2292 /***************************************************************************
2293 Display the contents of a single copy structure.
2294 ***************************************************************************/
2295 static void dump_copy_map(BOOL *pcopymap)
2298 if (!pcopymap) return;
2300 printf("\n\tNon-Copied parameters:\n");
2302 for (i=0;parm_table[i].label;i++)
2303 if (parm_table[i].class == P_LOCAL &&
2304 parm_table[i].ptr && !pcopymap[i] &&
2305 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2307 printf("\t\t%s\n",parm_table[i].label);
2312 /***************************************************************************
2313 Return TRUE if the passed service number is within range.
2314 ***************************************************************************/
2315 BOOL lp_snum_ok(int iService)
2317 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2321 /***************************************************************************
2322 auto-load some home services
2323 ***************************************************************************/
2324 static void lp_add_auto_services(char *str)
2335 homes = lp_servicenumber(HOMES_NAME);
2337 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
2338 char *home = get_home_dir(p);
2340 if (lp_servicenumber(p) >= 0) continue;
2342 if (home && homes >= 0) {
2343 lp_add_home(p,homes,home);
2349 /***************************************************************************
2350 auto-load one printer
2351 ***************************************************************************/
2352 void lp_add_one_printer(char *name,char *comment)
2354 int printers = lp_servicenumber(PRINTERS_NAME);
2357 if (lp_servicenumber(name) < 0) {
2358 lp_add_printer(name,printers);
2359 if ((i=lp_servicenumber(name)) >= 0)
2360 string_set(&iSERVICE(i).comment,comment);
2364 /***************************************************************************
2365 have we loaded a services file yet?
2366 ***************************************************************************/
2367 BOOL lp_loaded(void)
2372 /***************************************************************************
2373 unload unused services
2374 ***************************************************************************/
2375 void lp_killunused(BOOL (*snumused)(int ))
2378 for (i=0;i<iNumServices;i++)
2379 if (VALID(i) && (!snumused || !snumused(i)))
2381 iSERVICE(i).valid = False;
2382 free_service(pSERVICE(i));
2387 /***************************************************************************
2388 save the curent values of all global and sDefault parameters into the
2389 defaults union. This allows swat and testparm to show only the
2390 changed (ie. non-default) parameters.
2391 ***************************************************************************/
2392 static void lp_save_defaults(void)
2395 for (i = 0; parm_table[i].label; i++) {
2396 if (i>0 && parm_table[i].ptr == parm_table[i-1].ptr) continue;
2397 switch (parm_table[i].type) {
2400 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2404 parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
2408 parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr;
2411 parm_table[i].def.cvalue = *(char *)parm_table[i].ptr;
2416 parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
2422 defaults_saved = True;
2426 /***************************************************************************
2427 Load the services array from the services file. Return True on success,
2429 ***************************************************************************/
2430 BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
2435 add_to_file_list(pszFname);
2439 bInGlobalSection = True;
2440 bGlobalOnly = global_only;
2444 if (save_defaults) {
2449 pstrcpy(n2,pszFname);
2450 standard_sub_basic(n2);
2452 /* We get sections first, so have to start 'behind' to make up */
2454 bRetval = pm_process(n2, do_section, do_parameter);
2456 /* finish up the last section */
2457 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2459 if (iServiceIndex >= 0)
2460 bRetval = service_ok(iServiceIndex);
2462 lp_add_auto_services(lp_auto_services());
2467 set_default_server_announce_type();
2475 /***************************************************************************
2476 return the max number of services
2477 ***************************************************************************/
2478 int lp_numservices(void)
2480 return(iNumServices);
2483 /***************************************************************************
2484 Display the contents of the services array in human-readable form.
2485 ***************************************************************************/
2486 void lp_dump(FILE *f, BOOL show_defaults)
2490 if (show_defaults) {
2491 defaults_saved = False;
2496 dump_a_service(&sDefault, f);
2498 for (iService = 0; iService < iNumServices; iService++)
2500 if (VALID(iService))
2502 if (iSERVICE(iService).szService[0] == '\0')
2504 dump_a_service(pSERVICE(iService), f);
2510 /***************************************************************************
2511 Return the number of the service with the given name, or -1 if it doesn't
2512 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2513 getservicebyname()! This works ONLY if all services have been loaded, and
2514 does not copy the found service.
2515 ***************************************************************************/
2516 int lp_servicenumber(char *pszServiceName)
2520 for (iService = iNumServices - 1; iService >= 0; iService--)
2521 if (VALID(iService) &&
2522 strequal(lp_servicename(iService), pszServiceName))
2526 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2531 /*******************************************************************
2532 a useful volume label function
2533 ******************************************************************/
2534 char *volume_label(int snum)
2536 char *ret = lp_volume(snum);
2537 if (!*ret) return(lp_servicename(snum));
2542 /*******************************************************************
2543 Set the server type we will announce as via nmbd.
2544 ********************************************************************/
2545 static void set_default_server_announce_type()
2547 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2548 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2549 if(lp_announce_as() == ANNOUNCE_AS_NT)
2550 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2551 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2552 default_server_announce |= SV_TYPE_WIN95_PLUS;
2553 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2554 default_server_announce |= SV_TYPE_WFW;
2555 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2559 /*******************************************************************
2561 ********************************************************************/
2562 void lp_remove_service(int snum)
2564 pSERVICE(snum)->valid = False;
2567 /*******************************************************************
2569 ********************************************************************/
2570 void lp_copy_service(int snum, char *new_name)
2572 char *oldname = lp_servicename(snum);
2573 do_section(new_name);
2575 snum = lp_servicenumber(new_name);
2577 lp_do_parameter(snum, "copy", oldname);
2582 /*******************************************************************
2583 Get the default server type we will announce as via nmbd.
2584 ********************************************************************/
2585 int lp_default_server_announce(void)
2587 return default_server_announce;
2590 /*******************************************************************
2591 Split the announce version into major and minor numbers.
2592 ********************************************************************/
2593 int lp_major_announce_version(void)
2595 static BOOL got_major = False;
2596 static int major_version = DEFAULT_MAJOR_VERSION;
2601 return major_version;
2604 if((vers = lp_announce_version()) == NULL)
2605 return major_version;
2607 if((p = strchr(vers, '.')) == 0)
2608 return major_version;
2611 major_version = atoi(vers);
2612 return major_version;
2615 int lp_minor_announce_version(void)
2617 static BOOL got_minor = False;
2618 static int minor_version = DEFAULT_MINOR_VERSION;
2623 return minor_version;
2626 if((vers = lp_announce_version()) == NULL)
2627 return minor_version;
2629 if((p = strchr(vers, '.')) == 0)
2630 return minor_version;
2633 minor_version = atoi(p);
2634 return minor_version;
2637 /***********************************************************
2638 Set the global name resolution order (used in smbclient).
2639 ************************************************************/
2641 void lp_set_name_resolve_order(char *new_order)
2643 Globals.szNameResolveOrder = new_order;