Surf243 Posted September 9, 2016 Share Posted September 9, 2016 Hello, I've been using this UDF to set ACL permissions to some network folders, everything works great (no issues). However, I want to apply these permissions using elevated domain credentials supplied by the user and not the user that's currently running the script. As a temporary solution, I've implemented a RunAs function, but that's not the solution I'm looking for. I'm not fluent with using Dlls, but I have been trying out different methods. My RunAs Function: Func _RunAs($sUser, $sPass) If @Compiled Then RunAs($sUser, @LogonDomain, $sPass, 4, FileGetShortName(@ScriptFullPath), "", @SW_MAXIMIZE) Else RunAs($sUser, @LogonDomain, $sPass, 4, FileGetShortName(@AutoItExe) & " " & FileGetShortName(@ScriptFullPath), "", @SW_MAXIMIZE) EndIf EndFunc ;==>_RunAs I tried LogonUser and I know that I can take that token to ImpersonateLoggedOnUser, but I'm not sure how to implement that or if that's even the right method. I also need to RevertToSelf once completed. Func _LogonUser($sUsername, $sPassword, $sServer = @LogonDomain) ; Returns True if user exists Local $stToken $stToken = DllStructCreate("int") Local $aRet = DllCall("advapi32.dll", "int", "LogonUser", _ "str", $sUsername, "str", $sServer, "str", $sPassword, "dword", 3, "dword", 0, "ptr", DllStructGetPtr($stToken)) ;$hToken = DllStructGetData($stToken, 1) If Not @error And $aRet[0] <> 0 Then Return True EndIf Return False EndFunc ;==>_LogonUser Any assistance, suggestions or idea's would be helpful. Thanks! Link to comment Share on other sites More sharing options...
AdamUL Posted September 9, 2016 Share Posted September 9, 2016 RunAs or RunAsWait does not give you full admin rights (Admin Token), even if the user has admin right on the PC. One workaround you have is to use re-execution. Have a look at this thread for an example. You could also create another script that uses #RequireAdmin, but I prefer re-execution. Here is a more customized script for what I think you are trying to do, it uses RunAsWait and ShellExecuteWait. expandcollapse popupGlobal $sAdminUser = "USERNAME" Global $sAdminPassword = "PASSWORD" Global $sDomain = @LogonDomain Global $iLogOnFlag = 0 Global $sParameters = "" ;Run as the Admin account. If @UserName <> $sAdminUser And Not IsAdmin() Then $sParameters = "" If Not @Compiled Then $sParameters = ' "' & @ScriptFullPath & '"' EndIf ;Use RunAsWait to run as AdminUser, to continue the script as the user that started it, and to wait for the Admin part to Finish. RunAsWait($sAdminUser, $sDomain, $sAdminPassword, $iLogOnFlag, @AutoItExe & $sParameters) If @error Then Exit MsgBox(16 + 262144, "ERROR!", "Unable to run under administrator account.") EndIf ;Request the Admin Token for the Admin account in Windows Vista and Higher. If @UserName = $sAdminUser And Not IsAdmin() And Not StringRegExp(@OSVersion, "_(XP|200(0|3))") Then $sParameters = "" If Not @Compiled Then $sParameters = '"' & @ScriptFullPath & '"' EndIf ;Use ShellExecuteWait to run as AdminUser with Admin Token, to wait for the Admin part of the script to finish, and then to exit. ShellExecuteWait(@AutoItExe, $sParameters, "", "runas") If @error Then Exit MsgBox(16 + 262144, "ERROR!", "Unable to elevate to Admin due to UAC.") Exit EndIf MsgBox(16, @UserName, "Is " & (IsAdmin() ? "" : "Not " ) & "Admin") ;Example ;Admin part of script. If IsAdmin() Then MsgBox (0, "Admin Run Test", "Run Admin part of script and then exit to run as user who started the script.") ;Example ;Exit to finish Admin part of script. Exit EndIf ;Put rest of the non Admin part of script here. If you have any questions, please let me know. Adam Link to comment Share on other sites More sharing options...
Surf243 Posted September 16, 2016 Author Share Posted September 16, 2016 Hey @AdamUL, I really appreciate your response and customized script. I read through your posts and it helped me a lot to understand the process. However, with my script I'm already using #RequireAdmin and my goal was to not to use re-execution (if possible). Luckily, after days of researching I was able to find the solution I was looking for. I copied and modified an already existing function from this post: Hopefully, I've done this correctly but please correct me if needed. expandcollapse popupFunc _LogonOnUser($sUsername, $sPassword, $sServer = @LogonDomain) Local $aRet Local $stToken Local $phToken Local $nError = -1 $stToken = DllStructCreate("int") $aRet = DllCall("advapi32.dll", "int", "LogonUser", _ "str", $sUsername, _ "str", $sServer, _ "str", $sPassword, _ "dword", 8, _ ; LOGON32_LOGON_NETWORK_CLEARTEXT "dword", 0, _ "ptr", DllStructGetPtr($stToken)) $phToken = DllStructGetData($stToken, 1) If Not @error And $aRet[0] <> 0 Then ;Return True ; Return True if user exists $aRet = DllCall("advapi32.dll", "int", "ImpersonateLoggedOnUser", "ptr", $phToken) If Not @error And $aRet[0] <> 0 Then ConsoleWrite("Impersonated User = " & @UserName & @CRLF) ; Do Impersonation Stuff Here _InitiatePermissionResources() ; Requires Permissions UDF Else $aet = DllCall("kernel32.dll", "int", "GetLastError") If Not @error Then $nError = $aRet[0] EndIf DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $phToken) Else $aRet = DllCall("kernel32.dll", "int", "GetLastError") If Not @error Then $nError = $aRet[0] EndIf If $nError > -1 Then SetError($nError) Return 0 EndIf Return 1 EndFunc ;==>_LogOnUser Once the process is completed I then _LogOffUser and RevertToSelf Func _LogOffUser() _ClosePermissionResources() ; Requires Permissions UDF DllCall("advapi32.dll", "int", "RevertToSelf") ConsoleWrite("RevertToSelf User = " & @UserName & @CRLF) EndFunc Permissions Applied Successfully! If I don't use the _LogonOnUser function it errors out and I lose access to my network folders and it disappears! Luckily, I am able to recover it when I use this function. AdamUL 1 Link to comment Share on other sites More sharing options...
AdamUL Posted September 16, 2016 Share Posted September 16, 2016 @Surf243 Your welcome. A very nice find, and nicely created functions. I couldn't tell if the user that you were trying to run under was an admin user or not. My script is used mostly with non admin users. I'm glad your functions work for what you wanted to do. I have added them to my script library. The only issue, and it's really not an issue, is some of the DLL calls could be replaced by _WinAPI_* functions, such as _WinAPI_GetLastError and _WinAPI_CloseHandle. I'm also working with the Permissions UDF. I have found a few issues with it, and have added comments to that thread. Adam Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now