• Here is the script to be executed via AppleScript:
bash-3.2$ cd /Users/jack/Desktop/
bash-3.2$ ls -l | grep static
-rwxrwxrwx 1 jack admin 65 5 May 08:10 static-routes.sh
bash-3.2$ cat static-routes.sh
#!/bin/bash
sudo route -n add -net 192.168.3.0/24 172.16.254.134
~
• AppleScript contains the following:
do shell script "~/Desktop/static-routes.sh"
• When executing the script from within an AppleScript, by clicking on "Run" button, pop up window saying:
Script Error
sudo: a terminal is required to read the password;
Either use the -S option to read from standard input or
configure an askpass helper
• When exeucuting script from the console without sudo, no additional prompts appear:
bash-3.2$: Desktop jack$ ./static-routes.sh
add net 192.168.3.0: gateway 172.16.254.134
• Here is the snippet from /etc/sudoers:
bash-3.2$ sudo visudo
# root and users in group wheel can run anything on any machine as any user
root ALL = (ALL) ALL
%admin ALL = (ALL) ALL
jack ALL = (ALL) NOPASSWD: /Users/jack/Desktop/static-routes.sh
## Read drop-in files from /private/etc/sudoers.d
## (the '#' here does not indicate a comment)
#includedir /private/etc/sudoers.d
Defaults timestamp_timeout=60
Questions:
• Why this error is showing up, since, I have explicitly added the script to the sudoers file to be executed without password prompt via sudo?
• Which user does AppleScript use to execute the scripts? Is it possible to modify it?
The run a command that requires privileges from AppleScript, you need to specify that by adding the administrator privileges key, as in one of the following:
-- this will presented a standard authorization dialog
do shell script "~/Desktop/static-routes.sh" with administrator privileges
-- this will specifies an administrator account and password
-- (though note, the password will be visible as plain text in the script)
do shell script "~/Desktop/static-routes.sh" with administrator privileges user name XXXX password YYYY
You should not use sudo at the same time you use with administrator privileges; it's unnecessary and creates security holes. However, since you've changed the sudoers file already, you could try this:
do shell script "sudo ~/Desktop/static-routes.sh"
Putting sudo up front like that might cue AppleScript to do the correct thing.
See Technote 2065 for more information.
Related
Background
I have a long bash script which setup a large environment of interconnected software, taking several hours to complete. A few of the tasks it performs need to be run as root, for which I use sudo .... The whole process is then paused until the user notices and types in the root password. I seek some way for the user to type in the root password only at the beginning of the script, and then automatically supply it when required by sudo later.
My thoughts on possible (bad) solutions
I could store the password directly in a variable and then supply it using
echo "${root_password}" | sudo -S ...
but something tells me that this is bad practice.
Another workaround would be to force the user to run the entire script as root, but wouldn't that lead to different permissions for all of the files generated without the use of sudo?
You can prompt it at the start of your script, so it is not plain text hard saved.
Example:
#!/bin/bash
read -s -p "[sudo] sudo password for $(whoami): " pass
echo $pass | sudo -S apt-get update
help read:
-r do not allow backslashes to escape any characters
-s do not echo input coming from a terminal
I suggest you figure out all of the commands you need the script to run using SUDO, ensure the script is run by a special unprivileged user (e.g. scriptuser), and then edit /etc/sudoers to permit scriptuser to run those commands with NOPASSWD
As an example:
scriptuser ALL = NOPASSWD: /bin/kill, /usr/bin/othercommand, etc.
If you know the complete commands, including arguments, that's ideal (it means that an attacker that compromises the scriptuser account can only run those specific commands as root)
Sudo has a lot of options configurable in /etc/sudoers. If you man sudoers , you should see all of them. Forewarning: This man page is very hard to understand. Find examples. Test them. Ask on StackExchange.
Was trying to figure out how to execute a sudo command with the password as a parameter.
echo mypassword | sudo -S command
was using this reference Use sudo with password as parameter
However, on OS X it keeps say "sudo: incorrect password attempt" however that passwords is correct.
what am i doing wrong?
As pointed out in the comments already, what you're doing is a very bad idea because it leaves the password of an account laying around. Instead, if you need to run a specific command with sudo from a script, you could -- and you should -- define that single command for one specific user in such a way that its execution is allowed without having to type in the password.
So, you should edit /etc/sudoers to include an entry for your specific user for that one, single, specific command with the tag NOPASSWD:
youruser yourhostname = (root) NOPASSWD: /some/path/your/command
Or if you really don't feel like typing in the hostname of your computer, then go for:
youruser ALL = (root) NOPASSWD: /some/path/your/command
That way you will possibly leak the ability of executing that one, single command as root instead of leaking your password and with it the possibility of running any commands as root.
I'd like users in staff group who do not have admin/root permissions to run the following script without being prompted for a password. This is in OSX.
Note that /usr/sbin/serveradmin requires root/sudo privileges.
I've tried adding the following to my /etc/sudoers, but it does not work. Script has permissions of 755.
%staff ALL=NOPASSWD: /usr/sbin/serveradmin stop smb,/usr/sbin/serveradmin start smb
%staff ALL=NOPASSWD: /bin/sh /opt/scripts/restart-smb
Here's the shell script:
#!/bin/bash
#
# This script simply restarts SMB (Samba)
#
echo "Stopping SMB..."
/usr/sbin/serveradmin stop smb
echo "Pausing for 30 seconds..."
/bin/sleep 30
echo "Starting SMB..."
/usr/sbin/serveradmin start smb
echo "Script complete!"
Your ideas, suggestions most appreciated!
Dan
WARNING while playing with the /etc/sudoers file managing users privilege and permissions, I CRASHED Ubuntu.
Normal login was not possible anymore. I got a parsing error coming from a simple space missing between # and % character in a line I wrongly commented #%sudo ALL=NOPASSWD: /pathtoscripts/script.sh .
I had to recover it with the install/liveCD mounting again the hardrive filesystem, put back the original file in place and dismount the volume for recording changes.
For the above reason I would NOT RECOMMEND THIS METHOD first because it modifies /etc/sudoers privileges critical file. Choose first alternatives available unless:
you have a good back up of your data outside of your PC
you are not afraid to take the risk to repair/reinstall your system
you know the RIGHT SYNTAX of the /etc/sudoers file, trials and parsing errors could cost you a lot of time and/or efforts/crashes...
Reading the other posts, I managed to get it work on my system, managing permissions through a group:
I created the group mygroup
sudo groupadd mygroup
I added the user myuser which will execute the script
sudo usermod -a -G mygroup myuser
I added at the END of /etc/sudoers the entry, otherwise the privilege are overwritten by the previous lines (be careful with syntax)
%mygroup ALL=NOPASSWD: /mypath/to/myscripts/myscript.sh
The above script myscript.sh must have execute permission
sudo ugo+x /mypath/to/myscripts/myscript.sh
This script will then be able to be launched by the user myuser directly as below wihtout prompting for password anymore
sudo /mypath/to/myscripts/myscript.sh
Alternatively, the script can be launched within another one in a same way
I found another way without creating a group, adding to /etc/sudoers file (at the END of file) the line:
%sudo ALL=NOPASSWD: /mypath/to/myscripts/myscript.sh
In case the script must only be launched by a few existing users myuser1, myuser2, it is always possible to only add to /etc/sudoers (at the END of file) the lines :
myuser1 ALL=(ALL) NOPASSWD: /mypath/to/myscripts/myscript.sh
myuser2 ALL=(ALL) NOPASSWD: /mypath/to/myscripts/myscript.sh
I was able to make this work by adding the following to my /etc/sudoers file:
%staff ALL=/opt/scripts/restart-smb
Then of course making the script executable (I had forgotten that).
Still requires a password (which is okay), but working.
I'm wanting to make a simple program that runs each time on login behind the UI. In my applescript I'm running a sudo command that requires admin authentication. Is there a way to overwrite the need for authentication each time it runs? I don't want to have to type my username and password each time this script runs after login. any help? (and in very simple terms to as I'm a novice.)
Much Thanks!
You can put your username and password in the applescript command so that it doesn't ask for those credentials. However note that these items are stored as plain text inside the applescript and thus it's possible for others to see them. It's not really secure but it's up to you to decide if it's safe. NOTE: you don't need "sudo" in the command any longer.
do shell script "whatever" user name "username" password "password" with administrator privileges
There are methods where you can store your password in the Keychain and retrieve it from the applescript, thus making it secure. If you want to do that then you create the password item as follows.
Open Keychain Access application and select the keychain in the left column. Then click File>New Password Item..., give it a name, put your account shortname in account, and enter the password. Highlight it in the password list and get information on it. Under the Attributes button enter its kind as generic key. This is chosen because there aren't many of them and the search is much faster. Whatever name you give to it must be put in the code below in "Your Password Name".
Now from applescript you can use it like this...
set myPass to getPW()
do shell script "whatever" user name "username" password myPass with administrator privileges
on getPW()
do shell script "security 2>&1 >/dev/null find-generic-password -gl \"Your Password Name\" | awk '{print $2}'"
return (text 2 thru -2 of result)
end getPW
Good luck!
Another solution is editing the
etc/sudoers
configuration file.
A setting on that file can allow a specific user to execute a specific commands (with... yes... specific parameters) as super user.
If the command itself is not the problem, but the problem is exposing the password in the code then this may be the solution.
The sudores file should be edited running the command visudo as super user.
Before you start tampering with sudoers I strongly suggest you to get a basic knowledge of visudo and the sudoers syntax, as messing that file may causes serius issues to the system.
As you know what you are doing is just a matter of adding a couple of lines.
For information you may Google or start here http://www.sudo.ws/sudoers.man.html
If you want all Administrator accounts to be able to use the sudo command without entering a password, then do the following.
Change the line shown below in the /private/etc/sudoers file from
%admin ALL=(ALL) ALL
to
%admin ALL=(ALL) NOPASSWD: ALL
This edit can be accomplished, by using the Terminal and TextEdit applications. Open the Terminal application and type the following commands:
cd ~/desktop
sudo cp -n /etc/sudoers /etc/sudoers.orignal
sudo cp /etc/sudoers sudoers.txt
sudo chmod ug+w sudoers.txt
open sudoers.txt
visudo -c -f sudoers.txt
sudo cp -X sudoers.txt /etc/sudoers
When done, the sudoers.txt file on your desktop can be put in the trash.
To undo your changes, use the command:
sudo cp /etc/sudoers.original /etc/sudoers
This was tested using OS X 10.10.1
If you want to do the same for a single user then see:
http://hints.macworld.com/article.php?story=20021202054815892
Below is a brief explanation of what each command does:
cd ~/desktop
This makes sure you are working from your desktop folder.
sudo cp -n /etc/sudoers /etc/sudoers.original
This backups your sudoers file. The backup can be used to undo your changes. The -n option insures that an existing sudoers.original file will not be overwritten.
sudo cp /etc/sudoers sudoers.txt
Copies the sudoers file to your desktop. The .txt extension is added so OS X will know this is a text file.
sudo chmod ug+w sudoers.txt
Changes the file’s permissions to allow write access.
open sudoers.txt
Opens the file in the TextEdit application. You need to edit the file and save the changes.
visudo -c -f sudoers.txt
Checks the edited file for syntax errors. The output should be sudoers.txt: parsed OK.
sudo cp -X sudoers.txt /etc/sudoers
Copies the file back to the /etc directory.
I'm trying to write a bash script that sets up my web development environment in ubuntu. As part of the process of setting up the script, it needs to edit files that are owned by root. It also needs to create fields in the public_html directory of the user that runs the script.
Should I therefore require that the script be run as the superuser? If it should, then how do I get it to access the current user's username? I would normally use the $USER variable, but I can't do that if the script is being run as the superuser. If I'm not the superuser, how can I get the script to request super user privileges for certain operations, while not requiring the user to type in a password for every operation that requires super user privileges.
Thanks
You can use the -E flag for sudo to preserve the environment variables, or, you can set up sudoers to preserve the environment on a per-command basis.
You can also set up the sudoers file to not ask for a password on a per-command basis, for example, to allow user xy to use smbmount without asking for a password:
xy ALL=NOPASSWD: /usr/bin/smbmount
In your case, it would be enough to just store the current user in a variable before invoking sudo, and use the already saved username:
CURRENT_USER=$USER
sudo yourscript.sh $CURRENT_USER
Then read the username from $1.
You can also use the SUDO_USER env variable, which is set to the user who is invoking sudo.
Insert a check at the top of the script:
# Make sure only root can run this script
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
In this way when you run it without the root privileges you will be prompted, then you can simply rerun it the right way with:
sudo yourscript.sh
More infos at http://www.cyberciti.biz/tips/shell-root-user-check-script.html
There's a command named sudo for this purpose. It lets you specify that certain users can run certain commands as root (or another user).
If your users have root access anyway, you could just write a script that must be run as root and takes an username as parameter, instead of picking up the username.
Alternatively, one way of picking up the login username in an interactive shell is:
stat -Lc %U /proc/self/fd/0
This retrieves the ovner of the tty associated with stdin.
Just make it a setuid file. Or use sudo which is probably safer, since you can limit who gets to run it.
chmod 4755 script.sh
In Ubuntu, there's the SUDO_USER environment variable.
So, you can just run your script sudo somescript.sh and have it pull the invoking user's username $SUDO_USER.
Not sure on other dists, though.