1 /* 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 4 * 5 * This copyrighted material is made available to anyone wishing to use, 6 * modify, copy, or redistribute it subject to the terms and conditions 7 * of the GNU General Public License version 2. 8 */ 9 10 #include <linux/sched.h> 11 #include <linux/slab.h> 12 #include <linux/spinlock.h> 13 #include <linux/completion.h> 14 #include <linux/buffer_head.h> 15 #include <linux/xattr.h> 16 #include <linux/posix_acl.h> 17 #include <linux/posix_acl_xattr.h> 18 #include <linux/gfs2_ondisk.h> 19 20 #include "gfs2.h" 21 #include "incore.h" 22 #include "acl.h" 23 #include "xattr.h" 24 #include "glock.h" 25 #include "inode.h" 26 #include "meta_io.h" 27 #include "trans.h" 28 #include "util.h" 29 30 static const char *gfs2_acl_name(int type) 31 { 32 switch (type) { 33 case ACL_TYPE_ACCESS: 34 return GFS2_POSIX_ACL_ACCESS; 35 case ACL_TYPE_DEFAULT: 36 return GFS2_POSIX_ACL_DEFAULT; 37 } 38 return NULL; 39 } 40 41 static struct posix_acl *gfs2_acl_get(struct gfs2_inode *ip, int type) 42 { 43 struct posix_acl *acl; 44 const char *name; 45 char *data; 46 int len; 47 48 if (!ip->i_eattr) 49 return NULL; 50 51 acl = get_cached_acl(&ip->i_inode, type); 52 if (acl != ACL_NOT_CACHED) 53 return acl; 54 55 name = gfs2_acl_name(type); 56 if (name == NULL) 57 return ERR_PTR(-EINVAL); 58 59 len = gfs2_xattr_acl_get(ip, name, &data); 60 if (len < 0) 61 return ERR_PTR(len); 62 if (len == 0) 63 return NULL; 64 65 acl = posix_acl_from_xattr(data, len); 66 kfree(data); 67 return acl; 68 } 69 70 struct posix_acl *gfs2_get_acl(struct inode *inode, int type) 71 { 72 return gfs2_acl_get(GFS2_I(inode), type); 73 } 74 75 static int gfs2_set_mode(struct inode *inode, umode_t mode) 76 { 77 int error = 0; 78 79 if (mode != inode->i_mode) { 80 struct iattr iattr; 81 82 iattr.ia_valid = ATTR_MODE; 83 iattr.ia_mode = mode; 84 85 error = gfs2_setattr_simple(inode, &iattr); 86 } 87 88 return error; 89 } 90 91 static int gfs2_acl_set(struct inode *inode, int type, struct posix_acl *acl) 92 { 93 int error; 94 int len; 95 char *data; 96 const char *name = gfs2_acl_name(type); 97 98 BUG_ON(name == NULL); 99 len = posix_acl_to_xattr(acl, NULL, 0); 100 if (len == 0) 101 return 0; 102 data = kmalloc(len, GFP_NOFS); 103 if (data == NULL) 104 return -ENOMEM; 105 error = posix_acl_to_xattr(acl, data, len); 106 if (error < 0) 107 goto out; 108 error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS); 109 if (!error) 110 set_cached_acl(inode, type, acl); 111 out: 112 kfree(data); 113 return error; 114 } 115 116 int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode) 117 { 118 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 119 struct posix_acl *acl; 120 umode_t mode = inode->i_mode; 121 int error = 0; 122 123 if (!sdp->sd_args.ar_posix_acl) 124 return 0; 125 if (S_ISLNK(inode->i_mode)) 126 return 0; 127 128 acl = gfs2_acl_get(dip, ACL_TYPE_DEFAULT); 129 if (IS_ERR(acl)) 130 return PTR_ERR(acl); 131 if (!acl) { 132 mode &= ~current_umask(); 133 if (mode != inode->i_mode) 134 error = gfs2_set_mode(inode, mode); 135 return error; 136 } 137 138 if (S_ISDIR(inode->i_mode)) { 139 error = gfs2_acl_set(inode, ACL_TYPE_DEFAULT, acl); 140 if (error) 141 goto out; 142 } 143 144 error = posix_acl_create(&acl, GFP_NOFS, &mode); 145 if (error < 0) 146 return error; 147 148 if (error == 0) 149 goto munge; 150 151 error = gfs2_acl_set(inode, ACL_TYPE_ACCESS, acl); 152 if (error) 153 goto out; 154 munge: 155 error = gfs2_set_mode(inode, mode); 156 out: 157 posix_acl_release(acl); 158 return error; 159 } 160 161 int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) 162 { 163 struct inode *inode = &ip->i_inode; 164 struct posix_acl *acl; 165 char *data; 166 unsigned int len; 167 int error; 168 169 acl = gfs2_acl_get(ip, ACL_TYPE_ACCESS); 170 if (IS_ERR(acl)) 171 return PTR_ERR(acl); 172 if (!acl) 173 return gfs2_setattr_simple(inode, attr); 174 175 error = posix_acl_chmod(&acl, GFP_NOFS, attr->ia_mode); 176 if (error) 177 return error; 178 179 len = posix_acl_to_xattr(acl, NULL, 0); 180 data = kmalloc(len, GFP_NOFS); 181 error = -ENOMEM; 182 if (data == NULL) 183 goto out; 184 posix_acl_to_xattr(acl, data, len); 185 error = gfs2_xattr_acl_chmod(ip, attr, data); 186 kfree(data); 187 set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl); 188 189 out: 190 posix_acl_release(acl); 191 return error; 192 } 193 194 static int gfs2_acl_type(const char *name) 195 { 196 if (strcmp(name, GFS2_POSIX_ACL_ACCESS) == 0) 197 return ACL_TYPE_ACCESS; 198 if (strcmp(name, GFS2_POSIX_ACL_DEFAULT) == 0) 199 return ACL_TYPE_DEFAULT; 200 return -EINVAL; 201 } 202 203 static int gfs2_xattr_system_get(struct dentry *dentry, const char *name, 204 void *buffer, size_t size, int xtype) 205 { 206 struct inode *inode = dentry->d_inode; 207 struct gfs2_sbd *sdp = GFS2_SB(inode); 208 struct posix_acl *acl; 209 int type; 210 int error; 211 212 if (!sdp->sd_args.ar_posix_acl) 213 return -EOPNOTSUPP; 214 215 type = gfs2_acl_type(name); 216 if (type < 0) 217 return type; 218 219 acl = gfs2_acl_get(GFS2_I(inode), type); 220 if (IS_ERR(acl)) 221 return PTR_ERR(acl); 222 if (acl == NULL) 223 return -ENODATA; 224 225 error = posix_acl_to_xattr(acl, buffer, size); 226 posix_acl_release(acl); 227 228 return error; 229 } 230 231 static int gfs2_xattr_system_set(struct dentry *dentry, const char *name, 232 const void *value, size_t size, int flags, 233 int xtype) 234 { 235 struct inode *inode = dentry->d_inode; 236 struct gfs2_sbd *sdp = GFS2_SB(inode); 237 struct posix_acl *acl = NULL; 238 int error = 0, type; 239 240 if (!sdp->sd_args.ar_posix_acl) 241 return -EOPNOTSUPP; 242 243 type = gfs2_acl_type(name); 244 if (type < 0) 245 return type; 246 if (flags & XATTR_CREATE) 247 return -EINVAL; 248 if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) 249 return value ? -EACCES : 0; 250 if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER)) 251 return -EPERM; 252 if (S_ISLNK(inode->i_mode)) 253 return -EOPNOTSUPP; 254 255 if (!value) 256 goto set_acl; 257 258 acl = posix_acl_from_xattr(value, size); 259 if (!acl) { 260 /* 261 * acl_set_file(3) may request that we set default ACLs with 262 * zero length -- defend (gracefully) against that here. 263 */ 264 goto out; 265 } 266 if (IS_ERR(acl)) { 267 error = PTR_ERR(acl); 268 goto out; 269 } 270 271 error = posix_acl_valid(acl); 272 if (error) 273 goto out_release; 274 275 error = -EINVAL; 276 if (acl->a_count > GFS2_ACL_MAX_ENTRIES) 277 goto out_release; 278 279 if (type == ACL_TYPE_ACCESS) { 280 umode_t mode = inode->i_mode; 281 error = posix_acl_equiv_mode(acl, &mode); 282 283 if (error <= 0) { 284 posix_acl_release(acl); 285 acl = NULL; 286 287 if (error < 0) 288 return error; 289 } 290 291 error = gfs2_set_mode(inode, mode); 292 if (error) 293 goto out_release; 294 } 295 296 set_acl: 297 error = __gfs2_xattr_set(inode, name, value, size, 0, GFS2_EATYPE_SYS); 298 if (!error) { 299 if (acl) 300 set_cached_acl(inode, type, acl); 301 else 302 forget_cached_acl(inode, type); 303 } 304 out_release: 305 posix_acl_release(acl); 306 out: 307 return error; 308 } 309 310 const struct xattr_handler gfs2_xattr_system_handler = { 311 .prefix = XATTR_SYSTEM_PREFIX, 312 .flags = GFS2_EATYPE_SYS, 313 .get = gfs2_xattr_system_get, 314 .set = gfs2_xattr_system_set, 315 }; 316 317