aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Util/ca/scauser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/Util/ca/scauser.cpp')
-rw-r--r--src/ext/Util/ca/scauser.cpp62
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
5LPCWSTR vcsUserQuery = L"SELECT `User`, `Component_`, `Name`, `Domain`, `Password` FROM `Wix4User` WHERE `User`=?"; 5LPCWSTR vcsUserQuery = L"SELECT `User`, `Component_`, `Name`, `Domain`, `Comment`, `Password` FROM `Wix4User` WHERE `User`=?";
6enum eUserQuery { vuqUser = 1, vuqComponent, vuqName, vuqDomain, vuqPassword }; 6enum eUserQuery { vuqUser = 1, vuqComponent, vuqName, vuqDomain, vuqComment, vuqPassword };
7 7
8LPCWSTR vcsGroupQuery = L"SELECT `Group`, `Component_`, `Name`, `Domain` FROM `Wix4Group` WHERE `Group`=?"; 8LPCWSTR vcsGroupQuery = L"SELECT `Group`, `Component_`, `Name`, `Domain` FROM `Wix4Group` WHERE `Group`=?";
9enum eGroupQuery { vgqGroup = 1, vgqComponent, vgqName, vgqDomain }; 9enum eGroupQuery { vgqGroup = 1, vgqComponent, vgqName, vgqDomain };
@@ -11,8 +11,8 @@ enum eGroupQuery { vgqGroup = 1, vgqComponent, vgqName, vgqDomain };
11LPCWSTR vcsUserGroupQuery = L"SELECT `User_`, `Group_` FROM `Wix4UserGroup` WHERE `User_`=?"; 11LPCWSTR vcsUserGroupQuery = L"SELECT `User_`, `Group_` FROM `Wix4UserGroup` WHERE `User_`=?";
12enum eUserGroupQuery { vugqUser = 1, vugqGroup }; 12enum eUserGroupQuery { vugqUser = 1, vugqGroup };
13 13
14LPCWSTR vActionableQuery = L"SELECT `User`,`Component_`,`Name`,`Domain`,`Password`,`Attributes` FROM `Wix4User` WHERE `Component_` IS NOT NULL"; 14LPCWSTR vActionableQuery = L"SELECT `User`,`Component_`,`Name`,`Domain`,`Password`,`Comment`,`Attributes` FROM `Wix4User` WHERE `Component_` IS NOT NULL";
15enum eActionableQuery { vaqUser = 1, vaqComponent, vaqName, vaqDomain, vaqPassword, vaqAttributes }; 15enum eActionableQuery { vaqUser = 1, vaqComponent, vaqName, vaqDomain, vaqPassword, vaqComment, vaqAttributes };
16 16
17 17
18static HRESULT AddUserToList( 18static 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);