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