Click here to Skip to main content
Licence CPOL
First Posted 29 May 2006
Views 43,878
Downloads 1,934
Bookmarked 41 times

How to change a user's password on a remote computer

By Steffen Lange | 29 May 2006
Password Changer - A reusable tool for changing a user password's remotely.

1

2
1 vote, 16.7%
3
1 vote, 16.7%
4
4 votes, 66.7%
5
4.43/5 - 6 votes
μ 4.43, σa 1.46 [?]

Password Changer screenshot

Introduction

This is my first article on CodeProject. So please don't expect too much. ;-)

Given scenario

An old workstation running Windows 2000 acts as a "file server". Users can access shared folders over the network by connecting using a username and password. Unfortunately, in a workgroup environment, there is no built-in way to change the passwords of these local users from a remote machine.

Tasks to solve

The described problem can be divided into three main parts:

  1. How to get a list of all the computers in our workgroup?
  2. How to get a list of all users from a specific computer?
  3. How to change a user's password on a remote computer?

The API is your friend

In the MSDN are three corresponding network management functions mentioned. Their usage is well explained, so I won't recite the MSDN.

  1. NetServerEnum
  2. NetQueryDisplayInformation (see: How to get a list of users from a server)
  3. NetUserChangePassword

But the simple NetUserChangePassword function prototype should be self-explanatory.

DWORD NetUserChangePassword(
  LPCWSTR domainname,
  LPCWSTR username,
  LPCWSTR oldpassword,
  LPCWSTR newpassword
);

Naming conventions

The different strings (e.g., usernames, passwords) are limited to a certain number of characters. It seems that these limitations are a relic from the NT LAN Manager.

Name Length
Domain/Workgroup 15
Server 15
User 20
Password 14

Security concerns

NetQueryDisplayInformation requires anonymous access to the remote machine. Furthermore, an established NULL session connection (e.g., to $IPC) is required.

Using the code

The server and the user enumeration are wrapped into several classes.

Enumeration classes

Iterating through the result list shouldn't be a big deal.

NetObjectEnumerator *noe = 
   new [ NetServerEnumerator(Domain) | NetUserEnumerator(Server) ] ;
if(noe->GetError() == ERROR_SUCCESS){
  while(noe->HasNext()){
    NetObject *no = noe->GetNext();
    ... = no->name; // process the current server/user name...

  }
}
else
  ... = NetObjectEnumerator::GetErrorMessage(noe->GetError());
  // process the occurred error...

Error codes and message strings

The FormatMessage function maps an error code to a message. For network management errors, the netmsg.dll module is used to look up the specified errors.

CString GetErrorMessage(DWORD dwLastError){
  HMODULE hModule = NULL;
  DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM;
  LPTSTR lpMessageBuffer = NULL;
  if((dwLastError >= NERR_BASE) && (dwLastError <= MAX_NERR)){
    hModule = LoadLibraryEx(_T("netmsg.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE);
    if(hModule != NULL)
      dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
  }
  FormatMessage(
    dwFormatFlags,
    hModule,
    dwLastError,
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    (LPTSTR)&lpMessageBuffer,
    0,
    NULL);
  CString szMessage;
  szMessage.Format(_T("%s (%u)"), lpMessageBuffer, dwLastError);
  LocalFree(lpMessageBuffer);
  if(hModule != NULL)
    FreeLibrary(hModule);
  return szMessage;
}

Credits

Credits go to Chris Maunder for his great HyperLink static control.

Notice

The application has not been tested in a domain environment. Any volunteers?

Please feel free to send your feedback to me via email. Bug reports, spelling corrections, opinions, and comments would be much appreciated.

History

  • 05/16/2006:
    • Original article published.
    • Version 1.0.0.1 released

The newest Password Changer version is also available on my website.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Steffen Lange

Engineer

Germany Germany

Member
My first computer was a Z 9001.













Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Questionerror 2245 PinmemberGoldorack3411:39 1 Aug '11  
QuestionAccess Denied? PinmemberMattOliver16:04 24 Oct '09  
QuestionNice one...and for Visual Studio 2003? Pinmemberrootdial0:48 6 Jan '07  
AnswerRe: Nice one...and for Visual Studio 2003? PinmemberSteffen Lange7:47 6 Jan '07  
NewsSteps to compile the English version PinmemberSteffen Lange10:20 29 May '06  
1. Unzip PwdChange_src.zip
2. Delete PwdChange.rc (German resource script)
3. Rename PwdChange_en.rc to PwdChange.rc
4. Open PwdChange.sln in Visual Studio 2005
 
That's all folks! Wink | ;-)
GeneralRe: Steps to compile the English version PinmemberHerbert Yu11:54 26 Oct '06  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120210.1 | Last Updated 29 May 2006
Article Copyright 2006 by Steffen Lange
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid