Page 1 of 1

Module RunAsAdmin (root rights)

Posted: Thu Nov 08, 2018 7:49 pm
by mk-soft
Sometime we need root rights for programs

Now for OSX and Linux. Only Window is not ready...

Update v1.03
- New login window for linux

Update v1.04
- Linux over pkexec

Update v1.05.1
- Fix macOS
- Now with additional parameters. Last parameter is always "!admin!"

Update v1.06.0
- Added windows

Code: Select all

;-TOP

; Comment : Module RunAsAdmin
; Author  : mk-soft
; Version : v1.06.0
; Date    : 09.11.2018
; Update  : 08.11.2022
; OS      : OSX, Linux

; Thanks to:
; - Airr
; - Wolfram

EnableExplicit

; ***************************************************************************************

;- Begin Module RunAsAdmin

DeclareModule RunAsAdmin
  Declare Login()
EndDeclareModule

; ---

Module RunAsAdmin
  
  ; -----------------------------------------------------------------------------------
  
  CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
    ; Error codes returned by Authorization API.
    Enumeration AuthorizationResult
      #errAuthorizationSuccess                 = 0      ;/* The authorization was successful. */
      #errAuthorizationInvalidSet              = -60001 ;/* The authorization rights are invalid. */
      #errAuthorizationInvalidRef              = -60002 ;/* The authorization reference is invalid. */
      #errAuthorizationInvalidTag              = -60003 ;/* The authorization tag is invalid. */
      #errAuthorizationInvalidPointer          = -60004 ;/* The returned authorization is invalid. */
      #errAuthorizationDenied                  = -60005 ;/* The authorization was denied. */
      #errAuthorizationCanceled                = -60006 ;/* The authorization was cancelled by the user. */
      #errAuthorizationInteractionNotAllowed   = -60007 ;/* The authorization was denied since no user interaction was possible. */
      #errAuthorizationInternal                = -60008 ;/* Unable To obtain authorization For this operation. */
      #errAuthorizationExternalizeNotAllowed   = -60009 ;/* The authorization is Not allowed To be converted To an external format. */
      #errAuthorizationInternalizeNotAllowed   = -60010 ;/* The authorization is Not allowed To be created from an external format. */
      #errAuthorizationInvalidFlags            = -60011 ;/* The provided option flag(s) are invalid For this authorization operation. */
      #errAuthorizationToolExecuteFailure      = -60031 ;/* The specified program could Not be executed. */
      #errAuthorizationToolEnvironmenterror    = -60032 ;/* An invalid status was returned during execution of a privileged tool. */
      #errAuthorizationBadAddress              = -60033 ;/* The requested socket address is invalid (must be 0-1023 inclusive). */
    EndEnumeration
    
    ; Authorization
    #kAuthorizationEmptyEnvironment = #Null
    #kAuthorizationRightExecute = 0 ; UTF8("system.privilege.admin")
    #kAuthorizationFlagDefaults = 0
    #kAuthorizationFlagInteractionAllowed   = (1 << 0)
    #kAuthorizationFlagPreAuthorize = (1 << 4)
    #kAuthorizationFlagExtendRights = (1 << 1)
    
    ; -----------------------------------------------------------------------------------
    
    ; Structures
    Structure AuthorizationItem
      *name ;A zero-terminated string in UTF-8 encoding.
      valueLength.i
      *value       
      flags.i      
    EndStructure
    
    Structure AuthorizationRights
      AuthorizationItemSet.i
      *AuthorizationRights
    EndStructure
    
    Structure CMD
      *parameter[255]
      cmd_terminator.i
    EndStructure
    
    ImportC "-framework Security"
      AuthorizationCreate(rights, environment, flags, *AuthorizationRef)
      AuthorizationExecuteWithPrivileges(AuthorizationRef, cmd, flags, *arguments, file_ptr)
      AuthorizationFree(authRef, flags)
      AuthorizationCopyRights(authorization, *rights, *environment, flags.l, *authorizedRights)
    EndImport
  CompilerEndIf
  
  ; -----------------------------------------------------------------------------------
  
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_MacOS
      Procedure _Login()
        Protected authorizationRef.i, status.i, flags.i, *tool, result.i, cnt, index
        Protected right.AuthorizationItem
        Protected rights.AuthorizationRights
        Protected ArgList.CMD
        
        status = AuthorizationCreate(#Null, #kAuthorizationEmptyEnvironment, #kAuthorizationFlagDefaults, @authorizationRef)
        If status <> #errAuthorizationSuccess
          MessageRequester("Error", "Creating Initial Authorization: Errorcode " + Str(status), #PB_MessageRequester_Error)
        Else
          right\name = UTF8("system.privilege.admin")
          rights\AuthorizationItemSet = 1
          rights\AuthorizationRights = @right
          flags = #kAuthorizationFlagDefaults | #kAuthorizationFlagInteractionAllowed | #kAuthorizationFlagPreAuthorize | #kAuthorizationFlagExtendRights
          status = AuthorizationCopyRights(authorizationRef, @rights, #Null, flags, #Null);
          If status <> #errAuthorizationSuccess
            MessageRequester("Error", "No Authorization Rights: Errorcode " + Str(status), #PB_MessageRequester_Error)
            End
          EndIf
        EndIf
        *tool = UTF8(ProgramFilename())
        cnt = CountProgramParameters()
        For index = 0 To cnt - 1
          ArgList\parameter[index] = UTF8(ProgramParameter(index))
        Next
        ArgList\parameter[cnt] = UTF8("!admin!")
        status = AuthorizationExecuteWithPrivileges(authorizationRef, *tool,  #kAuthorizationFlagDefaults, @ArgList, #Null);
        If status <> #errAuthorizationSuccess
          MessageRequester("Error", "Execute With Privileges: Errorcode " + Str(status))
        EndIf
        For index = 0 To cnt
          FreeMemory(ArgList\parameter[index])
        Next
        End
      EndProcedure
    CompilerCase #PB_OS_Linux
      
      Global WinLogin
      Global Label_Prog, Text_Program, Label_User, Label_Passwd, String_User, String_Passwd, Button_Ok
      
      ; -------------------------------------------------------------------------------
      
      Procedure OpenWinLogin(x = 100, y = 100, width = 420, height = 180)
        WinLogin = OpenWindow(#PB_Any, x, y, width, height, "Login", #PB_Window_SystemMenu)
        Label_Prog = TextGadget(#PB_Any, 10, 10, 90, 25, "Program:")
        Text_Program = TextGadget(#PB_Any, 110, 10, 300, 25, "")
        Label_User = TextGadget(#PB_Any, 10, 50, 90, 25, "User:")
        Label_Passwd = TextGadget(#PB_Any, 10, 80, 90, 25, "Password:")
        String_User = StringGadget(#PB_Any, 110, 50, 300, 25, "")
        String_Passwd = StringGadget(#PB_Any, 110, 80, 300, 25, "", #PB_String_Password)
        Button_Ok = ButtonGadget(#PB_Any, 310, 130, 100, 30, "Ok")
      EndProcedure
      
      ; -------------------------------------------------------------------------------
      
      Procedure _Login()
        Protected cmd.s, program.s, cnt, index, params.s
        
        program = GetFilePart(ProgramFilename())
        cnt = CountProgramParameters()
        For index = 0 To cnt - 1
          params + " " + ProgramParameter(index)
        Next
        params + " !admin!"
        ; pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY PROGRAM_TO_RUN
        cmd = "-c " + #DQUOTE$ + "pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY " + ProgramFilename() + params + #DQUOTE$
        If RunProgram("bash", cmd, "", #PB_Program_Wait)
          End
        Else
          MessageRequester("Error", "Execute With Privileges!", #PB_MessageRequester_Error)
          End
        EndIf
        
      EndProcedure
      
      ; -------------------------------------------------------------------------------
      
      Procedure _LoginSuDo()
        Protected user.s, passwd.s, cmd.s, cnt, index, params.s
        
        OpenWinLogin()
        SetGadgetText(Text_Program, GetFilePart(ProgramFilename()))
        SetGadgetText(String_User, UserName())
        
        Repeat
          Select WaitWindowEvent()
            Case #PB_Event_CloseWindow
              End
            Case #PB_Event_Gadget
              If EventGadget() = Button_Ok
                Break
              EndIf
          EndSelect
        ForEver
        user = GetGadgetText(String_User)
        passwd = GetGadgetText(String_Passwd)
        CloseWindow(WinLogin)
        
        cnt = CountProgramParameters()
        For index = 0 To cnt - 1
          params + " " + ProgramParameter(index)
        Next
        params + " !admin!"
        If user = UserName()
          cmd.s = "-c " + #DQUOTE$ + "echo " + passwd + " | sudo -S " + ProgramFilename() + params + #DQUOTE$
        Else
          cmd.s = "-c " + #DQUOTE$ + "echo " + passwd + " | sudo -u " + user + " -S " + ProgramFilename() + params + #DQUOTE$
        EndIf
        If RunProgram("bash", cmd, "")
          End
        Else
          MessageRequester("Error", "Execute With Privileges!", #PB_MessageRequester_Error)
          End
        EndIf
        
      EndProcedure
      
    CompilerCase #PB_OS_Windows
      Procedure _Login()
        Protected cmd.s, cnt, index, params.s
        
        cnt = CountProgramParameters()
        For index = 0 To cnt - 1
          params + ProgramParameter(index) + " "
        Next
        params + "!admin!"
        If ShellExecute_(0, "runas", ProgramFilename(), params, 0, 0)
          End
        Else
          MessageRequester("Error", "Execute With Privileges!", #PB_MessageRequester_Error)
          End
        EndIf
      EndProcedure
      
  CompilerEndSelect
  
  ; -----------------------------------------------------------------------------------
  
  Procedure Login()
    Protected cnt
    
    cnt = CountProgramParameters()
    If cnt = 0 Or ProgramParameter(cnt - 1) <> "!admin!"
      ProcedureReturn _Login()
    Else
      ProcedureReturn #True
    EndIf
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
EndModule

;- End Module RunAsAdmin

; ***************************************************************************************

CompilerIf #PB_Compiler_IsMainFile
  
  ;IncludeFile "..."
  
  Global cnt, index, params.s
  
  If RunAsAdmin::Login()
    cnt = CountProgramParameters()
    params = "Parameters:" + #LF$
    For index = 0 To cnt - 1
      params + "Index " + index + ": " + ProgramParameter(index) + #LF$
    Next
    MessageRequester("Info", "Program run as admin!" + #LF$ + params, #PB_MessageRequester_Info)
  EndIf
  
CompilerEndIf

Re: Module RunAsAdmin (root rights)

Posted: Fri Nov 09, 2018 1:16 pm
by mk-soft
Update v1.03
- New login window for linux

Re: Module RunAsAdmin (root rights)

Posted: Sun Nov 11, 2018 2:24 pm
by vwidmer
Maybe use pkexec on linux?

https://linux.die.net/man/1/pkexec

Re: Module RunAsAdmin (root rights)

Posted: Sun Nov 11, 2018 3:05 pm
by mk-soft
I had a look at pkexec.
For "pkexec" and GUI applications you have to create a policy file.
So you can't start the program "gedit" without this "police file".

Re: Module RunAsAdmin (root rights)

Posted: Sat Mar 16, 2019 2:43 am
by vwidmer
Maybe some way to use it in one of these other ways?

1)

Code: Select all

pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY PROGRAM_TO_RUN
2)

Code: Select all

https://gist.githubusercontent.com/lentschi/605b031ea32d7c5c0655b5008ed8ee2a/raw/b56b0977803b93f09eeb3d472ac52d3f059eb185/xsudo.sh

Re: Module RunAsAdmin (root rights)

Posted: Sat Mar 16, 2019 12:13 pm
by mk-soft
Work now over pkexec...

Thanks :wink:

Re: Module RunAsAdmin (root rights)

Posted: Tue Nov 08, 2022 9:23 pm
by mk-soft
Update v1.05.1
- Fix macOS
- Now with additional parameters. Last parameter is always "!admin!"

Re: Module RunAsAdmin (root rights)

Posted: Tue Nov 08, 2022 9:58 pm
by mk-soft
Update v1.06.0
- Added windows

Re: Module RunAsAdmin (root rights)

Posted: Mon Mar 11, 2024 3:42 pm
by AZJIO
Is there a function to check if the executable file works with admin rights before requesting them (Linux)?

Code: Select all

id
uid=1000(user) gid=1000(user) groups=1000(user),969(autologin),998(wheel),1001(sudo)

sudo -i
id
uid=0(root) gid=0(root) groups=0(root)