1*9536Seric #include <pwd.h> 2*9536Seric #include <time.h> 3*9536Seric #include "sendmail.h" 4*9536Seric #include <sys/stat.h> 5*9536Seric 6*9536Seric SCCSID(@(#)envelope.c 3.1 12/05/82); 7*9536Seric 8*9536Seric /* 9*9536Seric ** NEWENVELOPE -- allocate a new envelope 10*9536Seric ** 11*9536Seric ** Supports inheritance. 12*9536Seric ** 13*9536Seric ** Parameters: 14*9536Seric ** e -- the new envelope to fill in. 15*9536Seric ** 16*9536Seric ** Returns: 17*9536Seric ** e. 18*9536Seric ** 19*9536Seric ** Side Effects: 20*9536Seric ** none. 21*9536Seric */ 22*9536Seric 23*9536Seric ENVELOPE * 24*9536Seric newenvelope(e) 25*9536Seric register ENVELOPE *e; 26*9536Seric { 27*9536Seric register HDR *bh; 28*9536Seric register HDR **nhp; 29*9536Seric register ENVELOPE *parent; 30*9536Seric extern putheader(), putbody(); 31*9536Seric extern ENVELOPE BlankEnvelope; 32*9536Seric 33*9536Seric parent = CurEnv; 34*9536Seric if (e == CurEnv) 35*9536Seric parent = e->e_parent; 36*9536Seric clear((char *) e, sizeof *e); 37*9536Seric bmove((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from); 38*9536Seric e->e_parent = parent; 39*9536Seric e->e_ctime = curtime(); 40*9536Seric e->e_puthdr = putheader; 41*9536Seric e->e_putbody = putbody; 42*9536Seric bh = BlankEnvelope.e_header; 43*9536Seric nhp = &e->e_header; 44*9536Seric while (bh != NULL) 45*9536Seric { 46*9536Seric *nhp = (HDR *) xalloc(sizeof *bh); 47*9536Seric bmove((char *) bh, (char *) *nhp, sizeof *bh); 48*9536Seric bh = bh->h_link; 49*9536Seric nhp = &(*nhp)->h_link; 50*9536Seric } 51*9536Seric if (CurEnv->e_xfp != NULL) 52*9536Seric (void) fflush(CurEnv->e_xfp); 53*9536Seric 54*9536Seric return (e); 55*9536Seric } 56*9536Seric /* 57*9536Seric ** DROPENVELOPE -- deallocate an envelope. 58*9536Seric ** 59*9536Seric ** Parameters: 60*9536Seric ** e -- the envelope to deallocate. 61*9536Seric ** 62*9536Seric ** Returns: 63*9536Seric ** none. 64*9536Seric ** 65*9536Seric ** Side Effects: 66*9536Seric ** housekeeping necessary to dispose of an envelope. 67*9536Seric ** Unlocks this queue file. 68*9536Seric */ 69*9536Seric 70*9536Seric dropenvelope(e) 71*9536Seric register ENVELOPE *e; 72*9536Seric { 73*9536Seric bool queueit = FALSE; 74*9536Seric register ADDRESS *q; 75*9536Seric 76*9536Seric #ifdef DEBUG 77*9536Seric if (tTd(50, 1)) 78*9536Seric { 79*9536Seric printf("dropenvelope %x id=", e); 80*9536Seric xputs(e->e_id); 81*9536Seric printf(" flags=%o\n", e->e_flags); 82*9536Seric } 83*9536Seric #endif DEBUG 84*9536Seric #ifdef LOG 85*9536Seric if (LogLevel > 10) 86*9536Seric syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=%o, pid=%d", 87*9536Seric e->e_id == NULL ? "(none)" : e->e_id, 88*9536Seric e->e_flags, getpid()); 89*9536Seric #endif LOG 90*9536Seric 91*9536Seric /* we must have an id to remove disk files */ 92*9536Seric if (e->e_id == NULL) 93*9536Seric return; 94*9536Seric 95*9536Seric /* 96*9536Seric ** Extract state information from dregs of send list. 97*9536Seric */ 98*9536Seric 99*9536Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 100*9536Seric { 101*9536Seric if (bitset(QQUEUEUP, q->q_flags)) 102*9536Seric queueit = TRUE; 103*9536Seric } 104*9536Seric 105*9536Seric /* 106*9536Seric ** Send back return receipts as requested. 107*9536Seric */ 108*9536Seric 109*9536Seric if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags)) 110*9536Seric { 111*9536Seric auto ADDRESS *rlist; 112*9536Seric 113*9536Seric sendto(CurEnv->e_receiptto, (ADDRESS *) NULL, &rlist); 114*9536Seric (void) returntosender("Return receipt", rlist, FALSE); 115*9536Seric } 116*9536Seric 117*9536Seric /* 118*9536Seric ** See if this message has timed out 119*9536Seric */ 120*9536Seric 121*9536Seric if (bitset(EF_TIMEOUT, e->e_flags) && queueit) 122*9536Seric timeout(e); 123*9536Seric 124*9536Seric /* 125*9536Seric ** Arrange to send error messages if there are fatal errors. 126*9536Seric */ 127*9536Seric 128*9536Seric if (bitset(EF_FATALERRS, e->e_flags)) 129*9536Seric savemail(e); 130*9536Seric 131*9536Seric /* 132*9536Seric ** Instantiate or deinstantiate the queue. 133*9536Seric */ 134*9536Seric 135*9536Seric if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) || 136*9536Seric bitset(EF_CLRQUEUE, e->e_flags)) 137*9536Seric { 138*9536Seric if (e->e_dfp != NULL) 139*9536Seric (void) fclose(e->e_dfp); 140*9536Seric if (e->e_df != NULL) 141*9536Seric xunlink(e->e_df); 142*9536Seric xunlink(queuename(e, 'q')); 143*9536Seric } 144*9536Seric else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 145*9536Seric queueup(e, FALSE, FALSE); 146*9536Seric 147*9536Seric /* now unlock the job */ 148*9536Seric if (e->e_xfp != NULL) 149*9536Seric (void) fclose(e->e_xfp); 150*9536Seric unlockqueue(e); 151*9536Seric 152*9536Seric /* make sure that this envelope is marked unused */ 153*9536Seric e->e_id = e->e_df = NULL; 154*9536Seric e->e_dfp = e->e_xfp = NULL; 155*9536Seric } 156*9536Seric /* 157*9536Seric ** CLEARENVELOPE -- clear an envelope without unlocking 158*9536Seric ** 159*9536Seric ** This is normally used by a child process to get a clean 160*9536Seric ** envelope without disturbing the parent. 161*9536Seric ** 162*9536Seric ** Parameters: 163*9536Seric ** e -- the envelope to clear. 164*9536Seric ** 165*9536Seric ** Returns: 166*9536Seric ** none. 167*9536Seric ** 168*9536Seric ** Side Effects: 169*9536Seric ** Closes files associated with the envelope. 170*9536Seric ** Marks the envelope as unallocated. 171*9536Seric */ 172*9536Seric 173*9536Seric clearenvelope(e) 174*9536Seric register ENVELOPE *e; 175*9536Seric { 176*9536Seric /* clear out any file information */ 177*9536Seric if (e->e_xfp != NULL) 178*9536Seric (void) fclose(e->e_xfp); 179*9536Seric if (e->e_dfp != NULL) 180*9536Seric (void) fclose(e->e_dfp); 181*9536Seric e->e_xfp = e->e_dfp = NULL; 182*9536Seric 183*9536Seric /* now expunge names of objects */ 184*9536Seric e->e_df = e->e_id = NULL; 185*9536Seric 186*9536Seric /* and the flags which are now meaningless */ 187*9536Seric e->e_flags = 0; 188*9536Seric } 189*9536Seric /* 190*9536Seric ** UNLOCKQUEUE -- unlock the queue entry for a specified envelope 191*9536Seric ** 192*9536Seric ** Parameters: 193*9536Seric ** e -- the envelope to unlock. 194*9536Seric ** 195*9536Seric ** Returns: 196*9536Seric ** none 197*9536Seric ** 198*9536Seric ** Side Effects: 199*9536Seric ** unlocks the queue for `e'. 200*9536Seric */ 201*9536Seric 202*9536Seric unlockqueue(e) 203*9536Seric ENVELOPE *e; 204*9536Seric { 205*9536Seric /* remove the transcript */ 206*9536Seric #ifdef DEBUG 207*9536Seric if (!tTd(51, 4)) 208*9536Seric #endif DEBUG 209*9536Seric xunlink(queuename(e, 'x')); 210*9536Seric 211*9536Seric /* last but not least, remove the lock */ 212*9536Seric xunlink(queuename(e, 'l')); 213*9536Seric } 214*9536Seric /* 215*9536Seric ** INITSYS -- initialize instantiation of system 216*9536Seric ** 217*9536Seric ** In Daemon mode, this is done in the child. 218*9536Seric ** 219*9536Seric ** Parameters: 220*9536Seric ** none. 221*9536Seric ** 222*9536Seric ** Returns: 223*9536Seric ** none. 224*9536Seric ** 225*9536Seric ** Side Effects: 226*9536Seric ** Initializes the system macros, some global variables, 227*9536Seric ** etc. In particular, the current time in various 228*9536Seric ** forms is set. 229*9536Seric */ 230*9536Seric 231*9536Seric initsys() 232*9536Seric { 233*9536Seric auto time_t now; 234*9536Seric static char cbuf[5]; /* holds hop count */ 235*9536Seric static char dbuf[30]; /* holds ctime(tbuf) */ 236*9536Seric static char pbuf[10]; /* holds pid */ 237*9536Seric static char tbuf[20]; /* holds "current" time */ 238*9536Seric static char ybuf[10]; /* holds tty id */ 239*9536Seric register char *p; 240*9536Seric register struct tm *tm; 241*9536Seric extern char *ttyname(); 242*9536Seric extern char *arpadate(); 243*9536Seric extern struct tm *gmtime(); 244*9536Seric extern char *macvalue(); 245*9536Seric extern char Version[]; 246*9536Seric 247*9536Seric /* 248*9536Seric ** Give this envelope a reality. 249*9536Seric ** I.e., an id, a transcript, and a creation time. 250*9536Seric */ 251*9536Seric 252*9536Seric openxscript(CurEnv); 253*9536Seric CurEnv->e_ctime = curtime(); 254*9536Seric 255*9536Seric /* 256*9536Seric ** Set OutChannel to something useful if stdout isn't it. 257*9536Seric ** This arranges that any extra stuff the mailer produces 258*9536Seric ** gets sent back to the user on error (because it is 259*9536Seric ** tucked away in the transcript). 260*9536Seric */ 261*9536Seric 262*9536Seric if (OpMode == MD_DAEMON && QueueRun) 263*9536Seric OutChannel = CurEnv->e_xfp; 264*9536Seric 265*9536Seric /* 266*9536Seric ** Set up some basic system macros. 267*9536Seric */ 268*9536Seric 269*9536Seric /* process id */ 270*9536Seric (void) sprintf(pbuf, "%d", getpid()); 271*9536Seric define('p', pbuf, CurEnv); 272*9536Seric 273*9536Seric /* hop count */ 274*9536Seric (void) sprintf(cbuf, "%d", CurEnv->e_hopcount); 275*9536Seric define('c', cbuf, CurEnv); 276*9536Seric 277*9536Seric /* time as integer, unix time, arpa time */ 278*9536Seric now = curtime(); 279*9536Seric tm = gmtime(&now); 280*9536Seric (void) sprintf(tbuf, "%02d%02d%02d%02d%02d", tm->tm_year, tm->tm_mon, 281*9536Seric tm->tm_mday, tm->tm_hour, tm->tm_min); 282*9536Seric define('t', tbuf, CurEnv); 283*9536Seric (void) strcpy(dbuf, ctime(&now)); 284*9536Seric *index(dbuf, '\n') = '\0'; 285*9536Seric if (macvalue('d', CurEnv) == NULL) 286*9536Seric define('d', dbuf, CurEnv); 287*9536Seric p = newstr(arpadate(dbuf)); 288*9536Seric if (macvalue('a', CurEnv) == NULL) 289*9536Seric define('a', p, CurEnv); 290*9536Seric define('b', p, CurEnv); 291*9536Seric 292*9536Seric /* version */ 293*9536Seric define('v', Version, CurEnv); 294*9536Seric 295*9536Seric /* tty name */ 296*9536Seric if (macvalue('y', CurEnv) == NULL) 297*9536Seric { 298*9536Seric p = ttyname(2); 299*9536Seric if (p != NULL) 300*9536Seric { 301*9536Seric if (rindex(p, '/') != NULL) 302*9536Seric p = rindex(p, '/') + 1; 303*9536Seric (void) strcpy(ybuf, p); 304*9536Seric define('y', ybuf, CurEnv); 305*9536Seric } 306*9536Seric } 307*9536Seric } 308*9536Seric /* 309*9536Seric ** QUEUENAME -- build a file name in the queue directory for this envelope. 310*9536Seric ** 311*9536Seric ** Assigns an id code if one does not already exist. 312*9536Seric ** This code is very careful to avoid trashing existing files 313*9536Seric ** under any circumstances. 314*9536Seric ** We first create an nf file that is only used when 315*9536Seric ** assigning an id. This file is always empty, so that 316*9536Seric ** we can never accidently truncate an lf file. 317*9536Seric ** 318*9536Seric ** Parameters: 319*9536Seric ** e -- envelope to build it in/from. 320*9536Seric ** type -- the file type, used as the first character 321*9536Seric ** of the file name. 322*9536Seric ** 323*9536Seric ** Returns: 324*9536Seric ** a pointer to the new file name (in a static buffer). 325*9536Seric ** 326*9536Seric ** Side Effects: 327*9536Seric ** Will create the lf and qf files if no id code is 328*9536Seric ** already assigned. This will cause the envelope 329*9536Seric ** to be modified. 330*9536Seric */ 331*9536Seric 332*9536Seric char * 333*9536Seric queuename(e, type) 334*9536Seric register ENVELOPE *e; 335*9536Seric char type; 336*9536Seric { 337*9536Seric static char buf[MAXNAME]; 338*9536Seric static int pid = -1; 339*9536Seric char c1 = 'A'; 340*9536Seric char c2 = 'A'; 341*9536Seric 342*9536Seric if (e->e_id == NULL) 343*9536Seric { 344*9536Seric char qf[20]; 345*9536Seric char lf[20]; 346*9536Seric char nf[20]; 347*9536Seric 348*9536Seric /* find a unique id */ 349*9536Seric if (pid != getpid()) 350*9536Seric { 351*9536Seric /* new process -- start back at "AA" */ 352*9536Seric pid = getpid(); 353*9536Seric c1 = 'A'; 354*9536Seric c2 = 'A' - 1; 355*9536Seric } 356*9536Seric (void) sprintf(qf, "qfAA%05d", pid); 357*9536Seric strcpy(lf, qf); 358*9536Seric lf[0] = 'l'; 359*9536Seric strcpy(nf, qf); 360*9536Seric nf[0] = 'n'; 361*9536Seric 362*9536Seric while (c1 < '~' || c2 < 'Z') 363*9536Seric { 364*9536Seric int i; 365*9536Seric 366*9536Seric if (c2 >= 'Z') 367*9536Seric { 368*9536Seric c1++; 369*9536Seric c2 = 'A' - 1; 370*9536Seric } 371*9536Seric qf[2] = lf[2] = nf[2] = c1; 372*9536Seric qf[3] = lf[3] = nf[3] = ++c2; 373*9536Seric # ifdef DEBUG 374*9536Seric if (tTd(7, 20)) 375*9536Seric printf("queuename: trying \"%s\"\n", nf); 376*9536Seric # endif DEBUG 377*9536Seric if (access(lf, 0) >= 0 || access(qf, 0) >= 0) 378*9536Seric continue; 379*9536Seric errno = 0; 380*9536Seric i = creat(nf, FileMode); 381*9536Seric if (i < 0) 382*9536Seric { 383*9536Seric (void) unlink(nf); /* kernel bug */ 384*9536Seric continue; 385*9536Seric } 386*9536Seric (void) close(i); 387*9536Seric i = link(nf, lf); 388*9536Seric (void) unlink(nf); 389*9536Seric if (i < 0) 390*9536Seric continue; 391*9536Seric if (link(lf, qf) >= 0) 392*9536Seric break; 393*9536Seric (void) unlink(lf); 394*9536Seric } 395*9536Seric if (c1 >= '~' && c2 >= 'Z') 396*9536Seric { 397*9536Seric syserr("queuename: Cannot create \"%s\" in \"%s\"", 398*9536Seric lf, QueueDir); 399*9536Seric exit(EX_OSERR); 400*9536Seric } 401*9536Seric e->e_id = newstr(&qf[2]); 402*9536Seric define('i', e->e_id, e); 403*9536Seric # ifdef DEBUG 404*9536Seric if (tTd(7, 1)) 405*9536Seric printf("queuename: assigned id %s, env=%x\n", e->e_id, e); 406*9536Seric # endif DEBUG 407*9536Seric } 408*9536Seric 409*9536Seric if (type == '\0') 410*9536Seric return (NULL); 411*9536Seric (void) sprintf(buf, "%cf%s", type, e->e_id); 412*9536Seric # ifdef DEBUG 413*9536Seric if (tTd(7, 2)) 414*9536Seric printf("queuename: %s\n", buf); 415*9536Seric # endif DEBUG 416*9536Seric return (buf); 417*9536Seric } 418*9536Seric /* 419*9536Seric ** OPENXSCRIPT -- Open transcript file 420*9536Seric ** 421*9536Seric ** Creates a transcript file for possible eventual mailing or 422*9536Seric ** sending back. 423*9536Seric ** 424*9536Seric ** Parameters: 425*9536Seric ** e -- the envelope to create the transcript in/for. 426*9536Seric ** 427*9536Seric ** Returns: 428*9536Seric ** none 429*9536Seric ** 430*9536Seric ** Side Effects: 431*9536Seric ** Creates the transcript file. 432*9536Seric */ 433*9536Seric 434*9536Seric openxscript(e) 435*9536Seric register ENVELOPE *e; 436*9536Seric { 437*9536Seric register char *p; 438*9536Seric 439*9536Seric if (e->e_xfp != NULL) 440*9536Seric return; 441*9536Seric p = queuename(e, 'x'); 442*9536Seric e->e_xfp = fopen(p, "w"); 443*9536Seric if (e->e_xfp == NULL) 444*9536Seric syserr("Can't create %s", p); 445*9536Seric else 446*9536Seric (void) chmod(p, 0644); 447*9536Seric } 448*9536Seric /* 449*9536Seric ** SETSENDER -- set the person who this message is from 450*9536Seric ** 451*9536Seric ** Under certain circumstances allow the user to say who 452*9536Seric ** s/he is (using -f or -r). These are: 453*9536Seric ** 1. The user's uid is zero (root). 454*9536Seric ** 2. The user's login name is in an approved list (typically 455*9536Seric ** from a network server). 456*9536Seric ** 3. The address the user is trying to claim has a 457*9536Seric ** "!" character in it (since #2 doesn't do it for 458*9536Seric ** us if we are dialing out for UUCP). 459*9536Seric ** A better check to replace #3 would be if the 460*9536Seric ** effective uid is "UUCP" -- this would require me 461*9536Seric ** to rewrite getpwent to "grab" uucp as it went by, 462*9536Seric ** make getname more nasty, do another passwd file 463*9536Seric ** scan, or compile the UID of "UUCP" into the code, 464*9536Seric ** all of which are reprehensible. 465*9536Seric ** 466*9536Seric ** Assuming all of these fail, we figure out something 467*9536Seric ** ourselves. 468*9536Seric ** 469*9536Seric ** Parameters: 470*9536Seric ** from -- the person we would like to believe this message 471*9536Seric ** is from, as specified on the command line. 472*9536Seric ** 473*9536Seric ** Returns: 474*9536Seric ** none. 475*9536Seric ** 476*9536Seric ** Side Effects: 477*9536Seric ** sets sendmail's notion of who the from person is. 478*9536Seric */ 479*9536Seric 480*9536Seric setsender(from) 481*9536Seric char *from; 482*9536Seric { 483*9536Seric register char **pvp; 484*9536Seric register struct passwd *pw = NULL; 485*9536Seric char *realname = NULL; 486*9536Seric char buf[MAXNAME]; 487*9536Seric extern char *macvalue(); 488*9536Seric extern char **prescan(); 489*9536Seric extern bool safefile(); 490*9536Seric extern char *FullName; 491*9536Seric 492*9536Seric # ifdef DEBUG 493*9536Seric if (tTd(45, 1)) 494*9536Seric printf("setsender(%s)\n", from); 495*9536Seric # endif DEBUG 496*9536Seric 497*9536Seric /* 498*9536Seric ** Figure out the real user executing us. 499*9536Seric ** Username can return errno != 0 on non-errors. 500*9536Seric */ 501*9536Seric 502*9536Seric if (QueueRun || OpMode == MD_SMTP || OpMode == MD_ARPAFTP) 503*9536Seric realname = from; 504*9536Seric if (realname == NULL || realname[0] == '\0') 505*9536Seric { 506*9536Seric extern char *username(); 507*9536Seric 508*9536Seric realname = username(); 509*9536Seric errno = 0; 510*9536Seric } 511*9536Seric if (realname == NULL || realname[0] == '\0') 512*9536Seric { 513*9536Seric extern struct passwd *getpwuid(); 514*9536Seric 515*9536Seric pw = getpwuid(getruid()); 516*9536Seric if (pw != NULL) 517*9536Seric realname = pw->pw_name; 518*9536Seric } 519*9536Seric if (realname == NULL || realname[0] == '\0') 520*9536Seric { 521*9536Seric syserr("Who are you?"); 522*9536Seric realname = "root"; 523*9536Seric } 524*9536Seric 525*9536Seric /* 526*9536Seric ** Determine if this real person is allowed to alias themselves. 527*9536Seric */ 528*9536Seric 529*9536Seric if (from != NULL) 530*9536Seric { 531*9536Seric extern bool trusteduser(); 532*9536Seric 533*9536Seric if (!trusteduser(realname) && 534*9536Seric # ifdef DEBUG 535*9536Seric (!tTd(1, 9) || getuid() != geteuid()) && 536*9536Seric # endif DEBUG 537*9536Seric index(from, '!') == NULL && getuid() != 0) 538*9536Seric { 539*9536Seric /* network sends -r regardless (why why why?) */ 540*9536Seric /* syserr("%s, you cannot use the -f flag", realname); */ 541*9536Seric from = NULL; 542*9536Seric } 543*9536Seric } 544*9536Seric 545*9536Seric SuprErrs = TRUE; 546*9536Seric if (from == NULL || parse(from, &CurEnv->e_from, 1) == NULL) 547*9536Seric { 548*9536Seric from = newstr(realname); 549*9536Seric (void) parse(from, &CurEnv->e_from, 1); 550*9536Seric } 551*9536Seric else 552*9536Seric FromFlag = TRUE; 553*9536Seric CurEnv->e_from.q_flags |= QDONTSEND; 554*9536Seric SuprErrs = FALSE; 555*9536Seric 556*9536Seric if (pw == NULL && CurEnv->e_from.q_mailer == LocalMailer) 557*9536Seric { 558*9536Seric extern struct passwd *getpwnam(); 559*9536Seric 560*9536Seric pw = getpwnam(CurEnv->e_from.q_user); 561*9536Seric } 562*9536Seric 563*9536Seric /* 564*9536Seric ** Process passwd file entry. 565*9536Seric */ 566*9536Seric 567*9536Seric if (pw != NULL) 568*9536Seric { 569*9536Seric /* extract home directory */ 570*9536Seric CurEnv->e_from.q_home = newstr(pw->pw_dir); 571*9536Seric 572*9536Seric /* run user's .mailcf file */ 573*9536Seric define('z', CurEnv->e_from.q_home, CurEnv); 574*9536Seric expand("$z/.mailcf", buf, &buf[sizeof buf - 1], CurEnv); 575*9536Seric if (safefile(buf, getruid(), S_IREAD)) 576*9536Seric readcf(buf, FALSE); 577*9536Seric 578*9536Seric /* if the user has given fullname already, don't redefine */ 579*9536Seric if (FullName == NULL) 580*9536Seric FullName = macvalue('x', CurEnv); 581*9536Seric if (FullName[0] == '\0') 582*9536Seric FullName = NULL; 583*9536Seric 584*9536Seric /* extract full name from passwd file */ 585*9536Seric if (FullName == NULL && pw->pw_gecos != NULL) 586*9536Seric { 587*9536Seric buildfname(pw->pw_gecos, CurEnv->e_from.q_user, buf); 588*9536Seric if (buf[0] != '\0') 589*9536Seric FullName = newstr(buf); 590*9536Seric } 591*9536Seric if (FullName != NULL) 592*9536Seric define('x', FullName, CurEnv); 593*9536Seric } 594*9536Seric 595*9536Seric #ifndef V6 596*9536Seric if (CurEnv->e_from.q_home == NULL) 597*9536Seric CurEnv->e_from.q_home = getenv("HOME"); 598*9536Seric #endif V6 599*9536Seric CurEnv->e_from.q_uid = getuid(); 600*9536Seric CurEnv->e_from.q_gid = getgid(); 601*9536Seric if (CurEnv->e_from.q_uid != 0) 602*9536Seric { 603*9536Seric DefUid = CurEnv->e_from.q_uid; 604*9536Seric DefGid = CurEnv->e_from.q_gid; 605*9536Seric } 606*9536Seric 607*9536Seric /* 608*9536Seric ** Rewrite the from person to dispose of possible implicit 609*9536Seric ** links in the net. 610*9536Seric */ 611*9536Seric 612*9536Seric pvp = prescan(from, '\0'); 613*9536Seric if (pvp == NULL) 614*9536Seric { 615*9536Seric syserr("cannot prescan from (%s)", from); 616*9536Seric finis(); 617*9536Seric } 618*9536Seric rewrite(pvp, 3); 619*9536Seric rewrite(pvp, 1); 620*9536Seric cataddr(pvp, buf, sizeof buf); 621*9536Seric define('f', newstr(buf), CurEnv); 622*9536Seric 623*9536Seric /* save the domain spec if this mailer wants it */ 624*9536Seric if (bitset(M_CANONICAL, CurEnv->e_from.q_mailer->m_flags)) 625*9536Seric { 626*9536Seric extern char **copyplist(); 627*9536Seric 628*9536Seric while (*pvp != NULL && strcmp(*pvp, "@") != 0) 629*9536Seric pvp++; 630*9536Seric if (*pvp != NULL) 631*9536Seric CurEnv->e_fromdomain = copyplist(pvp, TRUE); 632*9536Seric } 633*9536Seric } 634*9536Seric /* 635*9536Seric ** TRUSTEDUSER -- tell us if this user is to be trusted. 636*9536Seric ** 637*9536Seric ** Parameters: 638*9536Seric ** user -- the user to be checked. 639*9536Seric ** 640*9536Seric ** Returns: 641*9536Seric ** TRUE if the user is in an approved list. 642*9536Seric ** FALSE otherwise. 643*9536Seric ** 644*9536Seric ** Side Effects: 645*9536Seric ** none. 646*9536Seric */ 647*9536Seric 648*9536Seric bool 649*9536Seric trusteduser(user) 650*9536Seric char *user; 651*9536Seric { 652*9536Seric register char **ulist; 653*9536Seric extern char *TrustedUsers[]; 654*9536Seric 655*9536Seric for (ulist = TrustedUsers; *ulist != NULL; ulist++) 656*9536Seric if (strcmp(*ulist, user) == 0) 657*9536Seric return (TRUE); 658*9536Seric return (FALSE); 659*9536Seric } 660