1f466c6fdb3b1f043ff1977a8d2a1d0cd4dc164faAl Viro#include "reiserfs.h"
216f7e0fe2ecc30f30652e8185e1772cdebe39109Randy Dunlap#include <linux/capability.h>
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h>
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fs.h>
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pagemap.h>
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/xattr.h>
7c45ac8887e778c4fa2b572c51a94a681a0955d4dAl Viro#include "xattr.h"
817093991af4995c4b93f6d8ac63aab68fcd9e1beFabian Frederick#include <linux/uaccess.h>
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
11431547b3c4533b8c7fd150ab36980b9a3147797bChristoph Hellwigtrusted_get(struct dentry *dentry, const char *name, void *buffer, size_t size,
12431547b3c4533b8c7fd150ab36980b9a3147797bChristoph Hellwig	    int handler_flags)
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
14bd4c625c061c2a38568d0add3478f59172455159Linus Torvalds	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
15bd4c625c061c2a38568d0add3478f59172455159Linus Torvalds		return -EINVAL;
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17431547b3c4533b8c7fd150ab36980b9a3147797bChristoph Hellwig	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(dentry->d_inode))
18bd4c625c061c2a38568d0add3478f59172455159Linus Torvalds		return -EPERM;
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20431547b3c4533b8c7fd150ab36980b9a3147797bChristoph Hellwig	return reiserfs_xattr_get(dentry->d_inode, name, buffer, size);
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
24431547b3c4533b8c7fd150ab36980b9a3147797bChristoph Hellwigtrusted_set(struct dentry *dentry, const char *name, const void *buffer,
25431547b3c4533b8c7fd150ab36980b9a3147797bChristoph Hellwig	    size_t size, int flags, int handler_flags)
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
27bd4c625c061c2a38568d0add3478f59172455159Linus Torvalds	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
28bd4c625c061c2a38568d0add3478f59172455159Linus Torvalds		return -EINVAL;
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
30431547b3c4533b8c7fd150ab36980b9a3147797bChristoph Hellwig	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(dentry->d_inode))
31bd4c625c061c2a38568d0add3478f59172455159Linus Torvalds		return -EPERM;
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
33431547b3c4533b8c7fd150ab36980b9a3147797bChristoph Hellwig	return reiserfs_xattr_set(dentry->d_inode, name, buffer, size, flags);
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
36431547b3c4533b8c7fd150ab36980b9a3147797bChristoph Hellwigstatic size_t trusted_list(struct dentry *dentry, char *list, size_t list_size,
37431547b3c4533b8c7fd150ab36980b9a3147797bChristoph Hellwig			   const char *name, size_t name_len, int handler_flags)
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3948b32a3553a54740d236b79a90f20147a25875e3Jeff Mahoney	const size_t len = name_len + 1;
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
41431547b3c4533b8c7fd150ab36980b9a3147797bChristoph Hellwig	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(dentry->d_inode))
42bd4c625c061c2a38568d0add3478f59172455159Linus Torvalds		return 0;
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4448b32a3553a54740d236b79a90f20147a25875e3Jeff Mahoney	if (list && len <= list_size) {
4548b32a3553a54740d236b79a90f20147a25875e3Jeff Mahoney		memcpy(list, name, name_len);
4648b32a3553a54740d236b79a90f20147a25875e3Jeff Mahoney		list[name_len] = '\0';
4748b32a3553a54740d236b79a90f20147a25875e3Jeff Mahoney	}
48bd4c625c061c2a38568d0add3478f59172455159Linus Torvalds	return len;
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5194d09a98cdb163be12fb5c76841fa295f0bee22aStephen Hemmingerconst struct xattr_handler reiserfs_xattr_trusted_handler = {
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.prefix = XATTR_TRUSTED_PREFIX,
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get = trusted_get,
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.set = trusted_set,
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.list = trusted_list,
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
57