Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/safe-mkdir.c @ 1329:ae229b7acb4c HEAD
Mailbox names are now sent through imap-quoter instead of just escaping it.
This means that mailbox names that would require escapes are instead sent
as literals now.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 02 Apr 2003 05:05:38 +0300 |
parents | 500ec0ec3b85 |
children | 9df02b1533b3 |
rev | line source |
---|---|
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
1 /* |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 Copyright (c) 2002 Timo Sirainen |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 Permission is hereby granted, free of charge, to any person obtaining |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 a copy of this software and associated documentation files (the |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 "Software"), to deal in the Software without restriction, including |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 without limitation the rights to use, copy, modify, merge, publish, |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 distribute, sublicense, and/or sell copies of the Software, and to |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 permit persons to whom the Software is furnished to do so, subject to |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 the following conditions: |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 The above copyright notice and this permission notice shall be |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 included in all copies or substantial portions of the Software. |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 */ |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 #include "lib.h" |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 #include "safe-mkdir.h" |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 #include <sys/stat.h> |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 #include <unistd.h> |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
29 #include <fcntl.h> |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
30 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
31 int safe_mkdir(const char *dir, mode_t mode, uid_t uid, gid_t gid) |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 { |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 struct stat st; |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
34 int fd, ret = 1; |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 if (lstat(dir, &st) < 0) { |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
37 if (errno != ENOENT) |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 i_fatal("lstat() failed for %s: %m", dir); |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 if (mkdir(dir, mode) < 0) |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 i_fatal("Can't create directory %s: %m", dir); |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
42 } else { |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
43 /* already exists. */ |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
44 ret = 2; |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
45 } |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
47 /* use fchown() and fchmod() just to make sure we aren't following |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
48 symbolic links. */ |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
49 fd = open(dir, O_RDONLY); |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
50 if (fd == -1) |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
51 i_fatal("open() failed for %s: %m", dir); |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
52 |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
53 if (fstat(fd, &st) < 0) |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
54 i_fatal("fstat() failed for %s: %m", dir); |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
56 if (!S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)) |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
57 i_fatal("Not a directory %s", dir); |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
58 |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
59 if (st.st_uid != uid || st.st_gid != gid) { |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
60 if (fchown(fd, uid, gid) < 0) |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
61 i_fatal("fchown() failed for %s: %m", dir); |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
62 ret = 0; |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
63 } |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
65 if ((st.st_mode & 07777) != mode) { |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
66 if (fchmod(fd, mode) < 0) |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
67 i_fatal("chmod() failed for %s: %m", dir); |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
68 ret = 0; |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 } |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
71 if (close(fd) < 0) |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
72 i_fatal("close() failed for %s: %m", dir); |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
73 |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 /* make sure we succeeded in everything. chown() and chmod() |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 are racy: user owned 0777 file - change either and the user |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
76 can still change it back. */ |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
77 if (lstat(dir, &st) < 0) |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 i_fatal("lstat() check failed for %s: %m", dir); |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
80 if (!S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)) |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
81 i_fatal("Not a directory %s", dir); |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 |
823
d00ce0e4de7f
Whops, should have tested it :) Mode check always failed.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
83 if ((st.st_mode & 07777) != mode) { |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 i_fatal("safe_mkdir() failed: %s (%o) is still not mode %o", |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 dir, (int)st.st_mode, (int)mode); |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 } |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 if (st.st_uid != uid || st.st_gid != gid) { |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 i_fatal("safe_mkdir() failed: %s (%s, %s) " |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 "is still not owned by %s.%s", |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 dir, dec2str(st.st_uid), dec2str(st.st_gid), |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 dec2str(uid), dec2str(gid)); |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 } |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 return ret; |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 } |