VOID NTAPI NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext) { TOKEN_TYPE TokenType; PVOID ClientToken; if (!ClientContext) return; TokenType = SeTokenType(ClientContext->ClientToken); ClientToken = ClientContext->ClientToken; if ((TokenType == TokenPrimary) || (ClientToken)) { ObDereferenceObject(ClientToken); } ExFreePool(ClientContext); }
NTSTATUS FspFsvolSetSecurityPrepare( PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request) { PAGED_CODE(); NTSTATUS Result; SECURITY_SUBJECT_CONTEXT SecuritySubjectContext; SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; SECURITY_CLIENT_CONTEXT SecurityClientContext; HANDLE UserModeAccessToken; PEPROCESS Process; /* duplicate the subject context access token into an impersonation token */ SecurityQualityOfService.Length = sizeof SecurityQualityOfService; SecurityQualityOfService.ImpersonationLevel = SecurityIdentification; SecurityQualityOfService.ContextTrackingMode = SECURITY_STATIC_TRACKING; SecurityQualityOfService.EffectiveOnly = FALSE; SeCaptureSubjectContext(&SecuritySubjectContext); SeLockSubjectContext(&SecuritySubjectContext); Result = SeCreateClientSecurityFromSubjectContext(&SecuritySubjectContext, &SecurityQualityOfService, FALSE, &SecurityClientContext); SeUnlockSubjectContext(&SecuritySubjectContext); SeReleaseSubjectContext(&SecuritySubjectContext); if (!NT_SUCCESS(Result)) return Result; ASSERT(TokenImpersonation == SeTokenType(SecurityClientContext.ClientToken)); /* get a user-mode handle to the impersonation token */ Result = ObOpenObjectByPointer(SecurityClientContext.ClientToken, 0, 0, TOKEN_QUERY, *SeTokenObjectType, UserMode, &UserModeAccessToken); SeDeleteClientSecurity(&SecurityClientContext); if (!NT_SUCCESS(Result)) return Result; /* get a pointer to the current process so that we can close the impersonation token later */ Process = PsGetCurrentProcess(); ObReferenceObject(Process); /* send the user-mode handle to the user-mode file system */ FspIopRequestContext(Request, RequestAccessToken) = UserModeAccessToken; FspIopRequestContext(Request, RequestProcess) = Process; Request->Req.SetSecurity.AccessToken = (UINT_PTR)UserModeAccessToken; return STATUS_SUCCESS; }