17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bdstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bdstevel@tonic-gate * (the "License").  You may not use this file except in compliance
77c478bdstevel@tonic-gate * with the License.
87c478bdstevel@tonic-gate *
97c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bdstevel@tonic-gate * See the License for the specific language governing permissions
127c478bdstevel@tonic-gate * and limitations under the License.
137c478bdstevel@tonic-gate *
147c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bdstevel@tonic-gate *
207c478bdstevel@tonic-gate * CDDL HEADER END
217c478bdstevel@tonic-gate */
227c478bdstevel@tonic-gate/*
23b7d62afceastha * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bdstevel@tonic-gate * Use is subject to license terms.
257c478bdstevel@tonic-gate */
267c478bdstevel@tonic-gate
27b7d62afceastha/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28b7d62afceastha
297c478bdstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
307c478bdstevel@tonic-gate
317c478bdstevel@tonic-gate#include "mail.h"
327c478bdstevel@tonic-gate/*
337c478bdstevel@tonic-gate *  NAME
347c478bdstevel@tonic-gate *	sendlist - send copy to specified users
357c478bdstevel@tonic-gate *
367c478bdstevel@tonic-gate *  SYNOPSIS
377c478bdstevel@tonic-gate *	int sendlist(reciplist *list, int letnum, int level)
387c478bdstevel@tonic-gate *
397c478bdstevel@tonic-gate *  DESCRIPTION
407c478bdstevel@tonic-gate *	sendlist() will traverse the current recipient list and
417c478bdstevel@tonic-gate *	send a copy of the given letter to each user specified,
427c478bdstevel@tonic-gate *	invoking send() to do the sending. It returns
437c478bdstevel@tonic-gate *	1 if the sending fails, 0 otherwise.
447c478bdstevel@tonic-gate */
457c478bdstevel@tonic-gate
467c478bdstevel@tonic-gate
477c478bdstevel@tonic-gate/*
487c478bdstevel@tonic-gate * mailx and mailtool read the SENDMAIL from an environment, since few
497c478bdstevel@tonic-gate *  people use /bin/mail as their user agent and since /bin/mail is often
507c478bdstevel@tonic-gate *  called as root or made setuid it's safer to leave this hardwired.
517c478bdstevel@tonic-gate */
527c478bdstevel@tonic-gate
537c478bdstevel@tonic-gatestatic char *sendmail_prog = SENDMAIL;
547c478bdstevel@tonic-gate
55b7d62afceasthastatic void notifybiff(char *);
56b7d62afceastha
577c478bdstevel@tonic-gateint
58b7d62afceasthasendlist(reciplist *list, int letnum, int level)
597c478bdstevel@tonic-gate{
607c478bdstevel@tonic-gate	recip *to;
617c478bdstevel@tonic-gate	int rc = 0;
627c478bdstevel@tonic-gate	FILE *fp;
637c478bdstevel@tonic-gate	int nargs = 4;			/* "sendmail", "-oi", "--", .. NULL */
647c478bdstevel@tonic-gate	char **argv;
657c478bdstevel@tonic-gate	char **p;
667c478bdstevel@tonic-gate
677c478bdstevel@tonic-gate	/* Deliver mail directly to a mailbox */
687c478bdstevel@tonic-gate	if (deliverflag) {
697c478bdstevel@tonic-gate		/*
707c478bdstevel@tonic-gate		 * Note failure to deliver to any one of the recipients
717c478bdstevel@tonic-gate		 * should be considered a failure, so that the user
727c478bdstevel@tonic-gate		 * get's an indication of that failure.
737c478bdstevel@tonic-gate		 */
747c478bdstevel@tonic-gate		for (to = &(list->recip_list); to; to = to->next) {
757c478bdstevel@tonic-gate			if (to->name)
767c478bdstevel@tonic-gate				if (!send_mbox(to->name, letnum))
777c478bdstevel@tonic-gate					rc = 1;
787c478bdstevel@tonic-gate		}
797c478bdstevel@tonic-gate		return (rc);
807c478bdstevel@tonic-gate	}
817c478bdstevel@tonic-gate
827c478bdstevel@tonic-gate	/*
837c478bdstevel@tonic-gate	 * build argv list, allowing for arbitrarily long deliver lists
847c478bdstevel@tonic-gate	 * and then  hand the message off to sendmail
857c478bdstevel@tonic-gate	 */
867c478bdstevel@tonic-gate
877c478bdstevel@tonic-gate	if (!ismail)
887c478bdstevel@tonic-gate		nargs += 2;	/* for "-f", "Rpath" */
897c478bdstevel@tonic-gate
907c478bdstevel@tonic-gate	for (to = &(list->recip_list); to; to = to->next)
917c478bdstevel@tonic-gate		if (to->name)
927c478bdstevel@tonic-gate			nargs++;
937c478bdstevel@tonic-gate
947c478bdstevel@tonic-gate	argv = malloc(nargs * sizeof (char *));
957c478bdstevel@tonic-gate
967c478bdstevel@tonic-gate	if (argv == NULL)
977c478bdstevel@tonic-gate		return (1);
987c478bdstevel@tonic-gate
997c478bdstevel@tonic-gate	p = argv;
1007c478bdstevel@tonic-gate
1017c478bdstevel@tonic-gate	*p++ = sendmail_prog;
1027c478bdstevel@tonic-gate
1037c478bdstevel@tonic-gate	/* If we're rmail add "-f", "Rpath" to the the command line */
1047c478bdstevel@tonic-gate	if (!ismail) {
1057c478bdstevel@tonic-gate		*p++ = "-f";
1067c478bdstevel@tonic-gate		*p++ = Rpath;
1077c478bdstevel@tonic-gate	}
1087c478bdstevel@tonic-gate
1097c478bdstevel@tonic-gate	*p++ = "-oi";
1107c478bdstevel@tonic-gate	*p++ = "--";		/* extra protection: end of argument list */
1117c478bdstevel@tonic-gate
1127c478bdstevel@tonic-gate	for (to = &(list->recip_list); to; to = to->next)
1137c478bdstevel@tonic-gate		if (to->name)
1147c478bdstevel@tonic-gate			*p++ = to->name;
1157c478bdstevel@tonic-gate
1167c478bdstevel@tonic-gate	*p = NULL;
1177c478bdstevel@tonic-gate
1187c478bdstevel@tonic-gate	fp = popenvp(sendmail_prog, argv, "w", 0);
1197c478bdstevel@tonic-gate
1207c478bdstevel@tonic-gate	free(argv);
1217c478bdstevel@tonic-gate
1227c478bdstevel@tonic-gate	if (fp == NULL)
1237c478bdstevel@tonic-gate		return (1);
1247c478bdstevel@tonic-gate
1257c478bdstevel@tonic-gate	copylet(letnum, fp, ORDINARY);
1267c478bdstevel@tonic-gate	rc = pclosevp(fp);
1277c478bdstevel@tonic-gate	if (!rc)
1287c478bdstevel@tonic-gate		return (0);
1297c478bdstevel@tonic-gate	else
1307c478bdstevel@tonic-gate		return (1);
1317c478bdstevel@tonic-gate}
1327c478bdstevel@tonic-gate
1337c478bdstevel@tonic-gate/*
1347c478bdstevel@tonic-gate * send_mbox(user, letnum)  Sends the letter specified by letnum to the
1357c478bdstevel@tonic-gate *	"user"'s mailbox. It returns 1 if the sending fails;
1367c478bdstevel@tonic-gate *	0 on success.
1377c478bdstevel@tonic-gate */
1387c478bdstevel@tonic-gate
1397c478bdstevel@tonic-gate
1407c478bdstevel@tonic-gate
1417c478bdstevel@tonic-gateint
142b7d62afceasthasend_mbox(char *mbox, int letnum)
1437c478bdstevel@tonic-gate{
1447c478bdstevel@tonic-gate	char file[PATH_MAX];
1457c478bdstevel@tonic-gate	char biffmsg[PATH_MAX];
1467c478bdstevel@tonic-gate	int mbfd;
1477c478bdstevel@tonic-gate	FILE *malf;
1487c478bdstevel@tonic-gate	int rc;
1497c478bdstevel@tonic-gate	uid_t useruid, saved_uid;
1507c478bdstevel@tonic-gate	void (*istat)(), (*qstat)(), (*hstat)();
1517c478bdstevel@tonic-gate
1527c478bdstevel@tonic-gate	if (!islocal(mbox, &useruid))
1537c478bdstevel@tonic-gate		return (1);
1547c478bdstevel@tonic-gate	(void) strlcpy(file, maildir, sizeof (file));
1557c478bdstevel@tonic-gate	if (strlcat(file, mbox, sizeof (file)) >= sizeof (file)) {
1567c478bdstevel@tonic-gate		rc = FALSE;
1577c478bdstevel@tonic-gate		goto done;
1587c478bdstevel@tonic-gate	}
1597c478bdstevel@tonic-gate
1607c478bdstevel@tonic-gate	/*
1617c478bdstevel@tonic-gate	 * We need to setgid and seteuid here since the users's mail box
1627c478bdstevel@tonic-gate	 * might be NFS mounted and since root can't write across NFS.
1637c478bdstevel@tonic-gate	 * Note this won't work with Secure NFS/RPC's.  Since delivering to
1647c478bdstevel@tonic-gate	 * NFS mounted directories isn't really supported that's OK for now.
1657c478bdstevel@tonic-gate	 */
1667c478bdstevel@tonic-gate	setgid(mailgrp);
1677c478bdstevel@tonic-gate	saved_uid = geteuid();
1687c478bdstevel@tonic-gate	seteuid(useruid);
1697c478bdstevel@tonic-gate	lock(mbox);
1707c478bdstevel@tonic-gate
1717c478bdstevel@tonic-gate	/* ignore signals */
1727c478bdstevel@tonic-gate	istat = signal(SIGINT, SIG_IGN);
1737c478bdstevel@tonic-gate	qstat = signal(SIGQUIT, SIG_IGN);
1747c478bdstevel@tonic-gate	hstat = signal(SIGHUP, SIG_IGN);
1757c478bdstevel@tonic-gate	/* now access mail box */
1767c478bdstevel@tonic-gate	mbfd = accessmf(file);
1777c478bdstevel@tonic-gate	if (mbfd == -1) {	/* mail box access failed, bail out */
1787c478bdstevel@tonic-gate		unlock();
1797c478bdstevel@tonic-gate		rc = FALSE;
1807c478bdstevel@tonic-gate		sav_errno = EACCES;
1817c478bdstevel@tonic-gate		goto done;
1827c478bdstevel@tonic-gate	} else {
1837c478bdstevel@tonic-gate				/* mail box is ok, now do append */
1847c478bdstevel@tonic-gate		if ((malf = fdopen(mbfd, "a")) != NULL) {
1857c478bdstevel@tonic-gate			(void) snprintf(biffmsg, sizeof (biffmsg),
1867c478bdstevel@tonic-gate			    "%s@%d\n", mbox, ftell(malf));
1877c478bdstevel@tonic-gate			rc = copylet(letnum, malf, ORDINARY);
1887c478bdstevel@tonic-gate			fclose(malf);
1897c478bdstevel@tonic-gate		}
1907c478bdstevel@tonic-gate	}
1917c478bdstevel@tonic-gate
1927c478bdstevel@tonic-gate	if (rc == FALSE)
1937c478bdstevel@tonic-gate		fprintf(stderr, "%s: Cannot append to %s\n", program, file);
1947c478bdstevel@tonic-gate	else
1957c478bdstevel@tonic-gate		notifybiff(biffmsg);
1967c478bdstevel@tonic-gate
1977c478bdstevel@tonic-gatedone:
1987c478bdstevel@tonic-gate	/* restore signal */
1997c478bdstevel@tonic-gate	(void) signal(SIGINT, istat);
2007c478bdstevel@tonic-gate	(void) signal(SIGQUIT, qstat);
2017c478bdstevel@tonic-gate	(void) signal(SIGHUP, hstat);
2027c478bdstevel@tonic-gate	unlock();
2037c478bdstevel@tonic-gate	seteuid(saved_uid);
2047c478bdstevel@tonic-gate	return (rc);
2057c478bdstevel@tonic-gate}
2067c478bdstevel@tonic-gate
2077c478bdstevel@tonic-gate#include <sys/socket.h>
2087c478bdstevel@tonic-gate#include <netinet/in.h>
2097c478bdstevel@tonic-gate
210b7d62afceasthastatic void
211b7d62afceasthanotifybiff(char *msg)
2127c478bdstevel@tonic-gate{
2137c478bdstevel@tonic-gate	static struct sockaddr_in addr;
2147c478bdstevel@tonic-gate	static int f = -1;
2157c478bdstevel@tonic-gate
2167c478bdstevel@tonic-gate	if (addr.sin_family == 0) {
2177c478bdstevel@tonic-gate		addr.sin_family = AF_INET;
2187c478bdstevel@tonic-gate		addr.sin_addr.s_addr = INADDR_LOOPBACK;
2197c478bdstevel@tonic-gate		addr.sin_port = htons(IPPORT_BIFFUDP);
2207c478bdstevel@tonic-gate	}
2217c478bdstevel@tonic-gate	if (f < 0)
2227c478bdstevel@tonic-gate		f = socket(AF_INET, SOCK_DGRAM, 0);
2237c478bdstevel@tonic-gate	sendto(f, msg, strlen(msg)+1, 0, (struct sockaddr *)&addr,
2247c478bdstevel@tonic-gate		sizeof (addr));
2257c478bdstevel@tonic-gate}
226