How can I get all information about specific user in ubuntu using bash ? - linux

Right now I have this code, that gives me only name, but I want to get name and other information from file /etc/passwd,
#!/bin/bash
user=$1;
grep home /etc/passwd | grep $user | cut -d: -f1;
I would like to get the full line, Not only my name.

Here is all the info on the current user. Note that because $USER is just a variable, it can be changed whereas the id command gives the actual user.
myuser#PC:~$ getent passwd $(id -u)
myuser:x:1000:1000:"",,,:/home/myuser:/bin/bash
myuser#PC:~$ export USER=root
myuser#PC:~$ getent passwd $USER
root:x:0:0:root:/root:/bin/bash

Try the finger command. You may need to install it.

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

Why can't this script execute the other script

This script looks for all users that have the string RECHERCHE inside them. I tried running it in sudo and it worked, but then stopped at line 8 (permission denied). Even when removing the sudo from the script, this issue still happens.
#!/bin/bash
#challenge : user search and permission rewriting
echo -n "Enter string to search : "
read RECHERCHE
echo $(cat /etc/passwd | grep "/home" | cut -d: -f5 | grep -i "$RECHERCHE" | sed s/,//g)
echo "Changing permissions"
export RECHERCHE
sudo ./challenge2 $(/etc/passwd) &
The second script then changes permissions of each file belonging to each user that RECHERCHE found, in the background. If you could help me figure out what this isn't doing right, it would be of great service. I
#!/bin/bash
while read line
do
if [-z "$(grep "/home" | cut -d: -f5 | grep -i "$RECHERCHE")" ]
then
user=$(cut -f: -f1)
file=$(find / -user $(user))
if [$(stat -c %a file) >= 700]
then
chmod 700 file 2>> /home/$(user)/challenge.log
fi
if [$(stat -c %a file) < 600]
then
chmod 600 file 2>> /home/$(user)/challenge.log
fi
umask 177 2>> /home/$(user)/challenge.log
fi
done
I have to idea what I'm doing.
the $(...) syntax means command substitution, that is: it will be replaced by the output of the command within the paranthesis.
since /etc/passwd is no command but just a text-file, you cannot execute it.
so if you want to pass the contents of /etc/passwd to your script, you would just call it:
./challenge2 < /etc/passwd
or, if you need special permissions to read the file, something like
sudo cat /etc/passwd | ./challenge2
also in your challenge2 script, you are using $(user) which is wrong as you really only want to expand the user variable: use curly braces for this, like ${user}
/etc/passwd?
not what you were asking, but you probably should not read /etc/passwd directly anyhow.
if you want to get a list of users, use the following command:
$ getent passwd
this will probably give you more users than those stored in /etc/passwd, as your system might use other PAM backends (ldap,...)

'Permission Denied' even while running as root

I have a simple bash shell script:
user_exists=cat /etc/passwd | grep 'GNU Mailman'
echo $user_exists
when I run this script with sudo ./'script_name', I get a permission denied error on the line where I attempt to access /etc/passwd. What am I doing wrong here?
To understand why, you have to look at the line the way that bash looks at the line:
user_exists=cat /etc/passwd | grep 'GNU Mailman'
According to bash, you are (temporarily) setting the environment variable user_exists to have the value cat. With that value set, then the program /etc/passwd is executed and its output sent to grep 'GNU Mailman'. Since /etc/passwd does not have execute permission, this command fails for lack of permission.
The solution is to use the proper format for process substitution as outlined by Vladimir Kolesnikov:
user_exist=$(grep 'GNU Mailman' /etc/passwd)
user_exists=$(cat /etc/passwd | grep 'GNU Mailman')
or better yet,
getent passwd username

Why does the output differ when executed from a shell script?

According to this post, I run this from the command line:
USER_HOME=$(getent passwd $SUDO_USER | cut -d: -f6)
and get the following output:
/root
/usr/sbin
/bin
/dev
/bin
/usr/games
/var/cache/man
/var/spool/lpd
/var/mail
/var/spool/news
/var/spool/uucp
/bin
/var/www
/var/backups
/var/list
/var/run/ircd
/var/lib/gnats
/nonexistent
/var/lib/libuuid
/home/user
/var/run/vboxadd
/var/lib/puppet
/var/run/sshd
When I run this in a script (as sudo, which is the point of the whole thing --- as sudo, ~ expands to /root):
USER_HOME=$(getent passwd $SUDO_USER | cut -d: -f6)
echo $USER_HOME
I get my correct path /home/user.
Why can I not invoke my function manually to get the same output?
Because when not using sudo, $SUDO_USER is not set and you get the output of getent passwd without further argument, which lists all users. The cut then extracts the home directory part.
Replace $SUDO_USER with $USER when not running with sudo.
Note that using getent passwd ${SUDO_USER:-$USER} should work in both cases.

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.

Resources