From patchwork Wed Dec 22 21:50:48 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan Schumaker X-Patchwork-Id: 428711 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBMLoxqp005325 for ; Wed, 22 Dec 2010 21:51:00 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752560Ab0LVVuw (ORCPT ); Wed, 22 Dec 2010 16:50:52 -0500 Received: from mx2.netapp.com ([216.240.18.37]:52587 "EHLO mx2.netapp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752565Ab0LVVuu (ORCPT ); Wed, 22 Dec 2010 16:50:50 -0500 X-IronPort-AV: E=Sophos;i="4.60,215,1291622400"; d="scan'208";a="498061160" Received: from smtp1.corp.netapp.com ([10.57.156.124]) by mx2-out.netapp.com with ESMTP; 22 Dec 2010 13:50:50 -0800 Received: from [10.30.20.59] (hurlbut2-lxp.hq.netapp.com [10.30.20.59]) by smtp1.corp.netapp.com (8.13.1/8.13.1/NTAP-1.6) with ESMTP id oBMLonA8006544; Wed, 22 Dec 2010 13:50:49 -0800 (PST) Message-ID: <4D1272B8.5010202@netapp.com> Date: Wed, 22 Dec 2010 16:50:48 -0500 From: Bryan Schumaker User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101211 Lightning/1.0b2 Lanikai/3.1.7 MIME-Version: 1.0 To: "Myklebust, Trond" , "linux-nfs@vger.kernel.org" Subject: [PATCH 5/5] NFS: Determine initial mount security Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 22 Dec 2010 21:51:00 +0000 (UTC) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2d4a923..1ea4532 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -2141,15 +2142,43 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, return err; } +static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, + struct nfs_fsinfo *info, rpc_authflavor_t flavor) +{ + struct rpc_auth *auth; + int ret; + + auth = rpcauth_create(flavor, server->client); + if (!auth) { + ret = -EIO; + goto out; + } + ret = nfs4_lookup_root(server, fhandle, info); + if (ret < 0) + ret = -EAGAIN; +out: + return ret; +} + /* * get the file handle for the "/" directory on the server */ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *info) { - int status; + int i, len, status = 0; + rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS + 2]; - status = nfs4_lookup_root(server, fhandle, info); + flav_array[0] = RPC_AUTH_UNIX; + len = gss_mech_list_pseudoflavors(&flav_array[1]); + flav_array[1+len] = RPC_AUTH_NULL; + len += 2; + + for (i = 0; i < len; i++) { + status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); + if (status == 0) + break; + } if (status == 0) status = nfs4_server_capabilities(server, fhandle); if (status == 0) diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h index 5d8048b..332da61 100644 --- a/include/linux/sunrpc/gss_api.h +++ b/include/linux/sunrpc/gss_api.h @@ -126,6 +126,9 @@ struct gss_api_mech *gss_mech_get_by_name(const char *); /* Similar, but get by pseudoflavor. */ struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32); +/* Fill in an array with a list of supported pseudoflavors */ +int gss_mech_list_pseudoflavors(u32 *); + /* Just increments the mechanism's reference count and returns its input: */ struct gss_api_mech * gss_mech_get(struct gss_api_mech *); diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index 6c844b0..e3c36a2 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c @@ -215,6 +215,22 @@ gss_mech_get_by_pseudoflavor(u32 pseudoflavor) EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); +int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr) +{ + struct gss_api_mech *pos = NULL; + int i = 0; + + spin_lock(®istered_mechs_lock); + list_for_each_entry(pos, ®istered_mechs, gm_list) { + array_ptr[i] = pos->gm_pfs->pseudoflavor; + i++; + } + spin_unlock(®istered_mechs_lock); + return i; +} + +EXPORT_SYMBOL_GPL(gss_mech_list_pseudoflavors); + u32 gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) {