/dev/pts is somewhat special: there are no directories, and so we
don't need default acls.

Signed-off-by: Andreas Gruenbacher <[EMAIL PROTECTED]>

Index: linux-2.6.11-rc2-mm2/fs/devpts/inode.c
===================================================================
--- linux-2.6.11-rc2-mm2.orig/fs/devpts/inode.c
+++ linux-2.6.11-rc2-mm2/fs/devpts/inode.c
@@ -19,15 +19,43 @@
 #include <linux/tty.h>
 #include <linux/devpts_fs.h>
 #include <linux/xattr.h>
+#include <linux/generic_acl.h>
 
 #define DEVPTS_SUPER_MAGIC 0x1cd1
 
+#ifdef CONFIG_DEVPTS_POSIX_ACL
+static struct inode *
+devpts_alloc_inode(struct super_block *sb)
+{
+       struct devpts_inode_info *ei;
+       ei = kmalloc(sizeof(*ei), SLAB_KERNEL);
+       if (!ei)
+               return NULL;
+       inode_init_once(&ei->vfs_inode);
+       ei->i_acl = NULL;
+       return &ei->vfs_inode;
+}
+
+static void
+devpts_destroy_inode(struct inode *inode)
+{
+       struct devpts_inode_info *ei = DEVPTS_I(inode);
+       if (ei->i_acl)
+               posix_acl_release(ei->i_acl);
+       kfree(ei);
+}
+#endif  /* CONFIG_DEVPTS_POSIX_ACL */
+
 extern struct xattr_handler devpts_xattr_security_handler;
+extern struct xattr_handler devpts_xattr_acl_access_handler;
 
 static struct xattr_handler *devpts_xattr_handlers[] = {
 #ifdef CONFIG_DEVPTS_FS_SECURITY
        &devpts_xattr_security_handler,
 #endif
+#ifdef CONFIG_DEVPTS_POSIX_ACL
+       &devpts_xattr_acl_access_handler,
+#endif
        NULL
 };
 
@@ -38,6 +66,10 @@ static struct inode_operations devpts_fi
        .listxattr      = generic_listxattr,
        .removexattr    = generic_removexattr,
 #endif
+#ifdef CONFIG_DEVPTS_POSIX_ACL
+       .setattr        = devpts_setattr,
+       .permission     = devpts_permission,
+#endif
 };
 
 static struct vfsmount *devpts_mnt;
@@ -89,6 +121,10 @@ static int devpts_remount(struct super_b
 }
 
 static struct super_operations devpts_sops = {
+#ifdef CONFIG_DEVPTS_POSIX_ACL
+       .alloc_inode    = devpts_alloc_inode,
+       .destroy_inode  = devpts_destroy_inode,
+#endif
        .statfs         = simple_statfs,
        .remount_fs     = devpts_remount,
 };
@@ -117,6 +153,9 @@ devpts_fill_super(struct super_block *s,
        inode->i_op = &simple_dir_inode_operations;
        inode->i_fop = &simple_dir_operations;
        inode->i_nlink = 2;
+#ifdef CONFIG_TMPFS_POSIX_ACL
+       s->s_flags |= MS_POSIXACL;
+#endif
 
        devpts_root = s->s_root = d_alloc_root(inode);
        if (s->s_root)
Index: linux-2.6.11-rc2-mm2/fs/devpts/Makefile
===================================================================
--- linux-2.6.11-rc2-mm2.orig/fs/devpts/Makefile
+++ linux-2.6.11-rc2-mm2/fs/devpts/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_UNIX98_PTYS)               += devpts.o
 
 devpts-$(CONFIG_UNIX98_PTYS)           := inode.o
 devpts-$(CONFIG_DEVPTS_FS_SECURITY)    += xattr_security.o
+devpts-$(CONFIG_DEVPTS_POSIX_ACL)      += acl.o
Index: linux-2.6.11-rc2-mm2/include/linux/devpts_fs.h
===================================================================
--- linux-2.6.11-rc2-mm2.orig/include/linux/devpts_fs.h
+++ linux-2.6.11-rc2-mm2/include/linux/devpts_fs.h
@@ -17,6 +17,23 @@
 
 #ifdef CONFIG_UNIX98_PTYS
 
+#ifdef CONFIG_DEVPTS_POSIX_ACL
+struct devpts_inode_info {
+       struct posix_acl        *i_acl;
+       struct inode            vfs_inode;
+};
+
+static inline struct devpts_inode_info *DEVPTS_I(struct inode *inode)
+{
+       return container_of(inode, struct devpts_inode_info, vfs_inode);
+}
+
+/* acl.c */
+int devpts_setattr(struct dentry *, struct iattr *);
+int devpts_permission(struct inode *, int, struct nameidata *);
+#endif  /* CONFIG_DEVPTS_POSIX_ACL */
+
+/* inode.c */
 int devpts_pty_new(struct tty_struct *tty);      /* mknod in devpts */
 struct tty_struct *devpts_get_tty(int number);  /* get tty structure */
 void devpts_pty_kill(int number);               /* unlink */
Index: linux-2.6.11-rc2-mm2/fs/Kconfig
===================================================================
--- linux-2.6.11-rc2-mm2.orig/fs/Kconfig
+++ linux-2.6.11-rc2-mm2/fs/Kconfig
@@ -850,6 +850,19 @@ config DEVPTS_FS_XATTR
 
          If unsure, say N.
 
+config DEVPTS_POSIX_ACL
+       bool "/dev/pts POSIX Access Control Lists"
+       depends on DEVPTS_FS_XATTR
+       select GENERIC_ACL
+       help
+         POSIX Access Control Lists (ACLs) support permissions for users and
+         groups beyond the owner/group/world scheme.
+
+         To learn more about Access Control Lists, visit the POSIX ACLs for
+         Linux website <http://acl.bestbits.at/>.
+
+         If you don't know what Access Control Lists are, say N.
+
 config DEVPTS_FS_SECURITY
        bool "/dev/pts Security Labels"
        depends on DEVPTS_FS_XATTR
Index: linux-2.6.11-rc2-mm2/fs/devpts/acl.c
===================================================================
--- /dev/null
+++ linux-2.6.11-rc2-mm2/fs/devpts/acl.c
@@ -0,0 +1,112 @@
+/*
+ * fs/devpts/acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <[EMAIL PROTECTED]>
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/fs.h>
+#include <linux/tty.h>
+#include <linux/devpts_fs.h>
+#include <linux/xattr.h>
+#include <linux/generic_acl.h>
+
+static struct posix_acl *
+devpts_get_acl(struct inode *inode, int type)
+{
+       struct posix_acl *acl = NULL;
+
+       spin_lock(&inode->i_lock);
+       if (type == ACL_TYPE_ACCESS)
+               acl = posix_acl_dup(DEVPTS_I(inode)->i_acl);
+       spin_unlock(&inode->i_lock);
+
+       return acl;
+}
+
+static void
+devpts_set_acl(struct inode *inode, int type, struct posix_acl *acl)
+{
+       spin_lock(&inode->i_lock);
+       if (type == ACL_TYPE_ACCESS) {
+               if (DEVPTS_I(inode)->i_acl)
+                       posix_acl_release(DEVPTS_I(inode)->i_acl);
+               DEVPTS_I(inode)->i_acl = posix_acl_dup(acl);
+       }
+       spin_unlock(&inode->i_lock);
+}
+
+struct generic_acl_operations devpts_acl_ops = {
+       .getacl = devpts_get_acl,
+       .setacl = devpts_set_acl,
+};
+
+static size_t
+devpts_list_acl_access(struct inode *inode, char *list, size_t list_size,
+                      const char *name, size_t name_len)
+{
+       return generic_acl_list(inode, &devpts_acl_ops, ACL_TYPE_ACCESS,
+                               list, list_size);
+}
+
+static int
+devpts_get_acl_access(struct inode *inode, const char *name, void *buffer,
+                     size_t size)
+{
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
+       return generic_acl_get(inode, &devpts_acl_ops, ACL_TYPE_ACCESS, buffer,
+                              size);
+}
+
+static int
+devpts_set_acl_access(struct inode *inode, const char *name, const void *value,
+                     size_t size, int flags)
+{
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
+       return generic_acl_set(inode, &devpts_acl_ops, ACL_TYPE_ACCESS, value,
+                              size);
+}
+
+struct xattr_handler devpts_xattr_acl_access_handler = {
+       .prefix = XATTR_NAME_ACL_ACCESS,
+       .list   = devpts_list_acl_access,
+       .get    = devpts_get_acl_access,
+       .set    = devpts_set_acl_access,
+};
+
+int
+devpts_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+       struct inode *inode = dentry->d_inode;
+       int error;
+
+       error = inode_change_ok(inode, iattr);
+       if (error)
+               return error;
+       error = inode_setattr(inode, iattr);
+       if (!error && (iattr->ia_valid & ATTR_MODE))
+               error = generic_acl_chmod(inode, &devpts_acl_ops);
+       return error;
+}
+
+static int
+devpts_check_acl(struct inode *inode, int mask)
+{
+        struct posix_acl *acl = devpts_get_acl(inode, ACL_TYPE_ACCESS);
+
+        if (acl) {
+                int error = posix_acl_permission(inode, acl, mask);
+                posix_acl_release(acl);
+                return error;
+        }
+        return -EAGAIN;
+}
+
+int
+devpts_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+        return generic_permission(inode, mask, devpts_check_acl);
+}

--
Andreas Gruenbacher <[EMAIL PROTECTED]>
SUSE Labs, SUSE LINUX PRODUCTS GMBH

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to