diff options
| author | Rob Mensching <rob@firegiant.com> | 2021-05-03 09:55:22 -0700 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2021-05-03 09:55:22 -0700 |
| commit | ff659159e041bf6c083e6b7fcb9b726065a9dd73 (patch) | |
| tree | ea95bf3d3e031edcee65de33b9e6954178be669c /src/ext/Util/ca/scasmbsched.cpp | |
| parent | 8a8a25695351ee542f08886a9d0957c78c6af366 (diff) | |
| download | wix-ff659159e041bf6c083e6b7fcb9b726065a9dd73.tar.gz wix-ff659159e041bf6c083e6b7fcb9b726065a9dd73.tar.bz2 wix-ff659159e041bf6c083e6b7fcb9b726065a9dd73.zip | |
Move Util.wixext into ext
Diffstat (limited to 'src/ext/Util/ca/scasmbsched.cpp')
| -rw-r--r-- | src/ext/Util/ca/scasmbsched.cpp | 639 |
1 files changed, 639 insertions, 0 deletions
diff --git a/src/ext/Util/ca/scasmbsched.cpp b/src/ext/Util/ca/scasmbsched.cpp new file mode 100644 index 00000000..e29f7f51 --- /dev/null +++ b/src/ext/Util/ca/scasmbsched.cpp | |||
| @@ -0,0 +1,639 @@ | |||
| 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 | /******************************************************************** | ||
| 7 | Helper functions to maintain a list of file shares to create / remove | ||
| 8 | |||
| 9 | ********************************************************************/ | ||
| 10 | SCA_SMB* NewSmb() | ||
| 11 | { | ||
| 12 | SCA_SMB* pss = (SCA_SMB*)MemAlloc(sizeof(SCA_SMB), TRUE); | ||
| 13 | Assert(pss); | ||
| 14 | return pss; | ||
| 15 | } | ||
| 16 | |||
| 17 | |||
| 18 | SCA_SMB_EX_USER_PERMS* NewExUserPermsSmb() | ||
| 19 | { | ||
| 20 | SCA_SMB_EX_USER_PERMS* pExUserPerms = (SCA_SMB_EX_USER_PERMS*)MemAlloc(sizeof(SCA_SMB_EX_USER_PERMS), TRUE); | ||
| 21 | Assert(pExUserPerms); | ||
| 22 | return pExUserPerms; | ||
| 23 | } | ||
| 24 | |||
| 25 | |||
| 26 | SCA_SMB* AddSmbToList(SCA_SMB* pssList, SCA_SMB* pss) | ||
| 27 | { | ||
| 28 | if (pssList) | ||
| 29 | { | ||
| 30 | SCA_SMB* pssT = pssList; | ||
| 31 | while (pssT->pssNext) | ||
| 32 | { | ||
| 33 | pssT = pssT->pssNext; | ||
| 34 | } | ||
| 35 | |||
| 36 | pssT->pssNext = pss; | ||
| 37 | } | ||
| 38 | else | ||
| 39 | { | ||
| 40 | pssList = pss; | ||
| 41 | } | ||
| 42 | |||
| 43 | return pssList; | ||
| 44 | } | ||
| 45 | |||
| 46 | |||
| 47 | SCA_SMB_EX_USER_PERMS* AddExUserPermsSmbToList( | ||
| 48 | SCA_SMB_EX_USER_PERMS* pExUserPermsList, | ||
| 49 | SCA_SMB_EX_USER_PERMS* pExUserPerms | ||
| 50 | ) | ||
| 51 | { | ||
| 52 | SCA_SMB_EX_USER_PERMS* pExUserPermsTemp = pExUserPermsList; | ||
| 53 | if (pExUserPermsList) | ||
| 54 | { | ||
| 55 | while (pExUserPermsTemp->pExUserPermsNext) | ||
| 56 | { | ||
| 57 | pExUserPermsTemp = pExUserPermsTemp->pExUserPermsNext; | ||
| 58 | } | ||
| 59 | |||
| 60 | pExUserPermsTemp->pExUserPermsNext = pExUserPerms; | ||
| 61 | } | ||
| 62 | else | ||
| 63 | { | ||
| 64 | pExUserPermsList = pExUserPerms; | ||
| 65 | } | ||
| 66 | |||
| 67 | return pExUserPermsList; | ||
| 68 | } | ||
| 69 | |||
| 70 | void ScaSmbFreeList(SCA_SMB* pssList) | ||
| 71 | { | ||
| 72 | SCA_SMB* pssDelete = pssList; | ||
| 73 | while (pssList) | ||
| 74 | { | ||
| 75 | pssDelete = pssList; | ||
| 76 | pssList = pssList->pssNext; | ||
| 77 | |||
| 78 | MemFree(pssDelete); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | void ScaExUserPermsSmbFreeList(SCA_SMB_EX_USER_PERMS* pExUserPermsList) | ||
| 83 | { | ||
| 84 | SCA_SMB_EX_USER_PERMS* pExUserPermsDelete = pExUserPermsList; | ||
| 85 | while (pExUserPermsList) | ||
| 86 | { | ||
| 87 | pExUserPermsDelete = pExUserPermsList; | ||
| 88 | pExUserPermsList = pExUserPermsList->pExUserPermsNext; | ||
| 89 | |||
| 90 | MemFree(pExUserPermsDelete); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | // sql query constants | ||
| 95 | LPCWSTR vcsSmbQuery = L"SELECT `Wix4FileShare`, `ShareName`, `Description`, `Directory_`, " | ||
| 96 | L"`Component_`, `User_`, `Permissions` FROM `Wix4FileShare`"; | ||
| 97 | |||
| 98 | enum eSmbQuery { | ||
| 99 | ssqFileShare = 1, | ||
| 100 | ssqShareName, | ||
| 101 | ssqDescription, | ||
| 102 | ssqDirectory, | ||
| 103 | ssqComponent, | ||
| 104 | ssqUser, | ||
| 105 | ssqPermissions | ||
| 106 | }; | ||
| 107 | |||
| 108 | |||
| 109 | /******************************************************************** | ||
| 110 | ScaSmbRead - read all of the information from the msi tables and | ||
| 111 | return a list of file share jobs to be done. | ||
| 112 | |||
| 113 | ********************************************************************/ | ||
| 114 | HRESULT ScaSmbRead(SCA_SMB** ppssList) | ||
| 115 | { | ||
| 116 | HRESULT hr = S_OK; | ||
| 117 | UINT er = ERROR_SUCCESS; | ||
| 118 | PMSIHANDLE hView, hRec; | ||
| 119 | |||
| 120 | LPWSTR pwzData = NULL; | ||
| 121 | |||
| 122 | SCA_SMB* pss = NULL; | ||
| 123 | BOOL bUserPermissionsTableExists = FALSE; | ||
| 124 | |||
| 125 | if (S_OK != WcaTableExists(L"Wix4FileShare")) | ||
| 126 | { | ||
| 127 | WcaLog(LOGMSG_VERBOSE, "Skipping ScaSmbCreateShare() - Wix4FileShare table not present"); | ||
| 128 | ExitFunction1(hr = S_FALSE); | ||
| 129 | } | ||
| 130 | |||
| 131 | if (S_OK == WcaTableExists(L"Wix4FileSharePermissions")) | ||
| 132 | { | ||
| 133 | bUserPermissionsTableExists = TRUE; | ||
| 134 | } | ||
| 135 | else | ||
| 136 | { | ||
| 137 | WcaLog(LOGMSG_VERBOSE, "No Additional Permissions - Wix4FileSharePermissions table not present"); | ||
| 138 | } | ||
| 139 | |||
| 140 | WcaLog(LOGMSG_VERBOSE, "Reading File Share Tables"); | ||
| 141 | |||
| 142 | // loop through all the fileshares | ||
| 143 | hr = WcaOpenExecuteView(vcsSmbQuery, &hView); | ||
| 144 | ExitOnFailure(hr, "Failed to open view on Wix4FileShare table"); | ||
| 145 | while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) | ||
| 146 | { | ||
| 147 | pss = NewSmb(); | ||
| 148 | if (!pss) | ||
| 149 | { | ||
| 150 | hr = E_OUTOFMEMORY; | ||
| 151 | break; | ||
| 152 | } | ||
| 153 | Assert(pss); | ||
| 154 | ::ZeroMemory(pss, sizeof(*pss)); | ||
| 155 | |||
| 156 | hr = WcaGetRecordString(hRec, ssqFileShare, &pwzData); | ||
| 157 | ExitOnFailure(hr, "Failed to get Wix4FileShare.Wix4FileShare"); | ||
| 158 | hr = ::StringCchCopyW(pss->wzId, countof(pss->wzId), pwzData); | ||
| 159 | ExitOnFailure(hr, "Failed to copy ID string to smb object"); | ||
| 160 | |||
| 161 | hr = WcaGetRecordFormattedString(hRec, ssqShareName, &pwzData); | ||
| 162 | ExitOnFailure(hr, "Failed to get Wix4FileShare.ShareName"); | ||
| 163 | hr = ::StringCchCopyW(pss->wzShareName, countof(pss->wzShareName), pwzData); | ||
| 164 | ExitOnFailure(hr, "Failed to copy share name string to smb object"); | ||
| 165 | |||
| 166 | hr = WcaGetRecordString(hRec, ssqComponent, &pwzData); | ||
| 167 | ExitOnFailure(hr, "Failed to get Component for Wix4FileShare: '%ls'", pss->wzShareName); | ||
| 168 | hr = ::StringCchCopyW(pss->wzComponent, countof(pss->wzComponent), pwzData); | ||
| 169 | ExitOnFailure(hr, "Failed to copy component string to smb object"); | ||
| 170 | |||
| 171 | hr = WcaGetRecordFormattedString(hRec, ssqDescription, &pwzData); | ||
| 172 | ExitOnFailure(hr, "Failed to get Share Description for Wix4FileShare: '%ls'", pss->wzShareName); | ||
| 173 | hr = ::StringCchCopyW(pss->wzDescription, countof(pss->wzDescription), pwzData); | ||
| 174 | ExitOnFailure(hr, "Failed to copy description string to smb object"); | ||
| 175 | |||
| 176 | // get user info from the user table | ||
| 177 | hr = WcaGetRecordFormattedString(hRec, ssqUser, &pwzData); | ||
| 178 | ExitOnFailure(hr, "Failed to get Wix4User record for Wix4FileShare: '%ls'", pss->wzShareName); | ||
| 179 | |||
| 180 | // get component install state | ||
| 181 | er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pss->wzComponent, &pss->isInstalled, &pss->isAction); | ||
| 182 | hr = HRESULT_FROM_WIN32(er); | ||
| 183 | ExitOnFailure(hr, "Failed to get Component state for Wix4FileShare"); | ||
| 184 | |||
| 185 | // if a user was specified | ||
| 186 | if (*pwzData) | ||
| 187 | { | ||
| 188 | pss->fUseIntegratedAuth = FALSE; | ||
| 189 | pss->fLegacyUserProvided = TRUE; | ||
| 190 | hr = ScaGetUser(pwzData, &pss->scau); | ||
| 191 | ExitOnFailure(hr, "Failed to get user information for fileshare: '%ls'", pss->wzShareName); | ||
| 192 | } | ||
| 193 | else | ||
| 194 | { | ||
| 195 | pss->fLegacyUserProvided = FALSE; | ||
| 196 | // TODO: figure out whether this is useful still | ||
| 197 | //pss->fUseIntegratedAuth = TRUE; | ||
| 198 | // integrated authorization doesn't have a User record | ||
| 199 | } | ||
| 200 | |||
| 201 | // get the share's directory | ||
| 202 | hr = WcaGetRecordString(hRec, ssqDirectory, &pwzData); | ||
| 203 | ExitOnFailure(hr, "Failed to get directory for Wix4FileShare: '%ls'", pss->wzShareName); | ||
| 204 | |||
| 205 | WCHAR wzPath[MAX_PATH]; | ||
| 206 | DWORD dwLen; | ||
| 207 | dwLen = countof(wzPath); | ||
| 208 | // review: relevant for file shares? | ||
| 209 | if (INSTALLSTATE_SOURCE == pss->isAction) | ||
| 210 | { | ||
| 211 | er = ::MsiGetSourcePathW(WcaGetInstallHandle(), pwzData, wzPath, &dwLen); | ||
| 212 | } | ||
| 213 | else | ||
| 214 | { | ||
| 215 | er = ::MsiGetTargetPathW(WcaGetInstallHandle(), pwzData, wzPath, &dwLen); | ||
| 216 | } | ||
| 217 | hr = HRESULT_FROM_WIN32(er); | ||
| 218 | ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); | ||
| 219 | |||
| 220 | // If the path is to the root of a drive, then it needs a trailing backslash. | ||
| 221 | // Otherwise, it can't have a trailing backslash. | ||
| 222 | if (3 < dwLen) | ||
| 223 | { | ||
| 224 | if (wzPath[dwLen - 1] == L'\\') | ||
| 225 | { | ||
| 226 | wzPath[dwLen - 1] = 0; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | else if (2 == dwLen && wzPath[1] == L':') | ||
| 230 | { | ||
| 231 | wzPath[2] = L'\\'; | ||
| 232 | wzPath[3] = 0; | ||
| 233 | } | ||
| 234 | |||
| 235 | hr = ::StringCchCopyW(pss->wzDirectory, countof(pss->wzDirectory), wzPath); | ||
| 236 | ExitOnFailure(hr, "Failed to copy directory string to smb object"); | ||
| 237 | |||
| 238 | hr = WcaGetRecordInteger(hRec, ssqPermissions, &pss->nPermissions); | ||
| 239 | ExitOnFailure(hr, "Failed to get Wix4FileShare.Permissions"); | ||
| 240 | |||
| 241 | // Check to see if additional user & permissions are specified for this share | ||
| 242 | if (bUserPermissionsTableExists) | ||
| 243 | { | ||
| 244 | hr = ScaSmbExPermsRead(pss); | ||
| 245 | ExitOnFailure(hr, "Failed to get Additional File Share Permissions"); | ||
| 246 | } | ||
| 247 | |||
| 248 | *ppssList = AddSmbToList(*ppssList, pss); | ||
| 249 | pss = NULL; // set the smb NULL so it doesn't accidentally get freed below | ||
| 250 | } | ||
| 251 | |||
| 252 | if (E_NOMOREITEMS == hr) | ||
| 253 | { | ||
| 254 | hr = S_OK; | ||
| 255 | } | ||
| 256 | ExitOnFailure(hr, "Failure occured while processing Wix4FileShare table"); | ||
| 257 | |||
| 258 | LExit: | ||
| 259 | // if anything was left over after an error clean it all up | ||
| 260 | if (pss) | ||
| 261 | { | ||
| 262 | ScaSmbFreeList(pss); | ||
| 263 | } | ||
| 264 | |||
| 265 | ReleaseStr(pwzData); | ||
| 266 | |||
| 267 | return hr; | ||
| 268 | } | ||
| 269 | |||
| 270 | |||
| 271 | /******************************************************************** | ||
| 272 | RetrieveSMBShareUserPermList - retrieve SMB Share's user permission list | ||
| 273 | |||
| 274 | ********************************************************************/ | ||
| 275 | HRESULT RetrieveFileShareUserPerm(SCA_SMB* pss, SCA_SMB_EX_USER_PERMS** ppExUserPermsList, DWORD *pUserPermsCount) | ||
| 276 | { | ||
| 277 | HRESULT hr = S_OK; | ||
| 278 | SHARE_INFO_502* psi = NULL; | ||
| 279 | NET_API_STATUS s; | ||
| 280 | BOOL bValid, bDaclDefaulted; | ||
| 281 | PACL acl = NULL; | ||
| 282 | PEXPLICIT_ACCESSW pEA = NULL; | ||
| 283 | ULONG nCount = 0; | ||
| 284 | DWORD er = ERROR_SUCCESS; | ||
| 285 | PSID pSID = NULL; | ||
| 286 | DWORD nUserNameSize = MAX_DARWIN_COLUMN; | ||
| 287 | DWORD nDomainNameSize = MAX_DARWIN_COLUMN; | ||
| 288 | SID_NAME_USE peUse; | ||
| 289 | DWORD dwCounter = 0; | ||
| 290 | SCA_SMB_EX_USER_PERMS* pExUserPermsList = NULL; | ||
| 291 | DWORD dwUserPermsCount = 0; | ||
| 292 | |||
| 293 | *pUserPermsCount = 0; | ||
| 294 | s = ::NetShareGetInfo(NULL, pss->wzShareName, 502, (LPBYTE*)&psi); | ||
| 295 | WcaLog(LOGMSG_VERBOSE, "retrieving permissions on existing file share."); | ||
| 296 | if (NERR_NetNameNotFound == s) | ||
| 297 | { | ||
| 298 | WcaLog(LOGMSG_VERBOSE, "File share has already been removed."); | ||
| 299 | ExitFunction1(hr = S_OK); | ||
| 300 | } | ||
| 301 | else if (NERR_Success != s || psi == NULL) | ||
| 302 | { | ||
| 303 | hr = E_FAIL; | ||
| 304 | ExitOnFailure(hr, "Failed to get share information with return code: %d", s); | ||
| 305 | } | ||
| 306 | if (!::GetSecurityDescriptorDacl(psi->shi502_security_descriptor, &bValid, &acl, &bDaclDefaulted) || !bValid) | ||
| 307 | { | ||
| 308 | ExitOnLastError(hr, "Failed to get acl from security descriptor"); | ||
| 309 | } | ||
| 310 | |||
| 311 | er = ::GetExplicitEntriesFromAclW(acl, &nCount, &pEA); | ||
| 312 | hr = HRESULT_FROM_WIN32(er); | ||
| 313 | ExitOnFailure(hr, "Failed to get access entries from acl for file share %ls", pss->wzShareName); | ||
| 314 | for (dwCounter = 0; dwCounter < nCount; ++dwCounter) | ||
| 315 | { | ||
| 316 | if (TRUSTEE_IS_SID == pEA[dwCounter].Trustee.TrusteeForm) | ||
| 317 | { | ||
| 318 | SCA_SMB_EX_USER_PERMS* pExUserPerms = NewExUserPermsSmb(); | ||
| 319 | ::ZeroMemory(pExUserPerms, sizeof(*pExUserPerms)); | ||
| 320 | pExUserPermsList = AddExUserPermsSmbToList(pExUserPermsList, pExUserPerms); | ||
| 321 | pSID = (PSID)(pEA[dwCounter].Trustee.ptstrName); | ||
| 322 | if (!::LookupAccountSidW(NULL, pSID, pExUserPerms->scau.wzName, &nUserNameSize, pExUserPerms->scau.wzDomain, &nDomainNameSize, &peUse)) | ||
| 323 | { | ||
| 324 | hr = E_FAIL; | ||
| 325 | ExitOnFailure(hr, "Failed to get account name from SID"); | ||
| 326 | } | ||
| 327 | pExUserPerms->nPermissions = pEA[dwCounter].grfAccessPermissions; | ||
| 328 | pExUserPerms->accessMode = pEA[dwCounter].grfAccessMode; | ||
| 329 | ++dwUserPermsCount; | ||
| 330 | nUserNameSize = MAX_DARWIN_COLUMN; | ||
| 331 | nDomainNameSize = MAX_DARWIN_COLUMN; | ||
| 332 | } | ||
| 333 | } | ||
| 334 | *ppExUserPermsList = pExUserPermsList; | ||
| 335 | *pUserPermsCount = dwUserPermsCount; | ||
| 336 | |||
| 337 | LExit: | ||
| 338 | if (psi) | ||
| 339 | { | ||
| 340 | ::NetApiBufferFree(psi); | ||
| 341 | } | ||
| 342 | |||
| 343 | if (pEA) | ||
| 344 | { | ||
| 345 | ::LocalFree(pEA); | ||
| 346 | } | ||
| 347 | |||
| 348 | return hr; | ||
| 349 | } | ||
| 350 | |||
| 351 | |||
| 352 | /******************************************************************** | ||
| 353 | SchedCreateSmb - schedule one instance of a file share creation | ||
| 354 | |||
| 355 | ********************************************************************/ | ||
| 356 | HRESULT SchedCreateSmb(SCA_SMB* pss) | ||
| 357 | { | ||
| 358 | HRESULT hr = S_OK; | ||
| 359 | |||
| 360 | WCHAR wzDomainUser[255]; // "domain\user" | ||
| 361 | SCA_SMB_EX_USER_PERMS* pExUserPermsList = NULL; | ||
| 362 | int nCounter = 0; | ||
| 363 | WCHAR* pwzRollbackCustomActionData = NULL; | ||
| 364 | WCHAR* pwzCustomActionData = NULL; | ||
| 365 | |||
| 366 | hr = WcaWriteStringToCaData(pss->wzShareName, &pwzRollbackCustomActionData); | ||
| 367 | ExitOnFailure(hr, "failed to add ShareName to CustomActionData"); | ||
| 368 | |||
| 369 | hr = WcaWriteStringToCaData(pss->wzShareName, &pwzCustomActionData); | ||
| 370 | ExitOnFailure(hr, "failed to add ShareName to CustomActionData"); | ||
| 371 | |||
| 372 | hr = WcaWriteStringToCaData(pss->wzDescription, &pwzCustomActionData); | ||
| 373 | ExitOnFailure(hr, "Failed to add server name to CustomActionData"); | ||
| 374 | |||
| 375 | hr = WcaWriteStringToCaData(pss->wzDirectory, &pwzCustomActionData); | ||
| 376 | ExitOnFailure(hr, "Failed to add full path instance to CustomActionData"); | ||
| 377 | |||
| 378 | hr = WcaWriteStringToCaData(pss->fUseIntegratedAuth ? L"1" : L"0", &pwzCustomActionData); | ||
| 379 | ExitOnFailure(hr, "Failed to add server name to CustomActionData"); | ||
| 380 | |||
| 381 | if (pss->fLegacyUserProvided) | ||
| 382 | { | ||
| 383 | hr = WcaWriteIntegerToCaData(pss->nUserPermissionCount + 1, &pwzCustomActionData); | ||
| 384 | ExitOnFailure(hr, "Failed to add additional user permission count to CustomActionData"); | ||
| 385 | |||
| 386 | hr = UserBuildDomainUserName(wzDomainUser, countof(wzDomainUser), pss->scau.wzName, pss->scau.wzDomain); | ||
| 387 | ExitOnFailure(hr, "Failed to build user and domain name for CustomActionData"); | ||
| 388 | hr = WcaWriteStringToCaData(wzDomainUser, &pwzCustomActionData); | ||
| 389 | ExitOnFailure(hr, "Failed to add server Domain\\UserName to CustomActionData"); | ||
| 390 | |||
| 391 | hr = WcaWriteIntegerToCaData(pss->nPermissions, &pwzCustomActionData); | ||
| 392 | ExitOnFailure(hr, "Failed to add permissions to CustomActionData"); | ||
| 393 | } | ||
| 394 | else | ||
| 395 | { | ||
| 396 | hr = WcaWriteIntegerToCaData(pss->nUserPermissionCount, &pwzCustomActionData); | ||
| 397 | ExitOnFailure(hr, "Failed to add additional user permission count to CustomActionData"); | ||
| 398 | } | ||
| 399 | |||
| 400 | if (pss->nUserPermissionCount > 0) | ||
| 401 | { | ||
| 402 | nCounter = 0; | ||
| 403 | for (pExUserPermsList = pss->pExUserPerms; pExUserPermsList; pExUserPermsList = pExUserPermsList->pExUserPermsNext) | ||
| 404 | { | ||
| 405 | Assert(nCounter < pss->nUserPermissionCount); | ||
| 406 | |||
| 407 | hr = UserBuildDomainUserName(wzDomainUser, countof(wzDomainUser), pExUserPermsList->scau.wzName, pExUserPermsList->scau.wzDomain); | ||
| 408 | ExitOnFailure(hr, "Failed to build user and domain name for CustomActionData"); | ||
| 409 | hr = WcaWriteStringToCaData(wzDomainUser, &pwzCustomActionData); | ||
| 410 | ExitOnFailure(hr, "Failed to add server Domain\\UserName to CustomActionData"); | ||
| 411 | |||
| 412 | hr = WcaWriteIntegerToCaData((int)pExUserPermsList->accessMode, &pwzCustomActionData); | ||
| 413 | ExitOnFailure(hr, "Failed to add access mode to CustomActionData"); | ||
| 414 | |||
| 415 | hr = WcaWriteIntegerToCaData(pExUserPermsList->nPermissions, &pwzCustomActionData); | ||
| 416 | ExitOnFailure(hr, "Failed to add permissions to CustomActionData"); | ||
| 417 | ++nCounter; | ||
| 418 | } | ||
| 419 | Assert(nCounter == pss->nUserPermissionCount); | ||
| 420 | } | ||
| 421 | |||
| 422 | // Schedule the rollback first | ||
| 423 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"CreateSmbRollback"), pwzRollbackCustomActionData, COST_SMB_DROPSMB); | ||
| 424 | ExitOnFailure(hr, "Failed to schedule DropSmb action"); | ||
| 425 | |||
| 426 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"CreateSmb"), pwzCustomActionData, COST_SMB_CREATESMB); | ||
| 427 | ExitOnFailure(hr, "Failed to schedule CreateSmb action"); | ||
| 428 | |||
| 429 | LExit: | ||
| 430 | ReleaseStr(pwzRollbackCustomActionData); | ||
| 431 | ReleaseStr(pwzCustomActionData); | ||
| 432 | |||
| 433 | if (pExUserPermsList) | ||
| 434 | { | ||
| 435 | ScaExUserPermsSmbFreeList(pExUserPermsList); | ||
| 436 | } | ||
| 437 | |||
| 438 | return hr; | ||
| 439 | } | ||
| 440 | |||
| 441 | |||
| 442 | /******************************************************************** | ||
| 443 | ScaSmbInstall - for every file share, schedule the create custom action | ||
| 444 | |||
| 445 | ********************************************************************/ | ||
| 446 | HRESULT ScaSmbInstall(SCA_SMB* pssList) | ||
| 447 | { | ||
| 448 | HRESULT hr = S_FALSE; // assume nothing will be done | ||
| 449 | SCA_SMB* pss = NULL; | ||
| 450 | |||
| 451 | for (pss = pssList; pss; pss = pss->pssNext) | ||
| 452 | { | ||
| 453 | // if installing this component | ||
| 454 | if (WcaIsInstalling(pss->isInstalled, pss->isAction) ) | ||
| 455 | { | ||
| 456 | hr = SchedCreateSmb(pss); | ||
| 457 | ExitOnFailure(hr, "Failed to schedule the creation of the fileshare: %ls", pss->wzShareName); | ||
| 458 | } | ||
| 459 | } | ||
| 460 | |||
| 461 | LExit: | ||
| 462 | return hr; | ||
| 463 | } | ||
| 464 | |||
| 465 | |||
| 466 | /******************************************************************** | ||
| 467 | SchedDropSmb - schedule one instance of a file share removal | ||
| 468 | |||
| 469 | ********************************************************************/ | ||
| 470 | HRESULT SchedDropSmb(SCA_SMB* pss) | ||
| 471 | { | ||
| 472 | HRESULT hr = S_OK; | ||
| 473 | |||
| 474 | WCHAR* pwzCustomActionData = NULL; | ||
| 475 | WCHAR* pwzRollbackCustomActionData = NULL; | ||
| 476 | SCA_SMB_EX_USER_PERMS *pExUserPermsList = NULL; | ||
| 477 | SCA_SMB_EX_USER_PERMS *pExUserPerm = NULL; | ||
| 478 | WCHAR wzDomainUser[255]; // "domain\user" | ||
| 479 | DWORD dwUserPermsCount = 0; | ||
| 480 | |||
| 481 | // roll back DropSmb | ||
| 482 | hr = WcaWriteStringToCaData(pss->wzShareName, &pwzRollbackCustomActionData); | ||
| 483 | ExitOnFailure(hr, "failed to add ShareName to CustomActionData"); | ||
| 484 | |||
| 485 | hr = WcaWriteStringToCaData(pss->wzDescription, &pwzRollbackCustomActionData); | ||
| 486 | ExitOnFailure(hr, "Failed to add server name to CustomActionData"); | ||
| 487 | |||
| 488 | hr = WcaWriteStringToCaData(pss->wzDirectory, &pwzRollbackCustomActionData); | ||
| 489 | ExitOnFailure(hr, "Failed to add full path instance to CustomActionData"); | ||
| 490 | |||
| 491 | hr = WcaWriteStringToCaData(L"1", &pwzRollbackCustomActionData); | ||
| 492 | ExitOnFailure(hr, "Failed to add useintegrated flag to CustomActionData"); | ||
| 493 | |||
| 494 | hr = RetrieveFileShareUserPerm(pss, &pExUserPermsList, &dwUserPermsCount); | ||
| 495 | ExitOnFailure(hr, "Failed to retrieve SMBShare's user permissions"); | ||
| 496 | |||
| 497 | hr = WcaWriteIntegerToCaData((int)dwUserPermsCount, &pwzRollbackCustomActionData); | ||
| 498 | ExitOnFailure(hr, "Failed to add additional user permission count to CustomActionData"); | ||
| 499 | |||
| 500 | for (pExUserPerm = pExUserPermsList; pExUserPerm; pExUserPerm = pExUserPerm->pExUserPermsNext) | ||
| 501 | { | ||
| 502 | hr = UserBuildDomainUserName(wzDomainUser, countof(wzDomainUser), pExUserPerm->scau.wzName, pExUserPerm->scau.wzDomain); | ||
| 503 | ExitOnFailure(hr, "Failed to build user and domain name for CustomActionData"); | ||
| 504 | hr = WcaWriteStringToCaData(wzDomainUser, &pwzRollbackCustomActionData); | ||
| 505 | ExitOnFailure(hr, "Failed to add server Domain\\UserName to CustomActionData"); | ||
| 506 | |||
| 507 | hr = WcaWriteIntegerToCaData((int)pExUserPerm->accessMode, &pwzRollbackCustomActionData); | ||
| 508 | ExitOnFailure(hr, "Failed to add access mode to CustomActionData"); | ||
| 509 | |||
| 510 | hr = WcaWriteIntegerToCaData(pExUserPerm->nPermissions, &pwzRollbackCustomActionData); | ||
| 511 | ExitOnFailure(hr, "Failed to add permissions to CustomActionData"); | ||
| 512 | } | ||
| 513 | |||
| 514 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"DropSmbRollback"), pwzRollbackCustomActionData, COST_SMB_CREATESMB); | ||
| 515 | ExitOnFailure(hr, "Failed to schedule DropSmbRollback action"); | ||
| 516 | |||
| 517 | // DropSMB | ||
| 518 | hr = WcaWriteStringToCaData(pss->wzShareName, &pwzCustomActionData); | ||
| 519 | ExitOnFailure(hr, "failed to add ShareName to CustomActionData"); | ||
| 520 | |||
| 521 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"DropSmb"), pwzCustomActionData, COST_SMB_DROPSMB); | ||
| 522 | ExitOnFailure(hr, "Failed to schedule DropSmb action"); | ||
| 523 | |||
| 524 | LExit: | ||
| 525 | ReleaseStr(pwzCustomActionData); | ||
| 526 | |||
| 527 | if (pExUserPermsList) | ||
| 528 | { | ||
| 529 | ScaExUserPermsSmbFreeList(pExUserPermsList); | ||
| 530 | } | ||
| 531 | |||
| 532 | return hr; | ||
| 533 | |||
| 534 | } | ||
| 535 | |||
| 536 | |||
| 537 | /******************************************************************** | ||
| 538 | ScaSmbUninstall - for every file share, schedule the drop custom action | ||
| 539 | |||
| 540 | ********************************************************************/ | ||
| 541 | HRESULT ScaSmbUninstall(SCA_SMB* pssList) | ||
| 542 | { | ||
| 543 | HRESULT hr = S_FALSE; // assume nothing will be done | ||
| 544 | SCA_SMB* pss = NULL; | ||
| 545 | |||
| 546 | for (pss = pssList; pss; pss = pss->pssNext) | ||
| 547 | { | ||
| 548 | // if uninstalling this component | ||
| 549 | if (WcaIsUninstalling(pss->isInstalled, pss->isAction) ) | ||
| 550 | { | ||
| 551 | hr = SchedDropSmb(pss); | ||
| 552 | ExitOnFailure(hr, "Failed to remove file share %ls", pss->wzShareName); | ||
| 553 | } | ||
| 554 | } | ||
| 555 | |||
| 556 | LExit: | ||
| 557 | return hr; | ||
| 558 | } | ||
| 559 | |||
| 560 | LPCWSTR vcsSmbExUserPermsQuery = L"SELECT `FileShare_`,`User_`,`Permissions` " | ||
| 561 | L"FROM `Wix4FileSharePermissions` WHERE `FileShare_`=?"; | ||
| 562 | |||
| 563 | enum eSmbUserPermsQuery { | ||
| 564 | ssupqFileShare = 1, | ||
| 565 | ssupqUser, | ||
| 566 | ssupqPermissions | ||
| 567 | |||
| 568 | }; | ||
| 569 | |||
| 570 | |||
| 571 | /******************************************************************** | ||
| 572 | ScaSmbExPermsRead - for Every entry in File Permissions table add a | ||
| 573 | User Name & Permissions structure to the List | ||
| 574 | |||
| 575 | ********************************************************************/ | ||
| 576 | HRESULT ScaSmbExPermsRead(SCA_SMB* pss) | ||
| 577 | { | ||
| 578 | HRESULT hr = S_OK; | ||
| 579 | PMSIHANDLE hView, hRec; | ||
| 580 | |||
| 581 | LPWSTR pwzData = NULL; | ||
| 582 | SCA_SMB_EX_USER_PERMS* pExUserPermsList = pss->pExUserPerms; | ||
| 583 | SCA_SMB_EX_USER_PERMS* pExUserPerms = NULL; | ||
| 584 | int nCounter = 0; | ||
| 585 | |||
| 586 | hRec = ::MsiCreateRecord(1); | ||
| 587 | hr = WcaSetRecordString(hRec, 1, pss->wzId); | ||
| 588 | ExitOnFailure(hr, "Failed to look up FileShare"); | ||
| 589 | |||
| 590 | hr = WcaOpenView(vcsSmbExUserPermsQuery, &hView); | ||
| 591 | ExitOnFailure(hr, "Failed to open view on Wix4FileSharePermissions table"); | ||
| 592 | hr = WcaExecuteView(hView, hRec); | ||
| 593 | ExitOnFailure(hr, "Failed to execute view on Wix4FileSharePermissions table"); | ||
| 594 | |||
| 595 | // loop through all User/Permissions paris returned | ||
| 596 | while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) | ||
| 597 | { | ||
| 598 | pExUserPerms = NewExUserPermsSmb(); | ||
| 599 | if (!pExUserPerms) | ||
| 600 | { | ||
| 601 | hr = E_OUTOFMEMORY; | ||
| 602 | break; | ||
| 603 | } | ||
| 604 | Assert(pExUserPerms); | ||
| 605 | ::ZeroMemory(pExUserPerms, sizeof(*pExUserPerms)); | ||
| 606 | |||
| 607 | hr = WcaGetRecordString(hRec, ssupqUser, &pwzData); | ||
| 608 | ExitOnFailure(hr, "Failed to get Wix4FileSharePermissions.User"); | ||
| 609 | hr = ScaGetUser(pwzData, &pExUserPerms->scau); | ||
| 610 | ExitOnFailure(hr, "Failed to get user information for fileshare: '%ls'", pss->wzShareName); | ||
| 611 | |||
| 612 | hr = WcaGetRecordInteger(hRec, ssupqPermissions, &pExUserPerms->nPermissions); | ||
| 613 | ExitOnFailure(hr, "Failed to get Wix4FileSharePermissions.Permissions"); | ||
| 614 | pExUserPerms->accessMode = SET_ACCESS; // we only support SET_ACCESS here | ||
| 615 | |||
| 616 | pExUserPermsList = AddExUserPermsSmbToList(pExUserPermsList, pExUserPerms); | ||
| 617 | ++nCounter; | ||
| 618 | pExUserPerms = NULL; // set the smb NULL so it doesn't accidentally get freed below | ||
| 619 | } | ||
| 620 | |||
| 621 | if (E_NOMOREITEMS == hr) | ||
| 622 | { | ||
| 623 | hr = S_OK; | ||
| 624 | pss->pExUserPerms = pExUserPermsList; | ||
| 625 | pss->nUserPermissionCount = nCounter; | ||
| 626 | } | ||
| 627 | ExitOnFailure(hr, "Failure occured while processing FileShare table"); | ||
| 628 | |||
| 629 | LExit: | ||
| 630 | // if anything was left over after an error clean it all up | ||
| 631 | if (pExUserPerms) | ||
| 632 | { | ||
| 633 | ScaExUserPermsSmbFreeList(pExUserPerms); | ||
| 634 | } | ||
| 635 | |||
| 636 | ReleaseStr(pwzData); | ||
| 637 | |||
| 638 | return hr; | ||
| 639 | } | ||
