多用户一次性强制密码过期
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,通常是 500
或 1000
-- 检查你的发行版)。最大 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,那么管道将在两种情况下都有效)
满意后,取消注释循环中的最后一行,并可选择删除仅输出命令 运行.
的行
如何查询一个盒子上的所有用户并强制密码过期?
目前我正在查询所有用户:
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,通常是 500
或 1000
-- 检查你的发行版)。最大 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,那么管道将在两种情况下都有效)
满意后,取消注释循环中的最后一行,并可选择删除仅输出命令 运行.
的行