mirror of
https://github.com/openbsd/src.git
synced 2026-04-27 23:56:05 +00:00
Allow mail.local to be run as non-root.
If mail.local is invoked by a non-root user, open a pipe to lockspool(1) for file locking. It is only possible to delivery to a pre-existing mail spool when running mail.local as non-root. OK gilles@ deraadt@
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: locking.c,v 1.12 2015/01/16 06:39:50 deraadt Exp $ */
|
||||
/* $OpenBSD: locking.c,v 1.13 2020/02/02 23:17:09 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-1998 Theo de Raadt <deraadt@theos.com>
|
||||
@@ -55,7 +55,7 @@ rellock(void)
|
||||
}
|
||||
|
||||
int
|
||||
getlock(char *name, struct passwd *pw)
|
||||
getlock(const char *name, struct passwd *pw)
|
||||
{
|
||||
struct stat sb, fsb;
|
||||
int lfd=-1;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: mail.local.c,v 1.36 2019/06/28 13:32:53 deraadt Exp $ */
|
||||
/* $OpenBSD: mail.local.c,v 1.37 2020/02/02 23:17:09 millert Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996-1998 Theo de Raadt <deraadt@theos.com>
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <netinet/in.h>
|
||||
#include <syslog.h>
|
||||
#include <fcntl.h>
|
||||
@@ -46,6 +47,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include "pathnames.h"
|
||||
#include "mail.local.h"
|
||||
|
||||
@@ -92,8 +94,6 @@ main(int argc, char *argv[])
|
||||
} else {
|
||||
if (!*argv)
|
||||
usage();
|
||||
if (geteuid() != 0)
|
||||
merr(FATAL, "may only be run by the superuser");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -188,7 +188,7 @@ deliver(int fd, char *name, int lockfile)
|
||||
(void)snprintf(path, sizeof path, "%s/%s", _PATH_MAILDIR, name);
|
||||
|
||||
if (lockfile) {
|
||||
lfd = getlock(name, pw);
|
||||
lfd = lockspool(name, pw);
|
||||
if (lfd == -1)
|
||||
return (1);
|
||||
}
|
||||
@@ -270,10 +270,8 @@ retry:
|
||||
}
|
||||
|
||||
bad:
|
||||
if (lfd != -1) {
|
||||
rellock();
|
||||
close(lfd);
|
||||
}
|
||||
if (lfd != -1)
|
||||
unlockspool();
|
||||
|
||||
if (mbfd != -1) {
|
||||
(void)fsync(mbfd); /* Don't wait for update. */
|
||||
@@ -328,6 +326,65 @@ notifybiff(char *msg)
|
||||
merr(NOTFATAL, "sendto biff: %s", strerror(errno));
|
||||
}
|
||||
|
||||
static int lockfd = -1;
|
||||
static pid_t lockpid = -1;
|
||||
|
||||
int
|
||||
lockspool(const char *name, struct passwd *pw)
|
||||
{
|
||||
int pfd[2];
|
||||
char ch;
|
||||
|
||||
if (geteuid() == 0)
|
||||
return getlock(name, pw);
|
||||
|
||||
/* If not privileged, open pipe to lockspool(1) instead */
|
||||
if (pipe2(pfd, O_CLOEXEC) == -1) {
|
||||
merr(FATAL, "pipe: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
switch ((lockpid = fork())) {
|
||||
case -1:
|
||||
merr(FATAL, "fork: %s", strerror(errno));
|
||||
return -1;
|
||||
case 0:
|
||||
/* child */
|
||||
close(pfd[0]);
|
||||
dup2(pfd[1], STDOUT_FILENO);
|
||||
execl(_PATH_LOCKSPOOL, "lockspool", (char *)NULL);
|
||||
merr(FATAL, "execl: lockspool: %s", strerror(errno));
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
default:
|
||||
/* parent */
|
||||
close(pfd[1]);
|
||||
lockfd = pfd[0];
|
||||
break;
|
||||
}
|
||||
|
||||
if (read(lockfd, &ch, 1) != 1 || ch != '1') {
|
||||
unlockspool();
|
||||
merr(FATAL, "lockspool: unable to get lock");
|
||||
}
|
||||
|
||||
return lockfd;
|
||||
}
|
||||
|
||||
void
|
||||
unlockspool(void)
|
||||
{
|
||||
if (lockpid != -1) {
|
||||
waitpid(lockpid, NULL, 0);
|
||||
lockpid = -1;
|
||||
} else {
|
||||
rellock();
|
||||
}
|
||||
close(lockfd);
|
||||
lockfd = -1;
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: mail.local.h,v 1.5 2006/04/01 22:48:57 deraadt Exp $ */
|
||||
/* $OpenBSD: mail.local.h,v 1.6 2020/02/02 23:17:09 millert Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
@@ -35,8 +35,10 @@
|
||||
void baditem(char *);
|
||||
int deliver(int, char *, int);
|
||||
void merr(int, const char *, ...);
|
||||
int getlock(char *, struct passwd *);
|
||||
int getlock(const char *, struct passwd *);
|
||||
void notifybiff(char *);
|
||||
void rellock(void);
|
||||
int storemail(char *);
|
||||
int lockspool(const char *, struct passwd *);
|
||||
void unlockspool(void);
|
||||
void usage(void);
|
||||
|
||||
Reference in New Issue
Block a user