nohup - permission denied - shell

I am trying to get a start up script for OrientDB (a database) on Ubuntu to work.
This is currently the line that causes problems:
ORIENTDB_DIR="/usr/local/orientdb"
ORIENTDB_USER="www-user"
sudo -u $ORIENTDB_USER sh -c "cd \"$ORIENTDB_DIR/bin\"; /usr/bin/nohup server.sh 1>../log/orientdb.log 2>../log/orientdb.err &"
If I start the script, it results in this:
sh: 1: cannot create ../log/orientdb.log: Permission denied
Here's the setup:
www-user is in the sudoers file
server.sh and any the shell script posted above have execute privileges for root.
If I change the script to this:
sudo -u $ORIENTDB_USER sh -c "cd \"$ORIENTDB_DIR/bin\"; /usr/bin/nohup pwd 1>/home/www-user/test.log &", test.log shows /usr/local/orientdb/bin/ as the working directory.
/usr/local/orientdb/log exists but is an empty folder.
Given the above and the fact that I am using sudo to elevate the user, why is permission still denied?

You may have been misunderstanding sudo a bit — sudo does not necessarily elevate a user's rights; in fact, it may reduce the rights they have. When you pass sudo the -u flag, it will change to that user. If that user has more rights — root, for example (the default if -u is not passed) — then you'll get more rights. If the user has less rights — nobody, for example — you'll have less rights. You said that the log directory has these permissions:
drwxrwxr-x 2 root root 4096 Dec 11 10:13 /usr/local/orientdb/log
Yet, you're changing to the www-user user. The www-user user, unless it is part of the root group (unlikely), will not be able to write to that directory: it is only writable by the owner and group, and www-user is clearly not the root user and www-user is probably not part of the root group.
In short, don't pass -u (and its associated argument) if you want to elevate to root.

Try rewriting the last line of your script to:
sudo -u $ORIENTDB_USER sh -c "/usr/bin/nohup \"$ORIENTDB_DIR\"/bin/server.sh 1> \"$ORIENTDB_DIR\"/log/orientdb.log 2> \"$ORIENTDB_DIR\"/log/orientdb.err &"
If that still doesn't work, then www-user probably doesn't have write permission to /usr/local/orientdb/log (Note that you said /usr/local/orientdb/logs exists but is an empty folder: one of them has a s at the end)

Related

sudoless passwordless script

I want to make a sudoless passwordless script which doesn't prompt for password to any user executing that script.
Problem: my script contains rsync utility to send files to a backup server, but i always get permission denied error when the folder which needs to be send contains some files for which the access is set to none. whereas other files are also owned by root but their access is set to read only. I'm using public key authentication to send files to destination/backup so that it doesn't prompt for password input but it cannot send access protected files like above without sudo and password input.
Tries: I tried https://unix.stackexchange.com/a/229653/332764 this solution but it is not working. Still same error is there.
EDIT: sudoers file
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
ortega ALL=(ALL) NOPASSWD: /home/usr/path/transmit_ckpnt.sh
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
You have a few options:
Setup a root crontab job to do a chown (Have root do a job periodically)
Use docker privilege escalation to chmod your file in a container with a mounted volume.
Devise a non-root task equivalent to the root one you are doing
1. Root crontab
A crontab schedules commands execution at Specified time or time interval. Here you could create a root crontab with the command sudo crontab -u root -e. This will open you into an editor to write your crontab: best practices
2. Docker privilege escalation
This method requires either already being root or being part of a machines docker group. As a non-root user who is a member of the docker group you have the ability to mount any directory as a volume within a docker container. Within the container you are root, and changes you make to the mounted volume will persist. Simply chmod the file in the container.
File Permissions
Use chown and chmod to change file-system permissions.
Password-less rsync
The rsync command supports using ssh-keys which allow you to log into other machines password-less after a quick one time key-exchange.
If you cannot chown or chmod a file because of a permission error, that is because a user with more permissions than you (root) will need to help you change the file permissions.
I use this Sudoless no password bash script
1. Open the /etc/sudoers file (as root, of course!) by running:
sudo nano /etc/sudoers
2. At the end of the /etc/sudoers file add this line:
username ALL=(ALL) NOPASSWD:ALL

Usage of sudo in a shell script

When executing a shell script, how does sudo come into play in the following?
# script.sh
ls /root
sudo ls /root
Now, if I run $ sudo ./script.sh or $ ./script.sh what will be the difference? For example:
Do all commands that are run with sudo ./script.sh automatically prepend a "sudo" to that command?
Is the sudo ls /root line vlid? Or should the line instead of ls /root and require root invocation?
Basically, I'm trying to figure out the difference in a line-item being run as sudo, or the script itself being run as sudo.
If you have a script that requires elevated privileges for certain commands, one way to handle those commands is with sudo. Before using sudo, there are several considerations for configuring its use. For instance, if you have certain users you want to be able to run commands with sudo and further to run sudo without being prompted for a password, you need a bit of configuration first. sudo is configured through the visudo utility. For most uses of sudo you will simply need to uncomment options at the end of the file. However to allow users to run sudo without a password, you will also need to add those users to the wheel group (some distros now use a sudo group -- check). After adding users to the wheel group, to allow them to use sudo without a password, you would run visudo and uncomment the following line:
## Same thing without a password
%wheel ALL=(ALL) NOPASSWD: ALL
With sudo configured, then within a script, if elevated (root) privileges are needed you simply need to check whether the user UID (and/or EUID) are equal to zero indicating the user is root, if not, then you use sudo to run the command. You can structure the test in the negative or in the positive to fit your taste, e.g.
if [ "$UID" -eq 0 -o "$EUID" -eq 0 ]; then
command
else
sudo command
fi
or
if [ "$UID" -ne 0 -a "$EUID" -ne 0 ]; then
sudo command
else
command
fi
If your command is not a simple command, but instead contains redirections or pipelines, then you must run the entire command with sudo not just the first command in the list. To do so, just use sudo bash -c "your long command" to ensure elevated privileges are available to each part of a compound command that needs it. For example if you attempt:
sudo cat /etc/sudoers > sudoersbackup
The command will fail. While cat has the elevated privileges to read the file the > redirection is run as the regular user and will fail due to lack of permission. To handle that circumstance, you can do:
sudo bash -c "cat /etc/sudoers > sudoersbackup"
That ensures elevated privileges are available to the entire command.
SUDO stands for "super user do". Basically it is a keyword that when prefixed before any other command, will force that command to run with elevated privileges. Certain commands require elevated privileges. There should be a file located at /etc/sudoers which provides a list of users or user groups who have permission to execute privileged commands.
So if your shell script requires no special privileges to run (which I expect it does not), then sudo ./script.sh should be equivalent to bash script.sh or ./script.sh.

RHEL 7 tim ALL=(root) NOPASSWD: /path-to-shell.sh is not working

I have a Shell script which is owned by a particular user (tim:tim) and with permissions of 755. For example, if the shell is test.sh, the output of ls -la test.sh gives:
-rwxr-xr-x 1 tim tim 27 Sep 10 01:03 test.sh
This shell has commands that should only be run by the root user. So what I need is, I need to run this shell script as sudo test.sh without prompting for the password. So I added the following entry at the end of the /etc/sudoers file.
tim ALL=(root) NOPASSWD: /path-to-shell/test.sh
But above is not working. It's still asking for the password. But when I add an entry as follows, it works without asking for the password.
tim ALL=(root) NOPASSWD: ALL
But what I want is, user tim should only have the privilege to execute test.sh (not all) without prompting for the password.
sudo test.sh
is not same as
sudo /path-to-shell/test.sh
If the sudoers entry:
tim ALL=(root) NOPASSWD: /path-to-shell/test.sh
allowed anyone to run a sudo test.sh without password, it wold be a critical security weakness, because any user would be able to create a file named test.sh and have it executed with root privileges.
If your executable/script path is not in the secure_path variable from the /etc/sudoers file, the sudo permission only applies when invoking the command with its full path-name.
Now this may be a question for other stack site about system administration
See: https://unix.stackexchange.com/questions/83191/how-to-make-sudo-preserve-path/83194#83194

Execute script without reading permissions

I want to allow users to execute a bash script that contains sensitive data. Thus, I don't want them to have reading permissions. A 'direct' solution seems to be impossible, but I may have found a workaround in the expect man page:
Create the Expect script (that contains the secret data) as usual.
Make its permissions be 750 (-rwxr-x---) and owned by a trusted group,
i.e., a group which is allowed to read it. If necessary, create a new
group for this purpose. Next, create a /bin/sh script with permissions
2751 (-rwxr-s--x) owned by the same group as before.
I've tried to replicate this as follows:
In a folder, I have two scripts:
script.sh:
#!/bin/sh
echo "targetscript echo"
runscript.sh:
#!/bin/sh
echo "runscript echo"
groups
./script.sh
I gave them the rights as suggested in the man page:
groupadd scriptrunner
chown {myusername}:scriptrunner runscript.sh
chmod 2751 runscript.sh
chown root:scriptrunner script.sh
chmod 750 script.sh
The output of ls -l appears to be alright:
-rwxr-s--x. 1 {myusername} scriptrunner 51 Aug 25 13:04 runscript.sh
-rwxr-x---. 1 root scriptrunner 35 Aug 25 13:01 script.sh
However, when I run ./runscript.sh without root, I get the following error:
runscript echo
{myusername} wheel
./runscript.sh: line 4: ./script.sh: Permission denied
I don't know what went wrong. Can anyone help me?
I'll go back to the root problem as I think it's easier to solve without the expect hack.
So, what you need is having the execute permission on your script but not the reading permission. That is only possible for binaries (i.e. not interpreted scripts)- see details here https://unix.stackexchange.com/questions/34202/can-a-script-be-executable-but-not-readable
So maybe you'll be better off by first compiling your bash script into a binary (with shc - see here https://unix.stackexchange.com/questions/64762/how-to-convert-a-shell-script-into-a-binary-executable) and then set the execute only permission on the binary. Afterwards your users should be able to execute (but not read) the binary.

Add Entries to Hosts File

I would like to create a bash script that I will run inside an administrator account. I want the script to backup the existing hosts file to the same directory with the file extension .original and then I want the script to add 3 pre-defined entries (specified within the scripts body) into the hosts file and maintain the existing formatting of the hosts file. How can I accomplish this without the user having to authenticate - I want the administrators password to be stored in the script and passed to sudo every time it requests escalation. Thank you.
You shouldn't store the password in the script. That is a security vulnerability. You can achieve the behaviour you want without storing the password anywhere by using the setuid bit.
First run chmod u+s myscript to make it run as owner (when you make the owner root, this will make your script run as root, so you won't need to use sudo at all within your script).
Then make sure that anyone you want can execute the script. If you want all users to be able to then run chmod +x myscript. If you want only yourself to be able to make sure you are the only user in the group and use chmod g+x myscript instead.
Then run sudo chown root myscript to make it owned by root.
Now any time that anyone with permissions to execute that script runs it it will be executed as root, whether that user is an administrator or not.
You have to write a program (compiled code) and suid root to perform that, then you do not have to reveal the root password to the users. I have yet to encounter a system that allows you to suid scripts. Or you have to suid bash itself which is the actual program, then everyone can be root.
example: (run as root)
ex qq.c << EOF
1,\$d
i
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
int main() {
assert(0 == setreuid(geteuid(),-1));
return system(
"/bin/bash << DONE\n"
"if [ \"\$UID\" != '0' ];then echo \"need to be root to do this\";exit 16;fi;\n"
"cp /etc/hosts /etc/hosts.org\n"
"echo 127.0.0.1 banned1.domain >> /etc/hosts\n"
"echo 127.0.0.1 banned2.domain >> /etc/hosts\n"
"echo 127.0.0.1 banned3.domain >> /etc/hosts\n"
"DONE\n");
}
.
x
EOF
gcc -o qq qq.c && chmod u+s qq
You can do this via the sudo command. The sudo command allows you to specify which users can run which commands and what users. Normally, you give users access to particular commands that they need to be root to execute. For example, a particular person needs to be able to start and stop Apache httpd. Normally, only root is allowed to do this, but you can grant this permission to your web administrator without giving that person permission to do anything else as root.
The sudo command is controlled by the /private/etc/sudoers file. (Which you should edit with the visudo command).
Let's say you create a shell script to edit your /etc/hosts file. You'd first want to put it in a particular location, say /usr/local/edit_hosts_file. This is a good location since the directory is owned by root.
Now, you want to make sure that only root can execute this file, and maybe only root can even read this file, and you especially want to make sure only root can edit this file. Otherwise, people could use this file to give themselves root access to other parts of your system:
$ sudo chown root:root /usr/share/edit_hosts_file
$ sudo chmod 700 /usr/share/edit_hosts_file
Now, that your command is secure, you can edit the /private/etc/sudoers file to allow only particular users to run this shell script as root:
User_Alias ALLOWED_USERS = bob, carol, ted, alice
Cmnd_Alias ETC_HOSTS_EDIT = /usr/share/bin/edit_hosts_file
Host_Alias MACHINE_LIST = localhost
ALLOWED_USERS MACHINE_LIST=(ALL) NOPASSWD: ETC_HOSTS_EDIT
This would allow any user in the defined ALLOWED user list to run your etc/hosts edit script, without requiring a password.
Now, if someone wants to run your script, they can do it as root without knowing the password and without having to give the password. This way, your script could be executed by another script:
$ sudo /usr/share/bin/edit_hosts_file
Script completed: /etc/hosts edited

Resources