SUNRPC: Add enum svc_auth_status

In addition to the benefits of using an enum rather than a set of
macros, we now have a named type that can improve static type
checking of function return values.

As part of this change, I removed a stale comment from svcauth.h;
the return values from current implementations of the
auth_ops::release method are all zero/negative errno, not the SVC_OK
enum values as the old comment suggested.

Suggested-by: NeilBrown <neilb@suse.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
Chuck Lever 2023-07-29 20:58:54 -04:00
parent d75e490f35
commit 78c542f916
9 changed files with 73 additions and 49 deletions

View File

@ -506,7 +506,7 @@ static inline int is_callback(u32 proc)
}
static int lockd_authenticate(struct svc_rqst *rqstp)
static enum svc_auth_status lockd_authenticate(struct svc_rqst *rqstp)
{
rqstp->rq_client = NULL;
switch (rqstp->rq_authop->flavour) {

View File

@ -372,7 +372,7 @@ check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp)
* All other checking done after NFS decoding where the nfs_client can be
* found in nfs4_callback_compound
*/
static int nfs_callback_authenticate(struct svc_rqst *rqstp)
static enum svc_auth_status nfs_callback_authenticate(struct svc_rqst *rqstp)
{
rqstp->rq_auth_stat = rpc_autherr_badcred;

View File

@ -336,7 +336,7 @@ struct svc_program {
char * pg_name; /* service name */
char * pg_class; /* class name: services sharing authentication */
struct svc_stat * pg_stats; /* rpc statistics */
int (*pg_authenticate)(struct svc_rqst *);
enum svc_auth_status (*pg_authenticate)(struct svc_rqst *rqstp);
__be32 (*pg_init_request)(struct svc_rqst *,
const struct svc_program *,
struct svc_process_info *);

View File

@ -83,6 +83,19 @@ struct auth_domain {
struct rcu_head rcu_head;
};
enum svc_auth_status {
SVC_GARBAGE = 1,
SVC_SYSERR,
SVC_VALID,
SVC_NEGATIVE,
SVC_OK,
SVC_DROP,
SVC_CLOSE,
SVC_DENIED,
SVC_PENDING,
SVC_COMPLETE,
};
/*
* Each authentication flavour registers an auth_ops
* structure.
@ -98,6 +111,8 @@ struct auth_domain {
* is (probably) already in place. Certainly space is
* reserved for it.
* DROP - simply drop the request. It may have been deferred
* CLOSE - like SVC_DROP, but request is definitely lost.
* If there is a tcp connection, it should be closed.
* GARBAGE - rpc garbage_args error
* SYSERR - rpc system_err error
* DENIED - authp holds reason for denial.
@ -111,14 +126,10 @@ struct auth_domain {
*
* 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.
*
* set_client()
* Givens a pending request (struct svc_rqst), finds and assigns
* an appropriate 'auth_domain' as the client.
@ -127,31 +138,18 @@ struct auth_ops {
char * name;
struct module *owner;
int flavour;
int (*accept)(struct svc_rqst *rq);
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
#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
enum svc_auth_status (*accept)(struct svc_rqst *rqstp);
int (*release)(struct svc_rqst *rqstp);
void (*domain_release)(struct auth_domain *dom);
enum svc_auth_status (*set_client)(struct svc_rqst *rqstp);
};
struct svc_xprt;
extern int svc_authenticate(struct svc_rqst *rqstp);
extern enum svc_auth_status svc_authenticate(struct svc_rqst *rqstp);
extern int svc_authorise(struct svc_rqst *rqstp);
extern int svc_set_client(struct svc_rqst *rqstp);
extern enum svc_auth_status 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);
@ -161,7 +159,7 @@ extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *ne
extern struct auth_domain *auth_domain_find(char *name);
extern void svcauth_unix_purge(struct net *net);
extern void svcauth_unix_info_release(struct svc_xprt *xpt);
extern int svcauth_unix_set_client(struct svc_rqst *rqstp);
extern enum svc_auth_status svcauth_unix_set_client(struct svc_rqst *rqstp);
extern int unix_gid_cache_create(struct net *net);
extern void unix_gid_cache_destroy(struct net *net);

View File

@ -1706,7 +1706,7 @@ TRACE_DEFINE_ENUM(SVC_DENIED);
TRACE_DEFINE_ENUM(SVC_PENDING);
TRACE_DEFINE_ENUM(SVC_COMPLETE);
#define svc_show_status(status) \
#define show_svc_auth_status(status) \
__print_symbolic(status, \
{ SVC_GARBAGE, "SVC_GARBAGE" }, \
{ SVC_SYSERR, "SVC_SYSERR" }, \
@ -1743,7 +1743,10 @@ TRACE_DEFINE_ENUM(SVC_COMPLETE);
__entry->xid, __get_sockaddr(server), __get_sockaddr(client)
TRACE_EVENT_CONDITION(svc_authenticate,
TP_PROTO(const struct svc_rqst *rqst, int auth_res),
TP_PROTO(
const struct svc_rqst *rqst,
enum svc_auth_status auth_res
),
TP_ARGS(rqst, auth_res),
@ -1766,7 +1769,7 @@ TRACE_EVENT_CONDITION(svc_authenticate,
TP_printk(SVC_RQST_ENDPOINT_FORMAT
" auth_res=%s auth_stat=%s",
SVC_RQST_ENDPOINT_VARARGS,
svc_show_status(__entry->svc_status),
show_svc_auth_status(__entry->svc_status),
rpc_show_auth_stat(__entry->auth_stat))
);

View File

@ -986,7 +986,7 @@ bad_unwrap:
return -EINVAL;
}
static int
static enum svc_auth_status
svcauth_gss_set_client(struct svc_rqst *rqstp)
{
struct gss_svc_data *svcdata = rqstp->rq_auth_data;
@ -1634,7 +1634,7 @@ svcauth_gss_decode_credbody(struct xdr_stream *xdr,
*
* The rqstp->rq_auth_stat field is also set (see RFCs 2203 and 5531).
*/
static int
static enum svc_auth_status
svcauth_gss_accept(struct svc_rqst *rqstp)
{
struct gss_svc_data *svcdata = rqstp->rq_auth_data;
@ -1945,9 +1945,6 @@ bad_wrap:
* %0: the Reply is ready to be sent
* %-ENOMEM: failed to allocate memory
* %-EINVAL: encoding error
*
* XXX: These return values do not match the return values documented
* for the auth_ops ->release method in linux/sunrpc/svcauth.h.
*/
static int
svcauth_gss_release(struct svc_rqst *rqstp)

View File

@ -1275,8 +1275,9 @@ svc_process_common(struct svc_rqst *rqstp)
const struct svc_procedure *procp = NULL;
struct svc_serv *serv = rqstp->rq_server;
struct svc_process_info process;
int auth_res, rc;
enum svc_auth_status auth_res;
unsigned int aoffset;
int rc;
__be32 *p;
/* Will be turned off by GSS integrity and privacy services */
@ -1331,6 +1332,9 @@ svc_process_common(struct svc_rqst *rqstp)
goto dropit;
case SVC_COMPLETE:
goto sendit;
default:
pr_warn_once("Unexpected svc_auth_status (%d)\n", auth_res);
goto err_system_err;
}
if (progp == NULL)

View File

@ -60,8 +60,19 @@ svc_put_auth_ops(struct auth_ops *aops)
module_put(aops->owner);
}
int
svc_authenticate(struct svc_rqst *rqstp)
/**
* svc_authenticate - Initialize an outgoing credential
* @rqstp: RPC execution context
*
* Return values:
* %SVC_OK: XDR encoding of the result can begin
* %SVC_DENIED: Credential or verifier is not valid
* %SVC_GARBAGE: Failed to decode credential or verifier
* %SVC_COMPLETE: GSS context lifetime event; no further action
* %SVC_DROP: Drop this request; no further action
* %SVC_CLOSE: Like drop, but also close transport connection
*/
enum svc_auth_status svc_authenticate(struct svc_rqst *rqstp)
{
struct auth_ops *aops;
u32 flavor;
@ -89,16 +100,28 @@ svc_authenticate(struct svc_rqst *rqstp)
}
EXPORT_SYMBOL_GPL(svc_authenticate);
int svc_set_client(struct svc_rqst *rqstp)
/**
* svc_set_client - Assign an appropriate 'auth_domain' as the client
* @rqstp: RPC execution context
*
* Return values:
* %SVC_OK: Client was found and assigned
* %SVC_DENY: Client was explicitly denied
* %SVC_DROP: Ignore this request
* %SVC_CLOSE: Ignore this request and close the connection
*/
enum svc_auth_status svc_set_client(struct svc_rqst *rqstp)
{
rqstp->rq_client = NULL;
return rqstp->rq_authop->set_client(rqstp);
}
EXPORT_SYMBOL_GPL(svc_set_client);
/* A request, which was authenticated, has now executed.
* Time to finalise the credentials and verifier
* and release and resources
/**
* svc_authorise - Finalize credentials/verifier and release resources
* @rqstp: RPC execution context
*
* Returns zero on success, or a negative errno.
*/
int svc_authorise(struct svc_rqst *rqstp)
{

View File

@ -665,7 +665,7 @@ static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp)
}
}
int
enum svc_auth_status
svcauth_unix_set_client(struct svc_rqst *rqstp)
{
struct sockaddr_in *sin;
@ -736,7 +736,6 @@ out:
rqstp->rq_auth_stat = rpc_auth_ok;
return SVC_OK;
}
EXPORT_SYMBOL_GPL(svcauth_unix_set_client);
/**
@ -751,7 +750,7 @@ EXPORT_SYMBOL_GPL(svcauth_unix_set_client);
*
* rqstp->rq_auth_stat is set as mandated by RFC 5531.
*/
static int
static enum svc_auth_status
svcauth_null_accept(struct svc_rqst *rqstp)
{
struct xdr_stream *xdr = &rqstp->rq_arg_stream;
@ -828,7 +827,7 @@ struct auth_ops svcauth_null = {
*
* rqstp->rq_auth_stat is set as mandated by RFC 5531.
*/
static int
static enum svc_auth_status
svcauth_tls_accept(struct svc_rqst *rqstp)
{
struct xdr_stream *xdr = &rqstp->rq_arg_stream;
@ -913,7 +912,7 @@ struct auth_ops svcauth_tls = {
*
* rqstp->rq_auth_stat is set as mandated by RFC 5531.
*/
static int
static enum svc_auth_status
svcauth_unix_accept(struct svc_rqst *rqstp)
{
struct xdr_stream *xdr = &rqstp->rq_arg_stream;