422 lines
11 KiB
C++
422 lines
11 KiB
C++
#include <stdio.h>
|
|
#include <windows.h>
|
|
#include <winver.h>
|
|
#include <tchar.h>
|
|
#include <ole2.h>
|
|
#include <shlobj.h>
|
|
|
|
#include <winnt.h>
|
|
#include <subauth.h>
|
|
|
|
#include <lmaccess.h>
|
|
#include <lmserver.h>
|
|
#include <lmapibuf.h>
|
|
#include <lmerr.h>
|
|
|
|
#include <basetsd.h>
|
|
|
|
#define SECURITY_WIN32
|
|
#define ISSP_LEVEL 32
|
|
#define ISSP_MODE 1
|
|
#include <sspi.h>
|
|
|
|
#include "other.h"
|
|
|
|
//#ifdef UNICODE
|
|
BOOL ValidatePassword(IN LPCWSTR UserName,IN LPCWSTR Domain,IN LPCWSTR Password)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Uses SSPI to validate the specified password
|
|
|
|
Arguments:
|
|
|
|
UserName - Supplies the user name
|
|
|
|
Domain - Supplies the user's domain
|
|
|
|
Password - Supplies the password
|
|
|
|
Return Value:
|
|
|
|
TRUE if the password is valid.
|
|
|
|
FALSE otherwise.
|
|
|
|
--*/
|
|
{
|
|
SECURITY_STATUS SecStatus;
|
|
SECURITY_STATUS AcceptStatus;
|
|
SECURITY_STATUS InitStatus;
|
|
CredHandle ClientCredHandle;
|
|
CredHandle ServerCredHandle;
|
|
BOOL ClientCredAllocated = FALSE;
|
|
BOOL ServerCredAllocated = FALSE;
|
|
CtxtHandle ClientContextHandle;
|
|
CtxtHandle ServerContextHandle;
|
|
TimeStamp Lifetime;
|
|
ULONG ContextAttributes;
|
|
PSecPkgInfo PackageInfo = NULL;
|
|
ULONG ClientFlags;
|
|
ULONG ServerFlags;
|
|
TCHAR TargetName[100];
|
|
SEC_WINNT_AUTH_IDENTITY_W AuthIdentity;
|
|
BOOL Validated = FALSE;
|
|
|
|
SecBufferDesc NegotiateDesc;
|
|
SecBuffer NegotiateBuffer;
|
|
|
|
SecBufferDesc ChallengeDesc;
|
|
SecBuffer ChallengeBuffer;
|
|
|
|
SecBufferDesc AuthenticateDesc;
|
|
SecBuffer AuthenticateBuffer;
|
|
|
|
AuthIdentity.User = (LPWSTR)UserName;
|
|
AuthIdentity.UserLength = lstrlenW(UserName);
|
|
AuthIdentity.Domain = (LPWSTR)Domain;
|
|
AuthIdentity.DomainLength = lstrlenW(Domain);
|
|
AuthIdentity.Password = (LPWSTR)Password;
|
|
AuthIdentity.PasswordLength = lstrlenW(Password);
|
|
AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
|
|
|
NegotiateBuffer.pvBuffer = NULL;
|
|
ChallengeBuffer.pvBuffer = NULL;
|
|
AuthenticateBuffer.pvBuffer = NULL;
|
|
|
|
//
|
|
// Get info about the security packages.
|
|
//
|
|
|
|
SecStatus = QuerySecurityPackageInfo( _T("NTLM"), &PackageInfo );
|
|
|
|
if ( SecStatus != STATUS_SUCCESS ) {
|
|
goto error_exit;
|
|
}
|
|
|
|
//
|
|
// Acquire a credential handle for the server side
|
|
//
|
|
SecStatus = AcquireCredentialsHandle(
|
|
NULL,
|
|
_T("NTLM"),
|
|
SECPKG_CRED_INBOUND,
|
|
NULL,
|
|
&AuthIdentity,
|
|
NULL,
|
|
NULL,
|
|
&ServerCredHandle,
|
|
&Lifetime );
|
|
|
|
if ( SecStatus != STATUS_SUCCESS ) {
|
|
goto error_exit;
|
|
}
|
|
ServerCredAllocated = TRUE;
|
|
|
|
//
|
|
// Acquire a credential handle for the client side
|
|
//
|
|
|
|
SecStatus = AcquireCredentialsHandle(
|
|
NULL, // New principal
|
|
_T("NTLM"),
|
|
SECPKG_CRED_OUTBOUND,
|
|
NULL,
|
|
&AuthIdentity,
|
|
NULL,
|
|
NULL,
|
|
&ClientCredHandle,
|
|
&Lifetime );
|
|
|
|
if ( SecStatus != STATUS_SUCCESS ) {
|
|
goto error_exit;
|
|
}
|
|
ClientCredAllocated = TRUE;
|
|
|
|
//
|
|
// Get the NegotiateMessage (ClientSide)
|
|
//
|
|
|
|
NegotiateDesc.ulVersion = 0;
|
|
NegotiateDesc.cBuffers = 1;
|
|
NegotiateDesc.pBuffers = &NegotiateBuffer;
|
|
|
|
NegotiateBuffer.cbBuffer = PackageInfo->cbMaxToken;
|
|
NegotiateBuffer.BufferType = SECBUFFER_TOKEN;
|
|
NegotiateBuffer.pvBuffer = LocalAlloc( 0, NegotiateBuffer.cbBuffer );
|
|
if ( NegotiateBuffer.pvBuffer == NULL ) {
|
|
goto error_exit;
|
|
}
|
|
|
|
ClientFlags = ISC_REQ_MUTUAL_AUTH | ISC_REQ_REPLAY_DETECT;
|
|
|
|
InitStatus = InitializeSecurityContext(
|
|
&ClientCredHandle,
|
|
NULL, // No Client context yet
|
|
NULL,
|
|
ClientFlags,
|
|
0, // Reserved 1
|
|
SECURITY_NATIVE_DREP,
|
|
NULL, // No initial input token
|
|
0, // Reserved 2
|
|
&ClientContextHandle,
|
|
&NegotiateDesc,
|
|
&ContextAttributes,
|
|
&Lifetime );
|
|
|
|
if ( !NT_SUCCESS(InitStatus) ) {
|
|
goto error_exit;
|
|
}
|
|
|
|
//
|
|
// Get the ChallengeMessage (ServerSide)
|
|
//
|
|
|
|
NegotiateBuffer.BufferType |= SECBUFFER_READONLY;
|
|
ChallengeDesc.ulVersion = 0;
|
|
ChallengeDesc.cBuffers = 1;
|
|
ChallengeDesc.pBuffers = &ChallengeBuffer;
|
|
|
|
ChallengeBuffer.cbBuffer = PackageInfo->cbMaxToken;
|
|
ChallengeBuffer.BufferType = SECBUFFER_TOKEN;
|
|
ChallengeBuffer.pvBuffer = LocalAlloc( 0, ChallengeBuffer.cbBuffer );
|
|
if ( ChallengeBuffer.pvBuffer == NULL ) {
|
|
goto error_exit;
|
|
}
|
|
ServerFlags = ASC_REQ_EXTENDED_ERROR;
|
|
|
|
AcceptStatus = AcceptSecurityContext(
|
|
&ServerCredHandle,
|
|
NULL, // No Server context yet
|
|
&NegotiateDesc,
|
|
ServerFlags,
|
|
SECURITY_NATIVE_DREP,
|
|
&ServerContextHandle,
|
|
&ChallengeDesc,
|
|
&ContextAttributes,
|
|
&Lifetime );
|
|
|
|
if ( !NT_SUCCESS(AcceptStatus) ) {
|
|
goto error_exit;
|
|
}
|
|
|
|
if (InitStatus != STATUS_SUCCESS)
|
|
{
|
|
|
|
//
|
|
// Get the AuthenticateMessage (ClientSide)
|
|
//
|
|
|
|
ChallengeBuffer.BufferType |= SECBUFFER_READONLY;
|
|
AuthenticateDesc.ulVersion = 0;
|
|
AuthenticateDesc.cBuffers = 1;
|
|
AuthenticateDesc.pBuffers = &AuthenticateBuffer;
|
|
|
|
AuthenticateBuffer.cbBuffer = PackageInfo->cbMaxToken;
|
|
AuthenticateBuffer.BufferType = SECBUFFER_TOKEN;
|
|
AuthenticateBuffer.pvBuffer = LocalAlloc( 0, AuthenticateBuffer.cbBuffer );
|
|
if ( AuthenticateBuffer.pvBuffer == NULL ) {
|
|
goto error_exit;
|
|
}
|
|
|
|
SecStatus = InitializeSecurityContext(
|
|
NULL,
|
|
&ClientContextHandle,
|
|
TargetName,
|
|
0,
|
|
0, // Reserved 1
|
|
SECURITY_NATIVE_DREP,
|
|
&ChallengeDesc,
|
|
0, // Reserved 2
|
|
&ClientContextHandle,
|
|
&AuthenticateDesc,
|
|
&ContextAttributes,
|
|
&Lifetime );
|
|
|
|
if ( !NT_SUCCESS(SecStatus) ) {
|
|
goto error_exit;
|
|
}
|
|
|
|
if (AcceptStatus != STATUS_SUCCESS) {
|
|
|
|
//
|
|
// Finally authenticate the user (ServerSide)
|
|
//
|
|
|
|
AuthenticateBuffer.BufferType |= SECBUFFER_READONLY;
|
|
|
|
SecStatus = AcceptSecurityContext(
|
|
NULL,
|
|
&ServerContextHandle,
|
|
&AuthenticateDesc,
|
|
ServerFlags,
|
|
SECURITY_NATIVE_DREP,
|
|
&ServerContextHandle,
|
|
NULL,
|
|
&ContextAttributes,
|
|
&Lifetime );
|
|
|
|
if ( !NT_SUCCESS(SecStatus) ) {
|
|
goto error_exit;
|
|
}
|
|
Validated = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
error_exit:
|
|
if (ServerCredAllocated) {
|
|
FreeCredentialsHandle( &ServerCredHandle );
|
|
}
|
|
if (ClientCredAllocated) {
|
|
FreeCredentialsHandle( &ClientCredHandle );
|
|
}
|
|
|
|
//
|
|
// Final Cleanup
|
|
//
|
|
|
|
if ( NegotiateBuffer.pvBuffer != NULL ) {
|
|
(VOID) LocalFree( NegotiateBuffer.pvBuffer );
|
|
}
|
|
|
|
if ( ChallengeBuffer.pvBuffer != NULL ) {
|
|
(VOID) LocalFree( ChallengeBuffer.pvBuffer );
|
|
}
|
|
|
|
if ( AuthenticateBuffer.pvBuffer != NULL ) {
|
|
(VOID) LocalFree( AuthenticateBuffer.pvBuffer );
|
|
}
|
|
return(Validated);
|
|
}
|
|
//#endif
|
|
|
|
BOOL IsUserExist(LPWSTR strUsername)
|
|
{
|
|
BYTE *pBuffer;
|
|
INT err = NERR_Success;
|
|
|
|
do
|
|
{
|
|
const unsigned short *pMachineName = NULL;
|
|
|
|
// make sure we are not backup docmain first
|
|
if (( err = NetServerGetInfo( NULL, 101, &pBuffer )) != NERR_Success )
|
|
{
|
|
printf("NetServerGetInfo:failed.Do not call this on PDC or BDC takes too long.This must be a PDC or BDC.");
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Check if domain controller or backup domain controller
|
|
//
|
|
LPSERVER_INFO_101 pInfo = (LPSERVER_INFO_101)pBuffer;
|
|
if (( pInfo->sv101_type & SV_TYPE_DOMAIN_BAKCTRL ) != 0 )
|
|
{
|
|
printf("Backupdomaincontroller.NetGetDCName.start.");
|
|
NetGetDCName( NULL, NULL, (LPBYTE*)&pMachineName );
|
|
printf((char*) pMachineName);
|
|
printf("NetGetDCName.end.");
|
|
}
|
|
else
|
|
{
|
|
if (( pInfo->sv101_type & SV_TYPE_DOMAIN_CTRL ) != 0 )
|
|
{
|
|
printf("Domaincontroller.NetGetDCName.start.");
|
|
NetGetDCName( NULL, NULL, (LPBYTE*)&pMachineName );
|
|
printf((char*) pMachineName);
|
|
printf("NetGetDCName.end.");
|
|
}
|
|
}
|
|
|
|
NetApiBufferFree( pBuffer );
|
|
|
|
// old for testing
|
|
/*
|
|
char buf[ CNLEN + 10 ];
|
|
DWORD dwLen = CNLEN + 10;
|
|
if ( GetComputerName( buf, &dwLen ))
|
|
{
|
|
printf((char*) buf);
|
|
pMachineName = (const unsigned short *) buf;
|
|
printf((char*) buf);
|
|
}
|
|
*/
|
|
|
|
if (pMachineName)
|
|
{
|
|
printf("MachineName="); printf((char*) pMachineName);
|
|
printf("Username="); //printf((char*) strUsername);
|
|
}
|
|
else
|
|
{
|
|
printf("MachineName=(null)");
|
|
printf("Username="); //printf((char*) strUsername);
|
|
}
|
|
|
|
printf("\n");
|
|
err = NetUserGetInfo( pMachineName, strUsername, 3, &pBuffer );
|
|
char szTheError[255];
|
|
sprintf(szTheError, "TheErrCode=0x%x\n",err);
|
|
printf(szTheError);
|
|
if (err == ERROR_ACCESS_DENIED)
|
|
{
|
|
printf("ERROR_ACCESS_DENIED.The user does not have access to the requested information. \n");
|
|
printf("\n");
|
|
}
|
|
if (err == NERR_InvalidComputer)
|
|
{
|
|
printf("ERROR_ACCESS_DENIED.The computer name is invalid.\n");
|
|
printf("\n");
|
|
}
|
|
if (err == NERR_UserNotFound)
|
|
{
|
|
printf("NERR_UserNotFound.The user name could not be found.\n");
|
|
printf("\n");
|
|
}
|
|
|
|
//if (pMachineName){iisDebugOut((_T("NetUserGetInfo:[%s\\%s].End.Ret=0x%x.\n"),pMachineName,strUsername,err));}
|
|
//else{iisDebugOut((_T("NetUserGetInfo:[(null)\\%s].End.\n"),strUsername));}
|
|
|
|
if ( err == NERR_Success ){NetApiBufferFree( pBuffer );}
|
|
if ( pMachineName != NULL ){NetApiBufferFree( (void*) pMachineName );}
|
|
|
|
} while (FALSE);
|
|
|
|
if (err == NERR_Success )
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DoStuff99(LPCTSTR lpUserName)
|
|
{
|
|
//printf("DoStuff99.Start.\n");
|
|
WCHAR wchUsername[UNLEN+1];
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpUserName, -1, (LPWSTR)wchUsername, UNLEN);
|
|
|
|
//if (TRUE == IsUserExist((const unsigned short *) lpUserName))
|
|
if (TRUE == IsUserExist(wchUsername))
|
|
{
|
|
printf("IsUserExist.TRUE.\n");
|
|
}
|
|
else
|
|
{
|
|
printf("IsUserExist.FAILED.\n");
|
|
}
|
|
|
|
//printf("DoStuff99.End.\n");
|
|
return;
|
|
}
|
|
|