• linux /etc/shadow文件详解


    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 中的各项参数

    mail:*:15513:0:99999:7:::

      参数一: sp_namp 用户名称

      参数二: sp_pwdp 用户加密后的密码

      参数三: sp_lstchg 用户密码最近一次修改时间,算法是今天的时间减去jan,1,1970得到的时间间隔

      参数四: sp_min  用户最少多少天后才能改密码的天数(默认为0,表示可以在任何时间修改,有啥意义?有种需求叫密码永不变= =。)

      参数五: sp_max 用户最多多少天后一定要修改密码的天数,系统会强制用户修改密码(默认为99999,改为1 也能让密码改不了)

      参数六: sp_warn 过期前多少天时间会被警告(改为-1 则永远不会提示)

      参数七: sp_inact 过期后多少天内账号变为inactive状态,可登陆,但不能操作

      参数八: sp_expire 多少天后账号会过期,无法登陆

      参数九: sp_flag 保留参数

     

    ————————————————————————————————————————————————————————

      根据上述功能,我考虑了个需求

      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" "	\`date -d "1970-01-01 "MAX_CH" days" +%Y/%m\` 	`date -d "1970-01-01 "EXPIRE" days" +%Y/%m\`" "
     system(CMD);
     }
    }' $FILE 2>/dev/null |sort -k 3 | awk '{printf("%-15s%-15s%-15s
    ",$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" "	\`date -d "1970-01-01 "MAX_CH" days" +%Y/%m/%d\` 	`date -d "1970-01-01 "EXPIRE" days" +%Y/%m/%d\`" "
        system(CMD);
        }
      }' $FILE 2>/dev/null |sort -k 3 | awk '{printf("%-15s%-15s%-15s
    ",$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
  • 相关阅读:
    JAVA设计模式---总述篇
    Java中对象创建时的内存分配
    for循环打印空心菱形的新方法
    springcloud2.X通过actuator加载配置无效问题
    golang-错误处理
    golang-字符串
    golang-方法和接口
    golang-结构体与指针
    golang-数组、切片、映射
    golang-流程控制
  • 原文地址:https://www.cnblogs.com/linquan/p/5013625.html
Copyright © 2020-2023  润新知