While loop, username in /etc/passwd - linux

How would I go about writing a while loop that says: While a username is in the /etc/passwd file, do (command)?
I'm trying to use a command such as grep -q "^{usern}:" /etc/passwd but I'm not sure how to put that as the condition of the while loop.

To loop over the users in /etc/passwd and do something with each user, try the following:
cut -d: -f1 /etc/passwd | while IFS= read -r user
do
echo "$user"
# do something with $user
done
If you want to check whether a specific user exists in /etc/passwd and then do something, use an if-statement:
if grep -q "^username:" /etc/passwd
then
# do something
fi

Related

how to change user password in ubuntu using xargs

I need to change the password of "vtm" user to "abcd12345" by using xargs command.
so I wrote this comman
printf "vtm abcd12345 abcd12345" | xargs -t -n1 passwd
but I couldn't change it.
You could use chpasswd command to change password instead.
# 1. find the user id of `vtm`
> sudo grep "vtm" /etc/passwd.
# 2. change password with `chpasswd`
echo 'userid:abcd12345' | chpasswd
Or if you want to change password with echo:
echo -e -n "abcd12345\nabcd12345" | passwd vtm

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

Bash Script To Remove Users From Wordlist

I wrote the following script to remove users from a wordlist. The wordlist has 3 or 4 fields which are First Name, Middle Name, Last Name, and User ID. I am using awk to create a username that comprises of the user's firstname initial, lastname and last two digits of their ID. Then using the command userdel with flag r to remove users with their home directories as well.
However when I run the script it gives me an error saying the following:
Usage: userdel [options] LOGIN
Options:
-f, --force force some actions that would fail otherwise
e.g. removal of user still logged in
or files, even if not owned by the user
-h, --help display this help message and exit
-r, --remove remove home directory and mail spool
-R, --root CHROOT_DIR directory to chroot into
-Z, --selinux-user remove any SELinux user mapping for the user
The script:
#! /bin/bash
# Removing users using positional parameters
getusername(){
line=${1}
len=`echo ${line}|awk '{ FS = " " } ; { print NF}'`
if [[ ${len} -eq 3 ]]
then
initial=`echo ${line}| awk {'print $1'} |cut -c1`
lastname=`echo ${line} | awk {'print $2'}`
id=`echo ${line}| awk {'print $3'}|grep -o '..$'`
username=`echo ${initial}${lastname}${id} |tr '[:upper:]' '[:lower:]'`
elif [[ ${len} -eq 4 ]]
then
initial=`echo ${line} | awk {'print $1'} |cut -c1`
lastname=`echo ${line} | awk {'print $3'}`
id=`echo ${line}| awk {'print $4'}|grep -o '..$'`
username=`echo ${initial}${lastname}${id} |tr '[:upper:]' '[:lower:]'`
else
echo "Line ${line} is not expected as it should be considered for creating Username and Password"
fi
}
sudo userdel -r $getusername
How to invoke userdel?
userdel -r username
This deletes the account of user username, and removes that user's home directory and associated mail files.
For that, you need to use a variable instead of to invoke a function.
Otherwise userdel will complain, like it is already doing or like just typing userdel.

Linux - List users which have specific directory

I am trying to create a script which will list the name of the user, only if that specific user has a specific and available directory in his folder.
#!/bin/bash
for i in `cat /etc/passwd | cut -d : -f5\,6 | cut -d : -f2`
do
cd $i
if [ -d public_html ]
then
echo `cat /etc/passwd | cut -d : -f5,6 | cut -d : -f1`
fi
done
First, I get a list of all the user names that have home folders.
Then, for each user, I enter in his directory
If in his directory, public_html directory is found, echo the user.
When I run this in the terminal, all the users are listed:
cat /etc/passwd | cut -d : -f5,6 | cut -d : -f1
However, I need to somehow get the user i from that whole list.
Can anybody be so kind to explain what I´m doing wrong, and what to look out for?
You're getting the wrong result because you're checking for a file (with -f). Try using -d.
Using cat and cut is not bash either and can easily be replaced with script in most cases.
I'd do something like this:
while IFS=: read -r user pass uid gid desc homedir shell; do [ -d "$homedir"/public_html ] && echo "$user"; done < /etc/passwd
We set the field separator (IFS) to : (since that's what /etc/passwd uses), we read the file in and set the variables we want to use.
Then for each line we do the test and (&&) if the test is successful we echo the result.
The quotes are not really necessary since we know the formatting of the file but good practice.
If users' home directories are set up in the standard way:
cd /home
for pubdir in */public_html/ ; do
echo "${pubdir%%/*}"
done
I did it ghetto style...
#!/bin/bash
counter=0
for i in `cat /etc/passwd | cut -d : -f6`
do
if [ -r $i ]
then
cd $i
if [ -d public_html ]
then
counter2=2
for j in `cat /etc/passwd | cut -d : -f5`
do
counter2=$(($counter2 + 1))
if [ $counter -eq $counter2 ]
then
echo $j
fi
done
fi
counter=$(($counter + 1))
fi
done
#!/bin/bash
getent passwd | awk -F: '{printf "%s\t%s\n",$1, $6}'| while read -r user home
do
if [ -d ${home}/public_html ] ; then
echo ${user}
fi
done
This should work irrespective of use of /etc/passwd or ldap ...

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,...)

Resources