permission denied in running script - linux

I am running a script but there is an unusual warning:
This is what happened in my console
#whoami
root
#ls -l test.sh
-rwxr-xr-x. 1 root root 1894 Feb 2 01:58 test.sh*
#./test.sh
-bash: ./test.sh: Permission denied
Edit:
my script:
#!/bin/bash
while read pass port user ip file; do
echo "startt------------------------------------" $ip
ping $ip -c 4
if [ $? -eq 0 ]; then
echo $ip ok...
else
echo $ip failed...
fi
echo "finish------------------------------------" $ip
done <<____HERE
pass 22 root 1.1.1.1 test.txt
____HERE
any idea?
thank you

I am running the script in /tmp directory
as you see the result of ls is:
-rwxr-xr-x. 1 root root 1894 Feb 2 01:58 test.sh*
there is . after permissions which indicates that an SELinux security context applies to that file. so I copied test.sh in a directory else...
the problem was solved
ls -l /
drwxrwxrwt. 8 root root 1024 Feb 2 07:44 tmp/
I was in a directory where it might be a bad idea for executables to reside
These may work as well:
setenforce 0 | reboot
OR
echo 0 > /selinux/enforce | reboot
OR:
putting SELINUX=disabled in /etc/selinux/config and reboot (making sure to comment out anything in that file enabling selinux)
SELINUX status: sestatus

Related

Why cannot root writes on a file that it owns and has write access to?

I need to write to a.txt. The file is owned by root with a read-write access. But still I cannot write over it with a sudo. Why?
% ls -l
total 8
-rw-r--r-- 1 root staff 6 Mar 24 00:30 a.txt
% sudo echo "hi" >> a.txt
zsh: permission denied: a.txt
The redirection happens before the commands are run, i.e. using the original user.
Work-around:
sudo sh -c 'echo "hi" >> a.txt'

Why file is not created as owned by a specific user i designated

I have a php script that will collection data and write log into a file, the directory belongs to an user called 'ingestion' and a group called 'ingestion'. I was using the command
sudo -u ingestion php [script] &>> /var/log/FOLDER/adapter.log
The owner and group of FOLDER is ingestion. However, the created adapter.log still belongs to root user and root group, how is this possible?
Your file is created by the bash running as root, not by the process that you run via sudo as ingestion.
That's because the >> foo is part of the command line, not of the process started by sudo.
Here:
#foo.sh
echo foo: `id -u`
Then:
tmp root# sudo -u peter bash foo.sh > foo
tmp root# ls -l foo
-rw------- 1 root staff 9 Mar 2 18:52 foo
tmp root# cat foo
foo: 501
You can see that the file is created as root but the foo.sh script is run as uid 501.
You can fix this by running e.g.:
tmp root# sudo -u peter bash -c "bash foo.sh > foo"
tmp root# ls -l foo
-rw------- 1 peter staff 9 Mar 2 18:54 foo
tmp root# cat foo
foo: 501
In your case, of course, replace "..." with your php command.

"echo "password" | sudo -S <command>" asks for password

I trying run a script without become the su user and I use this command for this:
echo "password" | sudo -S <command>
If I use this command for "scp", "mv", "whoami" commands, the command works very well but when I use for "chmod", the command asks for password for my user. I don't enter password and the command works. My problem is the system asks password to me. I don't want the system asks for password.
Problem ss is like this:
[myLocalUser#myServer test-dir]$ ls -lt
total 24
--wx-wx-wx 1 root root 1397 May 26 12:12 file1
--wx-wx-wx 1 root root 867 May 26 12:12 script1
--wx-wx-wx 1 root root 8293 May 26 12:12 file2
--wx-wx-wx 1 root root 2521 May 26 12:12 file3
[myLocalUser#myServer test-dir]$ echo "myPassw0rd" | sudo -S chmod 111 /tmp/test-dir/*
[sudo] password for myLocalUser: I DONT WANT ASK FOR PASSWORD
[myLocalUser#myServer test-dir]$ ls -lt
total 24
---x--x--x 1 root root 1397 May 26 12:12 file1
---x--x--x 1 root root 867 May 26 12:12 script1
---x--x--x 1 root root 8293 May 26 12:12 file2
---x--x--x 1 root root 2521 May 26 12:12 file3
You can use the sudoers file, located in /etc/sudoers, to allow specific users execute commands as root without password.
myLocalUser ALL=(ALL) NOPASSWD: /bin/chmod
With this line the user myLocalUser can execute chmod as root without a password is needed.
But this also breaks parts of the system security, so be aware not allow too much and fence the task as much as possible.
sudoers information
sudo -S prints prompt to stderr.
If you don't want to see it, redirect stderr to /dev/null
The following command redirects stderr at the local host:
echo <password> | ssh <server> sudo -S ls 2>/dev/null
It is equivalent to echo <password> | ssh <server> "sudo -S ls" 2>/dev/null
The following command redirects stderr at the remote server:
echo <password> | ssh <server> "sudo -S ls 2>/dev/null"
If you need to keep stderr, but hide [sudo] password for ... then you can use process substitution on the local or remote machine. Since sudo prompt has no newline, I use sed to cut out the sudo prompt. I do this to save the first line of stderr of the created process.
# local filtering
echo <password> | ssh <server> "sudo -S ls" 2> >(sed -e 's/^.sudo[^:]\+: //')
#remote filtering
echo <password> | ssh <server> "sudo -S ls 2> >(sed -e 's/^.sudo[^:]\+: //')"

rsync prints "skipping non-regular file" for what appears to be a regular directory

I back up my files using rsync. Right after a sync, I ran it expecting to see nothing, but instead it looked like it was skipping directories. I've (obviously) changed names, but I believe I've still captured all the information I could. What's happening here?
$ ls -l /source/backup/myfiles
drwxr-xr-x 2 me me 4096 2010-10-03 14:00 foo
drwxr-xr-x 2 me me 4096 2011-08-03 23:49 bar
drwxr-xr-x 2 me me 4096 2011-08-18 18:58 baz
$ ls -l /destination/backup/myfiles
drwxr-xr-x 2 me me 4096 2010-10-03 14:00 foo
drwxr-xr-x 2 me me 4096 2011-08-03 23:49 bar
drwxr-xr-x 2 me me 4096 2011-08-18 18:58 baz
$ file /source/backup/myfiles/foo
/source/backup/myfiles/foo/: directory
Then I sync (expecting no changes):
$ rsync -rtvp /source/backup /destination
sending incremental file list
backup/myfiles
skipping non-regular file "backup/myfiles/foo"
skipping non-regular file "backup/myfiles/bar"
And here's the weird part:
$ echo 'hi' > /source/backup/myfiles/foo/test
$ rsync -rtvp /source/backup /destination
sending incremental file list
backup/myfiles
backup/myfiles/foo
backup/myfiles/foo/test
skipping non-regular file "backup/myfiles/foo"
skipping non-regular file "backup/myfiles/bar"
So it worked:
$ ls -l /source/backup/myfiles/foo
-rw-r--r-- 1 me me 3126091 2010-06-15 22:22 IMGP1856.JPG
-rw-r--r-- 1 me me 3473038 2010-06-15 22:30 P1010615.JPG
-rw-r--r-- 1 me me 3 2011-08-24 13:53 test
$ ls -l /destination/backup/myfiles/foo
-rw-r--r-- 1 me me 3126091 2010-06-15 22:22 IMGP1856.JPG
-rw-r--r-- 1 me me 3473038 2010-06-15 22:30 P1010615.JPG
-rw-r--r-- 1 me me 3 2011-08-24 13:53 test
but still:
$ rsync -rtvp /source/backup /destination
sending incremental file list
backup/myfiles
skipping non-regular file "backup/myfiles/foo"
skipping non-regular file "backup/myfiles/bar"
Other notes:
My actual directories "foo" and "bar" do have spaces, but no other strange characters. Other directories have spaces and have no problem. I 'stat'-ed and saw no differences between the directories that don't rsync and the ones that do.
If you need more information, just ask.
Are you absolutely sure those individual files are not symbolic links?
Rsync has a few useful flags such as -l which will "copy symlinks as symlinks". Adding -l to your command:
rsync -rtvpl /source/backup /destination
I believe symlinks are skipped by default because they can be a security risk. Check the man page or --help for more info on this:
rsync --help | grep link
To verify these are symbolic links or pro-actively to find symbolic links you can use file or find:
$ file /path/to/file
/path/to/file: symbolic link to `/path/file`
$ find /path -type l
/path/to/file
Are you absolutely sure that it's not a symbolic link directory?
try a:
file /source/backup/myfiles/foo
to make sure it's a directory
Also, it could very well be a loopback mount
try
mount
and make sure that /source/backup/myfiles/foo is not listed.
You should try the below command, most probably it will work for you:
rsync -ravz /source/backup /destination
You can try the following, it will work
rsync -rtvp /source/backup /destination
I personally always use this syntax in my script and works a treat to backup the entire system (skipping sys/* & proc/* nfs4/*)
sudo rsync --delete --stats --exclude-from $EXCLUDE -rlptgoDv / $TARGET/ | tee -a $LOG
Here is my script run by root's cron daily:
#!/bin/bash
#
NFS="/nfs4"
HOSTNAME=`hostname`
TIMESTAMP=`date "+%Y%m%d_%H%M%S"`
EXCLUDE="/home/gcclinux/Backups/root-rsync.excludes"
TARGET="${NFS}/${HOSTNAME}/SYS"
LOGDIR="${NFS}/${HOSTNAME}/SYS-LOG"
CMD=`/usr/bin/stat -f -L -c %T ${NFS}`
## CHECK IF NFS IS MOUNTED...
if [[ ! $CMD == "nfs" ]];then
echo "NFS NOT MOUNTED"
exit 1
fi
## CHECK IF LOG DIRECTORY EXIST
if [ ! -d "$LOGDIR" ]; then
/bin/mkdir -p $LOGDIR
fi
## CREATE LOG HEADER
LOG=$LOGDIR/"rsync_result."$TIMESTAMP".txt"
echo "-------------------------------------------------------" | tee -a $LOG
echo `date` | tee -a $LOG
echo "" | tee -a $LOG
## START RUNNING BACKUP
/usr/bin/rsync --delete --stats --exclude-from $EXCLUDE -rlptgoDv / $TARGET/ | tee -a $LOG
In some cases just copy file to another location (like home) then try again

Add or update a configuration record in /etc/environment

My /etc/environment looks like this:
cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
I wish to use a command (sed, awk, python, whatever....) that will make it look like this:
cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
JAVA_HOME="/usr/lib/jvm/java-6-sun"
Now the catch is, I would rather it be a 1 liner (in the fields of sed -XYZ /DoMagic/ /etc/environment), it needs to contain merging logic that is - either appends a new configuration record or update an existing one. Bottom line, it should prevent the file from looking like this: (Caused by in experienced shell scripters calling echo >> on each invocation)
cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
JAVA_HOME="/usr/lib/jvm/java-5-sun"
JAVA_HOME="/usr/lib/jvm/java-6-sun"
JAVA_HOME="/usr/lib/jvm/java-6-sun"
JAVA_HOME="/usr/lib/jvm/java-6-sun"
I guess this is a trick questions, because what I'm trying to avoid using custom scripts, such as
/usr/local/bin/PropUpdate /etc/environment JAVA_HOME "/usr/lib/jvm/java-6-sun"
/usr/local/bin/PropUpdate is the following script (written for the sake of example, may contain bugs. Comments are appreciated)
#!/bin/bash
# Append/Update a configuration record in a file
#
# Usage example:
# /usr/local/bin/PropUpdate /etc/environment JAVA_HOME "/usr/lib/jvm/java-6-sun"
#
# Author Maxim Veksler <maxim#vekslers.org>
# Version 0.5-2010-07-27
EXPECTED_ARGS=3
E_BADARGS=3
E_BADFILE=4
if [[ $# -ne ${EXPECTED_ARGS} ]]; then
echo "Usage: `basename $0` /path/to/config.conf ParameterName newValueText" >&2
exit $E_BADARGS
fi
CONFIGURATION_FILE="$1"
CONFIGURATION_PARAMETER="$2"
CONFIGURATION_VALUE="$3"
if [[ ! -e "${CONFIGURATION_FILE}" ]]; then
echo "Configuration file ${CONFIGURATION_FILE} does not exist" >&2
exit $E_BADFILE
fi
if [[ ! -w "${CONFIGURATION_FILE}" ]]; then
echo "Can't modify ${CONFIGURATION_FILE}" >&2
exit $E_BADFILE
fi
#########################################
## Decide what parameter we are adding ##
#########################################
__param_found=0
# First check CONFIGURATION_PARAMETER supplied by use that contains "="
if [[ ${CONFIGURATION_PARAMETER} == *=* ]]; then
# It should exist in the file, plain
if grep -qE "^${CONFIGURATION_PARAMETER}" "${CONFIGURATION_FILE}"; then
__param_found=1
SUFFIX_REGEX='[[:space:]]*'
fi
else
# OK, sophisticated user, did not send "=" with the parameter...
if grep -qE "^${CONFIGURATION_PARAMETER}[[:space:]]*=" "${CONFIGURATION_FILE}"; then
# Let's check if such configuration with Parameter + "=" exists
__param_found=1
SUFFIX_REGEX='[[:space:]]*=[[:space:]]*'
elif grep -qE "^${CONFIGURATION_PARAMETER}[[:space:]]+" "${CONFIGURATION_FILE}"; then
# If such parameter exists, at all
__param_found=1
SUFFIX_REGEX='[[:space:]]\+'
fi
fi
if [[ $__param_found == 1 ]]; then
#echo sed -i "s|^\(${CONFIGURATION_PARAMETER}${SUFFIX_REGEX}\).*$|\1${CONFIGURATION_VALUE}|g" "${CONFIGURATION_FILE}"
sed -i "s|^\(${CONFIGURATION_PARAMETER}${SUFFIX_REGEX}\).*$|\1${CONFIGURATION_VALUE}|g" "${CONFIGURATION_FILE}"
else
if [[ ${CONFIGURATION_PARAMETER} == *=* ]]; then
# Configuration parameter contains "=" in it's name, good just append
echo "${CONFIGURATION_PARAMETER}${CONFIGURATION_VALUE}" >> "${CONFIGURATION_FILE}"
else
# Try to guess if this file is a "param = value" or "param value" type of file.
if grep -qE "^[[:alnum:]]+[[:space:]]*=" "${CONFIGURATION_FILE}"; then
# Seems like a "param = value" type of file
echo "${CONFIGURATION_PARAMETER}=${CONFIGURATION_VALUE}" >> "${CONFIGURATION_FILE}"
else
# Seems like a "param value" type of file
echo "${CONFIGURATION_PARAMETER} ${CONFIGURATION_VALUE}" >> "${CONFIGURATION_FILE}"
fi
fi
fi
#cat $CONFIGURATION_FILE
Thank you,
Maxim.
-- Update: I actually kinda liked this script, so I've improved it a bit. It now seems to be production ready. Enjoy.
Instead of trying to parse /etc/environment file, you could instead create a file with your own name in /etc/profile.d/, as I described in my answer to a relevant question. Then you could just copy it over during installation, because it contains just your content. Let alone that it will make your scripts shorter.
grep -q JAVA_HOME /etc/environment || echo 'JAVA_HOME="/usr/lib/jvm/java-5-sun"' >> /etc/environment
The grep command returns 0 (true) if the pattern is found in the file. So, the above reads:
check if JAVA_HOME is set in the file
OR set JAVA_HOME in the file
0-15:49 root#noneedto ~# cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
0-15:49 root#noneedto ~# grep JAVA_HOME /etc/environment && echo true
1-15:49 root#noneedto ~# grep -q JAVA_HOME /etc/environment || echo 'JAVA_HOME="/usr/lib/jvm/java-5-sun"' >> /etc/environment
0-15:49 root#noneedto ~# grep JAVA_HOME /etc/environment && echo true
JAVA_HOME="/usr/lib/jvm/java-5-sun"
true
0-15:49 root#noneedto ~# grep -q JAVA_HOME /etc/environment || echo 'JAVA_HOME="/usr/lib/jvm/java-5-sun"' >> /etc/environment
0-15:49 root#noneedto ~# cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
JAVA_HOME="/usr/lib/jvm/java-5-sun"
As you can see, if you invoke this one-liner multiple times, subsequent invocations do not add to the file because grep returns true before you attempt to append the file.
In my Ubuntu system, my JAVA_HOME looks like this:
JAVA_HOME=/usr/lib/jvm/default-java
Looking at that file with ls -l /usr/lib/jvm/default-java I noticed this:
lrwxrwxrwx 1 root root 24 Apr 27 2012 /usr/lib/jvm/default-java -> java-1.7.0-openjdk-amd64
In other words, the path in the soft link is the only thing you have to change.
To see the list of installed Java environments, I used this ls -l ... command:
prompt$ ls -l /usr/lib/jvm
total 20
lrwxrwxrwx 1 root root 24 Apr 27 2012 default-java -> java-1.7.0-openjdk-amd64
drwxr-xr-x 4 root root 4096 Feb 23 17:54 java-1.5.0-gcj-4.8-amd64
lrwxrwxrwx 1 root root 20 Sep 2 2012 java-1.6.0-openjdk-amd64 -> java-6-openjdk-amd64
lrwxrwxrwx 1 root root 20 Jul 3 2013 java-1.7.0-openjdk-amd64 -> java-7-openjdk-amd64
drwxr-xr-x 5 root root 4096 Oct 7 2012 java-6-openjdk-amd64
drwxr-xr-x 3 root root 4096 Oct 7 2012 java-6-openjdk-common
drwxr-xr-x 5 root root 4096 Sep 21 20:06 java-7-openjdk-amd64
drwxr-xr-x 8 root root 4096 Sep 18 21:18 java-7-oracle
So now I can switch to another default with:
sudo rm /usr/lib/jvm/default-java
sudo ln -s java-7-oracle /usr/lib/jvm/default-java
And the JAVA_HOME variable will run Java 7 from Oracle.

Resources