OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [sunrpc/] [auth_unix.c] - Diff between revs 1275 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 1275 Rev 1765
/*
/*
 * linux/net/sunrpc/rpcauth_unix.c
 * linux/net/sunrpc/rpcauth_unix.c
 *
 *
 * UNIX-style authentication; no AUTH_SHORT support
 * UNIX-style authentication; no AUTH_SHORT support
 *
 *
 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
 */
 */
 
 
#include <linux/types.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/socket.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/in.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/auth.h>
#include <linux/sunrpc/auth.h>
 
 
#define NFS_NGROUPS     16
#define NFS_NGROUPS     16
struct unx_cred {
struct unx_cred {
        struct rpc_cred         uc_base;
        struct rpc_cred         uc_base;
        uid_t                   uc_fsuid;
        uid_t                   uc_fsuid;
        gid_t                   uc_gid, uc_fsgid;
        gid_t                   uc_gid, uc_fsgid;
        gid_t                   uc_gids[NFS_NGROUPS];
        gid_t                   uc_gids[NFS_NGROUPS];
};
};
#define uc_uid                  uc_base.cr_uid
#define uc_uid                  uc_base.cr_uid
#define uc_count                uc_base.cr_count
#define uc_count                uc_base.cr_count
#define uc_flags                uc_base.cr_flags
#define uc_flags                uc_base.cr_flags
#define uc_expire               uc_base.cr_expire
#define uc_expire               uc_base.cr_expire
 
 
#define UNX_CRED_EXPIRE         (60 * HZ)
#define UNX_CRED_EXPIRE         (60 * HZ)
 
 
#define UNX_WRITESLACK          (21 + (UNX_MAXNODENAME >> 2))
#define UNX_WRITESLACK          (21 + (UNX_MAXNODENAME >> 2))
 
 
#ifdef RPC_DEBUG
#ifdef RPC_DEBUG
# define RPCDBG_FACILITY        RPCDBG_AUTH
# define RPCDBG_FACILITY        RPCDBG_AUTH
#endif
#endif
 
 
static struct rpc_credops       unix_credops;
static struct rpc_credops       unix_credops;
 
 
static struct rpc_auth *
static struct rpc_auth *
unx_create(struct rpc_clnt *clnt)
unx_create(struct rpc_clnt *clnt)
{
{
        struct rpc_auth *auth;
        struct rpc_auth *auth;
 
 
        dprintk("RPC: creating UNIX authenticator for client %p\n", clnt);
        dprintk("RPC: creating UNIX authenticator for client %p\n", clnt);
        if (!(auth = (struct rpc_auth *) rpc_allocate(0, sizeof(*auth))))
        if (!(auth = (struct rpc_auth *) rpc_allocate(0, sizeof(*auth))))
                return NULL;
                return NULL;
        auth->au_cslack = UNX_WRITESLACK;
        auth->au_cslack = UNX_WRITESLACK;
        auth->au_rslack = 2;    /* assume AUTH_NULL verf */
        auth->au_rslack = 2;    /* assume AUTH_NULL verf */
        auth->au_expire = UNX_CRED_EXPIRE;
        auth->au_expire = UNX_CRED_EXPIRE;
        auth->au_ops = &authunix_ops;
        auth->au_ops = &authunix_ops;
 
 
        rpcauth_init_credcache(auth);
        rpcauth_init_credcache(auth);
 
 
        return auth;
        return auth;
}
}
 
 
static void
static void
unx_destroy(struct rpc_auth *auth)
unx_destroy(struct rpc_auth *auth)
{
{
        dprintk("RPC: destroying UNIX authenticator %p\n", auth);
        dprintk("RPC: destroying UNIX authenticator %p\n", auth);
        rpcauth_free_credcache(auth);
        rpcauth_free_credcache(auth);
        rpc_free(auth);
        rpc_free(auth);
}
}
 
 
static struct rpc_cred *
static struct rpc_cred *
unx_create_cred(int flags)
unx_create_cred(int flags)
{
{
        struct unx_cred *cred;
        struct unx_cred *cred;
        int             i;
        int             i;
 
 
        dprintk("RPC:      allocating UNIX cred for uid %d gid %d\n",
        dprintk("RPC:      allocating UNIX cred for uid %d gid %d\n",
                                current->uid, current->gid);
                                current->uid, current->gid);
 
 
        if (!(cred = (struct unx_cred *) rpc_allocate(flags, sizeof(*cred))))
        if (!(cred = (struct unx_cred *) rpc_allocate(flags, sizeof(*cred))))
                return NULL;
                return NULL;
 
 
        atomic_set(&cred->uc_count, 0);
        atomic_set(&cred->uc_count, 0);
        cred->uc_flags = RPCAUTH_CRED_UPTODATE;
        cred->uc_flags = RPCAUTH_CRED_UPTODATE;
        if (flags & RPC_TASK_ROOTCREDS) {
        if (flags & RPC_TASK_ROOTCREDS) {
                cred->uc_uid = cred->uc_fsuid = 0;
                cred->uc_uid = cred->uc_fsuid = 0;
                cred->uc_gid = cred->uc_fsgid = 0;
                cred->uc_gid = cred->uc_fsgid = 0;
                cred->uc_gids[0] = NOGROUP;
                cred->uc_gids[0] = NOGROUP;
        } else {
        } else {
                int groups = current->ngroups;
                int groups = current->ngroups;
                if (groups > NFS_NGROUPS)
                if (groups > NFS_NGROUPS)
                        groups = NFS_NGROUPS;
                        groups = NFS_NGROUPS;
 
 
                cred->uc_uid = current->uid;
                cred->uc_uid = current->uid;
                cred->uc_gid = current->gid;
                cred->uc_gid = current->gid;
                cred->uc_fsuid = current->fsuid;
                cred->uc_fsuid = current->fsuid;
                cred->uc_fsgid = current->fsgid;
                cred->uc_fsgid = current->fsgid;
                for (i = 0; i < groups; i++)
                for (i = 0; i < groups; i++)
                        cred->uc_gids[i] = (gid_t) current->groups[i];
                        cred->uc_gids[i] = (gid_t) current->groups[i];
                if (i < NFS_NGROUPS)
                if (i < NFS_NGROUPS)
                  cred->uc_gids[i] = NOGROUP;
                  cred->uc_gids[i] = NOGROUP;
        }
        }
        cred->uc_base.cr_ops = &unix_credops;
        cred->uc_base.cr_ops = &unix_credops;
 
 
        return (struct rpc_cred *) cred;
        return (struct rpc_cred *) cred;
}
}
 
 
struct rpc_cred *
struct rpc_cred *
authunix_fake_cred(struct rpc_task *task, uid_t uid, gid_t gid)
authunix_fake_cred(struct rpc_task *task, uid_t uid, gid_t gid)
{
{
        struct unx_cred *cred;
        struct unx_cred *cred;
 
 
        dprintk("RPC:      allocating fake UNIX cred for uid %d gid %d\n",
        dprintk("RPC:      allocating fake UNIX cred for uid %d gid %d\n",
                                uid, gid);
                                uid, gid);
 
 
        if (!(cred = (struct unx_cred *) rpc_malloc(task, sizeof(*cred))))
        if (!(cred = (struct unx_cred *) rpc_malloc(task, sizeof(*cred))))
                return NULL;
                return NULL;
 
 
        atomic_set(&cred->uc_count, 1);
        atomic_set(&cred->uc_count, 1);
        cred->uc_flags = RPCAUTH_CRED_DEAD|RPCAUTH_CRED_UPTODATE;
        cred->uc_flags = RPCAUTH_CRED_DEAD|RPCAUTH_CRED_UPTODATE;
        cred->uc_uid   = uid;
        cred->uc_uid   = uid;
        cred->uc_gid   = gid;
        cred->uc_gid   = gid;
        cred->uc_fsuid = uid;
        cred->uc_fsuid = uid;
        cred->uc_fsgid = gid;
        cred->uc_fsgid = gid;
        cred->uc_gids[0] = (gid_t) NOGROUP;
        cred->uc_gids[0] = (gid_t) NOGROUP;
 
 
        return task->tk_msg.rpc_cred = (struct rpc_cred *) cred;
        return task->tk_msg.rpc_cred = (struct rpc_cred *) cred;
}
}
 
 
static void
static void
unx_destroy_cred(struct rpc_cred *cred)
unx_destroy_cred(struct rpc_cred *cred)
{
{
        rpc_free(cred);
        rpc_free(cred);
}
}
 
 
/*
/*
 * Match credentials against current process creds.
 * Match credentials against current process creds.
 * The root_override argument takes care of cases where the caller may
 * The root_override argument takes care of cases where the caller may
 * request root creds (e.g. for NFS swapping).
 * request root creds (e.g. for NFS swapping).
 */
 */
static int
static int
unx_match(struct rpc_cred *rcred, int taskflags)
unx_match(struct rpc_cred *rcred, int taskflags)
{
{
        struct unx_cred *cred = (struct unx_cred *) rcred;
        struct unx_cred *cred = (struct unx_cred *) rcred;
        int             i;
        int             i;
 
 
        if (!(taskflags & RPC_TASK_ROOTCREDS)) {
        if (!(taskflags & RPC_TASK_ROOTCREDS)) {
                int groups;
                int groups;
 
 
                if (cred->uc_uid != current->uid
                if (cred->uc_uid != current->uid
                 || cred->uc_gid != current->gid
                 || cred->uc_gid != current->gid
                 || cred->uc_fsuid != current->fsuid
                 || cred->uc_fsuid != current->fsuid
                 || cred->uc_fsgid != current->fsgid)
                 || cred->uc_fsgid != current->fsgid)
                        return 0;
                        return 0;
 
 
                groups = current->ngroups;
                groups = current->ngroups;
                if (groups > NFS_NGROUPS)
                if (groups > NFS_NGROUPS)
                        groups = NFS_NGROUPS;
                        groups = NFS_NGROUPS;
                for (i = 0; i < groups ; i++)
                for (i = 0; i < groups ; i++)
                        if (cred->uc_gids[i] != (gid_t) current->groups[i])
                        if (cred->uc_gids[i] != (gid_t) current->groups[i])
                                return 0;
                                return 0;
                return 1;
                return 1;
        }
        }
        return (cred->uc_uid == 0 && cred->uc_fsuid == 0
        return (cred->uc_uid == 0 && cred->uc_fsuid == 0
             && cred->uc_gid == 0 && cred->uc_fsgid == 0
             && cred->uc_gid == 0 && cred->uc_fsgid == 0
             && cred->uc_gids[0] == (gid_t) NOGROUP);
             && cred->uc_gids[0] == (gid_t) NOGROUP);
}
}
 
 
/*
/*
 * Marshal credentials.
 * Marshal credentials.
 * Maybe we should keep a cached credential for performance reasons.
 * Maybe we should keep a cached credential for performance reasons.
 */
 */
static u32 *
static u32 *
unx_marshal(struct rpc_task *task, u32 *p, int ruid)
unx_marshal(struct rpc_task *task, u32 *p, int ruid)
{
{
        struct rpc_clnt *clnt = task->tk_client;
        struct rpc_clnt *clnt = task->tk_client;
        struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
        struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
        u32             *base, *hold;
        u32             *base, *hold;
        int             i, n;
        int             i, n;
 
 
        *p++ = htonl(RPC_AUTH_UNIX);
        *p++ = htonl(RPC_AUTH_UNIX);
        base = p++;
        base = p++;
        *p++ = htonl(jiffies/HZ);
        *p++ = htonl(jiffies/HZ);
 
 
        /*
        /*
         * Copy the UTS nodename captured when the client was created.
         * Copy the UTS nodename captured when the client was created.
         */
         */
        n = clnt->cl_nodelen;
        n = clnt->cl_nodelen;
        *p++ = htonl(n);
        *p++ = htonl(n);
        memcpy(p, clnt->cl_nodename, n);
        memcpy(p, clnt->cl_nodename, n);
        p += (n + 3) >> 2;
        p += (n + 3) >> 2;
 
 
        /* Note: we don't use real uid if it involves raising priviledge */
        /* Note: we don't use real uid if it involves raising priviledge */
        if (ruid && cred->uc_uid != 0 && cred->uc_gid != 0) {
        if (ruid && cred->uc_uid != 0 && cred->uc_gid != 0) {
                *p++ = htonl((u32) cred->uc_uid);
                *p++ = htonl((u32) cred->uc_uid);
                *p++ = htonl((u32) cred->uc_gid);
                *p++ = htonl((u32) cred->uc_gid);
        } else {
        } else {
                *p++ = htonl((u32) cred->uc_fsuid);
                *p++ = htonl((u32) cred->uc_fsuid);
                *p++ = htonl((u32) cred->uc_fsgid);
                *p++ = htonl((u32) cred->uc_fsgid);
        }
        }
        hold = p++;
        hold = p++;
        for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
        for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
                *p++ = htonl((u32) cred->uc_gids[i]);
                *p++ = htonl((u32) cred->uc_gids[i]);
        *hold = htonl(p - hold - 1);            /* gid array length */
        *hold = htonl(p - hold - 1);            /* gid array length */
        *base = htonl((p - base - 1) << 2);     /* cred length */
        *base = htonl((p - base - 1) << 2);     /* cred length */
 
 
        *p++ = htonl(RPC_AUTH_NULL);
        *p++ = htonl(RPC_AUTH_NULL);
        *p++ = htonl(0);
        *p++ = htonl(0);
 
 
        return p;
        return p;
}
}
 
 
/*
/*
 * Refresh credentials. This is a no-op for AUTH_UNIX
 * Refresh credentials. This is a no-op for AUTH_UNIX
 */
 */
static int
static int
unx_refresh(struct rpc_task *task)
unx_refresh(struct rpc_task *task)
{
{
        task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
        task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
        return task->tk_status = -EACCES;
        return task->tk_status = -EACCES;
}
}
 
 
static u32 *
static u32 *
unx_validate(struct rpc_task *task, u32 *p)
unx_validate(struct rpc_task *task, u32 *p)
{
{
        u32             n = ntohl(*p++);
        u32             n = ntohl(*p++);
 
 
        if (n != RPC_AUTH_NULL && n != RPC_AUTH_UNIX && n != RPC_AUTH_SHORT) {
        if (n != RPC_AUTH_NULL && n != RPC_AUTH_UNIX && n != RPC_AUTH_SHORT) {
                printk("RPC: bad verf flavor: %ld\n", (unsigned long) n);
                printk("RPC: bad verf flavor: %ld\n", (unsigned long) n);
                return NULL;
                return NULL;
        }
        }
        if ((n = ntohl(*p++)) > 400) {
        if ((n = ntohl(*p++)) > 400) {
                printk("RPC: giant verf size: %ld\n", (unsigned long) n);
                printk("RPC: giant verf size: %ld\n", (unsigned long) n);
                return NULL;
                return NULL;
        }
        }
        task->tk_auth->au_rslack = (n >> 2) + 2;
        task->tk_auth->au_rslack = (n >> 2) + 2;
        p += (n >> 2);
        p += (n >> 2);
 
 
        return p;
        return p;
}
}
 
 
struct rpc_authops      authunix_ops = {
struct rpc_authops      authunix_ops = {
        RPC_AUTH_UNIX,
        RPC_AUTH_UNIX,
#ifdef RPC_DEBUG
#ifdef RPC_DEBUG
        "UNIX",
        "UNIX",
#endif
#endif
        unx_create,
        unx_create,
        unx_destroy,
        unx_destroy,
        unx_create_cred
        unx_create_cred
};
};
 
 
static
static
struct rpc_credops      unix_credops = {
struct rpc_credops      unix_credops = {
        unx_destroy_cred,
        unx_destroy_cred,
        unx_match,
        unx_match,
        unx_marshal,
        unx_marshal,
        unx_refresh,
        unx_refresh,
        unx_validate
        unx_validate
};
};
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.