-
Notifications
You must be signed in to change notification settings - Fork 247
/
base_security.h
99 lines (80 loc) · 2.76 KB
/
base_security.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
WINRT_EXPORT namespace winrt
{
struct access_token : handle
{
static access_token process()
{
access_token token;
check_bool(WINRT_IMPL_OpenProcessToken(WINRT_IMPL_GetCurrentProcess(), 0x0002 /*TOKEN_DUPLICATE*/, token.put()));
access_token duplicate;
check_bool(WINRT_IMPL_DuplicateToken(token.get(), 2 /*SecurityImpersonation*/, duplicate.put()));
return duplicate;
}
static access_token thread()
{
access_token token;
if (!WINRT_IMPL_OpenThreadToken(WINRT_IMPL_GetCurrentThread(), 0x0004 /*TOKEN_IMPERSONATE*/, 1, token.put()))
{
uint32_t const error = WINRT_IMPL_GetLastError();
if (error != 1008 /*ERROR_NO_TOKEN*/)
{
throw_hresult(impl::hresult_from_win32(error));
}
}
return token;
}
static access_token client()
{
struct impersonate_guard
{
impersonate_guard(com_ptr<impl::IServerSecurity> const& server) : m_server(server)
{
check_hresult(m_server->ImpersonateClient());
}
~impersonate_guard()
{
check_hresult(m_server->RevertToSelf());
}
private:
com_ptr<impl::IServerSecurity> const& m_server;
};
auto server = capture<impl::IServerSecurity>(WINRT_IMPL_CoGetCallContext);
impersonate_guard impersonate(server);
return thread();
}
access_token() = default;
access_token(access_token&& other) = default;
access_token& operator=(access_token&& other) = default;
access_token impersonate() const
{
auto previous = thread();
check_bool(WINRT_IMPL_SetThreadToken(nullptr, get()));
return previous;
}
void revert() const
{
check_bool(WINRT_IMPL_SetThreadToken(nullptr, get()));
}
auto operator()() const
{
struct guard
{
guard(access_token&& previous) noexcept : m_previous(std::move(previous))
{
}
~guard()
{
m_previous.revert();
}
guard(guard const&)
{
// A Visual C++ compiler bug (550631) requires the copy constructor even though it is never called.
WINRT_ASSERT(false);
}
private:
access_token const m_previous;
};
return guard(impersonate());
}
};
}