home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / winnt / netapi / chngpass / chngpass.c next >
Encoding:
C/C++ Source or Header  |  1996-06-05  |  5.7 KB  |  245 lines

  1. /*++
  2.  
  3. Copyright (c) 1995, 1996  Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     chngpass.c
  8.  
  9. Abstract:
  10.  
  11.     This sample changes the password for an arbitrary user on an arbitrary
  12.     target machine.
  13.  
  14.     When targetting a domain controller for account update operations,
  15.     be sure to target the primary domain controller for the domain.
  16.     The account settings are replicated by the primary domain controller
  17.     to each backup domain controller as appropriate.  The NetGetDCName()
  18.     Lan Manager API call can be used to get the primary domain controller
  19.     computer name from a domain name.
  20.  
  21.  
  22.     Username is argv[1]
  23.     new password is argv[2]
  24.     optional target machine (or domain name) is argv[3]
  25.     optional old password is argv[4].  This allows non-admin password
  26.      changes.
  27.  
  28.     Note that admin or account operator privilege is required on the
  29.     target machine unless argv[4] is present and represents the correct
  30.     current password.
  31.  
  32.     NetUserSetInfo() at info-level 1003 is appropriate for administrative
  33.     over-ride of an existing password.
  34.  
  35.     NetUserChangePassword() allows for an arbitrary user to over-ride
  36.     an existing password providing that the current password is confirmed.
  37.  
  38.     Link with netapi32.lib
  39.  
  40. Author:
  41.  
  42.     Scott Field (sfield)    21-Dec-95
  43.  
  44. --*/
  45.  
  46. #include <windows.h>
  47. #include <stdio.h>
  48.  
  49. #include <lm.h>
  50.  
  51. #define RTN_OK 0
  52. #define RTN_USAGE 1
  53. #define RTN_ERROR 13
  54.  
  55. void
  56. DisplayErrorText(
  57.     DWORD dwLastError
  58.     );
  59.  
  60. //
  61. // Unicode entry point and argv
  62. //
  63.  
  64. int
  65. __cdecl
  66. wmain(
  67.     int argc,
  68.     wchar_t *argv[]
  69.     )
  70. {
  71.     LPWSTR          wUserName;
  72.     LPWSTR          wComputerName = NULL; // default to local machine
  73.     LPWSTR          wOldPassword;
  74.     LPWSTR          wNewPassword;
  75.     USER_INFO_1003  pi1003;
  76.     NET_API_STATUS  nas;
  77.  
  78.     if( argc < 3 ) {
  79.         fprintf(stderr, "Usage: %ls <user> <new_password> "
  80.                         "[\\\\machine | domain] [old_password]\n",
  81.                         argv[0]);
  82.         return RTN_USAGE;
  83.     }
  84.  
  85.     //
  86.     // process command line arguments
  87.     //
  88.  
  89.     wUserName = argv[1];
  90.     wNewPassword = argv[2];
  91.  
  92.     if( argc >= 4 && *argv[3] != L'\0' ) {
  93.  
  94.         //
  95.         // obtain target machine name, if appropriate
  96.         // always in Unicode, as that is what the API takes
  97.         //
  98.  
  99.         if(argv[3][0] == L'\\' && argv[3][1] == L'\\') {
  100.  
  101.             //
  102.             // target specified machine name
  103.             //
  104.  
  105.             wComputerName = argv[3];
  106.         }
  107.         else {
  108.  
  109.             //
  110.             // the user specified a domain name.  Lookup the PDC
  111.             //
  112.  
  113.             nas = NetGetDCName(
  114.                 NULL,
  115.                 argv[3],
  116.                 (LPBYTE *)&wComputerName
  117.                 );
  118.  
  119.             if(nas != NERR_Success) {
  120.                 DisplayErrorText( nas );
  121.                 return RTN_ERROR;
  122.             }
  123.         }
  124.     }
  125.  
  126.     if(argc == 5) {
  127.         wOldPassword = argv[4];
  128.     } else {
  129.         wOldPassword = NULL;
  130.     }
  131.  
  132.     if(wOldPassword == NULL) {
  133.  
  134.         //
  135.         // administrative over-ride of existing password
  136.         //
  137.  
  138.         pi1003.usri1003_password = wNewPassword;
  139.  
  140.         nas = NetUserSetInfo(
  141.                 wComputerName,  // computer name
  142.                 wUserName,      // username
  143.                 1003,           // info level
  144.                 (LPBYTE)&pi1003,     // new info
  145.                 NULL
  146.                 );
  147.     } else {
  148.  
  149.         //
  150.         // allows user to change their own password
  151.         //
  152.  
  153.         nas = NetUserChangePassword(
  154.                 wComputerName,
  155.                 wUserName,
  156.                 wOldPassword,
  157.                 wNewPassword
  158.                 );
  159.     }
  160.  
  161.     if(wComputerName != NULL && wComputerName != argv[3]) {
  162.  
  163.         //
  164.         // a buffer was allocated for the PDC name, free it
  165.         //
  166.  
  167.         NetApiBufferFree(wComputerName);
  168.     }
  169.  
  170.     if(nas != NERR_Success) {
  171.         DisplayErrorText( nas );
  172.         return RTN_ERROR;
  173.     }
  174.  
  175.     return RTN_OK;
  176. }
  177.  
  178. void
  179. DisplayErrorText(
  180.     DWORD dwLastError
  181.     )
  182. {
  183.     HMODULE hModule = NULL; // default to system source
  184.     LPSTR MessageBuffer;
  185.     DWORD dwBufferLength;
  186.     DWORD dwFormatFlags;
  187.  
  188.     dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
  189.                     FORMAT_MESSAGE_IGNORE_INSERTS |
  190.                     FORMAT_MESSAGE_FROM_SYSTEM ;
  191.  
  192.     //
  193.     // if dwLastError is in the network range, load the message source
  194.     //
  195.     if(dwLastError >= NERR_BASE && dwLastError <= MAX_NERR) {
  196.         hModule = LoadLibraryEx(
  197.             TEXT("netmsg.dll"),
  198.             NULL,
  199.             LOAD_LIBRARY_AS_DATAFILE
  200.             );
  201.  
  202.         if(hModule != NULL)
  203.             dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
  204.     }
  205.  
  206.     //
  207.     // call FormatMessage() to allow for message text to be acquired
  208.     // from the system or the supplied module handle
  209.     //
  210.     if(dwBufferLength = FormatMessageA(
  211.         dwFormatFlags,
  212.         hModule, // module to get message from (NULL == system)
  213.         dwLastError,
  214.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
  215.         (LPSTR) &MessageBuffer,
  216.         0,
  217.         NULL
  218.         ))
  219.     {
  220.         DWORD dwBytesWritten;
  221.  
  222.         //
  223.         // Output message string on stderr
  224.         //
  225.         WriteFile(
  226.             GetStdHandle(STD_ERROR_HANDLE),
  227.             MessageBuffer,
  228.             dwBufferLength,
  229.             &dwBytesWritten,
  230.             NULL
  231.             );
  232.  
  233.         //
  234.         // free the buffer allocated by the system
  235.         //
  236.         LocalFree(MessageBuffer);
  237.     }
  238.  
  239.     //
  240.     // if we loaded a message source, unload it
  241.     //
  242.     if(hModule != NULL)
  243.         FreeLibrary(hModule);
  244. }
  245.