aboutsummaryrefslogtreecommitdiff
path: root/src/ext/ComPlus/ca/cppartroleexec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/ComPlus/ca/cppartroleexec.cpp')
-rw-r--r--src/ext/ComPlus/ca/cppartroleexec.cpp397
1 files changed, 397 insertions, 0 deletions
diff --git a/src/ext/ComPlus/ca/cppartroleexec.cpp b/src/ext/ComPlus/ca/cppartroleexec.cpp
new file mode 100644
index 00000000..4a503c79
--- /dev/null
+++ b/src/ext/ComPlus/ca/cppartroleexec.cpp
@@ -0,0 +1,397 @@
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
6// private structs
7
8struct CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES
9{
10 int iActionType;
11 int iActionCost;
12 LPWSTR pwzKey;
13 LPWSTR pwzRoleName;
14 LPWSTR pwzAccount;
15 LPWSTR pwzPartID;
16};
17
18
19// prototypes for private helper functions
20
21static HRESULT ReadUserInPartitionRoleAttributes(
22 LPWSTR* ppwzData,
23 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
24 );
25static void FreeUserInPartitionRoleAttributes(
26 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
27 );
28static HRESULT CreateUserInPartitionRole(
29 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
30 );
31static HRESULT RemoveUserInPartitionRole(
32 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
33 );
34
35
36// function definitions
37
38HRESULT CpiConfigureUsersInPartitionRoles(
39 LPWSTR* ppwzData,
40 HANDLE hRollbackFile
41 )
42{
43 HRESULT hr = S_OK;
44
45 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES attrs;
46 ::ZeroMemory(&attrs, sizeof(attrs));
47
48 // read action text
49 hr = CpiActionStartMessage(ppwzData, FALSE);
50 ExitOnFailure(hr, "Failed to send action start message");
51
52 // ger count
53 int iCnt = 0;
54 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
55 ExitOnFailure(hr, "Failed to read count");
56
57 // write count to rollback file
58 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
59 ExitOnFailure(hr, "Failed to write count to rollback file");
60
61 for (int i = 0; i < iCnt; i++)
62 {
63 // read attributes from CustomActionData
64 hr = ReadUserInPartitionRoleAttributes(ppwzData, &attrs);
65 ExitOnFailure(hr, "Failed to read attributes");
66
67 // progress message
68 hr = CpiActionDataMessage(1, attrs.pwzRoleName);
69 ExitOnFailure(hr, "Failed to send progress messages");
70
71 if (S_FALSE == hr)
72 ExitFunction();
73
74 // write key to rollback file
75 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
76 ExitOnFailure(hr, "Failed to write key to rollback file");
77
78 // action
79 switch (attrs.iActionType)
80 {
81 case atCreate:
82 hr = CreateUserInPartitionRole(&attrs);
83 ExitOnFailure(hr, "Failed to add user to partition role, key: %S", attrs.pwzKey);
84 break;
85 case atRemove:
86 hr = RemoveUserInPartitionRole(&attrs);
87 ExitOnFailure(hr, "Failed to remove user from partition role, key: %S", attrs.pwzKey);
88 break;
89 }
90
91 // write completion status to rollback file
92 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
93 ExitOnFailure(hr, "Failed to write completion status to rollback file");
94
95 // progress
96 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
97 ExitOnFailure(hr, "Failed to update progress");
98 }
99
100 hr = S_OK;
101
102LExit:
103 // clean up
104 FreeUserInPartitionRoleAttributes(&attrs);
105
106 return hr;
107}
108
109HRESULT CpiRollbackConfigureUsersInPartitionRoles(
110 LPWSTR* ppwzData,
111 CPI_ROLLBACK_DATA* pRollbackDataList
112 )
113{
114 HRESULT hr = S_OK;
115
116 int iRollbackStatus;
117
118 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES attrs;
119 ::ZeroMemory(&attrs, sizeof(attrs));
120
121 // read action text
122 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
123 ExitOnFailure(hr, "Failed to send action start message");
124
125 // get count
126 int iCnt = 0;
127 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
128 ExitOnFailure(hr, "Failed to read count");
129
130 for (int i = 0; i < iCnt; i++)
131 {
132 // read attributes from CustomActionData
133 hr = ReadUserInPartitionRoleAttributes(ppwzData, &attrs);
134 ExitOnFailure(hr, "Failed to read attributes");
135
136 // rollback status
137 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
138
139 if (S_FALSE == hr)
140 continue; // not found, nothing to rollback
141
142 // progress message
143 hr = CpiActionDataMessage(1, attrs.pwzRoleName);
144 ExitOnFailure(hr, "Failed to send progress messages");
145
146 if (S_FALSE == hr)
147 ExitFunction();
148
149 // action
150 switch (attrs.iActionType)
151 {
152 case atCreate:
153 hr = CreateUserInPartitionRole(&attrs);
154 if (FAILED(hr))
155 WcaLog(LOGMSG_STANDARD, "Failed to add user to partition role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
156 break;
157 case atRemove:
158 hr = RemoveUserInPartitionRole(&attrs);
159 if (FAILED(hr))
160 WcaLog(LOGMSG_STANDARD, "Failed to remove user from partition role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
161 break;
162 }
163
164 // check rollback status
165 if (0 == iRollbackStatus)
166 continue; // operation did not complete, skip progress
167
168 // progress
169 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
170 ExitOnFailure(hr, "Failed to update progress");
171 }
172
173 hr = S_OK;
174
175LExit:
176 // clean up
177 FreeUserInPartitionRoleAttributes(&attrs);
178
179 return hr;
180}
181
182
183// helper function definitions
184
185static HRESULT ReadUserInPartitionRoleAttributes(
186 LPWSTR* ppwzData,
187 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
188 )
189{
190 HRESULT hr = S_OK;
191
192 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
193 ExitOnFailure(hr, "Failed to read action type");
194 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
195 ExitOnFailure(hr, "Failed to read action cost");
196 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
197 ExitOnFailure(hr, "Failed to read key");
198 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzRoleName);
199 ExitOnFailure(hr, "Failed to read role name");
200 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAccount);
201 ExitOnFailure(hr, "Failed to read account name");
202 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
203 ExitOnFailure(hr, "Failed to read partition id");
204
205 hr = S_OK;
206
207LExit:
208 return hr;
209}
210
211static void FreeUserInPartitionRoleAttributes(
212 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
213 )
214{
215 ReleaseStr(pAttrs->pwzKey);
216 ReleaseStr(pAttrs->pwzRoleName);
217 ReleaseStr(pAttrs->pwzAccount);
218 ReleaseStr(pAttrs->pwzPartID);
219}
220
221static HRESULT CreateUserInPartitionRole(
222 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
223 )
224{
225 HRESULT hr = S_OK;
226 UINT er = ERROR_SUCCESS;
227
228 ICatalogCollection* piUsrInRoleColl = NULL;
229 ICatalogObject* piUsrInRoleObj = NULL;
230
231 PSID pSid = NULL;
232 long lChanges = 0;
233
234 // log
235 WcaLog(LOGMSG_VERBOSE, "Adding user to partition role, key: %S", pAttrs->pwzKey);
236
237 // get users in partition role collection
238 hr = CpiGetUsersInPartitionRoleCollection(pAttrs->pwzPartID, pAttrs->pwzRoleName, &piUsrInRoleColl);
239 if (S_FALSE == hr)
240 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
241 ExitOnFailure(hr, "Failed to get users in partition role collection");
242
243 // get SID for account
244 do {
245 er = ERROR_SUCCESS;
246 hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
247 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
248 {
249 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
250 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
251 switch (er)
252 {
253 case IDABORT:
254 ExitFunction(); // exit with error code from CpiAccountNameToSid()
255 case IDRETRY:
256 break;
257 case IDIGNORE:
258 default:
259 ExitFunction1(hr = S_OK);
260 }
261 }
262 else
263 ExitOnFailure(hr, "Failed to get SID for account");
264 } while (IDRETRY == er);
265
266 // find any existing entry
267 hr = CpiFindUserCollectionObject(piUsrInRoleColl, pSid, NULL);
268 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
269 WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
270 else
271 ExitOnFailure(hr, "Failed to find user in partition role");
272
273 if (S_OK == hr)
274 {
275 WcaLog(LOGMSG_VERBOSE, "User already assigned to partition role, key: %S", pAttrs->pwzKey);
276 ExitFunction(); // exit with hr = S_OK
277 }
278
279 // convert SID back to account name
280 hr = CpiSidToAccountName(pSid, &pAttrs->pwzAccount);
281 ExitOnFailure(hr, "Failed to convert SID to account name");
282
283 // add user
284 hr = CpiAddCollectionObject(piUsrInRoleColl, &piUsrInRoleObj);
285 ExitOnFailure(hr, "Failed to add user in role to collection");
286
287 hr = CpiPutCollectionObjectValue(piUsrInRoleObj, L"User", pAttrs->pwzAccount);
288 ExitOnFailure(hr, "Failed to set role name property");
289
290 // save changes
291 hr = piUsrInRoleColl->SaveChanges(&lChanges);
292 if (COMADMIN_E_OBJECTERRORS == hr)
293 CpiLogCatalogErrorInfo();
294 ExitOnFailure(hr, "Failed to save changes");
295
296 // log
297 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
298
299 hr = S_OK;
300
301LExit:
302 // clean up
303 ReleaseObject(piUsrInRoleColl);
304 ReleaseObject(piUsrInRoleObj);
305
306 if (pSid)
307 ::HeapFree(::GetProcessHeap(), 0, pSid);
308
309 return hr;
310}
311
312static HRESULT RemoveUserInPartitionRole(
313 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
314 )
315{
316 HRESULT hr = S_OK;
317 UINT er = ERROR_SUCCESS;
318
319 ICatalogCollection* piUsrInRoleColl = NULL;
320
321 PSID pSid = NULL;
322 long lChanges = 0;
323
324 // log
325 WcaLog(LOGMSG_VERBOSE, "Removing user from partition role, key: %S", pAttrs->pwzKey);
326
327 // get users in partition role collection
328 hr = CpiGetUsersInPartitionRoleCollection(pAttrs->pwzPartID, pAttrs->pwzRoleName, &piUsrInRoleColl);
329 ExitOnFailure(hr, "Failed to get users in partition role collection");
330
331 if (S_FALSE == hr)
332 {
333 // users in role collection not found
334 WcaLog(LOGMSG_VERBOSE, "Unable to retrieve users in partition role collection, nothing to delete, key: %S", pAttrs->pwzKey);
335 ExitFunction1(hr = S_OK);
336 }
337
338 // get SID for account
339 do {
340 er = ERROR_SUCCESS;
341 hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
342 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
343 {
344 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
345 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
346 switch (er)
347 {
348 case IDABORT:
349 ExitFunction(); // exit with error code from CpiAccountNameToSid()
350 case IDRETRY:
351 break;
352 case IDIGNORE:
353 default:
354 ExitFunction1(hr = S_OK);
355 }
356 }
357 else
358 ExitOnFailure(hr, "Failed to get SID for account");
359 } while (IDRETRY == er);
360
361 // remove
362 hr = CpiRemoveUserCollectionObject(piUsrInRoleColl, pSid);
363 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
364 {
365 WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
366 hr = S_FALSE;
367 }
368 else
369 ExitOnFailure(hr, "Failed to remove user");
370
371 if (S_FALSE == hr)
372 {
373 // role not found
374 WcaLog(LOGMSG_VERBOSE, "User not found for partition role, nothing to delete, key: %S", pAttrs->pwzKey);
375 ExitFunction1(hr = S_OK);
376 }
377
378 // save changes
379 hr = piUsrInRoleColl->SaveChanges(&lChanges);
380 if (COMADMIN_E_OBJECTERRORS == hr)
381 CpiLogCatalogErrorInfo();
382 ExitOnFailure(hr, "Failed to save changes");
383
384 // log
385 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
386
387 hr = S_OK;
388
389LExit:
390 // clean up
391 ReleaseObject(piUsrInRoleColl);
392
393 if (pSid)
394 ::HeapFree(::GetProcessHeap(), 0, pSid);
395
396 return hr;
397}