summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1998-08-15 21:04:36 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1998-08-15 21:04:36 +0000
commit7931b8588f564d72815d8ccdd897665d7d0e1fbe (patch)
tree856f54a2c6fe8787fa78afb17d82621f08243974 /libexec
parent419d35e63268d3263b1b2192a4e4d85e883ae103 (diff)
Break out locking code into its own file so it can be shared with lockspool.
Call lockspool when invoked with -H flag for backward compatibility.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/mail.local/Makefile3
-rw-r--r--libexec/mail.local/locking.c191
-rw-r--r--libexec/mail.local/mail.local.814
-rw-r--r--libexec/mail.local/mail.local.c227
-rw-r--r--libexec/mail.local/mail.local.h46
-rw-r--r--libexec/mail.local/pathnames.h3
6 files changed, 263 insertions, 221 deletions
diff --git a/libexec/mail.local/Makefile b/libexec/mail.local/Makefile
index f61891cb428..5226f554de9 100644
--- a/libexec/mail.local/Makefile
+++ b/libexec/mail.local/Makefile
@@ -1,7 +1,8 @@
# from: @(#)Makefile 5.3 (Berkeley) 1/17/91
-# $Id: Makefile,v 1.1 1995/10/18 08:43:19 deraadt Exp $
+# $OpenBSD: Makefile,v 1.2 1998/08/15 21:04:31 millert Exp $
PROG= mail.local
+SRCS= mail.local.c locking.c
MAN= mail.local.8
BINOWN= root
BINMODE=4555
diff --git a/libexec/mail.local/locking.c b/libexec/mail.local/locking.c
new file mode 100644
index 00000000000..c0a4b8e95c4
--- /dev/null
+++ b/libexec/mail.local/locking.c
@@ -0,0 +1,191 @@
+/* $OpenBSD: locking.c,v 1.1 1998/08/15 21:04:33 millert Exp $ */
+
+/*
+ * Copyright (c) 1996-1998 Theo de Raadt <deraadt@theos.com>
+ * Copyright (c) 1996-1998 David Mazieres <dm@lcs.mit.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$OpenBSD: locking.c,v 1.1 1998/08/15 21:04:33 millert Exp $";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include "pathnames.h"
+#include "mail.local.h"
+
+static char lpath[MAXPATHLEN];
+
+void
+rellock()
+{
+
+ if (lpath[0])
+ unlink(lpath);
+}
+
+int
+getlock(name, pw)
+ char *name;
+ struct passwd *pw;
+{
+ struct stat sb, fsb;
+ int lfd=-1;
+ char buf[8*1024];
+ int tries = 0;
+
+ (void)snprintf(lpath, sizeof lpath, "%s/%s.lock",
+ _PATH_MAILDIR, name);
+
+ if (stat(_PATH_MAILDIR, &sb) != -1 &&
+ (sb.st_mode & S_IWOTH) == S_IWOTH) {
+ /*
+ * We have a writeable spool, deal with it as
+ * securely as possible.
+ */
+ time_t ctim = -1;
+
+ seteuid(pw->pw_uid);
+ if (lstat(lpath, &sb) != -1)
+ ctim = sb.st_ctime;
+ while (1) {
+ /*
+ * Deal with existing user.lock files
+ * or directories or symbolic links that
+ * should not be here.
+ */
+ if (readlink(lpath, buf, sizeof buf-1) != -1) {
+ if (lstat(lpath, &sb) != -1 &&
+ S_ISLNK(fsb.st_mode)) {
+ seteuid(sb.st_uid);
+ unlink(lpath);
+ seteuid(pw->pw_uid);
+ }
+ goto again;
+ }
+ if ((lfd = open(lpath, O_CREAT|O_WRONLY|O_EXCL|O_EXLOCK,
+ S_IRUSR|S_IWUSR)) != -1)
+ break;
+again:
+ if (tries > 10) {
+ err(NOTFATAL, "%s: %s", lpath,
+ strerror(errno));
+ seteuid(0);
+ return(-1);
+ }
+ if (tries > 9 &&
+ (lfd = open(lpath, O_WRONLY|O_EXLOCK, 0)) != -1) {
+ if (fstat(lfd, &fsb) != -1 &&
+ lstat(lpath, &sb) != -1) {
+ if (fsb.st_dev == sb.st_dev &&
+ fsb.st_ino == sb.st_ino &&
+ ctim == fsb.st_ctime ) {
+ seteuid(fsb.st_uid);
+ baditem(lpath);
+ seteuid(pw->pw_uid);
+ }
+ }
+ }
+ sleep(1 << tries);
+ tries++;
+ continue;
+ }
+ seteuid(0);
+ } else {
+ /*
+ * Only root can write the spool directory.
+ */
+ while (1) {
+ if ((lfd = open(lpath, O_CREAT|O_WRONLY|O_EXCL,
+ S_IRUSR|S_IWUSR)) != -1)
+ break;
+ if (tries > 9) {
+ err(NOTFATAL, "%s: %s", lpath, strerror(errno));
+ return(-1);
+ }
+ sleep(1 << tries);
+ tries++;
+ }
+ }
+ return(lfd);
+}
+
+void
+baditem(path)
+ char *path;
+{
+ char npath[MAXPATHLEN];
+ int fd;
+
+ if (unlink(path) == 0)
+ return;
+ snprintf(npath, sizeof npath, "%s/mailXXXXXXXXXX", _PATH_MAILDIR);
+ if ((fd = mkstemp(npath)) == -1)
+ return;
+ (void)close(fd);
+ if (rename(path, npath) == -1)
+ unlink(npath);
+ else
+ err(NOTFATAL, "nasty spool item %s renamed to %s",
+ path, npath);
+ /* XXX if we fail to rename, another attempt will happen later */
+}
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#ifdef __STDC__
+err(int isfatal, const char *fmt, ...)
+#else
+err(isfatal, fmt)
+ int isfatal;
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ vsyslog(LOG_ERR, fmt, ap);
+ va_end(ap);
+ if (isfatal)
+ exit(1);
+}
diff --git a/libexec/mail.local/mail.local.8 b/libexec/mail.local/mail.local.8
index 4050f83d55d..cd6d244f876 100644
--- a/libexec/mail.local/mail.local.8
+++ b/libexec/mail.local/mail.local.8
@@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)mail.local.8 6.8 (Berkeley) 4/27/91
-.\" $Id: mail.local.8,v 1.12 1998/02/24 05:00:24 millert Exp $
+.\" $Id: mail.local.8,v 1.13 1998/08/15 21:04:33 millert Exp $
.\"
.Dd April 27, 1991
.Dt MAIL.LOCAL 8
@@ -43,7 +43,6 @@
.Op Fl L
.Op Fl l
.Op Fl f Ar from
-.Op Fl H
.Ar user ...
.Sh DESCRIPTION
.Nm Mail.local
@@ -69,17 +68,6 @@ Request that
.Fn flock
be used for locking the mail spool rather than
.Nm username.lock .
-.It Fl H
-This mode is useful for a client mail program to attain proper locking.
-In this mode
-.Nm mail.local
-(ignoring all other arguments) attains a
-.Nm username.lock
-for the calling user and retains it until stdin is closed or a signal
-like SIGINT, SIGTERM, or SIGHUP is received. If
-.Nm mail.local
-is able to create the lock file, ``1'' is written to stdout, otherwise
-``0'' is written and an error message is written to stderr.
.El
.Pp
Individual mail messages in the mailbox are delimited by an empty
diff --git a/libexec/mail.local/mail.local.c b/libexec/mail.local/mail.local.c
index dd59d84813a..76dfcabf6ae 100644
--- a/libexec/mail.local/mail.local.c
+++ b/libexec/mail.local/mail.local.c
@@ -1,4 +1,8 @@
+/* $OpenBSD: mail.local.c,v 1.19 1998/08/15 21:04:34 millert Exp $ */
+
/*-
+ * Copyright (c) 1996-1998 Theo de Raadt <deraadt@theos.com>
+ * Copyright (c) 1996-1998 David Mazieres <dm@lcs.mit.edu>
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
@@ -38,8 +42,11 @@ char copyright[] =
#endif /* not lint */
#ifndef lint
-/*static char sccsid[] = "from: @(#)mail.local.c 5.6 (Berkeley) 6/19/91";*/
-static char rcsid[] = "$Id: mail.local.c,v 1.18 1998/05/18 09:58:03 deraadt Exp $";
+#if 0
+static char sccsid[] = "from: @(#)mail.local.c 5.6 (Berkeley) 6/19/91";
+#else
+static char rcsid[] = "$OpenBSD: mail.local.c,v 1.19 1998/08/15 21:04:34 millert Exp $";
+#endif
#endif /* not lint */
#include <sys/param.h>
@@ -58,26 +65,13 @@ static char rcsid[] = "$Id: mail.local.c,v 1.18 1998/05/18 09:58:03 deraadt Exp
#include <stdlib.h>
#include <string.h>
#include "pathnames.h"
-
-#define FATAL 1
-#define NOTFATAL 0
-
-int deliver __P((int, char *, int));
-void err __P((int, const char *, ...));
-void notifybiff __P((char *));
-int store __P((char *));
-void usage __P((void));
-int dohold __P((void));
-int getlock __P((char *, struct passwd *));
-void rellock __P((void));
+#include "mail.local.h"
int
main(argc, argv)
int argc;
char **argv;
{
- extern int optind;
- extern char *optarg;
struct passwd *pw;
int ch, fd, eval, lockfile=1, holdme=0;
uid_t uid;
@@ -112,11 +106,16 @@ main(argc, argv)
argc -= optind;
argv += optind;
- if (!*argv && !holdme)
- usage();
-
- if (holdme)
- exit(dohold());
+ /* Support -H flag for backwards compat */
+ if (holdme) {
+ execl(_PATH_LOCKSPOOL, "lockspool", NULL);
+ err(FATAL, "execl: lockspool: %s", strerror(errno));
+ } else {
+ if (!*argv)
+ usage();
+ if (geteuid() != 0)
+ err(FATAL, "may only be run by the superuser");
+ }
/*
* If from not specified, use the name from getlogin() if the
@@ -134,50 +133,6 @@ main(argc, argv)
exit(eval);
}
-void
-unhold()
-{
- rellock();
- exit(0);
-}
-
-int
-dohold()
-{
- struct passwd *pw;
- char *from, c;
- int holdfd;
-
- signal(SIGTERM, unhold);
- signal(SIGINT, unhold);
- signal(SIGHUP, unhold);
-
- from = getlogin();
- if (from) {
- pw = getpwnam(from);
- if (pw == NULL)
- return (1);
- } else {
- pw = getpwuid(getuid());
- if (pw)
- from = pw->pw_name;
- else
- return (1);
- }
-
- holdfd = getlock(from, pw);
- if (holdfd == -1) {
- write(STDOUT_FILENO, "0\n", 2);
- return (1);
- }
- write(STDOUT_FILENO, "1\n", 2);
-
- while (read(0, &c, 1) == -1 && errno == EINTR)
- ;
- rellock();
- return (0);
-}
-
int
store(from)
char *from;
@@ -223,118 +178,6 @@ store(from)
return(fd);
}
-void
-baditem(path)
- char *path;
-{
- char npath[MAXPATHLEN];
-
- if (unlink(path) == 0)
- return;
- snprintf(npath, sizeof npath, "%s/mailXXXXXXXXXX", _PATH_MAILDIR);
- if (mktemp(npath) == NULL)
- return;
- if (rename(path, npath) != -1)
- err(NOTFATAL, "nasty spool item %s renamed to %s",
- path, npath);
- /* XXX if we fail to rename, another attempt will happen later */
-}
-
-char lpath[MAXPATHLEN];
-
-void
-rellock()
-{
- if (lpath[0])
- unlink(lpath);
-}
-
-int
-getlock(name, pw)
- char *name;
- struct passwd *pw;
-{
- struct stat sb, fsb;
- int lfd=-1;
- char buf[8*1024];
- int tries = 0;
-
- (void)snprintf(lpath, sizeof lpath, "%s/%s.lock",
- _PATH_MAILDIR, name);
-
- if (stat(_PATH_MAILDIR, &sb) != -1 &&
- (sb.st_mode & S_IWOTH) == S_IWOTH) {
- /*
- * We have a writeable spool, deal with it as
- * securely as possible.
- */
- time_t ctim = -1;
-
- seteuid(pw->pw_uid);
- if (lstat(lpath, &sb) != -1)
- ctim = sb.st_ctime;
- while (1) {
- /*
- * Deal with existing user.lock files
- * or directories or symbolic links that
- * should not be here.
- */
- if (readlink(lpath, buf, sizeof buf-1) != -1) {
- if (lstat(lpath, &sb) != -1 &&
- S_ISLNK(fsb.st_mode)) {
- seteuid(sb.st_uid);
- unlink(lpath);
- seteuid(pw->pw_uid);
- }
- goto again;
- }
- if ((lfd = open(lpath, O_CREAT|O_WRONLY|O_EXCL|O_EXLOCK,
- S_IRUSR|S_IWUSR)) != -1)
- break;
-again:
- if (tries > 10) {
- err(NOTFATAL, "%s: %s", lpath,
- strerror(errno));
- seteuid(0);
- return(-1);
- }
- if (tries > 9 &&
- (lfd = open(lpath, O_WRONLY|O_EXLOCK, 0)) != -1) {
- if (fstat(lfd, &fsb) != -1 &&
- lstat(lpath, &sb) != -1) {
- if (fsb.st_dev == sb.st_dev &&
- fsb.st_ino == sb.st_ino &&
- ctim == fsb.st_ctime ) {
- seteuid(fsb.st_uid);
- baditem(lpath);
- seteuid(pw->pw_uid);
- }
- }
- }
- sleep(1 << tries);
- tries++;
- continue;
- }
- seteuid(0);
- } else {
- /*
- * Only root can write the spool directory.
- */
- while (1) {
- if ((lfd = open(lpath, O_CREAT|O_WRONLY|O_EXCL,
- S_IRUSR|S_IWUSR)) != -1)
- break;
- if (tries > 9) {
- err(NOTFATAL, "%s: %s", lpath, strerror(errno));
- return(-1);
- }
- sleep(1 << tries);
- tries++;
- }
- }
- return (lfd);
-}
-
int
deliver(fd, name, lockfile)
int fd;
@@ -492,33 +335,5 @@ notifybiff(msg)
void
usage()
{
- err(FATAL, "usage: mail.local [-lLH] [-f from] user ...");
-}
-
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-void
-#ifdef __STDC__
-err(int isfatal, const char *fmt, ...)
-#else
-err(isfatal, fmt)
- int isfatal;
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
-#ifdef __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- vsyslog(LOG_ERR, fmt, ap);
- va_end(ap);
- if (isfatal)
- exit(1);
+ err(FATAL, "usage: mail.local [-lL] [-f from] user ...");
}
diff --git a/libexec/mail.local/mail.local.h b/libexec/mail.local/mail.local.h
new file mode 100644
index 00000000000..8e13010818d
--- /dev/null
+++ b/libexec/mail.local/mail.local.h
@@ -0,0 +1,46 @@
+/* $OpenBSD: mail.local.h,v 1.1 1998/08/15 21:04:35 millert Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define FATAL 1
+#define NOTFATAL 0
+
+void baditem __P((char *));
+int deliver __P((int, char *, int));
+void err __P((int, const char *, ...));
+int getlock __P((char *, struct passwd *));
+void notifybiff __P((char *));
+void rellock __P((void));
+int store __P((char *));
+void usage __P((void));
diff --git a/libexec/mail.local/pathnames.h b/libexec/mail.local/pathnames.h
index ed790d93196..db5c1b2941b 100644
--- a/libexec/mail.local/pathnames.h
+++ b/libexec/mail.local/pathnames.h
@@ -31,8 +31,9 @@
* SUCH DAMAGE.
*
* from: @(#)pathnames.h 5.3 (Berkeley) 1/17/91
- * $Id: pathnames.h,v 1.2 1998/02/24 04:52:53 millert Exp $
+ * $Id: pathnames.h,v 1.3 1998/08/15 21:04:35 millert Exp $
*/
#include <paths.h>
#define _PATH_LOCTMP "/tmp/local.XXXXXXXXXX"
+#define _PATH_LOCKSPOOL "/usr/libexec/lockspool"