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:
parent
33a5f24f1f
commit
37f3fa0862
1 changed files with 62 additions and 27 deletions
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue