svcauth.h 5.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * linux/include/linux/sunrpc/svcauth.h
 *
 * RPC server-side authentication stuff.
 *
 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
 */

#ifndef _LINUX_SUNRPC_SVCAUTH_H_
#define _LINUX_SUNRPC_SVCAUTH_H_

#ifdef __KERNEL__

#include <linux/string.h>
#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/cache.h>
#include <linux/hash.h>
18
#include <linux/cred.h>
L
Linus Torvalds 已提交
19 20 21 22 23

struct svc_cred {
	uid_t			cr_uid;
	gid_t			cr_gid;
	struct group_info	*cr_group_info;
24
	char			*cr_principal; /* for gss */
L
Linus Torvalds 已提交
25 26
};

27 28 29 30 31 32 33
static inline void free_svc_cred(struct svc_cred *cred)
{
	if (cred->cr_group_info)
		put_group_info(cred->cr_group_info);
	kfree(cred->cr_principal);
}

L
Linus Torvalds 已提交
34
struct svc_rqst;		/* forward decl */
35
struct in6_addr;
L
Linus Torvalds 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

/* Authentication is done in the context of a domain.
 *
 * Currently, the nfs server uses the auth_domain to stand
 * for the "client" listed in /etc/exports.
 *
 * More generally, a domain might represent a group of clients using
 * a common mechanism for authentication and having a common mapping
 * between local identity (uid) and network identity.  All clients
 * in a domain have similar general access rights.  Each domain can
 * contain multiple principals which will have different specific right
 * based on normal Discretionary Access Control.
 *
 * A domain is created by an authentication flavour module based on name
 * only.  Userspace then fills in detail on demand.
 *
 * In the case of auth_unix and auth_null, the auth_domain is also
 * associated with entries in another cache representing the mapping
 * of ip addresses to the given client.
 */
struct auth_domain {
57 58
	struct kref		ref;
	struct hlist_node	hash;
L
Linus Torvalds 已提交
59
	char			*name;
60
	struct auth_ops		*flavour;
L
Linus Torvalds 已提交
61 62 63 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 90 91 92 93 94 95 96 97 98
};

/*
 * Each authentication flavour registers an auth_ops
 * structure.
 * name is simply the name.
 * flavour gives the auth flavour. It determines where the flavour is registered
 * accept() is given a request and should verify it.
 *   It should inspect the authenticator and verifier, and possibly the data.
 *    If there is a problem with the authentication *authp should be set.
 *    The return value of accept() can indicate:
 *      OK - authorised. client and credential are set in rqstp.
 *           reqbuf points to arguments
 *           resbuf points to good place for results.  verfier
 *             is (probably) already in place.  Certainly space is
 *	       reserved for it.
 *      DROP - simply drop the request. It may have been deferred
 *      GARBAGE - rpc garbage_args error
 *      SYSERR - rpc system_err error
 *      DENIED - authp holds reason for denial.
 *      COMPLETE - the reply is encoded already and ready to be sent; no
 *		further processing is necessary.  (This is used for processing
 *		null procedure calls which are used to set up encryption
 *		contexts.)
 *
 *   accept is passed the proc number so that it can accept NULL rpc requests
 *   even if it cannot authenticate the client (as is sometimes appropriate).
 *
 * release() is given a request after the procedure has been run.
 *  It should sign/encrypt the results if needed
 * It should return:
 *    OK - the resbuf is ready to be sent
 *    DROP - the reply should be quitely dropped
 *    DENIED - authp holds a reason for MSG_DENIED
 *    SYSERR - rpc system_err
 *
 * domain_release()
 *   This call releases a domain.
99 100 101
 * set_client()
 *   Givens a pending request (struct svc_rqst), finds and assigns
 *   an appropriate 'auth_domain' as the client.
L
Linus Torvalds 已提交
102 103 104 105 106
 */
struct auth_ops {
	char *	name;
	struct module *owner;
	int	flavour;
107
	int	(*accept)(struct svc_rqst *rq, __be32 *authp);
L
Linus Torvalds 已提交
108 109 110 111 112 113 114 115 116 117 118
	int	(*release)(struct svc_rqst *rq);
	void	(*domain_release)(struct auth_domain *);
	int	(*set_client)(struct svc_rqst *rq);
};

#define	SVC_GARBAGE	1
#define	SVC_SYSERR	2
#define	SVC_VALID	3
#define	SVC_NEGATIVE	4
#define	SVC_OK		5
#define	SVC_DROP	6
119 120 121 122 123 124 125
#define	SVC_CLOSE	7	/* Like SVC_DROP, but request is definitely
				 * lost so if there is a tcp connection, it
				 * should be closed
				 */
#define	SVC_DENIED	8
#define	SVC_PENDING	9
#define	SVC_COMPLETE	10
L
Linus Torvalds 已提交
126

127
struct svc_xprt;
L
Linus Torvalds 已提交
128

129
extern int	svc_authenticate(struct svc_rqst *rqstp, __be32 *authp);
L
Linus Torvalds 已提交
130 131 132 133 134 135 136
extern int	svc_authorise(struct svc_rqst *rqstp);
extern int	svc_set_client(struct svc_rqst *rqstp);
extern int	svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops);
extern void	svc_auth_unregister(rpc_authflavor_t flavor);

extern struct auth_domain *unix_domain_find(char *name);
extern void auth_domain_put(struct auth_domain *item);
137
extern int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom);
138
extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *new);
L
Linus Torvalds 已提交
139
extern struct auth_domain *auth_domain_find(char *name);
140
extern struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr);
L
Linus Torvalds 已提交
141
extern int auth_unix_forget_old(struct auth_domain *dom);
142
extern void svcauth_unix_purge(struct net *net);
143
extern void svcauth_unix_info_release(struct svc_xprt *xpt);
144
extern int svcauth_unix_set_client(struct svc_rqst *rqstp);
L
Linus Torvalds 已提交
145

146 147 148
extern int unix_gid_cache_create(struct net *net);
extern void unix_gid_cache_destroy(struct net *net);

L
Linus Torvalds 已提交
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
static inline unsigned long hash_str(char *name, int bits)
{
	unsigned long hash = 0;
	unsigned long l = 0;
	int len = 0;
	unsigned char c;
	do {
		if (unlikely(!(c = *name++))) {
			c = (char)len; len = -1;
		}
		l = (l << 8) | c;
		len++;
		if ((len & (BITS_PER_LONG/8-1))==0)
			hash = hash_long(hash^l, BITS_PER_LONG);
	} while (len);
	return hash >> (BITS_PER_LONG - bits);
}

static inline unsigned long hash_mem(char *buf, int length, int bits)
{
	unsigned long hash = 0;
	unsigned long l = 0;
	int len = 0;
	unsigned char c;
	do {
		if (len == length) {
			c = (char)len; len = -1;
		} else
			c = *buf++;
		l = (l << 8) | c;
		len++;
		if ((len & (BITS_PER_LONG/8-1))==0)
			hash = hash_long(hash^l, BITS_PER_LONG);
	} while (len);
	return hash >> (BITS_PER_LONG - bits);
}

#endif /* __KERNEL__ */

#endif /* _LINUX_SUNRPC_SVCAUTH_H_ */