xref: /openbsd/libexec/mail.local/locking.c (revision da07b1a3)
1 /*	$OpenBSD: locking.c,v 1.15 2020/05/27 03:12:06 millert Exp $	*/
2 
3 /*
4  * Copyright (c) 1996-1998 Theo de Raadt <deraadt@theos.com>
5  * Copyright (c) 1996-1998 David Mazieres <dm@lcs.mit.edu>
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  * 3. The name of the authors may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
22  * THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <pwd.h>
35 #include <syslog.h>
36 #include <unistd.h>
37 #include <limits.h>
38 #include <errno.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <stdarg.h>
43 #include "pathnames.h"
44 #include "mail.local.h"
45 
46 static char lpath[PATH_MAX];
47 
48 void
rellock(void)49 rellock(void)
50 {
51 
52 	if (lpath[0])
53 		unlink(lpath);
54 }
55 
56 int
getlock(const char * name,struct passwd * pw)57 getlock(const char *name, struct passwd *pw)
58 {
59 	struct stat sb;
60 	int lfd=-1;
61 	int tries = 0;
62 
63 	(void)snprintf(lpath, sizeof lpath, "%s/%s.lock",
64 	    _PATH_MAILDIR, name);
65 
66 	if (stat(_PATH_MAILDIR, &sb) != -1 &&
67 	    (sb.st_mode & S_IWOTH) == S_IWOTH) {
68 		mwarn("%s: will not deliver to world-writable spool",
69 		    _PATH_MAILDIR);
70 	} else {
71 		/*
72 		 * Only root can write the spool directory.
73 		 */
74 		while (1) {
75 			if ((lfd = open(lpath, O_CREAT|O_WRONLY|O_EXCL,
76 			    S_IRUSR|S_IWUSR)) != -1)
77 				break;
78 			if (tries > 9) {
79 				mwarn("%s: %s", lpath, strerror(errno));
80 				return(-1);
81 			}
82 			sleep(1U << tries);
83 			tries++;
84 		}
85 	}
86 	return(lfd);
87 }
88 
89 void
mwarn(const char * fmt,...)90 mwarn(const char *fmt, ...)
91 {
92 	va_list ap;
93 
94 	va_start(ap, fmt);
95 	vsyslog(LOG_ERR, fmt, ap);
96 	va_end(ap);
97 }
98 
99 void
merr(int eval,const char * fmt,...)100 merr(int eval, const char *fmt, ...)
101 {
102 	va_list ap;
103 
104 	va_start(ap, fmt);
105 	vsyslog(LOG_ERR, fmt, ap);
106 	va_end(ap);
107 	exit(eval);
108 }
109