Browse DevX
Sign up for e-mail newsletters from DevX

Tip of the Day
Language: NT
Expertise: Beginner
Oct 21, 1998



Building the Right Environment to Support AI, Machine Learning and Deep Learning

Reset NT password with 'User Must Change Password'

We are trying to reset the NT password using structure USER_INFO_1003. Everything worked fine. Then we also needed to set 'User Must Change Password at Next Logon' option. There is no structure just to change that. What I can find is that the only structure I can use is USER_INFO_3. This means that I have to user NetUserGetInfo() API to get all the user info using USER_INFO_3 and then use NetUserSetInfo() API to reset everything back except 'usri3_password_expired' value. This seems like a lot of work just to change one data value. On top of everything, I haven't been able to get this to work using both APIs. I get an error code 87: invalid parameter value. I am using VB6 for this.

It may be a lot of work, but it is the way you will have to do it. The following will reset the "Test guest account" to force a password change on the next logon. Note that this will work on a LOCAL machine. If you want to do it remotely, you must pass the Server name to the function.

Private Sub Command1_Click()
   Dim p_strUserName          As String
   p_strUserName = "Test guest account"
   If Module1.MustChangePassword(p_strUserName) = True Then
      MsgBox "Successfully set 'Must Change Password' for user '" & _
         p_strUserName & "'."
      MsgBox "Failed setting 'Must Change Password' for user '" & _
         p_strUserName & "'."
   End If
End Sub

IN BAS or CLS file:
Option Explicit

Public Declare Sub CopyMem Lib "kernel32" Alias _
   "RtlMoveMemory" (pTo As Any, pFrom As Any, _
   ByVal lCount As Long)
Private Declare Function NetApiBufferFree _
   Lib "netapi32.dll" _
   (ByVal lngPtrBuffer As Long) As Long
Private Declare Function NetUserSetInfo _
   Lib "netapi32" _
   (psServer As Byte, _
    psUser As Byte, _
    ByVal lLevel As Long, _
    ByVal pPtrBuffer As Long, _
    ParmErr As Long) As Long
Private Declare Function NetUserGetInfo _
   Lib "netapi32" _
   (ServerName As Byte, _
    UserName As Byte, _
    ByVal Level As Long, _
    lpBuffer As Long) As Long

Private Const NERR_Success As Long = 0&
Private Const UserInfo3 As Long = 3&

Private Type USER_INFO_3_API
   usri3_name              As Long
   usri3_password          As Long
   usri3_password_age      As Long
   usri3_priv              As Long
   usri3_home_dir          As Long
   usri3_comment           As Long
   usri3_flags             As Long
   usri3_script_path       As Long
   usri3_auth_flags        As Long
   usri3_full_name         As Long
   usri3_usr_comment       As Long
   usri3_parms             As Long
   usri3_workstations      As Long
   usri3_lastlogon         As Long
   usri3_lastlogoff        As Long
   usri3_acct_expires      As Long
   usri3_max_storage       As Long
   usri3_units_per_week    As Long
   usri3_logon_hours       As Long
   usri3_bad_pw_count      As Long
   usri3_num_logons        As Long
   usri3_logon_server      As Long
   usri3_country_code      As Long
   usri3_code_page         As Long
   usri3_user_id           As Long
   usri3_primary_group_id  As Long
   usri3_profile           As Long
   usri3_home_dir_drive    As Long
   usri3_password_expired  As Long
End Type

Public Function MustChangePassword(ByVal xi_strUserName As String) As Boolean
   Dim p_typUserInfo3API   As USER_INFO_3_API
   Dim p_bytSvrName()      As Byte
   Dim p_bytUserName()     As Byte
   Dim p_strServerName     As String
   Dim p_lngBuffer         As Long
   Dim p_lngParmErr        As Long
   Dim p_lngRtn            As Long
   ' ------------------------------------------
   ' Convert the server name to byte array
   ' ------------------------------------------
   p_strServerName = vbNullChar
   p_bytSvrName = p_strServerName
   ' ------------------------------------------
   ' Convert the user name to a byte array
   ' ------------------------------------------
   If Len(Trim$(xi_strUserName)) = 0 Then
      Exit Function 'Handle the error
      p_bytUserName = xi_strUserName & vbNullChar
   End If
   ' ------------------------------------------
   ' Get the current info
   ' ------------------------------------------
   p_lngRtn = NetUserGetInfo(p_bytSvrName(0), _
                             p_bytUserName(0), _
                             UserInfo3, _
   If p_lngRtn = NERR_Success Then
      CopyMem p_typUserInfo3API, _
              ByVal p_lngBuffer, _
      MsgBox "Error Number: " & p_lngRtn
   End If
   ' ------------------------------------------
   ' Set the current info
   ' ------------------------------------------
   p_typUserInfo3API.usri3_password_expired = 1
   p_lngBuffer = VarPtr(p_typUserInfo3API)
   p_lngRtn = NetUserSetInfo(p_bytSvrName(0), _
                             p_bytUserName(0), _
                             UserInfo3, _
                             p_lngBuffer, _
   If p_lngRtn = NERR_Success Then
      CopyMem p_typUserInfo3API, _
              ByVal p_lngBuffer, _
      MustChangePassword = True
      MsgBox "Error Number: " & p_lngRtn
   End If
   ' ------------------------------------------
   ' Clear the buffer
   ' ------------------------------------------
   If p_lngBuffer Then
      NetApiBufferFree p_lngBuffer
   End If
End Function
DevX Pro
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date