Skip to content

Commit 805c0e1

Browse files
committed
Base: resort to more drastic means to query profile directory
The profile directory for another user is considered private data and cannot be directly queried without an elevated privilege, the user's password, or a token with impersonation rights. Resort to trawling through the registry to query the information.
1 parent a1c25ff commit 805c0e1

File tree

1 file changed

+69
-17
lines changed

1 file changed

+69
-17
lines changed

CoreFoundation/Base.subproj/CFPlatform.c

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727

2828
#if TARGET_OS_WIN32
2929
#include <lm.h>
30+
#include <sddl.h>
3031
#include <shellapi.h>
3132
#include <shlobj.h>
33+
#include <shlwapi.h>
3234
#include <WinIoCtl.h>
3335
#include <direct.h>
3436
#include <process.h>
@@ -582,26 +584,76 @@ CF_EXPORT CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName) {
582584
return CFCopyHomeDirectoryURL();
583585
}
584586

585-
CFIndex ulLength = CFStringGetLength(uName);
587+
static const wchar_t * const kProfileListPath =
588+
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\";
589+
static const wchar_t * const kProfileImagePath = L"ProfileImagePath";
590+
591+
CFURLRef url = NULL;
586592

587-
UniChar *buffer = calloc(ulLength + 1, sizeof(UniChar));
588-
if (buffer == NULL)
593+
CFIndex ulLength = CFStringGetLength(uName);
594+
UniChar *pwszUserName =
595+
CFAllocatorAllocate(kCFAllocatorSystemDefault,
596+
(ulLength + 1) * sizeof(UniChar), 0);
597+
if (pwszUserName == NULL)
589598
return NULL;
590-
CFStringGetCharacters(uName, CFRangeMake(0, ulLength), buffer);
591599

592-
CFURLRef url = NULL;
593-
LPUSER_INFO_1 lpUI1 = NULL;
594-
if (NetUserGetInfo(NULL, buffer, 1, (LPBYTE*)&lpUI1) == NERR_Success) {
595-
CFStringRef path =
596-
CFStringCreateWithCharacters(kCFAllocatorSystemDefault,
597-
lpUI1->usri1_home_dir,
598-
wcslen(lpUI1->usri1_home_dir));
599-
url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path,
600-
kCFURLWindowsPathStyle, true);
601-
CFRelease(path);
602-
NetApiBufferFree(lpUI1);
603-
}
604-
free(buffer);
600+
CFStringGetCharacters(uName, CFRangeMake(0, ulLength), pwszUserName);
601+
pwszUserName[ulLength] = L'\0';
602+
603+
DWORD cbSID = 0;
604+
DWORD cchReferencedDomainName = 0;
605+
SID_NAME_USE eUse;
606+
LookupAccountNameW(NULL, pwszUserName, NULL, &cbSID, NULL,
607+
&cchReferencedDomainName, &eUse);
608+
609+
LPBYTE pSID = CFAllocatorAllocate(kCFAllocatorSystemDefault, cbSID, 0);
610+
LPWSTR pwszReferencedDomainName =
611+
CFAllocatorAllocate(kCFAllocatorSystemDefault,
612+
(cchReferencedDomainName + 1) * sizeof(UniChar), 0);
613+
614+
if (LookupAccountNameW(NULL, pwszUserName, pSID, &cbSID,
615+
pwszReferencedDomainName, &cchReferencedDomainName,
616+
&eUse)) {
617+
LPWSTR pwszSID;
618+
619+
if (ConvertSidToStringSidW(pSID, &pwszSID)) {
620+
DWORD cchBuffer = wcslen(kProfileListPath) + wcslen(pwszSID) + 1;
621+
PWSTR pwszKeyPath =
622+
CFAllocatorAllocate(kCFAllocatorSystemDefault,
623+
cchBuffer * sizeof(UniChar), 0);
624+
625+
DWORD dwOffset =
626+
StrCatChainW(pwszKeyPath, cchBuffer, 0, kProfileListPath);
627+
StrCatChainW(pwszKeyPath, cchBuffer, dwOffset, pwszSID);
628+
629+
DWORD cbData = 0;
630+
RegGetValueW(HKEY_LOCAL_MACHINE, pwszKeyPath, kProfileImagePath,
631+
RRF_RT_REG_SZ, NULL, NULL, &cbData);
632+
633+
LPWSTR pwszProfileImagePath =
634+
CFAllocatorAllocate(kCFAllocatorSystemDefault, cbData, 0);
635+
RegGetValueW(HKEY_LOCAL_MACHINE, pwszKeyPath, kProfileImagePath,
636+
RRF_RT_REG_SZ, NULL, pwszProfileImagePath, &cbData);
637+
638+
CFStringRef profile =
639+
CFStringCreateWithCharacters(kCFAllocatorSystemDefault,
640+
pwszProfileImagePath,
641+
cbData / sizeof(wchar_t));
642+
643+
url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault,
644+
profile, kCFURLWindowsPathStyle,
645+
true);
646+
CFRelease(profile);
647+
CFAllocatorDeallocate(kCFAllocatorSystemDefault, pwszProfileImagePath);
648+
CFAllocatorDeallocate(kCFAllocatorSystemDefault, pwszKeyPath);
649+
}
650+
651+
LocalFree(pwszSID);
652+
}
653+
654+
CFAllocatorDeallocate(kCFAllocatorSystemDefault, pwszReferencedDomainName);
655+
CFAllocatorDeallocate(kCFAllocatorSystemDefault, pSID);
656+
CFAllocatorDeallocate(kCFAllocatorSystemDefault, pwszUserName);
605657

606658
return url;
607659
#else

0 commit comments

Comments
 (0)