SUNRPC: Add enum svc_auth_status
authorChuck Lever <chuck.lever@oracle.com>
Sun, 30 Jul 2023 00:58:54 +0000 (20:58 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Tue, 29 Aug 2023 21:45:22 +0000 (17:45 -0400)
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>
fs/lockd/svc.c
fs/nfs/callback.c
include/linux/sunrpc/svc.h
include/linux/sunrpc/svcauth.h
include/trace/events/sunrpc.h
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/svc.c
net/sunrpc/svcauth.c
net/sunrpc/svcauth_unix.c

index ef3f77a..6579948 100644 (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) {
index 39a0ba7..466ebf1 100644 (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;
 
index 9b42925..1c491f0 100644 (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 *);
index 27582d3..6f90203 100644 (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);
index 00db9e1..55716b6 100644 (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))
 );
 
index c4a5667..18734e7 100644 (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)
index 030f8c7..7873a3f 100644 (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)
index 67d8245..aa4429d 100644 (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)
 {
index 174783f..04b4558 100644 (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;