Example #1
0
BOOLEAN
AFSIsInGroup(PSID Sid)
{
    SECURITY_SUBJECT_CONTEXT subjectContext;
    PTOKEN_GROUPS groups;
    PACCESS_TOKEN token;
    BOOLEAN retVal = FALSE;

    SeCaptureSubjectContext( &subjectContext );
    SeLockSubjectContext( &subjectContext );

    token = SeQuerySubjectContextToken( &subjectContext );

    if (NT_SUCCESS(SeQueryInformationToken(token, TokenGroups, (PVOID*) &groups)))
    {
        ULONG i;
        for (i = 0; !retVal && i < groups->GroupCount; i++)
        {
            retVal = RtlEqualSid(Sid, groups->Groups[i].Sid);
        }

        ExFreePool( groups );
    }
    SeUnlockSubjectContext( &subjectContext );
    SeReleaseSubjectContext( &subjectContext );
    return retVal;
}
Example #2
0
BOOLEAN
AFSIsUser( IN PSID Sid)
{
    SECURITY_SUBJECT_CONTEXT subjectContext;
    PTOKEN_USER user;
    PACCESS_TOKEN token;
    BOOLEAN retVal = FALSE;

    SeCaptureSubjectContext( &subjectContext);
    SeLockSubjectContext( &subjectContext);

    token = SeQuerySubjectContextToken( &subjectContext);

    if (NT_SUCCESS (SeQueryInformationToken( token, TokenUser, (PVOID*) &user)))
    {

        retVal = RtlEqualSid( user->User.Sid, Sid);

        ExFreePool( user );
    }
    SeUnlockSubjectContext( &subjectContext);
    SeReleaseSubjectContext( &subjectContext);
    return retVal;
}
void TestsSeQueryInformationToken(PACCESS_TOKEN Token) 
{
    NTSTATUS Status;
    PVOID Buffer = NULL;
    PSID sid;
    PTOKEN_OWNER Towner;
    PTOKEN_DEFAULT_DACL TDefDacl;
    PTOKEN_GROUPS TGroups;
    ULONG GroupCount;
    PACL acl;
    PTOKEN_STATISTICS TStats;
    PTOKEN_TYPE TType;
    PTOKEN_USER TUser;
    BOOLEAN Flag;
    ULONG i;

    //----------------------------------------------------------------//
    // Testing SeQueryInformationToken with various args              //
    //----------------------------------------------------------------//

    ok(Token != NULL, "Token is not captured. Testing SQIT interrupted\n\n");

    if (Token == NULL) return;

    Status = SeQueryInformationToken(Token, TokenOwner, &Buffer);
    ok((Status == STATUS_SUCCESS), "SQIT with TokenOwner arg fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenOwner arg. But Buffer = NULL\n");

        if (Buffer)
        {
            Towner = (TOKEN_OWNER *)Buffer;
            sid = Towner->Owner;
            ok((RtlValidSid(sid) == TRUE), "TokenOwner's SID is not a valid SID\n");
            ExFreePool(Buffer);
        }
    }

    //----------------------------------------------------------------//
    
    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenDefaultDacl, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenDefaultDacl fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenDefaultDacl arg. But Buffer = NULL\n");
        if (Buffer)
        {
            TDefDacl = (PTOKEN_DEFAULT_DACL)Buffer;
            acl = TDefDacl->DefaultDacl;
            ok(((acl->AclRevision == ACL_REVISION || acl->AclRevision == ACL_REVISION_DS) == TRUE), "DACL is invalid\n");
            ExFreePool(Buffer);
        }
    }

    //----------------------------------------------------------------//

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenGroups, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenGroups fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenGroups arg. But Buffer = NULL\n");
        if (Buffer)
        {
            TGroups = (PTOKEN_GROUPS)Buffer;
            GroupCount = TGroups->GroupCount;
            Flag = TRUE;
            for (i = 0; i < GroupCount; i++)
            {
                sid = TGroups->Groups[i].Sid;
                if (!RtlValidSid(sid))
                {
                    Flag = FALSE;
                    break;
                }
            }
            ok((Flag == TRUE), "TokenGroup's SIDs are not valid\n");
            ExFreePool(Buffer);
        }
    }

    //----------------------------------------------------------------//

    // Call SQIT with TokenImpersonationLevel argument
    //
    // What's up? Why SQIT fails with right arg?

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenImpersonationLevel fails with status 0x%X\n", Status);

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
    ok(Status == STATUS_SUCCESS, "and again: SQIT with TokenImpersonationLevel fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenImpersonationLevel arg. But Buffer = NULL\n");
    } else {
        ok(Buffer == NULL, "Wrong. SQIT call is't success. But Buffer != NULL\n");
    }

    //----------------------------------------------------------------//

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenStatistics, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenStatistics fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenStatistics arg. But Buffer = NULL\n");
        if (Buffer)
        {
            TStats = (PTOKEN_STATISTICS)Buffer;
            // just put 0 into 1st arg or use trace to print TokenStatistics f
            ok(1, "print statistics:\n\tTokenID = %u_%d\n\tSecurityImperLevel = %d\n\tPrivCount = %d\n\tGroupCount = %d\n\n", TStats->TokenId.LowPart, 
                TStats->TokenId.HighPart, 
                TStats->ImpersonationLevel,
                TStats->PrivilegeCount,
                TStats->GroupCount
                );
            ExFreePool(TStats);
        }
    } else {
        ok(Buffer == NULL, "Wrong. SQIT call is't success. But Buffer != NULL\n");
    }

    //----------------------------------------------------------------//

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenType, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenType fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenType arg. But Buffer = NULL\n");
        if (Buffer)
        {
            TType = (PTOKEN_TYPE)Buffer;
            ok((*TType == TokenPrimary || *TType == TokenImpersonation), "TokenType in not a primary nor impersonation. FAILED\n");
            ExFreePool(TType);
        }
    }

    //----------------------------------------------------------------//

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenUser, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenUser fails\n");
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenUser arg. But Buffer = NULL\n");
        if (Buffer)
        {
            TUser = (PTOKEN_USER)Buffer;
            ok(RtlValidSid(TUser->User.Sid), "TokenUser has an invalid Sid\n");
            ExFreePool(TUser);
        }
    }

    //----------------------------------------------------------------//

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenSandBoxInert, &Buffer);
    ok(Status != STATUS_SUCCESS, "SQIT must fail with wrong TOKEN_INFORMATION_CLASS arg\n");
}
Example #4
0
FLT_POSTOP_CALLBACK_STATUS
claimsmanPostOperation(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_opt_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
)
/*++

Routine Description:

This routine is the post-operation completion routine for this
miniFilter.

This is non-pageable because it may be called at DPC level.

Arguments:

Data - Pointer to the filter callbackData that is passed to us.

FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
opaque handles to this filter, instance, its associated volume and
file object.

CompletionContext - The completion context set in the pre-operation routine.

Flags - Denotes whether the completion is successful or is being drained.

Return Value:

The return value is the status of the operation.

--*/
{
	UNREFERENCED_PARAMETER(Data);
	UNREFERENCED_PARAMETER(CompletionContext);
	UNREFERENCED_PARAMETER(Flags);
	NTSTATUS status;
	PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
	PUNICODE_STRING fileName = NULL;
	PTOKEN_USER pTokenUser = NULL;
	UNICODE_STRING sidString;
	
	LARGE_INTEGER Timeout;
	Timeout.QuadPart = (LONGLONG)1 * 10 * 1000 * 1000;
	
	// If there is no client registered, bail out immediately!
	// If the event is from kernel, bail out immediately!
	// If the event check for existence of file, bail out immediately!
	if (
		(ClaimsmanData.ClientPort == NULL) || 
		(Data->RequestorMode == KernelMode) ||
		(Data->IoStatus.Information == FILE_DOES_NOT_EXIST) ||
		(Data->IoStatus.Information == FILE_EXISTS)
		) {
		return FLT_POSTOP_FINISHED_PROCESSING;
	}

	//  We got a log record, if there is a file object, get its name.

	if (FltObjects->FileObject != NULL) {
		status = FltGetFileNameInformation(Data,
			FLT_FILE_NAME_NORMALIZED |
			FLT_FILE_NAME_QUERY_DEFAULT,
			&nameInfo);
	}
	else {
		//  Can't get a name when there's no file object
		status = STATUS_UNSUCCESSFUL;
	}

	if (NT_SUCCESS(status)) {
		FltParseFileNameInformation(nameInfo);
		fileName = &nameInfo->Name;
		// Produces way too much logging
		//PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
		//	("claimsman!claimsmanPostOperation: fileName=%wZ\n", fileName));
	}
	else
	{
		// No point continuing because we obviously did not get a filename anyways
		return FLT_POSTOP_FINISHED_PROCESSING;
	}

	//The only IRP you can trust for user information is IRP_MJ_CREATE. Things 
	//like write can be in arbitrary thread context, and even if the call works
	//you can get the wrong SID.

	status = SeQueryInformationToken(SeQuerySubjectContextToken(&(Data->Iopb->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext)), TokenUser, &pTokenUser);
	if (STATUS_SUCCESS == status && RtlValidSid(pTokenUser->User.Sid))
	{
		// Interesting extension?
		if (ClaimsmanCheckExtension(&nameInfo->Extension)) {
			CLAIMSMAN_MESSAGE msg;

			status = RtlConvertSidToUnicodeString(&sidString, pTokenUser->User.Sid, TRUE);

			if (NT_SUCCESS(status)) {
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: SID=%wZ\n", &sidString));
			}
			else {
				// No point continuing because we obviously did not get a valid SID
				FltReleaseFileNameInformation(nameInfo);
				ExFreePool(pTokenUser);
				return FLT_POSTOP_FINISHED_PROCESSING;
			}

			if (ClaimsmanCheckUserIgnore(&sidString)) {
				// Ignored user! Bail out!
				FltReleaseFileNameInformation(nameInfo);
				ExFreePool(pTokenUser);
				RtlFreeUnicodeString(&sidString);
				return FLT_POSTOP_FINISHED_PROCESSING;
			}

			LONGLONG size;
			LONGLONG modified;
			getSizeModified(FltObjects->Instance, fileName, &size, &modified);

			InitializeMessage(&msg, &sidString, fileName, FltObjects->FileObject->ReadAccess, FltObjects->FileObject->WriteAccess, FltObjects->FileObject->DeleteAccess, size, modified, Data->IoStatus.Status);

			// Ready, send the message!
			// But only if there's a client connected
			if (ClaimsmanData.ClientPort != NULL) {

				FltSendMessage(ClaimsmanData.Filter,
					&ClaimsmanData.ClientPort,
					&msg,
					sizeof(msg),
					NULL,
					0,
					&Timeout
					);
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: sent message=%d\n", status));
			}
			else {
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: no client connected!"));
			}
			RtlFreeUnicodeString(&sidString);
		}
	}

	FltReleaseFileNameInformation(nameInfo);
	if (pTokenUser != NULL) {
		ExFreePool(pTokenUser);
	}
	return FLT_POSTOP_FINISHED_PROCESSING;
}