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