From: Andreas Gruenbacher <agruen@suse.de>
To: Andrew Morton <akpm@osdl.org>
Cc: linux-kernel@vger.kernel.org, James Morris <jmorris@namei.org>,
Kay Sievers <kay.sievers@vrfy.org>
Subject: Re: Generic infrastructure for acls
Date: Wed, 6 Sep 2006 18:40:12 +0200 [thread overview]
Message-ID: <200609061840.12707.agruen@suse.de> (raw)
In-Reply-To: <20060901144423.aa306d36.akpm@osdl.org>
[-- Attachment #1: Type: text/plain, Size: 244 bytes --]
On Friday, 01 September 2006 23:44, Andrew Morton wrote:
> That's a clumsy-looking interface.
I have added a little documentation now. This will hopefully suffice to
clarify why the interface is as clumsy-looking as it is ;)
Thanks,
Andreas
[-- Attachment #2: generic-acl.diff --]
[-- Type: text/x-diff, Size: 7176 bytes --]
From: Andreas Gruenbacher <agruen@suse.de>
Subject: Generic infrastructure for acls
Add some infrastructure for access control lists on in-memory
filesystems such as tmpfs.
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
---
fs/Kconfig | 4 +
fs/Makefile | 1
fs/generic_acl.c | 172 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/generic_acl.h | 30 +++++++
4 files changed, 207 insertions(+)
Index: linux-2.6.18-rc6/fs/Kconfig
===================================================================
--- linux-2.6.18-rc6.orig/fs/Kconfig
+++ linux-2.6.18-rc6/fs/Kconfig
@@ -1921,6 +1921,10 @@ config 9P_FS
If unsure, say N.
+config GENERIC_ACL
+ bool
+ select FS_POSIX_ACL
+
endmenu
menu "Partition Types"
Index: linux-2.6.18-rc6/fs/Makefile
===================================================================
--- linux-2.6.18-rc6.orig/fs/Makefile
+++ linux-2.6.18-rc6/fs/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat
obj-$(CONFIG_FS_MBCACHE) += mbcache.o
obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o
obj-$(CONFIG_NFS_COMMON) += nfs_common/
+obj-$(CONFIG_GENERIC_ACL) += generic_acl.o
obj-$(CONFIG_QUOTA) += dquot.o
obj-$(CONFIG_QFMT_V1) += quota_v1.o
Index: linux-2.6.18-rc6/include/linux/generic_acl.h
===================================================================
--- /dev/null
+++ linux-2.6.18-rc6/include/linux/generic_acl.h
@@ -0,0 +1,36 @@
+/*
+ * fs/generic_acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef GENERIC_ACL_H
+#define GENERIC_ACL_H
+
+#include <linux/posix_acl.h>
+#include <linux/posix_acl_xattr.h>
+
+/**
+ * struct generic_acl_operations - filesystem operations
+ *
+ * Filesystems must make these operations available to the generic
+ * operations.
+ */
+struct generic_acl_operations {
+ struct posix_acl *(*getacl)(struct inode *, int);
+ void (*setacl)(struct inode *, int, struct posix_acl *);
+};
+
+size_t generic_acl_list(struct inode *, struct generic_acl_operations *, int,
+ char *, size_t);
+int generic_acl_get(struct inode *, struct generic_acl_operations *, int,
+ void *, size_t);
+int generic_acl_set(struct inode *, struct generic_acl_operations *, int,
+ const void *, size_t);
+int generic_acl_init(struct inode *, struct inode *,
+ struct generic_acl_operations *);
+int generic_acl_chmod(struct inode *, struct generic_acl_operations *);
+
+#endif
Index: linux-2.6.18-rc6/fs/generic_acl.c
===================================================================
--- /dev/null
+++ linux-2.6.18-rc6/fs/generic_acl.c
@@ -0,0 +1,197 @@
+/*
+ * fs/generic_acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/generic_acl.h>
+
+/**
+ * generic_acl_list - Generic xattr_handler->list() operation
+ * @ops: Filesystem specific getacl and setacl callbacks
+ */
+size_t
+generic_acl_list(struct inode *inode, struct generic_acl_operations *ops,
+ int type, char *list, size_t list_size)
+{
+ struct posix_acl *acl;
+ const char *name;
+ size_t size;
+
+ acl = ops->getacl(inode, type);
+ if (!acl)
+ return 0;
+ posix_acl_release(acl);
+
+ switch(type) {
+ case ACL_TYPE_ACCESS:
+ name = POSIX_ACL_XATTR_ACCESS;
+ break;
+
+ case ACL_TYPE_DEFAULT:
+ name = POSIX_ACL_XATTR_DEFAULT;
+ break;
+
+ default:
+ return 0;
+ }
+ size = strlen(name) + 1;
+ if (list && size <= list_size)
+ memcpy(list, name, size);
+ return size;
+}
+
+/**
+ * generic_acl_get - Generic xattr_handler->get() operation
+ * @ops: Filesystem specific getacl and setacl callbacks
+ */
+int
+generic_acl_get(struct inode *inode, struct generic_acl_operations *ops,
+ int type, void *buffer, size_t size)
+{
+ struct posix_acl *acl;
+ int error;
+
+ acl = ops->getacl(inode, type);
+ if (!acl)
+ return -ENODATA;
+ error = posix_acl_to_xattr(acl, buffer, size);
+ posix_acl_release(acl);
+
+ return error;
+}
+
+/**
+ * generic_acl_set - Generic xattr_handler->set() operation
+ * @ops: Filesystem specific getacl and setacl callbacks
+ */
+int
+generic_acl_set(struct inode *inode, struct generic_acl_operations *ops,
+ int type, const void *value, size_t size)
+{
+ struct posix_acl *acl = NULL;
+ int error;
+
+ if (S_ISLNK(inode->i_mode))
+ return -EOPNOTSUPP;
+ if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
+ return -EPERM;
+ if (value) {
+ acl = posix_acl_from_xattr(value, size);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ }
+ if (acl) {
+ mode_t mode;
+
+ error = posix_acl_valid(acl);
+ if (error)
+ goto failed;
+ switch(type) {
+ case ACL_TYPE_ACCESS:
+ mode = inode->i_mode;
+ error = posix_acl_equiv_mode(acl, &mode);
+ if (error < 0)
+ goto failed;
+ inode->i_mode = mode;
+ if (error == 0) {
+ posix_acl_release(acl);
+ acl = NULL;
+ }
+ break;
+
+ case ACL_TYPE_DEFAULT:
+ if (!S_ISDIR(inode->i_mode)) {
+ error = -EINVAL;
+ goto failed;
+ }
+ break;
+ }
+ }
+ ops->setacl(inode, type, acl);
+ error = 0;
+failed:
+ posix_acl_release(acl);
+ return error;
+}
+
+/**
+ * generic_acl_init - Take care of acl inheritance at @inode create time
+ * @ops: Filesystem specific getacl and setacl callbacks
+ *
+ * Files created inside a directory with a default ACL inherit the
+ * directory's default ACL.
+ */
+int
+generic_acl_init(struct inode *inode, struct inode *dir,
+ struct generic_acl_operations *ops)
+{
+ struct posix_acl *acl = NULL;
+ mode_t mode = inode->i_mode;
+ int error;
+
+ inode->i_mode = mode & ~current->fs->umask;
+ if (!S_ISLNK(inode->i_mode))
+ acl = ops->getacl(dir, ACL_TYPE_DEFAULT);
+ if (acl) {
+ struct posix_acl *clone;
+
+ if (S_ISDIR(inode->i_mode)) {
+ clone = posix_acl_clone(acl, GFP_KERNEL);
+ error = -ENOMEM;
+ if (!clone)
+ goto cleanup;
+ ops->setacl(inode, ACL_TYPE_DEFAULT, clone);
+ posix_acl_release(clone);
+ }
+ clone = posix_acl_clone(acl, GFP_KERNEL);
+ error = -ENOMEM;
+ if (!clone)
+ goto cleanup;
+ error = posix_acl_create_masq(clone, &mode);
+ if (error >= 0) {
+ inode->i_mode = mode;
+ if (error > 0)
+ ops->setacl(inode, ACL_TYPE_ACCESS, clone);
+ }
+ posix_acl_release(clone);
+ }
+ error = 0;
+
+cleanup:
+ posix_acl_release(acl);
+ return error;
+}
+
+/**
+ * generic_acl_chmod - change the access acl of @inode upon chmod()
+ * @ops: FIlesystem specific getacl and setacl callbacks
+ *
+ * A chmod also changes the permissions of the owner, group/mask, and
+ * other ACL entries.
+ */
+int
+generic_acl_chmod(struct inode *inode, struct generic_acl_operations *ops)
+{
+ struct posix_acl *acl, *clone;
+ int error = 0;
+
+ if (S_ISLNK(inode->i_mode))
+ return -EOPNOTSUPP;
+ acl = ops->getacl(inode, ACL_TYPE_ACCESS);
+ if (acl) {
+ clone = posix_acl_clone(acl, GFP_KERNEL);
+ posix_acl_release(acl);
+ if (!clone)
+ return -ENOMEM;
+ error = posix_acl_chmod_masq(clone, inode->i_mode);
+ if (!error)
+ ops->setacl(inode, ACL_TYPE_ACCESS, clone);
+ posix_acl_release(clone);
+ }
+ return error;
+}
next prev parent reply other threads:[~2006-09-06 16:35 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-01 22:14 [patch 0/2] Tmpfs acls Andreas Gruenbacher
2006-09-01 22:14 ` Generic infrastructure for acls Andreas Gruenbacher
2006-09-01 21:44 ` Andrew Morton
2006-09-01 22:32 ` Andreas Gruenbacher
2006-09-06 16:40 ` Andreas Gruenbacher [this message]
2006-09-06 20:06 ` Randy.Dunlap
2006-09-06 6:54 ` Jan Engelhardt
2006-09-01 22:14 ` Access Control Lists for tmpfs Andreas Gruenbacher
2006-09-01 21:52 ` Andrew Morton
2006-09-02 7:24 ` Arjan van de Ven
2006-09-05 19:07 ` Andrew Morton
2006-09-06 16:40 ` Andreas Gruenbacher
2006-09-06 7:02 ` Jan Engelhardt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200609061840.12707.agruen@suse.de \
--to=agruen@suse.de \
--cc=akpm@osdl.org \
--cc=jmorris@namei.org \
--cc=kay.sievers@vrfy.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.