saving security context in vnetroot

windows calls into our driver from processes that have restricted access.

save security context during mount and use that for all other irps.
This commit is contained in:
Olga Kornievskaia 2011-12-06 17:19:46 -05:00 committed by unknown
parent 33a5f24f1f
commit 37f3fa0862

View file

@ -35,6 +35,7 @@
#include "nfs41_np.h" #include "nfs41_np.h"
#include "nfs41_debug.h" #include "nfs41_debug.h"
#define USE_MOUNT_SEC_CONTEXT
//#define DEBUG_CLOSE //#define DEBUG_CLOSE
//#define ENABLE_TIMINGS //#define ENABLE_TIMINGS
//#define ENABLE_INDV_TIMINGS //#define ENABLE_INDV_TIMINGS
@ -349,6 +350,10 @@ typedef struct _NFS41_V_NET_ROOT_EXTENSION {
LONG FsAttrsLen; LONG FsAttrsLen;
DWORD sec_flavor; DWORD sec_flavor;
BOOLEAN read_only; BOOLEAN read_only;
#define STORE_MOUNT_SEC_CONTEXT
#ifdef STORE_MOUNT_SEC_CONTEXT
SECURITY_CLIENT_CONTEXT mount_sec_ctx;
#endif
} NFS41_V_NET_ROOT_EXTENSION, *PNFS41_V_NET_ROOT_EXTENSION; } NFS41_V_NET_ROOT_EXTENSION, *PNFS41_V_NET_ROOT_EXTENSION;
#define NFS41GetVNetRootExtension(pVNetRoot) \ #define NFS41GetVNetRootExtension(pVNetRoot) \
(((pVNetRoot) == NULL) ? NULL : \ (((pVNetRoot) == NULL) ? NULL : \
@ -2610,6 +2615,29 @@ release_sec_ctx:
return status; return status;
} }
NTSTATUS nfs41_get_sec_ctx(
IN enum SECURITY_IMPERSONATION_LEVEL level,
OUT PSECURITY_CLIENT_CONTEXT out_ctx)
{
NTSTATUS status;
SECURITY_SUBJECT_CONTEXT ctx;
SECURITY_QUALITY_OF_SERVICE sec_qos;
SeCaptureSubjectContext(&ctx);
sec_qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
sec_qos.ImpersonationLevel = level;
sec_qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
sec_qos.EffectiveOnly = 0;
status = SeCreateClientSecurityFromSubjectContext(&ctx, &sec_qos, 1, out_ctx);
if (status != STATUS_SUCCESS) {
print_error("SeCreateClientSecurityFromSubjectContext "
"failed with %x\n", status);
}
DbgP("Created client security token %p\n", out_ctx->ClientToken);
SeReleaseSubjectContext(&ctx);
return status;
}
NTSTATUS nfs41_CreateVNetRoot( NTSTATUS nfs41_CreateVNetRoot(
IN OUT PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext) IN OUT PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext)
{ {
@ -2807,6 +2835,9 @@ NTSTATUS nfs41_CreateVNetRoot(
} }
pNetRootContext->nfs41d_version = nfs41d_version; pNetRootContext->nfs41d_version = nfs41d_version;
DbgP("Saving new session 0x%x\n", pVNetRootContext->session); DbgP("Saving new session 0x%x\n", pVNetRootContext->session);
#ifdef STORE_MOUNT_SEC_CONTEXT
status = nfs41_get_sec_ctx(SecurityImpersonation, &pVNetRootContext->mount_sec_ctx);
#endif
out: out:
/* AGLO do we need to worry about handling new netroot vs using existing one */ /* AGLO do we need to worry about handling new netroot vs using existing one */
@ -2983,11 +3014,17 @@ NTSTATUS nfs41_FinalizeVNetRoot(
IN PBOOLEAN ForceDisconnect) IN PBOOLEAN ForceDisconnect)
{ {
NTSTATUS status = STATUS_SUCCESS; NTSTATUS status = STATUS_SUCCESS;
PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
NFS41GetVNetRootExtension(pVNetRoot);
DbgEn(); DbgEn();
print_v_net_root(1, pVNetRoot); print_v_net_root(1, pVNetRoot);
if (pVNetRoot->pNetRoot->Type != NET_ROOT_DISK && if (pVNetRoot->pNetRoot->Type != NET_ROOT_DISK &&
pVNetRoot->pNetRoot->Type != NET_ROOT_WILD) pVNetRoot->pNetRoot->Type != NET_ROOT_WILD)
status = STATUS_NOT_SUPPORTED; status = STATUS_NOT_SUPPORTED;
#ifdef STORE_MOUNT_SEC_CONTEXT
SeDeleteClientSecurity(&pVNetRootContext->mount_sec_ctx);
#endif
DbgEx(); DbgEx();
return status; return status;
} }
@ -3123,8 +3160,13 @@ NTSTATUS nfs41_Create(
goto out; goto out;
} }
status = nfs41_UpcallCreate(NFS41_OPEN, NULL, pVNetRootContext->session, #if defined(STORE_MOUNT_SEC_CONTEXT) && defined (USE_MOUNT_SEC_CONTEXT)
INVALID_HANDLE_VALUE, pNetRootContext->nfs41d_version, &entry); status = nfs41_UpcallCreate(NFS41_OPEN, &pVNetRootContext->mount_sec_ctx,
#else
status = nfs41_UpcallCreate(NFS41_OPEN, NULL,
#endif
pVNetRootContext->session, INVALID_HANDLE_VALUE,
pNetRootContext->nfs41d_version, &entry);
if (status) if (status)
goto out; goto out;
entry->u.Open.filename = SrvOpen->pAlreadyPrefixedName; entry->u.Open.filename = SrvOpen->pAlreadyPrefixedName;
@ -3154,7 +3196,9 @@ NTSTATUS nfs41_Create(
status = STATUS_INTERNAL_ERROR; status = STATUS_INTERNAL_ERROR;
goto out; goto out;
} }
#ifndef USE_MOUNT_SEC_CONTEXT
SeDeleteClientSecurity(&entry->sec_ctx); SeDeleteClientSecurity(&entry->sec_ctx);
#endif
if (entry->status == NO_ERROR && entry->errno == ERROR_REPARSE) { if (entry->status == NO_ERROR && entry->errno == ERROR_REPARSE) {
/* symbolic link handling. when attempting to open a symlink when the /* symbolic link handling. when attempting to open a symlink when the
@ -3221,23 +3265,14 @@ NTSTATUS nfs41_Create(
print_fobx(1, RxContext->pFobx); print_fobx(1, RxContext->pFobx);
nfs41_fobx = (PNFS41_FOBX)(RxContext->pFobx)->Context; nfs41_fobx = (PNFS41_FOBX)(RxContext->pFobx)->Context;
nfs41_fobx->nfs41_open_state = entry->open_state; nfs41_fobx->nfs41_open_state = entry->open_state;
{ #ifndef USE_MOUNT_SEC_CONTEXT
SECURITY_SUBJECT_CONTEXT sec_ctx; status = nfs41_get_sec_ctx(SecurityImpersonation, &nfs41_fobx->sec_ctx);
SECURITY_QUALITY_OF_SERVICE sec_qos; if (status)
SeCaptureSubjectContext(&sec_ctx); goto out_free;
sec_qos.ContextTrackingMode = SECURITY_STATIC_TRACKING; #else
sec_qos.ImpersonationLevel = SecurityImpersonation; RtlCopyMemory(&nfs41_fobx->sec_ctx, &pVNetRootContext->mount_sec_ctx,
sec_qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); sizeof(nfs41_fobx->sec_ctx));
sec_qos.EffectiveOnly = 0; #endif
status = SeCreateClientSecurityFromSubjectContext(&sec_ctx, &sec_qos, 1, &nfs41_fobx->sec_ctx);
if (status != STATUS_SUCCESS) {
print_error("nfs41_Create: SeCreateClientSecurityFromSubjectContext "
"failed with %x\n", status);
RxFreePool(entry);
}
DbgP("Created client security token %p\n", nfs41_fobx->sec_ctx.ClientToken);
SeReleaseSubjectContext(&sec_ctx);
}
// we get attributes only for data access and file (not directories) // we get attributes only for data access and file (not directories)
if (Fcb->OpenCount > 0) if (Fcb->OpenCount > 0)
@ -3509,7 +3544,9 @@ NTSTATUS nfs41_CloseSrvOpen (
/* map windows ERRORs to NTSTATUS */ /* map windows ERRORs to NTSTATUS */
status = map_close_errors(entry->status); status = map_close_errors(entry->status);
RxFreePool(entry); RxFreePool(entry);
#ifndef USE_MOUNT_SEC_CONTEXT
SeDeleteClientSecurity(&nfs41_fobx->sec_ctx); SeDeleteClientSecurity(&nfs41_fobx->sec_ctx);
#endif
out: out:
#ifdef ENABLE_TIMINGS #ifdef ENABLE_TIMINGS
t2 = KeQueryPerformanceCounter(NULL); t2 = KeQueryPerformanceCounter(NULL);
@ -3655,7 +3692,6 @@ NTSTATUS nfs41_QueryDirectory (
status = STATUS_INVALID_PARAMETER; status = STATUS_INVALID_PARAMETER;
goto out; goto out;
} }
status = nfs41_UpcallCreate(NFS41_DIR_QUERY, &nfs41_fobx->sec_ctx, status = nfs41_UpcallCreate(NFS41_DIR_QUERY, &nfs41_fobx->sec_ctx,
pVNetRootContext->session, nfs41_fobx->nfs41_open_state, pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
pNetRootContext->nfs41d_version, &entry); pNetRootContext->nfs41d_version, &entry);
@ -3835,7 +3871,6 @@ NTSTATUS nfs41_QueryVolumeInformation (
status = STATUS_INVALID_PARAMETER; status = STATUS_INVALID_PARAMETER;
goto out; goto out;
} }
status = nfs41_UpcallCreate(NFS41_VOLUME_QUERY, &nfs41_fobx->sec_ctx, status = nfs41_UpcallCreate(NFS41_VOLUME_QUERY, &nfs41_fobx->sec_ctx,
pVNetRootContext->session, nfs41_fobx->nfs41_open_state, pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
pNetRootContext->nfs41d_version, &entry); pNetRootContext->nfs41d_version, &entry);