How can I see the loggedin users that have used 'su' - linux

If I use a login shell to login as root
then 'who' or 'users' commands
will show an entry for the root user.
However If I login with user1 and then use:
'su - root'
Then the 'who' and 'users' command will not show an entry for root.
Is there a way to find out whether there is a logged-in user in my system that has currently switched to root (or to any other account)?

Look at the /var/log/secure file.
Search for line like this:
Feb 6 14:12:09 myhost su: pam_unix(su-l:session): session opened for user root by root(uid=999)
the uid at the end of the string is the one of the original user.
Otherwise you can search for shells that executed su command and check who's the owner.
pgrep su | \
xargs -i sh -c "ps -p {} -o ppid=" | \
xargs -i ps -p {} -f
The result will be the uids of who is currently running su
I'm sure there's a more elegant method but nothing better comes to my mind right now.

Thanx to Davide Berra's answer, I think I have found what I was looking for.
> who | sort -k2 > /tmp/whoresult
> pgrep -x su | xargs -i ps hu -p{} | awk '{printf $7 " ";for (i=11; i<=NF; i++) printf $i " "; printf "\n"}' | sort -k1 | join -1 2 -2 1 /tmp/whoresult -
The output is something like:
pts/3 user1 2013-02-06 16:35 (:0.0) su - root #logged in as user1 and executed 'sudo - root'
pts/5 user1 2013-02-06 16:51 (:0.0) su #logged in as user1 executed 'sudo su'
tty2 root 2013-02-06 17:07 su - user1 #logged in as root and executed 'sudo - user1'

Related

How to set a password for all users (Bash Linux)

how do I set a single password for all users in a Linux system? For example, how will I set a password, x, so that it's the password of all users in the system?
I was thinking of a for loop that iterates between each other but then I realised I have no clue on how to go about this.
You could manually change all user accounts in question with the following, it will prompt you for the new password
$ sudo passwd <username>
You could automate this with a script. Or you could use a convoluted command at the command line, which is what I would do. The below example will pull all users from the passwd file, filter out the users that cannot login, and then run a loop to set their password
using cat piped to grep you can get a list of all users and filter out the users with "nologin" or "false" in their config. If you get users that you do not want, change the filter items or add the username to the grep statement to filter them out, separate each filter item with \|
$ cat /etc/passwd | grep -Ev nologin\|false
using awk you can get just the username to print out
$ cat /etc/passwd | grep -Ev nologin\|false | awk '{split($0,a,":");print a[1]}'
running this command in a for loop will let us run a command on each user, to test just echo the username
$ for user in `cat /etc/passwd | grep -Ev nologin\|false | awk '{split($0,a,":");print a[1]}'`; do echo $user; done
the tricky part is passing a password to the passwd command. switch to the root user and then echo the password to the passwd command. Here is an example
$ sudo -i
# (echo 'newpassword'; echo 'newpassword') | passwd <username>
however you do not want the password in your command line history. put the password in a tempfile and then cat it to xargs. As an example, just echo the password using xargs
$ sudo -i
# vi tempfile
enter only one line with the new password
# cat tempfile | xargs -i echo {}
now you'll use xargs to echo to passwd. this is tricky again because you need to run two echo commands correctly, just tell xargs to run the command in a sub shell
$ sudo -i
# cat tempfile | xargs -i /bin/bash -c "(echo '{}'; echo '{}') | sudo passwd <username>"
now add the xargs command in the for loop
$ sudo -i
# for user in `cat /etc/passwd | grep -Ev nologin\|false | awk '{split($0,a,":");print a[1]}'`; do cat tempfile | xargs -i /bin/bash -c "(echo '{}'; echo '{}') | sudo passwd $user"; done
That should be it, let me know if you have questions
I tested this example on ubuntu 20.04 using GNU bash 5.0.17

issue with restarting autossh reverse tunnel on boot

I seem to have a weird issue:
I want to restart a reverse ssh tunnel on boot, I've tried it with an init script (that works fine when executed as user) and with an added line in /etc/rc.d but none of it works. What I get after boot is:
$ ps ax | grep autossh
397 pts/10 S+ 0:00 grep --color=auto autossh
1351 ? Ss 0:00 /usr/lib/autossh/autossh -M 22221 -N -o PubkeyAuthentication=yes -o PasswordAuthentication=no -i ~/.ssh/etherwan.key -R 19999:localhost:22 ubuntu#server
but I'm unable to login from server. So I did the following after boot:
$ sudo killall -KILL autossh
[sudo] password for ron:
$ /usr/bin/autossh -M 22221 -f -N -o "PubkeyAuthentication=yes" -o "PasswordAuthentication=no" -i ~/.ssh/etherwan.key -R 19999:localhost:22 ubuntu#server
upon which I can login using port 19999 just fine!
The keys permissions look like: (but root should not need to care, would it?)
$ ls -l ~/.ssh/etherwan.key
-r-------- 1 ron ron 1675 Nov 6 04:15 /home/ron/.ssh/etherwan.key
Replace ~/.ssh/etherwan.key in your rc.d script with /home/ron/.ssh/etherwan.key
The '~' character is expanded to the user's home directory by the shell, but rc.d scripts are run as root.

"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[^:]\+: //')"

How to allow a normal user to kill a certain root application in visudo with no password

I wanna allow a normal user to kill a certain application which is started by root user.
In visudo:
I added a line like this:
normal_user ALL=(ALL) NOPASSWD: /usr/bin/kill $(ps aux | grep 'target_application' | awk '{print $2}')
But after save it and execute the following command as normal_user, I still get the prompt for root password:
sudo /usr/bin/kill $(ps aux | grep 'target_application' | awk '{print $2}')
What should I do then? Thanks a lot!
sudo will not interpret the command as a shell script to execute. Therefore you have said that this literal command can be run as normal_user:
/usr/bin/kill $(ps aux | grep 'target_application' | awk '{print $2}')
However since the shell will interpret the stuff in the $(...) before sudo is called on it, the command you are running looks more like this:
sudo /usr/bin/kill 1234
So it doesn't let you use it.
As fedorqui suggested, you should write a script that kills the user and then give normal_user the right to run that script (make sure they don't have write access to the script or its directory though).
kill_target_application.sh:
#!/bin/sh
/usr/bin/kill $(ps aux | grep 'target_application' | awk '{print $2}')
Use this command to allow users to execute or read the script, but not modify it:
chown root:root <filename>
chmod 755 <filename>
The give (r)ead and e(x)ecute permissions for all users, but only root can modify it. Also ensure that the user does not have write permissions for the directory or any of its parent directories. Read the chown and chmod man pages before doing this if you aren't familiar with these utilities.
visudo entry:
normal_user ALL=(ALL) NOPASSWD: /path/to/kill_target_application.sh
You should probably use "killall" instead of this complicated ps | grep option. Or at least look into pgrep.
Also, this really sounds like a job for an init script.

How to print al list of user one by one with complete information in linux using shell

I have started writing a small piece of code to print all the list of users available in the linux box. But I want to pass one by one user into my command to display each user details together.
to list all users
root#bt# getent passwd | grep /home/ | cut -d ':' -f 1
root
san
postgres
Now I want to pass one by user in to the below command to display each user details together.
root#bt# chage -l ${user1} ; chage -l ${user2} etcc.
should I need to user for loop or while loop here?
can any one help me in suggesting how to write the same?
You can use the while loop:
getent passwd | grep /home/ | cut -d ':' -f 1 | \
while read user ; do
chage -l "$user"
done
or the for loop:
for user in $(getent passwd | grep /home/ | cut -d ':' -f 1) ; do
chage -l "$user"
done
or xargs:
getent passwd | grep /home/ | cut -d ':' -f 1 | \
xargs -n1 chage -l
I would use xargs, which runs a command on each output item of the previous pipe:
getent passwd | grep /home/ | cut -d ':' -f 1 | sudo xargs -I % sh -c '{ echo "User: %"; chage -l %; echo;}'
sudo is used to get information about all users, if you don't have access to this information then you can remove sudo
-I % is used to specify that % is a placeholder for the input item (in your case a user)
sh -c '{ command1; command2; ...;}' is the command executed by xargs on every % item; in turn, the command sh -c allows multiple shell commands to be executed
'{ echo "User: %"; chage -l %; echo;}' echoes the current user in %, then runs chage -l on this user and finished with a final empty echo to format the ouput

Resources