FreeIPA Report Users Disabled

General Information

Run this script periodically via cron in order to report on disabled user accounts and how long their password has been expired.

Checklist


The Script

cron_report-users-disabled.sh
#!/bin/bash
# Name: cron_report-users-disabled.sh
# Description: Report what users are disabled and how long a password is expired
# Last Updated: 2018-04-10
# Recent Changes:-Initial release
###############################################################################################
 
#====================================
##### Customize These Variables #####
#====================================
 
# admin credentials
admin_user="admin"
admin_pass='adminpwhere'
 
# email report to system admins
system_admins_email="systemadmins@yourdomain.org"
 
# Temp files for e-mail message
report_email="/root/ldap-scripts/tmp/report-users-disabled_email"
report_users_over_limit="/root/ldap-scripts/tmp/report-users-disabled_overlimit"
 
# Expired Since Days Limit
expired_since_limit=-90
 
#=====================================
##### End of Customize Variables #####
#=====================================
 
#==========================================
#### Functions Here: Main Starts After ####
#==========================================
 
# Create the initial report layout/header
function create_report_header() {
 
# Clear out email temp file contents
cat /dev/null > ${report_email}
cat /dev/null > ${report_users_over_limit}
 
# Setup report header
echo -e "---- FreeIPA Users Disabled Report ----" > ${report_email}
echo -e "\nAccounts that are currently disabled and when their password expired." >> ${report_email}
 
echo -e "\n-----------------------------------------------------------------" >> ${report_email}
echo -e "Disabled Accounts pw expired <= ${expired_since_limit} days ago" >> ${report_email}
echo -e "-----------------------------------------------------------------" >> ${report_email}
 
}
 
# Add disabled usernames and days since expiration to the report
function add_to_report() {
 
# Determine report type (top or bottom)
if [[ ${1} == "report_top" ]]; then
  report_type=${report_email}
elif [[ ${1} == "report_bottom" ]]; then
  report_type=${report_users_over_limit}
else
  echo -e ">> ERROR! No report type determined. Assuming top of report."
  report_type=${report_email}
fi
 
# Set variables passed to the function
username=${2}
expires_in_days=${3}
expires_on_epoch=${4}
 
# Determine the friendly looking expiration date
userpw_expiry_date_long=$(date --date="@${expires_on_epoch}")
 
# Create expired dialog for report
dialog_expires="${expires_in_days} days (${userpw_expiry_date_long})"
 
# Status message
echo "--Adding ${username} to password report."
 
## Add user account and expiration line to report file
if [[ $(echo ${username} | wc --max-line-length) -lt 8 ]]; then
  # If less than 8 character username, use two tabs
  echo -e "${username}\t\t${dialog_expires}" >> ${report_type}
else
  # If 8 or more characters, use one tab
  echo -e "${username}\t${dialog_expires}" >> ${report_type}
fi
 
}
 
# Add disabled usernames that have been expired > ${expired_since_limit}
function add_to_expired_over_list() {
 
# Set variables passed to the function
username=${1}
expires_in_days=${2}
expires_on_epoch=${3}
 
# Determine the friendly looking expiration date
userpw_expiry_date_long=$(date --date="@${expires_on_epoch}")
 
# Status message
echo "--Adding ${username} to expired over limit report."
 
# Create expired dialog for report
dialog_expires="${expires_in_days} days (${userpw_expiry_date_long})"
 
## Add user account and expiration line to report file
if [[ $(echo ${username} | wc --max-line-length) -lt 8 ]]; then
  # If less than 8 character username, use two tabs
  echo -e "${username}\t\t${dialog_expires}" >> ${report_users_over_limit}
else
  # If 8 or more characters, use one tab
  echo -e "${username}\t${dialog_expires}" >> ${report_users_over_limit}
fi
 
}
 
# Add usernames that have been disabled > limit to the end of the email report
function add_over_limit_list_to_report() {
 
# Setup disabled users > expiry limit header
echo -e "\n\n----------------------------------------------------------------" >> ${report_email}
echo -e "Disabled Accounts pw expired > ${expired_since_limit} days ago" >> ${report_email}
echo -e "----------------------------------------------------------------" >> ${report_email}
 
# Add Disabled Users expired > ${expired_since_limit} to end of report
if [[ -s ${report_users_over_limit} ]]; then
  # If file size is greater than 0, add content to report
  cat ${report_users_over_limit} >> ${report_email}
else
  # If file size is 0, give a status message
  echo "No user accounts expired > ${expired_since_limit} days ago." >> ${report_email}
fi
 
}
 
#=========================
#### End of Functions ####
#=========================
 
#=========================
#### Main Starts Here ####
#=========================
 
# Initialize a kerberos ticket as admin and wait a short time
echo ">> Initializing kerberos ticket, please wait..."
echo ${admin_pass} | /usr/bin/kinit ${admin_user}
sleep 3
 
# Build a list of disabled accounts
#- Find all users | grep logins and disabled status lines |
#- If the current line matches "True" (/True/), print the stored username (print username),
#- next, store the current line's field 3 in the variable username (username=$3)
user_list=$(/usr/bin/ipa user-find --sizelimit=0 --all | grep -E "(User login|Account disabled)" | awk '/True/ { print username }; { username=$3 }')
 
# Get today's epoch time (seconds since Jan 1st, 1970, midnight UTC)
todays_epoch=$(date +%s)
 
# Create the report header
create_report_header
 
#### Main Loop ####
for user in ${user_list}; do
 
  echo "Checking expiry for ${user}..."
 
  # Get user's password expiration and cut off the zulu time designator trailing at the end('Z')
  userpw_expiry_datetime=$(/usr/bin/ipa user-show ${user} --all | grep krbpasswordexpiration | awk '{print $2}' | cut -c 1-14)
 
  # If the user account does not have a password expiration value, skip the user
  if [[ -z ${userpw_expiry_datetime} ]]; then
    # Skip to next user in user_list
    continue
  fi
 
  # Split up the year,month,day,hour,min, and sec from the datetime string
  userpw_expiry_date_year="$(echo ${userpw_expiry_datetime} | cut -c 1-4)"
  userpw_expiry_date_month="$(echo ${userpw_expiry_datetime} | cut -c 5-6)"
  userpw_expiry_date_day="$(echo ${userpw_expiry_datetime} | cut -c 7-8)"
  userpw_expiry_time_hour="$(echo ${userpw_expiry_datetime} | cut -c 9-10)"
  userpw_expiry_time_min="$(echo ${userpw_expiry_datetime} | cut -c 11-12)"
  userpw_expiry_time_sec="$(echo ${userpw_expiry_datetime} | cut -c 13-14)"
 
  # Caculate the user's expiry date in epoch time
  userpw_expiry_epoch=$(date --utc --date="${userpw_expiry_date_year}-${userpw_expiry_date_month}-${userpw_expiry_date_day} ${userpw_expiry_time_hour}:${userpw_expiry_time_min}:${userpw_expiry_time_sec}" +%s)
 
  # Calculate how many seconds and days until password expiration
  password_expires_seconds=$(expr ${userpw_expiry_epoch} - ${todays_epoch})
  password_expires_days=$(expr ${password_expires_seconds} / 86400)
 
 
  # if password has been expired for >= expired_since_limit, add to special list
  if [[ ${password_expires_days} -le ${expired_since_limit} ]]; then
    echo "-> User account has been expired for >= ${expired_since_limit} days: ${user} (${password_expires_days})"
    #add_to_expired_over_list ${user} ${password_expires_days} ${userpw_expiry_epoch}
    add_to_report "report_bottom" ${user} ${password_expires_days} ${userpw_expiry_epoch}
  else
    # Otherwise, add the expired user to the main section of the report
    echo "-> User account has been expired for < ${expired_since_limit} days: ${user} (${password_expires_days})"
    #add_to_report ${user} ${password_expires_days} ${userpw_expiry_epoch}
    add_to_report "report_top" ${user} ${password_expires_days} ${userpw_expiry_epoch}
  fi
 
done
#### End Main Loop ####
 
# Add disabled users that expired longer ago to the end of email report
add_over_limit_list_to_report
 
# Status message
echo ">>Emailing report to ${system_admins_email}..."
 
# Use the date-time from the beginning of the script
todays_date_long=$(date --date="@${todays_epoch}")
 
# Email Report
/usr/bin/mail -s "FreeIPA Users Disabled Report - ${todays_date_long}" ${system_admins_email} < ${report_email}
 
# Clear out email temp file contents
cat /dev/null > ${report_email}
cat /dev/null > ${report_users_over_limit}