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