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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }