blob: 53bb06dc0fe5919aa0fb46ba052bdd46a9f9721d [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/windows_services/service_program/test_support/scoped_medium_integrity.h"
#include <windows.h>
#include <optional>
#include <ostream>
#include "base/logging.h"
#include "base/win/access_token.h"
#include "testing/gtest/include/gtest/gtest.h"
ScopedMediumIntegrity::ScopedMediumIntegrity() {
// Ensure that GoogleTest has created at least one ThreadLocal on this thread
// before impersonating. Otherwise, a failure in the test could lead to an
// assertion failure when GoogleTest tries to get a handle to the current
// thread.
{ SCOPED_TRACE(""); }
if (auto process_token = base::win::AccessToken::FromCurrentProcess(
/*impersonation=*/false, TOKEN_DUPLICATE);
!process_token.has_value()) {
PLOG(ERROR) << "Failed to duplicate process token";
} else if (auto lua_token = process_token->CreateRestricted(
LUA_TOKEN, /*sids_to_disable=*/{},
/*privileges_to_delete=*/{},
/*sids_to_restrict=*/{}, TOKEN_ALL_ACCESS);
!lua_token.has_value()) {
PLOG(ERROR) << "Failed to create LUA token";
} else if (!lua_token->SetIntegrityLevel(SECURITY_MANDATORY_MEDIUM_RID)) {
PLOG(ERROR) << "Failed to set integrity level on UIA token";
} else if (auto imp_token = lua_token->DuplicateImpersonation(
base::win::SecurityImpersonationLevel::kImpersonation,
TOKEN_ALL_ACCESS);
!imp_token.has_value()) {
PLOG(ERROR) << "Failed to create impersonation token";
} else if (!::ImpersonateLoggedOnUser(imp_token->get())) {
PLOG(ERROR) << "Failed to impersonate";
} else {
impersonating_ = true;
}
}
ScopedMediumIntegrity::~ScopedMediumIntegrity() {
if (impersonating_ && !::RevertToSelf()) {
PLOG(ERROR) << "Failed to revert to self";
}
}