Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
xattr_acl.c
Go to the documentation of this file.
1 #include <linux/capability.h>
2 #include <linux/fs.h>
3 #include <linux/posix_acl.h>
4 #include "reiserfs.h"
5 #include <linux/errno.h>
6 #include <linux/pagemap.h>
7 #include <linux/xattr.h>
8 #include <linux/slab.h>
10 #include "xattr.h"
11 #include "acl.h"
12 #include <asm/uaccess.h>
13 
14 static int reiserfs_set_acl(struct reiserfs_transaction_handle *th,
15  struct inode *inode, int type,
16  struct posix_acl *acl);
17 
18 static int
19 posix_acl_set(struct dentry *dentry, const char *name, const void *value,
20  size_t size, int flags, int type)
21 {
22  struct inode *inode = dentry->d_inode;
23  struct posix_acl *acl;
24  int error, error2;
26  size_t jcreate_blocks;
27  if (!reiserfs_posixacl(inode->i_sb))
28  return -EOPNOTSUPP;
29  if (!inode_owner_or_capable(inode))
30  return -EPERM;
31 
32  if (value) {
33  acl = posix_acl_from_xattr(&init_user_ns, value, size);
34  if (IS_ERR(acl)) {
35  return PTR_ERR(acl);
36  } else if (acl) {
37  error = posix_acl_valid(acl);
38  if (error)
39  goto release_and_out;
40  }
41  } else
42  acl = NULL;
43 
44  /* Pessimism: We can't assume that anything from the xattr root up
45  * has been created. */
46 
47  jcreate_blocks = reiserfs_xattr_jcreate_nblocks(inode) +
48  reiserfs_xattr_nblocks(inode, size) * 2;
49 
50  reiserfs_write_lock(inode->i_sb);
51  error = journal_begin(&th, inode->i_sb, jcreate_blocks);
52  if (error == 0) {
53  error = reiserfs_set_acl(&th, inode, type, acl);
54  error2 = journal_end(&th, inode->i_sb, jcreate_blocks);
55  if (error2)
56  error = error2;
57  }
59 
60  release_and_out:
61  posix_acl_release(acl);
62  return error;
63 }
64 
65 static int
66 posix_acl_get(struct dentry *dentry, const char *name, void *buffer,
67  size_t size, int type)
68 {
69  struct posix_acl *acl;
70  int error;
71 
72  if (!reiserfs_posixacl(dentry->d_sb))
73  return -EOPNOTSUPP;
74 
75  acl = reiserfs_get_acl(dentry->d_inode, type);
76  if (IS_ERR(acl))
77  return PTR_ERR(acl);
78  if (acl == NULL)
79  return -ENODATA;
80  error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
81  posix_acl_release(acl);
82 
83  return error;
84 }
85 
86 /*
87  * Convert from filesystem to in-memory representation.
88  */
89 static struct posix_acl *posix_acl_from_disk(const void *value, size_t size)
90 {
91  const char *end = (char *)value + size;
92  int n, count;
93  struct posix_acl *acl;
94 
95  if (!value)
96  return NULL;
97  if (size < sizeof(reiserfs_acl_header))
98  return ERR_PTR(-EINVAL);
99  if (((reiserfs_acl_header *) value)->a_version !=
101  return ERR_PTR(-EINVAL);
102  value = (char *)value + sizeof(reiserfs_acl_header);
103  count = reiserfs_acl_count(size);
104  if (count < 0)
105  return ERR_PTR(-EINVAL);
106  if (count == 0)
107  return NULL;
108  acl = posix_acl_alloc(count, GFP_NOFS);
109  if (!acl)
110  return ERR_PTR(-ENOMEM);
111  for (n = 0; n < count; n++) {
113  if ((char *)value + sizeof(reiserfs_acl_entry_short) > end)
114  goto fail;
115  acl->a_entries[n].e_tag = le16_to_cpu(entry->e_tag);
116  acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm);
117  switch (acl->a_entries[n].e_tag) {
118  case ACL_USER_OBJ:
119  case ACL_GROUP_OBJ:
120  case ACL_MASK:
121  case ACL_OTHER:
122  value = (char *)value +
123  sizeof(reiserfs_acl_entry_short);
124  break;
125 
126  case ACL_USER:
127  value = (char *)value + sizeof(reiserfs_acl_entry);
128  if ((char *)value > end)
129  goto fail;
130  acl->a_entries[n].e_uid =
132  le32_to_cpu(entry->e_id));
133  break;
134  case ACL_GROUP:
135  value = (char *)value + sizeof(reiserfs_acl_entry);
136  if ((char *)value > end)
137  goto fail;
138  acl->a_entries[n].e_gid =
140  le32_to_cpu(entry->e_id));
141  break;
142 
143  default:
144  goto fail;
145  }
146  }
147  if (value != end)
148  goto fail;
149  return acl;
150 
151  fail:
152  posix_acl_release(acl);
153  return ERR_PTR(-EINVAL);
154 }
155 
156 /*
157  * Convert from in-memory to filesystem representation.
158  */
159 static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size)
160 {
161  reiserfs_acl_header *ext_acl;
162  char *e;
163  int n;
164 
165  *size = reiserfs_acl_size(acl->a_count);
166  ext_acl = kmalloc(sizeof(reiserfs_acl_header) +
167  acl->a_count *
168  sizeof(reiserfs_acl_entry),
169  GFP_NOFS);
170  if (!ext_acl)
171  return ERR_PTR(-ENOMEM);
173  e = (char *)ext_acl + sizeof(reiserfs_acl_header);
174  for (n = 0; n < acl->a_count; n++) {
175  const struct posix_acl_entry *acl_e = &acl->a_entries[n];
176  reiserfs_acl_entry *entry = (reiserfs_acl_entry *) e;
177  entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag);
178  entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
179  switch (acl->a_entries[n].e_tag) {
180  case ACL_USER:
181  entry->e_id = cpu_to_le32(
182  from_kuid(&init_user_ns, acl_e->e_uid));
183  e += sizeof(reiserfs_acl_entry);
184  break;
185  case ACL_GROUP:
186  entry->e_id = cpu_to_le32(
187  from_kgid(&init_user_ns, acl_e->e_gid));
188  e += sizeof(reiserfs_acl_entry);
189  break;
190 
191  case ACL_USER_OBJ:
192  case ACL_GROUP_OBJ:
193  case ACL_MASK:
194  case ACL_OTHER:
195  e += sizeof(reiserfs_acl_entry_short);
196  break;
197 
198  default:
199  goto fail;
200  }
201  }
202  return (char *)ext_acl;
203 
204  fail:
205  kfree(ext_acl);
206  return ERR_PTR(-EINVAL);
207 }
208 
209 /*
210  * Inode operation get_posix_acl().
211  *
212  * inode->i_mutex: down
213  * BKL held [before 2.5.x]
214  */
215 struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
216 {
217  char *name, *value;
218  struct posix_acl *acl;
219  int size;
220  int retval;
221 
222  acl = get_cached_acl(inode, type);
223  if (acl != ACL_NOT_CACHED)
224  return acl;
225 
226  switch (type) {
227  case ACL_TYPE_ACCESS:
228  name = POSIX_ACL_XATTR_ACCESS;
229  break;
230  case ACL_TYPE_DEFAULT:
232  break;
233  default:
234  BUG();
235  }
236 
237  size = reiserfs_xattr_get(inode, name, NULL, 0);
238  if (size < 0) {
239  if (size == -ENODATA || size == -ENOSYS) {
240  set_cached_acl(inode, type, NULL);
241  return NULL;
242  }
243  return ERR_PTR(size);
244  }
245 
246  value = kmalloc(size, GFP_NOFS);
247  if (!value)
248  return ERR_PTR(-ENOMEM);
249 
250  retval = reiserfs_xattr_get(inode, name, value, size);
251  if (retval == -ENODATA || retval == -ENOSYS) {
252  /* This shouldn't actually happen as it should have
253  been caught above.. but just in case */
254  acl = NULL;
255  } else if (retval < 0) {
256  acl = ERR_PTR(retval);
257  } else {
258  acl = posix_acl_from_disk(value, retval);
259  }
260  if (!IS_ERR(acl))
261  set_cached_acl(inode, type, acl);
262 
263  kfree(value);
264  return acl;
265 }
266 
267 /*
268  * Inode operation set_posix_acl().
269  *
270  * inode->i_mutex: down
271  * BKL held [before 2.5.x]
272  */
273 static int
274 reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
275  int type, struct posix_acl *acl)
276 {
277  char *name;
278  void *value = NULL;
279  size_t size = 0;
280  int error;
281 
282  if (S_ISLNK(inode->i_mode))
283  return -EOPNOTSUPP;
284 
285  switch (type) {
286  case ACL_TYPE_ACCESS:
287  name = POSIX_ACL_XATTR_ACCESS;
288  if (acl) {
289  error = posix_acl_equiv_mode(acl, &inode->i_mode);
290  if (error < 0)
291  return error;
292  else {
293  if (error == 0)
294  acl = NULL;
295  }
296  }
297  break;
298  case ACL_TYPE_DEFAULT:
300  if (!S_ISDIR(inode->i_mode))
301  return acl ? -EACCES : 0;
302  break;
303  default:
304  return -EINVAL;
305  }
306 
307  if (acl) {
308  value = posix_acl_to_disk(acl, &size);
309  if (IS_ERR(value))
310  return (int)PTR_ERR(value);
311  }
312 
313  error = reiserfs_xattr_set_handle(th, inode, name, value, size, 0);
314 
315  /*
316  * Ensure that the inode gets dirtied if we're only using
317  * the mode bits and an old ACL didn't exist. We don't need
318  * to check if the inode is hashed here since we won't get
319  * called by reiserfs_inherit_default_acl().
320  */
321  if (error == -ENODATA) {
322  error = 0;
323  if (type == ACL_TYPE_ACCESS) {
324  inode->i_ctime = CURRENT_TIME_SEC;
325  mark_inode_dirty(inode);
326  }
327  }
328 
329  kfree(value);
330 
331  if (!error)
332  set_cached_acl(inode, type, acl);
333 
334  return error;
335 }
336 
337 /* dir->i_mutex: locked,
338  * inode is new and not released into the wild yet */
339 int
341  struct inode *dir, struct dentry *dentry,
342  struct inode *inode)
343 {
344  struct posix_acl *acl;
345  int err = 0;
346 
347  /* ACLs only get applied to files and directories */
348  if (S_ISLNK(inode->i_mode))
349  return 0;
350 
351  /* ACLs can only be used on "new" objects, so if it's an old object
352  * there is nothing to inherit from */
354  goto apply_umask;
355 
356  /* Don't apply ACLs to objects in the .reiserfs_priv tree.. This
357  * would be useless since permissions are ignored, and a pain because
358  * it introduces locking cycles */
359  if (IS_PRIVATE(dir)) {
360  inode->i_flags |= S_PRIVATE;
361  goto apply_umask;
362  }
363 
365  if (IS_ERR(acl))
366  return PTR_ERR(acl);
367 
368  if (acl) {
369  /* Copy the default ACL to the default ACL of a new directory */
370  if (S_ISDIR(inode->i_mode)) {
371  err = reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT,
372  acl);
373  if (err)
374  goto cleanup;
375  }
376 
377  /* Now we reconcile the new ACL and the mode,
378  potentially modifying both */
379  err = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
380  if (err < 0)
381  return err;
382 
383  /* If we need an ACL.. */
384  if (err > 0)
385  err = reiserfs_set_acl(th, inode, ACL_TYPE_ACCESS, acl);
386  cleanup:
387  posix_acl_release(acl);
388  } else {
389  apply_umask:
390  /* no ACL, apply umask */
391  inode->i_mode &= ~current_umask();
392  }
393 
394  return err;
395 }
396 
397 /* This is used to cache the default acl before a new object is created.
398  * The biggest reason for this is to get an idea of how many blocks will
399  * actually be required for the create operation if we must inherit an ACL.
400  * An ACL write can add up to 3 object creations and an additional file write
401  * so we'd prefer not to reserve that many blocks in the journal if we can.
402  * It also has the advantage of not loading the ACL with a transaction open,
403  * this may seem silly, but if the owner of the directory is doing the
404  * creation, the ACL may not be loaded since the permissions wouldn't require
405  * it.
406  * We return the number of blocks required for the transaction.
407  */
408 int reiserfs_cache_default_acl(struct inode *inode)
409 {
410  struct posix_acl *acl;
411  int nblocks = 0;
412 
413  if (IS_PRIVATE(inode))
414  return 0;
415 
416  acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT);
417 
418  if (acl && !IS_ERR(acl)) {
419  int size = reiserfs_acl_size(acl->a_count);
420 
421  /* Other xattrs can be created during inode creation. We don't
422  * want to claim too many blocks, so we check to see if we
423  * we need to create the tree to the xattrs, and then we
424  * just want two files. */
425  nblocks = reiserfs_xattr_jcreate_nblocks(inode);
426  nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
427 
428  REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
429 
430  /* We need to account for writes + bitmaps for two files */
431  nblocks += reiserfs_xattr_nblocks(inode, size) * 4;
432  posix_acl_release(acl);
433  }
434 
435  return nblocks;
436 }
437 
438 int reiserfs_acl_chmod(struct inode *inode)
439 {
440  struct reiserfs_transaction_handle th;
441  struct posix_acl *acl;
442  size_t size;
443  int depth;
444  int error;
445 
446  if (S_ISLNK(inode->i_mode))
447  return -EOPNOTSUPP;
448 
449  if (get_inode_sd_version(inode) == STAT_DATA_V1 ||
450  !reiserfs_posixacl(inode->i_sb)) {
451  return 0;
452  }
453 
454  reiserfs_write_unlock(inode->i_sb);
455  acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
456  reiserfs_write_lock(inode->i_sb);
457  if (!acl)
458  return 0;
459  if (IS_ERR(acl))
460  return PTR_ERR(acl);
461  error = posix_acl_chmod(&acl, GFP_NOFS, inode->i_mode);
462  if (error)
463  return error;
464 
465  size = reiserfs_xattr_nblocks(inode, reiserfs_acl_size(acl->a_count));
466  depth = reiserfs_write_lock_once(inode->i_sb);
467  error = journal_begin(&th, inode->i_sb, size * 2);
468  if (!error) {
469  int error2;
470  error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS, acl);
471  error2 = journal_end(&th, inode->i_sb, size * 2);
472  if (error2)
473  error = error2;
474  }
475  reiserfs_write_unlock_once(inode->i_sb, depth);
476  posix_acl_release(acl);
477  return error;
478 }
479 
480 static size_t posix_acl_access_list(struct dentry *dentry, char *list,
481  size_t list_size, const char *name,
482  size_t name_len, int type)
483 {
484  const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
485  if (!reiserfs_posixacl(dentry->d_sb))
486  return 0;
487  if (list && size <= list_size)
488  memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
489  return size;
490 }
491 
493  .prefix = POSIX_ACL_XATTR_ACCESS,
494  .flags = ACL_TYPE_ACCESS,
495  .get = posix_acl_get,
496  .set = posix_acl_set,
497  .list = posix_acl_access_list,
498 };
499 
500 static size_t posix_acl_default_list(struct dentry *dentry, char *list,
501  size_t list_size, const char *name,
502  size_t name_len, int type)
503 {
504  const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
505  if (!reiserfs_posixacl(dentry->d_sb))
506  return 0;
507  if (list && size <= list_size)
508  memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
509  return size;
510 }
511 
513  .prefix = POSIX_ACL_XATTR_DEFAULT,
514  .flags = ACL_TYPE_DEFAULT,
515  .get = posix_acl_get,
516  .set = posix_acl_set,
517  .list = posix_acl_default_list,
518 };