Running a Service with sudo administrator privileges - shell

I have the following shell script that I normally run successfully as a system service (created in automator:
#!/bin/bash
for f in "$#"
do ln -s "$f" "${f}.deleteThisExtensionAfterMoving"
echo "${f}.deleteThisExtensionAfterMoving"
done
However, when trying to use this to make symlinks in folders that I'm not the owner of, it fails.
I tried saving it as a script, then using applescript in automator as I've seen described elsewhere here:
on run {input, parameters}
do shell script ("sudo ~/Documents/z_misc/makesymlink '" & POSIX path of input & "'") with administrator privileges
end run
However, upon running the service, I see a "command not found" error.
When I tried saving the script as a .sh file and using that instead, it still didn't work. When I try running from terminal without the preceding "sudo" command, I get a "permission denied" error.

When I try running from terminal without the preceding "sudo" command, I get a "permission denied" error.
The "permission denied" error when attempting to execute a shell script (or binary executable) is typically caused because the file is not set as executable. Use the following command in Terminal:
chmod +x file
Or:
chmod +x /path/to/file
Quoting if there are spaces or escaping spaces with a backslash (\), but not both.
However, the "permission denied" error can also be caused if there is a privileges issue with where the shell script or binary executable is located.
Keeping executables in you Documents folder or any of the default folders, except for Public, within your Home folder can be problematic to Automator actions and for use in Terminal.
I created a bin folder in my Home folder and place my shell scripts and binary executables that I do not want elsewhere, e.g. /use/local/bin, and have added "$HOME/bin" to my PATH.
Here is what I'd use in the Run AppleScript action in my Automator Service/Quick Action:
Example AppleScript code:
on run {input, parameters}
repeat with thisItem in input
set thisItem to the quoted form of the POSIX path of thisItem
do shell script ("$HOME/bin/makesymlink " & thisItem) with administrator privileges
end repeat
end run
As coded, this allows for multiple Finder items to be passed to the Automator Service/Quick Action.
That all said, without seeing the contest of the makesymlink file there is not anything else I can think off at the moment.
From the linked Technical Note below:
Note: Using sudo(8) with with administrator privileges is generally unnecessary and creates security holes; simply remove the sudo.
Have a look at Technical Note TN2065 do shell script in AppleScript
If you are going to use the do shell script command, then I suggest you read the entire Technical Note.

Related

sudo cp command to copy into launchDaemons

Just simplyfing a process for some internal mac users to put files in the right places but having trouble with a plist file needing to go in /Library/LaunchDaemons. Using some applescript to accomplish this. Unfortunately (for me) LaunchDaemons is read only, so need to sudo root privilege to copy a file into there. I can't seem to get it right as to how to do that with applescript. Copying files to unrestricted locations is done just fine with something like
do shell script ("/bin/cp " & posix_path & "file_to_copy.crt" & "/path/to/folder/")
For the plist file in LaunchDaemons, ideally something like below would work,
do shell script ("sudo /bin/cp " & posix_path & "file_to_copy.plist" & "/Library/LaunchDaemons/") with administrator privileges
I've tried a lot of variations but no luck. Reading through stack overflow I haven't spotted a question quite like this. Any insight would be much appreciated!
As far as using sudo in a do shell script command, do not use sudo in a do shell script command, have a look at: Technical Note TN2065 do shell script in AppleScript
As far as /Library/LaunchDaemons/, it is not read-only! In macOS Big Sur, here are the permissions on a recent 11.4 build:
drwxr-xr-x 3 root wheel - 96 May 30 13:01 LaunchDaemons
Note that it is writable for root and why you need to use with administrator privileges when using the do shell script command to write to it.
Example AppleScript code
do shell script "cp '/path/to/filename.plist' '/Library/LaunchDaemons/'" with administrator privileges
The above do shell script command works for just fine me.
Note the single-quotes around the POSIX paths.
If you are not using hard coded POSIX paths and using variables and concatenating the do shell script command, you can use e.g, the quoted form of theFilename or theFilename's quoted form, etc.
Example AppleScript code
set theFilename to the POSIX path of (choose file)
set theDestinationFolder to "/Library/LaunchDaemons/"
do shell script "cp " & ¬
theFilename's quoted form & space & ¬
theDestinationFolder's quoted form ¬
with administrator privileges

Applescript remove folder from directory with special characters and spaces

I have run into some installation problems with the new Sierra update.
I want to run a script that checks the version number and deletes a certain .mpkg file based on the version number because I am having a lot of customers running the wrong installation which is causing a lot of issues. I have tried multiple versions of this code and nothing seems to be working. My result in Applescript console is: "".
Any help would be greatly appreciated.
tell application "Finder"
set os_version to do shell script "sw_vers -productVersion"
if ((os_version as string) is equal to "10.12") then
do shell script (" rm -rf \"Step 1 Installer.mpkg\" ")
else
do shell script (" rm -rf \"Step 1 Installer (SIERRA ONLY).mpkg\" ")
end if
end tell
The problem is that when you run the rm command, you don't specify the directory the .mpkg file is in. It does not automatically look in the same directory the script is in. Instead, it looks in whatever the script's working directory is, which seems to be / (i.e. the top level of the system volume). You can use path to me to get the script's path, then you need to convert that to a POSIX path in quoted form to use in the shell, then get the parent directory name... Here's what I came up with:
set scriptPath to POSIX path of ((path to me) as string)
do shell script "rm -Rf \"$(dirname " & (quoted form of POSIX path of (scriptFile)) & ")/Step 1 Installer.mpkg\""
(and a similar variant for the other installer)
Warning: *I have not fully tested this, and it contains an rm -Rf command. Thus, if something goes wrong it could go very very wrong. Test well, on a system that you don't care about.

How to run multiple lines of commands in Terminal from AppleScript?

Please refer to this question first,
unable to read opensslv.h:No such file or directory
Based on that I need to run the following three line Terminal commands using AppleScript,
/tmp/ssl/openssl-1.0.1h/Configure darwin64-x86_64-cc ––prefix=/usr no-threads shared
make -f /tmp/ssl/openssl-1.0.1h/Makefile
sudo make -f /tmp/ssl/openssl-1.0.1h/Makefile install
I tried two methods I created text files with .command and .sh extensions and added the above three lines. Then tried to run it from AppleScript as,
do shell script "/Users/Username/Desktop/RunScript.sh"
But got this error,
error "/Users/Username/Desktop/RunScript.sh: line 1: /tmp/ssl/openssl-1.0.1h/Configure: No such file or directory
/Users/Muhriz/Desktop/InstallOpenSSL.sh: line 2: make: command not found sudo: no tty present and no askpass program specified" number 1
This could work,
tell application "Terminal" to activate
tell application "Terminal"
do script ("/tmp/ssl/openssl-1.0.1h/Configure darwin64-x86_64-cc ––prefix=/usr no-threads shared") in window 1
do script ("make -f /tmp/ssl/openssl-1.0.1h/Makefile") in window 1
do script ("sudo make -f /tmp/ssl/openssl-1.0.1h/Makefile install") in window 1
end tell
But it asks for password in Terminal at the third line and waits for user response. The password dialog shown from the AppleScript (when using with administrator privileges) is OK. But it must no ask for password via Terminal when running the commands. It needs to ask only once when the AppleScript is executed and run all sudo related commands without asking for password in Terminal.
What code needs to be used to run from AppleScript?
Perform the following before running your scripts.
chmod a+x /Users/Username/Desktop/RunScript.sh
xattr -r -d "com.apple.quarantine" /tmp/ssl/openssl-1.0.1h
do shell script "/Users/Username/Desktop/RunScript.sh"
That doesn’t work because you can’t pass a path to the “do shell script” command, you can only pass it the contents of the actual script.
If you want to run a bash script that is contained in its own file, you can use TextEdit to open the bash script file and set the contents of the file to a variable, which you can then pass to “do shell script.”
tell application "TextEdit"
set theDesktopPath to the path to the desktop folder as text
set theShellScriptPath to theDesktopPath & "RunScript.sh"
open file theShellScriptPath
set theShellScript to the text of document 1
set theScriptResult to do shell script theShellScript
make new document
set the text of document 1 to theScriptResult
end tell

Apple script with Bash SU Authentication ( Automator)

I have a bash scrips pasted into "Run shell script " Action in Automator apple script under 10.9.3 and the command is copy command a dll to system folder /Library/Audio/Plug-Ins/VST/ that is read only.
I need to prompt the user that runs the script to enter the password. what is the way to to that?
Thanks!
If it's short enough, you can instead use Run AppleScript, and use:
do shell script "command" with administrator privileges
That will prompt the user for administrator username and password in the GUI and then run "command" as root.
Update per comment below:
I missed the part about copying into a privileged folder. You can't use Automator's "Run Shell Script", because it doesn't support running commands as administrator (it's not interactive, so sudo doesn't work). So there are a couple of different ways you could solve the problem.
To run your Bash script as an administrator, save your Bash script as a typical script you run in Terminal. After the Automator action to choose the file, use the "Run AppleScript" action. Then put in the code below. You'll see no prompt and no Terminal window; it will just execute. (If you do want a prompt, you can get one in the GUI by omittinguser name "username" password "password".) The folder the user chose will be the argument to the Bash script.
on run {input, parameters}
do shell script ("sudo /path/to/yourscript '" & POSIX path of input & "') ¬
with administrator privileges user name "username" password "password"
end run
An alternative approach: A Terminal window will open with the prompt "Password:", and the user will enter their password (presumably, it's an administrator). Then your script will run as administrator and be able to copy into the privileged folder.
on run {input, parameters}
tell application "Terminal"
do script "sudo /path/to/yourscript '" & POSIX path of input & "'"
end tell
end run
Or, if you really want to put your Bash script in Automator under "Run Shell Script" as you have currently, and the copy instruction is at the end, you could take the copy instruction out, and have it instead echo the folder the user chose as its final instruction. This will return it to the next Automator action. After Run Shell Script, put in a Run AppleScript with a do shell script command as shown in the first example above, that contains a cp command in place of /path/to/yourscript, with administrator privileges.

Bash issues with osascript GUI commands

I am trying to automate the process of launching an application in OSX and typing an administrator password at a security agent prompt. I was hoping to avoid the use of AppleScript GUI scripting however the underlying cause of the admin prompt is so convoluted and complicated I just won't go there.
Below is the script which works perfectly when run locally by an OSX administrator. Ie. from terminal adminaccount# /usr/local/bin/ReasonScript.sh
#/bin/sh
sudo /usr/bin/osascript <<EOF
launch application "Reason"
tell application "System Events"
repeat until (exists window 1 of process "SecurityAgent")
delay 0.5
end repeat
tell window 1 of process "SecurityAgent"
tell scroll area 1 of group 1
set value of text field 1 to "adminaccount"
set value of text field 2 to "adminpassword"
end tell
click button "OK" of group 2
end tell
end tell
EOF
exit 0
The Problem
I need to execute this script as a root user (not great I know but its how our deployment software does it). So I try it like root# /usr/local/bin/ReasonScript.sh and I get the following error
105:106: syntax error: Expected “,” but found “"”. (-2741)
I have gone through the script but I am not expert at AppleScript but I can't find this syntax error. But at the same time I do not expect this to work as the ROOT user doesn't have a GUI to access so maybe this is part of that failure.
Then I try and assume the local users permissions from root... ie root# sudo -u adminaccount /usr/local/bin/ReasonScript.sh
Unfortunately i get the following
shell-init: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
job-working-directory: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
A thousand appologies if Stackoverflow is not the right place for this question. I'm so confused I don't know how to troubleshoot this further. Is it AppleScript, is it osascript, is it BASH or is it the administration structure of OSX.
I appreciate all the assistance I can get with this pickle.
From the man page:
osascript will look for the script in one of the following three places:
1. Specified line by line using -e switches on the command line.
2. Contained in the file specified by the first filename on the command
line. This file may be plain text or a compiled script.
3. Passed in using standard input. This works only if there are no
filename arguments; to pass arguments to a STDIN-read script, you
must explicitly specify ``-'' for the script name.
If you are going to use a heredoc, you will have to use the third option. Otherwise, you can either have an applescipt file or run it line by line with -e.

Resources