From f7a9932cb318c250035c81b494492f0d7da437d3 Mon Sep 17 00:00:00 2001 From: Olga Kornievskaia Date: Thu, 2 Dec 2010 12:28:49 -0500 Subject: [PATCH] creating nfs client per security flavor --- daemon/mount.c | 4 ++-- daemon/namespace.c | 4 +++- daemon/nfs41.h | 2 ++ daemon/nfs41_client.c | 7 ++++++ sys/nfs41_driver.c | 56 +++++++++++++++++++++++++++---------------- 5 files changed, 50 insertions(+), 23 deletions(-) diff --git a/daemon/mount.c b/daemon/mount.c index 85e9504..5169561 100644 --- a/daemon/mount.c +++ b/daemon/mount.c @@ -66,7 +66,7 @@ static int handle_mount(nfs41_upcall *upcall) goto out; } // create root - status = nfs41_root_create(args->hostname, + status = nfs41_root_create(args->hostname, args->sec_flavor, NFS41_MAX_FILEIO_SIZE + WRITE_OVERHEAD, NFS41_MAX_FILEIO_SIZE + READ_OVERHEAD, &root); if (status) { @@ -76,7 +76,7 @@ static int handle_mount(nfs41_upcall *upcall) // add a mount root->uid = upcall->uid; root->gid = upcall->gid; - root->sec_flavor = args->sec_flavor; + status = nfs41_root_mount_addrs(root, &addrs, 0, 0, &client); if (status) { eprintf("nfs41_root_mount() failed with %d\n", status); diff --git a/daemon/namespace.c b/daemon/namespace.c index e0f71c8..eb9d9b3 100644 --- a/daemon/namespace.c +++ b/daemon/namespace.c @@ -38,6 +38,7 @@ /* nfs41_root */ int nfs41_root_create( IN const char *name, + IN uint32_t sec_flavor, IN uint32_t wsize, IN uint32_t rsize, OUT nfs41_root **root_out) @@ -58,9 +59,10 @@ int nfs41_root_create( root->rsize = rsize; InitializeCriticalSection(&root->lock); root->ref_count = 1; + root->sec_flavor = sec_flavor; /* generate a unique client_owner */ - status = nfs41_client_owner(name, &root->client_owner); + status = nfs41_client_owner(name, sec_flavor, &root->client_owner); if (status) { eprintf("nfs41_client_owner() failed with %d\n", status); goto out; diff --git a/daemon/nfs41.h b/daemon/nfs41.h index 7f3f087..7123f90 100644 --- a/daemon/nfs41.h +++ b/daemon/nfs41.h @@ -191,6 +191,7 @@ typedef struct __nfs41_root { /* nfs41_namespace.c */ int nfs41_root_create( IN const char *name, + IN uint32_t sec_flavor, IN uint32_t wsize, IN uint32_t rsize, OUT nfs41_root **root_out); @@ -298,6 +299,7 @@ void nfs41_server_addrs( /* nfs41_client.c */ int nfs41_client_owner( IN const char *name, + IN uint32_t sec_flavor, OUT client_owner4 *owner); uint32_t nfs41_exchange_id_flags( diff --git a/daemon/nfs41_client.c b/daemon/nfs41_client.c index 738505a..d9fc8c4 100644 --- a/daemon/nfs41_client.c +++ b/daemon/nfs41_client.c @@ -365,6 +365,7 @@ out: int nfs41_client_owner( IN const char *name, + IN uint32_t sec_flavor, OUT client_owner4 *owner) { HCRYPTPROV context; @@ -391,6 +392,12 @@ int nfs41_client_owner( goto out_context; } + if (!CryptHashData(hash, (const BYTE*)&sec_flavor, (DWORD)sizeof(sec_flavor), 0)) { + status = GetLastError(); + eprintf("CryptHashData() failed with %d\n", status); + goto out_hash; + } + if (!CryptHashData(hash, (const BYTE*)name, (DWORD)strlen(name), 0)) { status = GetLastError(); eprintf("CryptHashData() failed with %d\n", status); diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c index 99d8880..6c6e333 100644 --- a/sys/nfs41_driver.c +++ b/sys/nfs41_driver.c @@ -292,7 +292,8 @@ typedef struct _NFS41_MOUNT_CONFIG { typedef struct _NFS41_NETROOT_EXTENSION { NODE_TYPE_CODE NodeTypeCode; NODE_BYTE_SIZE NodeByteSize; - HANDLE session; + HANDLE auth_sys_session; + HANDLE gss_session; DWORD nfs41d_version; } NFS41_NETROOT_EXTENSION, *PNFS41_NETROOT_EXTENSION; #define NFS41GetNetRootExtension(pNetRoot) \ @@ -2360,15 +2361,6 @@ NTSTATUS nfs41_CreateVNetRoot( pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_GOOD; pNetRoot->DeviceType = FILE_DEVICE_DISK; - if (pNetRootContext->session) { - /* already established a session for this net root */ - pVNetRootContext->session = pNetRootContext->session; - DbgP("Using existing session 0x%x\n", pVNetRootContext->session); - goto out; - } - - pVNetRootContext->session = pNetRootContext->session = NULL; - nfs41_MountConfig_InitDefaults(&Config); if (pCreateNetRootContext->RxContext->Create.EaLength) { @@ -2394,15 +2386,30 @@ NTSTATUS nfs41_CreateVNetRoot( goto out; } + if (pVNetRootContext->sec_flavor == RPCSEC_AUTH_SYS && + pNetRootContext->auth_sys_session) { + pVNetRootContext->session = pNetRootContext->auth_sys_session; + DbgP("Using existing AUTH_SYS session 0x%x\n", pVNetRootContext->session); + goto out; + } else if (pVNetRootContext->sec_flavor != RPCSEC_AUTH_SYS && + pNetRootContext->gss_session) { + pVNetRootContext->session = pNetRootContext->gss_session; + DbgP("Using existing AUTHGSS session 0x%x\n", pVNetRootContext->session); + goto out; + } + /* send the mount upcall */ - DbgP("Server Name %wZ Mount Point %wZ\n", - &Config.SrvName, &Config.MntPt); + DbgP("Server Name %wZ Mount Point %wZ SecFlavor %wZ\n", + &Config.SrvName, &Config.MntPt, &Config.SecFlavor); status = nfs41_mount(&Config.SrvName, &Config.MntPt, pVNetRootContext->sec_flavor, &pVNetRootContext->session, &nfs41d_version); if (status != STATUS_SUCCESS) goto out; pNetRootContext->nfs41d_version = nfs41d_version; - pNetRootContext->session = pVNetRootContext->session; + if (pVNetRootContext->sec_flavor == RPCSEC_AUTH_SYS) + pNetRootContext->auth_sys_session = pVNetRootContext->session; + else + pNetRootContext->gss_session = pVNetRootContext->session; DbgP("Saving new session 0x%x\n", pVNetRootContext->session); out: @@ -2499,7 +2506,8 @@ NTSTATUS nfs41_FinalizeNetRoot( goto out; } - if (pNetRootContext == NULL || pNetRootContext->session == NULL) { + if (pNetRootContext == NULL || (pNetRootContext->auth_sys_session == NULL && + pNetRootContext->gss_session == NULL)) { print_error("No valid session has been established\n"); goto out; } @@ -2510,12 +2518,20 @@ NTSTATUS nfs41_FinalizeNetRoot( goto out; } - status = nfs41_unmount(pNetRootContext->session, pNetRootContext->nfs41d_version); - if (status) { - print_error("nfs41_mount failed with %d\n", status); - goto out; + if (pNetRootContext->auth_sys_session) { + status = nfs41_unmount(pNetRootContext->auth_sys_session, pNetRootContext->nfs41d_version); + if (status) { + print_error("nfs41_mount AUTH_SYS failed with %d\n", status); + goto out; + } + } + if (pNetRootContext->gss_session) { + status = nfs41_unmount(pNetRootContext->gss_session, pNetRootContext->nfs41d_version); + if (status) { + print_error("nfs41_mount AUTHGSS failed with %d\n", status); + goto out; + } } - // check if there is anything waiting in the upcall or downcall queue do { nfs41_GetFirstEntry(upcallLock, upcall, tmp); @@ -2674,7 +2690,7 @@ NTSTATUS nfs41_Create( goto out; } - if (pNetRootContext->session == NULL) { + if (pNetRootContext->auth_sys_session == NULL && pNetRootContext->gss_session == NULL) { print_error("No valid session established\n"); goto out; }