struct spwd { char *sp_namp; /* user login name */ char *sp_pwdp; /* encrypted password */ long int sp_lstchg; /* last password change */ long int sp_min; /* days until change allowed. */ long int sp_max; /* days before change required */ long int sp_warn; /* days warning for expiration */ long int sp_inact; /* days before account inactive */ long int sp_expire; /* date when account expires */ unsigned long int sp_flag; /* reserved for future use */ }
经过查看shadow的手册,能够看到上面的代码解释,分别对应/etc/shadow 中的各项参数linux
mail:*:15513:0:99999:7:::
参数一: sp_namp 用户名称算法
参数二: sp_pwdp 用户加密后的密码安全
参数三: sp_lstchg 用户密码最近一次修改时间,算法是今天的时间减去jan,1,1970获得的时间间隔bash
参数四: sp_min 用户最少多少天后才能改密码的天数(默认为0,表示能够在任什么时候间修改,有啥意义?有种需求叫密码永不变= =。)测试
参数五: sp_max 用户最多多少天后必定要修改密码的天数,系统会强制用户修改密码(默认为99999,改成1 也能让密码改不了)ui
参数六: sp_warn 过时前多少天时间会被警告(改成-1 则永远不会提示)this
参数七: sp_inact 过时后多少天内帐号变为inactive状态,可登录,但不能操做 加密
参数八: sp_expire 多少天后帐号会过时,没法登录spa
参数九: sp_flag 保留参数code
————————————————————————————————————————————————————————
根据上述功能,我考虑了个需求
1. 查看当前全部用户何时过时的,用日期的表示方法表示出来
首先实现这个功能手动去加减实在不必,linux有个date命令自带了个转换功能(实在是人性化,修改days为sec 能够获得相加秒的结果)
[root ]# date -d "1970-01-01 15776 days" +%Y/%m/%d 2013/03/12
而后,就简单啦~~写个脚本转换下,一个awk能够搞定
再为了看的整齐点
#! /bin/bash # FILE=/etc/shadow awk -F ':' '{ if ($2 != "*" && $2 != "!!" ) { NAME=$1; MAX_CH=$3+$5; EXPIRE=$3+$8; CMD="echo -e "NAME" \"\t\`date -d \"1970-01-01 "MAX_CH" days\" +%Y/%m\` \t`date -d \"1970-01-01 "EXPIRE" days\" +%Y/%m\`\" " system(CMD); } }' $FILE 2>/dev/null |sort -k 3 | awk '{printf("%-15s%-15s%-15s\n",$1,$2,$3)}'
2.根据密码安全规则考虑,除了root用户 全部用户应该要3个月必须改一下密码并设置下时间提醒
这个需求涉及到如何修改已有用户的各项属性
先来了解个命令
[root@Bridge ~]# chage --help Usage: chage [options] [LOGIN] Options: -d, --lastday LAST_DAY set date of last password change to LAST_DAY -E, --expiredate EXPIRE_DATE set account expiration date to EXPIRE_DATE -h, --help display this help message and exit -I, --inactive INACTIVE set password inactive after expiration to INACTIVE -l, --list show account aging information -m, --mindays MIN_DAYS set minimum number of days before password change to MIN_DAYS -M, --maxdays MAX_DAYS set maximim number of days before password change to MAX_DAYS -W, --warndays WARN_DAYS set expiration warning days to WARN_DAYS
新建一个测试帐号 testlinjq:*****:16772:0:99999:7:::
根据需求chage –M 6 testlinjq ,令该“testlinjq”用户第七天就要改密码,测试下warning参数是否会提醒
testlinjq:*******:16772:0:6:7:::
Warning: your password will expire in 6 days Last login: Thu Dec 3 14:57:50 2015 from 10.0.0.120
确实生效了,那么本次修改的帐号属性应该有3个。
1. 用户上一次修改时间,改成今天,即从今天起后3个月要改密码,对应命令chage –d 16772
2. 用户最大超时时间,90天 chage –M 89,(有强迫症的同窗能够给改为90,测试了确实是从0开始计数)
3. 用户密码超时提醒开启,方便起见,我给设置成99,至关于永远提醒,只要比MAX的值大就行 chage –W 99
最终造成以下脚本
#! /bin/bash # FILE=/etc/shadow OUTPUT=/tmp/expire-time function PRINTUSERS { awk -F ':' '{ if ($2 != "*" && $2 != "!!" ) { NAME=$1; MAX_CH=$3+$5; EXPIRE=$3+$8; CMD="echo -e "NAME" \"\t\`date -d \"1970-01-01 "MAX_CH" days\" +%Y/%m/%d\` \t`date -d \"1970-01-01 "EXPIRE" days\" +%Y/%m/%d\`\" " system(CMD); } }' $FILE 2>/dev/null |sort -k 3 | awk '{printf("%-15s%-15s%-15s\n",$1,$2,$3)}' 1> $OUTPUT cat $OUTPUT } function UPDATAUSERS { let TODAY=`date +%s`/86400 while read LINE ;do NAME=`echo $LINE | cut -d ' ' -f 1` if [ $NAME == "root" ];then continue; fi chage -d $TODAY -M 89 -W 99 $NAME done < $OUTPUT } case $1 in "--PRINT") PRINTUSERS ;; "--UPDATA") UPDATAUSERS ;; *) echo "command is [--PRINT|--UPDATA] " ;; esac