Branch data Line data Source code
1 : : /*
2 : : * linux/include/linux/sunrpc/svcauth.h
3 : : *
4 : : * RPC server-side authentication stuff.
5 : : *
6 : : * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 : : */
8 : :
9 : : #ifndef _LINUX_SUNRPC_SVCAUTH_H_
10 : : #define _LINUX_SUNRPC_SVCAUTH_H_
11 : :
12 : : #ifdef __KERNEL__
13 : :
14 : : #include <linux/string.h>
15 : : #include <linux/sunrpc/msg_prot.h>
16 : : #include <linux/sunrpc/cache.h>
17 : : #include <linux/sunrpc/gss_api.h>
18 : : #include <linux/hash.h>
19 : : #include <linux/cred.h>
20 : :
21 : : struct svc_cred {
22 : : kuid_t cr_uid;
23 : : kgid_t cr_gid;
24 : : struct group_info *cr_group_info;
25 : : u32 cr_flavor; /* pseudoflavor */
26 : : char *cr_principal; /* for gss */
27 : : struct gss_api_mech *cr_gss_mech;
28 : : };
29 : :
30 : : static inline void init_svc_cred(struct svc_cred *cred)
31 : : {
32 : 0 : cred->cr_group_info = NULL;
33 : 0 : cred->cr_principal = NULL;
34 : 0 : cred->cr_gss_mech = NULL;
35 : : }
36 : :
37 : : static inline void free_svc_cred(struct svc_cred *cred)
38 : : {
39 [ # # ][ # # ]: 0 : if (cred->cr_group_info)
40 [ # # ]: 0 : put_group_info(cred->cr_group_info);
41 : 0 : kfree(cred->cr_principal);
42 : 0 : gss_mech_put(cred->cr_gss_mech);
43 : : init_svc_cred(cred);
44 : : }
45 : :
46 : : struct svc_rqst; /* forward decl */
47 : : struct in6_addr;
48 : :
49 : : /* Authentication is done in the context of a domain.
50 : : *
51 : : * Currently, the nfs server uses the auth_domain to stand
52 : : * for the "client" listed in /etc/exports.
53 : : *
54 : : * More generally, a domain might represent a group of clients using
55 : : * a common mechanism for authentication and having a common mapping
56 : : * between local identity (uid) and network identity. All clients
57 : : * in a domain have similar general access rights. Each domain can
58 : : * contain multiple principals which will have different specific right
59 : : * based on normal Discretionary Access Control.
60 : : *
61 : : * A domain is created by an authentication flavour module based on name
62 : : * only. Userspace then fills in detail on demand.
63 : : *
64 : : * In the case of auth_unix and auth_null, the auth_domain is also
65 : : * associated with entries in another cache representing the mapping
66 : : * of ip addresses to the given client.
67 : : */
68 : : struct auth_domain {
69 : : struct kref ref;
70 : : struct hlist_node hash;
71 : : char *name;
72 : : struct auth_ops *flavour;
73 : : };
74 : :
75 : : /*
76 : : * Each authentication flavour registers an auth_ops
77 : : * structure.
78 : : * name is simply the name.
79 : : * flavour gives the auth flavour. It determines where the flavour is registered
80 : : * accept() is given a request and should verify it.
81 : : * It should inspect the authenticator and verifier, and possibly the data.
82 : : * If there is a problem with the authentication *authp should be set.
83 : : * The return value of accept() can indicate:
84 : : * OK - authorised. client and credential are set in rqstp.
85 : : * reqbuf points to arguments
86 : : * resbuf points to good place for results. verfier
87 : : * is (probably) already in place. Certainly space is
88 : : * reserved for it.
89 : : * DROP - simply drop the request. It may have been deferred
90 : : * GARBAGE - rpc garbage_args error
91 : : * SYSERR - rpc system_err error
92 : : * DENIED - authp holds reason for denial.
93 : : * COMPLETE - the reply is encoded already and ready to be sent; no
94 : : * further processing is necessary. (This is used for processing
95 : : * null procedure calls which are used to set up encryption
96 : : * contexts.)
97 : : *
98 : : * accept is passed the proc number so that it can accept NULL rpc requests
99 : : * even if it cannot authenticate the client (as is sometimes appropriate).
100 : : *
101 : : * release() is given a request after the procedure has been run.
102 : : * It should sign/encrypt the results if needed
103 : : * It should return:
104 : : * OK - the resbuf is ready to be sent
105 : : * DROP - the reply should be quitely dropped
106 : : * DENIED - authp holds a reason for MSG_DENIED
107 : : * SYSERR - rpc system_err
108 : : *
109 : : * domain_release()
110 : : * This call releases a domain.
111 : : * set_client()
112 : : * Givens a pending request (struct svc_rqst), finds and assigns
113 : : * an appropriate 'auth_domain' as the client.
114 : : */
115 : : struct auth_ops {
116 : : char * name;
117 : : struct module *owner;
118 : : int flavour;
119 : : int (*accept)(struct svc_rqst *rq, __be32 *authp);
120 : : int (*release)(struct svc_rqst *rq);
121 : : void (*domain_release)(struct auth_domain *);
122 : : int (*set_client)(struct svc_rqst *rq);
123 : : };
124 : :
125 : : #define SVC_GARBAGE 1
126 : : #define SVC_SYSERR 2
127 : : #define SVC_VALID 3
128 : : #define SVC_NEGATIVE 4
129 : : #define SVC_OK 5
130 : : #define SVC_DROP 6
131 : : #define SVC_CLOSE 7 /* Like SVC_DROP, but request is definitely
132 : : * lost so if there is a tcp connection, it
133 : : * should be closed
134 : : */
135 : : #define SVC_DENIED 8
136 : : #define SVC_PENDING 9
137 : : #define SVC_COMPLETE 10
138 : :
139 : : struct svc_xprt;
140 : :
141 : : extern int svc_authenticate(struct svc_rqst *rqstp, __be32 *authp);
142 : : extern int svc_authorise(struct svc_rqst *rqstp);
143 : : extern int svc_set_client(struct svc_rqst *rqstp);
144 : : extern int svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops);
145 : : extern void svc_auth_unregister(rpc_authflavor_t flavor);
146 : :
147 : : extern struct auth_domain *unix_domain_find(char *name);
148 : : extern void auth_domain_put(struct auth_domain *item);
149 : : extern int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom);
150 : : extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *new);
151 : : extern struct auth_domain *auth_domain_find(char *name);
152 : : extern struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr);
153 : : extern int auth_unix_forget_old(struct auth_domain *dom);
154 : : extern void svcauth_unix_purge(struct net *net);
155 : : extern void svcauth_unix_info_release(struct svc_xprt *xpt);
156 : : extern int svcauth_unix_set_client(struct svc_rqst *rqstp);
157 : :
158 : : extern int unix_gid_cache_create(struct net *net);
159 : : extern void unix_gid_cache_destroy(struct net *net);
160 : :
161 : : static inline unsigned long hash_str(char *name, int bits)
162 : : {
163 : : unsigned long hash = 0;
164 : : unsigned long l = 0;
165 : : int len = 0;
166 : : unsigned char c;
167 : : do {
168 [ # # ][ # # ]: 0 : if (unlikely(!(c = *name++))) {
169 : 0 : c = (char)len; len = -1;
170 : : }
171 : 0 : l = (l << 8) | c;
172 : 0 : len++;
173 [ # # ][ # # ]: 0 : if ((len & (BITS_PER_LONG/8-1))==0)
174 : 0 : hash = hash_long(hash^l, BITS_PER_LONG);
175 [ # # ][ # # ]: 0 : } while (len);
176 : 0 : return hash >> (BITS_PER_LONG - bits);
177 : : }
178 : :
179 : : static inline unsigned long hash_mem(char *buf, int length, int bits)
180 : : {
181 : : unsigned long hash = 0;
182 : : unsigned long l = 0;
183 : : int len = 0;
184 : : unsigned char c;
185 : : do {
186 [ # # ][ # # ]: 0 : if (len == length) {
[ # # ][ # # ]
[ # # ][ # # ]
187 : 0 : c = (char)len; len = -1;
188 : : } else
189 : 0 : c = *buf++;
190 : 0 : l = (l << 8) | c;
191 : 0 : len++;
192 [ # # ][ # # ]: 0 : if ((len & (BITS_PER_LONG/8-1))==0)
[ # # ][ # # ]
[ # # ][ # # ]
193 : 0 : hash = hash_long(hash^l, BITS_PER_LONG);
194 [ # # ][ # # ]: 0 : } while (len);
[ # # ][ # # ]
[ # # ][ # # ]
195 : 0 : return hash >> (BITS_PER_LONG - bits);
196 : : }
197 : :
198 : : #endif /* __KERNEL__ */
199 : :
200 : : #endif /* _LINUX_SUNRPC_SVCAUTH_H_ */
|