1 # include <stdio.h> 2 # include <pwd.h> 3 # include "sendmail.h" 4 5 /* 6 ** CONF.C -- Sendmail Configuration Tables. 7 ** 8 ** Defines the configuration of this installation. 9 ** 10 ** Compilation Flags: 11 ** NETV6MAIL -- set if you want to use "v6mail" that 12 ** comes with the Berkeley network. Normally 13 ** /bin/mail will work fine, but around Berkeley 14 ** we use v6mail because it is a "fixed target". 15 ** Also, only v6mail has the "/dev/mail" stuff 16 ** in it (for biff(1)). 17 ** V6 -- running on a version 6 system. This determines 18 ** whether to define certain routines between 19 ** the two systems. If you are running a funny 20 ** system, e.g., V6 with long tty names, this 21 ** should be checked carefully. 22 ** 23 ** Configuration Variables: 24 ** Mailer -- a table of mailers known to the system. 25 ** This should be fairly static. The fields are: 26 ** - the pathname of the mailer. 27 ** - a list of flags describing the properties 28 ** of this mailer: 29 ** M_FOPT -- if set, the mailer has a picky "-f" 30 ** option. In this mode, the mailer will 31 ** only accept the "-f" option if the 32 ** sender is actually "root", "network", 33 ** and possibly (but not necessarily) if 34 ** the -f argument matches the real sender. 35 ** The effect is that if the "-f" option 36 ** is given to sendmail then it will be 37 ** passed through (as arguments 1 & 2) to 38 ** the mailer. 39 ** M_ROPT -- identical to M_FOPT, except uses 40 ** -r instead. 41 ** M_QUIET -- if set, don't print a message if 42 ** the mailer returns bad status. 43 ** M_RESTR -- if set, this mailer is restricted 44 ** to use by "daemon"; otherwise, we do a 45 ** setuid(getuid()) before calling the 46 ** mailer. 47 ** M_NHDR -- if set, the mailer doesn't want us 48 ** to insert a UNIX "From" line before 49 ** outputing. 50 ** M_NOHOST -- if set, this mailer doesn't care 51 ** about the host part (e.g., the local 52 ** mailer). 53 ** M_STRIPQ -- if set, strip quote (`"') 54 ** characters out of parameters as you 55 ** transliterate them into the argument 56 ** vector. For example, the local mailer 57 ** is called directly, so these should be 58 ** stripped, but the program-mailer (i.e., 59 ** csh) should leave them in. 60 ** M_NEEDDATE -- this mailer requires a Date: 61 ** field in the message. 62 ** M_NEEDFROM -- this mailer requires a From: 63 ** field in the message. 64 ** M_MSGID -- this mailer requires a Message-Id 65 ** field in the message. 66 ** M_ARPAFMT == M_NEEDDATE|M_NEEDFROM|M_MSGID. 67 ** - an exit status to use as the code for the 68 ** error message print if the mailer returns 69 ** something we don't understand. 70 ** - A list of names that are to be considered 71 ** "local" (and hence are stripped off) for 72 ** this mailer. 73 ** - An argument vector to be passed to the 74 ** mailer; this is macro substituted. 75 ** >>>>>>>>>> Entry zero must be for the local 76 ** >> NOTE >> mailer and entry one must be for 77 ** >>>>>>>>>> the shell. 78 ** HdrInfo -- a table describing well-known header fields. 79 ** Each entry has the field name and some flags, 80 ** which can be: 81 ** - H_EOH -- this field is equivalent to a blank 82 ** line; i.e., it signifies end of header. 83 ** - H_DELETE -- delete this field. 84 ** There is also a field pointing to a pointer 85 ** that should be set to point to this header. 86 */ 87 88 89 90 91 static char SccsId[] = "@(#)conf.c 3.14 08/09/81"; 92 93 94 # include <whoami.h> /* definitions of machine id's at berkeley */ 95 96 # ifdef BERKELEY 97 # define NETV6MAIL /* use /usr/net/bin/v6mail for local delivery */ 98 # endif BERKELEY 99 100 101 102 /* local mail -- must be #0 */ 103 static char *LocalArgv[] = 104 { 105 "...local%mail", 106 "-d", 107 "$u", 108 NULL 109 }; 110 111 static struct mailer LocalMailer = 112 { 113 # ifdef NETV6MAIL 114 "local", "/usr/net/bin/v6mail", 115 # else 116 "local", "/bin/mail", 117 # endif 118 M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT|M_MUSER|M_NHDR, 119 EX_NOUSER, "$f", LocalArgv, NULL, 120 }; 121 122 /* pipes through programs -- must be #1 -- also used for files */ 123 static char *ProgArgv[] = 124 { 125 "...prog%mail", 126 "-fc", 127 "$u", 128 NULL 129 }; 130 131 static struct mailer ProgMailer = 132 { 133 "prog", "/bin/csh", 134 M_NOHOST|M_ARPAFMT, 135 EX_UNAVAILABLE, "$f", ProgArgv, NULL, 136 }; 137 138 /* user-private mailers -- must be #2 */ 139 static char *PrivArgv[] = 140 { 141 "...priv%mail", 142 "$u", 143 NULL 144 }; 145 146 static struct mailer PrivMailer = 147 { 148 "priv", NULL, 149 M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT, 150 EX_UNAVAILABLE, "$f", PrivArgv, NULL, 151 }; 152 153 /* local berkeley mail */ 154 static char *BerkArgv[] = 155 { 156 "...berk%mail", 157 "-m", 158 "$h", 159 "-h", 160 "$c", 161 "-t", 162 "$u", 163 NULL 164 }; 165 166 static struct mailer BerkMailer = 167 { 168 "berk", "/usr/net/bin/sendberkmail", 169 M_FOPT|M_NEEDDATE|M_FULLNAME|M_STRIPQ, 170 EX_UNAVAILABLE, "$B:$f", BerkArgv, NULL, 171 }; 172 173 /* arpanet mail */ 174 static char *ArpaArgv[] = 175 { 176 "...arpa%mail", 177 "$f", 178 "$h", 179 "$u", 180 NULL 181 }; 182 183 static struct mailer ArpaMailer = 184 { 185 "arpa", "/usr/lib/mailers/arpa", 186 M_STRIPQ|M_ARPAFMT|M_USR_UPPER, 187 0, "$f@$A", ArpaArgv, NULL, 188 }; 189 190 /* uucp mail (cheat & use Bell's v7 mail) */ 191 static char *UucpArgv[] = 192 { 193 "...uucp%mail", 194 "-", 195 "$h!rmail", 196 "($u)", 197 NULL 198 }; 199 200 static struct mailer UucpMailer = 201 { 202 "uucp", "/usr/bin/uux", 203 M_ROPT|M_STRIPQ|M_NEEDDATE|M_FULLNAME|M_MUSER, 204 EX_NOUSER, "$U!$f", UucpArgv, NULL, 205 }; 206 207 struct mailer *Mailer[] = 208 { 209 &LocalMailer, /* 0 -- must be 0 */ 210 &ProgMailer, /* 1 -- must be 1 */ 211 &PrivMailer, /* 2 -- must be 2 */ 212 &BerkMailer, /* 3 */ 213 &ArpaMailer, /* 4 */ 214 &UucpMailer, /* 5 */ 215 NULL 216 }; 217 218 /* offsets for arbitrary mailers */ 219 # define M_BERK 2 /* berknet */ 220 # define M_ARPA 3 /* arpanet */ 221 # define M_UUCP 4 /* UUCPnet */ 222 223 224 225 226 227 /* 228 ** Header info table 229 ** Final (null) entry contains the flags used for any other field. 230 */ 231 232 struct hdrinfo HdrInfo[] = 233 { 234 "date", H_CHECK, M_NEEDDATE, 235 "from", H_CHECK, M_NEEDFROM, 236 "full-name", H_ACHECK, M_FULLNAME, 237 "to", 0, NULL, 238 "cc", 0, NULL, 239 "subject", 0, NULL, 240 "message-id", H_CHECK, M_MSGID, 241 "message", H_EOH, NULL, 242 NULL, 0, NULL, 243 }; 244 245 # ifdef V6 246 /* 247 ** TTYPATH -- Get the path of the user's tty -- Version 6 version. 248 ** 249 ** Returns the pathname of the user's tty. Returns NULL if 250 ** the user is not logged in or if s/he has write permission 251 ** denied. 252 ** 253 ** Parameters: 254 ** none 255 ** 256 ** Returns: 257 ** pathname of the user's tty. 258 ** NULL if not logged in or write permission denied. 259 ** 260 ** Side Effects: 261 ** none. 262 ** 263 ** WARNING: 264 ** Return value is in a local buffer. 265 ** 266 ** Called By: 267 ** savemail 268 */ 269 270 # include <sys/types.h> 271 # include <sys/stat.h> 272 273 char * 274 ttypath() 275 { 276 struct stat stbuf; 277 register int i; 278 static char pathn[] = "/dev/ttyx"; 279 extern int errno; 280 281 /* compute the pathname of the controlling tty */ 282 if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x') 283 { 284 errno = 0; 285 return (NULL); 286 } 287 pathn[8] = i; 288 289 /* see if we have write permission */ 290 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 291 { 292 errno = 0; 293 return (NULL); 294 } 295 296 /* see if the user is logged in */ 297 if (getlogin() == NULL) 298 return (NULL); 299 300 /* looks good */ 301 return (pathn); 302 } 303 /* 304 ** FDOPEN -- Open a stdio file given an open file descriptor. 305 ** 306 ** This is included here because it is standard in v7, but we 307 ** need it in v6. 308 ** 309 ** Algorithm: 310 ** Open /dev/null to create a descriptor. 311 ** Close that descriptor. 312 ** Copy the existing fd into the descriptor. 313 ** 314 ** Parameters: 315 ** fd -- the open file descriptor. 316 ** type -- "r", "w", or whatever. 317 ** 318 ** Returns: 319 ** The file descriptor it creates. 320 ** 321 ** Side Effects: 322 ** none 323 ** 324 ** Called By: 325 ** deliver 326 ** 327 ** Notes: 328 ** The mode of fd must match "type". 329 */ 330 331 FILE * 332 fdopen(fd, type) 333 int fd; 334 char *type; 335 { 336 register FILE *f; 337 338 f = fopen("/dev/null", type); 339 close(fileno(f)); 340 fileno(f) = fd; 341 return (f); 342 } 343 /* 344 ** INDEX -- Return pointer to character in string 345 ** 346 ** For V7 compatibility. 347 ** 348 ** Parameters: 349 ** s -- a string to scan. 350 ** c -- a character to look for. 351 ** 352 ** Returns: 353 ** If c is in s, returns the address of the first 354 ** instance of c in s. 355 ** NULL if c is not in s. 356 ** 357 ** Side Effects: 358 ** none. 359 */ 360 361 index(s, c) 362 register char *s; 363 register char c; 364 { 365 while (*s != '\0') 366 { 367 if (*s++ == c) 368 return (--s); 369 } 370 return (NULL); 371 } 372 # endif V6 373 374 # ifndef V6 375 /* 376 ** TTYPATH -- Get the path of the user's tty -- Version 7 version. 377 ** 378 ** Returns the pathname of the user's tty. Returns NULL if 379 ** the user is not logged in or if s/he has write permission 380 ** denied. 381 ** 382 ** Parameters: 383 ** none 384 ** 385 ** Returns: 386 ** pathname of the user's tty. 387 ** NULL if not logged in or write permission denied. 388 ** 389 ** Side Effects: 390 ** none. 391 ** 392 ** WARNING: 393 ** Return value is in a local buffer. 394 ** 395 ** Called By: 396 ** savemail 397 */ 398 399 # include <sys/types.h> 400 # include <sys/stat.h> 401 402 char * 403 ttypath() 404 { 405 struct stat stbuf; 406 register char *pathn; 407 extern int errno; 408 extern char *ttyname(); 409 410 /* compute the pathname of the controlling tty */ 411 if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 412 { 413 errno = 0; 414 return (NULL); 415 } 416 417 /* see if we have write permission */ 418 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 419 { 420 errno = 0; 421 return (NULL); 422 } 423 424 /* see if the user is logged in */ 425 if (getlogin() == NULL) 426 return (NULL); 427 428 /* looks good */ 429 return (pathn); 430 } 431 # endif V6 432 /* 433 ** CHECKCOMPAT -- check for From and To person compatible. 434 ** 435 ** This routine can be supplied on a per-installation basis 436 ** to determine whether a person is allowed to send a message. 437 ** This allows restriction of certain types of internet 438 ** forwarding or registration of users. 439 ** 440 ** If the hosts are found to be incompatible, an error 441 ** message should be given using "usrerr" and FALSE should 442 ** be returned. 443 ** 444 ** Parameters: 445 ** to -- the person being sent to. 446 ** 447 ** Returns: 448 ** TRUE -- ok to send. 449 ** FALSE -- not ok. 450 ** 451 ** Side Effects: 452 ** none (unless you include the usrerr stuff) 453 */ 454 455 bool 456 checkcompat(to) 457 register ADDRESS *to; 458 { 459 return (TRUE); 460 } 461