Shell command must be run as root

Hi there,

I’m trying to execute a shell command (pmset) that must be run as root.

I tried with the solution found here Run shell as root which is:

var Author as AuthorizationMBS
author=new AuthorizationMBS
if Author.SimpleNewAuthorization then
  var s(-1) as String
  s.add « -R
  Author.Execute("/bin/echo",s,true)
  
  if Author.LastError= 0 then
    // do whatever you want that needs the users password.
    // for example using the Xojo Shell that would need sudo
    var terminal as new shell
    terminal.Execute "/bin/pmset parameters »
    do
    loop until not terminal.IsRunning
    msgbox terminal.ReadAll
  end
end

I‘m getting the default password prompt.
I’m getting an error "pmset: Must be run as root to modify settings ».
Author.Authorized is False

It seems Author.SimpleNewAuthorization does not elevate to root level.

I’ve tried to use Author.Authorize (from the doc here) but I can’t find any MBS example, here is my code:

Var Author As AuthorizationMBS
Author =New AuthorizationMBS
Author.KeepRights = True

Var s As AuthorizationItemSetMBS
Var i As AuthorizationItemMBS
Var Flags As Integer

// check whether use is admin
s=New AuthorizationItemSetMBS
i=New AuthorizationItemMBS
i.Name="com.mycompany.myapplication.command1"
s.Append i

If Author.NewAuthorization(Nil,Author.kAuthorizationFlagDefaults) Then // create
  Flags=BitwiseOr(Author.kAuthorizationFlagExtendRights,Author.kAuthorizationFlagInteractionAllowed)
 
Author.Authorize(s,flags)

  If Author.LastError= 0 Then
    // do whatever you want that needs the users password.
    // for example using the Xojo Shell that would need sudo
    

Here Author.Authorized is True
But I’m getting the same error: « pmset: Must be run as root to modify settings ».

Does someone know how to run a shell command using root privileges ?

Running Xojo 2024r4.1 on macOS 15.3.2 (x64).

Thanks !

You have managed to totally confuse yourself. You need a script to run IN AuthorizationMBS and not use a new shell:

dim TempFile as FolderItem = Folderitem.TemporaryFile
if TempFile = Nil then
  globals.theErrorLog.DialogErrorProceed(kErrorAddScheduler + " " + "xxx")
  globals.theErrorLog.LogItem(CurrentMethodName + " no temp file")
  Return
end if
dim TempBinary as BinaryStream = BinaryStream.Open(TempFile, True)
if TempBinary = Nil then
  globals.theErrorLog.DialogErrorProceed(kErrorAddScheduler + " " + "xxx")
  globals.theErrorLog.LogItem(CurrentMethodName + " temp file no open")
  Return
end if

dim plistFile as String = "/Users/" + getUsername + "/Library/LaunchAgents/" + BundleID + "-helper.launchd.plist"
TempBinary.Write("#!/bin/sh" + EndOfLine.UNIX + "launchctl bootstrap gui/" + getUserID + " " + plistFile)
TempBinary.Close

'set permissions for shell script
dim theShell as new Shell
theShell.Execute("chmod 777 " + TempFile.ShellPath)
if theShell.ExitCode <> 0 then
  globals.theErrorLog.DialogErrorProceed(kErrorAddScheduler + " " + "xxx")
  globals.theErrorLog.LogItem(CurrentMethodName + " error chmod " + str(theShell.ExitCode))
  Return
end if

'do Authorization
if theAuthorisation = nil then
  theAuthorisation = new AuthorizationMBS
  theAuthorisation.KeepRights = true
  if not theAuthorisation.SimpleNewAuthorization then Return
end if

dim s(-1) as string
theAuthorisation.Execute(TempFile.UnixpathMBS, s, true)
if theAuthorisation.LastError = 0 then
  dim theResult as Integer = theAuthorisation.Wait
  #Pragma Unused theResult
else
  globals.theErrorLog.DialogErrorProceed(kErrorAddScheduler + " " + Str(theAuthorisation.LastError))
end if
1 Like

Hi,
Yes I’m confused, that’s why I’m seeking help :sweat_smile:.
Thanks for your your code, I’ll try something similar and let you know.

Best regards

Hi Beatrix,

Confusion is gone. Now it’s fine.
Thanks a lot.

Olivier

1 Like

et la solution est ?

Solution is to do something similar to the one proposed by Beatrix and use or build a script to run the commands needing root privileges.