Microsoft KB Archive/177200: Difference between revisions

From BetaArchive Wiki
m (Text replacement - ".htm|" to "|")
m (Text replacement - "&" to "&")
 
(3 intermediate revisions by the same user not shown)
Line 41: Line 41:


<pre class="CODESAMP">  ////////////////////////////////////  
<pre class="CODESAMP">  ////////////////////////////////////  
   #include &lt;windows.h&gt;
   #include <windows.h>
   #include &lt;stdio.h&gt;
   #include <stdio.h>
   #include &quot;pwdspi.h&quot;// Found in July 96 DDK otherwise define as follows
   #include "pwdspi.h"// Found in July 96 DDK otherwise define as follows


   #ifndef PS_SYNCMASTERPWD //if pwdspi.h is not present
   #ifndef PS_SYNCMASTERPWD //if pwdspi.h is not present
Line 74: Line 74:
   DWORD  res = 0;
   DWORD  res = 0;
   DWORD  cbUserName = 250;
   DWORD  cbUserName = 250;
   HINSTANCE  lib = LoadLibrary(&quot;MPR.DLL&quot;);
   HINSTANCE  lib = LoadLibrary("MPR.DLL");


   if (lib == NULL)
   if (lib == NULL)
         DisplayError(&quot;LoadLibrary&quot;);
         DisplayError("LoadLibrary");


   // To synchronize network provider password with windows password we
   // To synchronize network provider password with windows password we
Line 87: Line 87:
   // Get address of PwdGetPasswordStatus
   // Get address of PwdGetPasswordStatus
   sPwdSetPasswordStatus =
   sPwdSetPasswordStatus =
       (LPPwdSetPasswordStatus) GetProcAddress(lib,&quot;PwdSetPasswordStatusA&quot;);
       (LPPwdSetPasswordStatus) GetProcAddress(lib,"PwdSetPasswordStatusA");
   if (sPwdSetPasswordStatus == NULL)
   if (sPwdSetPasswordStatus == NULL)
       DisplayError(&quot;GetProcAddress&quot;);
       DisplayError("GetProcAddress");


   res = sPwdSetPasswordStatus(&quot;MSNP32&quot;, // name of password provider
   res = sPwdSetPasswordStatus("MSNP32", // name of password provider
                               PS_SYNCMASTERPWD,
                               PS_SYNCMASTERPWD,
                               PS_SYNCMASTERPWD_ON
                               PS_SYNCMASTERPWD_ON
                               );
                               );
   if (res != WN_SUCCESS)
   if (res != WN_SUCCESS)
         DisplayError(&quot;PwdSetPasswordStatus&quot;);
         DisplayError("PwdSetPasswordStatus");


   // Must get PwdChangePasswordA because in Windows 95 we are using the
   // Must get PwdChangePasswordA because in Windows 95 we are using the
   // ascii version of the exported function
   // ascii version of the exported function
   sPwdChangePassword =
   sPwdChangePassword =
       (LPPwdChangePassword) GetProcAddress(lib,&quot;PwdChangePasswordA&quot;);
       (LPPwdChangePassword) GetProcAddress(lib,"PwdChangePasswordA");


   // Call sPwdChangePassword specifying NULL as network provider.
   // Call sPwdChangePassword specifying NULL as network provider.
Line 109: Line 109:
                                 GetDesktopWindow(), //Window to own dialog
                                 GetDesktopWindow(), //Window to own dialog
                                 0,  // No special flag
                                 0,  // No special flag
                                 &amp;s  // Address of CHANGEPWDINFO structure
                                 &s  // Address of CHANGEPWDINFO structure
                                 );
                                 );
   if (res != WN_SUCCESS)
   if (res != WN_SUCCESS)
         DisplayError(&quot;PwdChangePassword&quot;);
         DisplayError("PwdChangePassword");


   FreeLibrary(lib);
   FreeLibrary(lib);
   printf(&quot;Password = %s\n&quot;,s.lpPassword);
   printf("Password = %s\n",s.lpPassword);


   return;
   return;
Line 127: Line 127:
                 NULL, GetLastError(),
                 NULL, GetLastError(),
                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                 (LPTSTR)&amp;lpvMessageBuffer, 0, NULL);
                 (LPTSTR)&lpvMessageBuffer, 0, NULL);


   //... now display this string
   //... now display this string
   printf(&quot;ERROR: API        = %s.\n&quot;, pszAPI);
   printf("ERROR: API        = %s.\n", pszAPI);
   printf(&quot;       error code = %d.\n&quot;, GetLastError());
   printf("       error code = %d.\n", GetLastError());
   printf(&quot;       message    = %s.\n&quot;, (char *)lpvMessageBuffer);
   printf("       message    = %s.\n", (char *)lpvMessageBuffer);


   // Free the buffer allocated by the system
   // Free the buffer allocated by the system

Latest revision as of 12:30, 21 July 2020

HOWTO: Programmatically Change Network Password Under Windows 95

Q177200



The information in this article applies to:


  • Microsoft Win32 Application Programming Interface (API), included with:
    • Microsoft Windows 95





SUMMARY

If you want to design your application to implement its own routine to change domain passwords on Windows 95, you have several methods available to you, each one of which has limitations on functionality, portability, or security. This article describes two of these methods in detail.



MORE INFORMATION

Method 1

Dynamically load the 32-bit API PwdChangePassword() from Mpr.dll and it will successfully change passwords. However, it will display a non- customizable dialog box to prompt the user for password information. If you want your application to have its own interface for changing passwords, you cannot use this API.

NOTE: PwdChangePassword() is the only interface that will change the Windows password as well as your network password.

The following sample code demonstrates how to use PwdChangePassword.

Sample Code

   //////////////////////////////////// 
   #include <windows.h>
   #include <stdio.h>
   #include "pwdspi.h"// Found in July 96 DDK otherwise define as follows

   #ifndef PS_SYNCMASTERPWD //if pwdspi.h is not present
   #define PS_SYNCMASTERPWD         0x03
   #define PS_SYNCMASTERPWD_OFF     0x00
   #define PS_SYNCMASTERPWD_ON      0x01

   // Function definition of PwdChangePassword and helper struct for
   // Windows 95. Helper structure (also found in pwdspi.h)
   typedef struct _CHANGEPWDINFO{
      LPTSTR lpUsername;
      LPTSTR lpPassword;
      DWORD cbPassword;
   } CHANGEPWDINFO, FAR *LPCHANGEPWDINFO;
   #endif

   // Function definitions:
   typedef DWORD
    (APIENTRY *LPPwdChangePassword)(LPCTSTR,HWND,DWORD,LPCHANGEPWDINFO);
   typedef DWORD (APIENTRY *LPPwdSetPasswordStatus)(LPCSTR,DWORD,DWORD);

   // Function to display error messages upon API failure
   void DisplayError(char *pszAPI);

   void main()
   {
   CHANGEPWDINFO   s = {NULL,NULL,0}; // initialize struct to empty.
   LPPwdChangePassword sPwdChangePassword;
   LPPwdSetPasswordStatus sPwdSetPasswordStatus;
   DWORD   res = 0;
   DWORD   cbUserName = 250;
   HINSTANCE   lib = LoadLibrary("MPR.DLL");

   if (lib == NULL)
        DisplayError("LoadLibrary");

   // To synchronize network provider password with windows password we
   // need to call PwdSetPasswordStatus. By synchronizing the network
   // provider password we avoid having to change each password separately.
   // Network providers listed in registry at:
   // HKLM/System\CurrentControlSet\Control\PwdProvider

   // Get address of PwdGetPasswordStatus
   sPwdSetPasswordStatus =
      (LPPwdSetPasswordStatus) GetProcAddress(lib,"PwdSetPasswordStatusA");
   if (sPwdSetPasswordStatus == NULL)
      DisplayError("GetProcAddress");

   res = sPwdSetPasswordStatus("MSNP32", // name of password provider
                               PS_SYNCMASTERPWD,
                               PS_SYNCMASTERPWD_ON
                               );
   if (res != WN_SUCCESS)
        DisplayError("PwdSetPasswordStatus");

   // Must get PwdChangePasswordA because in Windows 95 we are using the
   // ascii version of the exported function
   sPwdChangePassword =
      (LPPwdChangePassword) GetProcAddress(lib,"PwdChangePasswordA");

   // Call sPwdChangePassword specifying NULL as network provider.
   // This causes windows (non-network) password to be changed and hence
   // all synchronized passwords.
   res = sPwdChangePassword(    NULL, // Network provider
                                GetDesktopWindow(), //Window to own dialog
                                0,  // No special flag
                                &s  // Address of CHANGEPWDINFO structure
                                );
   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);

   //... now display this string
   printf("ERROR: API        = %s.\n", pszAPI);
   printf("       error code = %d.\n", GetLastError());
   printf("       message    = %s.\n", (char *)lpvMessageBuffer);

   // Free the buffer allocated by the system
   LocalFree(lpvMessageBuffer);
   ExitProcess(GetLastError());
   } 

Method 2

A relatively easy way to change passwords under Windows 95 is to have a server process running on a Windows NT server that creates a named pipe to which the Windows 95 client can connect. The Windows NT Server calls the ImpersonateNamedPipeClient() API and get the Windows 95 user's domain name and user name as described in the following knowledge base article:

Q155698 HOWTO: Look Up Current User Name and Domain Name

The Windows 95 Client then sends the password information to the Windows NT process which can then call the NetUserChangePassword() API. The restrictions to this design are that you need a process running on a Windows NT Server, and that sending the password information over a network poses a security risk. To increase the level of security, you can encrypt the password before sending it over the network. For more information on encryption see the Crypto API documentation in the Win32 SDK. Furthermore, this method changes the network password only, not the Windows Logon Password. You can only change the Windows Logon Password by implementing Option 1 above. This means that the Windows Password and the Network passwords are not be synchronized. As a result, the user has to enter both passwords when logging onto Windows 95.

NOTE: You should not use the 16-bit Lan Manager API NetUserChangePassword(). This API changes the password to all uppercase characters and then sends the username and password combination across the network in non-encrypted clear text form. This is not only a security risk, it may also invalidate the original password by modifying changing it to an all uppercase version that may no longer be valid if the server applies password filtering.

Additional query words: windows password PwdChangePassword domain

Keywords : kbnetwork kbADSI kbAPI kbKernBase kbSDKPlatform kbSecurity kbOSWin95 kbNetAPI kbFAQ kbGrpDSNet
Issue type : kbhowto
Technology : kbAudDeveloper kbWin32sSearch kbWin32API


Last Reviewed: December 16, 2000
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.