aboutsummaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/acl2util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/acl2util.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/acl2util.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/acl2util.cpp b/src/libs/dutil/WixToolset.DUtil/acl2util.cpp
new file mode 100644
index 00000000..598f12e7
--- /dev/null
+++ b/src/libs/dutil/WixToolset.DUtil/acl2util.cpp
@@ -0,0 +1,135 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5// Exit macros
6#define AclExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_ACLUTIL, x, s, __VA_ARGS__)
7#define AclExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_ACLUTIL, x, s, __VA_ARGS__)
8#define AclExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_ACLUTIL, x, s, __VA_ARGS__)
9#define AclExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_ACLUTIL, x, s, __VA_ARGS__)
10#define AclExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_ACLUTIL, x, s, __VA_ARGS__)
11#define AclExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_ACLUTIL, x, s, __VA_ARGS__)
12#define AclExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_ACLUTIL, p, x, e, s, __VA_ARGS__)
13#define AclExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_ACLUTIL, p, x, s, __VA_ARGS__)
14#define AclExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_ACLUTIL, p, x, e, s, __VA_ARGS__)
15#define AclExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_ACLUTIL, p, x, s, __VA_ARGS__)
16#define AclExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_ACLUTIL, e, x, s, __VA_ARGS__)
17#define AclExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_ACLUTIL, g, x, s, __VA_ARGS__)
18
19/********************************************************************
20AclCalculateServiceSidString - gets the SID string for the given service name
21
22NOTE: psczSid should be freed with StrFree()
23********************************************************************/
24extern "C" HRESULT DAPI AclCalculateServiceSidString(
25 __in LPCWSTR wzServiceName,
26 __in SIZE_T cchServiceName,
27 __deref_out_z LPWSTR* psczSid
28 )
29{
30 // TODO: use undocumented RtlCreateServiceSid function?
31 // http://blogs.technet.com/b/voy/archive/2007/03/22/per-service-sid.aspx
32 // Assume little endian.
33 HRESULT hr = S_OK;
34 LPWSTR sczUpperServiceName = NULL;
35 DWORD cbHash = SHA1_HASH_LEN;
36 BYTE* pbHash = NULL;
37
38 Assert(psczSid);
39
40 if (0 == cchServiceName)
41 {
42 hr = ::StringCchLengthW(wzServiceName, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchServiceName));
43 AclExitOnFailure(hr, "Failed to get the length of the service name.");
44 }
45
46 hr = StrAllocStringToUpperInvariant(&sczUpperServiceName, wzServiceName, cchServiceName);
47 AclExitOnFailure(hr, "Failed to upper case the service name.");
48
49 pbHash = reinterpret_cast<BYTE*>(MemAlloc(cbHash, TRUE));
50 AclExitOnNull(pbHash, hr, E_OUTOFMEMORY, "Failed to allocate hash byte array.");
51
52 hr = CrypHashBuffer(reinterpret_cast<BYTE*>(sczUpperServiceName), cchServiceName * sizeof(WCHAR), PROV_RSA_FULL, CALG_SHA1, pbHash, cbHash);
53 AclExitOnNull(pbHash, hr, E_OUTOFMEMORY, "Failed to hash the service name.");
54
55 hr = StrAllocFormatted(psczSid, L"S-1-5-80-%u-%u-%u-%u-%u",
56 MAKEDWORD(MAKEWORD(pbHash[0], pbHash[1]), MAKEWORD(pbHash[2], pbHash[3])),
57 MAKEDWORD(MAKEWORD(pbHash[4], pbHash[5]), MAKEWORD(pbHash[6], pbHash[7])),
58 MAKEDWORD(MAKEWORD(pbHash[8], pbHash[9]), MAKEWORD(pbHash[10], pbHash[11])),
59 MAKEDWORD(MAKEWORD(pbHash[12], pbHash[13]), MAKEWORD(pbHash[14], pbHash[15])),
60 MAKEDWORD(MAKEWORD(pbHash[16], pbHash[17]), MAKEWORD(pbHash[18], pbHash[19])));
61
62LExit:
63 ReleaseMem(pbHash);
64 ReleaseStr(sczUpperServiceName);
65
66 return hr;
67}
68
69
70/********************************************************************
71AclGetAccountSidStringEx - gets a string version of the account's SID
72 calculates a service's SID if lookup fails
73
74NOTE: psczSid should be freed with StrFree()
75********************************************************************/
76extern "C" HRESULT DAPI AclGetAccountSidStringEx(
77 __in_z LPCWSTR wzSystem,
78 __in_z LPCWSTR wzAccount,
79 __deref_out_z LPWSTR* psczSid
80 )
81{
82 HRESULT hr = S_OK;
83 SIZE_T cchAccount = 0;
84 PSID psid = NULL;
85 LPWSTR pwz = NULL;
86 LPWSTR sczSid = NULL;
87
88 Assert(psczSid);
89
90 hr = AclGetAccountSid(wzSystem, wzAccount, &psid);
91 if (SUCCEEDED(hr))
92 {
93 Assert(::IsValidSid(psid));
94
95 if (!::ConvertSidToStringSidW(psid, &pwz))
96 {
97 AclExitWithLastError(hr, "Failed to convert SID to string for Account: %ls", wzAccount);
98 }
99
100 hr = StrAllocString(psczSid, pwz, 0);
101 }
102 else
103 {
104 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr)
105 {
106 HRESULT hrLength = ::StringCchLengthW(wzAccount, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchAccount));
107 AclExitOnFailure(hrLength, "Failed to get the length of the account name.");
108
109 if (11 < cchAccount && CSTR_EQUAL == CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, L"NT SERVICE\\", 11, wzAccount, 11))
110 {
111 // If the service is not installed then LookupAccountName doesn't resolve the SID, but we can calculate it.
112 LPCWSTR wzServiceName = &wzAccount[11];
113 hr = AclCalculateServiceSidString(wzServiceName, cchAccount - 11, &sczSid);
114 AclExitOnFailure(hr, "Failed to calculate the service SID for %ls", wzServiceName);
115
116 *psczSid = sczSid;
117 sczSid = NULL;
118 }
119 }
120 AclExitOnFailure(hr, "Failed to get SID for account: %ls", wzAccount);
121 }
122
123LExit:
124 ReleaseStr(sczSid);
125 if (pwz)
126 {
127 ::LocalFree(pwz);
128 }
129 if (psid)
130 {
131 AclFreeSid(psid);
132 }
133
134 return hr;
135}