Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/safe-mkdir.c @ 1742:05427d8112ee HEAD
comment updates. it's not possible to change the file mode if you're not the
owner..
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 27 Aug 2003 01:15:36 +0300 |
parents | 9df02b1533b3 |
children | fa7353daa44f |
rev | line source |
---|---|
1741
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1263
diff
changeset
|
1 /* Copyright (c) 2002-2003 Timo Sirainen */ |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #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
|
4 #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
|
5 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 #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
|
7 #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
|
8 #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
|
9 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 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
|
11 { |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 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
|
13 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
|
14 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 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
|
16 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
|
17 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
|
18 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 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
|
20 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
|
21 } else { |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
22 /* already exists. */ |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
23 ret = 2; |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
24 } |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
26 /* 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
|
27 symbolic links. */ |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
28 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
|
29 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
|
30 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
|
31 |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
32 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
|
33 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
|
34 |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
35 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
|
36 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
|
37 |
1742
05427d8112ee
comment updates. it's not possible to change the file mode if you're not the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
38 /* change the file owner first, since it's the only user one who |
05427d8112ee
comment updates. it's not possible to change the file mode if you're not the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
39 can mess up with the file mode. */ |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
40 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
|
41 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
|
42 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
|
43 ret = 0; |
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
44 } |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
46 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
|
47 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
|
48 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
|
49 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
|
50 } |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
52 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
|
53 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
|
54 |
1742
05427d8112ee
comment updates. it's not possible to change the file mode if you're not the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
55 /* paranoia: make sure we succeeded in everything. */ |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 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
|
57 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
|
58 |
1263
500ec0ec3b85
safe_mkdir(): usage fchmod() and fchown(). chmod() wasn't really safe and
Timo Sirainen <tss@iki.fi>
parents:
823
diff
changeset
|
59 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
|
60 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
|
61 |
823
d00ce0e4de7f
Whops, should have tested it :) Mode check always failed.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
62 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
|
63 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
|
64 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
|
65 } |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 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
|
67 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
|
68 "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
|
69 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
|
70 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
|
71 } |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
72 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
73 return ret; |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 } |