X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/cbdb73579a44ca48a6e8032960428fdb1302ea22..d4d03212909ba072bf7f3f2d318af2e1463e20e9:/usr/src/usr.sbin/sendmail/src/recipient.c diff --git a/usr/src/usr.sbin/sendmail/src/recipient.c b/usr/src/usr.sbin/sendmail/src/recipient.c index 729146ab57..737c875c5c 100644 --- a/usr/src/usr.sbin/sendmail/src/recipient.c +++ b/usr/src/usr.sbin/sendmail/src/recipient.c @@ -1,9 +1,8 @@ # include -# include -# include # include "sendmail.h" +# include -static char SccsId[] = "@(#)recipient.c 3.26 %G%"; +SCCSID(@(#)recipient.c 3.33 %G%); /* ** SENDTO -- Designate a send list. @@ -11,14 +10,25 @@ static char SccsId[] = "@(#)recipient.c 3.26 %G%"; ** The parameter is a comma-separated list of people to send to. ** This routine arranges to send to all of them. ** +** The `ctladdr' is the address that expanded to be this one, +** e.g., in an alias expansion. This is used for a number of +** purposed, most notably inheritance of uid/gid for protection +** purposes. It is also used to detect self-reference in group +** expansions and the like. +** ** Parameters: ** list -- the send list. ** copyf -- the copy flag; passed to parse. ** ctladdr -- the address template for the person to ** send to -- effective uid/gid are important. +** This is typically the alias that caused this +** expansion. +** sendq -- a pointer to the head of a queue to put +** these people into. +** qflags -- special flags to set in the q_flags field. ** ** Returns: -** none +** pointer to chain of addresses. ** ** Side Effects: ** none. @@ -26,16 +36,21 @@ static char SccsId[] = "@(#)recipient.c 3.26 %G%"; # define MAXRCRSN 10 -sendto(list, copyf, ctladdr) +ADDRESS * +sendto(list, copyf, ctladdr, qflags) char *list; int copyf; ADDRESS *ctladdr; + ADDRESS **sendq; + u_short qflags; { register char *p; bool more; /* set if more addresses to send to */ ADDRESS *al; /* list of addresses to send to */ bool firstone; /* set on first address sent */ bool selfref; /* set if this list includes ctladdr */ + ADDRESS *sibl; /* sibling pointer in tree */ + ADDRESS *prev; /* previous sibling */ # ifdef DEBUG if (Debug > 1) @@ -73,6 +88,9 @@ sendto(list, copyf, ctladdr) continue; a->q_next = al; a->q_alias = ctladdr; + if (ctladdr != NULL) + a->q_flags |= ctladdr->q_flags & ~QPRIMARY; + a->q_flags |= qflags; /* see if this should be marked as a primary address */ if (ctladdr == NULL || @@ -92,15 +110,71 @@ sendto(list, copyf, ctladdr) ctladdr->q_flags |= QDONTSEND; /* arrange to send to everyone on the local send list */ + prev = sibl = NULL; + if (ctladdr != NULL) + prev = ctladdr->q_child; while (al != NULL) { register ADDRESS *a = al; + extern ADDRESS *recipient(); al = a->q_next; - recipient(a); + sibl = recipient(a); + if (sibl != NULL) + { + extern ADDRESS *addrref(); + + /* inherit full name */ + if (sibl->q_fullname == NULL && ctladdr != NULL) + sibl->q_fullname = ctladdr->q_fullname; + + /* link tree together (but only if the node is new) */ + if (sibl == a) + { + sibl->q_sibling = prev; + prev = sibl; + } + } } To = NULL; + if (ctladdr != NULL) + ctladdr->q_child = prev; + return (prev); +} + /* +** ADDRREF -- return pointer to address that references another address. +** +** Parameters: +** a -- address to check. +** r -- reference to find. +** +** Returns: +** address of node in tree rooted at 'a' that references +** 'r'. +** NULL if no such node exists. +** +** Side Effects: +** none. +*/ + +ADDRESS * +addrref(a, r) + register ADDRESS *a; + register ADDRESS *r; +{ + register ADDRESS *q; + + while (a != NULL) + { + if (a->q_child == r || a->q_sibling == r) + return (a); + q = addrref(a->q_child, r); + if (q != NULL) + return (q); + a = a->q_sibling; + } + return (NULL); } /* ** RECIPIENT -- Designate a message recipient @@ -109,24 +183,30 @@ sendto(list, copyf, ctladdr) ** ** Parameters: ** a -- the (preparsed) address header for the recipient. +** sendq -- a pointer to the head of a queue to put the +** recipient in. Duplicate supression is done +** in this queue. ** ** Returns: -** none. +** pointer to address actually inserted in send list. ** ** Side Effects: ** none. */ -recipient(a) +ADDRESS * +recipient(a, sendq) register ADDRESS *a; + register ADDRESS **sendq; { register ADDRESS *q; ADDRESS **pq; register struct mailer *m; extern ADDRESS *getctladdr(); + extern bool safefile(); To = a->q_paddr; - m = Mailer[a->q_mailer]; + m = a->q_mailer; errno = 0; # ifdef DEBUG if (Debug) @@ -140,21 +220,23 @@ recipient(a) if (AliasLevel > MAXRCRSN) { usrerr("aliasing/forwarding loop broken"); - return; + return (NULL); } /* - ** Do sickly crude mapping for program mailing, etc. + ** Finish setting up address structure. */ - if (a->q_mailer == MN_LOCAL) + a->q_timeout = TimeOut; + + /* do sickly crude mapping for program mailing, etc. */ + if (a->q_mailer == LocalMailer) { if (a->q_user[0] == '|') { - a->q_mailer = MN_PROG; - m = Mailer[MN_PROG]; + a->q_mailer = m = ProgMailer; a->q_user++; - if (a->q_alias == NULL && Debug == 0) + if (a->q_alias == NULL && Debug == 0 && !QueueRun && !ForceMail) { usrerr("Cannot mail directly to programs"); a->q_flags |= QDONTSEND; @@ -171,7 +253,7 @@ recipient(a) ** [Please note: the emphasis is on "hack."] */ - for (pq = &m->m_sendq; (q = *pq) != NULL; pq = &q->q_next) + for (pq = sendq; (q = *pq) != NULL; pq = &q->q_next) { if (!ForceMail && sameaddr(q, a, FALSE)) { @@ -182,11 +264,13 @@ recipient(a) printaddr(q, FALSE); } # endif DEBUG - if (Verbose && !bitset(QDONTSEND, a->q_flags)) + if (Verbose && !bitset(QDONTSEND|QPSEUDO, a->q_flags)) message(Arpa_Info, "duplicate suppressed"); if (!bitset(QPRIMARY, q->q_flags)) q->q_flags |= a->q_flags; - return; + if (!bitset(QPSEUDO, a->q_flags)) + q->q_flags &= ~QPSEUDO; + return (q); } } @@ -200,22 +284,22 @@ recipient(a) ** Alias the name and handle :include: specs. */ - if (a->q_mailer == MN_LOCAL) + if (a->q_mailer == LocalMailer) { if (strncmp(a->q_user, ":include:", 9) == 0) { a->q_flags |= QDONTSEND; - if (a->q_alias == NULL && Debug == 0) + if (a->q_alias == NULL && Debug == 0 && !QueueRun && !ForceMail) usrerr("Cannot mail directly to :include:s"); else { if (Verbose) message(Arpa_Info, "including file %s", &a->q_user[9]); - include(&a->q_user[9], " sending", a); + include(&a->q_user[9], " sending", a, sendq); } } else - alias(a); + alias(a, sendq); } /* @@ -226,7 +310,7 @@ recipient(a) ** the user (which is probably correct anyway). */ - if (!bitset(QDONTSEND, a->q_flags) && a->q_mailer == MN_LOCAL) + if (!bitset(QDONTSEND, a->q_flags) && a->q_mailer == LocalMailer) { char buf[MAXNAME]; register char *p; @@ -237,16 +321,17 @@ recipient(a) strcpy(buf, a->q_user); for (p = buf; *p != '\0' && !quoted; p++) { - if (!isascii(*p)) + if (!isascii(*p) && (*p & 0377) != (SPACESUB) & 0377) quoted = TRUE; } stripquotes(buf, TRUE); /* see if this is to a file */ - if ((p = rindex(buf, '/')) != NULL) + if (buf[0] == '/') { + p = rindex(buf, '/'); /* check if writable or creatable */ - if (a->q_alias == NULL && Debug == 0) + if (a->q_alias == NULL && Debug == 0 && !QueueRun && !ForceMail) { usrerr("Cannot mail directly to files"); a->q_flags |= QDONTSEND; @@ -272,6 +357,10 @@ recipient(a) } else { + char nbuf[MAXNAME]; + + char nbuf[MAXNAME]; + if (strcmp(a->q_user, pw->pw_name) != 0) { a->q_user = newstr(pw->pw_name); @@ -281,11 +370,19 @@ recipient(a) a->q_uid = pw->pw_uid; a->q_gid = pw->pw_gid; a->q_flags |= QGOODUID; + buildfname(pw->pw_gecos, pw->pw_name, nbuf); + if (nbuf[0] != '\0') + a->q_fullname = newstr(nbuf); + fullname(pw, nbuf); + if (nbuf[0] != '\0') + a->q_fullname = newstr(nbuf); if (!quoted) - forward(a); + forward(a, sendq); } } } + + return (a); } /* ** FINDUSER -- find the password entry for a user. @@ -325,17 +422,17 @@ finduser(name) setpwent(); while ((pw = getpwent()) != NULL) { - char buf[MAXNAME]; extern bool sameword(); + char buf[MAXNAME]; if (strcmp(pw->pw_name, name) == 0) return (pw); - buildfname(pw->pw_gecos, pw->pw_name, buf); + fullname(pw, buf); if (index(buf, ' ') != NULL && sameword(buf, name)) { if (Verbose) - message(Arpa_Info, "sending to login name %s", - pw->pw_name); + message(Arpa_Info, "sending to %s <%s>", + buf, pw->pw_name); return (pw); } } @@ -402,6 +499,8 @@ writable(s) ** ctladdr -- address template to use to fill in these ** addresses -- effective user/group id are ** the important things. +** sendq -- a pointer to the head of the send queue +** to put these addresses in. ** ** Returns: ** none. @@ -411,10 +510,11 @@ writable(s) ** listed in that file. */ -include(fname, msg, ctladdr) +include(fname, msg, ctladdr, sendq) char *fname; char *msg; ADDRESS *ctladdr; + ADDRESS **sendq; { char buf[MAXLINE]; register FILE *fp; @@ -450,7 +550,7 @@ include(fname, msg, ctladdr) if (Verbose) message(Arpa_Info, "%s to %s", msg, buf); AliasLevel++; - sendto(buf, 1, ctladdr); + sendto(buf, 1, ctladdr, 0); AliasLevel--; } @@ -493,7 +593,7 @@ sendtoargv(argv) argv += 2; } } - sendto(p, 0, NULL); + sendto(p, 0, (ADDRESS *) NULL, 0); } } /*