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.15 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 280 /* compute the pathname of the controlling tty */ 281 if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x') 282 { 283 errno = 0; 284 return (NULL); 285 } 286 pathn[8] = i; 287 288 /* see if we have write permission */ 289 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 290 { 291 errno = 0; 292 return (NULL); 293 } 294 295 /* see if the user is logged in */ 296 if (getlogin() == NULL) 297 return (NULL); 298 299 /* looks good */ 300 return (pathn); 301 } 302 /* 303 ** FDOPEN -- Open a stdio file given an open file descriptor. 304 ** 305 ** This is included here because it is standard in v7, but we 306 ** need it in v6. 307 ** 308 ** Algorithm: 309 ** Open /dev/null to create a descriptor. 310 ** Close that descriptor. 311 ** Copy the existing fd into the descriptor. 312 ** 313 ** Parameters: 314 ** fd -- the open file descriptor. 315 ** type -- "r", "w", or whatever. 316 ** 317 ** Returns: 318 ** The file descriptor it creates. 319 ** 320 ** Side Effects: 321 ** none 322 ** 323 ** Called By: 324 ** deliver 325 ** 326 ** Notes: 327 ** The mode of fd must match "type". 328 */ 329 330 FILE * 331 fdopen(fd, type) 332 int fd; 333 char *type; 334 { 335 register FILE *f; 336 337 f = fopen("/dev/null", type); 338 (void) close(fileno(f)); 339 fileno(f) = fd; 340 return (f); 341 } 342 /* 343 ** INDEX -- Return pointer to character in string 344 ** 345 ** For V7 compatibility. 346 ** 347 ** Parameters: 348 ** s -- a string to scan. 349 ** c -- a character to look for. 350 ** 351 ** Returns: 352 ** If c is in s, returns the address of the first 353 ** instance of c in s. 354 ** NULL if c is not in s. 355 ** 356 ** Side Effects: 357 ** none. 358 */ 359 360 index(s, c) 361 register char *s; 362 register char c; 363 { 364 while (*s != '\0') 365 { 366 if (*s++ == c) 367 return (--s); 368 } 369 return (NULL); 370 } 371 # endif V6 372 373 # ifndef V6 374 /* 375 ** TTYPATH -- Get the path of the user's tty -- Version 7 version. 376 ** 377 ** Returns the pathname of the user's tty. Returns NULL if 378 ** the user is not logged in or if s/he has write permission 379 ** denied. 380 ** 381 ** Parameters: 382 ** none 383 ** 384 ** Returns: 385 ** pathname of the user's tty. 386 ** NULL if not logged in or write permission denied. 387 ** 388 ** Side Effects: 389 ** none. 390 ** 391 ** WARNING: 392 ** Return value is in a local buffer. 393 ** 394 ** Called By: 395 ** savemail 396 */ 397 398 # include <sys/types.h> 399 # include <sys/stat.h> 400 401 char * 402 ttypath() 403 { 404 struct stat stbuf; 405 register char *pathn; 406 extern char *ttyname(); 407 extern char *getlogin(); 408 409 /* compute the pathname of the controlling tty */ 410 if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 411 { 412 errno = 0; 413 return (NULL); 414 } 415 416 /* see if we have write permission */ 417 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 418 { 419 errno = 0; 420 return (NULL); 421 } 422 423 /* see if the user is logged in */ 424 if (getlogin() == NULL) 425 return (NULL); 426 427 /* looks good */ 428 return (pathn); 429 } 430 # endif V6 431 /* 432 ** CHECKCOMPAT -- check for From and To person compatible. 433 ** 434 ** This routine can be supplied on a per-installation basis 435 ** to determine whether a person is allowed to send a message. 436 ** This allows restriction of certain types of internet 437 ** forwarding or registration of users. 438 ** 439 ** If the hosts are found to be incompatible, an error 440 ** message should be given using "usrerr" and FALSE should 441 ** be returned. 442 ** 443 ** Parameters: 444 ** to -- the person being sent to. 445 ** 446 ** Returns: 447 ** TRUE -- ok to send. 448 ** FALSE -- not ok. 449 ** 450 ** Side Effects: 451 ** none (unless you include the usrerr stuff) 452 */ 453 454 bool 455 checkcompat(to) 456 register ADDRESS *to; 457 { 458 # ifdef lint 459 ADDRESS *x = to; 460 461 to = x; 462 # endif lint 463 464 return (TRUE); 465 } 466