From patchwork Sun Jun 22 00:52:17 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 4395361 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 27822BEEAA for ; Sun, 22 Jun 2014 00:52:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 36C6A201C0 for ; Sun, 22 Jun 2014 00:52:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 149242020E for ; Sun, 22 Jun 2014 00:52:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751099AbaFVAwb (ORCPT ); Sat, 21 Jun 2014 20:52:31 -0400 Received: from mail-qg0-f41.google.com ([209.85.192.41]:36763 "EHLO mail-qg0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751192AbaFVAw3 (ORCPT ); Sat, 21 Jun 2014 20:52:29 -0400 Received: by mail-qg0-f41.google.com with SMTP id i50so4802070qgf.0 for ; Sat, 21 Jun 2014 17:52:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=Nw3RUthZ48Kp4jePDKmI1mO8KU6at34fAafXP/QEedE=; b=U/smJZe7qO2McKd1WZHiwVhEph+8uRzvjVvESbvJRpIGbvsJPX0gMm71vtesB6TUvi 32pfYEWedhDaMdXwtfUU985EfAT5l7YIBrnHX+N21ePwjPJpVQ501wOrE/O9CR7b0whe uCRmhE6S+xU1nOuYRm5fFfdkAhCN1nzA9Bhrcbseoqa5Vgj0hgJCdVAZwBF8KtSN0ZuE wAjnnhCD3UleT8FwCuzTFqCCU2x94HSl7YreEjLoAEYa3Ob2HDoKU+mZtPUeN/Qgtisq bwOCe3SGL/nmtXrZHiPAQ1SZPJl0fFaRVIVIFHLg5eP9TaRjx4J7tmSYFtnfq5iMzZWQ 9vyw== X-Gm-Message-State: ALoCoQnmIqsmHw4P/HVpdfbEaDcI+nEBGvlUWJVJws4d6HVqaJW5/Phd6FR8Xx61c1SlAdB5USW2 X-Received: by 10.140.109.118 with SMTP id k109mr18131864qgf.98.1403398348799; Sat, 21 Jun 2014 17:52:28 -0700 (PDT) Received: from tlielax.poochiereds.net ([2001:470:8:d63:3a60:77ff:fe93:a95d]) by mx.google.com with ESMTPSA id k8sm11116811qas.23.2014.06.21.17.52.27 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 21 Jun 2014 17:52:27 -0700 (PDT) From: Jeff Layton To: trond.myklebust@primarydata.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v2 3/3] nfs4: copy acceptor name from context to nfs_client Date: Sat, 21 Jun 2014 20:52:17 -0400 Message-Id: <1403398337-4174-4-git-send-email-jlayton@primarydata.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1403398337-4174-1-git-send-email-jlayton@primarydata.com> References: <1403398337-4174-1-git-send-email-jlayton@primarydata.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Jeff Layton The current CB_COMPOUND handling code tries to compare the principal name of the request with the cl_hostname in the client. This is not guaranteed to ever work, particularly if the client happened to mount a CNAME of the server or a non-fqdn. Fix this by instead comparing the cr_principal string with the acceptor name that we get from gssd. In the event that gssd didn't send one down (i.e. it was too old), then we fall back to trying to use the cl_hostname as we do today. Signed-off-by: Jeff Layton --- fs/nfs/callback.c | 12 ++++++++++++ fs/nfs/client.c | 1 + fs/nfs/nfs4proc.c | 33 ++++++++++++++++++++++++++++++++- include/linux/nfs_fs_sb.h | 1 + include/linux/nfs_xdr.h | 1 + 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 073b4cf67ed9..54de482143cc 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -428,6 +428,18 @@ check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) if (p == NULL) return 0; + /* + * Did we get the acceptor from userland during the SETCLIENID + * negotiation? + */ + if (clp->cl_acceptor) + return !strcmp(p, clp->cl_acceptor); + + /* + * Otherwise try to verify it using the cl_hostname. Note that this + * doesn't work if a non-canonical hostname was used in the devname. + */ + /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */ if (memcmp(p, "nfs@", 4) != 0) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 1d09289c8f0e..6a461378fcf2 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -252,6 +252,7 @@ void nfs_free_client(struct nfs_client *clp) put_net(clp->cl_net); put_nfs_version(clp->cl_nfs_mod); kfree(clp->cl_hostname); + kfree(clp->cl_acceptor); kfree(clp); dprintk("<-- nfs_free_client()\n"); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index b0e5705599bf..f198a1e86e8d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4886,6 +4886,18 @@ nfs4_init_callback_netid(const struct nfs_client *clp, char *buf, size_t len) return scnprintf(buf, len, "tcp"); } +static void nfs4_setclientid_done(struct rpc_task *task, void *calldata) +{ + struct nfs4_setclientid *sc = calldata; + + if (task->tk_status == 0) + sc->sc_cred = get_rpccred(task->tk_rqstp->rq_cred); +} + +static const struct rpc_call_ops nfs4_setclientid_ops = { + .rpc_call_done = nfs4_setclientid_done, +}; + /** * nfs4_proc_setclientid - Negotiate client ID * @clp: state data structure @@ -4912,6 +4924,14 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, .rpc_resp = res, .rpc_cred = cred, }; + struct rpc_task *task; + struct rpc_task_setup task_setup_data = { + .rpc_client = clp->cl_rpcclient, + .rpc_message = &msg, + .callback_ops = &nfs4_setclientid_ops, + .callback_data = &setclientid, + .flags = RPC_TASK_TIMEOUT, + }; int status; /* nfs_client_id4 */ @@ -4938,7 +4958,18 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, dprintk("NFS call setclientid auth=%s, '%.*s'\n", clp->cl_rpcclient->cl_auth->au_ops->au_name, setclientid.sc_name_len, setclientid.sc_name); - status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); + task = rpc_run_task(&task_setup_data); + if (IS_ERR(task)) { + status = PTR_ERR(task); + goto out; + } + status = task->tk_status; + if (setclientid.sc_cred) { + clp->cl_acceptor = rpcauth_stringify_acceptor(setclientid.sc_cred); + put_rpccred(setclientid.sc_cred); + } + rpc_put_task(task); +out: trace_nfs4_setclientid(clp, status); dprintk("NFS reply setclientid: %d\n", status); return status; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 1150ea41b626..922be2e050f5 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -45,6 +45,7 @@ struct nfs_client { struct sockaddr_storage cl_addr; /* server identifier */ size_t cl_addrlen; char * cl_hostname; /* hostname of server */ + char * cl_acceptor; /* GSSAPI acceptor name */ struct list_head cl_share_link; /* link in global client list */ struct list_head cl_superblocks; /* List of nfs_server structs */ diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 81cbbf313272..0040629894df 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -993,6 +993,7 @@ struct nfs4_setclientid { unsigned int sc_uaddr_len; char sc_uaddr[RPCBIND_MAXUADDRLEN + 1]; u32 sc_cb_ident; + struct rpc_cred *sc_cred; }; struct nfs4_setclientid_res {