From 1223ca9cabb15fad01acae3f67096f4b955f1f97 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 23 Jul 2006 08:20:57 +0000 Subject: [PATCH] - Refactor SeCaptureSubjectContext into SeCaptureSubjectContextEx and SeCreateAccessState into SeCreateAccessStateEx. The *Ex routines allow specifying a custom process/thread which isn't the current one. This is useful when creating a new process or thread since we're not actually in it. - Implemented a bit more security calls in PspCreateProcess as seen in WI II. We now create an AccessState. - Also write the PID in the ObjectTable. svn path=/trunk/; revision=23236 --- reactos/ntoskrnl/include/internal/se.h | 23 +++++++++ reactos/ntoskrnl/ps/process.c | 35 ++++++++++++-- reactos/ntoskrnl/se/access.c | 52 +++++++++++++------- reactos/ntoskrnl/se/audit.c | 7 +++ reactos/ntoskrnl/se/semgr.c | 66 ++++++++++++++++---------- 5 files changed, 138 insertions(+), 45 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/se.h b/reactos/ntoskrnl/include/internal/se.h index c0cb0fd45b4..96f64715094 100644 --- a/reactos/ntoskrnl/include/internal/se.h +++ b/reactos/ntoskrnl/include/internal/se.h @@ -129,6 +129,17 @@ SeSubProcessToken( IN ULONG SessionId ); +NTSTATUS +NTAPI +SeCreateAccessStateEx( + IN PETHREAD Thread, + IN PEPROCESS Process, + IN OUT PACCESS_STATE AccessState, + IN PAUX_DATA AuxData, + IN ACCESS_MASK Access, + IN PGENERIC_MAPPING GenericMapping +); + NTSTATUS NTAPI SeIsTokenChild( @@ -160,6 +171,10 @@ VOID NTAPI SeAuditProcessExit(IN PEPROCESS Process); +VOID +NTAPI +SeAuditProcessCreate(IN PEPROCESS Process); + NTSTATUS NTAPI SeExchangePrimaryToken( @@ -168,6 +183,14 @@ SeExchangePrimaryToken( PACCESS_TOKEN* OldTokenP ); +VOID +NTAPI +SeCaptureSubjectContextEx( + IN PETHREAD Thread, + IN PEPROCESS Process, + OUT PSECURITY_SUBJECT_CONTEXT SubjectContext +); + NTSTATUS NTAPI SeCaptureLuidAndAttributesArray( diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 3727aa82b41..9b48e495c8f 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -368,6 +368,9 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, PETHREAD CurrentThread; PEPROCESS CurrentProcess; ULONG MinWs, MaxWs; + ACCESS_STATE LocalAccessState; + PACCESS_STATE AccessState = &LocalAccessState; + AUX_DATA AuxData; PAGED_CODE(); DirectoryTableBase.QuadPart = 0; @@ -633,7 +636,19 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, goto CleanupWithRef; } - /* FIXME: Insert into Job Object */ + /* Set the handle table PID */ + Process->ObjectTable->UniqueProcessId = Process->UniqueProcessId; + + /* Check if we need to audit */ + if (SeDetailedAuditingWithToken(NULL)) SeAuditProcessCreate(Process); + + /* Check if the parent had a job */ + if ((Parent) && (Parent->Job)) + { + /* FIXME: We need to insert this process */ + DPRINT1("Jobs not yet supported\n"); + KEBUGCHECK(0); + } /* Create PEB only for User-Mode Processes */ if (Parent) @@ -647,15 +662,29 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, InsertTailList(&PsActiveProcessHead, &Process->ActiveProcessLinks); KeReleaseGuardedMutex(&PspActiveProcessMutex); - /* FIXME: SeCreateAccessStateEx */ + /* Create an access state */ + Status = SeCreateAccessStateEx(CurrentThread, + ((Parent) && + (Parent == PsInitialSystemProcess)) ? + Parent : CurrentProcess, + &LocalAccessState, + &AuxData, + DesiredAccess, + &PsProcessType->TypeInfo.GenericMapping); + if (!NT_SUCCESS(Status)) goto CleanupWithRef; /* Insert the Process into the Object Directory */ Status = ObInsertObject(Process, - NULL, + AccessState, DesiredAccess, 1, (PVOID*)&Process, &hProcess); + + /* Free the access state */ + if (AccessState) SeDeleteAccessState(AccessState); + + /* Cleanup on failure */ if (!NT_SUCCESS(Status)) goto Cleanup; /* FIXME: Compute Quantum and Priority */ diff --git a/reactos/ntoskrnl/se/access.c b/reactos/ntoskrnl/se/access.c index 714e0f7d712..2d5f721c6f2 100644 --- a/reactos/ntoskrnl/se/access.c +++ b/reactos/ntoskrnl/se/access.c @@ -14,24 +14,19 @@ #define NDEBUG #include -#define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | \ - GENERIC_ALL) - /* FUNCTIONS ***************************************************************/ -/* - * @implemented - */ NTSTATUS -STDCALL -SeCreateAccessState(PACCESS_STATE AccessState, - PAUX_DATA AuxData, - ACCESS_MASK Access, - PGENERIC_MAPPING GenericMapping) +NTAPI +SeCreateAccessStateEx(IN PETHREAD Thread, + IN PEPROCESS Process, + IN OUT PACCESS_STATE AccessState, + IN PAUX_DATA AuxData, + IN ACCESS_MASK Access, + IN PGENERIC_MAPPING GenericMapping) { ACCESS_MASK AccessMask = Access; PTOKEN Token; - PAGED_CODE(); /* Map the Generic Acess to Specific Access if we have a Mapping */ @@ -44,8 +39,10 @@ SeCreateAccessState(PACCESS_STATE AccessState, RtlZeroMemory(AccessState, sizeof(ACCESS_STATE)); /* Capture the Subject Context */ - SeCaptureSubjectContext(&AccessState->SubjectSecurityContext); - + SeCaptureSubjectContextEx(Thread, + Process, + &AccessState->SubjectSecurityContext); + /* Set Access State Data */ AccessState->AuxData = AuxData; AccessState->RemainingDesiredAccess = AccessMask; @@ -56,7 +53,7 @@ SeCreateAccessState(PACCESS_STATE AccessState, Token = AccessState->SubjectSecurityContext.ClientToken ? (PTOKEN)&AccessState->SubjectSecurityContext.ClientToken : (PTOKEN)&AccessState->SubjectSecurityContext.PrimaryToken; - + /* Check for Travers Privilege */ if (Token->TokenFlags & TOKEN_HAS_TRAVERSE_PRIVILEGE) { @@ -67,13 +64,34 @@ SeCreateAccessState(PACCESS_STATE AccessState, /* Set the Auxiliary Data */ AuxData->PrivilegeSet = (PPRIVILEGE_SET)((ULONG_PTR)AccessState + FIELD_OFFSET(ACCESS_STATE, - Privileges)); + Privileges)); if (GenericMapping) AuxData->GenericMapping = *GenericMapping; /* Return Sucess */ return STATUS_SUCCESS; } +/* + * @implemented + */ +NTSTATUS +STDCALL +SeCreateAccessState(IN OUT PACCESS_STATE AccessState, + IN PAUX_DATA AuxData, + IN ACCESS_MASK Access, + IN PGENERIC_MAPPING GenericMapping) +{ + PAGED_CODE(); + + /* Call the internal API */ + return SeCreateAccessStateEx(PsGetCurrentThread(), + PsGetCurrentProcess(), + AccessState, + AuxData, + Access, + GenericMapping); +} + /* * @implemented */ @@ -89,7 +107,7 @@ SeDeleteAccessState(IN PACCESS_STATE AccessState) /* Deallocate Privileges */ if (AccessState->PrivilegesAllocated) ExFreePool(AuxData->PrivilegeSet); - + /* Deallocate Name and Type Name */ if (AccessState->ObjectName.Buffer) { diff --git a/reactos/ntoskrnl/se/audit.c b/reactos/ntoskrnl/se/audit.c index 2cfca0d6f39..754259f2841 100644 --- a/reactos/ntoskrnl/se/audit.c +++ b/reactos/ntoskrnl/se/audit.c @@ -23,6 +23,13 @@ SeDetailedAuditingWithToken(IN PTOKEN Token) return FALSE; } +VOID +NTAPI +SeAuditProcessCreate(IN PEPROCESS Process) +{ + /* FIXME */ +} + VOID NTAPI SeAuditProcessExit(IN PEPROCESS Process) diff --git a/reactos/ntoskrnl/se/semgr.c b/reactos/ntoskrnl/se/semgr.c index f171e2aac82..dbb605c2355 100644 --- a/reactos/ntoskrnl/se/semgr.c +++ b/reactos/ntoskrnl/se/semgr.c @@ -416,36 +416,52 @@ SeDefaultObjectMethod(PVOID Object, return STATUS_SUCCESS; } +VOID +NTAPI +SeCaptureSubjectContextEx(IN PETHREAD Thread, + IN PEPROCESS Process, + OUT PSECURITY_SUBJECT_CONTEXT SubjectContext) +{ + BOOLEAN CopyOnOpen, EffectiveOnly; + PAGED_CODE(); + + /* ROS HACK */ + if (!Process) return; + + /* Save the unique ID */ + SubjectContext->ProcessAuditId = Process->UniqueProcessId; + + /* Check if we have a thread */ + if (!Thread) + { + /* We don't, so no token */ + SubjectContext->ClientToken = NULL; + } + else + { + /* Get the impersonation token */ + SubjectContext->ClientToken = + PsReferenceImpersonationToken(Thread, + &CopyOnOpen, + &EffectiveOnly, + &SubjectContext->ImpersonationLevel); + } + + /* Get the primary token */ + SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process); +} + /* * @implemented */ -VOID STDCALL +VOID +NTAPI SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext) { - PETHREAD Thread; - BOOLEAN CopyOnOpen; - BOOLEAN EffectiveOnly; - - PAGED_CODE(); - - Thread = PsGetCurrentThread(); - if (Thread == NULL) - { - SubjectContext->ProcessAuditId = 0; - SubjectContext->PrimaryToken = NULL; - SubjectContext->ClientToken = NULL; - SubjectContext->ImpersonationLevel = 0; - } - else - { - SubjectContext->ProcessAuditId = Thread->ThreadsProcess; - SubjectContext->ClientToken = - PsReferenceImpersonationToken(Thread, - &CopyOnOpen, - &EffectiveOnly, - &SubjectContext->ImpersonationLevel); - SubjectContext->PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess); - } + /* Call the internal API */ + SeCaptureSubjectContextEx(PsGetCurrentThread(), + PsGetCurrentProcess(), + SubjectContext); }