From: Andy Adamson <andros@xxxxxxxxxx> nfs_create_rpc_client only creates an rpc_auth, which only checks to see if rpc.gssd is running to succeed. Create a gss_context with the proposed pseudoflavor (as in nfs_find_best_sec) to verify pseudoflavor. Some servers support RPC_AUTH_GSS_KRB5 but not RPC_AUTH_GSS_KRB5I Try RPC_AUTH_GSS_KRB5I then RPC_AUTH_GSS_KRB5 for the clientid establishment rpc client cl_rpcclient. Signed-off-by: Andy Adamson <andros@xxxxxxxxxx> --- fs/nfs/nfs4client.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index ffdb28d..9f8631d 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -341,6 +341,47 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp) } /** + * Verify the client and server kerberos and gss configurations by obtaining + * a gss_context for UID 0 (current_cred()) prior to use in an RPC call. + */ +int nfs_create_gss_rpc_client(struct nfs_client *clp, + const struct rpc_timeout *timeparams) +{ + struct rpc_cred *cred; + int err; + + /* This creates a krb5i rpc_auth if rpc.gssd is running */ + err = nfs_create_rpc_client(clp, timeparams, RPC_AUTH_GSS_KRB5I); + if (err == -EINVAL) + return err; + + /* Check that krb5i can be used: cr_init obtains a gss_context */ + cred = rpcauth_lookupcred(clp->cl_rpcclient->cl_auth, 0); + if (IS_ERR(cred)) { + struct rpc_clnt *krb5i, *krb5; + + /* Try krb5 */ + krb5i = clp->cl_rpcclient; + krb5 = rpc_clone_client_set_auth(krb5i, RPC_AUTH_GSS_KRB5); + rpc_shutdown_client(krb5i); + /* Check that krb5 can be used */ + cred = rpcauth_lookupcred(krb5->cl_auth, 0); + if (IS_ERR(cred)) { + rpc_shutdown_client(krb5); + clp->cl_rpcclient = ERR_PTR(-EINVAL); + return -EINVAL; + } + /* Use krb5 */ + put_rpccred(cred); + clp->cl_rpcclient = krb5; + return 0; + } + /* Use krb5i */ + put_rpccred(cred); + return 0; +} + +/** * nfs4_init_client - Initialise an NFS4 client record * * @clp: nfs_client to initialise @@ -372,7 +413,8 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp, __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); __set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags); - error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I); + /* Try RPC_AUTH_GSS_KRB51 then RPC_AUTH_GSS_KRB5 */ + error = nfs_create_gss_rpc_client(clp, timeparms); if (error == -EINVAL) error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX); if (error < 0) -- 1.9.3 (Apple Git-50) -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html