//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1997. // // File: pwdssp.c // // Contents: // // Classes: // // Functions: // // History: 9-07-97 RichardW Created // //---------------------------------------------------------------------------- #include "pwdsspp.h" typedef struct _PWD_CRED { DWORD Ref; } PWD_CRED, * PPWD_CRED; typedef struct _PWD_CONTEXT { DWORD Tag; HANDLE Token; } PWD_CONTEXT, *PPWD_CONTEXT ; PWD_CRED PwdGlobalAnsi; PWD_CRED PwdGlobalUnicode; #define CONTEXT_TAG 'txtC' #define ANONYMOUS_TOKEN ((HANDLE) 1) SecPkgInfoA PwdInfoA = { SECPKG_FLAG_CONNECTION | SECPKG_FLAG_ACCEPT_WIN32_NAME, 1, (WORD) -1, 768, PWDSSP_NAME_A, "Microsoft Clear Text Password Security Provider" }; SecPkgInfoW PwdInfoW = { SECPKG_FLAG_CONNECTION | SECPKG_FLAG_ACCEPT_WIN32_NAME, 1, (WORD) -1, 768, PWDSSP_NAME_W, L"Microsoft Clear Text Password Security Provider" }; SecurityFunctionTableA PwdTableA = { SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION, EnumerateSecurityPackagesA, NULL, AcquireCredentialsHandleA, FreeCredentialsHandle, NULL, InitializeSecurityContextA, AcceptSecurityContext, CompleteAuthToken, DeleteSecurityContext, ApplyControlToken, QueryContextAttributesA, ImpersonateSecurityContext, RevertSecurityContext, MakeSignature, VerifySignature, FreeContextBuffer, QuerySecurityPackageInfoA, NULL, NULL, NULL, NULL, NULL, NULL, QuerySecurityContextToken }; SecurityFunctionTableW PwdTableW = { SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION, EnumerateSecurityPackagesW, NULL, AcquireCredentialsHandleW, FreeCredentialsHandle, NULL, InitializeSecurityContextW, AcceptSecurityContext, CompleteAuthToken, DeleteSecurityContext, ApplyControlToken, QueryContextAttributesW, ImpersonateSecurityContext, RevertSecurityContext, MakeSignature, VerifySignature, FreeContextBuffer, QuerySecurityPackageInfoW, NULL, NULL, NULL, NULL, NULL, NULL, QuerySecurityContextToken }; //#define PwdAlloc(x) LsaIAllocateHeap(x) //#define PwdFree(x) LsaIFreeHeap(x) #define PwdAlloc(x) LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT,x) #define PwdFree(x) LocalFree(x) NTSTATUS VerifyCredentials( IN PWSTR UserName, IN PWSTR DomainName, IN PWSTR Password, IN ULONG VerifyFlags ); UNICODE_STRING AuthenticationPackage; //+--------------------------------------------------------------------------- // // Function: DllMain // // Synopsis: Entry point // // Arguments: [hInstance] -- // [dwReason] -- // [lpReserved] -- // // Notes: // //---------------------------------------------------------------------------- BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls( hInstance ); RtlInitUnicodeString(&AuthenticationPackage, MICROSOFT_KERBEROS_NAME_W); if ( !CacheInitialize() ) { return FALSE; } } return(TRUE); } //+--------------------------------------------------------------------------- // // Function: PwdpParseBuffers // // Synopsis: Parse out right buffer descriptor // // Arguments: [pMessage] -- // [pToken] -- // [pEmpty] -- // // Notes: // //---------------------------------------------------------------------------- VOID PwdpParseBuffers( PSecBufferDesc pMessage, PSecBuffer * pToken, PSecBuffer * pEmpty) { ULONG i; PSecBuffer pFirstBlank = NULL; PSecBuffer pWholeMessage = NULL; for (i = 0 ; i < pMessage->cBuffers ; i++ ) { if ( (pMessage->pBuffers[i].BufferType & (~SECBUFFER_ATTRMASK)) == SECBUFFER_TOKEN ) { pWholeMessage = &pMessage->pBuffers[i]; if (pFirstBlank) { break; } } else if ( (pMessage->pBuffers[i].BufferType & (~SECBUFFER_ATTRMASK)) == SECBUFFER_EMPTY ) { pFirstBlank = &pMessage->pBuffers[i]; if (pWholeMessage) { break; } } } if (pToken) { *pToken = pWholeMessage; } if (pEmpty) { *pEmpty = pFirstBlank; } } //+--------------------------------------------------------------------------- // // Function: AcquireCredentialsHandleW // // Synopsis: Get the credential handle // // Arguments: [pszPrincipal] -- // [pszPackageName] -- // [fCredentialUse] -- // [pvLogonId] -- // [pAuthData] -- // [pGetKeyFn] -- // [GetKey] -- // [pvGetKeyArgument] -- // [GetKey] -- // [phCredential] -- // [PTimeStamp] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleW( SEC_WCHAR SEC_FAR * pszPrincipal, // Name of principal SEC_WCHAR SEC_FAR * pszPackageName, // Name of package unsigned long fCredentialUse, // Flags indicating use void SEC_FAR * pvLogonId, // Pointer to logon ID void SEC_FAR * pAuthData, // Package specific data SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func void SEC_FAR * pvGetKeyArgument, // Value to pass to GetKey() PCredHandle phCredential, // (out) Cred Handle PTimeStamp ptsExpiry // (out) Lifetime (optional) ) { if (_wcsicmp(pszPackageName, PWDSSP_NAME_W)) { return( SEC_E_SECPKG_NOT_FOUND ); } if ( fCredentialUse & SECPKG_CRED_OUTBOUND ) { return( SEC_E_NO_CREDENTIALS ); } InterlockedIncrement( &PwdGlobalUnicode.Ref ); phCredential->dwUpper = (ULONG_PTR) &PwdGlobalUnicode ; if ( ptsExpiry ) { ptsExpiry->LowPart = (DWORD) 0xFFFFFFFF; ptsExpiry->HighPart = (DWORD) 0x7FFFFFFF; } return( SEC_E_OK ); } //+--------------------------------------------------------------------------- // // Function: AcquireCredentialsHandleA // // Synopsis: ANSI entry // // Arguments: [pszPrincipal] -- // [pszPackageName] -- // [fCredentialUse] -- // [pvLogonId] -- // [pAuthData] -- // [pGetKeyFn] -- // [GetKey] -- // [pvGetKeyArgument] -- // [GetKey] -- // [phCredential] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleA( SEC_CHAR SEC_FAR * pszPrincipal, // Name of principal SEC_CHAR SEC_FAR * pszPackageName, // Name of package unsigned long fCredentialUse, // Flags indicating use void SEC_FAR * pvLogonId, // Pointer to logon ID void SEC_FAR * pAuthData, // Package specific data SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func void SEC_FAR * pvGetKeyArgument, // Value to pass to GetKey() PCredHandle phCredential, // (out) Cred Handle PTimeStamp ptsExpiry // (out) Lifetime (optional) ) { if (_stricmp(pszPackageName, PWDSSP_NAME_A)) { return( SEC_E_SECPKG_NOT_FOUND ); } if ( fCredentialUse & SECPKG_CRED_OUTBOUND ) { return( SEC_E_NO_CREDENTIALS ); } InterlockedIncrement( &PwdGlobalAnsi.Ref ); phCredential->dwUpper = (ULONG_PTR) &PwdGlobalAnsi ; if ( ptsExpiry ) { ptsExpiry->LowPart = (DWORD) 0xFFFFFFFF; ptsExpiry->HighPart = (DWORD) 0x7FFFFFFF; } return(SEC_E_OK); } //+--------------------------------------------------------------------------- // // Function: FreeCredentialHandle // // Synopsis: Free a credential handle // // Arguments: [free] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY FreeCredentialsHandle( PCredHandle phCredential // Handle to free ) { PPWD_CRED Cred; if ( (phCredential->dwUpper != (ULONG_PTR) &PwdGlobalAnsi ) && (phCredential->dwUpper != (ULONG_PTR) &PwdGlobalUnicode ) ) { return( SEC_E_INVALID_HANDLE ); } Cred = (PPWD_CRED) phCredential->dwUpper ; InterlockedDecrement( &Cred->Ref ); return( SEC_E_OK ); } //+--------------------------------------------------------------------------- // // Function: InitializeSecurityContextW // // Synopsis: Initialize a security context (outbound) NOT SUPPORTED // // Arguments: [phCredential] -- // [phContext] -- // [pszTargetName] -- // [fContextReq] -- // [Reserved1] -- // [Reserved] -- // [TargetDataRep] -- // [pInput] -- // [Reserved2] -- // [Reserved] -- // [phNewContext] -- // [pOutput] -- // [pfContextAttr] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY InitializeSecurityContextW( PCredHandle phCredential, // Cred to base context PCtxtHandle phContext, // Existing context (OPT) SEC_WCHAR SEC_FAR * pszTargetName, // Name of target unsigned long fContextReq, // Context Requirements unsigned long Reserved1, // Reserved, MBZ unsigned long TargetDataRep, // Data rep of target PSecBufferDesc pInput, // Input Buffers unsigned long Reserved2, // Reserved, MBZ PCtxtHandle phNewContext, // (out) New Context handle PSecBufferDesc pOutput, // (inout) Output Buffers unsigned long SEC_FAR * pfContextAttr, // (out) Context attrs PTimeStamp ptsExpiry // (out) Life span (OPT) ) { return( SEC_E_UNSUPPORTED_FUNCTION ); } //+--------------------------------------------------------------------------- // // Function: InitializeSecurityContextA // // Synopsis: NOT SUPPORTED // // Arguments: [phCredential] -- // [phContext] -- // [pszTargetName] -- // [fContextReq] -- // [Reserved1] -- // [TargetDataRep] -- // [pInput] -- // [Reserved2] -- // [phNewContext] -- // [pOutput] -- // [pfContextAttr] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY InitializeSecurityContextA( PCredHandle phCredential, // Cred to base context PCtxtHandle phContext, // Existing context (OPT) SEC_CHAR SEC_FAR * pszTargetName, // Name of target unsigned long fContextReq, // Context Requirements unsigned long Reserved1, // Reserved, MBZ unsigned long TargetDataRep, // Data rep of target PSecBufferDesc pInput, // Input Buffers unsigned long Reserved2, // Reserved, MBZ PCtxtHandle phNewContext, // (out) New Context handle PSecBufferDesc pOutput, // (inout) Output Buffers unsigned long SEC_FAR * pfContextAttr, // (out) Context attrs PTimeStamp ptsExpiry // (out) Life span (OPT) ) { return( SEC_E_UNSUPPORTED_FUNCTION ); } PSEC_WINNT_AUTH_IDENTITY_A PwdpMakeAnsiCopy( PSEC_WINNT_AUTH_IDENTITY_A Ansi ) { PSEC_WINNT_AUTH_IDENTITY_A New ; New = PwdAlloc( sizeof( SEC_WINNT_AUTH_IDENTITY_A ) + Ansi->UserLength + 1 + Ansi->DomainLength + 1 + Ansi->PasswordLength + 1 ); if ( New ) { New->User = (PSTR) (New + 1); CopyMemory( New->User, Ansi->User, Ansi->UserLength ); New->User[ Ansi->UserLength ] = '\0'; New->Domain = New->User + Ansi->UserLength + 1 ; CopyMemory( New->Domain, Ansi->Domain, Ansi->DomainLength ); New->Domain[ Ansi->DomainLength ] = '\0'; New->Password = New->Domain + Ansi->DomainLength + 1 ; CopyMemory( New->Password, Ansi->Password, Ansi->PasswordLength ); New->Password[ Ansi->PasswordLength ] = '\0'; } return( New ); } PSEC_WINNT_AUTH_IDENTITY_W PwdpMakeWideCopy( PSEC_WINNT_AUTH_IDENTITY_W Wide, BOOLEAN ValidateOnly ) { PSEC_WINNT_AUTH_IDENTITY_W New ; ULONG FlatUserLength ; PWSTR FlatUser = NULL; WCHAR FlatDomain[ DNLEN + 2 ]; SEC_WINNT_AUTH_IDENTITY_W Local ; if ( (Wide->Domain == NULL) ) { if( ValidateOnly ) { ULONG Index; Local = *Wide ; FlatUserLength = wcslen( Wide->User ); for( Index = 0 ; Index < FlatUserLength ; Index++ ) { if( Wide->User[ Index ] == '\\' ) { Local.Domain = Wide->User; Local.DomainLength = Index; Local.User = &(Wide->User[Index+1]); Local.UserLength = FlatUserLength - Index - 1; break; } } } else { FlatUserLength = wcslen( Wide->User ) + 1; if ( FlatUserLength < UNLEN+2 ) { FlatUserLength = UNLEN + 2; } FlatUser = PwdAlloc(FlatUserLength * sizeof( WCHAR )); if ( FlatUser == NULL ) { return NULL ; } if ( ! PwdCrackName( Wide->User, FlatDomain, FlatUser ) ) { PwdFree( FlatUser ); SetLastError( ERROR_NO_SUCH_USER ); return NULL ; } Local = *Wide ; Local.User = FlatUser ; Local.Domain = FlatDomain ; Local.UserLength = wcslen( FlatUser ); Local.DomainLength = wcslen( FlatDomain ); } Wide = &Local ; } New = PwdAlloc( sizeof( SEC_WINNT_AUTH_IDENTITY_W ) + (Wide->UserLength + 1) * sizeof(WCHAR) + (Wide->DomainLength + 1) * sizeof(WCHAR) + (Wide->PasswordLength + 1) * sizeof(WCHAR) ); if ( New ) { New->User = (PWSTR) (New + 1); CopyMemory( New->User, Wide->User, Wide->UserLength * 2 ); New->User[ Wide->UserLength ] = L'\0'; New->UserLength = Wide->UserLength; New->Domain = New->User + Wide->UserLength + 1 ; CopyMemory( New->Domain, Wide->Domain, Wide->DomainLength * 2 ); New->Domain[ Wide->DomainLength ] = L'\0'; New->DomainLength = Wide->DomainLength; New->Password = New->Domain + Wide->DomainLength + 1 ; CopyMemory( New->Password, Wide->Password, Wide->PasswordLength * 2); New->Password[ Wide->PasswordLength ] = '\0'; New->PasswordLength = Wide->PasswordLength; } if ( Wide == &Local ) { if( FlatUser != NULL ) { PwdFree( FlatUser ); } } return( New ); } //+--------------------------------------------------------------------------- // // Function: AcceptSecurityContext // // Synopsis: Server side accept security context // // Arguments: [phCredential] -- // [phContext] -- // [pInput] -- // [fContextReq] -- // [TargetDataRep] -- // [phNewContext] -- // [pOutput] -- // [pfContextAttr] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY AcceptSecurityContext( PCredHandle phCredential, // Cred to base context PCtxtHandle phContext, // Existing context (OPT) PSecBufferDesc pInput, // Input buffer unsigned long fContextReq, // Context Requirements unsigned long TargetDataRep, // Target Data Rep PCtxtHandle phNewContext, // (out) New context handle PSecBufferDesc pOutput, // (inout) Output buffers unsigned long SEC_FAR * pfContextAttr, // (out) Context attributes PTimeStamp ptsExpiry // (out) Life span (OPT) ) { PPWD_CONTEXT Context ; PSecBuffer Buffer ; DWORD Type; PSEC_WINNT_AUTH_IDENTITY_W Unknown ; PSEC_WINNT_AUTH_IDENTITY_A Ansi; PSEC_WINNT_AUTH_IDENTITY_W Unicode; HANDLE Token; BOOL Ret; if ( phCredential->dwUpper == (ULONG_PTR) &PwdGlobalAnsi ) { Type = 1; } else { if ( phCredential->dwUpper == (ULONG_PTR) &PwdGlobalUnicode ) { Type = 2; } else { return( SEC_E_INVALID_HANDLE ); } } PwdpParseBuffers( pInput, &Buffer, NULL ); if ( !Buffer ) { return( SEC_E_INVALID_TOKEN ); } Unknown = (PSEC_WINNT_AUTH_IDENTITY_W) Buffer->pvBuffer ; if ( Unknown->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE ) { Type = 2 ; } if ( Type == 1 ) { // // ANSI: // Ansi = PwdpMakeAnsiCopy( (PSEC_WINNT_AUTH_IDENTITY_A) Buffer->pvBuffer); if ( Ansi ) { Ret = LogonUserA( Ansi->User, Ansi->Domain, Ansi->Password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token ) ; PwdFree( Ansi ); } else { Ret = FALSE ; } } else { BOOLEAN ValidateOnly = ((fContextReq & ASC_REQ_ALLOW_NON_USER_LOGONS) != 0); Unicode = PwdpMakeWideCopy( (PSEC_WINNT_AUTH_IDENTITY_W) Buffer->pvBuffer, ValidateOnly ); if ( Unicode ) { if( ValidateOnly ) { PVOID DsContext = THSave(); NTSTATUS Status; Status = VerifyCredentials( Unicode->User, Unicode->Domain, Unicode->Password, 0 ); THRestore( DsContext ); if( NT_SUCCESS(Status) ) { Ret = TRUE; Token = ANONYMOUS_TOKEN ; } else { Ret = FALSE; } } else { Ret = LogonUserW( Unicode->User, Unicode->Domain, Unicode->Password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token ); } PwdFree( Unicode ); } else { Ret = FALSE ; if ( GetLastError() == ERROR_NO_SUCH_USER ) { Unicode = (PSEC_WINNT_AUTH_IDENTITY_W) Buffer->pvBuffer ; __try { if ( Unicode->PasswordLength == 0 ) { Ret = TRUE ; Token = ANONYMOUS_TOKEN ; } } __except( EXCEPTION_EXECUTE_HANDLER ) { NOTHING ; } } } } if ( Ret ) { Context = (PPWD_CONTEXT) PwdAlloc( sizeof( PWD_CONTEXT ) ); if ( Context ) { Context->Tag = CONTEXT_TAG ; Context->Token = Token ; phNewContext->dwUpper = (ULONG_PTR) Context ; return( SEC_E_OK ); } if ( Token != ANONYMOUS_TOKEN ) { CloseHandle( Token ); } return( SEC_E_INSUFFICIENT_MEMORY ); } return( SEC_E_INVALID_TOKEN ); } //+--------------------------------------------------------------------------- // // Function: DeleteSecurityContext // // Synopsis: Deletes a security context // // Arguments: [phContext] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY DeleteSecurityContext( PCtxtHandle phContext ) { PPWD_CONTEXT Context; Context = (PPWD_CONTEXT) phContext->dwUpper ; #if DBG // What is the appropriate assert model? This dll does not seem to // nt specific, win32 does not provide a model, and the crt requires // NDEBUG to set, which is not always the case. if (!Context) { OutputDebugStringA("[PWDSSP]: !!Error!! - Context is NULL\n"); DebugBreak(); } #endif if ( Context->Tag == CONTEXT_TAG ) { if ( Context->Token != ANONYMOUS_TOKEN ) { CloseHandle( Context->Token ); } PwdFree( Context ); return( SEC_E_OK ); } return( SEC_E_INVALID_HANDLE ); } //+--------------------------------------------------------------------------- // // Function: ImpersonateSecurityContext // // Synopsis: Impersonate the security context // // Arguments: [impersonate] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY ImpersonateSecurityContext( PCtxtHandle phContext // Context to impersonate ) { PPWD_CONTEXT Context; HANDLE hThread; NTSTATUS Status ; Context = (PPWD_CONTEXT) phContext->dwUpper ; if ( Context->Tag == CONTEXT_TAG ) { if ( Context->Token != ANONYMOUS_TOKEN ) { hThread = GetCurrentThread(); SetThreadToken( &hThread, Context->Token ); Status = SEC_E_OK ; } else { Status = NtImpersonateAnonymousToken( NtCurrentThread() ); } return( Status ); } return( SEC_E_INVALID_HANDLE ); } //+--------------------------------------------------------------------------- // // Function: RevertSecurityContext // // Synopsis: Revert the security context // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY RevertSecurityContext( PCtxtHandle phContext // Context from which to re ) { PPWD_CONTEXT Context; Context = (PPWD_CONTEXT) phContext->dwUpper ; if ( Context->Tag == CONTEXT_TAG ) { RevertToSelf(); return( SEC_E_OK ); } return( SEC_E_INVALID_HANDLE ); } SECURITY_STATUS SEC_ENTRY QueryContextAttributesA( PCtxtHandle phContext, // Context to query unsigned long ulAttribute, // Attribute to query void SEC_FAR * pBuffer // Buffer for attributes ) { return( SEC_E_UNSUPPORTED_FUNCTION ); } SECURITY_STATUS SEC_ENTRY QueryContextAttributesW( PCtxtHandle phContext, // Context to query unsigned long ulAttribute, // Attribute to query void SEC_FAR * pBuffer // Buffer for attributes ) { return( SEC_E_UNSUPPORTED_FUNCTION ); } //+--------------------------------------------------------------------------- // // Function: PwdpCopyInfoW // // Synopsis: Helper - copy package info around // // Arguments: [ppPackageInfo] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS PwdpCopyInfoW( PSecPkgInfoW * ppPackageInfo) { DWORD cbTotal; PSecPkgInfoW pInfo; PWSTR pszCopy; cbTotal = sizeof(SecPkgInfoW) + (wcslen(PwdInfoW.Name) + wcslen(PwdInfoW.Comment) + 2) * 2; pInfo = PwdAlloc( cbTotal ); if (pInfo) { *pInfo = PwdInfoW; pszCopy = (PWSTR) (pInfo + 1); pInfo->Name = pszCopy; wcscpy(pszCopy, PwdInfoW.Name); pszCopy += wcslen(PwdInfoW.Name) + 1; pInfo->Comment = pszCopy; wcscpy(pszCopy, PwdInfoW.Comment); *ppPackageInfo = pInfo; return(SEC_E_OK); } return(SEC_E_INSUFFICIENT_MEMORY); } //+--------------------------------------------------------------------------- // // Function: PwdpCopyInfoA // // Synopsis: copy ansi package info around // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS PwdpCopyInfoA( PSecPkgInfoA * ppPackageInfo) { DWORD cbTotal; PSecPkgInfoA pInfo; PSTR pszCopy; cbTotal = sizeof(SecPkgInfoA) + (strlen(PwdInfoA.Name) + strlen(PwdInfoA.Comment) + 2) * 2; pInfo = PwdAlloc( cbTotal ); if (pInfo) { *pInfo = PwdInfoA; pszCopy = (PSTR) (pInfo + 1); pInfo->Name = pszCopy; strcpy(pszCopy, PwdInfoA.Name); pszCopy += strlen(PwdInfoA.Name) + 1; pInfo->Comment = pszCopy; strcpy(pszCopy, PwdInfoA.Comment); *ppPackageInfo = pInfo; return(SEC_E_OK); } return(SEC_E_INSUFFICIENT_MEMORY); } //+--------------------------------------------------------------------------- // // Function: EnumerateSecurityPackagesW // // Synopsis: Enumerate packages in this DLL // // Arguments: [pcPackages] -- // [info] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesW( unsigned long SEC_FAR * pcPackages, // Receives num. packages PSecPkgInfoW SEC_FAR * ppPackageInfo // Receives array of info ) { SECURITY_STATUS scRet; *ppPackageInfo = NULL; scRet = PwdpCopyInfoW(ppPackageInfo); if (SUCCEEDED(scRet)) { *pcPackages = 1; return(scRet); } *pcPackages = 0; return(scRet); } //+--------------------------------------------------------------------------- // // Function: EnumerateSecurityPackagesA // // Synopsis: Enumerate // // Arguments: [pcPackages] -- // [info] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesA( unsigned long SEC_FAR * pcPackages, // Receives num. packages PSecPkgInfoA SEC_FAR * ppPackageInfo // Receives array of info ) { SECURITY_STATUS scRet; *ppPackageInfo = NULL; scRet = PwdpCopyInfoA(ppPackageInfo); if (SUCCEEDED(scRet)) { *pcPackages = 1; return(scRet); } *pcPackages = 0; return(scRet); } //+--------------------------------------------------------------------------- // // Function: QuerySecurityPackageInfoW // // Synopsis: Query individual package info // // Arguments: [pszPackageName] -- // [info] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoW( SEC_WCHAR SEC_FAR * pszPackageName, // Name of package PSecPkgInfoW * ppPackageInfo // Receives package info ) { if (_wcsicmp(pszPackageName, PWDSSP_NAME_W)) { return(SEC_E_SECPKG_NOT_FOUND); } return(PwdpCopyInfoW(ppPackageInfo)); } //+--------------------------------------------------------------------------- // // Function: QuerySecurityPackageInfoA // // Synopsis: Same, ansi // // Arguments: [pszPackageName] -- // [info] -- // // Notes: // //---------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoA( SEC_CHAR SEC_FAR * pszPackageName, // Name of package PSecPkgInfoA * ppPackageInfo // Receives package info ) { if (_stricmp(pszPackageName, PWDSSP_NAME_A)) { return(SEC_E_SECPKG_NOT_FOUND); } return(PwdpCopyInfoA(ppPackageInfo)); } SECURITY_STATUS SEC_ENTRY MakeSignature(PCtxtHandle phContext, DWORD fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) { return(SEC_E_UNSUPPORTED_FUNCTION); } SECURITY_STATUS SEC_ENTRY VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, DWORD * pfQOP) { return(SEC_E_UNSUPPORTED_FUNCTION); } SECURITY_STATUS SEC_ENTRY SealMessage(PCtxtHandle phContext, DWORD fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) { return(SEC_E_UNSUPPORTED_FUNCTION); } SECURITY_STATUS SEC_ENTRY UnsealMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, DWORD * pfQOP) { return(SEC_E_UNSUPPORTED_FUNCTION); } SECURITY_STATUS SEC_ENTRY ApplyControlToken( PCtxtHandle phContext, // Context to modify PSecBufferDesc pInput // Input token to apply ) { return( SEC_E_UNSUPPORTED_FUNCTION ); } SECURITY_STATUS SEC_ENTRY FreeContextBuffer( PVOID p) { if( p != NULL ) { PwdFree( p ); } return( SEC_E_OK ); } SECURITY_STATUS SEC_ENTRY QuerySecurityContextToken( PCtxtHandle phContext, PHANDLE Token) { PPWD_CONTEXT Context; Context = (PPWD_CONTEXT) phContext->dwUpper ; if ( Context->Tag == CONTEXT_TAG ) { *Token = Context->Token ; return( SEC_E_OK ); } return( SEC_E_INVALID_HANDLE ); } SECURITY_STATUS SEC_ENTRY CompleteAuthToken( PCtxtHandle phContext, // Context to complete PSecBufferDesc pToken // Token to complete ) { return( SEC_E_UNSUPPORTED_FUNCTION ); } PSecurityFunctionTableA SEC_ENTRY InitSecurityInterfaceA( VOID ) { return( &PwdTableA ); } PSecurityFunctionTableW SEC_ENTRY InitSecurityInterfaceW( VOID ) { return( &PwdTableW ); } NTSTATUS VerifyCredentials( IN PWSTR UserName, IN PWSTR DomainName, IN PWSTR Password, IN ULONG VerifyFlags ) { PKERB_VERIFY_CREDENTIALS_REQUEST pVerifyRequest; KERB_VERIFY_CREDENTIALS_REQUEST VerifyRequest; ULONG cbVerifyRequest; PVOID pResponse = NULL; ULONG cbResponse; USHORT cbUserName; USHORT cbDomainName; USHORT cbPassword; NTSTATUS ProtocolStatus = STATUS_LOGON_FAILURE; NTSTATUS Status; cbUserName = (USHORT)(lstrlenW(UserName) * sizeof(WCHAR)) ; cbDomainName = (USHORT)(lstrlenW(DomainName) * sizeof(WCHAR)) ; cbPassword = (USHORT)(lstrlenW(Password) * sizeof(WCHAR)) ; cbVerifyRequest = sizeof(VerifyRequest) + cbUserName + cbDomainName + cbPassword ; pVerifyRequest = &VerifyRequest; ZeroMemory( &VerifyRequest, sizeof(VerifyRequest) ); pVerifyRequest->MessageType = KerbVerifyCredentialsMessage ; // // do the length, buffers, copy, marshall dance. // pVerifyRequest->UserName.Length = cbUserName; pVerifyRequest->UserName.MaximumLength = cbUserName; pVerifyRequest->UserName.Buffer = UserName; pVerifyRequest->DomainName.Length = cbDomainName; pVerifyRequest->DomainName.MaximumLength = cbDomainName; pVerifyRequest->DomainName.Buffer = DomainName; pVerifyRequest->Password.Length = cbPassword; pVerifyRequest->Password.MaximumLength = cbPassword; pVerifyRequest->Password.Buffer = Password; pVerifyRequest->VerifyFlags = VerifyFlags; Status = I_LsaICallPackage( &AuthenticationPackage, pVerifyRequest, cbVerifyRequest, &pResponse, &cbResponse, &ProtocolStatus ); if(!NT_SUCCESS(Status)) { goto Cleanup; } Status = ProtocolStatus; Cleanup: return Status; }