Check if user exists and belong to group - linux

I want to check three conditions before I run the command: If string (username) match to regexp, if user exists and if user belongs to certain group:
PASSWORD=`/usr/bin/pwgen -sync -1 15`
CHPASSWD=/usr/sbin/chpasswd
FILE=/tmp/password
USER_GROUP=somegroup
while true
do
echo -ne "username: "; read USER_NAME
if [[ "$USER_NAME" =~ ^[a-z_][a-z0-9_]*[$]?$ ]] &&
[[ `getent group $USER_GROUP | grep -o $USER_NAME` -eq 0 ]] &&
[[ `getent passwd $USER_NAME | cut -d ':' -f -1` -eq 0 ]]
then
break
else
echo "error"
fi
done
echo $USER_NAME:$PASSWORD > $FILE
sudo $CHPASSWD < $FILE
rm -f $FILE
The above code works partially only. It checks for regexp and group but it is trying to change password for even if user doesn't exist.

The right solution is:
while true
do
echo -ne "username: "; read USER_NAME
if [[ "$USER_NAME" =~ ^[a-z_][a-z0-9_]*[$]?$ ]]
then
if [[ `getent group $USER_GROUP | grep -w -c "$USER_NAME"` -eq 1 ]]
then
break
else
echo "User not in the right group"
fi
else
echo "Invalid characters"
fi
done

Related

Having difficulty checking a file for if input is repeated in a file using bash script

#!/bin/bash
#variables
option=$1
myfile=~/.bdrecord.txt;
#supported options
opts=("-a" "--test" "-app" "-c" "-v");
argc=("ram ram nov 12 pen | --test" "" "1s|1m|1h" "" "");
flag=0;
for o in ${opts[#]}
do
if [[ $o = ${option} ]];
then
flag=1;
break
fi
done
if [[ ${flag} -ne 1 ]];
then
echo -e "Program aborted!\nSupported commands are like"
for i in ${!opts[#]};
do
echo -e "$i.\t" $0 ${opts[$i]} ${argc[$i]}
done
fi
#defaults
name="Rambo"
nickname="Ram"
bmth=$(date +%h);
bday=$(date +%d);
gift="hat-type"
#new feature, handle --test option along with -a option
if [[ ${option} = "-a" ]];
then
while read -r name nickn month day gift
do
if [[ ${2} = ${name} ]];
then
isRepeated=1;
break;
fi
done
if [[ isRepeated == 1 ]]
then
echo "${name} is a repeated name. Try again."
exit 22;
fi
if [[ ${2} = "--test" ]];
then
#add some test data and exit.
for ((i=0;i<5; i++))
do
row="${name}-$i,${nickname},${bmth},$(($bday+$i)),${gift}-${i}";
echo ${row} >> ${myfile}
done
echo "Saved 5 samples in ${myfile}";
echo "...";
tail -n 5 ${myfile};
echo -e ".." $(cat ${myfile} | wc -l) "entries"
exit 0;
fi
#handle more or less than 5 inputs
if [[ $# -ne 6 ]];
then
echo "Expected 5 args (name nickname month day gift) with -a option."
exit 22;
fi
echo "option -a is received!"
#save last 5 inputs in the file
##collect last 5 inputs
name=$2
nickname=$3
bmth=$4
bday=$5
gift=$6
row="${name},${nickname},${bmth},${bday},${gift}";
echo ${row} >> ${myfile}
#display current date
echo "Today: $(date)";
#display "yeah.."
echo "Yeah ${nickname} has been added!"
#display count of records
echo "--------"
wc -l ${myfile}
fi
#handle -c option
#handle -v option
#new feature, handle -app option
if [[ ${option} = "--app" ]];
then
if [[ $# -ne 2 ]];
then
echo "Expected arg sleep time {1s, 2s, 3s..1m, 2m, 3m, ..1h, 2h, 3h..}";
exit 44;
fi
echo "Entered App Mode. Use kill command to kill it."
#find person whose birthday is today
thismonth=$(date +"%h")
ithismonth=$(date +"%m")
thisday=$(date +"%d")
bdlist=();
while IFS="," read -r name nickn month day gift
do
if [[ ("${month,,}" = "${thismonth,,}" \
||
"${month,,}" -eq "${ithismonth,,}") ]] \
&& [[ ${day} = ${thisday} ]]
then
#add to list
bdlist+=("Today is ${name}'s $day birthday! Selected gift is:${gift} ")
fi
done < ${myfile}
while :
do
#every hour send three messages notifying whose birthday is today.
sleep ${2};
for l in "${bdlist[#]}";
do
echo "$l" >> ~/.bdlog.txt;
done
let i++;
done
fi
The instructions of my assignment clearly state to: Modify the given script so that for the "-a" option, the script stores the arguments (name, nickname, birthday month, birthday day, gift) in the file ~/.bdrecord.txt only if the given input name does not exist in the record file ~/.bdrecord.txt
However, my code is erroring. The part that I added is the part where isRepeated is.

Adding exceptions during cut returns unwanted results

I have a file that is being generated (sort of an audit file) with who have accessed said file. Looks as follows:
I need to write an alarming system that enters said report and checks for all users. however bash for some reason interprets the "------" as an input.
for i in $(cut -c 8-13 report_file.csv)
do
if [[ $i -eq 'suser' ]] || [[ $i -eq '--------' ]] || [[ $i -eq 'login' ]] || $i -eq 'root']]
then
break
else
echo "email text"+ $i | mailx -s "email subject" $EMAILS_LIST
done
the output for this is:
./script_name.sh: line 26: [[: --------: syntax error: operand
expected (error token is "-")
So as I understand it takes the exception "------" and still sees it as sort of input.
So, what am I missing?
-eq in test (same in extended test [[...]]) is an operator for integers. '---------' is not an integer. Use = to compare strings.
... [[ "$i" = 'suser' ]] || [[ "$i" = '--------' ]] || [[ "$i" = 'login' ]] || [[ "$i" = 'root' ]]
or simpler
... [[ "$i" = 'suser' || "$i" = '--------' || "$i" = 'login' || "$i" = 'root' ]]
or simpler:
case "$i" in
suser|--------|login|root) ;;
*) echo "email text"+ $i | mailx -s "email subject" $EMAILS_LIST; ;;
esac
Side note:
Reading lines from file using for i in $(...) is bad. It's better to use while read -r line; do .... done < <(cut -c 8-13 report_file.csv) or cut -c 8-13 report_file.csv | while read -r line; do ... done see here.

How to match "whitespace" and "OR" condition with bash script?

I want to match a condition in bash containing "whitespaces" and "OR" condition within strings. I am unable to do as i am new to shell scripting, please help as it going to else loop where it is matching ${myarrlin[1]} . I am getting "Centrify is disabled" but i want the condition to be true here. Here is my code :
FILE_CENT="/etc/nsswitch.conf"
OS=`uname`
if [[ $OS = 'Linux' ]]; then
if [[ -e $FILE_CENT ]]; then
echo "nsswitch.conf found, Proceeding further..."
while read -r LINE
do
if [[ $LINE =~ ^passwd ]]; then
myarrlin=($LINE)
if [[ ${myarrlin[1]} =~ ^(centrify)|(centrifydc)[[:space:]]* || ${myarrlin[1]} =~ [[:space:]]+(centrify)|(centrifydc)[[:space:]]* ]]; then
echo "Centrify is enabled"
else
echo "Centrify is disabled"
fi
fi
done < $FILE_CENT
else
echo "nsswitch.conf does not exist in $OS, cannot fetch CENTRIFY information!"
fi
fi
nsswitch.conf >>>
passwd: centrify files
or
passwd: centrifydc files
or
passwd: files centrify
or
passwd: files centrifydc
Why are you doing this: myarrlin=($LINE) ?
If you just want to know if the line contains centrify:
while read -r LINE
do
if [[ ${LINE} =~ ^passwd ]]; then
if [[ ${LINE} == *"centrify"* ]]; then
echo "Centrify is enabled"
else
echo "Centrify is disabled"
fi
fi
done < $FILE_CENT

CouchDB Replication verify

I am searching easy way to verify replicated documents, that all of them were transferred.
Also, when some documents have error during replication process, how to check, which one and/or why ?
Now, I have an idea, that I could check current checkpointed sequence on the source. Then list all ids from source/_changes and then HEADing (or GETing) documents from target database and verify their presence (or values).
Simple nagios script to check two servers dbs and doc counts match - could be improved to check that _rev for each between dbs match.
#!/usr/local/bin/bash
# nagios check script to make sure 2 couch servers are the same
#
# ie: have same dbs
# have same number of documents in each db
#
# ./check_couch_dbs 192.168.1.2 192.168.1.3
#
# Needs fdescfs for bash redirects
#
# Needs npm - as root: 'pkg install npm'
# Needs json - as root: 'npm install -g json'
# https://github.com/zpoley/json-command
#
#
# check_couch_dbs command definition example
#
# define command{
# command_name check_couch_dbs
# command_line $USER1$/check_couch_dbs $ARG1$ $ARG2$
# }
#
host1=$1
host2=$2
difference_threashold=10
dbs1=`curl -s http://$host1:5984/_all_dbs | json -ga | grep -v -E '_replicator|_users' | sort`
dbs2=`curl -s http://$host2:5984/_all_dbs | json -ga | grep -v -E '_replicator|_users' | sort`
dif=`diff -y --suppress-common-lines -b -s <(echo "$dbs1") <(echo "$dbs2")`
err=""
msg=""
exitcode=0
if [[ "$dif" == *identical* ]]; then
msg+="Couchdbs lists match"
fi
if [[ "$dif" == *\<* ]]; then
err+="ERROR - db missing from $host2 \n"
exitcode=2
fi
if [[ "$dif" == *\>* ]]; then
err+="ERROR - db missing from $host1 \n"
exitcode=2
fi
if [[ $exitcode -gt 0 ]]; then
echo -e -n $err
echo "$dif"
err=""
# exit $exitcode
fi
dbs=`echo -e "$dbs1\n$dbs2" | sort | uniq`
#echo "$dbs"
for db in $dbs; do
count1=`curl -s http://$host1:5984/$db | json doc_count`
if [ -z "$count1" ]; then continue; fi #no db
count2=`curl -s http://$host2:5984/$db | json doc_count`
if [ -z "$count2" ]; then continue; fi #no db
if [ "$count1" -ne "$count2" ]; then
if [ "$count1" -gt "$count2" ]; then
difference=$(($count1 - $count2))
else
difference=$(($count2 - $count1))
fi
if [[ $difference -gt $difference_threashold ]]; then
err+="ERROR - $db count difference $host1: $count1 != $host2: $count2 - difference: $difference\n"
exitcode=2
else
err+="WARNING - $db count difference $host1: $count1 != $host2: $count2 - difference: $difference\n"
if [[ $exitcode -lt 1 ]]; then
exitcode=1
fi
fi
fi
done
if [[ $exitcode -gt 0 ]]; then
echo -e -n $err $msg
exit $exitcode
else
echo -e "OK - $msg - doc_count match"
exit $exitcode
fi
Having slept on it i think the below would cover the comparing of all docs and _revs
#!/usr/local/bin/bash
db1=`curl -s http://192.168.1.2:5984/mydb/_all_docs`
db2=`curl -s http://192.168.1.3:5984/mydb/_all_docs`
dif=`diff -y --suppress-common-lines -b -s <(echo "$db1") <(echo "$db2")`
echo $dif

Linux bash read from a file then adduser to linux

I want to add linux users then i want to restrict them as hard as possible. (noshell etc) from a file called users.
This is my code but not working:
while read line
do
input = echo ($input | tr ":" "\n")
#!/bin/bash
# Script to add a user to Linux system
if [ $(id -u) -eq 0 ]; then
if [ $? -eq 0 ]; then
echo "$username exists!"
exit 1
else
pass=$(perl -e 'print crypt($ARGV[0], "password")' $input[1)
useradd -m -p $input[1] $input[0]
[ $? -eq 0 ] && echo "User has been added to system!" || echo "Failed to add a user!"
fi
else
echo "Only root may add a user to the system"
exit 2
fi
done < /var/www/users
Then i want to restrict their accounts with noshell. (but i know how can i do. But i cant separate the input from the file correctly :/)
input(users):
john:lol
rambo:sanyi
cula:kari
Thank you very much!
I think, following script will do:
#!/bin/bash
USERS=`cat /etc/passwd | cut -d: -f1`
if [ `id -u` -ne 0 ]
then
echo "Login as Root"
else
while read line
do
USER=`echo $line | cut -d ":" -f1`
PASS=`echo $line | cut -d ":" -f2`
echo $USERS | grep "${USER}" > /dev/null
if [ $? -eq 0 ]
then
echo "Username ${USER} Exists!"
else
password=`perl -e 'print crypt("${PASS}", "salt")', "\n"`
useradd -p "${password}" ${USER}
echo "User ${USER} created!"
fi
i+=1
done < /var/www/users
fi

Resources