diff options
Diffstat (limited to 'fs/reiserfs/xattr_security.c')
-rw-r--r-- | fs/reiserfs/xattr_security.c | 80 |
1 files changed, 62 insertions, 18 deletions
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index 056008db1377..4d3c20e787c3 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/pagemap.h> | 4 | #include <linux/pagemap.h> |
5 | #include <linux/xattr.h> | 5 | #include <linux/xattr.h> |
6 | #include <linux/reiserfs_xattr.h> | 6 | #include <linux/reiserfs_xattr.h> |
7 | #include <linux/security.h> | ||
7 | #include <asm/uaccess.h> | 8 | #include <asm/uaccess.h> |
8 | 9 | ||
9 | static int | 10 | static int |
@@ -12,7 +13,7 @@ security_get(struct inode *inode, const char *name, void *buffer, size_t size) | |||
12 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) | 13 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) |
13 | return -EINVAL; | 14 | return -EINVAL; |
14 | 15 | ||
15 | if (is_reiserfs_priv_object(inode)) | 16 | if (IS_PRIVATE(inode)) |
16 | return -EPERM; | 17 | return -EPERM; |
17 | 18 | ||
18 | return reiserfs_xattr_get(inode, name, buffer, size); | 19 | return reiserfs_xattr_get(inode, name, buffer, size); |
@@ -25,41 +26,84 @@ security_set(struct inode *inode, const char *name, const void *buffer, | |||
25 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) | 26 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) |
26 | return -EINVAL; | 27 | return -EINVAL; |
27 | 28 | ||
28 | if (is_reiserfs_priv_object(inode)) | 29 | if (IS_PRIVATE(inode)) |
29 | return -EPERM; | 30 | return -EPERM; |
30 | 31 | ||
31 | return reiserfs_xattr_set(inode, name, buffer, size, flags); | 32 | return reiserfs_xattr_set(inode, name, buffer, size, flags); |
32 | } | 33 | } |
33 | 34 | ||
34 | static int security_del(struct inode *inode, const char *name) | 35 | static size_t security_list(struct inode *inode, char *list, size_t list_len, |
36 | const char *name, size_t namelen) | ||
35 | { | 37 | { |
36 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) | 38 | const size_t len = namelen + 1; |
37 | return -EINVAL; | ||
38 | 39 | ||
39 | if (is_reiserfs_priv_object(inode)) | 40 | if (IS_PRIVATE(inode)) |
40 | return -EPERM; | 41 | return 0; |
42 | |||
43 | if (list && len <= list_len) { | ||
44 | memcpy(list, name, namelen); | ||
45 | list[namelen] = '\0'; | ||
46 | } | ||
41 | 47 | ||
42 | return 0; | 48 | return len; |
43 | } | 49 | } |
44 | 50 | ||
45 | static int | 51 | /* Initializes the security context for a new inode and returns the number |
46 | security_list(struct inode *inode, const char *name, int namelen, char *out) | 52 | * of blocks needed for the transaction. If successful, reiserfs_security |
53 | * must be released using reiserfs_security_free when the caller is done. */ | ||
54 | int reiserfs_security_init(struct inode *dir, struct inode *inode, | ||
55 | struct reiserfs_security_handle *sec) | ||
47 | { | 56 | { |
48 | int len = namelen; | 57 | int blocks = 0; |
58 | int error = security_inode_init_security(inode, dir, &sec->name, | ||
59 | &sec->value, &sec->length); | ||
60 | if (error) { | ||
61 | if (error == -EOPNOTSUPP) | ||
62 | error = 0; | ||
49 | 63 | ||
50 | if (is_reiserfs_priv_object(inode)) | 64 | sec->name = NULL; |
51 | return 0; | 65 | sec->value = NULL; |
66 | sec->length = 0; | ||
67 | return error; | ||
68 | } | ||
52 | 69 | ||
53 | if (out) | 70 | if (sec->length) { |
54 | memcpy(out, name, len); | 71 | blocks = reiserfs_xattr_jcreate_nblocks(inode) + |
72 | reiserfs_xattr_nblocks(inode, sec->length); | ||
73 | /* We don't want to count the directories twice if we have | ||
74 | * a default ACL. */ | ||
75 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; | ||
76 | } | ||
77 | return blocks; | ||
78 | } | ||
55 | 79 | ||
56 | return len; | 80 | int reiserfs_security_write(struct reiserfs_transaction_handle *th, |
81 | struct inode *inode, | ||
82 | struct reiserfs_security_handle *sec) | ||
83 | { | ||
84 | int error; | ||
85 | if (strlen(sec->name) < sizeof(XATTR_SECURITY_PREFIX)) | ||
86 | return -EINVAL; | ||
87 | |||
88 | error = reiserfs_xattr_set_handle(th, inode, sec->name, sec->value, | ||
89 | sec->length, XATTR_CREATE); | ||
90 | if (error == -ENODATA || error == -EOPNOTSUPP) | ||
91 | error = 0; | ||
92 | |||
93 | return error; | ||
94 | } | ||
95 | |||
96 | void reiserfs_security_free(struct reiserfs_security_handle *sec) | ||
97 | { | ||
98 | kfree(sec->name); | ||
99 | kfree(sec->value); | ||
100 | sec->name = NULL; | ||
101 | sec->value = NULL; | ||
57 | } | 102 | } |
58 | 103 | ||
59 | struct reiserfs_xattr_handler security_handler = { | 104 | struct xattr_handler reiserfs_xattr_security_handler = { |
60 | .prefix = XATTR_SECURITY_PREFIX, | 105 | .prefix = XATTR_SECURITY_PREFIX, |
61 | .get = security_get, | 106 | .get = security_get, |
62 | .set = security_set, | 107 | .set = security_set, |
63 | .del = security_del, | ||
64 | .list = security_list, | 108 | .list = security_list, |
65 | }; | 109 | }; |