1 # include <pwd.h> 2 # include "sendmail.h" 3 4 /* 5 ** CONF.C -- Sendmail Configuration Tables. 6 ** 7 ** Defines the configuration of this installation. 8 ** 9 ** Compilation Flags: 10 ** V6 -- running on a version 6 system. This determines 11 ** whether to define certain routines between 12 ** the two systems. If you are running a funny 13 ** system, e.g., V6 with long tty names, this 14 ** should be checked carefully. 15 ** 16 ** Configuration Variables: 17 ** HdrInfo -- a table describing well-known header fields. 18 ** Each entry has the field name and some flags, 19 ** which are described in sendmail.h. 20 ** 21 ** Notes: 22 ** I have tried to put almost all the reasonable 23 ** configuration information into the configuration 24 ** file read at runtime. My intent is that anything 25 ** here is a function of the version of UNIX you 26 ** are running, or is really static -- for example 27 ** the headers are a superset of widely used 28 ** protocols. If you find yourself playing with 29 ** this file too much, you may be making a mistake! 30 */ 31 32 33 34 35 SCCSID(@(#)conf.c 3.59 09/26/82); 36 37 38 39 /* 40 ** Header info table 41 ** Final (null) entry contains the flags used for any other field. 42 ** 43 ** Not all of these are actually handled specially by sendmail 44 ** at this time. They are included as placeholders, to let 45 ** you know that "someday" I intend to have sendmail do 46 ** something with them. 47 */ 48 49 struct hdrinfo HdrInfo[] = 50 { 51 /* date information */ 52 "posted-date", 0, 0, 53 "date", H_CHECK, M_NEEDDATE, 54 "resent-date", 0, 0, 55 "received-date", H_CHECK, M_LOCAL, 56 /* originator fields, most to least significant */ 57 "resent-sender", H_FROM, 0, 58 "resent-from", H_FROM, 0, 59 "sender", H_FROM, 0, 60 "from", H_FROM|H_CHECK, M_NEEDFROM, 61 "full-name", H_ACHECK, M_FULLNAME, 62 "received-from", H_CHECK, M_LOCAL, 63 "return-receipt-to", H_FROM, 0, 64 "errors-to", H_FROM, 0, 65 /* destination fields */ 66 "to", H_RCPT, 0, 67 "resent-to", H_RCPT, 0, 68 "cc", H_RCPT, 0, 69 "resent-cc", H_RCPT, 0, 70 "bcc", H_RCPT, 0, 71 "resent-bcc", H_RCPT, 0, 72 /* message identification and control */ 73 "message-id", 0, 0, 74 "resent-message-id", 0, 0, 75 "precedence", 0, 0, 76 "message", H_EOH, 0, 77 "text", H_EOH, 0, 78 /* trace fields */ 79 "received", H_TRACE|H_FORCE, 0, 80 "via", H_TRACE|H_FORCE, 0, 81 "mail-from", H_TRACE|H_FORCE, 0, 82 83 NULL, 0, 0, 84 }; 85 86 87 /* 88 ** ARPANET error message numbers. 89 */ 90 91 char Arpa_Info[] = "050"; /* arbitrary info */ 92 char Arpa_TSyserr[] = "451"; /* some (transient) system error */ 93 char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ 94 char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ 95 96 97 98 99 100 /* 101 ** Location of system files/databases/etc. 102 */ 103 104 char *ConfFile = "/usr/lib/sendmail.cf"; /* runtime configuration */ 105 char *XcriptFile = "/tmp/mailxXXXXXX"; /* template for transcript */ 106 107 # ifdef V6 108 /* 109 ** TTYNAME -- return name of terminal. 110 ** 111 ** Parameters: 112 ** fd -- file descriptor to check. 113 ** 114 ** Returns: 115 ** pointer to full path of tty. 116 ** NULL if no tty. 117 ** 118 ** Side Effects: 119 ** none. 120 */ 121 122 char * 123 ttyname(fd) 124 int fd; 125 { 126 register char tn; 127 static char pathn[] = "/dev/ttyx"; 128 129 /* compute the pathname of the controlling tty */ 130 if ((tn = ttyn(fd)) == NULL) 131 { 132 errno = 0; 133 return (NULL); 134 } 135 pathn[8] = tn; 136 return (pathn); 137 } 138 /* 139 ** FDOPEN -- Open a stdio file given an open file descriptor. 140 ** 141 ** This is included here because it is standard in v7, but we 142 ** need it in v6. 143 ** 144 ** Algorithm: 145 ** Open /dev/null to create a descriptor. 146 ** Close that descriptor. 147 ** Copy the existing fd into the descriptor. 148 ** 149 ** Parameters: 150 ** fd -- the open file descriptor. 151 ** type -- "r", "w", or whatever. 152 ** 153 ** Returns: 154 ** The file descriptor it creates. 155 ** 156 ** Side Effects: 157 ** none 158 ** 159 ** Called By: 160 ** deliver 161 ** 162 ** Notes: 163 ** The mode of fd must match "type". 164 */ 165 166 FILE * 167 fdopen(fd, type) 168 int fd; 169 char *type; 170 { 171 register FILE *f; 172 173 f = fopen("/dev/null", type); 174 (void) close(fileno(f)); 175 fileno(f) = fd; 176 return (f); 177 } 178 /* 179 ** INDEX -- Return pointer to character in string 180 ** 181 ** For V7 compatibility. 182 ** 183 ** Parameters: 184 ** s -- a string to scan. 185 ** c -- a character to look for. 186 ** 187 ** Returns: 188 ** If c is in s, returns the address of the first 189 ** instance of c in s. 190 ** NULL if c is not in s. 191 ** 192 ** Side Effects: 193 ** none. 194 */ 195 196 char * 197 index(s, c) 198 register char *s; 199 register char c; 200 { 201 while (*s != '\0') 202 { 203 if (*s++ == c) 204 return (--s); 205 } 206 return (NULL); 207 } 208 /* 209 ** UMASK -- fake the umask system call. 210 ** 211 ** Since V6 always acts like the umask is zero, we will just 212 ** assume the same thing. 213 */ 214 215 /*ARGSUSED*/ 216 umask(nmask) 217 { 218 return (0); 219 } 220 221 222 /* 223 ** GETRUID -- get real user id. 224 */ 225 226 getruid() 227 { 228 return (getuid() & 0377); 229 } 230 231 232 /* 233 ** GETRGID -- get real group id. 234 */ 235 236 getrgid() 237 { 238 return (getgid() & 0377); 239 } 240 241 242 /* 243 ** GETEUID -- get effective user id. 244 */ 245 246 geteuid() 247 { 248 return ((getuid() >> 8) & 0377); 249 } 250 251 252 /* 253 ** GETEGID -- get effective group id. 254 */ 255 256 getegid() 257 { 258 return ((getgid() >> 8) & 0377); 259 } 260 261 # endif V6 262 263 # ifndef V6 264 265 /* 266 ** GETRUID -- get real user id (V7) 267 */ 268 269 getruid() 270 { 271 if (Mode == MD_DAEMON) 272 return (RealUid); 273 else 274 return (getuid()); 275 } 276 277 278 /* 279 ** GETRGID -- get real group id (V7). 280 */ 281 282 getrgid() 283 { 284 if (Mode == MD_DAEMON) 285 return (RealGid); 286 else 287 return (getgid()); 288 } 289 290 # endif V6 291 /* 292 ** TTYPATH -- Get the path of the user's tty 293 ** 294 ** Returns the pathname of the user's tty. Returns NULL if 295 ** the user is not logged in or if s/he has write permission 296 ** denied. 297 ** 298 ** Parameters: 299 ** none 300 ** 301 ** Returns: 302 ** pathname of the user's tty. 303 ** NULL if not logged in or write permission denied. 304 ** 305 ** Side Effects: 306 ** none. 307 ** 308 ** WARNING: 309 ** Return value is in a local buffer. 310 ** 311 ** Called By: 312 ** savemail 313 */ 314 315 # include <sys/stat.h> 316 317 char * 318 ttypath() 319 { 320 struct stat stbuf; 321 register char *pathn; 322 extern char *ttyname(); 323 extern char *getlogin(); 324 325 /* compute the pathname of the controlling tty */ 326 if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 327 { 328 errno = 0; 329 return (NULL); 330 } 331 332 /* see if we have write permission */ 333 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 334 { 335 errno = 0; 336 return (NULL); 337 } 338 339 /* see if the user is logged in */ 340 if (getlogin() == NULL) 341 return (NULL); 342 343 /* looks good */ 344 return (pathn); 345 } 346 /* 347 ** CHECKCOMPAT -- check for From and To person compatible. 348 ** 349 ** This routine can be supplied on a per-installation basis 350 ** to determine whether a person is allowed to send a message. 351 ** This allows restriction of certain types of internet 352 ** forwarding or registration of users. 353 ** 354 ** If the hosts are found to be incompatible, an error 355 ** message should be given using "usrerr" and FALSE should 356 ** be returned. 357 ** 358 ** 'NoReturn' can be set to suppress the return-to-sender 359 ** function; this should be done on huge messages. 360 ** 361 ** Parameters: 362 ** to -- the person being sent to. 363 ** 364 ** Returns: 365 ** TRUE -- ok to send. 366 ** FALSE -- not ok. 367 ** 368 ** Side Effects: 369 ** none (unless you include the usrerr stuff) 370 */ 371 372 bool 373 checkcompat(to) 374 register ADDRESS *to; 375 { 376 # ifdef ING70 377 register STAB *s; 378 # endif ING70 379 380 if (to->q_mailer != LocalMailer && CurEnv->e_msgsize > 100000) 381 { 382 usrerr("Message exceeds 100000 bytes"); 383 NoReturn++; 384 return (FALSE); 385 } 386 # ifdef ING70 387 s = stab("arpa", ST_MAILER, ST_FIND); 388 if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && to->q_mailer == s->s_mailer) 389 { 390 usrerr("No ARPA mail through this machine: see your system administration"); 391 return (FALSE); 392 } 393 # endif ING70 394 return (TRUE); 395 } 396