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