Blame view

net/sunrpc/auth_generic.c 4.56 KB
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
1
2
3
4
5
6
7
  /*
   * Generic RPC credential
   *
   * Copyright (C) 2008, Trond Myklebust <Trond.Myklebust@netapp.com>
   */
  
  #include <linux/err.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
8
  #include <linux/slab.h>
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
9
10
11
12
13
14
15
16
17
18
19
  #include <linux/types.h>
  #include <linux/module.h>
  #include <linux/sched.h>
  #include <linux/sunrpc/auth.h>
  #include <linux/sunrpc/clnt.h>
  #include <linux/sunrpc/debug.h>
  #include <linux/sunrpc/sched.h>
  
  #ifdef RPC_DEBUG
  # define RPCDBG_FACILITY	RPCDBG_AUTH
  #endif
b4528762c   Trond Myklebust   SUNRPC: AUTH_SYS ...
20
21
  #define RPC_MACHINE_CRED_USERID		((uid_t)0)
  #define RPC_MACHINE_CRED_GROUPID	((gid_t)0)
7c67db3a8   Trond Myklebust   NFSv4: Reintroduc...
22

9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
23
24
25
26
27
28
  struct generic_cred {
  	struct rpc_cred gc_base;
  	struct auth_cred acred;
  };
  
  static struct rpc_auth generic_auth;
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
29
30
31
32
33
34
35
36
37
38
  static const struct rpc_credops generic_credops;
  
  /*
   * Public call interface
   */
  struct rpc_cred *rpc_lookup_cred(void)
  {
  	return rpcauth_lookupcred(&generic_auth, 0);
  }
  EXPORT_SYMBOL_GPL(rpc_lookup_cred);
7c67db3a8   Trond Myklebust   NFSv4: Reintroduc...
39
40
41
  /*
   * Public call interface for looking up machine creds.
   */
68c97153f   Trond Myklebust   SUNRPC: Clean up ...
42
  struct rpc_cred *rpc_lookup_machine_cred(const char *service_name)
7c67db3a8   Trond Myklebust   NFSv4: Reintroduc...
43
44
  {
  	struct auth_cred acred = {
b4528762c   Trond Myklebust   SUNRPC: AUTH_SYS ...
45
46
  		.uid = RPC_MACHINE_CRED_USERID,
  		.gid = RPC_MACHINE_CRED_GROUPID,
68c97153f   Trond Myklebust   SUNRPC: Clean up ...
47
  		.principal = service_name,
7c67db3a8   Trond Myklebust   NFSv4: Reintroduc...
48
49
  		.machine_cred = 1,
  	};
68c97153f   Trond Myklebust   SUNRPC: Clean up ...
50
51
52
  	dprintk("RPC:       looking up machine cred for service %s
  ",
  			service_name);
7c67db3a8   Trond Myklebust   NFSv4: Reintroduc...
53
54
55
  	return generic_auth.au_ops->lookup_cred(&generic_auth, &acred, 0);
  }
  EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred);
8572b8e2e   Trond Myklebust   SUNRPC: Clean up ...
56
57
  static struct rpc_cred *generic_bind_cred(struct rpc_task *task,
  		struct rpc_cred *cred, int lookupflags)
5c691044e   Trond Myklebust   SUNRPC: Add an rp...
58
59
60
  {
  	struct rpc_auth *auth = task->tk_client->cl_auth;
  	struct auth_cred *acred = &container_of(cred, struct generic_cred, gc_base)->acred;
5c691044e   Trond Myklebust   SUNRPC: Add an rp...
61

8572b8e2e   Trond Myklebust   SUNRPC: Clean up ...
62
  	return auth->au_ops->lookup_cred(auth, acred, lookupflags);
5c691044e   Trond Myklebust   SUNRPC: Add an rp...
63
  }
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  /*
   * Lookup generic creds for current process
   */
  static struct rpc_cred *
  generic_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
  {
  	return rpcauth_lookup_credcache(&generic_auth, acred, flags);
  }
  
  static struct rpc_cred *
  generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
  {
  	struct generic_cred *gcred;
  
  	gcred = kmalloc(sizeof(*gcred), GFP_KERNEL);
  	if (gcred == NULL)
  		return ERR_PTR(-ENOMEM);
  
  	rpcauth_init_cred(&gcred->gc_base, acred, &generic_auth, &generic_credops);
  	gcred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
  
  	gcred->acred.uid = acred->uid;
  	gcred->acred.gid = acred->gid;
  	gcred->acred.group_info = acred->group_info;
  	if (gcred->acred.group_info != NULL)
  		get_group_info(gcred->acred.group_info);
7c67db3a8   Trond Myklebust   NFSv4: Reintroduc...
90
  	gcred->acred.machine_cred = acred->machine_cred;
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
91

7c67db3a8   Trond Myklebust   NFSv4: Reintroduc...
92
93
94
  	dprintk("RPC:       allocated %s cred %p for uid %d gid %d
  ",
  			gcred->acred.machine_cred ? "machine" : "generic",
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  			gcred, acred->uid, acred->gid);
  	return &gcred->gc_base;
  }
  
  static void
  generic_free_cred(struct rpc_cred *cred)
  {
  	struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
  
  	dprintk("RPC:       generic_free_cred %p
  ", gcred);
  	if (gcred->acred.group_info != NULL)
  		put_group_info(gcred->acred.group_info);
  	kfree(gcred);
  }
  
  static void
  generic_free_cred_callback(struct rcu_head *head)
  {
  	struct rpc_cred *cred = container_of(head, struct rpc_cred, cr_rcu);
  	generic_free_cred(cred);
  }
  
  static void
  generic_destroy_cred(struct rpc_cred *cred)
  {
  	call_rcu(&cred->cr_rcu, generic_free_cred_callback);
  }
  
  /*
   * Match credentials against current process creds.
   */
  static int
  generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
  {
  	struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
23918b030   Trond Myklebust   SUNRPC: Fix a per...
131
  	int i;
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
132
133
134
  
  	if (gcred->acred.uid != acred->uid ||
  	    gcred->acred.gid != acred->gid ||
7c67db3a8   Trond Myklebust   NFSv4: Reintroduc...
135
  	    gcred->acred.machine_cred != acred->machine_cred)
23918b030   Trond Myklebust   SUNRPC: Fix a per...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
  		goto out_nomatch;
  
  	/* Optimisation in the case where pointers are identical... */
  	if (gcred->acred.group_info == acred->group_info)
  		goto out_match;
  
  	/* Slow path... */
  	if (gcred->acred.group_info->ngroups != acred->group_info->ngroups)
  		goto out_nomatch;
  	for (i = 0; i < gcred->acred.group_info->ngroups; i++) {
  		if (GROUP_AT(gcred->acred.group_info, i) !=
  				GROUP_AT(acred->group_info, i))
  			goto out_nomatch;
  	}
  out_match:
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
151
  	return 1;
23918b030   Trond Myklebust   SUNRPC: Fix a per...
152
153
  out_nomatch:
  	return 0;
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
154
  }
5d8d9a4d9   Trond Myklebust   NFS: Ensure the A...
155
  int __init rpc_init_generic_auth(void)
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
156
  {
5d8d9a4d9   Trond Myklebust   NFS: Ensure the A...
157
  	return rpcauth_init_credcache(&generic_auth);
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
158
  }
c135e84af   Stephen Rothwell   sunrpc: fix up rp...
159
  void rpc_destroy_generic_auth(void)
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
160
  {
5d8d9a4d9   Trond Myklebust   NFS: Ensure the A...
161
  	rpcauth_destroy_credcache(&generic_auth);
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
162
  }
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
163
164
  static const struct rpc_authops generic_auth_ops = {
  	.owner = THIS_MODULE,
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
165
  	.au_name = "Generic",
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
166
167
168
169
170
171
172
  	.lookup_cred = generic_lookup_cred,
  	.crcreate = generic_create_cred,
  };
  
  static struct rpc_auth generic_auth = {
  	.au_ops = &generic_auth_ops,
  	.au_count = ATOMIC_INIT(0),
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
173
174
175
176
177
  };
  
  static const struct rpc_credops generic_credops = {
  	.cr_name = "Generic cred",
  	.crdestroy = generic_destroy_cred,
5c691044e   Trond Myklebust   SUNRPC: Add an rp...
178
  	.crbind = generic_bind_cred,
9a559efd4   Trond Myklebust   SUNRPC: Add a gen...
179
180
  	.crmatch = generic_match,
  };