Как программно изменить сетевой пароль под
Windows 95
Существует несколько методов смены доменного
пароля в Windows 95. Каждый из них обладает своими
преимуществами и недостатками. В данной статье
детально описываются два метода.
Первый метод
Для смены паролей можно динамически загрузить
32-битную API функцию PwdChangePassword() из Mpr.dll. Однако, при
этом будет показан стандартное диалоговое окно,
предлагающее пользователю ввести пароль. Если
Вам необходимо, чтобы приложение имело свой
интерфейс для смены пароля, то данная функция не
подойдёт.
ЗАМЕЧАНИЕ: PwdChangePassword(), это единственный
интерфейс, который позволяет менять как пароль
Windows, так и сетевой пароль.
Следующий код демонстрирует использование
PwdChangePassword.
Пример кода
////////////////////////////////////
#include <windows.h>
#include <stdio.h>
#include "pwdspi.h" // Найдите его в июльском 96 DDK иначе сделайте
// следующие объявления
#ifndef PS_SYNCMASTERPWD //если pwdspi.h не присутствует
#define PS_SYNCMASTERPWD 0x03
#define PS_SYNCMASTERPWD_OFF 0x00
#define PS_SYNCMASTERPWD_ON 0x01
// Объявление функции PwdChangePassword и вспомогательной структуры для
// Windows 95. Вспомогательная структура (так же содержащаяся в pwdspi.h)
typedef struct _CHANGEPWDINFO{
LPTSTR lpUsername;
LPTSTR lpPassword;
DWORD cbPassword;
} CHANGEPWDINFO, FAR *LPCHANGEPWDINFO;
#endif
// Объявления функции:
typedef DWORD
(APIENTRY *LPPwdChangePassword)(LPCTSTR,HWND,DWORD,LPCHANGEPWDINFO);
typedef DWORD (APIENTRY *LPPwdSetPasswordStatus)(LPCSTR,DWORD,DWORD);
// Функция для отображения сообщения об ошибке
void DisplayError(char *pszAPI);
void main()
{
CHANGEPWDINFO s = {NULL,NULL,0}; // инициализируем пустую структуру.
LPPwdChangePassword sPwdChangePassword;
LPPwdSetPasswordStatus sPwdSetPasswordStatus;
DWORD res = 0;
DWORD cbUserName = 250;
HINSTANCE lib = LoadLibrary("MPR.DLL");
if (lib == NULL)
DisplayError("LoadLibrary");
// Чтобы синхронизировать сетевой пароль с паролем, нам необходимо
// вызвать PwdSetPasswordStatus. Синхронизируя сетевой пароль, мы
// освобождаем себя от необходимости изменять каждый пароль в отдельности.
// Информация о сетевых провайдерах находится в реестре по адресу:
// HKLM/System\CurrentControlSet\Control\PwdProvider
// Получаем адрес функции PwdGetPasswordStatus
sPwdSetPasswordStatus =
(LPPwdSetPasswordStatus) GetProcAddress(lib,"PwdSetPasswordStatusA");
if (sPwdSetPasswordStatus == NULL)
DisplayError("GetProcAddress");
res = sPwdSetPasswordStatus("MSNP32", // имя провайдера пароля
PS_SYNCMASTERPWD,
PS_SYNCMASTERPWD_ON
);
if (res != WN_SUCCESS)
DisplayError("PwdSetPasswordStatus");
// Нужно получить адрес PwdChangePasswordA, так как в Windows 95 мы
// мы используем ascii версию экспортированной функции
sPwdChangePassword =
(LPPwdChangePassword) GetProcAddress(lib,"PwdChangePasswordA");
// Вызываем sPwdChangePassword, указывая NULL в качестве сетевого
// провайдера. Это заставит windows изменить несетевой пароль а заодно
// и все синхронизированные с ним пароли.
res = sPwdChangePassword( NULL, // Сетевой провайдер
GetDesktopWindow(), //Окно для диалога
0, // Флаги не указываем
&s // Адрес структуры CHANGEPWDINFO
);
if (res != WN_SUCCESS)
DisplayError("PwdChangePassword");
FreeLibrary(lib);
printf("Password = %s\n",s.lpPassword);
return;
}
void DisplayError(char *pszAPI)
{
LPVOID lpvMessageBuffer;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpvMessageBuffer, 0, NULL);
//... теперь отображаем эту строку
printf("ERROR: API = %s.\n", pszAPI);
printf(" error code = %d.\n", GetLastError());
printf(" message = %s.\n", (char *)lpvMessageBuffer);
// Освобождаем буфер, распределённый системой
LocalFree(lpvMessageBuffer);
ExitProcess(GetLastError());
}
Второй метод
Относительно простой способ смены паролей под
Windows 95, заключается в том, чтобы иметь серверный
процесс, запущенный на Windows NT server, который создаёт
named pipe, к которому может приконнектиться клиент
Windows 95. Windows NT Server вызывает API функцию
ImpersonateNamedPipeClient() и получает доменное имя и имя
пользователя Windows 95 как описано в следующей
статье:
Q155698 Как получить текущее имя
пользователя и имя домена
Затем клиент Windows 95 посылает информацию о
пароле процессу Windows NT который затем может
вызвать функцию NetUserChangePassword(). Недостаток этого
метода состоит в том, что необходимо иметь
запущенный процесс Windows NT Server, а затем отправлять
пароль через сеть с определённой долей риска.
Чтобы увеличить уровень безопасности, можно
зашифровать пароль перед отправкой его по сети.
Кроме того, данный метод позволяет изменить
только сетевой пароль, но никак не пароль входа в
Windows. Это значит, Пароль Windows и сетевой пароль не
синхронизированы. В результате, пользователь
должен вводить оба пароля при входе в Windows 95.
ЗАМЕЧАНИЕ: Вы не должны использовать 16-битную
функцию NetUserChangePassword() сетевого менеджера. Эта
функция конвертирует все символы пароля в
верхний регистр а затем отправляет комбинацию
имени пользователя и пароля через сеть в
незашифрованном виде (в виде чистого текста). Это
не только определённый риск для безопасности
пароля, но не возможности вдальнейнейшем
пользоваться паролем из-за смени всех символов
на верхний регистр.
|