1 /* 2 * linux/fs/attr.c 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 * changes by Thomas Schoebel-Theuer 6 */ 7 8 #include <linux/module.h> 9 #include <linux/time.h> 10 #include <linux/mm.h> 11 #include <linux/string.h> 12 #include <linux/smp_lock.h> 13 #include <linux/dnotify.h> 14 #include <linux/fcntl.h> 15 #include <linux/quotaops.h> 16 #include <linux/security.h> 17 #include <linux/time.h> 18 19 /* Taken over from the old code... */ 20 21 /* POSIX UID/GID verification for setting inode attributes. */ 22 int inode_change_ok(struct inode *inode, struct iattr *attr) 23 { 24 int retval = -EPERM; 25 unsigned int ia_valid = attr->ia_valid; 26 27 /* If force is set do it anyway. */ 28 if (ia_valid & ATTR_FORCE) 29 goto fine; 30 31 /* Make sure a caller can chown. */ 32 if ((ia_valid & ATTR_UID) && 33 (current->fsuid != inode->i_uid || 34 attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN)) 35 goto error; 36 37 /* Make sure caller can chgrp. */ 38 if ((ia_valid & ATTR_GID) && 39 (current->fsuid != inode->i_uid || 40 (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) && 41 !capable(CAP_CHOWN)) 42 goto error; 43 44 /* Make sure a caller can chmod. */ 45 if (ia_valid & ATTR_MODE) { 46 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) 47 goto error; 48 /* Also check the setgid bit! */ 49 if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : 50 inode->i_gid) && !capable(CAP_FSETID)) 51 attr->ia_mode &= ~S_ISGID; 52 } 53 54 /* Check for setting the inode time. */ 55 if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) { 56 if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER)) 57 goto error; 58 } 59 fine: 60 retval = 0; 61 error: 62 return retval; 63 } 64 65 EXPORT_SYMBOL(inode_change_ok); 66 67 int inode_setattr(struct inode * inode, struct iattr * attr) 68 { 69 unsigned int ia_valid = attr->ia_valid; 70 int error = 0; 71 72 if (ia_valid & ATTR_SIZE) { 73 if (attr->ia_size != i_size_read(inode)) { 74 error = vmtruncate(inode, attr->ia_size); 75 if (error || (ia_valid == ATTR_SIZE)) 76 goto out; 77 } else { 78 /* 79 * We skipped the truncate but must still update 80 * timestamps 81 */ 82 ia_valid |= ATTR_MTIME|ATTR_CTIME; 83 } 84 } 85 86 if (ia_valid & ATTR_UID) 87 inode->i_uid = attr->ia_uid; 88 if (ia_valid & ATTR_GID) 89 inode->i_gid = attr->ia_gid; 90 if (ia_valid & ATTR_ATIME) 91 inode->i_atime = timespec_trunc(attr->ia_atime, 92 inode->i_sb->s_time_gran); 93 if (ia_valid & ATTR_MTIME) 94 inode->i_mtime = timespec_trunc(attr->ia_mtime, 95 inode->i_sb->s_time_gran); 96 if (ia_valid & ATTR_CTIME) 97 inode->i_ctime = timespec_trunc(attr->ia_ctime, 98 inode->i_sb->s_time_gran); 99 if (ia_valid & ATTR_MODE) { 100 umode_t mode = attr->ia_mode; 101 102 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) 103 mode &= ~S_ISGID; 104 inode->i_mode = mode; 105 } 106 mark_inode_dirty(inode); 107 out: 108 return error; 109 } 110 111 EXPORT_SYMBOL(inode_setattr); 112 113 int setattr_mask(unsigned int ia_valid) 114 { 115 unsigned long dn_mask = 0; 116 117 if (ia_valid & ATTR_UID) 118 dn_mask |= DN_ATTRIB; 119 if (ia_valid & ATTR_GID) 120 dn_mask |= DN_ATTRIB; 121 if (ia_valid & ATTR_SIZE) 122 dn_mask |= DN_MODIFY; 123 /* both times implies a utime(s) call */ 124 if ((ia_valid & (ATTR_ATIME|ATTR_MTIME)) == (ATTR_ATIME|ATTR_MTIME)) 125 dn_mask |= DN_ATTRIB; 126 else if (ia_valid & ATTR_ATIME) 127 dn_mask |= DN_ACCESS; 128 else if (ia_valid & ATTR_MTIME) 129 dn_mask |= DN_MODIFY; 130 if (ia_valid & ATTR_MODE) 131 dn_mask |= DN_ATTRIB; 132 return dn_mask; 133 } 134 135 int notify_change(struct dentry * dentry, struct iattr * attr) 136 { 137 struct inode *inode = dentry->d_inode; 138 mode_t mode; 139 int error; 140 struct timespec now; 141 unsigned int ia_valid = attr->ia_valid; 142 143 if (!inode) 144 BUG(); 145 146 mode = inode->i_mode; 147 now = current_fs_time(inode->i_sb); 148 149 attr->ia_ctime = now; 150 if (!(ia_valid & ATTR_ATIME_SET)) 151 attr->ia_atime = now; 152 if (!(ia_valid & ATTR_MTIME_SET)) 153 attr->ia_mtime = now; 154 if (ia_valid & ATTR_KILL_SUID) { 155 attr->ia_valid &= ~ATTR_KILL_SUID; 156 if (mode & S_ISUID) { 157 if (!(ia_valid & ATTR_MODE)) { 158 ia_valid = attr->ia_valid |= ATTR_MODE; 159 attr->ia_mode = inode->i_mode; 160 } 161 attr->ia_mode &= ~S_ISUID; 162 } 163 } 164 if (ia_valid & ATTR_KILL_SGID) { 165 attr->ia_valid &= ~ ATTR_KILL_SGID; 166 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { 167 if (!(ia_valid & ATTR_MODE)) { 168 ia_valid = attr->ia_valid |= ATTR_MODE; 169 attr->ia_mode = inode->i_mode; 170 } 171 attr->ia_mode &= ~S_ISGID; 172 } 173 } 174 if (!attr->ia_valid) 175 return 0; 176 177 if (ia_valid & ATTR_SIZE) 178 down_write(&dentry->d_inode->i_alloc_sem); 179 180 if (inode->i_op && inode->i_op->setattr) { 181 error = security_inode_setattr(dentry, attr); 182 if (!error) 183 error = inode->i_op->setattr(dentry, attr); 184 } else { 185 error = inode_change_ok(inode, attr); 186 if (!error) 187 error = security_inode_setattr(dentry, attr); 188 if (!error) { 189 if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || 190 (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) 191 error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; 192 if (!error) 193 error = inode_setattr(inode, attr); 194 } 195 } 196 197 if (ia_valid & ATTR_SIZE) 198 up_write(&dentry->d_inode->i_alloc_sem); 199 200 if (!error) { 201 unsigned long dn_mask = setattr_mask(ia_valid); 202 if (dn_mask) 203 dnotify_parent(dentry, dn_mask); 204 } 205 return error; 206 } 207 208 EXPORT_SYMBOL(notify_change); 209