summaryrefslogtreecommitdiff
path: root/localnotifypwexp
blob: 2ea686e914b4610f05544b36d1abd5ca2eca71c1 (plain)
  1. #!/bin/bash
  2. set -e
  3. # notifypwexp - send mail to users whose passwords are expiring soon
  4. # designed to be run daily or weekly from cron
  5. # call with -w for weekly mode (checks to see if warning period begins in the next 7 days
  6. # use -w for a weekly cron job, avoiding excessive emails
  7. # with no option, it only checks whether we're in the warning period now
  8. # use this for a daily cron job
  9. # by Dennis Williamson
  10. # Origin: http://serverfault.com/questions/11887
  11. # ### SETUP ###
  12. if [[ $1 == "-w" ]] # check for expiration warnings beginning during the next seven days
  13. then
  14. weekmode=7
  15. else
  16. weekmode=0
  17. fi
  18. admins="root postmaster"
  19. declare -r aged=21 # minimum days after expiration before admins are emailed, set to 0 for "always"
  20. hostname=$(hostname --fqdn)
  21. # /etc/shadow is system dependent
  22. shadowfile="/etc/shadow"
  23. # fields in /etc/shadow
  24. declare -r last=2
  25. #declare -r may=3 # not used in this script
  26. declare -r must=4
  27. declare -r warn=5
  28. #declare -r grace=6 # not used in this script
  29. declare -r disable=7
  30. declare -r doesntmust=99999
  31. declare -r warndefault=7
  32. passwdfile="/etc/passwd"
  33. declare -r uidfield=3
  34. declare -r unamefield=1
  35. # UID range is system dependent
  36. declare -r uidmin=1000
  37. declare -r uidmax=65534 # exclusive
  38. # remove the hardcoded path from these progs to use them via $PATH
  39. # mailx is system dependent
  40. notifyprog="/bin/mailx"
  41. grepprog="/bin/grep"
  42. awkprog="/usr/bin/awk"
  43. dateprog="/bin/date"
  44. # comment out one of these
  45. #useUTC=""
  46. useUTC="-u"
  47. # +%s is a GNUism - set it to blank and use dateformat if you have
  48. # a system that uses something else like epochdays, for example
  49. epochseconds="+%s"
  50. dateformat="" # blank for GNU when epochseconds="+%s"
  51. secondsperday=86400 # set this to 1 for no division
  52. today=$(($($dateprog $useUTC $epochseconds $dateformat)/$secondsperday))
  53. oIFS=$IFS
  54. # ### END SETUP ###
  55. # ### MAIL TEMPLATES ###
  56. # use single quotes around templates, backslash escapes and substitutions
  57. # will be evaluated upon output
  58. usersubjecttemplate='Your password is expiring soon'
  59. userbodytemplate='Your password on $hostname expires in $(($expdate - $today)) days.
  60. Please contact the IT department by email at \"helpdesk\" or at
  61. extension 555 if you have any questions. Help is also available at
  62. http://helpdesk.example.com/password'
  63. adminsubjecttemplate='User Password Expired: $user@$hostname'
  64. adminbodytemplate='The password for user $user on $hostname expired $age days ago.
  65. Please contact this user about their inactive account and consider whether
  66. the account should be disabled or deleted.'
  67. # ### END MAIL TEMPLATES ###
  68. # allow overrides (especially userbodytemplate)
  69. declare -r orgconfig=local-ORG/notifypwexp
  70. declare -r hostconfig=local/notifypwexp
  71. [ ! -r /etc/$orgconfig ] || . /etc/$orgconfig
  72. [ ! -r /etc/$hostconfig ] || . /etc/$hostconfig
  73. # get real users
  74. users=$($awkprog -F: -v uidfield=$uidfield \
  75. -v unamefield=$unamefield \
  76. -v uidmin=$uidmin \
  77. -v uidmax=$uidmax \
  78. -- '$uidfield>=uidmin && $uidfield<uidmax \
  79. {print $unamefield}' $passwdfile)
  80. for user in $users;
  81. do
  82. IFS=":"
  83. usershadow=$($grepprog ^$user $shadowfile)
  84. # make an array out of it
  85. usershadow=($usershadow)
  86. IFS=$oIFS
  87. mustchange=${usershadow[$must]}
  88. disabledate=${usershadow[$disable]:-$doesntmust}
  89. # skip users that aren't expiring or that are disabled
  90. if [[ $mustchange -ge $doesntmust || $disabledate -le $today ]] ; then continue; fi;
  91. lastchange=${usershadow[$last]}
  92. warndays=${usershadow[$warn]:-$warndefault}
  93. expdate=$(($lastchange + $mustchange))
  94. threshhold=$(($today + $warndays + $weekmode))
  95. if [[ $expdate -lt $threshhold ]];
  96. then
  97. if [[ $expdate -ge $today ]];
  98. then
  99. subject=$(eval "echo \"$usersubjecttemplate\"")
  100. body=$(eval "echo \"$userbodytemplate\"")
  101. echo -e "$body" | $notifyprog -s "$subject" $user
  102. else
  103. if [[ $age -ge $aged ]];
  104. then
  105. subject=$(eval "echo \"$adminsubjecttemplate\"")
  106. body=$(eval "echo \"$adminbodytemplate\"")
  107. echo -e "$body" | $notifyprog -s "$subject" $admins
  108. fi
  109. fi
  110. fi
  111. done