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.61 11/03/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|H_ACHECK, 0, 71 "resent-bcc", H_RCPT|H_ACHECK, 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 /* 108 ** Some other configuration.... 109 */ 110 111 char SpaceSub = '.'; 112 113 # ifdef V6 114 /* 115 ** TTYNAME -- return name of terminal. 116 ** 117 ** Parameters: 118 ** fd -- file descriptor to check. 119 ** 120 ** Returns: 121 ** pointer to full path of tty. 122 ** NULL if no tty. 123 ** 124 ** Side Effects: 125 ** none. 126 */ 127 128 char * 129 ttyname(fd) 130 int fd; 131 { 132 register char tn; 133 static char pathn[] = "/dev/ttyx"; 134 135 /* compute the pathname of the controlling tty */ 136 if ((tn = ttyn(fd)) == NULL) 137 { 138 errno = 0; 139 return (NULL); 140 } 141 pathn[8] = tn; 142 return (pathn); 143 } 144 /* 145 ** FDOPEN -- Open a stdio file given an open file descriptor. 146 ** 147 ** This is included here because it is standard in v7, but we 148 ** need it in v6. 149 ** 150 ** Algorithm: 151 ** Open /dev/null to create a descriptor. 152 ** Close that descriptor. 153 ** Copy the existing fd into the descriptor. 154 ** 155 ** Parameters: 156 ** fd -- the open file descriptor. 157 ** type -- "r", "w", or whatever. 158 ** 159 ** Returns: 160 ** The file descriptor it creates. 161 ** 162 ** Side Effects: 163 ** none 164 ** 165 ** Called By: 166 ** deliver 167 ** 168 ** Notes: 169 ** The mode of fd must match "type". 170 */ 171 172 FILE * 173 fdopen(fd, type) 174 int fd; 175 char *type; 176 { 177 register FILE *f; 178 179 f = fopen("/dev/null", type); 180 (void) close(fileno(f)); 181 fileno(f) = fd; 182 return (f); 183 } 184 /* 185 ** INDEX -- Return pointer to character in string 186 ** 187 ** For V7 compatibility. 188 ** 189 ** Parameters: 190 ** s -- a string to scan. 191 ** c -- a character to look for. 192 ** 193 ** Returns: 194 ** If c is in s, returns the address of the first 195 ** instance of c in s. 196 ** NULL if c is not in s. 197 ** 198 ** Side Effects: 199 ** none. 200 */ 201 202 char * 203 index(s, c) 204 register char *s; 205 register char c; 206 { 207 while (*s != '\0') 208 { 209 if (*s++ == c) 210 return (--s); 211 } 212 return (NULL); 213 } 214 /* 215 ** UMASK -- fake the umask system call. 216 ** 217 ** Since V6 always acts like the umask is zero, we will just 218 ** assume the same thing. 219 */ 220 221 /*ARGSUSED*/ 222 umask(nmask) 223 { 224 return (0); 225 } 226 227 228 /* 229 ** GETRUID -- get real user id. 230 */ 231 232 getruid() 233 { 234 return (getuid() & 0377); 235 } 236 237 238 /* 239 ** GETRGID -- get real group id. 240 */ 241 242 getrgid() 243 { 244 return (getgid() & 0377); 245 } 246 247 248 /* 249 ** GETEUID -- get effective user id. 250 */ 251 252 geteuid() 253 { 254 return ((getuid() >> 8) & 0377); 255 } 256 257 258 /* 259 ** GETEGID -- get effective group id. 260 */ 261 262 getegid() 263 { 264 return ((getgid() >> 8) & 0377); 265 } 266 267 # endif V6 268 269 # ifndef V6 270 271 /* 272 ** GETRUID -- get real user id (V7) 273 */ 274 275 getruid() 276 { 277 if (Mode == MD_DAEMON) 278 return (RealUid); 279 else 280 return (getuid()); 281 } 282 283 284 /* 285 ** GETRGID -- get real group id (V7). 286 */ 287 288 getrgid() 289 { 290 if (Mode == MD_DAEMON) 291 return (RealGid); 292 else 293 return (getgid()); 294 } 295 296 # endif V6 297 /* 298 ** TTYPATH -- Get the path of the user's tty 299 ** 300 ** Returns the pathname of the user's tty. Returns NULL if 301 ** the user is not logged in or if s/he has write permission 302 ** denied. 303 ** 304 ** Parameters: 305 ** none 306 ** 307 ** Returns: 308 ** pathname of the user's tty. 309 ** NULL if not logged in or write permission denied. 310 ** 311 ** Side Effects: 312 ** none. 313 ** 314 ** WARNING: 315 ** Return value is in a local buffer. 316 ** 317 ** Called By: 318 ** savemail 319 */ 320 321 # include <sys/stat.h> 322 323 char * 324 ttypath() 325 { 326 struct stat stbuf; 327 register char *pathn; 328 extern char *ttyname(); 329 extern char *getlogin(); 330 331 /* compute the pathname of the controlling tty */ 332 if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL) 333 { 334 errno = 0; 335 return (NULL); 336 } 337 338 /* see if we have write permission */ 339 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 340 { 341 errno = 0; 342 return (NULL); 343 } 344 345 /* see if the user is logged in */ 346 if (getlogin() == NULL) 347 return (NULL); 348 349 /* looks good */ 350 return (pathn); 351 } 352 /* 353 ** CHECKCOMPAT -- check for From and To person compatible. 354 ** 355 ** This routine can be supplied on a per-installation basis 356 ** to determine whether a person is allowed to send a message. 357 ** This allows restriction of certain types of internet 358 ** forwarding or registration of users. 359 ** 360 ** If the hosts are found to be incompatible, an error 361 ** message should be given using "usrerr" and FALSE should 362 ** be returned. 363 ** 364 ** 'NoReturn' can be set to suppress the return-to-sender 365 ** function; this should be done on huge messages. 366 ** 367 ** Parameters: 368 ** to -- the person being sent to. 369 ** 370 ** Returns: 371 ** TRUE -- ok to send. 372 ** FALSE -- not ok. 373 ** 374 ** Side Effects: 375 ** none (unless you include the usrerr stuff) 376 */ 377 378 bool 379 checkcompat(to) 380 register ADDRESS *to; 381 { 382 # ifdef ING70 383 register STAB *s; 384 # endif ING70 385 386 if (to->q_mailer != LocalMailer && CurEnv->e_msgsize > 100000) 387 { 388 usrerr("Message exceeds 100000 bytes"); 389 NoReturn++; 390 return (FALSE); 391 } 392 # ifdef ING70 393 s = stab("arpa", ST_MAILER, ST_FIND); 394 if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && to->q_mailer == s->s_mailer) 395 { 396 usrerr("No ARPA mail through this machine: see your system administration"); 397 return (FALSE); 398 } 399 # endif ING70 400 return (TRUE); 401 } 402