?
Solved

Best way to get user permissions from VB6

Posted on 2009-12-23
4
Medium Priority
?
1,159 Views
Last Modified: 2012-05-08

Hello, I have the unenviable task of modifying an ancient VB6 program.  Don't know if anyone is still using this stuff, but...

A feature we want to add is to disable certain functions if the user is not logged in to that computer as an administrator.

What is the best way (if I recall there are often a few ways to do things in VB6, but they could be of varying reliability/robustness) for a VB6 app to query the OS as to whether the user is part of the Administrators group?

Thanks very much in advance.
0
Comment
Question by:riceman0
  • 2
4 Comments
 
LVL 15

Assisted Solution

by:greg ward
greg ward earned 800 total points
ID: 26113908
This looks worth a look
http://www.experts-exchange.com/Programming/Languages/Visual_Basic/Q_22812226.html
Private Declare Function IsUserAnAdmin Lib "shell32" () As Long
   

Private Sub Form_Load()

   Command1.Caption = "IsUserAnAdmin"
   Label1.Caption = ""
   
End Sub

   
Private Sub Command1_Click()
 
   Select Case IsUserAnAdmin()
      Case 1:
         Label1.Caption = "YES"
         
      Case False:
         Label1.Caption = "NO"
   End Select

End Sub

Greg
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 26113955
Don't check against being a member of the Administrator group because on newer operating systems ex. Vista, Win7 each process is given a split token which means you can be a member of Administrative group but it doesn't mean the process has administrative rights.
Option Explicit

Private Const TOKEN_DUPLICATE = &H2&
Private Const TOKEN_QUERY = &H8&
Private Const ERROR_NO_TOKEN = 1008

Private Const SECURITY_BUILTIN_DOMAIN_RID = &H20&
Private Const DOMAIN_ALIAS_RID_ADMINS = &H220&
Private Const SECURITY_NT_AUTHORITY = &H5&

Private Type SID_IDENTIFIER_AUTHORITY
Value(6) As Byte
End Type

Private Enum SECURITY_IMPERSONATION_LEVEL
SecurityAnonymous
SecurityIdentification
SecurityImpersonation
SecurityDelegation
End Enum

Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, ByRef TokenHandle As Long) As Long
Private Declare Function OpenThreadToken Lib "advapi32" (ByVal ThreadHandle As Long, ByVal DesiredAccess As Long, ByVal OpenAsSelf As Long, ByRef TokenHandle As Long) As Long
Private Declare Function AllocateAndInitializeSid Lib "advapi32" (ByRef pIdentifierAuthority As SID_IDENTIFIER_AUTHORITY, ByVal nSubAuthorityCount As Byte, ByVal nSubAuthority0 As Long, ByVal nSubAuthority1 As Long, ByVal nSubAuthority2 As Long, ByVal nSubAuthority3 As Long, ByVal nSubAuthority4 As Long, ByVal nSubAuthority5 As Long, ByVal nSubAuthority6 As Long, ByVal nSubAuthority7 As Long, ByRef lpPSid As Long) As Long
Private Declare Function CheckTokenMembership Lib "advapi32" (ByVal TokenHandle As Long, ByVal SidToCheck As Long, ByRef IsMember As Long) As Long
Private Declare Function DuplicateToken Lib "advapi32" (ByVal ExistingTokenHandle As Long, ByVal ImpersonationLevel As Long, ByRef DuplicateTokenHandle As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function GetCurrentThread Lib "kernel32" () As Long
Private Declare Sub FreeSid Lib "advapi32.dll" (ByVal pSid As Long)

Public Function IsInRoleAdmin() As Boolean

    Dim NtAuthority As SID_IDENTIFIER_AUTHORITY
    Dim AdminGroup As Long
    Dim Success As Long
    Dim hToken As Long
    Dim hTokenDup As Long

    If OpenThreadToken(GetCurrentThread, TOKEN_DUPLICATE Or TOKEN_QUERY, True, hToken) = 0 Then
        OpenProcessToken GetCurrentProcess, TOKEN_DUPLICATE Or TOKEN_QUERY, hToken
    End If
    
    If DuplicateToken(hToken, SecurityImpersonation, hTokenDup) Then
        ' Well-known SIDs
        NtAuthority.Value(5) = SECURITY_NT_AUTHORITY
        ' allocates and initializes a security identifier (SID)
        Success = AllocateAndInitializeSid(NtAuthority, 2, _
            SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, AdminGroup)
        If Success Then
            If CheckTokenMembership(hTokenDup, AdminGroup, Success) = 0 Then
                Success = 0
            End If
        FreeSid AdminGroup
        End If
    End If
    
    IsInRoleAdmin = Success
    
    CloseHandle hToken
    CloseHandle hTokenDup
    
End Function

Open in new window

0
 

Author Comment

by:riceman0
ID: 26116301
egl1044, I guess I'm not sure what it means for a process to have different rights than a user.  I guess our requirement is (not surprisingly) incomplete: "only users with administrator privileges will be able to do X"

So the right thing to do is to check both "sides" of the token?

How does a process get granted permissions?  I assume by default a process has the permissions of the user who starts it?

Thanks for the extra info.
0
 
LVL 29

Accepted Solution

by:
nffvrxqgrcfqvvc earned 1200 total points
ID: 26116547
This would be the case on Windows XP where an administrator that runs a process is by default granted the administrative token. However on OS using user account control the processes are launched with split tokens this means although you may be using an administrative account the process itself is running as a standard user. This would be like running on a limited account on Window XP regardless if that account was administrator or belongs to the administrative group.

I would recommend reading the following documentation. This will give you a better understanding of how UAC works.
http://msdn.microsoft.com/en-us/library/bb756973.aspx

Deepraw example is also correct and if you look at the documentation for that API call it's a wrapper for CheckTokenMembership. The one line API internally is doing the same thing that I have shown in my code snippet although microsoft warns you that it might not be supported in later versions so that is something to consider I can confirm it does work up to Windows 7 for now. I don't know if it would work with impersonation token where you might call ImpersonateLoggedOnUser() LogOnUser() to imperonate another account. It might return incorrect information in that sense but I would need to test that to be sure. I personally wouldn't use it for anything commercial but it should be okay for personal use.
IsUserAnAdmin
http://msdn.microsoft.com/en-us/library/bb776463(VS.85).aspx

0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Suggested Courses
Course of the Month8 days, 7 hours left to enroll

616 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question