diff options
Diffstat (limited to 'src/ext/Util/ca/scauser.cpp')
-rw-r--r-- | src/ext/Util/ca/scauser.cpp | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/src/ext/Util/ca/scauser.cpp b/src/ext/Util/ca/scauser.cpp index f92ebf1b..dc5bebba 100644 --- a/src/ext/Util/ca/scauser.cpp +++ b/src/ext/Util/ca/scauser.cpp | |||
@@ -2,8 +2,8 @@ | |||
2 | 2 | ||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | ||
5 | LPCWSTR vcsUserQuery = L"SELECT `User`, `Component_`, `Name`, `Domain`, `Password` FROM `Wix4User` WHERE `User`=?"; | 5 | LPCWSTR vcsUserQuery = L"SELECT `User`, `Component_`, `Name`, `Domain`, `Comment`, `Password` FROM `Wix4User` WHERE `User`=?"; |
6 | enum eUserQuery { vuqUser = 1, vuqComponent, vuqName, vuqDomain, vuqPassword }; | 6 | enum eUserQuery { vuqUser = 1, vuqComponent, vuqName, vuqDomain, vuqComment, vuqPassword }; |
7 | 7 | ||
8 | LPCWSTR vcsGroupQuery = L"SELECT `Group`, `Component_`, `Name`, `Domain` FROM `Wix4Group` WHERE `Group`=?"; | 8 | LPCWSTR vcsGroupQuery = L"SELECT `Group`, `Component_`, `Name`, `Domain` FROM `Wix4Group` WHERE `Group`=?"; |
9 | enum eGroupQuery { vgqGroup = 1, vgqComponent, vgqName, vgqDomain }; | 9 | enum eGroupQuery { vgqGroup = 1, vgqComponent, vgqName, vgqDomain }; |
@@ -11,8 +11,8 @@ enum eGroupQuery { vgqGroup = 1, vgqComponent, vgqName, vgqDomain }; | |||
11 | LPCWSTR vcsUserGroupQuery = L"SELECT `User_`, `Group_` FROM `Wix4UserGroup` WHERE `User_`=?"; | 11 | LPCWSTR vcsUserGroupQuery = L"SELECT `User_`, `Group_` FROM `Wix4UserGroup` WHERE `User_`=?"; |
12 | enum eUserGroupQuery { vugqUser = 1, vugqGroup }; | 12 | enum eUserGroupQuery { vugqUser = 1, vugqGroup }; |
13 | 13 | ||
14 | LPCWSTR vActionableQuery = L"SELECT `User`,`Component_`,`Name`,`Domain`,`Password`,`Attributes` FROM `Wix4User` WHERE `Component_` IS NOT NULL"; | 14 | LPCWSTR vActionableQuery = L"SELECT `User`,`Component_`,`Name`,`Domain`,`Password`,`Comment`,`Attributes` FROM `Wix4User` WHERE `Component_` IS NOT NULL"; |
15 | enum eActionableQuery { vaqUser = 1, vaqComponent, vaqName, vaqDomain, vaqPassword, vaqAttributes }; | 15 | enum eActionableQuery { vaqUser = 1, vaqComponent, vaqName, vaqDomain, vaqPassword, vaqComment, vaqAttributes }; |
16 | 16 | ||
17 | 17 | ||
18 | static HRESULT AddUserToList( | 18 | static HRESULT AddUserToList( |
@@ -78,6 +78,11 @@ HRESULT __stdcall ScaGetUser( | |||
78 | hr = ::StringCchCopyW(pscau->wzDomain, countof(pscau->wzDomain), pwzData); | 78 | hr = ::StringCchCopyW(pscau->wzDomain, countof(pscau->wzDomain), pwzData); |
79 | ExitOnFailure(hr, "Failed to copy domain string to user object"); | 79 | ExitOnFailure(hr, "Failed to copy domain string to user object"); |
80 | 80 | ||
81 | hr = WcaGetRecordFormattedString(hRec, vuqComment, &pwzData); | ||
82 | ExitOnFailure(hr, "Failed to get Wix4User.Comment"); | ||
83 | hr = ::StringCchCopyW(pscau->wzComment, countof(pscau->wzComment), pwzData); | ||
84 | ExitOnFailure(hr, "Failed to copy comment string to user object"); | ||
85 | |||
81 | hr = WcaGetRecordFormattedString(hRec, vuqPassword, &pwzData); | 86 | hr = WcaGetRecordFormattedString(hRec, vuqPassword, &pwzData); |
82 | ExitOnFailure(hr, "Failed to get Wix4User.Password"); | 87 | ExitOnFailure(hr, "Failed to get Wix4User.Password"); |
83 | hr = ::StringCchCopyW(pscau->wzPassword, countof(pscau->wzPassword), pwzData); | 88 | hr = ::StringCchCopyW(pscau->wzPassword, countof(pscau->wzPassword), pwzData); |
@@ -154,6 +159,11 @@ HRESULT __stdcall ScaGetUserDeferred( | |||
154 | hr = ::StringCchCopyW(pscau->wzDomain, countof(pscau->wzDomain), pwzData); | 159 | hr = ::StringCchCopyW(pscau->wzDomain, countof(pscau->wzDomain), pwzData); |
155 | ExitOnFailure(hr, "Failed to copy domain string to user object (in deferred CA)"); | 160 | ExitOnFailure(hr, "Failed to copy domain string to user object (in deferred CA)"); |
156 | 161 | ||
162 | hr = WcaGetRecordString(hRec, vuqComment, &pwzData); | ||
163 | ExitOnFailure(hr, "Failed to get Wix4User.Comment"); | ||
164 | hr = ::StringCchCopyW(pscau->wzComment, countof(pscau->wzComment), pwzData); | ||
165 | ExitOnFailure(hr, "Failed to copy comment string to user object (in deferred CA)"); | ||
166 | |||
157 | hr = WcaGetRecordString(hRec, vuqPassword, &pwzData); | 167 | hr = WcaGetRecordString(hRec, vuqPassword, &pwzData); |
158 | ExitOnFailure(hr, "Failed to get Wix4User.Password"); | 168 | ExitOnFailure(hr, "Failed to get Wix4User.Password"); |
159 | hr = ::StringCchCopyW(pscau->wzPassword, countof(pscau->wzPassword), pwzData); | 169 | hr = ::StringCchCopyW(pscau->wzPassword, countof(pscau->wzPassword), pwzData); |
@@ -316,7 +326,7 @@ HRESULT ScaUserRead( | |||
316 | ExitOnFailure(hr, "failed to get Component state for Wix4User"); | 326 | ExitOnFailure(hr, "failed to get Component state for Wix4User"); |
317 | 327 | ||
318 | // don't bother if we aren't installing or uninstalling this component | 328 | // don't bother if we aren't installing or uninstalling this component |
319 | if (WcaIsInstalling(isInstalled, isAction) || WcaIsUninstalling(isInstalled, isAction)) | 329 | if (WcaIsInstalling(isInstalled, isAction) || WcaIsUninstalling(isInstalled, isAction)) |
320 | { | 330 | { |
321 | // | 331 | // |
322 | // Add the user to the list and populate it's values | 332 | // Add the user to the list and populate it's values |
@@ -345,6 +355,10 @@ HRESULT ScaUserRead( | |||
345 | ExitOnFailure(hr, "failed to get Wix4User.Domain"); | 355 | ExitOnFailure(hr, "failed to get Wix4User.Domain"); |
346 | hr = ::StringCchCopyW(psu->wzDomain, countof(psu->wzDomain), pwzData); | 356 | hr = ::StringCchCopyW(psu->wzDomain, countof(psu->wzDomain), pwzData); |
347 | ExitOnFailure(hr, "failed to copy user domain: %ls", pwzData); | 357 | ExitOnFailure(hr, "failed to copy user domain: %ls", pwzData); |
358 | hr = WcaGetRecordFormattedString(hRec, vaqComment, &pwzData); | ||
359 | ExitOnFailure(hr, "failed to get Wix4User.Comment"); | ||
360 | hr = ::StringCchCopyW(psu->wzComment, countof(psu->wzComment), pwzData); | ||
361 | ExitOnFailure(hr, "failed to copy user comment: %ls", pwzData); | ||
348 | 362 | ||
349 | hr = WcaGetRecordFormattedString(hRec, vaqPassword, &pwzData); | 363 | hr = WcaGetRecordFormattedString(hRec, vaqPassword, &pwzData); |
350 | ExitOnFailure(hr, "failed to get Wix4User.Password"); | 364 | ExitOnFailure(hr, "failed to get Wix4User.Password"); |
@@ -492,15 +506,16 @@ HRESULT ScaUserExecute( | |||
492 | { | 506 | { |
493 | USER_EXISTS ueUserExists = USER_EXISTS_INDETERMINATE; | 507 | USER_EXISTS ueUserExists = USER_EXISTS_INDETERMINATE; |
494 | 508 | ||
495 | // Always put the User Name and Domain plus Attributes on the front of the CustomAction | 509 | // Always put the User Name, Domain, and Comment on the front of the CustomAction data. |
496 | // data. Sometimes we'll add more data. | 510 | // The attributes will be added when we have finished adjusting them. Sometimes we'll |
511 | // add more data. | ||
497 | Assert(psu->wzName); | 512 | Assert(psu->wzName); |
498 | hr = WcaWriteStringToCaData(psu->wzName, &pwzActionData); | 513 | hr = WcaWriteStringToCaData(psu->wzName, &pwzActionData); |
499 | ExitOnFailure(hr, "Failed to add user name to custom action data: %ls", psu->wzName); | 514 | ExitOnFailure(hr, "Failed to add user name to custom action data: %ls", psu->wzName); |
500 | hr = WcaWriteStringToCaData(psu->wzDomain, &pwzActionData); | 515 | hr = WcaWriteStringToCaData(psu->wzDomain, &pwzActionData); |
501 | ExitOnFailure(hr, "Failed to add user domain to custom action data: %ls", psu->wzDomain); | 516 | ExitOnFailure(hr, "Failed to add user domain to custom action data: %ls", psu->wzDomain); |
502 | hr = WcaWriteIntegerToCaData(psu->iAttributes, &pwzActionData); | 517 | hr = WcaWriteStringToCaData(psu->wzComment, &pwzActionData); |
503 | ExitOnFailure(hr, "failed to add user attributes to custom action data for user: %ls", psu->wzKey); | 518 | ExitOnFailure(hr, "Failed to add user comment to custom action data: %ls", psu->wzComment); |
504 | 519 | ||
505 | // Check to see if the user already exists since we have to be very careful when adding | 520 | // Check to see if the user already exists since we have to be very careful when adding |
506 | // and removing users. Note: MSDN says that it is safe to call these APIs from any | 521 | // and removing users. Note: MSDN says that it is safe to call these APIs from any |
@@ -520,7 +535,12 @@ HRESULT ScaUserExecute( | |||
520 | } | 535 | } |
521 | if (ERROR_SUCCESS == er) | 536 | if (ERROR_SUCCESS == er) |
522 | { | 537 | { |
523 | wzDomain = pDomainControllerInfo->DomainControllerName + 2; //Add 2 so that we don't get the \\ prefix | 538 | if (2 <= wcslen(pDomainControllerInfo->DomainControllerName)) |
539 | { | ||
540 | wzDomain = pDomainControllerInfo->DomainControllerName + 2; // Add 2 so that we don't get the \\ prefix. | ||
541 | // Pass the entire string if it is too short | ||
542 | // to have a \\ prefix. | ||
543 | } | ||
524 | } | 544 | } |
525 | } | 545 | } |
526 | 546 | ||
@@ -544,23 +564,32 @@ HRESULT ScaUserExecute( | |||
544 | 564 | ||
545 | if (WcaIsInstalling(psu->isInstalled, psu->isAction)) | 565 | if (WcaIsInstalling(psu->isInstalled, psu->isAction)) |
546 | { | 566 | { |
547 | // If the user exists, check to see if we are supposed to fail if user the exists before | 567 | // If the user exists, check to see if we are supposed to fail if the user exists before |
548 | // the install. | 568 | // the install. |
549 | if (USER_EXISTS_YES == ueUserExists) | 569 | if (USER_EXISTS_YES == ueUserExists) |
550 | { | 570 | { |
551 | // Reinstalls will always fail if we don't remove the check for "fail if exists". | 571 | // Re-installs will always fail if we don't remove the check for "fail if exists". |
552 | if (WcaIsReInstalling(psu->isInstalled, psu->isAction)) | 572 | if (WcaIsReInstalling(psu->isInstalled, psu->isAction)) |
553 | { | 573 | { |
554 | psu->iAttributes &= ~SCAU_FAIL_IF_EXISTS; | 574 | psu->iAttributes &= ~SCAU_FAIL_IF_EXISTS; |
575 | |||
576 | // If install would create the user, re-install should be able to update the user. | ||
577 | if (!(psu->iAttributes & SCAU_DONT_CREATE_USER)) | ||
578 | { | ||
579 | psu->iAttributes |= SCAU_UPDATE_IF_EXISTS; | ||
580 | } | ||
555 | } | 581 | } |
556 | 582 | ||
557 | if ((SCAU_FAIL_IF_EXISTS & (psu->iAttributes)) && !(SCAU_UPDATE_IF_EXISTS & (psu->iAttributes))) | 583 | if (SCAU_FAIL_IF_EXISTS & psu->iAttributes && !(SCAU_UPDATE_IF_EXISTS & psu->iAttributes)) |
558 | { | 584 | { |
559 | hr = HRESULT_FROM_WIN32(NERR_UserExists); | 585 | hr = HRESULT_FROM_WIN32(NERR_UserExists); |
560 | MessageExitOnFailure(hr, msierrUSRFailedUserCreateExists, "Failed to create user: %ls because user already exists.", psu->wzName); | 586 | MessageExitOnFailure(hr, msierrUSRFailedUserCreateExists, "Failed to create user: %ls because user already exists.", psu->wzName); |
561 | } | 587 | } |
562 | } | 588 | } |
563 | 589 | ||
590 | hr = WcaWriteIntegerToCaData(psu->iAttributes, &pwzActionData); | ||
591 | ExitOnFailure(hr, "failed to add user attributes to custom action data for user: %ls", psu->wzKey); | ||
592 | |||
564 | // Rollback only if the user already exists, we couldn't determine if the user exists, or we are going to create the user | 593 | // Rollback only if the user already exists, we couldn't determine if the user exists, or we are going to create the user |
565 | if ((USER_EXISTS_YES == ueUserExists) || (USER_EXISTS_INDETERMINATE == ueUserExists) || !(psu->iAttributes & SCAU_DONT_CREATE_USER)) | 594 | if ((USER_EXISTS_YES == ueUserExists) || (USER_EXISTS_INDETERMINATE == ueUserExists) || !(psu->iAttributes & SCAU_DONT_CREATE_USER)) |
566 | { | 595 | { |
@@ -597,7 +626,6 @@ HRESULT ScaUserExecute( | |||
597 | ExitOnFailure(hr, "Failed to add user domain to rollback custom action data: %ls", psu->wzDomain); | 626 | ExitOnFailure(hr, "Failed to add user domain to rollback custom action data: %ls", psu->wzDomain); |
598 | hr = WcaWriteIntegerToCaData(iRollbackUserAttributes, &pwzRollbackData); | 627 | hr = WcaWriteIntegerToCaData(iRollbackUserAttributes, &pwzRollbackData); |
599 | ExitOnFailure(hr, "failed to add user attributes to rollback custom action data for user: %ls", psu->wzKey); | 628 | ExitOnFailure(hr, "failed to add user attributes to rollback custom action data for user: %ls", psu->wzKey); |
600 | |||
601 | // If the user already exists, add relevant group information to rollback data | 629 | // If the user already exists, add relevant group information to rollback data |
602 | if (USER_EXISTS_YES == ueUserExists || USER_EXISTS_INDETERMINATE == ueUserExists) | 630 | if (USER_EXISTS_YES == ueUserExists || USER_EXISTS_INDETERMINATE == ueUserExists) |
603 | { | 631 | { |
@@ -630,11 +658,13 @@ HRESULT ScaUserExecute( | |||
630 | } | 658 | } |
631 | else if (((USER_EXISTS_YES == ueUserExists) || (USER_EXISTS_INDETERMINATE == ueUserExists)) && WcaIsUninstalling(psu->isInstalled, psu->isAction) && !(psu->iAttributes & SCAU_DONT_REMOVE_ON_UNINSTALL)) | 659 | else if (((USER_EXISTS_YES == ueUserExists) || (USER_EXISTS_INDETERMINATE == ueUserExists)) && WcaIsUninstalling(psu->isInstalled, psu->isAction) && !(psu->iAttributes & SCAU_DONT_REMOVE_ON_UNINSTALL)) |
632 | { | 660 | { |
661 | hr = WcaWriteIntegerToCaData(psu->iAttributes, &pwzActionData); | ||
662 | ExitOnFailure(hr, "failed to add user attributes to custom action data for user: %ls", psu->wzKey); | ||
663 | |||
633 | // Add user's group information - this will ensure the user can be removed from any groups they were added to, if the user isn't be deleted | 664 | // Add user's group information - this will ensure the user can be removed from any groups they were added to, if the user isn't be deleted |
634 | hr = WriteGroupInfo(psu->psgGroups, &pwzActionData); | 665 | hr = WriteGroupInfo(psu->psgGroups, &pwzActionData); |
635 | ExitOnFailure(hr, "failed to add group information to custom action data"); | 666 | ExitOnFailure(hr, "failed to add group information to custom action data"); |
636 | 667 | ||
637 | // | ||
638 | // Schedule the removal because the user exists and we don't have any flags set | 668 | // Schedule the removal because the user exists and we don't have any flags set |
639 | // that say, don't remove the user on uninstall. | 669 | // that say, don't remove the user on uninstall. |
640 | // | 670 | // |
@@ -642,7 +672,7 @@ HRESULT ScaUserExecute( | |||
642 | // CustomAction. | 672 | // CustomAction. |
643 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RemoveUser"), pwzActionData, COST_USER_DELETE); | 673 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RemoveUser"), pwzActionData, COST_USER_DELETE); |
644 | ExitOnFailure(hr, "failed to schedule RemoveUser"); | 674 | ExitOnFailure(hr, "failed to schedule RemoveUser"); |
645 | } | 675 | } |
646 | 676 | ||
647 | ReleaseNullStr(pwzScriptKey); | 677 | ReleaseNullStr(pwzScriptKey); |
648 | ReleaseNullStr(pwzActionData); | 678 | ReleaseNullStr(pwzActionData); |