Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

AdjustTokenPrivilages 3

Status
Not open for further replies.

ADoozer

Programmer
Dec 15, 2002
3,487
AU
ok here goes!

im using code provided in thread222-601022

the return code from the AdjustTokenPrivilages is 1, how do i determine what the new privilages are.

i read its something to do with the NewState and PreviousState, but i dont know how to determine exactly what that means! (in other words its just a bunch of numbers to me!)

the only thing that changes is that:-

NewTokenStuff.Privilages(0).Attributes=2

does that mean i succesfully changed my Atributes???

any help appreciated!

thnx in advance!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
To get the best response to a question, please check out FAQ222-2244 first
A General Guide To Excel in VB FAQ222-3383
 
Nothing. As I've said before, I've only tried it on XP Pro and NT4SP6, where it works.
 
mattknight! thank you!

i was resigned to the fact it was just me or my machine!

im not going insane after all!!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
come on... get involved!
To get the best response to a question, please check out FAQ222-2244 first
A General Guide To Excel in VB FAQ222-3383
 
I am looking at creating some software for use inhouse that requires this sort of coding.

I have used the code and find that if I click on command Button 1 then i get a Impersonation sucessful message.

However clicking on Command button 2 I recieve the error message number 5 AdjustToken Access is Denied.

Can I assume in that case that the AdjustToken function is not needed?

This happens when the code in command 1 if for a standard user and I click on command 1 then command 2.

If I click on command 2 before command 1 then I get the message Error 1300 Adjust Token:Not all privledges referenced are assigned to the caller.



Greg Palmer

----------------------------------------
Any feed back is appreciated.
 
ok first... have the necessary corrections been made in the following lines?

If NOT result Then Err.Raise Err.LastDllError, "MakeMeImpersonate", "ImpersonateLoggedOnUser: " & ApiErrorText(Err.LastDllError)

should read

If result = 0 Then Err.Raise Err.LastDllError, "MakeMeImpersonate", "ImpersonateLoggedOnUser: " & ApiErrorText(Err.LastDllError)

and

If Not result Then Err.Raise Err.LastDllError, "LogonUser", "AdjustToken: " & ApiErrorText(Err.LastDllError)

should read

If result=0 Then Err.Raise Err.LastDllError, "LogonUser", "AdjustToken: " & ApiErrorText(Err.LastDllError)

now the bit i think i understand!

command2 should be clicked before command1 for reasons mentioned in thread222-548282 however its not always neccesaary

as for runtime error5 i was getting that on an xp box because i hadnt altered the raise err bit in the "makemeimpersonate" sub

hope that answers a few questions... and if you get it workin on 2k please let me know!!!!

good luck!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
come on... get involved!
To get the best response to a question, please check out FAQ222-2244 first
A General Guide To Excel in VB FAQ222-3383
 
ADoozer,
I found that on my winxp machine the code worked fine without the 2nd command button. This works fine for commands that will be run within the VB Application. This got me thinking about what would happen if I wanted to execute a external exe file? Alas the code Strongm kindly provided did not allow the execution of external applications. I had a play around and the code below will work for external applications.

****** POST THIS IN A MODULE **********

Code:
Option Explicit

Private Const CREATE_DEFAULT_ERROR_MODE = &H4000000

Private Const LOGON_WITH_PROFILE = &H1
Private Const LOGON_NETCREDENTIALS_ONLY = &H2

Private Const LOGON32_LOGON_INTERACTIVE = 2
Private Const LOGON32_PROVIDER_DEFAULT = 0
   
Private Type STARTUPINFO
    cb As Long
    lpReserved As Long ' !!! must be Long for Unicode string
    lpDesktop As Long  ' !!! must be Long for Unicode string
    lpTitle As Long    ' !!! must be Long for Unicode string
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type

Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadId As Long
End Type

'  LogonUser() requires that the caller has the following permission
'  Permission                        Display Name
'  --------------------------------------------------------------------
'  SE_TCB_NAME                      Act as part of the operating system

'  CreateProcessAsUser() requires that the caller has the following permissions
'  Permission                        Display Name
'  ---------------------------------------------------------------
'  SE_ASSIGNPRIMARYTOKEN_NAME       Replace a process level token
'  SE_INCREASE_QUOTA_NAME           Increase quotas
  
Private Declare Function LogonUser Lib "advapi32.dll" Alias _
        "LogonUserA" _
        (ByVal lpszUsername As String, _
        ByVal lpszDomain As String, _
        ByVal lpszPassword As String, _
        ByVal dwLogonType As Long, _
        ByVal dwLogonProvider As Long, _
        phToken As Long) As Long

Private Declare Function CreateProcessAsUser Lib "advapi32.dll" _
        Alias "CreateProcessAsUserA" _
        (ByVal hToken As Long, _
        ByVal lpApplicationName As Long, _
        ByVal lpCommandLine As String, _
        ByVal lpProcessAttributes As Long, _
        ByVal lpThreadAttributes As Long, _
        ByVal bInheritHandles As Long, _
        ByVal dwCreationFlags As Long, _
        ByVal lpEnvironment As Long, _
        ByVal lpCurrentDirectory As String, _
        lpStartupInfo As STARTUPINFO, _
        lpProcessInformation As PROCESS_INFORMATION) As Long

' CreateProcessWithLogonW API is available only on Windows 2000 and later.
Private Declare Function CreateProcessWithLogonW Lib "advapi32.dll" _
        (ByVal lpUsername As String, _
        ByVal lpDomain As String, _
        ByVal lpPassword As String, _
        ByVal dwLogonFlags As Long, _
        ByVal lpApplicationName As Long, _
        ByVal lpCommandLine As String, _
        ByVal dwCreationFlags As Long, _
        ByVal lpEnvironment As Long, _
        ByVal lpCurrentDirectory As String, _
        ByRef lpStartupInfo As STARTUPINFO, _
        ByRef lpProcessInformation As PROCESS_INFORMATION) As Long
      
Private Declare Function CloseHandle Lib "kernel32.dll" _
        (ByVal hObject As Long) As Long
                             
Private Declare Function SetErrorMode Lib "kernel32.dll" _
        (ByVal uMode As Long) As Long
        
Private Type OSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long
    szCSDVersion As String * 128
End Type
                             
' Version Checking APIs
Private Declare Function GetVersionExA Lib "kernel32.dll" _
    (lpVersionInformation As OSVERSIONINFO) As Integer

Private Const VER_PLATFORM_WIN32_NT = &H2

'********************************************************************

'                   RunAsUser for Windows 2000 and Later
'********************************************************************
Public Function W2KRunAsUser(ByVal UserName As String, _
        ByVal Password As String, _
        ByVal DomainName As String, _
        ByVal CommandLine As String, _
        ByVal CurrentDirectory As String) As Long

    Dim si As STARTUPINFO
    Dim pi As PROCESS_INFORMATION
    
    Dim wUser As String
    Dim wDomain As String
    Dim wPassword As String
    Dim wCommandLine As String
    Dim wCurrentDir As String
    
    Dim Result As Long
    
    si.cb = Len(si)
        
    wUser = StrConv(UserName + Chr$(0), vbUnicode)
    wDomain = StrConv(DomainName + Chr$(0), vbUnicode)
    wPassword = StrConv(Password + Chr$(0), vbUnicode)
    wCommandLine = StrConv(CommandLine + Chr$(0), vbUnicode)
    wCurrentDir = StrConv(CurrentDirectory + Chr$(0), vbUnicode)
    
    Result = CreateProcessWithLogonW(wUser, wDomain, wPassword, _
          LOGON_WITH_PROFILE, 0&, wCommandLine, _
          CREATE_DEFAULT_ERROR_MODE, 0&, wCurrentDir, si, pi)
    ' CreateProcessWithLogonW() does not
    If Result <> 0 Then
        CloseHandle pi.hThread
        CloseHandle pi.hProcess
        W2KRunAsUser = 0
    Else
        W2KRunAsUser = Err.LastDllError
        MsgBox &quot;CreateProcessWithLogonW() failed with error &quot; & Err.LastDllError, vbExclamation
    End If

End Function

'********************************************************************
'                   RunAsUser for Windows NT 4.0
'********************************************************************
Public Function NT4RunAsUser(ByVal UserName As String, _
                ByVal Password As String, _
                ByVal DomainName As String, _
                ByVal CommandLine As String, _
                ByVal CurrentDirectory As String) As Long
Dim Result As Long
Dim hToken As Long
Dim si As STARTUPINFO
Dim pi As PROCESS_INFORMATION

    Result = LogonUser(UserName, DomainName, Password, LOGON32_LOGON_INTERACTIVE, _
                       LOGON32_PROVIDER_DEFAULT, hToken)
    If Result = 0 Then
        NT4RunAsUser = Err.LastDllError
        ' LogonUser will fail with 1314 error code, if the user account associated
        ' with the calling security context does not have
        ' &quot;Act as part of the operating system&quot; permission
        MsgBox &quot;LogonUser() failed with error &quot; & Err.LastDllError, vbExclamation
        Exit Function
    End If
    
    si.cb = Len(si)
    Result = CreateProcessAsUser(hToken, 0&, CommandLine, 0&, 0&, False, _
                CREATE_DEFAULT_ERROR_MODE, _
                0&, CurrentDirectory, si, pi)
    If Result = 0 Then
        NT4RunAsUser = Err.LastDllError
        ' CreateProcessAsUser will fail with 1314 error code, if the user
        ' account associated with the calling security context does not have
        ' the following two permissions
        ' &quot;Replace a process level token&quot;
        ' &quot;Increase Quotoas&quot;
        MsgBox &quot;CreateProcessAsUser() failed with error &quot; & Err.LastDllError, vbExclamation
        CloseHandle hToken
        Exit Function
    End If
    
    CloseHandle hToken
    CloseHandle pi.hThread
    CloseHandle pi.hProcess
    NT4RunAsUser = 0

End Function

Public Function RunAsUser(ByVal UserName As String, _
                ByVal Password As String, _
                ByVal DomainName As String, _
                ByVal CommandLine As String, _
                ByVal CurrentDirectory As String) As Long

    Dim w2kOrAbove As Boolean
    Dim osinfo As OSVERSIONINFO
    Dim Result As Long
    Dim uErrorMode As Long
    
    ' Determine if system is Windows 2000 or later
    osinfo.dwOSVersionInfoSize = Len(osinfo)
    osinfo.szCSDVersion = Space$(128)
    GetVersionExA osinfo
    w2kOrAbove = _
        (osinfo.dwPlatformId = VER_PLATFORM_WIN32_NT And _
         osinfo.dwMajorVersion >= 5)
    If (w2kOrAbove) Then
        Result = W2KRunAsUser(UserName, Password, DomainName, _
                    CommandLine, CurrentDirectory)
    Else
        Result = NT4RunAsUser(UserName, Password, DomainName, _
                    CommandLine, CurrentDirectory)
    End If
    RunAsUser = Result
End Function

Then add a command button and assign the following code:

RunAsUser &quot;UserName&quot;, &quot;PassWord&quot;, &quot;Domain&quot;, &quot;File to be Executed&quot;, &quot;Path of file to be executed&quot;

You do not have to include the domain name, instead you can just add &quot;&quot;.

Hope this helps.


Greg Palmer

----------------------------------------
Any feed back is appreciated.
 
ouch... ill get round to reading the code soon (snowed under at the moment) however a straight copy and paste seemed to work (hence the star)

are we resigned to the fact that logonuser is not compatible with 2k pro then???

thnx for the continued support!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
come on... get involved!
To get the best response to a question, please check out FAQ222-2244 first
A General Guide To Excel in VB FAQ222-3383
 
A quick search on Google reveals a lot of people suffering a similar problem...

Oh, is there anything of interest in the Event logs?
 
yeah.. ive been googling since day 0 lol.. not found much out there!!

honestly dont know... not a tool i use often (or am familiar with)

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
come on... get involved!
To get the best response to a question, please check out FAQ222-2244 first
A General Guide To Excel in VB FAQ222-3383
 
gpalmer:
I use your runasuser program which appears to work well with Win2000, shoudl it also work for Windows NT? It appears not, but maybe something else.

User gets:
Popup &quot;project1&quot; header and worded &quot;logon user() failed with error 1314&quot;

Thanks
 
Can somebody please explain in words of not more than 2 syllables (oops 3) exactly what is a &quot;privlege&quot; and what it is used for and why you ever have to change it?
Is it something like an attribute or a share permission?
Reading through this thread is just like reading Chinese, I can see all the strokes but I dont know what they mean!
 
Sure (but note that there is some simplification in the following explanation_

If you go back to the thread that originally started all this off (thread222-548282) you'll see that the question started out as whether it was possible to run a program (or process) as Administrator (or, more accurately, with Administrator rights).

By default, any program/process that you launch from a particular login account inherits the rights of that login account. So if you are logged in as John Smith, but want to run a program that, say, accesses one of the Administrative shares on a workstation (C$), you'll find that you cannot.

Now this could be solved by logging John Smith out and logging in as Administrator to run the program or process. But sometimes this could be inconvenient, and it is certainly longwinded. Or you could write it as an NT Service that starts up under the Service account. Again, this might not always be appropriate.

So Anaesthesia was looking for an alternative. Simply put, they wanted to know whether it was possible to temporarily get a program/or process to pretend it was running with Admin rights.

As you'll see in that thread, I provide code to do just that (the MakeMeImpersonate function). Don't worry, it doesn't break any security, as you need to know an Admin account name and the relevant password.

However, most normal accounts don't have the right privileges to run the LogonUser function that MakeMeImpersonate uses. So we need to figure out how to do that.

Now, the capability and security rights of a user account (and of a program/process) a represented by what Microsoft call a token. So what we need to do is modify the value of that token to add or alter the rights that the user account has to give it the necessary privileges to run the API call mentioned above (LogonUser).

More succintly, a token represents the various privileges assigned to a user acoount and/or process, and we need to adjust those privileges (my second block of code in the refrenced above referenced thread does just this).

Because this particular part of the code became an issue, it was spun off into a continuation thread (thread222-548282), and then moved to here because it is more an API issue than a VB issue.

Anyway, in summary, all we are doing is:

1. Opening the current privilege token for the current process (OpenProcessToken), which contains all the current privileges of our current process (i.e our VB program)
2. Getting the current status of the particular privilege we are interested in (SE_TCB_NAME)
3 Enabling it if it isn't currently enabled

(and all this just so we can run the MakeMeImpersonate function...)
 
and it still wont run on 2k [cry]

(but having said that ive not played with it for a while now)

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
come on... get involved!
To get the best response to a question, please check out FAQ222-2244 first
A General Guide To Excel in VB FAQ222-3383
 
Thanks but this subject seems far more complicated than I would have imagined.

I will have to sit down quietly in one spot and think about it! Is there a resource that explains how accounts and tokens or how the idea of being able to allow one user or not to be able to open up a program really works?

I find the use of the word 'account' rather off putting. I dont know why computer people hijacked the word as it obviously nothing to do with money!
 
Guys,

I have got the code to run on a Win2k machine. I have logged on to a Win2k notebook as a local user who cannot write to the root of c:, i run the neat little app and i can add and remove folders from the root c: without any errors etc. so i assume the code works great!

However (and isnt there always a however!) I was needing the code to be able to change a registry setting in HKEY_CURRENT_USER, but when the code runs it seems to access the registry as the impersonated user, not the user who is actually logged in, so when i change the reg setting it changes it for the wrong user.

I have had this problem with another LoggedOnAsUser function and was hopeing the Token method may get around this problem, but it hasnt.

Any suggestions?
 
Guys,

I have battled on through the day and perused many tek-tips articles and msdn articles and worked out my problem. I just needed to access the HKEY_USERS keys, which required obtaining the SID number, which i have managed to do so everything is working for me now. So no need to post any replies to my premature question.

Thanks
 
Nazgul79: strongm's code or gpalmer711's code works on 2k?

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
come on... get involved!
To get the best response to a question, please check out FAQ222-2244 first
A General Guide To Excel in VB FAQ222-3383
 
ADoozer: i used strongm's code and added a simple mkdir command after the &quot;msgbox MakeMeImpersonate&quot; command to test to see if it was actually giving higher admin rights and it did add/remove folders from the root c:.

i have had problems getting it to work with the registry but feel thats a problem with my registry code, rather that the Impersonate code as i can add/remove folders

i applied the changes you suggested earlier in this Thread before testing it, so i'm not sure if it worked before that or not

my pc's are running Win2k with SP2 btw
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top