Find users with root UID or GID or root home

I need to list users in /etc/passwd with root's GID or UID or /root as home directory
If we have these entries in /etc/passwd

root:x:0:0:root:/root:/bin/bash
rootgooduser1:x:100:100::/home/gooduser1:/bin/bash
baduser1:x:0:300::/home/baduser1:/bin/bash
baduser2:x:400:0::/home/baduser2:/bin/bash
baduser3:x:500:500:root:root:/bin/bash
baduser4:x:0:0::/home/baduser4:/bin/bash
gooduser2:x:600:600::/home/gooduser1:/bin/bash

The sed/awk operation should list out only badusers, as they hold either, roots UID or GID or /root as home directory.

So, The UID & GID for the root account are both zero. The fields are separated by : so you can:

grep ":0:" /etc/passwd

Does that give you a starter? Have a look at the cut manual page if you need to slice up the output to give you just the names.

I hope that this helps,

Robin
Liverpool/Blackburn
UK

Thank you, but it should not list
root:x:0:0:root:/root:/bin/bash
and also, should list
baduser3:x:500:500:root:root:/bin/bash
as baduser3 has home directory set as /root

You said you want to use sed or awk, cut (as suggested by rbatte1) is another possibility. I would guess that awk will be better for this job than sed.

You've been watching what we have been doing here for more than 1.5 years.
Can you show us how to use awk (or grep and cut) to get the UID, GID, and home directory for root out of /etc/passwd?

Once you have those values, can you show us how to use awk or cut to find other users with the same UID as root, the same GID as root, or the same home directory as root?

Show us that you have made an attempt to solve this problem by showing us what you have tried so far. Tell us what is working and what you can't get to work yet.

Strictly, baduser3 has an invalid home directory. You can always extend the grep to include :/root: too. Have a read of the man page for that.

What have you tried so far with awk or sed?

Robin

Thanks for the help guys. Was able to manage.

$ cat testpasswd
root:x:0:0:root:/root:/bin/bash
rootgooduser1:x:100:100::/home/gooduser1:/bin/bash
baduser1:x:0:300::/home/baduser1:/bin/bash
baduser2:x:400:0::/home/baduser2:/bin/bash
baduser3:x:500:500:root:root:/bin/bash
baduser4:x:0:0::/home/baduser4:/bin/bash
gooduser2:x:600:600::/home/gooduser1:/bin/bash
baduser5:x:0:0:root:/root:/bin/bash

Operation

$ cat testpasswd |  grep -E ':0:|:root:'  | grep -v  'root:x:0:0'
baduser1:x:0:300::/home/baduser1:/bin/bash
baduser2:x:400:0::/home/baduser2:/bin/bash
baduser3:x:500:500:root:root:/bin/bash
baduser4:x:0:0::/home/baduser4:/bin/bash
baduser5:x:0:0:root:/root:/bin/bash

---------- Post updated at 07:14 AM ---------- Previous update was at 07:00 AM ----------

I have attempted.

$ cat testpasswd | awk 'BEGIN{print "UID\tGID\tHome_Directory";} {FS=":"} {print $3 "\t" $4 "\t" $6}'
UID     GID     Home_Directory

100     100     /home/gooduser1
0       300     /home/baduser1
400     0       /home/baduser2
500     500     root
0       0       /home/baduser4
600     600     /home/gooduser1
0       0       /root

With cut

$ cat testpasswd | cut -d: -f 3,4,6
0:0:/root
100:100:/home/gooduser1
0:300:/home/baduser1
400:0:/home/baduser2
500:500:root
0:0:/home/baduser4
600:600:/home/gooduser1
0:0:/root

1 Like

Good. You're learning how to use the tools.

Note that your output doesn't include the login names of the users whose entries are failing your tests. You might want to add that to your output.

If you'd like to get root's UID, GID, and login directory from the password file instead of assuming that they will be 0, 0, and /root, respectively, (and you're willing to live with the limitation that root's information must appear on the 1st line in the passwd file), you could consider something like:

#!/bin/ksh
awk -F: '
NR == 1 {if($1 != "root") {
                printf("root expected on first line in %s; found %s instead.\n",
                        FILENAME, $1)
                exit 1
        }
        rootuid = $3
        rootgid = $4
        roothd = $6
        next
}
$3 == rootuid || $4 == rootgid || $6 == roothd { print }' "${1:-testpasswd}"

which produces the output:

baduser1:x:0:300::/home/baduser1:/bin/bash
baduser2:x:400:0::/home/baduser2:/bin/bash
baduser4:x:0:0::/home/baduser4:/bin/bash

Note also that baduser3's login directory ( root ) is not identical to root's login directory ( /root ), so I'm not sure if that line should be included in your output or not. (However, all login directories in /etc/passwd should have absolute pathnames. Should you add a check to verify that each user's login directory starts with a / ?)
If you don't want to print the entire line from the passwd file for lines that fail your tests, you've already shown that you know how to print just the fields you want.