LCOV - code coverage report
Current view: top level - net/sunrpc - auth_unix.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 73 0.0 %
Date: 2014-04-07 Functions: 0 12 0.0 %
Branches: 0 38 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * linux/net/sunrpc/auth_unix.c
       3                 :            :  *
       4                 :            :  * UNIX-style authentication; no AUTH_SHORT support
       5                 :            :  *
       6                 :            :  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
       7                 :            :  */
       8                 :            : 
       9                 :            : #include <linux/slab.h>
      10                 :            : #include <linux/types.h>
      11                 :            : #include <linux/sched.h>
      12                 :            : #include <linux/module.h>
      13                 :            : #include <linux/sunrpc/clnt.h>
      14                 :            : #include <linux/sunrpc/auth.h>
      15                 :            : #include <linux/user_namespace.h>
      16                 :            : 
      17                 :            : #define NFS_NGROUPS     16
      18                 :            : 
      19                 :            : struct unx_cred {
      20                 :            :         struct rpc_cred         uc_base;
      21                 :            :         kgid_t                  uc_gid;
      22                 :            :         kgid_t                  uc_gids[NFS_NGROUPS];
      23                 :            : };
      24                 :            : #define uc_uid                  uc_base.cr_uid
      25                 :            : 
      26                 :            : #define UNX_WRITESLACK          (21 + (UNX_MAXNODENAME >> 2))
      27                 :            : 
      28                 :            : #ifdef RPC_DEBUG
      29                 :            : # define RPCDBG_FACILITY        RPCDBG_AUTH
      30                 :            : #endif
      31                 :            : 
      32                 :            : static struct rpc_auth          unix_auth;
      33                 :            : static const struct rpc_credops unix_credops;
      34                 :            : 
      35                 :            : static struct rpc_auth *
      36                 :          0 : unx_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
      37                 :            : {
      38                 :            :         dprintk("RPC:       creating UNIX authenticator for client %p\n",
      39                 :            :                         clnt);
      40                 :            :         atomic_inc(&unix_auth.au_count);
      41                 :          0 :         return &unix_auth;
      42                 :            : }
      43                 :            : 
      44                 :            : static void
      45                 :          0 : unx_destroy(struct rpc_auth *auth)
      46                 :            : {
      47                 :            :         dprintk("RPC:       destroying UNIX authenticator %p\n", auth);
      48                 :          0 :         rpcauth_clear_credcache(auth->au_credcache);
      49                 :          0 : }
      50                 :            : 
      51                 :            : /*
      52                 :            :  * Lookup AUTH_UNIX creds for current process
      53                 :            :  */
      54                 :            : static struct rpc_cred *
      55                 :          0 : unx_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
      56                 :            : {
      57                 :          0 :         return rpcauth_lookup_credcache(auth, acred, flags);
      58                 :            : }
      59                 :            : 
      60                 :            : static struct rpc_cred *
      61                 :          0 : unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
      62                 :            : {
      63                 :            :         struct unx_cred *cred;
      64                 :            :         unsigned int groups = 0;
      65                 :            :         unsigned int i;
      66                 :            : 
      67                 :            :         dprintk("RPC:       allocating UNIX cred for uid %d gid %d\n",
      68                 :            :                         from_kuid(&init_user_ns, acred->uid),
      69                 :            :                         from_kgid(&init_user_ns, acred->gid));
      70                 :            : 
      71         [ #  # ]:          0 :         if (!(cred = kmalloc(sizeof(*cred), GFP_NOFS)))
      72                 :            :                 return ERR_PTR(-ENOMEM);
      73                 :            : 
      74                 :          0 :         rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops);
      75                 :          0 :         cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
      76                 :            : 
      77         [ #  # ]:          0 :         if (acred->group_info != NULL)
      78                 :          0 :                 groups = acred->group_info->ngroups;
      79         [ #  # ]:          0 :         if (groups > NFS_NGROUPS)
      80                 :            :                 groups = NFS_NGROUPS;
      81                 :            : 
      82                 :          0 :         cred->uc_gid = acred->gid;
      83         [ #  # ]:          0 :         for (i = 0; i < groups; i++)
      84                 :          0 :                 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
      85         [ #  # ]:          0 :         if (i < NFS_NGROUPS)
      86                 :          0 :                 cred->uc_gids[i] = INVALID_GID;
      87                 :            : 
      88                 :          0 :         return &cred->uc_base;
      89                 :            : }
      90                 :            : 
      91                 :            : static void
      92                 :            : unx_free_cred(struct unx_cred *unx_cred)
      93                 :            : {
      94                 :            :         dprintk("RPC:       unx_free_cred %p\n", unx_cred);
      95                 :          0 :         kfree(unx_cred);
      96                 :            : }
      97                 :            : 
      98                 :            : static void
      99                 :          0 : unx_free_cred_callback(struct rcu_head *head)
     100                 :            : {
     101                 :          0 :         struct unx_cred *unx_cred = container_of(head, struct unx_cred, uc_base.cr_rcu);
     102                 :            :         unx_free_cred(unx_cred);
     103                 :          0 : }
     104                 :            : 
     105                 :            : static void
     106                 :          0 : unx_destroy_cred(struct rpc_cred *cred)
     107                 :            : {
     108                 :          0 :         call_rcu(&cred->cr_rcu, unx_free_cred_callback);
     109                 :          0 : }
     110                 :            : 
     111                 :            : /*
     112                 :            :  * Match credentials against current process creds.
     113                 :            :  * The root_override argument takes care of cases where the caller may
     114                 :            :  * request root creds (e.g. for NFS swapping).
     115                 :            :  */
     116                 :            : static int
     117                 :          0 : unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
     118                 :            : {
     119                 :            :         struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base);
     120                 :            :         unsigned int groups = 0;
     121                 :            :         unsigned int i;
     122                 :            : 
     123                 :            : 
     124 [ #  # ][ #  # ]:          0 :         if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
     125                 :            :                 return 0;
     126                 :            : 
     127         [ #  # ]:          0 :         if (acred->group_info != NULL)
     128                 :          0 :                 groups = acred->group_info->ngroups;
     129         [ #  # ]:          0 :         if (groups > NFS_NGROUPS)
     130                 :            :                 groups = NFS_NGROUPS;
     131         [ #  # ]:          0 :         for (i = 0; i < groups ; i++)
     132         [ #  # ]:          0 :                 if (!gid_eq(cred->uc_gids[i], GROUP_AT(acred->group_info, i)))
     133                 :            :                         return 0;
     134 [ #  # ][ #  # ]:          0 :         if (groups < NFS_NGROUPS && gid_valid(cred->uc_gids[groups]))
     135                 :            :                 return 0;
     136                 :          0 :         return 1;
     137                 :            : }
     138                 :            : 
     139                 :            : /*
     140                 :            :  * Marshal credentials.
     141                 :            :  * Maybe we should keep a cached credential for performance reasons.
     142                 :            :  */
     143                 :            : static __be32 *
     144                 :          0 : unx_marshal(struct rpc_task *task, __be32 *p)
     145                 :            : {
     146                 :          0 :         struct rpc_clnt *clnt = task->tk_client;
     147                 :          0 :         struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
     148                 :            :         __be32          *base, *hold;
     149                 :            :         int             i;
     150                 :            : 
     151                 :          0 :         *p++ = htonl(RPC_AUTH_UNIX);
     152                 :          0 :         base = p++;
     153                 :          0 :         *p++ = htonl(jiffies/HZ);
     154                 :            : 
     155                 :            :         /*
     156                 :            :          * Copy the UTS nodename captured when the client was created.
     157                 :            :          */
     158                 :          0 :         p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
     159                 :            : 
     160                 :          0 :         *p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
     161                 :          0 :         *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
     162                 :          0 :         hold = p++;
     163 [ #  # ][ #  # ]:          0 :         for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++)
     164                 :          0 :                 *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
     165         [ #  # ]:          0 :         *hold = htonl(p - hold - 1);            /* gid array length */
     166         [ #  # ]:          0 :         *base = htonl((p - base - 1) << 2);       /* cred length */
     167                 :            : 
     168                 :          0 :         *p++ = htonl(RPC_AUTH_NULL);
     169                 :          0 :         *p++ = htonl(0);
     170                 :            : 
     171                 :          0 :         return p;
     172                 :            : }
     173                 :            : 
     174                 :            : /*
     175                 :            :  * Refresh credentials. This is a no-op for AUTH_UNIX
     176                 :            :  */
     177                 :            : static int
     178                 :          0 : unx_refresh(struct rpc_task *task)
     179                 :            : {
     180                 :          0 :         set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_rqstp->rq_cred->cr_flags);
     181                 :          0 :         return 0;
     182                 :            : }
     183                 :            : 
     184                 :            : static __be32 *
     185                 :          0 : unx_validate(struct rpc_task *task, __be32 *p)
     186                 :            : {
     187                 :            :         rpc_authflavor_t        flavor;
     188                 :            :         u32                     size;
     189                 :            : 
     190                 :          0 :         flavor = ntohl(*p++);
     191         [ #  # ]:          0 :         if (flavor != RPC_AUTH_NULL &&
     192                 :            :             flavor != RPC_AUTH_UNIX &&
     193                 :            :             flavor != RPC_AUTH_SHORT) {
     194                 :          0 :                 printk("RPC: bad verf flavor: %u\n", flavor);
     195                 :          0 :                 return ERR_PTR(-EIO);
     196                 :            :         }
     197                 :            : 
     198                 :          0 :         size = ntohl(*p++);
     199         [ #  # ]:          0 :         if (size > RPC_MAX_AUTH_SIZE) {
     200                 :          0 :                 printk("RPC: giant verf size: %u\n", size);
     201                 :          0 :                 return ERR_PTR(-EIO);
     202                 :            :         }
     203                 :          0 :         task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2;
     204                 :          0 :         p += (size >> 2);
     205                 :            : 
     206                 :          0 :         return p;
     207                 :            : }
     208                 :            : 
     209                 :          0 : int __init rpc_init_authunix(void)
     210                 :            : {
     211                 :          0 :         return rpcauth_init_credcache(&unix_auth);
     212                 :            : }
     213                 :            : 
     214                 :          0 : void rpc_destroy_authunix(void)
     215                 :            : {
     216                 :          0 :         rpcauth_destroy_credcache(&unix_auth);
     217                 :          0 : }
     218                 :            : 
     219                 :            : const struct rpc_authops authunix_ops = {
     220                 :            :         .owner          = THIS_MODULE,
     221                 :            :         .au_flavor      = RPC_AUTH_UNIX,
     222                 :            :         .au_name        = "UNIX",
     223                 :            :         .create         = unx_create,
     224                 :            :         .destroy        = unx_destroy,
     225                 :            :         .lookup_cred    = unx_lookup_cred,
     226                 :            :         .crcreate       = unx_create_cred,
     227                 :            : };
     228                 :            : 
     229                 :            : static
     230                 :            : struct rpc_auth         unix_auth = {
     231                 :            :         .au_cslack      = UNX_WRITESLACK,
     232                 :            :         .au_rslack      = 2,                    /* assume AUTH_NULL verf */
     233                 :            :         .au_ops         = &authunix_ops,
     234                 :            :         .au_flavor      = RPC_AUTH_UNIX,
     235                 :            :         .au_count       = ATOMIC_INIT(0),
     236                 :            : };
     237                 :            : 
     238                 :            : static
     239                 :            : const struct rpc_credops unix_credops = {
     240                 :            :         .cr_name        = "AUTH_UNIX",
     241                 :            :         .crdestroy      = unx_destroy_cred,
     242                 :            :         .crbind         = rpcauth_generic_bind_cred,
     243                 :            :         .crmatch        = unx_match,
     244                 :            :         .crmarshal      = unx_marshal,
     245                 :            :         .crrefresh      = unx_refresh,
     246                 :            :         .crvalidate     = unx_validate,
     247                 :            : };

Generated by: LCOV version 1.9