Mercurial > dovecot > core-2.2
annotate src/lib/safe-mkstemp.c @ 22664:fea53c2725c0
director: Fix director_max_parallel_moves/kicks type
Should be uint, not time.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 09 Nov 2017 12:24:16 +0200 |
parents | 2e2563132d5f |
children | cb108f786fb4 |
rev | line source |
---|---|
21390
2e2563132d5f
Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
20747
diff
changeset
|
1 /* Copyright (c) 2007-2017 Dovecot authors, see the included COPYING file */ |
5542 | 2 |
3 #include "lib.h" | |
4 #include "str.h" | |
5 #include "hex-binary.h" | |
6 #include "randgen.h" | |
7 #include "hostpid.h" | |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
8 #include "eacces-error.h" |
5542 | 9 #include "safe-mkstemp.h" |
10 | |
11 #include <unistd.h> | |
12 #include <fcntl.h> | |
13 #include <sys/stat.h> | |
14 | |
14629
c93ca5e46a8a
Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
15 static int ATTR_NULL(5) |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
16 safe_mkstemp_full(string_t *prefix, mode_t mode, uid_t uid, gid_t gid, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
17 const char *gid_origin) |
5542 | 18 { |
19 size_t prefix_len; | |
20 struct stat st; | |
21 unsigned char randbuf[8]; | |
9191
92d0383cc323
safe_mkstemp()'s mode parameter didn't override umask as it was supposed to.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
22 mode_t old_umask; |
5542 | 23 int fd; |
24 | |
25 prefix_len = str_len(prefix); | |
26 for (;;) { | |
27 do { | |
28 random_fill_weak(randbuf, sizeof(randbuf)); | |
29 str_truncate(prefix, prefix_len); | |
30 str_append(prefix, | |
31 binary_to_hex(randbuf, sizeof(randbuf))); | |
32 } while (lstat(str_c(prefix), &st) == 0); | |
33 | |
34 if (errno != ENOENT) { | |
35 i_error("stat(%s) failed: %m", str_c(prefix)); | |
9583
3f32abc198d6
safe_mkstemp*(): Truncate prefix to original length if creation failed.
Timo Sirainen <tss@iki.fi>
parents:
9537
diff
changeset
|
36 str_truncate(prefix, prefix_len); |
5542 | 37 return -1; |
38 } | |
39 | |
9191
92d0383cc323
safe_mkstemp()'s mode parameter didn't override umask as it was supposed to.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
40 old_umask = umask(0666 ^ mode); |
92d0383cc323
safe_mkstemp()'s mode parameter didn't override umask as it was supposed to.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
41 fd = open(str_c(prefix), O_RDWR | O_EXCL | O_CREAT, 0666); |
92d0383cc323
safe_mkstemp()'s mode parameter didn't override umask as it was supposed to.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
42 umask(old_umask); |
5542 | 43 if (fd != -1) |
44 break; | |
45 | |
46 if (errno != EEXIST) { | |
7343 | 47 if (errno != ENOENT && errno != EACCES) |
6775 | 48 i_error("open(%s) failed: %m", str_c(prefix)); |
9583
3f32abc198d6
safe_mkstemp*(): Truncate prefix to original length if creation failed.
Timo Sirainen <tss@iki.fi>
parents:
9537
diff
changeset
|
49 str_truncate(prefix, prefix_len); |
5542 | 50 return -1; |
51 } | |
52 } | |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
53 if (uid == (uid_t)-1 && gid == (gid_t)-1) |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
54 return fd; |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
55 |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
56 if (fchown(fd, uid, gid) < 0) { |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
57 if (errno == EPERM) { |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
58 i_error("%s", eperm_error_get_chgrp("fchown", |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
59 str_c(prefix), gid, gid_origin)); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
60 } else { |
8032
fa2bd47fc59c
safe_mkstemp(): If fchown() fails, log the used uid/gid.
Timo Sirainen <tss@iki.fi>
parents:
7343
diff
changeset
|
61 i_error("fchown(%s, %ld, %ld) failed: %m", |
fa2bd47fc59c
safe_mkstemp(): If fchown() fails, log the used uid/gid.
Timo Sirainen <tss@iki.fi>
parents:
7343
diff
changeset
|
62 str_c(prefix), |
fa2bd47fc59c
safe_mkstemp(): If fchown() fails, log the used uid/gid.
Timo Sirainen <tss@iki.fi>
parents:
7343
diff
changeset
|
63 uid == (uid_t)-1 ? -1L : (long)uid, |
fa2bd47fc59c
safe_mkstemp(): If fchown() fails, log the used uid/gid.
Timo Sirainen <tss@iki.fi>
parents:
7343
diff
changeset
|
64 gid == (gid_t)-1 ? -1L : (long)gid); |
5542 | 65 } |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14687
diff
changeset
|
66 i_close_fd(&fd); |
19136
fefaa6d09a81
Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
67 i_unlink(str_c(prefix)); |
20747
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
68 str_truncate(prefix, prefix_len); |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
69 return -1; |
5542 | 70 } |
71 return fd; | |
72 } | |
73 | |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
74 int safe_mkstemp(string_t *prefix, mode_t mode, uid_t uid, gid_t gid) |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
75 { |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
76 return safe_mkstemp_full(prefix, mode, uid, gid, NULL); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
77 } |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
78 |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
79 int safe_mkstemp_group(string_t *prefix, mode_t mode, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
80 gid_t gid, const char *gid_origin) |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
81 { |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
82 return safe_mkstemp_full(prefix, mode, (uid_t)-1, gid, gid_origin); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
83 } |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
84 |
5542 | 85 int safe_mkstemp_hostpid(string_t *prefix, mode_t mode, uid_t uid, gid_t gid) |
86 { | |
20747
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
87 size_t orig_prefix_len = str_len(prefix); |
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
88 int fd; |
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
89 |
5542 | 90 str_printfa(prefix, "%s.%s.", my_hostname, my_pid); |
20747
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
91 if ((fd = safe_mkstemp(prefix, mode, uid, gid)) == -1) |
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
92 str_truncate(prefix, orig_prefix_len); |
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
93 return fd; |
5542 | 94 } |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
95 |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
96 int safe_mkstemp_hostpid_group(string_t *prefix, mode_t mode, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
97 gid_t gid, const char *gid_origin) |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
98 { |
20747
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
99 size_t orig_prefix_len = str_len(prefix); |
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
100 int fd; |
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
101 |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
102 str_printfa(prefix, "%s.%s.", my_hostname, my_pid); |
20747
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
103 if ((fd = safe_mkstemp_group(prefix, mode, gid, gid_origin)) == -1) |
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
104 str_truncate(prefix, orig_prefix_len); |
0f5809a9f137
lib: safe_mkstemp*() didn't always truncate prefix back to original on failure.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
105 return fd; |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9191
diff
changeset
|
106 } |