1 #include <linux/capability.h> 2 #include <linux/fs.h> 3 #include <linux/posix_acl.h> 4 #include <linux/reiserfs_fs.h> 5 #include <linux/errno.h> 6 #include <linux/pagemap.h> 7 #include <linux/xattr.h> 8 #include <linux/posix_acl_xattr.h> 9 #include <linux/reiserfs_xattr.h> 10 #include <linux/reiserfs_acl.h> 11 #include <asm/uaccess.h> 12 13 static int reiserfs_set_acl(struct inode *inode, int type, 14 struct posix_acl *acl); 15 16 static int 17 xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) 18 { 19 struct posix_acl *acl; 20 int error; 21 22 if (!reiserfs_posixacl(inode->i_sb)) 23 return -EOPNOTSUPP; 24 if (!is_owner_or_cap(inode)) 25 return -EPERM; 26 27 if (value) { 28 acl = posix_acl_from_xattr(value, size); 29 if (IS_ERR(acl)) { 30 return PTR_ERR(acl); 31 } else if (acl) { 32 error = posix_acl_valid(acl); 33 if (error) 34 goto release_and_out; 35 } 36 } else 37 acl = NULL; 38 39 error = reiserfs_set_acl(inode, type, acl); 40 41 release_and_out: 42 posix_acl_release(acl); 43 return error; 44 } 45 46 static int 47 xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size) 48 { 49 struct posix_acl *acl; 50 int error; 51 52 if (!reiserfs_posixacl(inode->i_sb)) 53 return -EOPNOTSUPP; 54 55 acl = reiserfs_get_acl(inode, type); 56 if (IS_ERR(acl)) 57 return PTR_ERR(acl); 58 if (acl == NULL) 59 return -ENODATA; 60 error = posix_acl_to_xattr(acl, buffer, size); 61 posix_acl_release(acl); 62 63 return error; 64 } 65 66 /* 67 * Convert from filesystem to in-memory representation. 68 */ 69 static struct posix_acl *posix_acl_from_disk(const void *value, size_t size) 70 { 71 const char *end = (char *)value + size; 72 int n, count; 73 struct posix_acl *acl; 74 75 if (!value) 76 return NULL; 77 if (size < sizeof(reiserfs_acl_header)) 78 return ERR_PTR(-EINVAL); 79 if (((reiserfs_acl_header *) value)->a_version != 80 cpu_to_le32(REISERFS_ACL_VERSION)) 81 return ERR_PTR(-EINVAL); 82 value = (char *)value + sizeof(reiserfs_acl_header); 83 count = reiserfs_acl_count(size); 84 if (count < 0) 85 return ERR_PTR(-EINVAL); 86 if (count == 0) 87 return NULL; 88 acl = posix_acl_alloc(count, GFP_NOFS); 89 if (!acl) 90 return ERR_PTR(-ENOMEM); 91 for (n = 0; n < count; n++) { 92 reiserfs_acl_entry *entry = (reiserfs_acl_entry *) value; 93 if ((char *)value + sizeof(reiserfs_acl_entry_short) > end) 94 goto fail; 95 acl->a_entries[n].e_tag = le16_to_cpu(entry->e_tag); 96 acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm); 97 switch (acl->a_entries[n].e_tag) { 98 case ACL_USER_OBJ: 99 case ACL_GROUP_OBJ: 100 case ACL_MASK: 101 case ACL_OTHER: 102 value = (char *)value + 103 sizeof(reiserfs_acl_entry_short); 104 acl->a_entries[n].e_id = ACL_UNDEFINED_ID; 105 break; 106 107 case ACL_USER: 108 case ACL_GROUP: 109 value = (char *)value + sizeof(reiserfs_acl_entry); 110 if ((char *)value > end) 111 goto fail; 112 acl->a_entries[n].e_id = le32_to_cpu(entry->e_id); 113 break; 114 115 default: 116 goto fail; 117 } 118 } 119 if (value != end) 120 goto fail; 121 return acl; 122 123 fail: 124 posix_acl_release(acl); 125 return ERR_PTR(-EINVAL); 126 } 127 128 /* 129 * Convert from in-memory to filesystem representation. 130 */ 131 static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size) 132 { 133 reiserfs_acl_header *ext_acl; 134 char *e; 135 int n; 136 137 *size = reiserfs_acl_size(acl->a_count); 138 ext_acl = kmalloc(sizeof(reiserfs_acl_header) + 139 acl->a_count * 140 sizeof(reiserfs_acl_entry), 141 GFP_NOFS); 142 if (!ext_acl) 143 return ERR_PTR(-ENOMEM); 144 ext_acl->a_version = cpu_to_le32(REISERFS_ACL_VERSION); 145 e = (char *)ext_acl + sizeof(reiserfs_acl_header); 146 for (n = 0; n < acl->a_count; n++) { 147 reiserfs_acl_entry *entry = (reiserfs_acl_entry *) e; 148 entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag); 149 entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm); 150 switch (acl->a_entries[n].e_tag) { 151 case ACL_USER: 152 case ACL_GROUP: 153 entry->e_id = cpu_to_le32(acl->a_entries[n].e_id); 154 e += sizeof(reiserfs_acl_entry); 155 break; 156 157 case ACL_USER_OBJ: 158 case ACL_GROUP_OBJ: 159 case ACL_MASK: 160 case ACL_OTHER: 161 e += sizeof(reiserfs_acl_entry_short); 162 break; 163 164 default: 165 goto fail; 166 } 167 } 168 return (char *)ext_acl; 169 170 fail: 171 kfree(ext_acl); 172 return ERR_PTR(-EINVAL); 173 } 174 175 /* 176 * Inode operation get_posix_acl(). 177 * 178 * inode->i_mutex: down 179 * BKL held [before 2.5.x] 180 */ 181 struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) 182 { 183 char *name, *value; 184 struct posix_acl *acl, **p_acl; 185 int size; 186 int retval; 187 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 188 189 switch (type) { 190 case ACL_TYPE_ACCESS: 191 name = POSIX_ACL_XATTR_ACCESS; 192 p_acl = &reiserfs_i->i_acl_access; 193 break; 194 case ACL_TYPE_DEFAULT: 195 name = POSIX_ACL_XATTR_DEFAULT; 196 p_acl = &reiserfs_i->i_acl_default; 197 break; 198 default: 199 return ERR_PTR(-EINVAL); 200 } 201 202 if (IS_ERR(*p_acl)) { 203 if (PTR_ERR(*p_acl) == -ENODATA) 204 return NULL; 205 } else if (*p_acl != NULL) 206 return posix_acl_dup(*p_acl); 207 208 size = reiserfs_xattr_get(inode, name, NULL, 0); 209 if (size < 0) { 210 if (size == -ENODATA || size == -ENOSYS) { 211 *p_acl = ERR_PTR(-ENODATA); 212 return NULL; 213 } 214 return ERR_PTR(size); 215 } 216 217 value = kmalloc(size, GFP_NOFS); 218 if (!value) 219 return ERR_PTR(-ENOMEM); 220 221 retval = reiserfs_xattr_get(inode, name, value, size); 222 if (retval == -ENODATA || retval == -ENOSYS) { 223 /* This shouldn't actually happen as it should have 224 been caught above.. but just in case */ 225 acl = NULL; 226 *p_acl = ERR_PTR(-ENODATA); 227 } else if (retval < 0) { 228 acl = ERR_PTR(retval); 229 } else { 230 acl = posix_acl_from_disk(value, retval); 231 if (!IS_ERR(acl)) 232 *p_acl = posix_acl_dup(acl); 233 } 234 235 kfree(value); 236 return acl; 237 } 238 239 /* 240 * Inode operation set_posix_acl(). 241 * 242 * inode->i_mutex: down 243 * BKL held [before 2.5.x] 244 */ 245 static int 246 reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) 247 { 248 char *name; 249 void *value = NULL; 250 struct posix_acl **p_acl; 251 size_t size; 252 int error; 253 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 254 255 if (S_ISLNK(inode->i_mode)) 256 return -EOPNOTSUPP; 257 258 switch (type) { 259 case ACL_TYPE_ACCESS: 260 name = POSIX_ACL_XATTR_ACCESS; 261 p_acl = &reiserfs_i->i_acl_access; 262 if (acl) { 263 mode_t mode = inode->i_mode; 264 error = posix_acl_equiv_mode(acl, &mode); 265 if (error < 0) 266 return error; 267 else { 268 inode->i_mode = mode; 269 if (error == 0) 270 acl = NULL; 271 } 272 } 273 break; 274 case ACL_TYPE_DEFAULT: 275 name = POSIX_ACL_XATTR_DEFAULT; 276 p_acl = &reiserfs_i->i_acl_default; 277 if (!S_ISDIR(inode->i_mode)) 278 return acl ? -EACCES : 0; 279 break; 280 default: 281 return -EINVAL; 282 } 283 284 if (acl) { 285 value = posix_acl_to_disk(acl, &size); 286 if (IS_ERR(value)) 287 return (int)PTR_ERR(value); 288 error = reiserfs_xattr_set(inode, name, value, size, 0); 289 } else { 290 error = reiserfs_xattr_del(inode, name); 291 if (error == -ENODATA) { 292 /* This may seem odd here, but it means that the ACL was set 293 * with a value representable with mode bits. If there was 294 * an ACL before, reiserfs_xattr_del already dirtied the inode. 295 */ 296 mark_inode_dirty(inode); 297 error = 0; 298 } 299 } 300 301 kfree(value); 302 303 if (!error) { 304 /* Release the old one */ 305 if (!IS_ERR(*p_acl) && *p_acl) 306 posix_acl_release(*p_acl); 307 308 if (acl == NULL) 309 *p_acl = ERR_PTR(-ENODATA); 310 else 311 *p_acl = posix_acl_dup(acl); 312 } 313 314 return error; 315 } 316 317 /* dir->i_mutex: locked, 318 * inode is new and not released into the wild yet */ 319 int 320 reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, 321 struct inode *inode) 322 { 323 struct posix_acl *acl; 324 int err = 0; 325 326 /* ACLs only get applied to files and directories */ 327 if (S_ISLNK(inode->i_mode)) 328 return 0; 329 330 /* ACLs can only be used on "new" objects, so if it's an old object 331 * there is nothing to inherit from */ 332 if (get_inode_sd_version(dir) == STAT_DATA_V1) 333 goto apply_umask; 334 335 /* Don't apply ACLs to objects in the .reiserfs_priv tree.. This 336 * would be useless since permissions are ignored, and a pain because 337 * it introduces locking cycles */ 338 if (is_reiserfs_priv_object(dir)) { 339 reiserfs_mark_inode_private(inode); 340 goto apply_umask; 341 } 342 343 acl = reiserfs_get_acl(dir, ACL_TYPE_DEFAULT); 344 if (IS_ERR(acl)) { 345 if (PTR_ERR(acl) == -ENODATA) 346 goto apply_umask; 347 return PTR_ERR(acl); 348 } 349 350 if (acl) { 351 struct posix_acl *acl_copy; 352 mode_t mode = inode->i_mode; 353 int need_acl; 354 355 /* Copy the default ACL to the default ACL of a new directory */ 356 if (S_ISDIR(inode->i_mode)) { 357 err = reiserfs_set_acl(inode, ACL_TYPE_DEFAULT, acl); 358 if (err) 359 goto cleanup; 360 } 361 362 /* Now we reconcile the new ACL and the mode, 363 potentially modifying both */ 364 acl_copy = posix_acl_clone(acl, GFP_NOFS); 365 if (!acl_copy) { 366 err = -ENOMEM; 367 goto cleanup; 368 } 369 370 need_acl = posix_acl_create_masq(acl_copy, &mode); 371 if (need_acl >= 0) { 372 if (mode != inode->i_mode) { 373 inode->i_mode = mode; 374 } 375 376 /* If we need an ACL.. */ 377 if (need_acl > 0) { 378 err = 379 reiserfs_set_acl(inode, ACL_TYPE_ACCESS, 380 acl_copy); 381 if (err) 382 goto cleanup_copy; 383 } 384 } 385 cleanup_copy: 386 posix_acl_release(acl_copy); 387 cleanup: 388 posix_acl_release(acl); 389 } else { 390 apply_umask: 391 /* no ACL, apply umask */ 392 inode->i_mode &= ~current->fs->umask; 393 } 394 395 return err; 396 } 397 398 /* Looks up and caches the result of the default ACL. 399 * We do this so that we don't need to carry the xattr_sem into 400 * reiserfs_new_inode if we don't need to */ 401 int reiserfs_cache_default_acl(struct inode *inode) 402 { 403 int ret = 0; 404 if (reiserfs_posixacl(inode->i_sb) && !is_reiserfs_priv_object(inode)) { 405 struct posix_acl *acl; 406 reiserfs_read_lock_xattr_i(inode); 407 reiserfs_read_lock_xattrs(inode->i_sb); 408 acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); 409 reiserfs_read_unlock_xattrs(inode->i_sb); 410 reiserfs_read_unlock_xattr_i(inode); 411 ret = (acl && !IS_ERR(acl)); 412 if (ret) 413 posix_acl_release(acl); 414 } 415 416 return ret; 417 } 418 419 int reiserfs_acl_chmod(struct inode *inode) 420 { 421 struct posix_acl *acl, *clone; 422 int error; 423 424 if (S_ISLNK(inode->i_mode)) 425 return -EOPNOTSUPP; 426 427 if (get_inode_sd_version(inode) == STAT_DATA_V1 || 428 !reiserfs_posixacl(inode->i_sb)) { 429 return 0; 430 } 431 432 reiserfs_read_lock_xattrs(inode->i_sb); 433 acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); 434 reiserfs_read_unlock_xattrs(inode->i_sb); 435 if (!acl) 436 return 0; 437 if (IS_ERR(acl)) 438 return PTR_ERR(acl); 439 clone = posix_acl_clone(acl, GFP_NOFS); 440 posix_acl_release(acl); 441 if (!clone) 442 return -ENOMEM; 443 error = posix_acl_chmod_masq(clone, inode->i_mode); 444 if (!error) { 445 int lock = !has_xattr_dir(inode); 446 reiserfs_write_lock_xattr_i(inode); 447 if (lock) 448 reiserfs_write_lock_xattrs(inode->i_sb); 449 else 450 reiserfs_read_lock_xattrs(inode->i_sb); 451 error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone); 452 if (lock) 453 reiserfs_write_unlock_xattrs(inode->i_sb); 454 else 455 reiserfs_read_unlock_xattrs(inode->i_sb); 456 reiserfs_write_unlock_xattr_i(inode); 457 } 458 posix_acl_release(clone); 459 return error; 460 } 461 462 static int 463 posix_acl_access_get(struct inode *inode, const char *name, 464 void *buffer, size_t size) 465 { 466 if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) 467 return -EINVAL; 468 return xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size); 469 } 470 471 static int 472 posix_acl_access_set(struct inode *inode, const char *name, 473 const void *value, size_t size, int flags) 474 { 475 if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) 476 return -EINVAL; 477 return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); 478 } 479 480 static int posix_acl_access_del(struct inode *inode, const char *name) 481 { 482 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 483 struct posix_acl **acl = &reiserfs_i->i_acl_access; 484 if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) 485 return -EINVAL; 486 if (!IS_ERR(*acl) && *acl) { 487 posix_acl_release(*acl); 488 *acl = ERR_PTR(-ENODATA); 489 } 490 491 return 0; 492 } 493 494 static int 495 posix_acl_access_list(struct inode *inode, const char *name, int namelen, 496 char *out) 497 { 498 int len = namelen; 499 if (!reiserfs_posixacl(inode->i_sb)) 500 return 0; 501 if (out) 502 memcpy(out, name, len); 503 504 return len; 505 } 506 507 struct reiserfs_xattr_handler posix_acl_access_handler = { 508 .prefix = POSIX_ACL_XATTR_ACCESS, 509 .get = posix_acl_access_get, 510 .set = posix_acl_access_set, 511 .del = posix_acl_access_del, 512 .list = posix_acl_access_list, 513 }; 514 515 static int 516 posix_acl_default_get(struct inode *inode, const char *name, 517 void *buffer, size_t size) 518 { 519 if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) 520 return -EINVAL; 521 return xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size); 522 } 523 524 static int 525 posix_acl_default_set(struct inode *inode, const char *name, 526 const void *value, size_t size, int flags) 527 { 528 if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) 529 return -EINVAL; 530 return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); 531 } 532 533 static int posix_acl_default_del(struct inode *inode, const char *name) 534 { 535 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 536 struct posix_acl **acl = &reiserfs_i->i_acl_default; 537 if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) 538 return -EINVAL; 539 if (!IS_ERR(*acl) && *acl) { 540 posix_acl_release(*acl); 541 *acl = ERR_PTR(-ENODATA); 542 } 543 544 return 0; 545 } 546 547 static int 548 posix_acl_default_list(struct inode *inode, const char *name, int namelen, 549 char *out) 550 { 551 int len = namelen; 552 if (!reiserfs_posixacl(inode->i_sb)) 553 return 0; 554 if (out) 555 memcpy(out, name, len); 556 557 return len; 558 } 559 560 struct reiserfs_xattr_handler posix_acl_default_handler = { 561 .prefix = POSIX_ACL_XATTR_DEFAULT, 562 .get = posix_acl_default_get, 563 .set = posix_acl_default_set, 564 .del = posix_acl_default_del, 565 .list = posix_acl_default_list, 566 }; 567