📄 credapi.cxx
字号:
//
// Effects: Unlinks the credential from the global list and the list
// for this client.
//
// Arguments: CredentialHandle - Handle to the credential to free
// (acquired through AcquireCredentialsHandle)
//
// Requires:
//
// Returns: STATUS_SUCCESS on success,
// SEC_E_INVALID_HANDLE if the handle is not valid
//
// Notes:
//
//
//--------------------------------------------------------------------------
NTSTATUS NTAPI
SpFreeCredentialsHandle(
IN ULONG_PTR CredentialHandle
)
{
SspPrint((SSP_API, "Entering SpFreeCredentialsHandle\n"));
NTSTATUS Status = STATUS_SUCCESS;
PSSP_CREDENTIAL Credential;
// BUGBUG Check args specific to NTLM
//
// Find the referenced credential and delink it.
//
Status = SspCredentialReferenceCredential(
CredentialHandle,
TRUE, // remove the instance of the credential
FALSE,
&Credential );
if ( !NT_SUCCESS( Status ) ) {
SspPrint((SSP_CRITICAL, "SpFreeCredentialsHandle, Error from SspCredentialReferenceCredential is 0x%lx\n", Status));
goto Cleanup;
}
//
// Dereferencing the Credential will remove the client's reference
// to it, causing it to be rundown if nobody else is using it.
//
SspCredentialDereferenceCredential( Credential );
Cleanup:
//
// Catch spurious INVALID_HANDLE being returned to RPC.
//
ASSERT( (Status != STATUS_INVALID_HANDLE) );
SspPrint((SSP_API, "Leaving SpFreeCredentialsHandle\n"));
return(SspNtStatusToSecStatus(Status, SEC_E_INTERNAL_ERROR));
}
NTSTATUS NTAPI
SpQueryCredentialsAttributes(
IN LSA_SEC_HANDLE CredentialHandle,
IN ULONG CredentialAttribute,
IN OUT PVOID Buffer
)
{
PSSP_CREDENTIAL Credential = NULL;
SecPkgCredentials_NamesW Names;
LUID LogonId;
BOOLEAN ActiveLogonsAreLocked = FALSE;
LPWSTR ContextNames = NULL;
LPWSTR Where;
LPWSTR UserName = NULL;
LPWSTR DomainName = NULL;
DWORD cchUserName;
DWORD cchDomainName;
ULONG Length;
BOOLEAN CalledLsaLookup = FALSE;
PLSAPR_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL;
LSAPR_TRANSLATED_NAMES ReferencedUser;
NTSTATUS Status = STATUS_SUCCESS;
SspPrint((SSP_API,"In SpQueryCredentialsAttributes\n"));
Names.sUserName = NULL;
if (CredentialAttribute != SECPKG_CRED_ATTR_NAMES)
{
SspPrint((SSP_MISC, "Asked for illegal info level in QueryCredAttr: %d\n",
CredentialAttribute));
Status = STATUS_INVALID_PARAMETER;
goto Cleanup;
}
Status = SspCredentialReferenceCredential(
CredentialHandle,
FALSE,
FALSE,
&Credential );
if ( !NT_SUCCESS( Status ) ) {
SspPrint((SSP_CRITICAL, "SpQueryCredentialsAttributes, Error from SspCredentialReferenceCredential is 0x%lx\n", Status));
goto Cleanup;
}
//
// The logon id of the credential is constant, so it is o.k.
// to use it without locking the credential
//
LogonId = Credential->LogonId;
//
// credentials were either specified when cred built, or, they were defaulted.
//
if( Credential->UserName.Buffer == NULL &&
Credential->DomainName.Buffer == NULL )
{
PACTIVE_LOGON *ActiveLogon, Logon = NULL;
//
// defaulted creds: pickup info from active logon table.
//
NlpLockActiveLogons();
ActiveLogonsAreLocked = TRUE;
if (NlpFindActiveLogon (
&LogonId,
&ActiveLogon))
{
//
// found an active logon entry.
//
Logon = *ActiveLogon;
UserName = Logon->UserName.Buffer;
cchUserName = Logon->UserName.Length / sizeof(WCHAR);
DomainName = Logon->LogonDomainName.Buffer;
cchDomainName = Logon->LogonDomainName.Length / sizeof(WCHAR);
} else {
PTOKEN_USER pTokenInfo;
BYTE FastBuffer[ 256 ];
DWORD cbTokenInfo;
SID_NAME_USE snu;
BOOL fSuccess = FALSE;
NlpUnlockActiveLogons();
ActiveLogonsAreLocked = FALSE;
//
// get Sid associated with credential.
//
cbTokenInfo = sizeof(FastBuffer);
pTokenInfo = (PTOKEN_USER)FastBuffer;
fSuccess = GetTokenInformation(
Credential->ClientTokenHandle,
TokenUser,
pTokenInfo,
cbTokenInfo,
&cbTokenInfo
);
if( fSuccess ) {
LSAPR_SID_ENUM_BUFFER SidEnumBuffer;
LSAPR_SID_INFORMATION SidInfo;
ULONG MappedCount;
SidEnumBuffer.Entries = 1;
SidEnumBuffer.SidInfo = &SidInfo;
SidInfo.Sid = (LSAPR_SID*)pTokenInfo->User.Sid;
if ( !NlpSamInitialized ) {
Status = NlSamInitialize( SAM_STARTUP_TIME );
} else {
Status = STATUS_SUCCESS;
}
if ( NT_SUCCESS(Status) ) {
ZeroMemory( &ReferencedUser, sizeof(ReferencedUser) );
CalledLsaLookup = TRUE;
Status = LsarLookupSids(
NlpPolicyHandle,
&SidEnumBuffer,
&ReferencedDomain,
&ReferencedUser,
LsapLookupWksta,
&MappedCount
);
}
if( !NT_SUCCESS( Status ) ||
(MappedCount == 0) ||
(ReferencedUser.Entries == 0) ||
(ReferencedDomain == NULL) ||
(ReferencedDomain->Entries == 0)
) {
fSuccess = FALSE;
} else {
LONG Index = ReferencedUser.Names->DomainIndex;
UserName = ReferencedUser.Names->Name.Buffer;
cchUserName = ReferencedUser.Names->Name.Length / sizeof(WCHAR);
DomainName = ReferencedDomain->Domains[Index].Name.Buffer;
cchDomainName = ReferencedDomain->Domains[Index].Name.Length / sizeof(WCHAR);
}
}
if( !fSuccess )
{
Status = STATUS_NO_SUCH_LOGON_SESSION;
SspPrint(( SSP_CRITICAL, "SpQueryCredentialsAtributes, NlpFindActiveLogon returns FALSE\n"));
goto Cleanup;
}
}
} else {
//
// specified creds.
//
UserName = Credential->UserName.Buffer;
cchUserName = Credential->UserName.Length / sizeof(WCHAR);
DomainName = Credential->DomainName.Buffer;
cchDomainName = Credential->DomainName.Length / sizeof(WCHAR);
}
Length = (cchUserName + 1 + cchDomainName + 1) * sizeof(WCHAR);
ContextNames = (LPWSTR)NtLmAllocate( Length );
if( ContextNames == NULL ) {
goto Cleanup;
}
Where = ContextNames;
if( DomainName) {
RtlCopyMemory( ContextNames, DomainName, cchDomainName * sizeof(WCHAR) );
ContextNames[ cchDomainName ] = L'\\';
Where += (cchDomainName+1);
}
if( UserName ) {
RtlCopyMemory( Where, UserName, cchUserName * sizeof(WCHAR) );
}
Where[ cchUserName ] = L'\0';
if (ActiveLogonsAreLocked)
{
NlpUnlockActiveLogons();
ActiveLogonsAreLocked = FALSE;
}
//
// Allocate memory in the client's address space
//
Status = LsaFunctions->AllocateClientBuffer(
NULL,
Length,
(PVOID *) &Names.sUserName
);
if (!NT_SUCCESS(Status))
{
goto Cleanup;
}
//
// Copy the string there
//
Status = LsaFunctions->CopyToClientBuffer(
NULL,
Length,
Names.sUserName,
ContextNames
);
if (!NT_SUCCESS(Status))
{
goto Cleanup;
}
//
// Now copy the address of the string there
//
Status = LsaFunctions->CopyToClientBuffer(
NULL,
sizeof(Names),
Buffer,
&Names
);
if (!NT_SUCCESS(Status))
{
goto Cleanup;
}
Cleanup:
if (ActiveLogonsAreLocked)
{
NlpUnlockActiveLogons();
}
if( Credential != NULL ) {
SspCredentialDereferenceCredential( Credential );
}
if( CalledLsaLookup ) {
if( ReferencedDomain ) {
LsaIFree_LSAPR_REFERENCED_DOMAIN_LIST( ReferencedDomain );
}
LsaIFree_LSAPR_TRANSLATED_NAMES( &ReferencedUser );
}
if (!NT_SUCCESS(Status))
{
if (Names.sUserName != NULL)
{
(VOID) LsaFunctions->FreeClientBuffer(
NULL,
Names.sUserName
);
}
}
if( ContextNames ) {
NtLmFree( ContextNames );
}
SspPrint((SSP_API, "Leaving SpQueryCredentialsAttributes\n"));
return(SspNtStatusToSecStatus(Status, SEC_E_INTERNAL_ERROR));
}
NTSTATUS NTAPI
SpSaveCredentials(
IN ULONG_PTR CredentialHandle,
IN PSecBuffer Credentials
)
{
UNREFERENCED_PARAMETER(CredentialHandle);
UNREFERENCED_PARAMETER(Credentials);
SspPrint((SSP_API,"In SpSaveCredentials\n"));
return(SEC_E_UNSUPPORTED_FUNCTION);
}
NTSTATUS NTAPI
SpGetCredentials(
IN ULONG_PTR CredentialHandle,
IN OUT PSecBuffer Credentials
)
{
UNREFERENCED_PARAMETER(CredentialHandle);
UNREFERENCED_PARAMETER(Credentials);
SspPrint((SSP_API,"In SpGetCredentials\n"));
return(SEC_E_UNSUPPORTED_FUNCTION);
}
NTSTATUS NTAPI
SpDeleteCredentials(
IN ULONG_PTR CredentialHandle,
IN PSecBuffer Key
)
{
UNREFERENCED_PARAMETER(CredentialHandle);
UNREFERENCED_PARAMETER(Key);
SspPrint((SSP_API,"In SpDeleteCredentials\n"));
return(SEC_E_UNSUPPORTED_FUNCTION);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -