]> git.proxmox.com Git - mirror_spl-debian.git/blobdiff - module/spl/spl-cred.c
Imported Upstream version 0.6.4.1
[mirror_spl-debian.git] / module / spl / spl-cred.c
index c5994aa2056fdfc327a8306a12b4d8f885f5a655..a03f459e04efc25499a4783d3774026a75fb4dd0 100644 (file)
@@ -1,26 +1,28 @@
-/*
- *  This file is part of the SPL: Solaris Porting Layer.
- *
- *  Copyright (c) 2009 Lawrence Livermore National Security, LLC.
- *  Produced at Lawrence Livermore National Laboratory
- *  Written by:
- *          Brian Behlendorf <behlendorf1@llnl.gov>,
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
  *  UCRL-CODE-235197
  *
- *  This is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
  *
- *  This is distributed in the hope that it will be useful, but WITHOUT
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL 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.
  *
  *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
- */
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Credential Implementation.
+\*****************************************************************************/
 
 #include <sys/cred.h>
 
 
 #define DEBUG_SUBSYSTEM S_CRED
 
-#ifdef HAVE_GROUPS_SEARCH
-/* Symbol may be exported by custom kernel patch */
-#define cr_groups_search(gi, grp)      groups_search(gi, grp)
-#else
-/* Implementation from 2.6.30 kernel */
 static int
+#ifdef HAVE_KUIDGID_T
+cr_groups_search(const struct group_info *group_info, kgid_t grp)
+#else
 cr_groups_search(const struct group_info *group_info, gid_t grp)
+#endif
 {
-       unsigned int left, right;
+       unsigned int left, right, mid;
+       int cmp;
 
        if (!group_info)
                return 0;
@@ -46,8 +48,10 @@ cr_groups_search(const struct group_info *group_info, gid_t grp)
        left = 0;
        right = group_info->ngroups;
        while (left < right) {
-               unsigned int mid = (left+right)/2;
-               int cmp = grp - GROUP_AT(group_info, mid);
+               mid = (left + right) / 2;
+               cmp = KGID_TO_SGID(grp) -
+                   KGID_TO_SGID(GROUP_AT(group_info, mid));
+
                if (cmp > 0)
                        left = mid + 1;
                else if (cmp < 0)
@@ -57,14 +61,6 @@ cr_groups_search(const struct group_info *group_info, gid_t grp)
        }
        return 0;
 }
-#endif
-
-#ifdef HAVE_CRED_STRUCT
-
-/*
- * As of 2.6.29 a clean credential API appears in the linux kernel.
- * We attempt to layer the Solaris API on top of the linux API.
- */
 
 /* Hold a reference on the credential and group info */
 void
@@ -82,48 +78,6 @@ crfree(cred_t *cr)
        put_cred((const cred_t *)cr);
 }
 
-/* Return the effective user id */
-uid_t
-crgetuid(const cred_t *cr)
-{
-       return cr->euid;
-}
-
-/* Return the real user id */
-uid_t
-crgetruid(const cred_t *cr)
-{
-       return cr->uid;
-}
-
-/* Return the saved user id */
-uid_t
-crgetsuid(const cred_t *cr)
-{
-       return cr->suid;
-}
-
-/* Return the effective group id */
-gid_t
-crgetgid(const cred_t *cr)
-{
-       return cr->egid;
-}
-
-/* Return the real group id */
-gid_t
-crgetrgid(const cred_t *cr)
-{
-       return cr->gid;
-}
-
-/* Return the saved group id */
-gid_t
-crgetsgid(const cred_t *cr)
-{
-       return cr->sgid;
-}
-
 /* Return the number of supplemental groups */
 int
 crgetngroups(const cred_t *cr)
@@ -150,13 +104,13 @@ crgetgroups(const cred_t *cr)
        gid_t *gids;
 
        gi = get_group_info(cr->group_info);
-       gids = gi->blocks[0];
+       gids = KGIDP_TO_SGIDP(gi->blocks[0]);
        put_group_info(gi);
 
        return gids;
 }
 
-/* Check if the passed gid is available is in supplied credential. */
+/* Check if the passed gid is available in supplied credential. */
 int
 groupmember(gid_t gid, const cred_t *cr)
 {
@@ -164,145 +118,78 @@ groupmember(gid_t gid, const cred_t *cr)
        int rc;
 
        gi = get_group_info(cr->group_info);
-       rc = cr_groups_search(cr->group_info, gid);
+       rc = cr_groups_search(gi, SGID_TO_KGID(gid));
        put_group_info(gi);
 
        return rc;
 }
 
-#else /* HAVE_CRED_STRUCT */
-
-/*
- * Until very recently all credential information was embedded in
- * the linux task struct.  For this reason to simulate a Solaris
- * cred_t we need to pass the entire task structure around.
- */
-
-/* Hold a reference on the credential and group info */
-void
-crhold(cred_t *cr)
-{
-       get_task_struct(cr);
-}
-
-/* Free a reference on the credential and group info */
-void
-crfree(cred_t *cr)
+/* Return the effective user id */
+uid_t
+crgetuid(const cred_t *cr)
 {
-       put_task_struct(cr);
+       return KUID_TO_SUID(cr->euid);
 }
 
-/* Return the effective user id */
+/* Return the real user id */
 uid_t
-crgetuid(const cred_t *cr) {
-       return cr->euid;
+crgetruid(const cred_t *cr)
+{
+       return KUID_TO_SUID(cr->uid);
 }
 
-/* Return the effective real id */
+/* Return the saved user id */
 uid_t
-crgetruid(const cred_t *cr) {
-       return cr->uid;
+crgetsuid(const cred_t *cr)
+{
+       return KUID_TO_SUID(cr->suid);
 }
 
-/* Return the effective saved id */
+/* Return the filesystem user id */
 uid_t
-crgetsuid(const cred_t *cr) {
-       return cr->suid;
+crgetfsuid(const cred_t *cr)
+{
+       return KUID_TO_SUID(cr->fsuid);
 }
 
 /* Return the effective group id */
 gid_t
-crgetgid(const cred_t *cr) {
-       return cr->egid;
+crgetgid(const cred_t *cr)
+{
+       return KGID_TO_SGID(cr->egid);
 }
 
 /* Return the real group id */
 gid_t
-crgetrgid(const cred_t *cr) {
-       return cr->gid;
+crgetrgid(const cred_t *cr)
+{
+       return KGID_TO_SGID(cr->gid);
 }
 
 /* Return the saved group id */
 gid_t
-crgetsgid(const cred_t *cr) {
-       return cr->sgid;
-}
-
-/* Return the number of supplemental groups */
-int
-crgetngroups(const cred_t *cr)
-{
-       int lock, rc;
-
-       lock = (cr != current);
-       if (lock)
-               task_lock((struct task_struct *)cr);
-
-       get_group_info(cr->group_info);
-       rc = cr->group_info->ngroups;
-       put_group_info(cr->group_info);
-
-       if (lock)
-               task_unlock((struct task_struct *)cr);
-
-       return rc;
-}
-
-/*
- * Return an array of supplemental gids.  The returned address is safe
- * to use as long as the caller has taken a reference with crhold().
- * The caller is responsible for releasing the reference with crfree().
- */
-gid_t *
-crgetgroups(const cred_t *cr)
+crgetsgid(const cred_t *cr)
 {
-       gid_t *gids;
-       int lock;
-
-       lock = (cr != current);
-       if (lock)
-               task_lock((struct task_struct *)cr);
-
-       get_group_info(cr->group_info);
-       gids = cr->group_info->blocks[0];
-       put_group_info(cr->group_info);
-
-       if (lock)
-               task_unlock((struct task_struct *)cr);
-
-       return gids;
+       return KGID_TO_SGID(cr->sgid);
 }
 
-/* Check if the passed gid is available is in supplied credential. */
-int
-groupmember(gid_t gid, const cred_t *cr)
+/* Return the filesystem group id */
+gid_t
+crgetfsgid(const cred_t *cr)
 {
-       int lock, rc;
-
-       lock = (cr != current);
-       if (lock)
-               task_lock((struct task_struct *)cr);
-
-       get_group_info(cr->group_info);
-       rc = cr_groups_search(cr->group_info, gid);
-       put_group_info(cr->group_info);
-
-       if (lock)
-               task_unlock((struct task_struct *)cr);
-
-       return rc;
+       return KGID_TO_SGID(cr->fsgid);
 }
 
-#endif /* HAVE_CRED_STRUCT */
-
 EXPORT_SYMBOL(crhold);
 EXPORT_SYMBOL(crfree);
 EXPORT_SYMBOL(crgetuid);
 EXPORT_SYMBOL(crgetruid);
 EXPORT_SYMBOL(crgetsuid);
+EXPORT_SYMBOL(crgetfsuid);
 EXPORT_SYMBOL(crgetgid);
 EXPORT_SYMBOL(crgetrgid);
 EXPORT_SYMBOL(crgetsgid);
+EXPORT_SYMBOL(crgetfsgid);
 EXPORT_SYMBOL(crgetngroups);
 EXPORT_SYMBOL(crgetgroups);
 EXPORT_SYMBOL(groupmember);