Detect left over users and groups on OpenBSD

Comment on Mastodon

Introduction

If you use OpenBSD and administrate machines, you may be aware that packages can install new dedicated users and groups, and that if you remove a package doing so, the users/groups won't be deleted, instead, `pkg_delete` displays instructions about deletion.

In order to keep my OpenBSD systems clean, I wrote a script looking for users and groups that have been installed (they start by the character `_`), and check if the related package is still installed, if not, it outputs instructions that could be run in a shell to cleanup your system.

The code

#!/bin/sh

SYS_USERS=$(mktemp /tmp/system_users.txt.XXXXXXXXXXXXXXX)
PKG_USERS=$(mktemp /tmp/packages_users.txt.XXXXXXXXXXXXXXX)

awk -F ':' '/^_/ && $3 > 500 { print $1 }' /etc/passwd | sort > "$SYS_USERS"
find /var/db/pkg/ -name '+CONTENTS' -exec grep -h ^@newuser {} + | sed 's/^@newuser //' | awk -F ':' '{ print $1 }' | sort > "$PKG_USERS"

BOGUS=$(comm -1 -3 "$SYS_USERS" "$PKG_USERS")
if [ -n "$BOGUS" ]
then
    echo "Bogus users/groups (missing in /etc/passwd, but a package need them)" >/dev/stderr
    echo "$BOGUS" >/dev/stderr
fi

EXTRA=$(comm -2 -3 "$SYS_USERS" "$PKG_USERS")
if [ -n "$EXTRA" ]
then
    echo "Extra users" >/dev/stderr

    for user in $EXTRA
    do
        echo "userdel $user"
        echo "groupdel $user"
    done
fi

rm "$SYS_USERS" "$PKG_USERS"

How to run

Write the content of the script above in a file, mark it executable, and run it from the shell, it should display a list of `userdel` and `groupdel` commands for all the extra users and groups.

Conclusion

With this script and the package `sysclean`, it's quite easy to keep your OpenBSD system clean, as if it was just a fresh install.

Limitations

It's not perfect in its current state because if you deleted an user, the according group that is still left won't be reported.