Whamcloud - gitweb
LU-1330 obdclass: splits server-side object stack from client
[fs/lustre-release.git] / lustre / obdclass / acl.c
index d358f54..b16289c 100644 (file)
@@ -1,36 +1,54 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
+/*
+ * GPL HEADER START
  *
- *   lustre/obdclass/acl.c
- *   Lustre Access Control List.
- *   Author: Fan Yong <fanyong@clusterfs.com>
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * Copyright (c) 2004-2007 Cluster File Systems, Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
  *
- *   This file is part of Lustre, http://www.lustre.org.
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
  *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
  *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/obdclass/acl.c
+ *
+ * Lustre Access Control List.
+ *
+ * Author: Fan Yong <fanyong@clusterfs.com>
  */
-#ifndef EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
 
 #define DEBUG_SUBSYSTEM S_SEC
-
-#include <linux/lustre_acl.h>
+#include <lu_object.h>
+#include <lustre_acl.h>
 #include <lustre_eacl.h>
 #include <obd_support.h>
+#ifdef HAVE_SERVER_SUPPORT
+# include <lustre_idmap.h>
+# include <md_object.h>
+#endif /* HAVE_SERVER_SUPPORT */
 
 #ifdef CONFIG_FS_POSIX_ACL
 
@@ -78,12 +96,13 @@ static inline void lustre_posix_acl_cpu_to_le(posix_acl_xattr_entry *d,
         d->e_id         = cpu_to_le32(s->e_id);
 }
 
+#ifdef HAVE_SERVER_SUPPORT
 /*
  * Check permission based on POSIX ACL.
  */
-int lustre_posix_acl_permission(struct md_ucred *mu, struct lu_attr *la,
-                                int want, posix_acl_xattr_entry *entry,
-                                int count)
+int lustre_posix_acl_permission(struct lu_ucred *mu, struct lu_attr *la,
+                               int want, posix_acl_xattr_entry *entry,
+                               int count)
 {
         posix_acl_xattr_entry *pa, *pe, *mask_obj;
         posix_acl_xattr_entry ae, me;
@@ -97,12 +116,12 @@ int lustre_posix_acl_permission(struct md_ucred *mu, struct lu_attr *la,
                 switch (ae.e_tag) {
                 case ACL_USER_OBJ:
                         /* (May have been checked already) */
-                        if (la->la_uid == mu->mu_fsuid)
-                                goto check_perm;
+                       if (la->la_uid == mu->uc_fsuid)
+                               goto check_perm;
                         break;
                 case ACL_USER:
-                        if (ae.e_id == mu->mu_fsuid)
-                                goto mask;
+                       if (ae.e_id == mu->uc_fsuid)
+                               goto mask;
                         break;
                 case ACL_GROUP_OBJ:
                         if (lustre_in_group_p(mu, la->la_gid)) {
@@ -193,6 +212,49 @@ int lustre_posix_acl_chmod_masq(posix_acl_xattr_entry *entry, __u32 mode,
 EXPORT_SYMBOL(lustre_posix_acl_chmod_masq);
 
 /*
+ * Returns 0 if the acl can be exactly represented in the traditional
+ * file mode permission bits, or else 1. Returns -E... on error.
+ */
+       int
+lustre_posix_acl_equiv_mode(posix_acl_xattr_entry *entry, mode_t *mode_p,
+               int count)
+{
+       posix_acl_xattr_entry *pa, *pe;
+       mode_t                 mode = 0;
+       int                    not_equiv = 0;
+
+       for (pa = &entry[0], pe = &entry[count - 1]; pa <= pe; pa++) {
+               __u16 perm = le16_to_cpu(pa->e_perm);
+               switch (le16_to_cpu(pa->e_tag)) {
+                       case ACL_USER_OBJ:
+                               mode |= (perm & S_IRWXO) << 6;
+                               break;
+                       case ACL_GROUP_OBJ:
+                               mode |= (perm & S_IRWXO) << 3;
+                               break;
+                       case ACL_OTHER:
+                               mode |= perm & S_IRWXO;
+                               break;
+                       case ACL_MASK:
+                               mode = (mode & ~S_IRWXG) |
+                                       ((perm & S_IRWXO) << 3);
+                               not_equiv = 1;
+                               break;
+                       case ACL_USER:
+                       case ACL_GROUP:
+                               not_equiv = 1;
+                               break;
+                       default:
+                               return -EINVAL;
+               }
+       }
+       if (mode_p)
+               *mode_p = (*mode_p & ~S_IRWXUGO) | mode;
+       return not_equiv;
+}
+EXPORT_SYMBOL(lustre_posix_acl_equiv_mode);
+
+/*
  * Modify acl when creating a new object.
  */
 int lustre_posix_acl_create_masq(posix_acl_xattr_entry *entry, __u32 *pmode,
@@ -251,6 +313,136 @@ int lustre_posix_acl_create_masq(posix_acl_xattr_entry *entry, __u32 *pmode,
 }
 EXPORT_SYMBOL(lustre_posix_acl_create_masq);
 
+/*
+ * Convert server-side uid/gid in the posix ACL items to the client-side ones.
+ * convert rule:
+ * @CFS_IC_NOTHING
+ *  nothing to be converted.
+ * @CFS_IC_ALL
+ *  mapped ids are converted to client-side ones,
+ *  unmapped ones are converted to "nobody".
+ * @CFS_IC_MAPPED
+ *  only mapped ids are converted to "nobody".
+ * @CFS_IC_UNMAPPED
+ *  only unmapped ids are converted to "nobody".
+ */
+int lustre_posix_acl_xattr_id2client(struct lu_ucred *mu,
+                                    struct lustre_idmap_table *t,
+                                    posix_acl_xattr_header *header,
+                                    int size, int flags)
+{
+       int count, i;
+       __u32 id;
+       ENTRY;
+
+       if (unlikely(size < 0))
+               RETURN(-EINVAL);
+       else if (!size)
+               RETURN(0);
+
+       if (unlikely(flags == CFS_IC_NOTHING))
+               RETURN(0);
+
+       count = CFS_ACL_XATTR_COUNT(size, posix_acl_xattr);
+       for (i = 0; i < count; i++) {
+               id = le32_to_cpu(header->a_entries[i].e_id);
+               switch (le16_to_cpu(header->a_entries[i].e_tag)) {
+               case ACL_USER_OBJ:
+               case ACL_GROUP_OBJ:
+               case ACL_MASK:
+               case ACL_OTHER:
+                       if (id != ACL_UNDEFINED_ID)
+                               RETURN(-EIO);
+                       break;
+               case ACL_USER:
+                       id = lustre_idmap_lookup_uid(mu, t, 1, id);
+                       if (flags == CFS_IC_ALL) {
+                               if (id == CFS_IDMAP_NOTFOUND)
+                                       id = NOBODY_UID;
+                               header->a_entries[i].e_id = cpu_to_le32(id);
+                       } else if (flags == CFS_IC_MAPPED) {
+                               if (id != CFS_IDMAP_NOTFOUND)
+                                       header->a_entries[i].e_id =
+                                               cpu_to_le32(NOBODY_UID);
+                       } else if (flags == CFS_IC_UNMAPPED) {
+                               if (id == CFS_IDMAP_NOTFOUND)
+                                       header->a_entries[i].e_id =
+                                               cpu_to_le32(NOBODY_UID);
+                       }
+                       break;
+               case ACL_GROUP:
+                       id = lustre_idmap_lookup_gid(mu, t, 1, id);
+                       if (flags == CFS_IC_ALL) {
+                               if (id == CFS_IDMAP_NOTFOUND)
+                                       id = NOBODY_GID;
+                               header->a_entries[i].e_id = cpu_to_le32(id);
+                       } else if (flags == CFS_IC_MAPPED) {
+                               if (id != CFS_IDMAP_NOTFOUND)
+                                       header->a_entries[i].e_id =
+                                               cpu_to_le32(NOBODY_GID);
+                       } else if (flags == CFS_IC_UNMAPPED) {
+                               if (id == CFS_IDMAP_NOTFOUND)
+                                       header->a_entries[i].e_id =
+                                               cpu_to_le32(NOBODY_GID);
+                       }
+                       break;
+               default:
+                       RETURN(-EIO);
+               }
+       }
+
+       RETURN(0);
+}
+EXPORT_SYMBOL(lustre_posix_acl_xattr_id2client);
+
+/*
+ * Converts client-side uid/gid in the extended ACL items to server-side ones.
+ * convert rule:
+ *  mapped ids are converted to server-side ones,
+ *  unmapped ones cause "EPERM" error.
+ */
+int lustre_ext_acl_xattr_id2server(struct lu_ucred *mu,
+                                  struct lustre_idmap_table *t,
+                                  ext_acl_xattr_header *header)
+{
+       int i, count = le32_to_cpu(header->a_count);
+       __u32 id;
+       ENTRY;
+
+       for (i = 0; i < count; i++) {
+               id = le32_to_cpu(header->a_entries[i].e_id);
+               switch (le16_to_cpu(header->a_entries[i].e_tag)) {
+               case ACL_USER_OBJ:
+               case ACL_GROUP_OBJ:
+               case ACL_MASK:
+               case ACL_OTHER:
+                       if (id != ACL_UNDEFINED_ID)
+                               RETURN(-EIO);
+                       break;
+               case ACL_USER:
+                       id = lustre_idmap_lookup_uid(mu, t, 0, id);
+                       if (id == CFS_IDMAP_NOTFOUND)
+                               RETURN(-EPERM);
+                       else
+                               header->a_entries[i].e_id = cpu_to_le32(id);
+                       break;
+               case ACL_GROUP:
+                       id = lustre_idmap_lookup_gid(mu, t, 0, id);
+                       if (id == CFS_IDMAP_NOTFOUND)
+                               RETURN(-EPERM);
+                       else
+                               header->a_entries[i].e_id = cpu_to_le32(id);
+                       break;
+               default:
+                       RETURN(-EIO);
+               }
+       }
+
+       RETURN(0);
+}
+EXPORT_SYMBOL(lustre_ext_acl_xattr_id2server);
+#endif /* HAVE_SERVER_SUPPORT */
+
 /* if "new_count == 0", then "new = {a_version, NULL}", NOT NULL. */
 static int lustre_posix_acl_xattr_reduce_space(posix_acl_xattr_header **header,
                                                int old_count, int new_count)
@@ -398,87 +590,6 @@ _out:
 EXPORT_SYMBOL(lustre_posix_acl_xattr_filter);
 
 /*
- * Convert server-side uid/gid in the posix ACL items to the client-side ones.
- * convert rule:
- * @CFS_IC_NOTHING
- *  nothing to be converted.
- * @CFS_IC_ALL
- *  mapped ids are converted to client-side ones,
- *  unmapped ones are converted to "nobody".
- * @CFS_IC_MAPPED
- *  only mapped ids are converted to "nobody".
- * @CFS_IC_UNMAPPED
- *  only unmapped ids are converted to "nobody".
- */
-int lustre_posix_acl_xattr_id2client(struct md_ucred *mu,
-                                     struct lustre_idmap_table *t,
-                                     posix_acl_xattr_header *header,
-                                     int size, int flags)
-{
-        int count, i;
-        __u32 id;
-        ENTRY;
-
-        if (unlikely(size < 0))
-                RETURN(-EINVAL);
-        else if (!size)
-                RETURN(0);
-
-        if (unlikely(flags == CFS_IC_NOTHING))
-                RETURN(0);
-
-        count = CFS_ACL_XATTR_COUNT(size, posix_acl_xattr);
-        for (i = 0; i < count; i++) {
-                id = le32_to_cpu(header->a_entries[i].e_id);
-                switch (le16_to_cpu(header->a_entries[i].e_tag)) {
-                case ACL_USER_OBJ:
-                case ACL_GROUP_OBJ:
-                case ACL_MASK:
-                case ACL_OTHER:
-                        if (id != ACL_UNDEFINED_ID)
-                                RETURN(-EIO);
-                        break;
-                case ACL_USER:
-                        id = lustre_idmap_lookup_uid(mu, t, 1, id);
-                        if (flags == CFS_IC_ALL) {
-                                if (id == CFS_IDMAP_NOTFOUND)
-                                        id = NOBODY_UID;
-                                header->a_entries[i].e_id = cpu_to_le32(id);
-                        } else if (flags == CFS_IC_MAPPED) {
-                                if (id != CFS_IDMAP_NOTFOUND)
-                                        header->a_entries[i].e_id =
-                                                        cpu_to_le32(NOBODY_UID);
-                        } else if (flags == CFS_IC_UNMAPPED) {
-                                if (id == CFS_IDMAP_NOTFOUND)
-                                        header->a_entries[i].e_id =
-                                                        cpu_to_le32(NOBODY_UID);
-                        }
-                        break;
-                case ACL_GROUP:
-                        id = lustre_idmap_lookup_gid(mu, t, 1, id);
-                        if (flags == CFS_IC_ALL) {
-                                if (id == CFS_IDMAP_NOTFOUND)
-                                        id = NOBODY_GID;
-                                header->a_entries[i].e_id = cpu_to_le32(id);
-                        } else if (flags == CFS_IC_MAPPED) {
-                                if (id != CFS_IDMAP_NOTFOUND)
-                                        header->a_entries[i].e_id =
-                                                        cpu_to_le32(NOBODY_GID);
-                        } else if (flags == CFS_IC_UNMAPPED) {
-                                if (id == CFS_IDMAP_NOTFOUND)
-                                        header->a_entries[i].e_id =
-                                                        cpu_to_le32(NOBODY_GID);
-                        }
-                        break;
-                 default:
-                        RETURN(-EIO);
-                }
-        }
-    RETURN(0);
-}
-EXPORT_SYMBOL(lustre_posix_acl_xattr_id2client);
-
-/*
  * Release the posix ACL space.
  */
 void lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size)
@@ -488,53 +599,6 @@ void lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size)
 EXPORT_SYMBOL(lustre_posix_acl_xattr_free);
 
 /*
- * Converts client-side uid/gid in the extended ACL items to server-side ones.
- * convert rule:
- *  mapped ids are converted to server-side ones,
- *  unmapped ones cause "EPERM" error.
- */
-int lustre_ext_acl_xattr_id2server(struct md_ucred *mu,
-                                   struct lustre_idmap_table *t,
-                                   ext_acl_xattr_header *header)
-
-{
-        int i, count = le32_to_cpu(header->a_count);
-        __u32 id;
-        ENTRY;
-
-        for (i = 0; i < count; i++) {
-                id = le32_to_cpu(header->a_entries[i].e_id);
-                switch (le16_to_cpu(header->a_entries[i].e_tag)) {
-                case ACL_USER_OBJ:
-                case ACL_GROUP_OBJ:
-                case ACL_MASK:
-                case ACL_OTHER:
-                        if (id != ACL_UNDEFINED_ID)
-                                RETURN(-EIO);
-                        break;
-                case ACL_USER:
-                        id = lustre_idmap_lookup_uid(mu, t, 0, id);
-                        if (id == CFS_IDMAP_NOTFOUND)
-                                RETURN(-EPERM);
-                        else
-                                header->a_entries[i].e_id = cpu_to_le32(id);
-                        break;
-                case ACL_GROUP:
-                        id = lustre_idmap_lookup_gid(mu, t, 0, id);
-                        if (id == CFS_IDMAP_NOTFOUND)
-                                RETURN(-EPERM);
-                        else
-                                header->a_entries[i].e_id = cpu_to_le32(id);
-                        break;
-                default:
-                        RETURN(-EIO);
-                }
-        }
-        RETURN(0);
-}
-EXPORT_SYMBOL(lustre_ext_acl_xattr_id2server);
-
-/*
  * Release the extended ACL space.
  */
 void lustre_ext_acl_xattr_free(ext_acl_xattr_header *header)
@@ -748,12 +812,12 @@ lustre_acl_xattr_merge2ext(posix_acl_xattr_header *posix_header, int size,
                                 if (posix_header->a_entries[i].e_perm !=
                                                                 ee->e_perm)
                                         /* entry modified. */
-                                        ee->e_perm =
+                                        ee->e_stat =
                                         new->a_entries[j++].e_stat =
                                                         cpu_to_le32(ES_MOD);
                                 else
                                         /* entry unchanged. */
-                                        ee->e_perm =
+                                        ee->e_stat =
                                         new->a_entries[j++].e_stat =
                                                         cpu_to_le32(ES_UNC);
                         } else {
@@ -778,12 +842,12 @@ lustre_acl_xattr_merge2ext(posix_acl_xattr_header *posix_header, int size,
                                 if (posix_header->a_entries[i].e_perm !=
                                                                 ee->e_perm)
                                         /* entry modified. */
-                                        ee->e_perm =
+                                        ee->e_stat =
                                         new->a_entries[j++].e_stat =
                                                         cpu_to_le32(ES_MOD);
                                 else
                                         /* entry unchanged. */
-                                        ee->e_perm =
+                                        ee->e_stat =
                                         new->a_entries[j++].e_stat =
                                                         cpu_to_le32(ES_UNC);
                         } else {