Как программно осуществить вход в сеть в WinNT и Win95Иногда бывает необходимо, чтобы приложение
проверяло имя пользователя и пароль. Существует
пара способов, чтобы проделать эту операцию, в
зависимости от того, на какой платформе запущено
приложение: Windows 95 или Windows NT. Пример кода /*++
Module Name:
SSPLogon.c
Abstract:
This module implements the network logon type by
interfacing with the Windows NT Lan Man Security Support
Provider (NTLMSSP) for the purpose of validating
the provided users credentials.
Автор:
David Mowers (DaveMo) January 14, 1998
Необходимы следующие модули из примера SockAuth:
security.c (modify according to comment below)
collect.c
Revision History:
--*/
#define SECURITY_WIN32
#include <windows.h>
#include <sspi.h>
//
// Небольшое изменение в GenClientContext, чтобы можно было
// передавать пользовательские данные авторизации.
//
BOOL GenClientContext (
DWORD dwKey,
SEC_WINNT_AUTH_IDENTITY *pAuthIdentity,
BYTE *pIn,
DWORD cbIn,
BYTE *pOut,
DWORD *pcbOut,
BOOL *pfDone);
/*
В security.c, для функции GenClientContext,
сделайте следующие изменения:
ss = g_pFuncs->AcquireCredentialsHandle (
NULL, // principal
PACKAGE_NAME,
SECPKG_CRED_OUTBOUND,
NULL, // LOGON id
pAuthIdentity, // auth data
NULL, // get key fn
NULL, // get key arg
&pAS->_hcred,
&Lifetime
);
*/
static PBYTE g_pClientBuf = NULL;
static PBYTE g_pServerBuf = NULL;
static DWORD g_cbMaxMessage = 0;
BOOL
SSPLogonUser(
LPTSTR DomainName,
LPTSTR UserName,
LPTSTR Password
)
{
BOOL done = FALSE;
DWORD cbOut, cbIn;
char szUser[80];
DWORD cbUser = 80;
SEC_WINNT_AUTH_IDENTITY AuthIdentity;
if(!InitSession(0))
{
return(FALSE);
}
if(!InitSession(1))
{
return(FALSE);
}
if (!InitPackage (&g_cbMaxMessage))
{
return(FALSE);
}
g_pClientBuf = (PBYTE) malloc(g_cbMaxMessage);
g_pServerBuf = (PBYTE) malloc(g_cbMaxMessage);
ZeroMemory( &AuthIdentity, sizeof(AuthIdentity) );
if ( DomainName != NULL )
{
AuthIdentity.Domain = DomainName;
AuthIdentity.DomainLength = lstrlen(DomainName);
}
if ( UserName != NULL )
{
AuthIdentity.User = UserName;
AuthIdentity.UserLength = lstrlen(UserName);
}
if ( Password != NULL )
{
AuthIdentity.Password = Password;
AuthIdentity.PasswordLength = lstrlen(Password);
}
#ifdef UNICODE
AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
#else
AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
#endif
//
// Подготовка клиентского сообщения (negotiate).
//
cbOut = g_cbMaxMessage;
if (!GenClientContext (
0,
&AuthIdentity,
NULL,
0,
g_pClientBuf,
&cbOut,
&done))
{
return(FALSE);
}
cbIn = cbOut;
//
// Подготовка сообщения сервера (challenge).
//
cbOut = g_cbMaxMessage;
if (!GenServerContext (
1,
g_pClientBuf,
cbIn,
g_pServerBuf,
&cbOut,
&done))
{
//
// Наиболее вероятный отказ: AcceptServerContext с сообщением
// SEC_E_LOGON_DENIED в случе неправильного имени или пароля
//
// Неожиданный Результат: Вход будет удачным, если имя
// неправильно, а гостевой аккаунт присутствует в указанно
// домене.
//
return(FALSE);
}
cbIn = cbOut;
//
// Подготовка клиентского сообщения (authenticate).
//
cbOut = g_cbMaxMessage;
if (!GenClientContext (
0,
&AuthIdentity,
g_pServerBuf,
cbIn,
g_pClientBuf,
&cbOut,
&done))
{
return(FALSE);
}
cbIn = cbOut;
//
// Подготовка сообщения сервера (authentication).
//
cbOut = g_cbMaxMessage;
if (!GenServerContext (
1,
g_pClientBuf,
cbIn,
g_pServerBuf,
&cbOut,
&done))
{
return(FALSE);
}
TermSession(0);
TermSession(1);
TermPackage();
free(g_pClientBuf);
free(g_pServerBuf);
return(TRUE);
}
int main( int argc, char *argv[] )
{
if(argc<4)
{
printf(
"Usage: %s <domain> <user> <password>\n",
argv[0]);
exit(0);
}
if(SSPLogonUser(
argv[1],
argv[2],
argv[3]))
{
printf("SSP Logon Succeeded!\n");
exit(1);
}
else
{
printf("SSP Logon Failed!\n");
exit(0);
}
}
|