Author: sginsberg
Date: Fri Jan 2 11:39:45 2009
New Revision: 38510
URL:
http://svn.reactos.org/svn/reactos?rev=38510&view=rev
Log:
- Cleanup AccessCheck, and set the correct last error in the case where the check succeeds
but access is denied
- Cleanup NtAccessCheck, properly set desired access when previous mode is kernel, remove
a duplicate check that is performed in SeAccessCheck, and don't fail with
STATUS_ACCESS_DENIED when the check succeeds but denies access -- the result of the access
check is returned in the 'AccessStatus' parameter
Modified:
trunk/reactos/dll/win32/advapi32/token/token.c
trunk/reactos/ntoskrnl/se/semgr.c
Modified: trunk/reactos/dll/win32/advapi32/token/token.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/token/t…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/token/token.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/token/token.c [iso-8859-1] Fri Jan 2 11:39:45 2009
@@ -135,19 +135,21 @@
/*
* @implemented
*/
-BOOL WINAPI
-AccessCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
- HANDLE ClientToken,
- DWORD DesiredAccess,
- PGENERIC_MAPPING GenericMapping,
- PPRIVILEGE_SET PrivilegeSet,
- LPDWORD PrivilegeSetLength,
- LPDWORD GrantedAccess,
- LPBOOL AccessStatus)
-{
- NTSTATUS Status;
- NTSTATUS AccessStat;
-
+BOOL
+WINAPI
+AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ IN HANDLE ClientToken,
+ IN DWORD DesiredAccess,
+ IN PGENERIC_MAPPING GenericMapping,
+ OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL,
+ IN OUT LPDWORD PrivilegeSetLength,
+ OUT LPDWORD GrantedAccess,
+ OUT LPBOOL AccessStatus)
+{
+ NTSTATUS Status;
+ NTSTATUS NtAccessStatus;
+
+ /* Do the access check */
Status = NtAccessCheck(pSecurityDescriptor,
ClientToken,
DesiredAccess,
@@ -155,22 +157,30 @@
PrivilegeSet,
(PULONG)PrivilegeSetLength,
(PACCESS_MASK)GrantedAccess,
- &AccessStat);
- if (!NT_SUCCESS(Status))
- {
- SetLastError(RtlNtStatusToDosError(Status));
- return FALSE;
- }
-
- if (!NT_SUCCESS(AccessStat))
- {
- SetLastError(RtlNtStatusToDosError(Status));
+ &NtAccessStatus);
+
+ /* See if the access check operation succeeded */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Check failed */
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ /* Now check the access status */
+ if (!NT_SUCCESS(NtAccessStatus))
+ {
+ /* Access denied */
+ SetLastError(RtlNtStatusToDosError(NtAccessStatus));
*AccessStatus = FALSE;
- return TRUE;
- }
-
- *AccessStatus = TRUE;
-
+ }
+ else
+ {
+ /* Access granted */
+ *AccessStatus = TRUE;
+ }
+
+ /* Check succeeded */
return TRUE;
}
Modified: trunk/reactos/ntoskrnl/se/semgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/semgr.c?rev=38…
==============================================================================
--- trunk/reactos/ntoskrnl/se/semgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/se/semgr.c [iso-8859-1] Fri Jan 2 11:39:45 2009
@@ -619,33 +619,48 @@
/* SYSTEM CALLS ***************************************************************/
-NTSTATUS NTAPI
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
IN HANDLE TokenHandle,
IN ACCESS_MASK DesiredAccess,
IN PGENERIC_MAPPING GenericMapping,
- OUT PPRIVILEGE_SET PrivilegeSet,
- OUT PULONG ReturnLength,
+ OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL,
+ IN OUT PULONG PrivilegeSetLength,
OUT PACCESS_MASK GrantedAccess,
OUT PNTSTATUS AccessStatus)
{
- SECURITY_SUBJECT_CONTEXT SubjectSecurityContext = { NULL, 0, NULL, NULL };
- KPROCESSOR_MODE PreviousMode;
+ SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PTOKEN Token;
NTSTATUS Status;
-
PAGED_CODE();
- DPRINT("NtAccessCheck() called\n");
-
- PreviousMode = KeGetPreviousMode();
+ /* Check if this is kernel mode */
if (PreviousMode == KernelMode)
{
- *GrantedAccess = DesiredAccess;
+ /* Check if kernel wants everything */
+ if (DesiredAccess & MAXIMUM_ALLOWED)
+ {
+ /* Give it */
+ *GrantedAccess = GenericMapping->GenericAll;
+ *GrantedAccess |= (DesiredAccess &~ MAXIMUM_ALLOWED);
+ }
+ else
+ {
+ /* Just give the desired access */
+ *GrantedAccess = DesiredAccess;
+ }
+
+ /* Success */
*AccessStatus = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
-
+
+ /* Reference the token */
Status = ObReferenceObjectByHandle(TokenHandle,
TOKEN_QUERY,
SepTokenObjectType,
@@ -657,56 +672,42 @@
DPRINT1("Failed to reference token (Status %lx)\n", Status);
return Status;
}
-
+
/* Check token type */
if (Token->TokenType != TokenImpersonation)
{
DPRINT1("No impersonation token\n");
ObDereferenceObject(Token);
- return STATUS_ACCESS_VIOLATION;
- }
-
- /* Check impersonation level */
- if (Token->ImpersonationLevel < SecurityIdentification)
- {
- DPRINT1("Invalid impersonation level\n");
- ObDereferenceObject(Token);
- return STATUS_ACCESS_VIOLATION;
- }
-
+ return STATUS_ACCESS_DENIED;
+ }
+
+ /* Set up the subject context, and lock it */
SubjectSecurityContext.ClientToken = Token;
SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
-
- /* Lock subject context */
+ SubjectSecurityContext.PrimaryToken = NULL;
+ SubjectSecurityContext.ProcessAuditId = NULL;
SeLockSubjectContext(&SubjectSecurityContext);
-
- if (SeAccessCheck(SecurityDescriptor,
- &SubjectSecurityContext,
- TRUE,
- DesiredAccess,
- 0,
- &PrivilegeSet,
- GenericMapping,
- PreviousMode,
- GrantedAccess,
- AccessStatus))
- {
- Status = *AccessStatus;
- }
- else
- {
- Status = STATUS_ACCESS_DENIED;
- }
-
- /* Unlock subject context */
+
+ /* Now perform the access check */
+ SeAccessCheck(SecurityDescriptor,
+ &SubjectSecurityContext,
+ TRUE,
+ DesiredAccess,
+ 0,
+ &PrivilegeSet, //FIXME
+ GenericMapping,
+ PreviousMode,
+ GrantedAccess,
+ AccessStatus);
+
+ /* Unlock subject context and dereference the token */
SeUnlockSubjectContext(&SubjectSecurityContext);
-
ObDereferenceObject(Token);
-
- DPRINT("NtAccessCheck() done\n");
-
- return Status;
-}
+
+ /* Check succeeded */
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
NTAPI