static int security_del(struct inode *inode, const char *name) { if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) return -EINVAL; if (is_reiserfs_priv_object(inode)) return -EPERM; return 0; }
static int security_get(struct inode *inode, const char *name, void *buffer, size_t size) { if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) return -EINVAL; if (is_reiserfs_priv_object(inode)) return -EPERM; return reiserfs_xattr_get(inode, name, buffer, size); }
static int security_list(struct inode *inode, const char *name, int namelen, char *out) { int len = namelen; if (is_reiserfs_priv_object(inode)) return 0; if (out) memcpy(out, name, len); return len; }
static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { int retval; struct inode *inode = NULL; struct reiserfs_dir_entry de; INITIALIZE_PATH(path_to_entry); if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len) return ERR_PTR(-ENAMETOOLONG); reiserfs_write_lock(dir->i_sb); de.de_gen_number_bit_string = NULL; retval = reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de); pathrelse(&path_to_entry); if (retval == NAME_FOUND) { /* Hide the .reiserfs_priv directory */ if (reiserfs_xattrs(dir->i_sb) && !old_format_only(dir->i_sb) && REISERFS_SB(dir->i_sb)->priv_root && REISERFS_SB(dir->i_sb)->priv_root->d_inode && de.de_objectid == le32_to_cpu(INODE_PKEY (REISERFS_SB(dir->i_sb)->priv_root->d_inode)-> k_objectid)) { reiserfs_write_unlock(dir->i_sb); return ERR_PTR(-EACCES); } inode = reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id)); if (!inode || IS_ERR(inode)) { reiserfs_write_unlock(dir->i_sb); return ERR_PTR(-EACCES); } /* Propogate the priv_object flag so we know we're in the priv tree */ if (is_reiserfs_priv_object(dir)) reiserfs_mark_inode_private(inode); } reiserfs_write_unlock(dir->i_sb); if (retval == IO_ERROR) { return ERR_PTR(-EIO); } return d_splice_alias(inode, dentry); }
/* Looks up and caches the result of the default ACL. * We do this so that we don't need to carry the xattr_sem into * reiserfs_new_inode if we don't need to */ int reiserfs_cache_default_acl(struct inode *inode) { int ret = 0; if (reiserfs_posixacl(inode->i_sb) && !is_reiserfs_priv_object(inode)) { struct posix_acl *acl; reiserfs_read_lock_xattr_i(inode); reiserfs_read_lock_xattrs(inode->i_sb); acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); reiserfs_read_unlock_xattrs(inode->i_sb); reiserfs_read_unlock_xattr_i(inode); ret = (acl && !IS_ERR(acl)); if (ret) posix_acl_release(acl); } return ret; }
/* dir->i_sem: down, * inode is new and not released into the wild yet */ int reiserfs_inherit_default_acl (struct inode *dir, struct dentry *dentry, struct inode *inode) { struct posix_acl *acl; int err = 0; /* ACLs only get applied to files and directories */ if (S_ISLNK (inode->i_mode)) return 0; /* ACLs can only be used on "new" objects, so if it's an old object * there is nothing to inherit from */ if (get_inode_sd_version (dir) == STAT_DATA_V1) goto apply_umask; /* Don't apply ACLs to objects in the .reiserfs_priv tree.. This * would be useless since permissions are ignored, and a pain because * it introduces locking cycles */ if (is_reiserfs_priv_object (dir)) { reiserfs_mark_inode_private (inode); goto apply_umask; } acl = reiserfs_get_acl (dir, ACL_TYPE_DEFAULT); if (IS_ERR (acl)) { if (PTR_ERR (acl) == -ENODATA) goto apply_umask; return PTR_ERR (acl); } if (acl) { struct posix_acl *acl_copy; mode_t mode = inode->i_mode; int need_acl; /* Copy the default ACL to the default ACL of a new directory */ if (S_ISDIR (inode->i_mode)) { err = reiserfs_set_acl (inode, ACL_TYPE_DEFAULT, acl); if (err) goto cleanup; } /* Now we reconcile the new ACL and the mode, potentially modifying both */ acl_copy = posix_acl_clone (acl, GFP_NOFS); if (!acl_copy) { err = -ENOMEM; goto cleanup; } need_acl = posix_acl_create_masq (acl_copy, &mode); if (need_acl >= 0) { if (mode != inode->i_mode) { inode->i_mode = mode; } /* If we need an ACL.. */ if (need_acl > 0) { err = reiserfs_set_acl (inode, ACL_TYPE_ACCESS, acl_copy); if (err) goto cleanup_copy; } } cleanup_copy: posix_acl_release (acl_copy); cleanup: posix_acl_release (acl); } else { apply_umask: /* no ACL, apply umask */ inode->i_mode &= ~current->fs->umask; } return err; }