|
|
![]() |
|
||
|
|
|||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||
| Visual Basic Network Services NetUserSetInfo: Enable/Disable User Accounts (USER_INFO_3) |
||
| Posted: | Sunday December 19, 2004 | |
| Updated: | Monday December 26, 2011 | |
| Applies to: | VB4-32, VB5, VB6 | |
| Developed with: | VB6, Windows NT4 | |
| OS restrictions: | Windows NT4 / Windows 2000, Windows XP, Windows 2003 | |
| Author: | VBnet - Randy Birch | |
|
Related: |
NetUserGetInfo: Enumerate the User List and Obtain User Info NetUserSetInfo: Disable User Accounts (USER_INFO_1008) NetUserSetInfo: Enable/Disable User Accounts (USER_INFO_3) |
|
| Prerequisites |
| One of the operating systems listed above. |
|
|
Compared
to NetUserSetInfo: Disable User Accounts (USER_INFO_1008),
this is a more in-depth demo showing not only how to disable the user's
account, but also how to enable it and how to determine the disabled
status of the account.
The demo starts by retrieving a user's info via NetUserGetInfo into a USER_INFO_3 structure, where we can toggle the bit allowing to enable or disable the user's account. NetUserSetInfo is then called to write out the revised USER_INFO_3 structure. The demo provides the means to disable or enable the specified account, and returns a number of different error status codes representing the success of the call or the point of failure. The code below takes care of creating the form shown. Note that the MSDN has some apparently contradictory information regarding the USER_INFO_3 structure: on one hand it states that USER_INFO_4 is the preferred structure to use, while on the other hand it states that USER_INFO_4 is not supported under Windows 2000/NT. Both are identical in the definition of their members, both in name and data type, as well as having the structure members in the same order. This means that to use the USER_INFO_4 structure rather than 3, only the specification of the user level is different in the NetUserGetInfo and NetUserSetInfo calls. Because this was developed on NT-based XP I elected to use the level 3 designation for this demo - feel free to use 4 if you understand the requirements. Note that only members of the Administrators or Account Operators local group can successfully execute the NetUserSetInfo function on a remote server or on a computer that has local security enabled. |
| BAS Module Code |
| None. |
|
|
| Form Code |
|
|
| You can clone the form used in the NetUserSetInfo: Disable User Accounts (USER_INFO_1008) demo, or start a new project and add a command button (Command1), one text boxes (Text1), a check box (Check1) and two labels (Label1, Label2), along with the following code: |
|
|
Option Explicit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved. ' Some pages may also contain other copyrights by the author. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Distribution: You can freely use this code in your own ' applications, but you may not reproduce ' or publish this code on any web site, ' online service, or distribute as source ' on any media without express permission. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Private Const ERROR_SUCCESS As Long = 0
Private Const UF_ACCOUNTDISABLE As Long = &H2
'our defined constants for errors
'we might encounter
Private Const ERR_ACCOUNT_CHANGED As Long = &H0
Private Const ERR_ACCOUNT_ALREADY_DISABLED As Long = -&H10
Private Const ERR_ACCOUNT_ALREADY_ENABLED As Long = -&H20
Private Const ERR_ACCOUNT_NOT_FOUND As Long = -&H40
Private Const ERR_UPDATE_NOT_SUCCESSFUL As Long = -&H80
Private Type USER_INFO_3
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_last_logon As Long
usri3_last_logoff 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
Private Declare Function NetUserGetInfo Lib "Netapi32" _
(servername As Byte, _
username As Byte, _
ByVal level As Long, _
bufptr As Long) As Long
Private Declare Function NetUserSetInfo Lib "Netapi32" _
(servername As Byte, _
username As Byte, _
ByVal level As Long, _
bufptr As Long, _
parm_err As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" _
(pTo As Any, _
uFrom As Any, _
ByVal lSize As Long)
Private Declare Function NetApiBufferFree Lib "Netapi32" _
(ByVal Buffer As Long) As Long
Private Sub Form_Load()
With Label1
.Caption = "Account:"
.AutoSize = True
.Move 200, 400
End With
With Text1
.Text = "(enter a user name)"
.Move 1000, 360, 1600, 285
End With
With Label2
.Caption = "(result)"
.AutoSize = True
.WordWrap = True
.Move 2800, 400, 2200
End With
With Check1
.Caption = "Disable this account"
.Move 1000, 800, 2600, 345
End With
With Command1
.Caption = "Change Account"
.Move 1000, 1200, 1600, 345
End With
End Sub
Private Sub Command1_Click()
Dim bLockout As Boolean
Dim sUser As String
Dim buff As String
Dim success As Long
'set-up
bLockout = Check1.Value = vbChecked
sUser = Text1.Text
'call
success = DisableAccount(bLockout, sUser, "")
'results (using our defined error codes)
Select Case success
Case ERR_ACCOUNT_CHANGED
buff = "NetUserSetInfo completed successfully"
Case ERR_ACCOUNT_ALREADY_DISABLED
buff = "The specified account is already disabled"
Case ERR_ACCOUNT_ALREADY_ENABLED
buff = "The specified account is already enabled"
Case ERR_ACCOUNT_NOT_FOUND
buff = "The specified account or server was not found"
Case ERR_UPDATE_NOT_SUCCESSFUL
buff = "The call to NetUserSetInfo failed"
Case Else
buff = "Unknown error"
End Select
Label2.Caption = buff
End Sub
Private Function DisableAccount(bDisableAccount As Boolean, _
sUsername As String, _
Optional sServer As String = vbNullString) As Long
Dim parm_err As Long
Dim success As Long
Dim buff As Long
Dim bServer() As Byte
Dim bUser() As Byte
Dim ui3 As USER_INFO_3
bUser = sUsername & vbNullChar
bServer = QualifyServer(sServer) & vbNullChar
'retrieve the user info into a buffer
success = NetUserGetInfo(bServer(0), bUser(0), 3, buff)
If success = ERROR_SUCCESS Then
'copy it to a USER_INFO_3 structure
CopyMemory ui3, ByVal buff, Len(ui3)
'if the flag is disable
If bDisableAccount = True Then
'and the account already isn't
If (ui3.usri3_flags And UF_ACCOUNTDISABLE) <> UF_ACCOUNTDISABLE Then
'toggle the flag
ui3.usri3_flags = ui3.usri3_flags Or UF_ACCOUNTDISABLE
Else
'it's already disabled
DisableAccount = ERR_ACCOUNT_ALREADY_DISABLED
Call NetApiBufferFree(buff)
Exit Function
End If 'ui3.usri3_flags)
Else
'the account should be enabled,
'so if it is currently disabled
If (ui3.usri3_flags And UF_ACCOUNTDISABLE) = UF_ACCOUNTDISABLE Then
'toggle the flag
ui3.usri3_flags = ui3.usri3_flags Xor UF_ACCOUNTDISABLE
Else
'it's already enabled
DisableAccount = ERR_ACCOUNT_ALREADY_ENABLED
Call NetApiBufferFree(buff)
Exit Function
End If 'ui3.usri3_flags
End If 'bDisableAccount
'copy the structure back to the buffer,
'call NetUserSetInfo and clean up
CopyMemory ByVal buff, ui3, ByVal Len(ui3)
success = NetUserSetInfo(bServer(0), _
bUser(0), _
3, _
ByVal buff, _
parm_err)
NetApiBufferFree buff
If success = ERROR_SUCCESS Then
DisableAccount = ERR_ACCOUNT_CHANGED
Else
'something prevented the change
DisableAccount = ERR_UPDATE_NOT_SUCCESSFUL
End If
Else
'the call to obtain the userinfo failed,
'probably because the account or server
'passed was incorrect
DisableAccount = ERR_ACCOUNT_NOT_FOUND
End If 'success = 0
End Function
Private Function QualifyServer(ByVal sServer As String) As String
'if nullstring was passed, the
'API does not expect slashes in
'the server name
If Len(sServer) > 0 Then
'are already two slashes
'preceeding the server name?
If Left$(sServer, 2) = "\\" Then
'there are, so the server is already
'qualified; return the passed string
QualifyServer = sServer
Else
'there aren't two, but is there one?
If Left$(sServer, 1) = "\" Then
'yes, so add one more
QualifyServer = "\" & sServer
Else
'the string needs both
QualifyServer = "\\" & sServer
End If 'Left$(sServer, 1) <> "\"
End If 'Left$(sServer, 2) = "\\"
Else
'empty string passed, so return it
QualifyServer = sServer
End If 'Len(sServer)
End Function
|
| Comments |
|
|
|
|
|
|||||
|
|||||
|
|
|||||
|
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |
![]() |