lockspool.c revision 1.15
1/*	$OpenBSD: lockspool.c,v 1.15 2008/10/01 20:32:44 millert Exp $	*/
2
3/*
4 * Copyright (c) 1998 Theo de Raadt <deraadt@theos.com>
5 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef lint
30static const char rcsid[] = "$OpenBSD: lockspool.c,v 1.15 2008/10/01 20:32:44 millert Exp $";
31#endif /* not lint */
32
33#include <signal.h>
34#include <pwd.h>
35#include <syslog.h>
36#include <unistd.h>
37#include <errno.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <poll.h>
41#include "mail.local.h"
42
43void unhold(int);
44void usage(void);
45
46extern char *__progname;
47
48int
49main(int argc, char *argv[])
50{
51	struct passwd *pw;
52	struct pollfd pfd;
53	ssize_t nread;
54	char *from, c;
55	int holdfd;
56
57	openlog(__progname, LOG_PERROR, LOG_MAIL);
58
59	if (argc != 1 && argc != 2)
60		usage();
61	if (argc == 2 && getuid() != 0)
62		merr(FATAL, "you must be root to lock someone else's spool");
63
64	signal(SIGTERM, unhold);
65	signal(SIGINT, unhold);
66	signal(SIGHUP, unhold);
67	signal(SIGPIPE, unhold);
68
69	if (argc == 2)
70		pw = getpwnam(argv[1]);
71	else
72		pw = getpwuid(getuid());
73	if (pw == NULL)
74		exit (1);
75	from = pw->pw_name;
76
77	holdfd = getlock(from, pw);
78	if (holdfd == -1) {
79		write(STDOUT_FILENO, "0\n", 2);
80		exit (1);
81	}
82	write(STDOUT_FILENO, "1\n", 2);
83
84	/* wait for the other end of the pipe to close, then release the lock */
85	pfd.fd = STDIN_FILENO;
86	pfd.events = POLLIN;
87	do {
88		if (poll(&pfd, 1, INFTIM) == -1) {
89			if (errno != EINTR)
90				break;
91		}
92		do {
93			nread = read(STDIN_FILENO, &c, 1);
94		} while (nread == 1 || (nread == -1 && errno == EINTR));
95	} while (nread == -1 && errno == EAGAIN);
96	rellock();
97	exit (0);
98}
99
100/*ARGSUSED*/
101void
102unhold(int signo)
103{
104
105	rellock();
106	_exit(0);
107}
108
109void
110usage(void)
111{
112
113	merr(FATAL, "usage: %s [username]", __progname);
114}
115