BOOL readOnly;
};
+static WINPR_SAM_ENTRY* SamEntryFromDataA(LPCSTR User, DWORD UserLength, LPCSTR Domain,
+ DWORD DomainLength)
+{
+ WINPR_SAM_ENTRY* entry = calloc(1, sizeof(WINPR_SAM_ENTRY));
+ if (!entry)
+ return NULL;
+ entry->User = _strdup(User);
+ entry->UserLength = UserLength;
+ entry->Domain = _strdup(Domain);
+ entry->DomainLength = DomainLength;
+ return entry;
+}
+
+static BOOL SamAreEntriesEqual(const WINPR_SAM_ENTRY* a, const WINPR_SAM_ENTRY* b)
+{
+ if (!a || !b)
+ return FALSE;
+ if (a->UserLength != b->UserLength)
+ return FALSE;
+ if (a->DomainLength != b->DomainLength)
+ return FALSE;
+ if (strncmp(a->User, b->User, a->UserLength) != 0)
+ return FALSE;
+ if (strncmp(a->Domain, b->Domain, a->DomainLength) != 0)
+ return FALSE;
+ return TRUE;
+}
+
WINPR_SAM* SamOpen(const char* filename, BOOL readOnly)
{
FILE* fp = NULL;
if (fp)
{
- sam = (WINPR_SAM*)malloc(sizeof(WINPR_SAM));
+ sam = (WINPR_SAM*)calloc(1, sizeof(WINPR_SAM));
if (!sam)
{
return FALSE;
sam->context = NULL;
- sam->buffer = (char*)malloc(fileSize + 2);
+ sam->buffer = (char*)calloc(fileSize + 2, 1);
if (!sam->buffer)
return FALSE;
sam->line = NULL;
}
-static void HexStrToBin(char* str, BYTE* bin, int length)
+static void HexStrToBin(const char* str, BYTE* bin, size_t length)
{
- int i;
+ size_t i;
CharUpperBuffA(str, length * 2);
for (i = 0; i < length; i++)
{
size_t length;
BOOL found = FALSE;
- WINPR_SAM_ENTRY* entry;
- entry = (WINPR_SAM_ENTRY*)calloc(1, sizeof(WINPR_SAM_ENTRY));
+ WINPR_SAM_ENTRY* search = SamEntryFromDataA(User, UserLength, Domain, DomainLength);
+ WINPR_SAM_ENTRY* entry = (WINPR_SAM_ENTRY*)calloc(1, sizeof(WINPR_SAM_ENTRY));
- if (!entry)
- return NULL;
+ if (!entry || !search)
+ goto fail;
if (!SamLookupStart(sam))
- {
- free(entry);
- return NULL;
- }
+ goto fail;
while (sam->line != NULL)
{
goto out_fail;
}
- if (strcmp(User, entry->User) == 0)
+ if (SamAreEntriesEqual(entry, search))
{
found = 1;
break;
out_fail:
SamLookupFinish(sam);
+fail:
+ SamFreeEntry(sam, search);
if (!found)
{
- free(entry);
+ SamFreeEntry(sam, entry);
return NULL;
}
WINPR_SAM_ENTRY* SamLookupUserW(WINPR_SAM* sam, LPWSTR User, UINT32 UserLength, LPWSTR Domain,
UINT32 DomainLength)
{
- size_t length;
- BOOL Found = FALSE;
- BOOL UserMatch;
- BOOL DomainMatch;
- LPWSTR EntryUser = NULL;
- UINT32 EntryUserLength;
- LPWSTR EntryDomain = NULL;
- UINT32 EntryDomainLength;
- WINPR_SAM_ENTRY* entry;
-
- if (!(entry = (WINPR_SAM_ENTRY*)calloc(1, sizeof(WINPR_SAM_ENTRY))))
- return NULL;
-
- if (!SamLookupStart(sam))
- {
- free(entry);
- return NULL;
- }
-
- while (sam->line != NULL)
- {
- length = strlen(sam->line);
-
- if (length > 1)
- {
- if (sam->line[0] != '#')
- {
- DomainMatch = 0;
- UserMatch = 0;
-
- if (!SamReadEntry(sam, entry))
- goto out_fail;
-
- if (DomainLength > 0)
- {
- if (entry->DomainLength > 0)
- {
- EntryDomainLength = (UINT32)strlen(entry->Domain) * 2;
- EntryDomain = (LPWSTR)malloc(EntryDomainLength + 2);
-
- if (!EntryDomain)
- goto out_fail;
-
- MultiByteToWideChar(CP_ACP, 0, entry->Domain, EntryDomainLength / 2,
- (LPWSTR)EntryDomain, EntryDomainLength / 2);
-
- if (DomainLength == EntryDomainLength)
- {
- if (memcmp(Domain, EntryDomain, DomainLength) == 0)
- {
- DomainMatch = 1;
- }
- }
-
- free(EntryDomain);
- }
- else
- {
- DomainMatch = 0;
- }
- }
- else
- {
- DomainMatch = 1;
- }
-
- if (DomainMatch)
- {
- EntryUserLength = (UINT32)strlen(entry->User) * 2;
- EntryUser = (LPWSTR)malloc(EntryUserLength + 2);
-
- if (!EntryUser)
- goto out_fail;
-
- MultiByteToWideChar(CP_ACP, 0, entry->User, EntryUserLength / 2,
- (LPWSTR)EntryUser, EntryUserLength / 2);
-
- if (UserLength == EntryUserLength)
- {
- if (memcmp(User, EntryUser, UserLength) == 0)
- {
- UserMatch = 1;
- }
- }
-
- free(EntryUser);
-
- if (UserMatch)
- {
- Found = TRUE;
- break;
- }
- }
- }
- }
-
- SamResetEntry(entry);
- sam->line = strtok_s(NULL, "\n", &sam->context);
- }
-
-out_fail:
- SamLookupFinish(sam);
-
- if (!Found)
- {
- free(entry);
- return NULL;
- }
-
+ int rc;
+ WINPR_SAM_ENTRY* entry = NULL;
+ char* utfUser = NULL;
+ char* utfDomain = NULL;
+ const size_t UserCharLength = UserLength / sizeof(WCHAR);
+ const size_t DomainCharLength = DomainLength / sizeof(WCHAR);
+
+ rc = ConvertFromUnicode(CP_UTF8, 0, User, UserCharLength, &utfUser, 0, NULL, NULL);
+ if ((rc < 0) || ((size_t)rc != UserCharLength))
+ goto fail;
+ rc = ConvertFromUnicode(CP_UTF8, 0, Domain, DomainCharLength, &utfDomain, 0, NULL, NULL);
+ if ((rc < 0) || ((size_t)rc != DomainCharLength))
+ goto fail;
+ entry = SamLookupUserA(sam, utfUser, UserCharLength, utfDomain, DomainCharLength);
+fail:
+ free(utfUser);
+ free(utfDomain);
return entry;
}