Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/safe-mkstemp.c @ 9490:fd84592e817b HEAD
dovecot-example.conf: Updated dict comments.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 23 Nov 2009 13:08:47 -0500 |
parents | 644b956f5f5a |
children | 00cd9aacd03c |
rev | line source |
---|---|
8590
b9faf4db2a9f
Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents:
8032
diff
changeset
|
1 /* Copyright (c) 2007-2009 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" | |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
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 | |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
15 static int |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
16 safe_mkstemp_full(string_t *prefix, mode_t mode, uid_t uid, gid_t gid, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
17 const char *gid_origin) |
5542 | 18 { |
19 size_t prefix_len; | |
20 struct stat st; | |
21 unsigned char randbuf[8]; | |
9001
5302ce189a70
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)); | |
9206
644b956f5f5a
safe_mkstemp*(): Truncate prefix to original length if creation failed.
Timo Sirainen <tss@iki.fi>
parents:
9168
diff
changeset
|
36 str_truncate(prefix, prefix_len); |
5542 | 37 return -1; |
38 } | |
39 | |
9001
5302ce189a70
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); |
5302ce189a70
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); |
5302ce189a70
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)); |
9206
644b956f5f5a
safe_mkstemp*(): Truncate prefix to original length if creation failed.
Timo Sirainen <tss@iki.fi>
parents:
9168
diff
changeset
|
49 str_truncate(prefix, prefix_len); |
5542 | 50 return -1; |
51 } | |
52 } | |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
53 if (uid == (uid_t)-1 && gid == (gid_t)-1) |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
54 return fd; |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
55 |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
56 if (fchown(fd, uid, gid) < 0) { |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
57 if (errno == EPERM) { |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
58 i_error("%s", eperm_error_get_chgrp("fchown", |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
59 str_c(prefix), gid, gid_origin)); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
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 } |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
66 (void)close(fd); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
67 (void)unlink(str_c(prefix)); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
68 return -1; |
5542 | 69 } |
70 return fd; | |
71 } | |
72 | |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
73 int safe_mkstemp(string_t *prefix, mode_t mode, uid_t uid, gid_t gid) |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
74 { |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
75 return safe_mkstemp_full(prefix, mode, uid, gid, NULL); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
76 } |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
77 |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
78 int safe_mkstemp_group(string_t *prefix, mode_t mode, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
79 gid_t gid, const char *gid_origin) |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
80 { |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
81 return safe_mkstemp_full(prefix, mode, (uid_t)-1, gid, gid_origin); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
82 } |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
83 |
5542 | 84 int safe_mkstemp_hostpid(string_t *prefix, mode_t mode, uid_t uid, gid_t gid) |
85 { | |
86 str_printfa(prefix, "%s.%s.", my_hostname, my_pid); | |
87 return safe_mkstemp(prefix, mode, uid, gid); | |
88 } | |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
89 |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
90 int safe_mkstemp_hostpid_group(string_t *prefix, mode_t mode, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
91 gid_t gid, const char *gid_origin) |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
92 { |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
93 str_printfa(prefix, "%s.%s.", my_hostname, my_pid); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
94 return safe_mkstemp_group(prefix, mode, gid, gid_origin); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9001
diff
changeset
|
95 } |