Getting User Admin Rights

E

Edward Thrashcort

What's the recommended way to determine if the current user has Windows
NT(XP) Administrator's rights?



Eddie
 
E

Edward Thrashcort

No-one?

I'm trying to determine whether to use a value read from HKEY_CURRENT_USER
or HKEY_LOCAL_MACHINE, depending on the user's admin rights.

Presumably there is a standard way to do this?
eg HKEY_CURRENT_USER/???/UserAdminRights or something

Eddie
 
J

Jay Freedman

Hi Eddie,

I have a partial answer, but with a big hole in it.

There isn't AFAIK a registry entry of the kind you mentioned. The logged-in
user is validated against the permissions granted to whatever user groups
that login belongs to.

There's a Win32 API for getting the privileges (and a ton of other info)
about a user whose login is listed in the Users list. The function is
NetUserGetInfo(). Below I'll post a macro that uses the function.

The hole is that you can (and I almost always do) log in with credentials
supplied by Active Directory in a domain. As long as that login is a member
of a user group, it doesn't have to be listed in the Users list. When you
feed that login name to the NetUserGetInfo() function, you get back a "user
not found" error. I don't know how to work around that, and I don't have any
more time to play with it.

--
Regards,
Jay Freedman
Microsoft Word MVP

Code tweaked into VBA from the sample VB at http://www.allapi.net ... Fix
any lines broken by the newsgroup before trying to run it.

Const NERR_Success = 0
Private Const NERR_BASE = 2100
Private Const NERR_InvalidComputer = (NERR_BASE + 251)
Private Const NERR_UserNotFound = (NERR_BASE + 121)
Const CP_ACP = 0
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 Byte
usri3_bad_pw_count As Long
usri3_num_logons As Long
usri3_logon_server As String
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" (lpServer As Any,
UserName As Byte, ByVal Level As Long, lpBuffer As Long) As Long
Private Declare Function NetApiBufferFree Lib "netapi32" (ByVal Buffer As
Long) As Long
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest
As Any, pSource As Any, ByVal dwLength As Long)
Private Declare Function lstrlenW Lib "kernel32" (lpString As Any) As Long
Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal codepage
As Long, ByVal dwFlags As Long, lpWideCharStr As Any, ByVal cchWideChar As
Long, lpMultiByteStr As Any, ByVal cchMultiByte As Long, ByVal lpDefaultChar
As String, ByVal lpUsedDefaultChar As Long) As Long
' Returns an ANSI string from a pointer to a Unicode string.
Public Function GetStrFromPtrW(lpszW As Long) As String
Dim sRtn As String
sRtn = String$(lstrlenW(ByVal lpszW) * 2, 0) ' 2 bytes/char
' WideCharToMultiByte also returns Unicode string length
Call WideCharToMultiByte(CP_ACP, 0, ByVal lpszW, -1, ByVal sRtn,
Len(sRtn), 0, 0)
GetStrFromPtrW = GetStrFromBufferA(sRtn)
End Function
' Returns the string before first null char encountered (if any) from an
ANSII string.
Public Function GetStrFromBufferA(sz As String) As String
If InStr(sz, vbNullChar) Then
GetStrFromBufferA = Left$(sz, InStr(sz, vbNullChar) - 1)
Else
' If sz had no null char, the Left$ function
' above would return a zero length string ("").
GetStrFromBufferA = sz
End If
End Function

Private Sub Test()
'KPD-Team 2001
'URL: http://www.allapi.net/
'E-Mail: (e-mail address removed)
Dim lpBuf As Long
Dim ui3 As USER_INFO_3
Dim bServer() As Byte, bUsername() As Byte
Dim strUsername As String
Dim nRet As Long
Dim strPriv As Variant
strPriv = Array("Guest", "User", "Administrator")
strUsername = Environ("userdomain") & "\" & UCase(Environ("username"))

bServer = "" & vbNullChar
bUsername = strUsername & vbNullChar

nRet = NetUserGetInfo(bServer(0), bUsername(0), 3, lpBuf)
Select Case nRet
Case NERR_Success
Call MoveMemory(ui3, ByVal lpBuf, Len(ui3))
MsgBox GetStrFromPtrW(ui3.usri3_name) & " has " &
strPriv(ui3.usri3_priv) & " privileges"
Call NetApiBufferFree(ByVal lpBuf)
Case NERR_UserNotFound
MsgBox "The user name " & strUsername & " was not found"
Case NERR_InvalidComputer
' should never get here with null computer name
MsgBox "Invalid computer"
Case Else
MsgBox "Unrecognized return value: " & nRet
End Select
End Sub
 
E

Edward Thrashcort

Thanks Jay I'll try that over the weekend

What do you think of these ideas?

1. Write a registry entry to, say HKEY_LOCAL_MACHINE/Software
2. Read it back to confirm
3. Delete it
If not successful, the no Admin rights

1. Copy a file to the windows folder (If I can determine where that is)
2. DIR() the file
3. Delete it
If not successful, the no Admin rights

*From:* "Jay Freedman" <[email protected]>
*Date:* Fri, 14 Oct 2005 12:00:59 -0400

Hi Eddie,

I have a partial answer, but with a big hole in it.

There isn't AFAIK a registry entry of the kind you mentioned. The
logged-in
user is validated against the permissions granted to whatever user groups
that login belongs to.

There's a Win32 API for getting the privileges (and a ton of other info)
about a user whose login is listed in the Users list. The function is
NetUserGetInfo(). Below I'll post a macro that uses the function.

The hole is that you can (and I almost always do) log in with credentials
supplied by Active Directory in a domain. As long as that login is a
member
of a user group, it doesn't have to be listed in the Users list. When you
feed that login name to the NetUserGetInfo() function, you get back a
"user
not found" error. I don't know how to work around that, and I don't have
any
more time to play with it.

--
Regards,
Jay Freedman
Microsoft Word MVP

Code tweaked into VBA from the sample VB at http://www.allapi.net ... Fix
any lines broken by the newsgroup before trying to run it.

Const NERR_Success = 0
Private Const NERR_BASE = 2100
Private Const NERR_InvalidComputer = (NERR_BASE + 251)
Private Const NERR_UserNotFound = (NERR_BASE + 121)
Const CP_ACP = 0
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 Byte
usri3_bad_pw_count As Long
usri3_num_logons As Long
usri3_logon_server As String
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" (lpServer As Any,
UserName As Byte, ByVal Level As Long, lpBuffer As Long) As Long
Private Declare Function NetApiBufferFree Lib "netapi32" (ByVal Buffer As
Long) As Long
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest
As Any, pSource As Any, ByVal dwLength As Long)
Private Declare Function lstrlenW Lib "kernel32" (lpString As Any) As Long
Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal
codepage
As Long, ByVal dwFlags As Long, lpWideCharStr As Any, ByVal cchWideChar As
Long, lpMultiByteStr As Any, ByVal cchMultiByte As Long, ByVal
lpDefaultChar
As String, ByVal lpUsedDefaultChar As Long) As Long
' Returns an ANSI string from a pointer to a Unicode string.
Public Function GetStrFromPtrW(lpszW As Long) As String
Dim sRtn As String
sRtn = String$(lstrlenW(ByVal lpszW) * 2, 0) ' 2 bytes/char
' WideCharToMultiByte also returns Unicode string length
Call WideCharToMultiByte(CP_ACP, 0, ByVal lpszW, -1, ByVal sRtn,
Len(sRtn), 0, 0)
GetStrFromPtrW = GetStrFromBufferA(sRtn)
End Function
' Returns the string before first null char encountered (if any) from an
ANSII string.
Public Function GetStrFromBufferA(sz As String) As String
If InStr(sz, vbNullChar) Then
GetStrFromBufferA = Left$(sz, InStr(sz, vbNullChar) - 1)
Else
' If sz had no null char, the Left$ function
' above would return a zero length string ("").
GetStrFromBufferA = sz
End If
End Function

Private Sub Test()
'KPD-Team 2001
'URL: http://www.allapi.net/
'E-Mail: (e-mail address removed)
Dim lpBuf As Long
Dim ui3 As USER_INFO_3
Dim bServer() As Byte, bUsername() As Byte
Dim strUsername As String
Dim nRet As Long
Dim strPriv As Variant
strPriv = Array("Guest", "User", "Administrator")
strUsername = Environ("userdomain") & "\" & UCase(Environ("username"))

bServer = "" & vbNullChar
bUsername = strUsername & vbNullChar

nRet = NetUserGetInfo(bServer(0), bUsername(0), 3, lpBuf)
Select Case nRet
Case NERR_Success
Call MoveMemory(ui3, ByVal lpBuf, Len(ui3))
MsgBox GetStrFromPtrW(ui3.usri3_name) & " has " &
strPriv(ui3.usri3_priv) & " privileges"
Call NetApiBufferFree(ByVal lpBuf)
Case NERR_UserNotFound
MsgBox "The user name " & strUsername & " was not found"
Case NERR_InvalidComputer
' should never get here with null computer name
MsgBox "Invalid computer"
Case Else
MsgBox "Unrecognized return value: " & nRet
End Select
End Sub


Eddie
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top