Question:
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_3and 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.
Answer:
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.
IN FORM: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 & "'." Else MsgBox "Failed setting 'Must Change Password' for user '" & _ p_strUserName & "'." End If End SubIN BAS or CLS file:Option ExplicitPublic 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 LongPrivate Declare Function NetUserSetInfo _ Lib "netapi32" _ (psServer As Byte, _ psUser As Byte, _ ByVal lLevel As Long, _ ByVal pPtrBuffer As Long, _ ParmErr As Long) As LongPrivate Declare Function NetUserGetInfo _ Lib "netapi32" _ (ServerName As Byte, _ UserName As Byte, _ ByVal Level As Long, _ lpBuffer As Long) As LongPrivate 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 LongEnd TypePublic 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 Else p_bytUserName = xi_strUserName & vbNullChar End If ' ------------------------------------------ ' Get the current info ' ------------------------------------------ p_lngRtn = NetUserGetInfo(p_bytSvrName(0), _ p_bytUserName(0), _ UserInfo3, _ p_lngBuffer) If p_lngRtn = NERR_Success Then CopyMem p_typUserInfo3API, _ ByVal p_lngBuffer, _ Len(p_typUserInfo3API) Else 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, _ p_lngParmErr) If p_lngRtn = NERR_Success Then CopyMem p_typUserInfo3API, _ ByVal p_lngBuffer, _ Len(p_typUserInfo3API) MustChangePassword = True Else MsgBox "Error Number: " & p_lngRtn End If ' ------------------------------------------ ' Clear the buffer ' ------------------------------------------ If p_lngBuffer Then NetApiBufferFree p_lngBuffer End If End Function