/** * Internal. Free all allocated space for representing an image except pImage, * and optionally delete the image from disk. */ static int rawFreeImage(PRAWIMAGE pImage, bool fDelete) { int rc = VINF_SUCCESS; /* Freeing a never allocated image (e.g. because the open failed) is * not signalled as an error. After all nothing bad happens. */ if (pImage) { if (pImage->pStorage) { /* No point updating the file that is deleted anyway. */ if (!fDelete) { /* For newly created images in sequential mode fill it to * the nominal size. */ if ( pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) && pImage->fCreate) { /* Fill rest of image with zeroes, a must for sequential * images to reach the nominal size. */ uint64_t uOff; void *pvBuf = RTMemTmpAllocZ(RAW_FILL_SIZE); if (RT_LIKELY(pvBuf)) { uOff = pImage->offAccess; /* Write data to all image blocks. */ while (uOff < pImage->cbSize) { unsigned cbChunk = (unsigned)RT_MIN(pImage->cbSize - uOff, RAW_FILL_SIZE); rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, uOff, pvBuf, cbChunk); if (RT_FAILURE(rc)) break; uOff += cbChunk; } RTMemTmpFree(pvBuf); } else rc = VERR_NO_MEMORY; } rawFlushImage(pImage); } rc = vdIfIoIntFileClose(pImage->pIfIo, pImage->pStorage); pImage->pStorage = NULL; } if (fDelete && pImage->pszFilename) vdIfIoIntFileDelete(pImage->pIfIo, pImage->pszFilename); } LogFlowFunc(("returns %Rrc\n", rc)); return rc; }
/** * Check the credentials and return the gid/uid of user. * * @param pszUser username * @param pszPasswd password * @param gid where to store the GID of the user * @param uid where to store the UID of the user * @returns IPRT status code */ static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *pGid, uid_t *pUid) { #if defined(RT_OS_LINUX) struct passwd *pw; pw = getpwnam(pszUser); if (!pw) return VERR_PERMISSION_DENIED; if (!pszPasswd) pszPasswd = ""; struct spwd *spwd; /* works only if /etc/shadow is accessible */ spwd = getspnam(pszUser); if (spwd) pw->pw_passwd = spwd->sp_pwdp; /* be reentrant */ struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data)); char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data); int fCorrect = !strcmp(pszEncPasswd, pw->pw_passwd); RTMemTmpFree(data); if (!fCorrect) return VERR_PERMISSION_DENIED; *pGid = pw->pw_gid; *pUid = pw->pw_uid; return VINF_SUCCESS; #elif defined(RT_OS_SOLARIS) struct passwd *ppw, pw; char szBuf[1024]; if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL) return VERR_PERMISSION_DENIED; if (!pszPasswd) pszPasswd = ""; struct spwd spwd; char szPwdBuf[1024]; /* works only if /etc/shadow is accessible */ if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL) ppw->pw_passwd = spwd.sp_pwdp; char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); if (strcmp(pszEncPasswd, ppw->pw_passwd)) return VERR_PERMISSION_DENIED; *pGid = ppw->pw_gid; *pUid = ppw->pw_uid; return VINF_SUCCESS; #else NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid); return VERR_PERMISSION_DENIED; #endif }
static void tst1(size_t cTest, size_t cchDigits, char chSep) { RTTestISubF("tst #%u (digits: %u; sep: %c)", cTest, cchDigits, chSep ? chSep : ' '); /* We try to create max possible + one. */ size_t cTimes = 1; for (size_t i = 0; i < cchDigits; ++i) cTimes *= 10; /* Allocate the result array. */ char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *)); RTTESTI_CHECK_RETV(papszNames != NULL); int rc = VERR_INTERNAL_ERROR; /* The test loop. */ size_t i; for (i = 0; i < cTimes; i++) { char szName[RTPATH_MAX]; RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS); if (RT_FAILURE(rc)) break; RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VINF_SUCCESS); if (RT_FAILURE(rc)) { RTTestIFailed("RTDirCreateUniqueNumbered(%s) call #%u -> %Rrc\n", szName, i, rc); break; } RTTESTI_CHECK(papszNames[i] = RTStrDup(szName)); if (!papszNames[i]) break; RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]); } /* Try to create one more, which shouldn't be possible. */ if (RT_SUCCESS(rc)) { char szName[RTPATH_MAX]; RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VERR_ALREADY_EXISTS); } /* cleanup */ while (i-- > 0) { RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS); RTStrFree(papszNames[i]); } RTMemTmpFree(papszNames); }
/** * Prepares a GMMR0AllocatePages request. * * @returns VINF_SUCCESS or VERR_NO_TMP_MEMORY. * @param pVM The cross context VM structure. * @param[out] ppReq Where to store the pointer to the request packet. * @param cPages The number of pages that's to be allocated. * @param enmAccount The account to charge. */ GMMR3DECL(int) GMMR3AllocatePagesPrepare(PVM pVM, PGMMALLOCATEPAGESREQ *ppReq, uint32_t cPages, GMMACCOUNT enmAccount) { uint32_t cb = RT_OFFSETOF(GMMALLOCATEPAGESREQ, aPages[cPages]); PGMMALLOCATEPAGESREQ pReq = (PGMMALLOCATEPAGESREQ)RTMemTmpAllocZ(cb); if (!pReq) return VERR_NO_TMP_MEMORY; pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; pReq->Hdr.cbReq = cb; pReq->enmAccount = enmAccount; pReq->cPages = cPages; NOREF(pVM); *ppReq = pReq; return VINF_SUCCESS; }
RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed, PFNRTPROGRESS pfnProgressCallback, void *pvUser) { /* Validate input */ AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER); AssertPtrReturn(papszFiles, VERR_INVALID_POINTER); AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_POINTER); int rc = VINF_SUCCESS; /* Create our compare list */ PRTMANIFESTTEST paFiles = (PRTMANIFESTTEST)RTMemTmpAllocZ(sizeof(RTMANIFESTTEST) * cFiles); if (!paFiles) return VERR_NO_MEMORY; RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 }; /* Fill our compare list */ for (size_t i = 0; i < cFiles; ++i) { char *pszDigest; if (pfnProgressCallback) { callback.cCurrentFile = i; rc = RTSha1DigestFromFile(papszFiles[i], &pszDigest, rtSHAProgressCallback, &callback); } else rc = RTSha1DigestFromFile(papszFiles[i], &pszDigest, NULL, NULL); if (RT_FAILURE(rc)) break; paFiles[i].pszTestFile = (char*)papszFiles[i]; paFiles[i].pszTestDigest = pszDigest; } /* Do the verification */ if (RT_SUCCESS(rc)) rc = RTManifestVerify(pszManifestFile, paFiles, cFiles, piFailed); /* Cleanup */ for (size_t i = 0; i < cFiles; ++i) { if (paFiles[i].pszTestDigest) RTStrFree((char*)paFiles[i].pszTestDigest); } RTMemTmpFree(paFiles); return rc; }
/** * Creates a hashes structure. * * @returns Pointer to a hashes structure. * @param fAttrs The desired hashes, RTMANIFEST_ATTR_XXX. */ static PRTMANIFESTHASHES rtManifestHashesCreate(uint32_t fAttrs) { PRTMANIFESTHASHES pHashes = (PRTMANIFESTHASHES)RTMemTmpAllocZ(sizeof(*pHashes)); if (pHashes) { pHashes->fAttrs = fAttrs; /*pHashes->cbStream = 0;*/ if (fAttrs & RTMANIFEST_ATTR_MD5) RTMd5Init(&pHashes->Md5Ctx); if (fAttrs & RTMANIFEST_ATTR_SHA1) RTSha1Init(&pHashes->Sha1Ctx); if (fAttrs & RTMANIFEST_ATTR_SHA256) RTSha256Init(&pHashes->Sha256Ctx); if (fAttrs & RTMANIFEST_ATTR_SHA512) RTSha512Init(&pHashes->Sha512Ctx); } return pHashes; }
static void tstDirCreateTemp(const char *pszSubTest, const char *pszTemplate, unsigned cTimes, bool fSkipXCheck) { RTTestISub(pszSubTest); /* Allocate the result array. */ char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *)); RTTESTI_CHECK_RETV(papszNames != NULL); /* The test loop. */ unsigned i; for (i = 0; i < cTimes; i++) { int rc; char szName[RTPATH_MAX]; RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), pszTemplate), VINF_SUCCESS); if (RT_FAILURE(rc)) break; RTTESTI_CHECK(papszNames[i] = RTStrDup(szName)); if (!papszNames[i]) break; rc = RTDirCreateTemp(papszNames[i]); if (rc != VINF_SUCCESS) { RTTestIFailed("RTDirCreateTemp(%s) call #%u -> %Rrc\n", szName, i, rc); RTStrFree(papszNames[i]); papszNames[i] = NULL; break; } RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]); RTTESTI_CHECK_MSG(strlen(szName) == strlen(papszNames[i]), ("szName %s\nReturned %s\n", szName, papszNames[i])); if (!fSkipXCheck) RTTESTI_CHECK_MSG(strchr(RTPathFilename(papszNames[i]), 'X') == NULL, ("szName %s\nReturned %s\n", szName, papszNames[i])); } /* cleanup */ while (i-- > 0) { RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS); RTStrFree(papszNames[i]); } RTMemTmpFree(papszNames); }
RTR3DECL(int) RTProcQueryUsernameA(RTPROCESS hProcess, char **ppszUser) { AssertPtrReturn(ppszUser, VERR_INVALID_POINTER); int rc; if ( hProcess == NIL_RTPROCESS || hProcess == RTProcSelf()) { /* * Figure a good buffer estimate. */ int32_t cbPwdMax = sysconf(_SC_GETPW_R_SIZE_MAX); if (cbPwdMax <= _1K) cbPwdMax = _1K; else AssertStmt(cbPwdMax <= 32*_1M, cbPwdMax = 32*_1M); char *pchBuf = (char *)RTMemTmpAllocZ(cbPwdMax); if (pchBuf) { /* * Get the password file entry. */ struct passwd Pwd; struct passwd *pPwd = NULL; rc = getpwuid_r(geteuid(), &Pwd, pchBuf, cbPwdMax, &pPwd); if (!rc) { /* * Convert the name to UTF-8, assuming that we're getting it in the local codeset. */ rc = RTStrCurrentCPToUtf8(ppszUser, pPwd->pw_name); } else rc = RTErrConvertFromErrno(rc); RTMemFree(pchBuf); } else rc = VERR_NO_TMP_MEMORY; } else rc = VERR_NOT_SUPPORTED; return rc; }
USBLIB_DECL(int) USBLibResetDevice(char *pszDevicePath, bool fReattach) { LogFlow((USBLIBR3 ":USBLibResetDevice pszDevicePath=%s\n", pszDevicePath)); size_t cbReq = sizeof(VBOXUSBREQ_RESET_DEVICE) + strlen(pszDevicePath); VBOXUSBREQ_RESET_DEVICE *pReq = (VBOXUSBREQ_RESET_DEVICE *)RTMemTmpAllocZ(cbReq); if (RT_UNLIKELY(!pReq)) return VERR_NO_MEMORY; pReq->fReattach = fReattach; strcpy(pReq->szDevicePath, pszDevicePath); int rc = usblibDoIOCtl(VBOXUSBMON_IOCTL_RESET_DEVICE, pReq, cbReq); if (RT_FAILURE(rc)) LogRel((USBLIBR3 ":VBOXUSBMON_IOCTL_RESET_DEVICE failed! rc=%Rrc\n", rc)); RTMemFree(pReq); return rc; }
/** * Frees allocated pages, for bailing out on failure. * * This will not call VMSetError on failure but will use AssertLogRel instead. * * @param pVM The cross context VM structure. * @param pAllocReq The allocation request to undo. */ GMMR3DECL(void) GMMR3FreeAllocatedPages(PVM pVM, GMMALLOCATEPAGESREQ const *pAllocReq) { uint32_t cb = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[pAllocReq->cPages]); PGMMFREEPAGESREQ pReq = (PGMMFREEPAGESREQ)RTMemTmpAllocZ(cb); AssertLogRelReturnVoid(pReq); pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; pReq->Hdr.cbReq = cb; pReq->enmAccount = pAllocReq->enmAccount; pReq->cPages = pAllocReq->cPages; uint32_t iPage = pAllocReq->cPages; while (iPage-- > 0) { Assert(pAllocReq->aPages[iPage].idPage != NIL_GMM_PAGEID); pReq->aPages[iPage].idPage = pAllocReq->aPages[iPage].idPage; } int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FREE_PAGES, 0, &pReq->Hdr); AssertLogRelRC(rc); RTMemTmpFree(pReq); }
/** * Check the credentials and return the gid/uid of user. * * @param pszUser username * @param pszPasswd password * @param gid where to store the GID of the user * @param uid where to store the UID of the user * @returns IPRT status code */ static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *pGid, uid_t *pUid) { #if defined(RT_OS_DARWIN) RTLogPrintf("rtCheckCredentials\n"); /* * Resolve user to UID and GID. */ char szBuf[_4K]; struct passwd Pw; struct passwd *pPw; if (getpwnam_r(pszUser, &Pw, szBuf, sizeof(szBuf), &pPw) != 0) return VERR_AUTHENTICATION_FAILURE; if (!pPw) return VERR_AUTHENTICATION_FAILURE; *pUid = pPw->pw_uid; *pGid = pPw->pw_gid; /* * Use PAM for the authentication. * Note! libpam.2.dylib was introduced with 10.6.x (OpenPAM). */ void *hModPam = dlopen("libpam.dylib", RTLD_LAZY | RTLD_GLOBAL); if (hModPam) { int (*pfnPamStart)(const char *, const char *, struct pam_conv *, pam_handle_t **); int (*pfnPamAuthenticate)(pam_handle_t *, int); int (*pfnPamAcctMgmt)(pam_handle_t *, int); int (*pfnPamSetItem)(pam_handle_t *, int, const void *); int (*pfnPamEnd)(pam_handle_t *, int); *(void **)&pfnPamStart = dlsym(hModPam, "pam_start"); *(void **)&pfnPamAuthenticate = dlsym(hModPam, "pam_authenticate"); *(void **)&pfnPamAcctMgmt = dlsym(hModPam, "pam_acct_mgmt"); *(void **)&pfnPamSetItem = dlsym(hModPam, "pam_set_item"); *(void **)&pfnPamEnd = dlsym(hModPam, "pam_end"); ASMCompilerBarrier(); if ( pfnPamStart && pfnPamAuthenticate && pfnPamAcctMgmt && pfnPamSetItem && pfnPamEnd) { #define pam_start pfnPamStart #define pam_authenticate pfnPamAuthenticate #define pam_acct_mgmt pfnPamAcctMgmt #define pam_set_item pfnPamSetItem #define pam_end pfnPamEnd /* Do the PAM stuff. Note! Abusing 'login' here for now... */ pam_handle_t *hPam = NULL; RTPROCPAMARGS PamConvArgs = { pszUser, pszPasswd }; struct pam_conv PamConversation; RT_ZERO(PamConversation); PamConversation.appdata_ptr = &PamConvArgs; PamConversation.conv = rtPamConv; int rc = pam_start("login", pszUser, &PamConversation, &hPam); if (rc == PAM_SUCCESS) { rc = pam_set_item(hPam, PAM_RUSER, pszUser); if (rc == PAM_SUCCESS) rc = pam_authenticate(hPam, 0); if (rc == PAM_SUCCESS) { rc = pam_acct_mgmt(hPam, 0); if ( rc == PAM_SUCCESS || rc == PAM_AUTHINFO_UNAVAIL /*??*/) { pam_end(hPam, PAM_SUCCESS); dlclose(hModPam); return VINF_SUCCESS; } Log(("rtCheckCredentials: pam_acct_mgmt -> %d\n", rc)); } else Log(("rtCheckCredentials: pam_authenticate -> %d\n", rc)); pam_end(hPam, rc); } else Log(("rtCheckCredentials: pam_start -> %d\n", rc)); } else Log(("rtCheckCredentials: failed to resolve symbols: %p %p %p %p %p\n", pfnPamStart, pfnPamAuthenticate, pfnPamAcctMgmt, pfnPamSetItem, pfnPamEnd)); dlclose(hModPam); } else Log(("rtCheckCredentials: Loading libpam.dylib failed\n")); return VERR_AUTHENTICATION_FAILURE; #elif defined(RT_OS_LINUX) struct passwd *pw; pw = getpwnam(pszUser); if (!pw) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd *spwd; /* works only if /etc/shadow is accessible */ spwd = getspnam(pszUser); if (spwd) pw->pw_passwd = spwd->sp_pwdp; /* Default fCorrect=true if no password specified. In that case, pw->pw_passwd * must be NULL (no password set for this user). Fail if a password is specified * but the user does not have one assigned. */ int fCorrect = !pszPasswd || !*pszPasswd; if (pw->pw_passwd && *pw->pw_passwd) { struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data)); /* be reentrant */ char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data); fCorrect = pszEncPasswd && !strcmp(pszEncPasswd, pw->pw_passwd); RTMemTmpFree(data); } if (!fCorrect) return VERR_AUTHENTICATION_FAILURE; *pGid = pw->pw_gid; *pUid = pw->pw_uid; return VINF_SUCCESS; #elif defined(RT_OS_SOLARIS) struct passwd *ppw, pw; char szBuf[1024]; if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd spwd; char szPwdBuf[1024]; /* works only if /etc/shadow is accessible */ if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL) ppw->pw_passwd = spwd.sp_pwdp; char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); if (strcmp(pszEncPasswd, ppw->pw_passwd)) return VERR_AUTHENTICATION_FAILURE; *pGid = ppw->pw_gid; *pUid = ppw->pw_uid; return VINF_SUCCESS; #else NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid); return VERR_AUTHENTICATION_FAILURE; #endif }
/** * Relocates the RC address space. * * @param pUVM The user mode VM handle. * @param offDelta The relocation delta. */ void dbgfR3AsRelocate(PUVM pUVM, RTGCUINTPTR offDelta) { /* * We will relocate the raw-mode context modules by offDelta if they have * been injected into the the DBGF_AS_RC map. */ if ( pUVM->dbgf.s.afAsAliasPopuplated[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)] && offDelta != 0) { RTDBGAS hAs = pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)]; /* Take a snapshot of the modules as we might have overlapping addresses between the previous and new mapping. */ RTDbgAsLockExcl(hAs); uint32_t cModules = RTDbgAsModuleCount(hAs); if (cModules > 0 && cModules < _4K) { struct DBGFASRELOCENTRY { RTDBGMOD hDbgMod; RTRCPTR uOldAddr; } *paEntries = (struct DBGFASRELOCENTRY *)RTMemTmpAllocZ(sizeof(paEntries[0]) * cModules); if (paEntries) { /* Snapshot. */ for (uint32_t i = 0; i < cModules; i++) { paEntries[i].hDbgMod = RTDbgAsModuleByIndex(hAs, i); AssertLogRelMsg(paEntries[i].hDbgMod != NIL_RTDBGMOD, ("iModule=%#x\n", i)); RTDBGASMAPINFO aMappings[1] = { { 0, 0 } }; uint32_t cMappings = 1; int rc = RTDbgAsModuleQueryMapByIndex(hAs, i, &aMappings[0], &cMappings, 0 /*fFlags*/); if (RT_SUCCESS(rc) && cMappings == 1 && aMappings[0].iSeg == NIL_RTDBGSEGIDX) paEntries[i].uOldAddr = (RTRCPTR)aMappings[0].Address; else AssertLogRelMsgFailed(("iModule=%#x rc=%Rrc cMappings=%#x.\n", i, rc, cMappings)); } /* Unlink them. */ for (uint32_t i = 0; i < cModules; i++) { int rc = RTDbgAsModuleUnlink(hAs, paEntries[i].hDbgMod); AssertLogRelMsg(RT_SUCCESS(rc), ("iModule=%#x rc=%Rrc hDbgMod=%p\n", i, rc, paEntries[i].hDbgMod)); } /* Link them at the new locations. */ for (uint32_t i = 0; i < cModules; i++) { RTRCPTR uNewAddr = paEntries[i].uOldAddr + offDelta; int rc = RTDbgAsModuleLink(hAs, paEntries[i].hDbgMod, uNewAddr, RTDBGASLINK_FLAGS_REPLACE); AssertLogRelMsg(RT_SUCCESS(rc), ("iModule=%#x rc=%Rrc hDbgMod=%p %RRv -> %RRv\n", i, rc, paEntries[i].hDbgMod, paEntries[i].uOldAddr, uNewAddr)); RTDbgModRelease(paEntries[i].hDbgMod); } RTMemTmpFree(paEntries); } else AssertLogRelMsgFailed(("No memory for %#x modules.\n", cModules)); } else AssertLogRelMsgFailed(("cModules=%#x\n", cModules)); RTDbgAsUnlockExcl(hAs); } }
/** * Internal: Create a raw image. */ static int rawCreateImage(PRAWIMAGE pImage, uint64_t cbSize, unsigned uImageFlags, const char *pszComment, PCVDGEOMETRY pPCHSGeometry, PCVDGEOMETRY pLCHSGeometry, unsigned uOpenFlags, PFNVDPROGRESS pfnProgress, void *pvUser, unsigned uPercentStart, unsigned uPercentSpan) { int rc; RTFOFF cbFree = 0; uint64_t uOff; void *pvBuf = NULL; int32_t fOpen; uImageFlags |= VD_IMAGE_FLAGS_FIXED; pImage->uOpenFlags = uOpenFlags & ~VD_OPEN_FLAGS_READONLY; pImage->uImageFlags = uImageFlags; pImage->fCreate = true; pImage->PCHSGeometry = *pPCHSGeometry; pImage->LCHSGeometry = *pLCHSGeometry; pImage->pIfError = VDIfErrorGet(pImage->pVDIfsDisk); pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage); AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER); if (uImageFlags & VD_IMAGE_FLAGS_DIFF) { rc = vdIfError(pImage->pIfError, VERR_VD_RAW_INVALID_TYPE, RT_SRC_POS, N_("Raw: cannot create diff image '%s'"), pImage->pszFilename); goto out; } /* Create image file. */ fOpen = VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags, true /* fCreate */); if (uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL) fOpen &= ~RTFILE_O_READ; rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename, fOpen, &pImage->pStorage); if (RT_FAILURE(rc)) { rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Raw: cannot create image '%s'"), pImage->pszFilename); goto out; } if (!(uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL)) { /* Check the free space on the disk and leave early if there is not * sufficient space available. */ rc = vdIfIoIntFileGetFreeSpace(pImage->pIfIo, pImage->pszFilename, &cbFree); if (RT_SUCCESS(rc) /* ignore errors */ && ((uint64_t)cbFree < cbSize)) { rc = vdIfError(pImage->pIfError, VERR_DISK_FULL, RT_SRC_POS, N_("Raw: disk would overflow creating image '%s'"), pImage->pszFilename); goto out; } /* Allocate & commit whole file if fixed image, it must be more * effective than expanding file by write operations. */ rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, cbSize); if (RT_FAILURE(rc)) { rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Raw: setting image size failed for '%s'"), pImage->pszFilename); goto out; } /* Fill image with zeroes. We do this for every fixed-size image since * on some systems (for example Windows Vista), it takes ages to write * a block near the end of a sparse file and the guest could complain * about an ATA timeout. */ pvBuf = RTMemTmpAllocZ(RAW_FILL_SIZE); if (!pvBuf) { rc = VERR_NO_MEMORY; goto out; } uOff = 0; /* Write data to all image blocks. */ while (uOff < cbSize) { unsigned cbChunk = (unsigned)RT_MIN(cbSize, RAW_FILL_SIZE); rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, uOff, pvBuf, cbChunk, NULL); if (RT_FAILURE(rc)) { rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Raw: writing block failed for '%s'"), pImage->pszFilename); goto out; } uOff += cbChunk; if (pfnProgress) { rc = pfnProgress(pvUser, uPercentStart + uOff * uPercentSpan * 98 / (cbSize * 100)); if (RT_FAILURE(rc)) goto out; } } } if (RT_SUCCESS(rc) && pfnProgress) pfnProgress(pvUser, uPercentStart + uPercentSpan * 98 / 100); pImage->cbSize = cbSize; rc = rawFlushImage(pImage); out: if (pvBuf) RTMemTmpFree(pvBuf); if (RT_SUCCESS(rc) && pfnProgress) pfnProgress(pvUser, uPercentStart + uPercentSpan); if (RT_FAILURE(rc)) rawFreeImage(pImage, rc != VERR_ALREADY_EXISTS); return rc; }
/** * Check the credentials and return the gid/uid of user. * * @param pszUser username * @param pszPasswd password * @param gid where to store the GID of the user * @param uid where to store the UID of the user * @returns IPRT status code */ static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *pGid, uid_t *pUid) { #if defined(RT_OS_LINUX) struct passwd *pw; pw = getpwnam(pszUser); if (!pw) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd *spwd; /* works only if /etc/shadow is accessible */ spwd = getspnam(pszUser); if (spwd) pw->pw_passwd = spwd->sp_pwdp; /* Default fCorrect=true if no password specified. In that case, pw->pw_passwd * must be NULL (no password set for this user). Fail if a password is specified * but the user does not have one assigned. */ int fCorrect = !pszPasswd || !*pszPasswd; if (pw->pw_passwd && *pw->pw_passwd) { struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data)); /* be reentrant */ char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data); fCorrect = pszEncPasswd && !strcmp(pszEncPasswd, pw->pw_passwd); RTMemTmpFree(data); } if (!fCorrect) return VERR_AUTHENTICATION_FAILURE; *pGid = pw->pw_gid; *pUid = pw->pw_uid; return VINF_SUCCESS; #elif defined(RT_OS_SOLARIS) struct passwd *ppw, pw; char szBuf[1024]; if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd spwd; char szPwdBuf[1024]; /* works only if /etc/shadow is accessible */ if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL) ppw->pw_passwd = spwd.sp_pwdp; char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); if (strcmp(pszEncPasswd, ppw->pw_passwd)) return VERR_AUTHENTICATION_FAILURE; *pGid = ppw->pw_gid; *pUid = ppw->pw_uid; return VINF_SUCCESS; #else NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid); return VERR_AUTHENTICATION_FAILURE; #endif }
RTR3DECL(int) RTManifestVerifyFilesBuf(void *pvBuf, size_t cbSize, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed) { /* Validate input */ AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); AssertReturn(cbSize > 0, VERR_INVALID_PARAMETER); AssertPtrReturn(paTests, VERR_INVALID_POINTER); AssertReturn(cTests > 0, VERR_INVALID_PARAMETER); AssertPtrNullReturn(piFailed, VERR_INVALID_POINTER); int rc = VINF_SUCCESS; PRTMANIFESTFILEENTRY paFiles = (PRTMANIFESTFILEENTRY)RTMemTmpAllocZ(sizeof(RTMANIFESTFILEENTRY) * cTests); if (!paFiles) return VERR_NO_MEMORY; /* Fill our compare list */ for (size_t i = 0; i < cTests; ++i) paFiles[i].pTestPattern = &paTests[i]; char *pcBuf = (char*)pvBuf; size_t cbRead = 0; /* Parse the manifest file line by line */ for (;;) { if (cbRead >= cbSize) break; size_t cch = rtManifestIndexOfCharInBuf(pcBuf, cbSize - cbRead, '\n') + 1; /* Skip empty lines (UNIX/DOS format) */ if ( ( cch == 1 && pcBuf[0] == '\n') || ( cch == 2 && pcBuf[0] == '\r' && pcBuf[1] == '\n')) { pcBuf += cch; cbRead += cch; continue; } /** @todo r=bird: * -# Better deal with this EOF line platform dependency * -# The SHA1 and SHA256 tests should probably include a blank space check. * -# If there is a specific order to the elements in the string, it would be * good if the delimiter searching checked for it. * -# Deal with filenames containing delimiter characters. */ /* Check for the digest algorithm */ if ( cch < 4 || ( !( pcBuf[0] == 'S' && pcBuf[1] == 'H' && pcBuf[2] == 'A' && pcBuf[3] == '1') && !( pcBuf[0] == 'S' && pcBuf[1] == 'H' && pcBuf[2] == 'A' && pcBuf[3] == '2' && pcBuf[4] == '5' && pcBuf[5] == '6') ) ) { /* Digest unsupported */ rc = VERR_MANIFEST_UNSUPPORTED_DIGEST_TYPE; break; } /* Try to find the filename */ char *pszNameStart = rtManifestPosOfCharInBuf(pcBuf, cch, '('); if (!pszNameStart) { rc = VERR_MANIFEST_WRONG_FILE_FORMAT; break; } char *pszNameEnd = rtManifestPosOfCharInBuf(pcBuf, cch, ')'); if (!pszNameEnd) { rc = VERR_MANIFEST_WRONG_FILE_FORMAT; break; } /* Copy the filename part */ size_t cchName = pszNameEnd - pszNameStart - 1; char *pszName = (char *)RTMemTmpAlloc(cchName + 1); if (!pszName) { rc = VERR_NO_MEMORY; break; } memcpy(pszName, pszNameStart + 1, cchName); pszName[cchName] = '\0'; /* Try to find the digest sum */ char *pszDigestStart = rtManifestPosOfCharInBuf(pcBuf, cch, '=') + 1; if (!pszDigestStart) { RTMemTmpFree(pszName); rc = VERR_MANIFEST_WRONG_FILE_FORMAT; break; } char *pszDigestEnd = rtManifestPosOfCharInBuf(pcBuf, cch, '\r'); if (!pszDigestEnd) pszDigestEnd = rtManifestPosOfCharInBuf(pcBuf, cch, '\n'); if (!pszDigestEnd) { RTMemTmpFree(pszName); rc = VERR_MANIFEST_WRONG_FILE_FORMAT; break; } /* Copy the digest part */ size_t cchDigest = pszDigestEnd - pszDigestStart - 1; char *pszDigest = (char *)RTMemTmpAlloc(cchDigest + 1); if (!pszDigest) { RTMemTmpFree(pszName); rc = VERR_NO_MEMORY; break; } memcpy(pszDigest, pszDigestStart + 1, cchDigest); pszDigest[cchDigest] = '\0'; /* Check our file list against the extracted data */ bool fFound = false; for (size_t i = 0; i < cTests; ++i) { /** @todo r=bird: Using RTStrStr here looks bogus. */ if (RTStrStr(paFiles[i].pTestPattern->pszTestFile, RTStrStrip(pszName)) != NULL) { /* Add the data of the manifest file to the file list */ paFiles[i].pszManifestFile = RTStrDup(RTStrStrip(pszName)); paFiles[i].pszManifestDigest = RTStrDup(RTStrStrip(pszDigest)); fFound = true; break; } } RTMemTmpFree(pszName); RTMemTmpFree(pszDigest); if (!fFound) { /* There have to be an entry in the file list */ rc = VERR_MANIFEST_FILE_MISMATCH; break; } pcBuf += cch; cbRead += cch; } if ( rc == VINF_SUCCESS || rc == VERR_EOF) { rc = VINF_SUCCESS; for (size_t i = 0; i < cTests; ++i) { /* If there is an entry in the file list, which hasn't an * equivalent in the manifest file, its an error. */ if ( !paFiles[i].pszManifestFile || !paFiles[i].pszManifestDigest) { rc = VERR_MANIFEST_FILE_MISMATCH; break; } /* Do the manifest SHA digest match against the actual digest? */ if (RTStrICmp(paFiles[i].pszManifestDigest, paFiles[i].pTestPattern->pszTestDigest)) { if (piFailed) *piFailed = i; rc = VERR_MANIFEST_DIGEST_MISMATCH; break; } } } /* Cleanup */ for (size_t i = 0; i < cTests; ++i) { if (paFiles[i].pszManifestFile) RTStrFree(paFiles[i].pszManifestFile); if (paFiles[i].pszManifestDigest) RTStrFree(paFiles[i].pszManifestDigest); } RTMemTmpFree(paFiles); RTPrintf("rc = %Rrc\n", rc); return rc; }
/** * Worker for VBoxServiceGetFileVersionString. * * @returns VBox status code. * @param pszFilename ASCII & ANSI & UTF-8 compliant name. */ static int VBoxServiceGetFileVersion(const char *pszFilename, PDWORD pdwMajor, PDWORD pdwMinor, PDWORD pdwBuildNumber, PDWORD pdwRevisionNumber) { int rc; *pdwMajor = *pdwMinor = *pdwBuildNumber = *pdwRevisionNumber = 0; /* * Get the file version info. */ DWORD dwHandleIgnored; DWORD cbVerData = GetFileVersionInfoSizeA(pszFilename, &dwHandleIgnored); if (cbVerData) { LPTSTR pVerData = (LPTSTR)RTMemTmpAllocZ(cbVerData); if (pVerData) { if (GetFileVersionInfoA(pszFilename, dwHandleIgnored, cbVerData, pVerData)) { /* * Try query and parse the FileVersion string our selves first * since this will give us the correct revision number when * it goes beyond the range of an uint16_t / WORD. */ if (VBoxServiceGetFileVersionOwn(pVerData, pdwMajor, pdwMinor, pdwBuildNumber, pdwRevisionNumber)) rc = VINF_SUCCESS; else { /* Fall back on VS_FIXEDFILEINFO */ UINT cbFileInfoIgnored = 0; VS_FIXEDFILEINFO *pFileInfo = NULL; if (VerQueryValue(pVerData, "\\", (LPVOID *)&pFileInfo, &cbFileInfoIgnored)) { *pdwMajor = HIWORD(pFileInfo->dwFileVersionMS); *pdwMinor = LOWORD(pFileInfo->dwFileVersionMS); *pdwBuildNumber = HIWORD(pFileInfo->dwFileVersionLS); *pdwRevisionNumber = LOWORD(pFileInfo->dwFileVersionLS); rc = VINF_SUCCESS; } else { rc = RTErrConvertFromWin32(GetLastError()); VBoxServiceVerbose(3, "No file version value for file \"%s\" available! (%d / rc=%Rrc)\n", pszFilename, GetLastError(), rc); } } } else { rc = RTErrConvertFromWin32(GetLastError()); VBoxServiceVerbose(0, "GetFileVersionInfo(%s) -> %u / %Rrc\n", pszFilename, GetLastError(), rc); } RTMemTmpFree(pVerData); } else { VBoxServiceVerbose(0, "Failed to allocate %u byte for file version info for '%s'\n", cbVerData, pszFilename); rc = VERR_NO_TMP_MEMORY; } } else { rc = RTErrConvertFromWin32(GetLastError()); VBoxServiceVerbose(3, "GetFileVersionInfoSize(%s) -> %u / %Rrc\n", pszFilename, GetLastError(), rc); } return rc; }
static void tstObjectCreateTemp(const char *pszSubTest, const char *pszTemplate, bool fFile, RTFMODE fMode, unsigned cTimes, bool fSkipXCheck) { RTTestISub(pszSubTest); const char *pcszAPI = fFile ? "RTFileCreateTemp" : "RTDirCreateTemp"; /* Allocate the result array. */ char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *)); RTTESTI_CHECK_RETV(papszNames != NULL); /* The test loop. */ unsigned i; for (i = 0; i < cTimes; i++) { int rc; char szName[RTPATH_MAX]; RTFMODE fModeFinal; RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), pszTemplate), VINF_SUCCESS); if (RT_FAILURE(rc)) break; RTTESTI_CHECK(papszNames[i] = RTStrDup(szName)); if (!papszNames[i]) break; rc = fFile ? RTFileCreateTemp(papszNames[i], fMode) : RTDirCreateTemp(papszNames[i], fMode); if (rc != VINF_SUCCESS) { RTTestIFailed("%s(%s, %#o) call #%u -> %Rrc\n", pcszAPI, szName, (int)fMode, i, rc); RTStrFree(papszNames[i]); papszNames[i] = NULL; break; } /* Check that the final permissions are not more permissive than * the ones requested (less permissive is fine, c.f. umask etc.). * I mask out the group as I am not sure how we deal with that on * Windows. */ RTTESTI_CHECK_RC_OK(rc = RTPathGetMode(papszNames[i], &fModeFinal)); if (RT_SUCCESS(rc)) { fModeFinal &= (RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXO); RTTESTI_CHECK_MSG((fModeFinal & ~fMode) == 0, ("%s: szName %s\nfModeFinal ~= %#o, expected %#o\n", pcszAPI, szName, fModeFinal, (int)fMode)); } RTTestIPrintf(RTTESTLVL_DEBUG, "%s: %s\n", pcszAPI, papszNames[i]); RTTESTI_CHECK_MSG(strlen(szName) == strlen(papszNames[i]), ("%s: szName %s\nReturned %s\n", pcszAPI, szName, papszNames[i])); if (!fSkipXCheck) RTTESTI_CHECK_MSG(strchr(RTPathFilename(papszNames[i]), 'X') == NULL, ("%s: szName %s\nReturned %s\n", pcszAPI, szName, papszNames[i])); } /* cleanup */ while (i-- > 0) { if (fFile) RTTESTI_CHECK_RC(RTFileDelete(papszNames[i]), VINF_SUCCESS); else RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS); RTStrFree(papszNames[i]); } RTMemTmpFree(papszNames); }
RTDECL(int) RTCrStoreCertAddWantedFromFishingExpedition(RTCRSTORE hStore, uint32_t fFlags, PCRTCRCERTWANTED paWanted, size_t cWanted, bool *pafFound, PRTERRINFO pErrInfo) { int rc = VINF_SUCCESS; int rc2; /* * Validate input. */ AssertReturn(!(fFlags & ~(RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR)), VERR_INVALID_FLAGS); fFlags |= RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR; /* force these! */ AssertReturn(cWanted, VERR_NOT_FOUND); for (uint32_t i = 0; i < cWanted; i++) { AssertReturn(!paWanted[i].pszSubject || *paWanted[i].pszSubject, VERR_INVALID_PARAMETER); AssertReturn( paWanted[i].pszSubject || paWanted[i].fSha1Fingerprint || paWanted[i].fSha512Fingerprint, VERR_INVALID_PARAMETER); } /* * Make sure we've got a result array. */ bool *pafFoundFree = NULL; if (!pafFound) { pafFound = pafFoundFree = (bool *)RTMemTmpAllocZ(sizeof(bool) * cWanted); AssertReturn(pafFound, VERR_NO_TMP_MEMORY); } /* * Search the user and system stores first. */ bool fAllFound = false; RTCRSTORE hTmpStore; for (int iStoreId = RTCRSTOREID_INVALID + 1; iStoreId < RTCRSTOREID_END; iStoreId++) { rc2 = RTCrStoreCreateSnapshotById(&hTmpStore, (RTCRSTOREID)iStoreId, NULL); if (RT_SUCCESS(rc2)) { rc2 = RTCrStoreCertAddWantedFromStore(hStore, fFlags, hTmpStore, paWanted, cWanted, pafFound); RTCrStoreRelease(hTmpStore); fAllFound = rc2 == VINF_SUCCESS; if (fAllFound) break; } } /* * Search alternative file based stores. */ if (!fAllFound) { static const char * const s_apszFiles[] = { PREFIX_UNIXROOT "/usr/share/ca-certificates/trust-source/mozilla.neutral-trust.crt", PREFIX_UNIXROOT "/usr/share/ca-certificates/trust-source/mozilla.trust.crt", PREFIX_UNIXROOT "/usr/share/doc/mutt/samples/ca-bundle.crt", PREFIX_UNIXROOT "/usr/jdk/latest/jre/lib/security/cacerts", PREFIX_UNIXROOT "/usr/share/curl/curl-ca-bundle.crt", #ifdef RT_OS_DARWIN "/opt/local/share/curl/curl-ca-bundle.crt", "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts", "/System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security/cacerts", "/System/Library/Java/Support/CoreDeploy.bundle/Contents/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts", "/System/Library/Java/Support/Deploy.bundle/Contents/Home/lib/security/cacerts", "/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java/lib/security/cacerts", "/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/itms/java/lib/security/cacerts", "/Applications/Xcode-beta.app/Contents/Applications/Application Loader.app/Contents/itms/java/lib/security/cacerts", "/System/Library/Java/JavaVirtualMachines/*/Contents/Home/lib/security/cacerts", #endif #ifdef RT_OS_LINUX PREFIX_UNIXROOT "/etc/ssl/certs/java/cacerts", PREFIX_UNIXROOT "/usr/lib/j*/*/jre/lib/security/cacerts", PREFIX_UNIXROOT "/opt/*/jre/lib/security/cacerts", #endif #ifdef RT_OS_SOLARIS PREFIX_UNIXROOT "/usr/java/jre/lib/security/cacerts", PREFIX_UNIXROOT "/usr/jdk/instances/*/jre/lib/security/cacerts", #endif #ifdef RT_OS_WINDOWS "${AllProgramFiles}/Git/bin/curl-ca-bundle.crt", "${AllProgramFiles}/Mercurial/hgrc.d/cacert.pem", "${AllProgramFiles}/Java/jre*/lib/security/cacerts", "${AllProgramFiles}/Java/jdk*/jre/lib/security/cacerts", "${AllProgramFiles}/HexChat/cert.pem", "${SystemDrive}/BitNami/*/git/bin/curl-ca-bundle.crt", "${SystemDrive}/BitNami/*/heroku/data/cacert.pem", "${SystemDrive}/BitNami/*/heroku/vendor/gems/excon*/data/cacert.pem", "${SystemDrive}/BitNami/*/php/PEAR/AWSSDKforPHP/lib/requstcore/cacert.pem", #endif }; for (uint32_t i = 0; i < RT_ELEMENTS(s_apszFiles) && !fAllFound; i++) { PCRTPATHGLOBENTRY pResultHead; rc2 = RTPathGlob(s_apszFiles[i], RTPATHGLOB_F_NO_DIRS, &pResultHead, NULL); if (RT_SUCCESS(rc2)) { for (PCRTPATHGLOBENTRY pCur = pResultHead; pCur; pCur = pCur->pNext) { rc2 = RTCrStoreCertAddWantedFromFile(hStore, fFlags, pCur->szPath, paWanted, cWanted, pafFound, pErrInfo); fAllFound = rc2 == VINF_SUCCESS; if (fAllFound) break; } RTPathGlobFree(pResultHead); } } } /* * Search alternative directory based stores. */ if (!fAllFound) { static const char * const s_apszFiles[] = { PREFIX_UNIXROOT "/usr/share/ca-certificates/mozilla/", #ifdef RT_OS_DARWIN "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/ssl_certs/", #endif #ifdef RT_OS_SOLARIS "/etc/certs/", "/etc/crypto/certs/", #endif #ifdef RT_OS_WINDOWS "${AllProgramFiles}/Git/ssl/certs/", "${AllProgramFiles}/Git/ssl/certs/expired/", "${AllProgramFiles}/Common Files/Apple/Internet Services/security.resources/roots/", "${AllProgramFiles}/Raptr/ca-certs/", "${SystemDrive}/Bitname/*/git/ssl/certs/", "${SystemDrive}/Bitnami/*/git/ssl/certs/expired/", #endif }; for (uint32_t i = 0; i < RT_ELEMENTS(s_apszFiles) && !fAllFound; i++) { PCRTPATHGLOBENTRY pResultHead; rc2 = RTPathGlob(s_apszFiles[i], RTPATHGLOB_F_ONLY_DIRS, &pResultHead, NULL); if (RT_SUCCESS(rc2)) { for (PCRTPATHGLOBENTRY pCur = pResultHead; pCur; pCur = pCur->pNext) { rc2 = RTCrStoreCertAddWantedFromDir(hStore, fFlags, pCur->szPath, NULL /*paSuffixes*/, 0 /*cSuffixes*/, paWanted, cWanted, pafFound, pErrInfo); fAllFound = rc2 == VINF_SUCCESS; if (fAllFound) break; } RTPathGlobFree(pResultHead); } } } /* * If all found, return VINF_SUCCESS, otherwise warn that we didn't find everything. */ if (RT_SUCCESS(rc)) { size_t cFound = rtCrStoreCountFound(pafFound, cWanted); Assert(cFound == cWanted || !fAllFound); if (cFound == cWanted) rc = VINF_SUCCESS; else if (cFound > 0) rc = VWRN_NOT_FOUND; else rc = VERR_NOT_FOUND; } if (pafFoundFree) RTMemTmpFree(pafFoundFree); return rc; }
RTR3DECL(int) RTProcQueryUsername(RTPROCESS hProcess, char *pszUser, size_t cbUser, size_t *pcbUser) { AssertReturn( (pszUser && cbUser > 0) || (!pszUser && !cbUser), VERR_INVALID_PARAMETER); AssertReturn(pcbUser || pszUser, VERR_INVALID_PARAMETER); int rc; if ( hProcess == NIL_RTPROCESS || hProcess == RTProcSelf()) { /* * Figure a good buffer estimate. */ int32_t cbPwdMax = sysconf(_SC_GETPW_R_SIZE_MAX); if (cbPwdMax <= _1K) cbPwdMax = _1K; else AssertStmt(cbPwdMax <= 32*_1M, cbPwdMax = 32*_1M); char *pchBuf = (char *)RTMemTmpAllocZ(cbPwdMax); if (pchBuf) { /* * Get the password file entry. */ struct passwd Pwd; struct passwd *pPwd = NULL; rc = getpwuid_r(geteuid(), &Pwd, pchBuf, cbPwdMax, &pPwd); if (!rc) { /* * Convert the name to UTF-8, assuming that we're getting it in the local codeset. */ /** @todo This isn't exactly optimal... the current codeset/page conversion * stuff never was. Should optimize that for UTF-8 and ASCII one day. * And also optimize for avoiding heap. */ char *pszTmp = NULL; rc = RTStrCurrentCPToUtf8(&pszTmp, pPwd->pw_name); if (RT_SUCCESS(rc)) { size_t cbTmp = strlen(pszTmp) + 1; if (pcbUser) *pcbUser = cbTmp; if (cbTmp <= cbUser) { memcpy(pszUser, pszTmp, cbTmp); rc = VINF_SUCCESS; } else rc = VERR_BUFFER_OVERFLOW; RTStrFree(pszTmp); } } else rc = RTErrConvertFromErrno(rc); RTMemFree(pchBuf); } else rc = VERR_NO_TMP_MEMORY; } else rc = VERR_NOT_SUPPORTED; return rc; }