多用户一次性强制密码过期

Force password expiration multiple-users one-time

如何查询一个盒子上的所有用户并强制密码过期?

目前我正在查询所有用户:

getent shadow | awk -F: ' ~ /^$/ ||  ~ /^!$/ {print } {print }'

这让我得到了用户名和最后一次更改密码,但我只需要对自 2022 年 3 月 1 日以来没有更改过密码的用户强制执行 passwd -e - 任何人在 2022 年 3 月 1 日之后更改了他们的密码,我可以不理会它们(我相信这将是一个值 19052 - 所以任何大于或等于该值的值我都可以跳过)。

我这样做了:

cut -d: -f1 /etc/passwd | { while IFS= read -r n; do echo -n "$n "; chage -li "$n" | awk 'NR==1{print $NF}'; done; echo CUTME 2022-03-01; } | sort -k2 | awk 'f{print} /CUTME/{f=1}'

如果需要,您可以xargs passwd -e

我喜欢@KamilCuk 采取的方法。除此之外,我将在解析 /etc/passwd 时包括最小值 UID 和最大值 UID 以排除系统帐户。 (注意:一些发行版以不同的值开始第一个 non-system UID,通常是 5001000 -- 检查你的发行版)。最大 UID 可以排除位于范围顶部的通用用户帐户,例如 openSUSE 上的 nobody 帐户 UID == 65534

要确定密码更改早于 2022 年 3 月 1 日的帐户是否过期,可以很容易将该日期和 chage 返回的日期转换为 seconds-since-Epoch。这样您就可以使用一个简单的比较来比较上次密码更改是否小于自 2022 年 3 月 1 日大纪元以来的秒数——使帐户过期。

下面是您可以采用的一种将所有内容组合在一起的方法。 xargs 是构建列表而不是过期帐户的另一种选择 one-by-one。实际过期在下面被注释掉,而是 运行 的命令被打印到 stdout 以允许在帐户实际过期之前进行测试。

#!/bin/bash

## validate script is run with root privilege
[ $UID != 0 ] && [ $EUID != 0 ] && {
  printf "error: script must be run as root, UID '%s' can't,\n" "$UID" >&2
  exit 1
} 

minUID=1000     ## first non-system UID
maxUID=65534    ## nobody

march1epoch=$(date -d "2022-03-01" +%s)   ## seconds since epoch

## pipe non-system users to while loop to check aging with chage
awk -v minU="$minUID" -v maxU="$maxUID" -F: '
   >= minU &&  < maxU { print  }
' /etc/passwd | 
{
## read each user name, get age since last pw change
while read -r usrnm; do 
  age=$(date -d "$(chage -l "$usrnm" | 
        awk -F: 'FNR==1 {print $NF; exit}')" +%s)
  ## compare with march1epoch, expire all that are older
  [ "$age" -lt "$march1epoch" ] && echo "passwd -e \"$usrnm\""
  ### uncomment line below to actually expire account
  # [ "$age" -lt "$march1epoch" ] && passwd -e "$usrnm"
done
}

(注意: 您可以使用 进程替换 来提供 bash 中的 while 循环,而不是将结果传递给它——由你决定。如果你坚持使用 POSIX shell,那么管道将在两种情况下都有效)

满意后,取消注释循环中的最后一行,并可选择删除仅输出命令 运行.

的行