{"id":513821,"date":"2025-08-25T11:56:18","date_gmt":"2025-08-25T11:56:18","guid":{"rendered":"https:\/\/www.ninjaone.com\/?post_type=script_hub&#038;p=513821"},"modified":"2025-08-25T11:56:18","modified_gmt":"2025-08-25T11:56:18","slug":"definir-la-politique-de-mot-de-passe-linux-avec-un-script-shell","status":"publish","type":"script_hub","link":"https:\/\/www.ninjaone.com\/fr\/script-hub\/definir-la-politique-de-mot-de-passe-linux-avec-un-script-shell\/","title":{"rendered":"Comment d\u00e9finir la politique de mot de passe Linux avec un script Shell"},"content":{"rendered":"<p>Les politiques en mati\u00e8re de mots de passe sont un \u00e9l\u00e9ment fondamental de la s\u00e9curit\u00e9 des syst\u00e8mes, en particulier sur les appareils Linux g\u00e9r\u00e9s par les entreprises. Pour les <a href=\"https:\/\/www.ninjaone.com\/fr\/quest-ce-quun-msp\/\">fournisseurs de services g\u00e9r\u00e9s (MSP)<\/a> et les professionnels de l&rsquo;informatique qui supervisent des flottes de terminaux <a href=\"https:\/\/www.ninjaone.com\/blog\/linux-filesystems\/\">Linux<\/a>, l&rsquo;application de politiques de mots de passe coh\u00e9rentes est essentielle pour r\u00e9duire les surfaces d&rsquo;attaque et garantir la conformit\u00e9 aux r\u00e9glementations. Ce billet explore un script shell complet qui configure les contr\u00f4les de mots de passe critiques dans diverses distributions Linux en utilisant authconfig, authselect, ou des modifications PAM manuelles. La possibilit\u00e9 de\u00a0<strong>d\u00e9finir la politique de mot de passe pour les appareils Linux \u00e0 l&rsquo;aide de scripts shell<\/strong>\u00a0ajoute de l&rsquo;<a href=\"https:\/\/www.ninjaone.com\/fr\/blog\/tout-ce-que-vous-devez-savoir-sur-lautomatisation\/\">automatisation<\/a> et de la fiabilit\u00e9 \u00e0 votre strat\u00e9gie de gestion des terminaux.<\/p>\n<h2>Contexte<\/h2>\n<p>De nombreux environnements Linux, en particulier ceux des infrastructures g\u00e9r\u00e9es par des entreprises ou des MSP, reposent sur des syst\u00e8mes d\u00e9centralis\u00e9s, ce qui rend difficile l&rsquo;application d&rsquo;exigences uniformes en mati\u00e8re de mots de passe. La configuration manuelle est sujette aux erreurs et inefficace \u00e0 grande \u00e9chelle. Si des outils comme Ansible et Puppet peuvent \u00eatre utiles, ils peuvent s&rsquo;av\u00e9rer inutiles pour les \u00e9quipes qui utilisent des plateformes <a href=\"https:\/\/www.ninjaone.com\/fr\/blog\/definition-de-la-surveillance-et-gestion-a-distance\/\">RMM<\/a> comme NinjaOne.<\/p>\n<p>Ce script shell comble le foss\u00e9 : il cible les syst\u00e8mes Debian 11+ et RHEL 8+ et applique dynamiquement les politiques de mot de passe en fonction de la disponibilit\u00e9 des fichiers de configuration authconfig, authselect ou PAM direct. Les professionnels de l&rsquo;informatique peuvent\u00a0<strong>utiliser des scripts shell pour d\u00e9finir la politique de mot de passe pour les appareils Linux<\/strong>, garantissant ainsi une meilleure hygi\u00e8ne de s\u00e9curit\u00e9 sans n\u00e9cessiter une organisation complexe.<\/p>\n<h2>Le script<\/h2>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">#!\/usr\/bin\/env bash\r\n#\r\n# Description: Sets the password policy for linux devices.\r\n# By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https:\/\/www.ninjaone.com\/terms-of-use.\r\n# Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. \r\n# Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. \r\n# Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. \r\n# Warranty Disclaimer: The script is provided \u201cas is\u201d and \u201cas available\u201d, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. \r\n# Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. \r\n# Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. \r\n# EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).\r\n#\r\n# Preset Parameter: --maxLoginAttempts \"replaceMeWithANumber\"\r\n#\t\tDefine how many incorrect password attempts are allowed before the device locks.\r\n#\r\n# Preset Parameter: --loginAttemptLockTime \"replaceMeWithANumber\"\r\n#\t\tSet the lock duration (in minutes) after the maximum login attempts is reached. Max Login Attempts is required (if not previously set).\r\n#\r\n# Preset Parameter: --daysUntilPasswordExpiration \"replaceMeWithANumber\"\r\n#\t\tSpecify how many days before a password expires.\r\n#\r\n# Preset Parameter: --minimumPasswordLength \"replaceMeWithANumber\"\r\n#\t\tDefine the minimum number of characters required for a password.\r\n#\r\n# Preset Parameter: --passwordHistory \"replaceMeWithANumber\"\r\n#\t\tDefine how many previous passwords must be remembered before reuse.\r\n#   This option is only available on Debian-based or RHEL 8+-based distributions.\r\n#   https:\/\/bugzilla.redhat.com\/show_bug.cgi?id=1271804\r\n#\r\n# Preset Parameter: --help\r\n#\t\tDisplays some help text.\r\n#\r\n# Minimum OS Architecture Supported: Debian 11 (Bullseye)+, Red Hat Enterprise Linux (RHEL) 8+\r\n#\r\n# Release Notes: Initial Release\r\n\r\n# Initialize variables for various password policy parameters with default values\r\n_arg_maxLoginAttempts=\r\n_arg_loginAttemptLockTime=\r\n_arg_daysUntilPasswordExpiration=\r\n_arg_minimumPasswordLength=\r\n_arg_passwordHistory=\r\n\r\nprint_help() {\r\n  printf '\\n\\n%s\\n\\n' 'Usage: [--maxLoginAttempts|-a &lt;arg&gt;] [--loginAttemptLockTime|-t &lt;arg&gt;] [--daysUntilPasswordExpiration|-e &lt;arg&gt;] \r\n  [--minimumPasswordLength|-l &lt;arg&gt;] [--passwordHistory|-ph &lt;arg&gt;] [--help|-h]'\r\n  printf '%s\\n' 'Preset Parameter: --maxLoginAttempts \"replaceMeWithANumber\"'\r\n  printf '\\t%s\\n' \"Define how many incorrect password attempts are allowed before the device locks.\"\r\n  printf '%s\\n' 'Preset Parameter: --loginAttemptLockTime \"replaceMeWithANumber\"'\r\n  printf '\\t%s\\n' \"Set the lock duration (in minutes) after the maximum login attempts is reached. Max Login Attempts is required (if not previously set).\"\r\n  printf '%s\\n' 'Preset Parameter: --daysUntilPasswordExpiration \"replaceMeWithANumber\"'\r\n  printf '\\t%s\\n' \"Specify how many days before a password expires.\"\r\n  printf '%s\\n' 'Preset Parameter: --minimumPasswordLength \"replaceMeWithANumber\"'\r\n  printf '\\t%s\\n' \"Define the minimum number of characters required for a password.\"\r\n  printf '%s\\n' 'Preset Parameter: --passwordHistory \"replaceMeWithANumber\"'\r\n  printf '\\t%s\\n' \"Define how many previous passwords must be remembered before reuse.\"\r\n  printf '\\t%s\\n' \"This option is only available on Debian-based or RHEL 8+-based distributions.\"\r\n  printf '\\t%s\\n' \"https:\/\/bugzilla.redhat.com\/show_bug.cgi?id=1271804\"\r\n  printf '%s\\n' 'Preset Parameter: --help'\r\n  printf '\\t%s\\n' \"Displays this help menu.\"\r\n}\r\n\r\ndie() {\r\n  local _ret=\"${2:-1}\"\r\n  echo \"$1\" &gt;&amp;2\r\n  test \"${_PRINT_HELP:-no}\" = yes &amp;&amp; print_help &gt;&amp;2\r\n  exit \"${_ret}\"\r\n}\r\n\r\nparse_commandline() {\r\n  while test $# -gt 0; do\r\n    _key=\"$1\"\r\n    case \"$_key\" in\r\n    --maxLoginAttempts | --maxloginattempts | --attempts | -a)\r\n      test $# -lt 2 &amp;&amp; die \"[Error] Missing value for the optional argument '$_key'.\" 1\r\n      _arg_maxLoginAttempts=$2\r\n      shift\r\n      ;;\r\n    --maxLoginAttempts=*)\r\n      _arg_maxLoginAttempts=\"${_key##--maxLoginAttempts=}\"\r\n      ;;\r\n    --loginAttemptLockTime | --loginattemptlocktime | --locktime | -t)\r\n      test $# -lt 2 &amp;&amp; die \"[Error] Missing value for the optional argument '$_key'.\" 1\r\n      _arg_loginAttemptLockTime=$2\r\n      shift\r\n      ;;\r\n    --loginAttemptLockTime=*)\r\n      _arg_loginAttemptLockTime=\"${_key##--loginAttemptLockTime=}\"\r\n      ;;\r\n    --daysUntilPasswordExpiration | --daysuntilpasswordexpiration | --expiration | -e)\r\n      test $# -lt 2 &amp;&amp; die \"[Error] Missing value for the optional argument '$_key'.\" 1\r\n      _arg_daysUntilPasswordExpiration=$2\r\n      shift\r\n      ;;\r\n    --daysUntilPasswordExpiration=*)\r\n      _arg_daysUntilPasswordExpiration=\"${_key##--daysUntilPasswordExpiration=}\"\r\n      ;;\r\n    --minimumPasswordLength | --minimumpasswordlength | --length | -l)\r\n      test $# -lt 2 &amp;&amp; die \"[Error] Missing value for the optional argument '$_key'.\" 1\r\n      _arg_minimumPasswordLength=$2\r\n      shift\r\n      ;;\r\n    --minimumPasswordLength=*)\r\n      _arg_minimumPasswordLength=\"${_key##--minimumPasswordLength=}\"\r\n      ;;\r\n    --passwordHistory | --passwordhistory | --history | -ph)\r\n      test $# -lt 2 &amp;&amp; die \"[Error] Missing value for the optional argument '$_key'.\" 1\r\n      _arg_passwordHistory=$2\r\n      shift\r\n      ;;\r\n    --passwordHistory=*)\r\n      _arg_passwordHistory=\"${_key##--passwordHistory=}\"\r\n      ;;\r\n    --help | -h)\r\n      _PRINT_HELP=yes die\r\n      ;;\r\n    *)\r\n      _PRINT_HELP=yes die \"[Error] Got an unexpected argument '$1'\" 1\r\n      ;;\r\n    esac\r\n    shift\r\n  done\r\n}\r\n\r\necho \"\"\r\nparse_commandline \"$@\"\r\n\r\n# If environment variables for the script parameters are set, override the command line argument values\r\nif [[ -n \"$maxLoginAttempts\" ]]; then\r\n  _arg_maxLoginAttempts=\"$maxLoginAttempts\"\r\nfi\r\nif [[ -n \"$loginAttemptLockTime\" ]]; then\r\n  _arg_loginAttemptLockTime=\"$loginAttemptLockTime\"\r\nfi\r\nif [[ -n \"$daysUntilPasswordExpiration\" ]]; then\r\n  _arg_daysUntilPasswordExpiration=\"$daysUntilPasswordExpiration\"\r\nfi\r\nif [[ -n \"$minimumPasswordLength\" ]]; then\r\n  _arg_minimumPasswordLength=\"$minimumPasswordLength\"\r\nfi\r\nif [[ -n \"$passwordHistory\" ]]; then\r\n  _arg_passwordHistory=\"$passwordHistory\"\r\nfi\r\n\r\n# Check if the script is being run as root. If not, exit with an error message.\r\nif [[ $(id -u) -ne 0 ]]; then\r\n  _PRINT_HELP=no die \"[Error] This script must be run with root permissions. Try running it with sudo or as the system\/root user.\" 1\r\nfi\r\n\r\n# Validate max login attempts. Ensure it is a positive integer greater than zero.\r\nif [[ -n \"$_arg_maxLoginAttempts\" ]]; then\r\n  _arg_maxLoginAttempts=$(echo \"$_arg_maxLoginAttempts\" | xargs)\r\n\r\n  if [[ -z \"$_arg_maxLoginAttempts\" ]]; then\r\n    _PRINT_HELP=yes die \"[Error] An invalid number of max login attempts was given. Please specify a positive whole number that is greater than 0.\" 1\r\n  fi\r\nfi\r\nif [[ \"$_arg_maxLoginAttempts\" =~ [^0-9] ]]; then\r\n  _PRINT_HELP=yes die \"[Error] An invalid value for max login attempts was given: '$_arg_maxLoginAttempts'. Please specify a positive whole number that is greater than 0.\" 1\r\nfi\r\nif [[ \"$_arg_maxLoginAttempts\" == 0 ]]; then\r\n  _PRINT_HELP=yes die \"[Error] An invalid value for max login attempts was given: '$_arg_maxLoginAttempts'. Please specify a positive whole number that is greater than 0.\" 1\r\nfi\r\n\r\n# Validate login attempt lock time. Ensure it is a positive integer greater than zero.\r\nif [[ -n \"$_arg_loginAttemptLockTime\" ]]; then\r\n  _arg_loginAttemptLockTime=$(echo \"$_arg_loginAttemptLockTime\" | xargs)\r\n\r\n  if [[ -z \"$_arg_loginAttemptLockTime\" ]]; then\r\n    _PRINT_HELP=yes die \"[Error] An invalid lock time was given. Please specify a positive whole number that is greater than 0.\" 1\r\n  fi\r\nfi\r\nif [[ \"$_arg_loginAttemptLockTime\" =~ [^0-9] ]]; then\r\n  _PRINT_HELP=yes die \"[Error] An invalid value for lock time was given: '$_arg_loginAttemptLockTime'. Please specify a positive whole number that is greater than 0.\" 1\r\nfi\r\nif [[ \"$_arg_loginAttemptLockTime\" == 0 ]]; then\r\n  _PRINT_HELP=yes die \"[Error] An invalid value for lock time was given: '$_arg_loginAttemptLockTime'. Please specify a positive whole number that is greater than 0.\" 1\r\nfi\r\n\r\n# Validate password expiration time. Ensure it is a positive whole number or 99999 for no expiration.\r\nif [[ -n \"$_arg_daysUntilPasswordExpiration\" ]]; then\r\n  _arg_daysUntilPasswordExpiration=$(echo \"$_arg_daysUntilPasswordExpiration\" | xargs)\r\n\r\n  if [[ -z \"$_arg_daysUntilPasswordExpiration\" ]]; then\r\n    _PRINT_HELP=yes die \"[Error] An invalid expiration time was given. Please specify a positive whole number or '99999' for no expiration.\" 1\r\n  fi\r\n\r\n  if [[ \"$_arg_daysUntilPasswordExpiration\" =~ [^0-9] ]]; then\r\n    _PRINT_HELP=yes die \"[Error] An invalid value for password expiration was given: '$_arg_daysUntilPasswordExpiration'. Please specify a positive whole number that is greater than 0 and less than or equal to 99999.\" 1\r\n  fi\r\n\r\n  if [[ \"$_arg_daysUntilPasswordExpiration\" == 0 || \"$_arg_daysUntilPasswordExpiration\" -gt 99999 ]]; then\r\n    _PRINT_HELP=yes die \"[Error] An invalid value for password expiration was given: '$_arg_daysUntilPasswordExpiration'. Please specify a positive whole number that is greater than 0 and less than or equal to 99999.\" 1\r\n  fi\r\nfi\r\n\r\n# Validate minimum password length. Ensure it is a positive whole number greater than or equal to 8.\r\nif [[ -n \"$_arg_minimumPasswordLength\" ]]; then\r\n  _arg_minimumPasswordLength=$(echo \"$_arg_minimumPasswordLength\" | xargs)\r\n\r\n  if [[ -z \"$_arg_minimumPasswordLength\" ]]; then\r\n    _PRINT_HELP=yes die \"[Error] An invalid minimum password length was given. Please specify a positive whole number that is greater than or equal to '8'.\" 1\r\n  fi\r\nfi\r\nif [[ \"$_arg_minimumPasswordLength\" =~ [^0-9] ]]; then\r\n  _PRINT_HELP=yes die \"[Error] An invalid value for minimum password length was given: '$_arg_minimumPasswordLength'. Please specify a positive whole number that is greater than or equal to 8.\" 1\r\nfi\r\nif [[ -n \"$_arg_minimumPasswordLength\" &amp;&amp; \"$_arg_minimumPasswordLength\" -lt 8 ]]; then\r\n  _PRINT_HELP=yes die \"[Error] An invalid value for minimum password length was given: '$_arg_minimumPasswordLength'. Please specify a positive whole number that is greater than or equal to 8.\" 1\r\nfi\r\n\r\n# Validate password history setting. Ensure it is a positive whole number greater than zero.\r\nif [[ -n \"$_arg_passwordHistory\" ]]; then\r\n  _arg_passwordHistory=$(echo \"$_arg_passwordHistory\" | xargs)\r\n\r\n  if [[ -z \"$_arg_passwordHistory\" ]]; then\r\n    _PRINT_HELP=yes die \"[Error] An invalid number of passwords to remember was given. Please specify a positive whole number that is greater than 0.\" 1\r\n  fi\r\nfi\r\nif [[ \"$_arg_passwordHistory\" =~ [^0-9] ]]; then\r\n  _PRINT_HELP=yes die \"[Error] An invalid value for the number of passwords to remember was given: '$_arg_passwordHistory'. Please specify a positive whole number that is greater than 0.\" 1\r\nfi\r\nif [[ \"$_arg_passwordHistory\" == 0 ]]; then\r\n  _PRINT_HELP=yes die \"[Error] An invalid value for the number of passwords to remember was given: '$_arg_passwordHistory'. Please specify a positive whole number that is greater than 0.\" 1\r\nfi\r\n\r\ntoday=$(date \"+%s\")\r\n\r\n# Ensure that at least one password policy is being set. If none are provided and the reset flag is off, throw an error.\r\nif [[ -z \"$_arg_maxLoginAttempts\" &amp;&amp; -z \"$_arg_loginAttemptLockTime\" &amp;&amp; -z \"$_arg_daysUntilPasswordExpiration\" &amp;&amp; -z \"$_arg_minimumPasswordLength\" &amp;&amp; -z \"$_arg_passwordHistory\" ]]; then\r\n  _PRINT_HELP=yes die \"[Error] You must specify the password policy you are trying to set.\" 1\r\nfi\r\n\r\n# Check if authselect and authconfig commands are available\r\nauthselectAvailable=$(command -v authselect)\r\nauthconfigAvailable=$(command -v authconfig)\r\n\r\n# Proceed only if authconfig is available but authselect is not\r\nif [[ -n \"$authconfigAvailable\" &amp;&amp; -z \"$authselectAvailable\" ]]; then\r\n  echo \"Detected the command authconfig. Setting the password policy using authconfig.\"\r\n\r\n  # If maximum login attempts or login attempt lock time arguments are provided\r\n  if [[ -n \"$_arg_maxLoginAttempts\" || -n \"$_arg_loginAttemptLockTime\" ]]; then\r\n    echo \"\"\r\n    echo \"Checking the current status of the login attempt lock and lock time.\"\r\n\r\n    # Check current status of faillock settings\r\n    failLockStatus=$(authconfig --test | grep \"pam_faillock\" | grep -v \"disabled\")\r\n\r\n    # Extract current maximum login attempts and lock time values\r\n    currentAttempts=$(authconfig --test | grep \"pam_faillock\" | grep -o -e \"deny[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\" | xargs)\r\n    currentLockTime=$(authconfig --test | grep \"pam_faillock\" | grep -o -e \"unlock_time[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\" | xargs)\r\n\r\n    # Convert lock time from seconds to minutes if available\r\n    if [[ -n \"$currentLockTime\" ]]; then\r\n      currentLockTimeMinutes=$((currentLockTime \/ 60))\r\n    fi\r\n\r\n    # If login attempt lock time is provided, convert to seconds\r\n    if [[ -n \"$_arg_loginAttemptLockTime\" ]]; then\r\n      loginAttemptLockTimeMinutes=\"$_arg_loginAttemptLockTime\"\r\n      _arg_loginAttemptLockTime=$((_arg_loginAttemptLockTime * 60))\r\n    fi\r\n\r\n    echo \"Successfully retrieved the current lock status and lock time.\"\r\n\r\n    # If faillock module is not enabled, enable it\r\n    if [[ -z \"$failLockStatus\" ]]; then\r\n      echo \"Enabling faillock PAM module.\"\r\n      if ! authconfig --enablefaillock --update; then\r\n        _PRINT_HELP=no die \"[Error] Failed to enable faillock. This is required to set the max login attempts allowed as well as the lock time.\" 1\r\n      fi\r\n\r\n      # Verify that faillock has been enabled successfully\r\n      failLockStatus=$(authconfig --test | grep \"pam_faillock\" | grep -v \"disabled\")\r\n      if [[ -z \"$failLockStatus\" ]]; then\r\n        _PRINT_HELP=no die \"[Error] Failed to enable faillock. This is required to set the max login attempts allowed as well as the lock time.\" 1\r\n      fi\r\n    fi\r\n\r\n    # Check if max login attempts value is already set correctly\r\n    if [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -n \"$currentAttempts\" &amp;&amp; \"$_arg_maxLoginAttempts\" == \"$currentAttempts\" ]]; then\r\n      echo \"The maximum login attempts is already set to '$_arg_maxLoginAttempts'. Skipping.\"\r\n      _arg_maxLoginAttempts=\r\n    fi\r\n\r\n    # Check if lock time value is already set correctly\r\n    if [[ -n \"$_arg_loginAttemptLockTime\" &amp;&amp; -n \"$currentLockTime\" &amp;&amp; \"$_arg_loginAttemptLockTime\" == \"$currentLockTime\" ]]; then\r\n      echo \"The lock time is already set to '$loginAttemptLockTimeMinutes' minutes. Skipping.\"\r\n      _arg_loginAttemptLockTime=\r\n    fi\r\n  fi\r\n\r\n  # Exit with error if only max login attempts or lock time is provided without the other\r\n  if [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -z \"$_arg_loginAttemptLockTime\" &amp;&amp; -z \"$currentLockTime\" ]]; then\r\n    _PRINT_HELP=yes die \"[Error] When specifying the maximum number of login attempts, you must also specify the login attempt lock time.\" 1\r\n  fi\r\n\r\n  if [[ -n \"$_arg_loginAttemptLockTime\" &amp;&amp; -z \"$_arg_maxLoginAttempts\" &amp;&amp; -z \"$currentAttempts\" ]]; then\r\n    _PRINT_HELP=yes die \"[Error] When specifying a login attempt lock time you must also specify the maximum login attempts.\" 1\r\n  fi\r\n\r\n  # If both maximum login attempts and lock time arguments are provided, update authconfig policy\r\n  if [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -n \"$_arg_loginAttemptLockTime\" ]]; then\r\n    echo \"Setting the maximum login attempts and lock time in the authconfig policy.\"\r\n\r\n    # Update authconfig with max login attempts and lock time\r\n    if ! authconfig --faillockargs=\"deny=$_arg_maxLoginAttempts unlock_time=$_arg_loginAttemptLockTime\" --update; then\r\n      _PRINT_HELP=no die \"[Error] Failed to set the maximum login attempts and lock time in the authconfig policy.\" 1\r\n    fi\r\n\r\n    # Verify the updated values\r\n    newAttempts=$(authconfig --test | grep \"pam_faillock\" | grep -o -e \"deny[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\" | xargs)\r\n    newLockTime=$(authconfig --test | grep \"pam_faillock\" | grep -o -e \"unlock_time[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\" | xargs)\r\n\r\n    if [[ -n \"$newAttempts\" &amp;&amp; \"$newAttempts\" == \"$_arg_maxLoginAttempts\" ]]; then\r\n      echo \"Successfully added the max login attempts to the authconfig policy.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to add the max login attempts to the authconfig policy.\" 1\r\n    fi\r\n\r\n    if [[ -n \"$newLockTime\" &amp;&amp; \"$newLockTime\" == \"$_arg_loginAttemptLockTime\" ]]; then\r\n      echo \"Successfully set the lock time in the authconfig policy.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to set the lock time in the authconfig policy.\" 1\r\n    fi\r\n  fi\r\n\r\n  # Update only maximum login attempts if lock time is not provided\r\n  if [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -z \"$_arg_loginAttemptLockTime\" ]]; then\r\n    echo \"Modifying the maximum login attempts from '$currentAttempts' to '$_arg_maxLoginAttempts' in the authconfig policy.\"\r\n\r\n    # Update max login attempts in authconfig\r\n    if ! authconfig --faillockargs=\"deny=$_arg_maxLoginAttempts unlock_time=$currentLockTime\" --update; then\r\n      _PRINT_HELP=no die \"[Error] Failed to modify the max login attempts in the authconfig policy.\" 1\r\n    fi\r\n\r\n    # Verify the new maximum login attempts value\r\n    newAttempts=$(authconfig --test | grep \"pam_faillock\" | grep -o -e \"deny[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\" | xargs)\r\n\r\n    if [[ -n \"$newAttempts\" &amp;&amp; \"$newAttempts\" == \"$_arg_maxLoginAttempts\" ]]; then\r\n      echo \"Successfully modified the max login attempts in the authconfig policy.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to modify the max login attempts in the authconfig policy.\" 1\r\n    fi\r\n  fi\r\n\r\n  # Update only lock time if max login attempts is not provided\r\n  if [[ -n \"$_arg_loginAttemptLockTime\" &amp;&amp; -z \"$_arg_maxLoginAttempts\" ]]; then\r\n    echo \"Modifying the current lock time from '$currentLockTimeMinutes' minutes to '$loginAttemptLockTimeMinutes' minutes in the authconfig policy.\"\r\n\r\n    # Update lock time in authconfig\r\n    if ! authconfig --faillockargs=\"deny=$currentAttempts unlock_time=$_arg_loginAttemptLockTime\" --update; then\r\n      _PRINT_HELP=no die \"[Error] Failed to modify the lock time in the authconfig policy.\" 1\r\n    fi\r\n\r\n    # Verify the new lock time value\r\n    newLockTime=$(authconfig --test | grep \"pam_faillock\" | grep -o -e \"unlock_time[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\" | xargs)\r\n\r\n    if [[ -n \"$newLockTime\" &amp;&amp; \"$newLockTime\" == \"$_arg_loginAttemptLockTime\" ]]; then\r\n      echo \"Successfully modified the lock time of the authconfig policy.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to set the lock time in the authconfig policy.\" 1\r\n    fi\r\n  fi\r\n\r\n  # If minimum password length is specified, retrieve and update the policy\r\n  if [[ -n \"$_arg_minimumPasswordLength\" ]]; then\r\n    echo \"\"\r\n    echo \"Retrieving the current password quality policy.\"\r\n\r\n    # Check if the password quality configuration file exists\r\n    if [[ ! -f \"\/etc\/security\/pwquality.conf\" ]]; then\r\n      _PRINT_HELP=no die \"[Error] The file '\/etc\/security\/pwquality.conf' does not exist. Unable to read the current password quality policy.\" 1\r\n    fi\r\n\r\n    # Get the current minimum password length value\r\n    currentMinimumLength=$(grep -v \"^#\" \/etc\/security\/pwquality.conf | grep -v '^\\s*$' | grep -o -e \"minlen[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\" | xargs)\r\n    echo \"Successfully retrieved the current password quality policy.\"\r\n\r\n    # If the minimum password length is already set correctly, skip the update\r\n    if [[ -n \"$currentMinimumLength\" &amp;&amp; \"$currentMinimumLength\" == \"$_arg_minimumPasswordLength\" ]]; then\r\n      echo \"The minimum password length is already '$_arg_minimumPasswordLength'. Skipping.\"\r\n      _arg_minimumPasswordLength=\r\n    fi\r\n  fi\r\n\r\n  # Set or update the minimum password length in the policy\r\n  if [[ -n \"$_arg_minimumPasswordLength\" ]]; then\r\n    if [[ -n \"$currentMinimumLength\" ]]; then\r\n      echo \"Updating the minimum password length from '$currentMinimumLength' to '$_arg_minimumPasswordLength'.\"\r\n    else\r\n      echo \"Setting the minimum password length to '$_arg_minimumPasswordLength'.\"\r\n    fi\r\n\r\n    # Update the password quality policy with the new minimum length\r\n    if ! authconfig --passminlen=\"$_arg_minimumPasswordLength\" --update; then\r\n      _PRINT_HELP=no die \"[Error] Failed to modify the password length in the authconfig policy.\" 1\r\n    fi\r\n\r\n    # Verify the updated minimum password length value\r\n    newMinimumLength=$(grep -v \"^#\" \/etc\/security\/pwquality.conf | grep -v '^\\s*$' | grep -o -e \"minlen[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\" | xargs)\r\n    if [[ -n \"$newMinimumLength\" &amp;&amp; \"$newMinimumLength\" == \"$_arg_minimumPasswordLength\" ]]; then\r\n      echo \"Successfully set the minimum password length.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to modify the minimum password length in '\/etc\/security\/pwquality.conf'.\" 1\r\n    fi\r\n  fi\r\nfi\r\n\r\n# Check if authselect is available\r\nif [[ -n \"$authselectAvailable\" ]]; then\r\n  echo \"The command authselect was detected. Setting the password policy using authselect.\"\r\n\r\n  # Check if max login attempts or lock time arguments are provided\r\n  if [[ -n \"$_arg_maxLoginAttempts\" || -n \"$_arg_loginAttemptLockTime\" ]]; then\r\n    echo \"\"\r\n    echo \"Checking the current status of the login attempt lock and lock time.\"\r\n\r\n    # Check if the faillock module is enabled in authselect\r\n    failLockStatus=$(authselect current | grep \"with-faillock\")\r\n\r\n    # Exit if faillock.conf file does not exist\r\n    if [[ ! -f \"\/etc\/security\/faillock.conf\" ]]; then\r\n      _PRINT_HELP=no die \"[Error] The file '\/etc\/security\/faillock.conf' does not exist. Unable to read the current faillock policy.\" 1\r\n    fi\r\n\r\n    # Retrieve current maximum login attempts and lock time from faillock.conf\r\n    currentAttempts=$(grep -v \"^#\" \/etc\/security\/faillock.conf | grep -v '^\\s*$' | grep -o -e \"deny[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n    currentLockTime=$(grep -v \"^#\" \/etc\/security\/faillock.conf | grep -v '^\\s*$' | grep -o -e \"unlock_time[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n\r\n    # Convert lock time to minutes if it exists\r\n    if [[ -n \"$currentLockTime\" ]]; then\r\n      currentLockTimeMinutes=$((currentLockTime \/ 60))\r\n    fi\r\n\r\n    # Convert provided lock time to seconds for internal use\r\n    if [[ -n \"$_arg_loginAttemptLockTime\" ]]; then\r\n      loginAttemptLockTimeMinutes=\"$_arg_loginAttemptLockTime\"\r\n      _arg_loginAttemptLockTime=$((_arg_loginAttemptLockTime * 60))\r\n    fi\r\n\r\n    echo \"Successfully retrieved the current lock status and lock time.\"\r\n\r\n    # Enable faillock if not currently enabled\r\n    if [[ -z \"$failLockStatus\" ]]; then\r\n      echo \"Enabling faillock PAM module.\"\r\n      if ! authselect enable-feature with-faillock; then\r\n        _PRINT_HELP=no die \"[Error] Failed to enable faillock. This is required to set the max login attempts allowed as well as the lock time.\" 1\r\n      fi\r\n\r\n      if ! authselect apply-changes; then\r\n        _PRINT_HELP=no die \"[Error] Failed to enable faillock. This is required to set the max login attempts allowed as well as the lock time.\" 1\r\n      fi\r\n\r\n      # Confirm if faillock has been enabled successfully\r\n      failLockStatus=$(authselect current | grep \"with-faillock\")\r\n      if [[ -z \"$failLockStatus\" ]]; then\r\n        _PRINT_HELP=no die \"[Error] Failed to enable faillock. This is required to set the max login attempts allowed as well as the lock time.\" 1\r\n      fi\r\n    fi\r\n\r\n    # Skip updating if max login attempts or lock time are already set to the desired values\r\n    if [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -n \"$currentAttempts\" &amp;&amp; \"$_arg_maxLoginAttempts\" == \"$currentAttempts\" ]]; then\r\n      echo \"The maximum login attempts is already set to '$_arg_maxLoginAttempts'. Skipping.\"\r\n      _arg_maxLoginAttempts=\r\n    fi\r\n\r\n    if [[ -n \"$_arg_loginAttemptLockTime\" &amp;&amp; -n \"$currentLockTime\" &amp;&amp; \"$_arg_loginAttemptLockTime\" == \"$currentLockTime\" ]]; then\r\n      echo \"The lock time is already set to '$loginAttemptLockTimeMinutes' minutes. Skipping.\"\r\n      _arg_loginAttemptLockTime=\r\n    fi\r\n  fi\r\n\r\n  # Exit with error if only max login attempts or lock time is provided without the other\r\n  if [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -z \"$_arg_loginAttemptLockTime\" &amp;&amp; -z \"$currentLockTime\" ]]; then\r\n    _PRINT_HELP=yes die \"[Error] When specifying the maximum number of login attempts, you must also specify the login attempt lock time.\" 1\r\n  fi\r\n\r\n  if [[ -n \"$_arg_loginAttemptLockTime\" &amp;&amp; -z \"$_arg_maxLoginAttempts\" &amp;&amp; -z \"$currentAttempts\" ]]; then\r\n    _PRINT_HELP=yes die \"[Error] When specifying a login attempt lock time you must also specify the maximum login attempts.\" 1\r\n  fi\r\n\r\n  # Backup faillock.conf if changes are to be made\r\n  if [[ -n \"$_arg_maxLoginAttempts\" || -n \"$_arg_loginAttemptLockTime\" ]]; then\r\n    faillockBackup=\"\/etc\/security\/$today-faillock.conf.backup\"\r\n    echo \"Backing up '\/etc\/security\/faillock.conf' to '$faillockBackup'\"\r\n\r\n    # Exit if backup file already exists to avoid overwriting\r\n    if [[ -f \"$faillockBackup\" ]]; then\r\n      _PRINT_HELP=no die \"[Error] The backup file '$faillockBackup' already exists. Unable to backup faillock policy.\" 1\r\n    fi\r\n\r\n    # Attempt to create backup of faillock.conf, exit if it fails\r\n    if ! cp \/etc\/security\/faillock.conf \"$faillockBackup\"; then\r\n      _PRINT_HELP=no die \"[Error] Unable to backup faillock policy. Failed to save file to '$faillockBackup'\" 1\r\n    fi\r\n\r\n    # Confirm if the backup was successful\r\n    if [[ -f \"$faillockBackup\" ]]; then\r\n      echo \"Backup created successfully.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Unable to backup faillock. Failed to save the file to '$faillockBackup'\" 1\r\n    fi\r\n  fi\r\n\r\n  # Configure maximum login attempts and lock time in faillock policy if they are not set already\r\n  if [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -n \"$_arg_loginAttemptLockTime\" &amp;&amp; -z \"$currentAttempts\" &amp;&amp; -z \"$currentLockTime\" ]]; then\r\n    echo \"Configuring the maximum login attempts and lock time in the faillock policy.\"\r\n\r\n    # Define the new faillock policy values\r\n    faillockPolicy=\"silent\r\ndeny = $_arg_maxLoginAttempts\r\nunlock_time = $_arg_loginAttemptLockTime\"\r\n\r\n    # Append new policy to faillock.conf, exit if it fails\r\n    if ! echo \"$faillockPolicy\" &gt;&gt;\"\/etc\/security\/faillock.conf\"; then\r\n      _PRINT_HELP=no die \"[Error] Failed to configure the maximum login attempts and lock time in the faillock policy.\" 1\r\n    fi\r\n\r\n    # Confirm if the values were correctly set in faillock.conf\r\n    newAttempts=$(grep -v \"^#\" \/etc\/security\/faillock.conf | grep -v '^\\s*$' | grep -o -e \"deny[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n    newLockTime=$(grep -v \"^#\" \/etc\/security\/faillock.conf | grep -v '^\\s*$' | grep -o -e \"unlock_time[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n\r\n    # Verify if new max login attempts were set correctly\r\n    if [[ -n \"$newAttempts\" &amp;&amp; \"$newAttempts\" == \"$_arg_maxLoginAttempts\" ]]; then\r\n      echo \"Successfully set the maximum login attempts in the faillock policy.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Unable to configure the maximum login attempts in the faillock policy.\" 1\r\n    fi\r\n\r\n    if [[ -n \"$newLockTime\" &amp;&amp; \"$newLockTime\" == \"$_arg_loginAttemptLockTime\" ]]; then\r\n      echo \"Successfully added the lock time to the faillock policy.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to add the lock time to the faillock policy.\" 1\r\n    fi\r\n  fi\r\n\r\n  # Update max login attempts in faillock.conf if the current attempts differ from desired setting\r\n  if [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -n \"$currentAttempts\" ]]; then\r\n    echo \"Updating the current maximum login attempts from '$currentAttempts' to '$_arg_maxLoginAttempts' in the faillock policy.\"\r\n\r\n    # Update deny value in faillock.conf using sed, exit if it fails\r\n    if ! sed -i \"s\/^[^#]*deny[[:space:]]*=[[:space:]]*[0-9]*\/deny = $_arg_maxLoginAttempts\/g\" \"\/etc\/security\/faillock.conf\"; then\r\n      _PRINT_HELP=no die \"[Error] Failed to modify the max login attempts in the faillock policy.\" 1\r\n    fi\r\n\r\n    # Confirm if the updated max login attempts value was set correctly\r\n    newAttempts=$(grep -v \"^#\" \/etc\/security\/faillock.conf | grep -v '^\\s*$' | grep -o -e \"deny[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n    if [[ -n \"$newAttempts\" &amp;&amp; \"$newAttempts\" == \"$_arg_maxLoginAttempts\" ]]; then\r\n      echo \"Successfully updated the maximum login attempts in the faillock policy.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to modify the max login attempts in the faillock policy.\" 1\r\n    fi\r\n  fi\r\n\r\n  # Check if a new lock time argument is provided and differs from the current setting\r\n  if [[ -n \"$_arg_loginAttemptLockTime\" &amp;&amp; -n \"$currentLockTime\" ]]; then\r\n    echo \"Updating the lock time from '$currentLockTimeMinutes' minutes to '$loginAttemptLockTimeMinutes' minutes in the faillock policy.\"\r\n\r\n    # Modify the unlock_time value in faillock.conf, exiting with error if the operation fails\r\n    if ! sed -i \"s\/^[^#]*unlock_time[[:space:]]*=[[:space:]]*[0-9]*\/unlock_time = $_arg_loginAttemptLockTime\/g\" \"\/etc\/security\/faillock.conf\"; then\r\n      _PRINT_HELP=no die \"[Error] Failed to modify the lock time in the faillock policy.\" 1\r\n    fi\r\n\r\n    # Retrieve and verify the updated lock time from faillock.conf\r\n    newLockTime=$(grep -v \"^#\" \/etc\/security\/faillock.conf | grep -v '^\\s*$' | grep -o -e \"unlock_time[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n    if [[ -n \"$newLockTime\" &amp;&amp; \"$newLockTime\" == \"$_arg_loginAttemptLockTime\" ]]; then\r\n      echo \"Successfully modified the lock time in the faillock policy.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to modify the lock time in the faillock policy.\" 1\r\n    fi\r\n  fi\r\n\r\n  # Check if a minimum password length argument is provided\r\n  if [[ -n \"$_arg_minimumPasswordLength\" ]]; then\r\n    echo \"\"\r\n    echo \"Retrieving the current password quality policy.\"\r\n\r\n    # Exit with error if pwquality.conf does not exist\r\n    if [[ ! -f \"\/etc\/security\/pwquality.conf\" ]]; then\r\n      _PRINT_HELP=no die \"[Error] The file '\/etc\/security\/pwquality.conf' does not exist. Unable to read the current password quality policy.\" 1\r\n    fi\r\n\r\n    # Retrieve the current minimum password length setting from pwquality.conf\r\n    currentMinimumLength=$(grep -v \"^#\" \/etc\/security\/pwquality.conf | grep -v '^\\s*$' | grep -o -e \"minlen[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n    echo \"Successfully retrieved the current password quality policy.\"\r\n\r\n    # Skip updating if the current minimum length matches the desired setting\r\n    if [[ -n \"$currentMinimumLength\" &amp;&amp; \"$currentMinimumLength\" == \"$_arg_minimumPasswordLength\" ]]; then\r\n      echo \"The minimum password length is already '$_arg_minimumPasswordLength'. Skipping.\"\r\n      _arg_minimumPasswordLength=\r\n    fi\r\n  fi\r\n\r\n  # Back up pwquality.conf if changes are to be made\r\n  if [[ -n \"$_arg_minimumPasswordLength\" ]]; then\r\n    passwordQualityBackup=\"\/etc\/security\/$today-pwquality.conf.backup\"\r\n    echo \"Backing up '\/etc\/security\/pwquality.conf' to '$passwordQualityBackup'\"\r\n\r\n    # Exit if backup file already exists to prevent overwriting\r\n    if [[ -f \"$passwordQualityBackup\" ]]; then\r\n      _PRINT_HELP=no die \"[Error] The backup file '$passwordQualityBackup' already exists. Unable to backup password quality policy.\" 1\r\n    fi\r\n\r\n    # Attempt to create the backup, exiting if it fails\r\n    if ! cp \"\/etc\/security\/pwquality.conf\" \"$passwordQualityBackup\"; then\r\n      _PRINT_HELP=no die \"[Error] Failed to back up the password quality policy to '$passwordQualityBackup'.\" 1\r\n    fi\r\n\r\n    # Confirm if the backup was successful\r\n    if [[ -f \"$passwordQualityBackup\" ]]; then\r\n      echo \"Backup created successfully.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to back up the password quality policy to '$passwordQualityBackup'.\" 1\r\n    fi\r\n  fi\r\n\r\n  # Set minimum password length if no current setting exists\r\n  if [[ -n \"$_arg_minimumPasswordLength\" &amp;&amp; -z \"$currentMinimumLength\" ]]; then\r\n    echo \"Setting the minimum password length to '$_arg_minimumPasswordLength'.\"\r\n\r\n    # Append new minlen value to pwquality.conf, exiting with error if the operation fails\r\n    if ! echo \"minlen = $_arg_minimumPasswordLength\" &gt;&gt;\"\/etc\/security\/pwquality.conf\"; then\r\n      _PRINT_HELP=no die \"[Error] Unable to set the minimum password length in '\/etc\/security\/pwquality.conf'.\" 1\r\n    fi\r\n\r\n    # Confirm the updated minimum password length value\r\n    newMinimumLength=$(grep -v \"^#\" \/etc\/security\/pwquality.conf | grep -v '^\\s*$' | grep -o -e \"minlen[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n    if [[ -n \"$newMinimumLength\" &amp;&amp; \"$newMinimumLength\" == \"$_arg_minimumPasswordLength\" ]]; then\r\n      echo \"Successfully set the minimum password length.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Unable to set the minimum password length in '\/etc\/security\/pwquality.conf'.\" 1\r\n    fi\r\n  fi\r\n\r\n  # Update the minimum password length if a current setting already exists\r\n  if [[ -n \"$_arg_minimumPasswordLength\" &amp;&amp; -n \"$currentMinimumLength\" ]]; then\r\n    echo \"Updating the minimum password length from '$currentMinimumLength' to '$_arg_minimumPasswordLength'.\"\r\n\r\n    # Modify minlen value in pwquality.conf using sed, exit if the operation fails\r\n    if ! sed -i \"s\/^[^#]*minlen[[:space:]]*=[[:space:]]*[0-9]*\/minlen = $_arg_minimumPasswordLength\/g\" \"\/etc\/security\/pwquality.conf\"; then\r\n      _PRINT_HELP=no die \"[Error] Failed to update the password length policy.\" 1\r\n    fi\r\n\r\n    # Verify if the update was successful\r\n    newMinimumLength=$(grep -v \"^#\" \/etc\/security\/pwquality.conf | grep -v '^\\s*$' | grep -o -e \"minlen[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n    if [[ -n \"$newMinimumLength\" &amp;&amp; \"$newMinimumLength\" == \"$_arg_minimumPasswordLength\" ]]; then\r\n      echo \"Successfully updated the minimum password length.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to update the minimum password length in '\/etc\/security\/pwquality.conf'.\" 1\r\n    fi\r\n  fi\r\n\r\n  # Check if a password history argument is provided\r\n  if [[ -n \"$_arg_passwordHistory\" ]]; then\r\n    echo \"\"\r\n    echo \"Retrieving the current password history policy.\"\r\n\r\n    # Exit with error if pwhistory.conf does not exist\r\n    if [[ ! -f \"\/etc\/security\/pwhistory.conf\" ]]; then\r\n      errorMessage=\"[Error] The file '\/etc\/security\/pwhistory.conf' does not exist.\r\n[Error] This system may not support changing the password history.\r\n[Error] https:\/\/bugzilla.redhat.com\/show_bug.cgi?id=2063379\r\n[Error] Unable to read the current password history policy.\r\n\"\r\n      _PRINT_HELP=no die \"$errorMessage\" 1\r\n    fi\r\n\r\n    # Retrieve current password history setting from pwhistory.conf\r\n    currentPasswordHistory=$(grep -v \"^#\" \/etc\/security\/pwhistory.conf | grep -v '^\\s*$' | grep -o -e \"remember[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n    echo \"Successfully retrieved the current password history policy.\"\r\n\r\n    # Skip updating if current password history matches desired setting\r\n    if [[ -n \"$currentPasswordHistory\" &amp;&amp; \"$currentPasswordHistory\" == \"$_arg_passwordHistory\" ]]; then\r\n      echo \"The minimum password history is already set to remember the past '$_arg_passwordHistory' passwords. Skipping.\"\r\n      _arg_passwordHistory=\r\n    fi\r\n  fi\r\n\r\n  # Back up pwhistory.conf if changes are to be made\r\n  if [[ -n \"$_arg_passwordHistory\" ]]; then\r\n    passwordHistoryBackup=\"\/etc\/security\/$today-pwhistory.conf.backup\"\r\n    echo \"Backing up '\/etc\/security\/pwhistory.conf' to '$passwordHistoryBackup'\"\r\n\r\n    # Exit if backup file already exists\r\n    if [[ -f \"$passwordHistoryBackup\" ]]; then\r\n      _PRINT_HELP=no die \"[Error] The backup file '$passwordHistoryBackup' already exists. Unable to backup the password history policy.\" 1\r\n    fi\r\n\r\n    # Attempt to create backup, exiting if it fails\r\n    if ! cp \"\/etc\/security\/pwhistory.conf\" \"$passwordHistoryBackup\"; then\r\n      _PRINT_HELP=no die \"[Error] Failed to back up the password history policy to '$passwordHistoryBackup'.\" 1\r\n    fi\r\n\r\n    # Confirm if the backup was successful\r\n    if [[ -f \"$passwordHistoryBackup\" ]]; then\r\n      echo \"Backup created successfully.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to back up the password history policy to '$passwordHistoryBackup'.\" 1\r\n    fi\r\n  fi\r\n\r\n  # Set password history requirement if no current setting exists\r\n  if [[ -n \"$_arg_passwordHistory\" &amp;&amp; -z \"$currentPasswordHistory\" ]]; then\r\n    echo \"Setting the password history requirement.\"\r\n\r\n    # Append remember value to pwhistory.conf, exit if operation fails\r\n    if ! echo \"remember = $_arg_passwordHistory\" &gt;&gt;\"\/etc\/security\/pwhistory.conf\"; then\r\n      _PRINT_HELP=no die \"[Error] Failed to configure the password history requirement in '\/etc\/security\/pwhistory.conf'.\" 1\r\n    fi\r\n\r\n    # Verify if the password history setting was added successfully\r\n    newPasswordHistory=$(grep -v \"^#\" \/etc\/security\/pwhistory.conf | grep -v '^\\s*$' | grep -o -e \"remember[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n    if [[ -n \"$newPasswordHistory\" &amp;&amp; \"$newPasswordHistory\" == \"$_arg_passwordHistory\" ]]; then\r\n      echo \"Successfully set the password history requirement.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to set the password history requirement in the file '\/etc\/security\/pwhistory.conf'.\" 1\r\n    fi\r\n  fi\r\n\r\n  # Update password history requirement if current setting already exists\r\n  if [[ -n \"$_arg_passwordHistory\" &amp;&amp; -n \"$currentPasswordHistory\" ]]; then\r\n    echo \"Updating the password history requirement from remembering the last '$currentPasswordHistory' passwords to the last '$_arg_passwordHistory' passwords.\"\r\n\r\n    # Modify remember value in pwhistory.conf, exit if operation fails\r\n    if ! sed -i \"s\/^[^#]*remember[[:space:]]*=[[:space:]]*[0-9]*\/remember = $_arg_passwordHistory\/g\" \"\/etc\/security\/pwhistory.conf\"; then\r\n      _PRINT_HELP=no die \"[Error] Failed to update the password history policy.\" 1\r\n    fi\r\n\r\n    # Verify if the update was successful\r\n    newPasswordHistory=$(grep -v \"^#\" \/etc\/security\/pwhistory.conf | grep -v '^\\s*$' | grep -o -e \"remember[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n    if [[ -n \"$newPasswordHistory\" &amp;&amp; \"$newPasswordHistory\" == \"$_arg_passwordHistory\" ]]; then\r\n      echo \"Successfully updated the password history requirement.\"\r\n    else\r\n      _PRINT_HELP=no die \"[Error] Failed to update the password history requirement in the file '\/etc\/security\/pwhistory.conf'.\" 1\r\n    fi\r\n  fi\r\nfi\r\n\r\n# Check if a days until password expiration argument is provided\r\nif [[ -n \"$_arg_daysUntilPasswordExpiration\" ]]; then\r\n  echo \"\"\r\n  echo \"Retrieving the current password expiration policy.\"\r\n\r\n  # Exit with error if login.defs file does not exist\r\n  if [[ ! -f \"\/etc\/login.defs\" ]]; then\r\n    _PRINT_HELP=no die \"[Error] The file '\/etc\/login.defs' does not exist. Unable to read the current password expiration policy.\" 1\r\n  fi\r\n\r\n  # Exit with error if login.defs file is empty\r\n  if [[ ! -s \"\/etc\/login.defs\" ]]; then\r\n    _PRINT_HELP=no die \"[Error] The file '\/etc\/login.defs' is empty. Unable to read the current password expiration policy.\" 1\r\n  fi\r\n\r\n  # Retrieve current maximum password age setting from login.defs\r\n  currentMaxAge=$(grep \"^PASS_MAX_DAYS\" \"\/etc\/login.defs\" | grep -o -e \"[0-9]*\")\r\n\r\n  echo \"Successfully retrieved the current password expiration policy.\"\r\n\r\n  # Skip updating if current max age matches desired setting\r\n  if [[ -n \"$currentMaxAge\" &amp;&amp; \"$currentMaxAge\" == \"$_arg_daysUntilPasswordExpiration\" ]]; then\r\n    echo \"The current password expiration policy is already set to a maximum of '$_arg_daysUntilPasswordExpiration' days. Skipping.\"\r\n    skipMaxAge=\"on\"\r\n  fi\r\nfi\r\n\r\n# Back up login.defs if changes to password expiration are needed\r\nif [[ -n \"$_arg_daysUntilPasswordExpiration\" &amp;&amp; \"$skipMaxAge\" != \"on\" ]]; then\r\n  loginDefsBackup=\"\/etc\/$today-login.defs.backup\"\r\n  echo \"Backing up '\/etc\/login.defs' to '$loginDefsBackup'\"\r\n\r\n  # Exit if backup file already exists to prevent overwriting\r\n  if [[ -f \"$loginDefsBackup\" ]]; then\r\n    _PRINT_HELP=no die \"[Error] The backup file '$loginDefsBackup' already exists. Unable to backup login.defs.\" 1\r\n  fi\r\n\r\n  # Attempt to create backup, exiting if it fails\r\n  if ! cp \/etc\/login.defs \"$loginDefsBackup\"; then\r\n    _PRINT_HELP=no die \"[Error] Unable to backup login.defs. Failed to save file to '$loginDefsBackup'\" 1\r\n  fi\r\n\r\n  # Confirm if the backup was successful\r\n  if [[ -f \"$loginDefsBackup\" ]]; then\r\n    echo \"Backup created successfully.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Unable to backup login.defs. Failed to save file to '$loginDefsBackup'\" 1\r\n  fi\r\nfi\r\n\r\n# Set maximum password age if there is no existing setting\r\nif [[ -n \"$_arg_daysUntilPasswordExpiration\" &amp;&amp; -z \"$currentMaxAge\" &amp;&amp; \"$skipMaxAge\" != \"on\" ]]; then\r\n  echo \"Configuring the maximum password age in '\/etc\/login.defs'.\"\r\n\r\n  # Append new PASS_MAX_DAYS value to login.defs, exiting if the operation fails\r\n  if ! echo \"PASS_MAX_DAYS   $_arg_daysUntilPasswordExpiration\" &gt;&gt;\"\/etc\/login.defs\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to configure the password expiration policy in '\/etc\/login.defs'.\" 1\r\n  fi\r\n\r\n  # Verify if the maximum age setting was added successfully\r\n  newMaxAge=$(grep \"^PASS_MAX_DAYS\" \"\/etc\/login.defs\" | grep -o -e \"[0-9]*\")\r\n  if [[ -n \"$newMaxAge\" &amp;&amp; \"$newMaxAge\" == \"$_arg_daysUntilPasswordExpiration\" ]]; then\r\n    echo \"Successfully added a password expiration of '$_arg_daysUntilPasswordExpiration' days for new users.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Failed to configure the password expiration policy in '\/etc\/login.defs'.\" 1\r\n  fi\r\nfi\r\n\r\n# Update existing maximum password age if a current setting is already present\r\nif [[ -n \"$_arg_daysUntilPasswordExpiration\" &amp;&amp; -n \"$currentMaxAge\" &amp;&amp; \"$skipMaxAge\" != \"on\" ]]; then\r\n  echo \"Updating the maximum password age from '$currentMaxAge' to '$_arg_daysUntilPasswordExpiration'.\"\r\n\r\n  # Modify PASS_MAX_DAYS value in login.defs using sed, exiting if the operation fails\r\n  if ! sed -i \"s\/^PASS_MAX_DAYS[[:space:]]*[0-9]*\/PASS_MAX_DAYS   $_arg_daysUntilPasswordExpiration\/g\" \"\/etc\/login.defs\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to set the maximum password age in '\/etc\/login.defs'.\" 1\r\n  fi\r\n\r\n  # Confirm the update was successful\r\n  newMaxAge=$(grep \"^PASS_MAX_DAYS\" \"\/etc\/login.defs\" | grep -o -e \"[0-9]*\")\r\n  if [[ -n \"$newMaxAge\" &amp;&amp; \"$newMaxAge\" == \"$_arg_daysUntilPasswordExpiration\" ]]; then\r\n    echo \"Successfully modified the maximum password age for new users.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Failed to configure the password expiration policy in '\/etc\/login.defs'.\" 1\r\n  fi\r\nfi\r\n\r\n# Apply password expiration policy to existing accounts if a days until expiration argument is provided\r\nif [[ -n \"$_arg_daysUntilPasswordExpiration\" ]]; then\r\n  echo \"Retrieving list of existing accounts.\"\r\n\r\n  # Retrieve user information, exiting if the operation fails\r\n  if ! allUsers=$(cut -f 1,3 -d ':' \"\/etc\/passwd\"); then\r\n    _PRINT_HELP=no die \"[Error] Failed to retrieve existing users from '\/etc\/passwd'.\" 1\r\n  fi\r\n\r\n  # Retrieve minimum and maximum user IDs from login.defs, exiting if retrieval fails\r\n  if ! minId=$(grep \"^UID_MIN\" \"\/etc\/login.defs\" | grep -o -e \"[0-9]*\"); then\r\n    _PRINT_HELP=no die \"[Error] Failed to find the minimum user ID in '\/etc\/login.defs'.\" 1\r\n  fi\r\n\r\n  if ! maxId=$(grep \"^UID_MAX\" \"\/etc\/login.defs\" | grep -o -e \"[0-9]*\"); then\r\n    _PRINT_HELP=no die \"[Error] Failed to find the minimum user ID in '\/etc\/login.defs'.\" 1\r\n  fi\r\n\r\n  # Ensure both minimum and maximum IDs were found, otherwise exit with error\r\n  if [[ -z \"$minId\" || -z \"$maxId\" ]]; then\r\n    _PRINT_HELP=no die \"[Error] Failed to find the minimum or maximum user ID in '\/etc\/login.defs'.\" 1\r\n  fi\r\n\r\n  echo \"Setting the maximum password age for existing accounts.\"\r\n\r\n  # Loop through each user to apply the expiration policy if the user ID is within the range\r\n  for user in $allUsers; do\r\n    uid=$(echo \"$user\" | cut -f 2 -d \":\")\r\n\r\n    # Check if the user ID is within the defined range\r\n    if [[ \"$uid\" -ge \"$minId\" &amp;&amp; \"$uid\" -le \"$maxId\" ]]; then\r\n      usernameToModify=$(echo \"$user\" | cut -f 1 -d \":\")\r\n      currentMaxAge=$(chage -l \"$usernameToModify\" | grep Max | grep -o -e \"[0-9]*\" | xargs)\r\n\r\n      # Skip updating if the user's maximum password age already matches the desired setting\r\n      if [[ -n \"$currentMaxAge\" &amp;&amp; \"$currentMaxAge\" == \"$_arg_daysUntilPasswordExpiration\" ]]; then\r\n        echo \"The user '$usernameToModify' already has a maximum password age of '$_arg_daysUntilPasswordExpiration'. Skipping.\"\r\n        continue\r\n      fi\r\n\r\n      echo \"Updating the maximum password age for the user '$usernameToModify'.\"\r\n\r\n      # Attempt to apply the expiration policy, exiting with error if it fails\r\n      if ! chage --maxdays \"$_arg_daysUntilPasswordExpiration\" \"$usernameToModify\"; then\r\n        _PRINT_HELP=no die \"[Error] Failed to update the maximum password age for the user '$usernameToModify'.\" 1\r\n      fi\r\n\r\n      # Confirm the update was successful\r\n      newMaxAge=$(chage -l \"$usernameToModify\" | grep Max | grep -o -e \"[0-9]*\" | xargs)\r\n      if [[ -z \"$newMaxAge\" || \"$newMaxAge\" != \"$_arg_daysUntilPasswordExpiration\" ]]; then\r\n        _PRINT_HELP=no die \"[Error] Failed to update the maximum password age for the user '$usernameToModify'.\" 1\r\n      else\r\n        echo \"Successfully updated the maximum password age for the user '$usernameToModify'.\"\r\n      fi\r\n    fi\r\n  done\r\nfi\r\n\r\n# Check if authselect or authconfig is available\r\nif [[ -n \"$authselectAvailable\" || -n \"$authconfigAvailable\" ]]; then\r\n  # If password history is specified and only authconfig is available, exit with error\r\n  if [[ -n \"$_arg_passwordHistory\" &amp;&amp; -n \"$authconfigAvailable\" &amp;&amp; -z \"$authselectAvailable\" ]]; then\r\n    errorMessage=\"\r\n[Error] This system uses authconfig to modify the PAM configuration files.\r\n[Error] Unfortunately, authconfig does not provide an option to implement a password history requirement and will overwrite all manual changes every time it is run.\r\n[Error] Please upgrade your system to a distribution that supports authselect or allows manual edits of PAM configuration files.\r\n[Error] https:\/\/bugzilla.redhat.com\/show_bug.cgi?id=1271804\"\r\n    _PRINT_HELP=no die \"$errorMessage\" 1\r\n  fi\r\n\r\n  exit\r\nfi\r\n\r\n# Check if max login attempts or lock time is provided\r\nif [[ -n \"$_arg_maxLoginAttempts\" || -n \"$_arg_loginAttemptLockTime\" ]]; then\r\n  echo \"\"\r\n  echo \"Attempting to retrieve the current PAM authentication policy.\"\r\n\r\n  # Check if common-auth file exists and is not empty\r\n  if [[ ! -f \"\/etc\/pam.d\/common-auth\" ]]; then\r\n    _PRINT_HELP=no die \"[Error] The file '\/etc\/pam.d\/common-auth' does not exist. Cannot read the current PAM authentication policy.\" 1\r\n  fi\r\n  if [[ ! -s \"\/etc\/pam.d\/common-auth\" ]]; then\r\n    _PRINT_HELP=no die \"[Error] The file '\/etc\/pam.d\/common-auth' is empty. Cannot read the current PAM authentication policy.\" 1\r\n  fi\r\n\r\n  # Retrieve current max login attempts and lock time from common-auth\r\n  currentAttempts=$(grep -v \"^#\" \/etc\/pam.d\/common-auth | grep -v '^\\s*$' | grep \"pam_faillock.so\" | grep \"preauth\" | grep -o -e \"deny[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n  currentLockTime=$(grep -v \"^#\" \/etc\/pam.d\/common-auth | grep -v '^\\s*$' | grep \"pam_faillock.so\" | grep \"preauth\" | grep -o -e \"unlock_time[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n\r\n  # Convert lock time to minutes if it exists\r\n  if [[ -n \"$currentLockTime\" ]]; then\r\n    currentLockTimeMinutes=$((currentLockTime \/ 60))\r\n  fi\r\n\r\n  # Convert provided lock time to seconds if specified\r\n  if [[ -n \"$_arg_loginAttemptLockTime\" ]]; then\r\n    loginAttemptLockTimeMinutes=\"$_arg_loginAttemptLockTime\"\r\n    _arg_loginAttemptLockTime=$((_arg_loginAttemptLockTime * 60))\r\n  fi\r\n\r\n  echo \"Current PAM authentication policy retrieved successfully.\"\r\n\r\n  # Skip max login attempts setting if it matches the current configuration\r\n  if [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -n \"$currentAttempts\" &amp;&amp; \"$_arg_maxLoginAttempts\" == \"$currentAttempts\" ]]; then\r\n    echo \"The maximum login attempts is already set to '$_arg_maxLoginAttempts'. Skipping.\"\r\n    _arg_maxLoginAttempts=\r\n  fi\r\n\r\n  # Skip lock time setting if it matches the current configuration\r\n  if [[ -n \"$_arg_loginAttemptLockTime\" &amp;&amp; -n \"$currentLockTime\" &amp;&amp; \"$_arg_loginAttemptLockTime\" == \"$currentLockTime\" ]]; then\r\n    echo \"The lock time is already set to '$loginAttemptLockTimeMinutes' minutes. Skipping.\"\r\n    _arg_loginAttemptLockTime=\r\n  fi\r\nfi\r\n\r\n# Check for missing lock time or max attempts arguments\r\nif [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -z \"$_arg_loginAttemptLockTime\" &amp;&amp; -z \"$currentLockTime\" ]]; then\r\n  _PRINT_HELP=yes die \"[Error] When specifying the maximum number of login attempts, you must also specify the login attempt lock time.\" 1\r\nfi\r\nif [[ -n \"$_arg_loginAttemptLockTime\" &amp;&amp; -z \"$_arg_maxLoginAttempts\" &amp;&amp; -z \"$currentAttempts\" ]]; then\r\n  _PRINT_HELP=yes die \"[Error] When specifying a login attempt lock time you must also specify the maximum login attempts.\" 1\r\nfi\r\n\r\n# Create a backup of the common-auth file if settings need to be applied\r\nif [[ -n \"$_arg_maxLoginAttempts\" || -n \"$_arg_loginAttemptLockTime\" ]]; then\r\n  commonAuthBackup=\"\/etc\/pam.d\/$today-common-auth.backup\"\r\n  echo \"Creating a backup of '\/etc\/pam.d\/common-auth' to '$commonAuthBackup'.\"\r\n\r\n  # Exit if a backup file already exists\r\n  if [[ -f \"$commonAuthBackup\" ]]; then\r\n    _PRINT_HELP=no die \"[Error] Backup file '$commonAuthBackup' already exists. Cannot create a backup of the common-auth policy.\" 1\r\n  fi\r\n\r\n  # Attempt to create a backup, exiting if it fails\r\n  if ! cp \/etc\/pam.d\/common-auth \"$commonAuthBackup\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to create a backup of the common-auth policy to '$commonAuthBackup'.\" 1\r\n  fi\r\n\r\n  # Confirm successful backup creation\r\n  if [[ -f \"$commonAuthBackup\" ]]; then\r\n    echo \"Backup created successfully.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Unable to backup common-auth. Failed to save file to '$commonAuthBackup'\" 1\r\n  fi\r\nfi\r\n\r\n# Apply max login attempts and lock time settings if none exist in the current policy\r\nif [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -n \"$_arg_loginAttemptLockTime\" &amp;&amp; -z \"$currentAttempts\" &amp;&amp; -z \"$currentLockTime\" ]]; then\r\n  echo \"Configuring the maximum login attempts and lock time in the PAM authentication policy.\"\r\n\r\n  # Prepend authfail and preauth lines to common-auth for faillock, exiting if any operation fails\r\n  if ! sed -i \"1i auth  required  pam_faillock.so  authfail  deny=$_arg_maxLoginAttempts  unlock_time=$_arg_loginAttemptLockTime\" \"\/etc\/pam.d\/common-auth\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to configure the maximum login attempts and lock time in the PAM authentication policy.\" 1\r\n  fi\r\n  if ! sed -i \"1i auth  required  pam_faillock.so  preauth  silent  deny=$_arg_maxLoginAttempts  unlock_time=$_arg_loginAttemptLockTime\" \"\/etc\/pam.d\/common-auth\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to configure the maximum login attempts and lock time in the PAM authentication policy.\" 1\r\n  fi\r\n\r\n  # Verify if the settings were applied successfully\r\n  newAttempts=$(grep -v \"^#\" \/etc\/pam.d\/common-auth | grep -v '^\\s*$' | grep \"pam_faillock.so\" | grep \"preauth\" | grep -o -e \"deny[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n  newLockTime=$(grep -v \"^#\" \/etc\/pam.d\/common-auth | grep -v '^\\s*$' | grep \"pam_faillock.so\" | grep \"preauth\" | grep -o -e \"unlock_time[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n\r\n  if [[ -n \"$newAttempts\" &amp;&amp; \"$newAttempts\" == \"$_arg_maxLoginAttempts\" ]]; then\r\n    echo \"Successfully configured the maximum login attempts in the PAM authentication policy.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Failed to add the max login attempts to the PAM authentication policy.\" 1\r\n  fi\r\n  if [[ -n \"$newLockTime\" &amp;&amp; \"$newLockTime\" == \"$_arg_loginAttemptLockTime\" ]]; then\r\n    echo \"Successfully added the lock time to the PAM authentication policy.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Failed to configure the lock time in the PAM authentication policy.\" 1\r\n  fi\r\nfi\r\n\r\n# Modify existing max login attempts setting if it doesn't match the desired setting\r\nif [[ -n \"$_arg_maxLoginAttempts\" &amp;&amp; -n \"$currentAttempts\" ]]; then\r\n  echo \"Modifying the current max login attempts from '$currentAttempts' to '$_arg_maxLoginAttempts' in the PAM authentication policy.\"\r\n\r\n  # Update max login attempts in preauth and authfail lines, exiting if any operation fails\r\n  existingPreAuthLine=$(grep -v \"^#\" \/etc\/pam.d\/common-auth | grep -v '^\\s*$' | grep -e \"pam_faillock\\.so [[:space:]]*preauth\")\r\n  newAttemptPreAuthLine=$(echo \"$existingPreAuthLine\" | sed \"s\/deny[[:space:]]*=[[:space:]]*[0-9]*\/deny=$_arg_maxLoginAttempts\/g\")\r\n  if ! sed -i \"s\/$existingPreAuthLine\/$newAttemptPreAuthLine\/g\" \"\/etc\/pam.d\/common-auth\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to modify the max login attempts in the PAM authentication policy 1.\" 1\r\n  fi\r\n\r\n  existingAuthFailLine=$(grep -v \"^#\" \/etc\/pam.d\/common-auth | grep -v '^\\s*$' | grep -e \"pam_faillock\\.so [[:space:]]*authfail\")\r\n  newAttemptAuthFailLine=$(echo \"$existingAuthFailLine\" | sed \"s\/deny[[:space:]]*=[[:space:]]*[0-9]*\/deny=$_arg_maxLoginAttempts\/g\")\r\n  if ! sed -i \"s\/$existingAuthFailLine\/$newAttemptAuthFailLine\/g\" \"\/etc\/pam.d\/common-auth\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to modify the max login attempts in the PAM authentication policy 2.\" 1\r\n  fi\r\n\r\n  # Confirm the new max attempts setting was applied\r\n  newAttempts=$(grep -v \"^#\" \/etc\/pam.d\/common-auth | grep -v '^\\s*$' | grep \"pam_faillock.so\" | grep \"preauth\" | grep -o -e \"deny[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n  if [[ -n \"$newAttempts\" &amp;&amp; \"$newAttempts\" == \"$_arg_maxLoginAttempts\" ]]; then\r\n    echo \"Successfully modified the max login attempts.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Failed to modify the max login attempts in the PAM authentication policy.\" 1\r\n  fi\r\nfi\r\n\r\n# Check if a new lock time is specified and differs from the current one\r\nif [[ -n \"$_arg_loginAttemptLockTime\" &amp;&amp; -n \"$currentLockTime\" ]]; then\r\n  echo \"Modifying the current lock time from '$currentLockTimeMinutes' minutes to '$loginAttemptLockTimeMinutes' minutes in the PAM authentication policy template.\"\r\n\r\n  # Find and replace the unlock_time in the preauth line\r\n  existingPreAuthLine=$(grep -v \"^#\" \/etc\/pam.d\/common-auth | grep -v '^\\s*$' | grep -e \"pam_faillock\\.so [[:space:]]*preauth\")\r\n  newLockTimePreAuthLine=$(echo \"$existingPreAuthLine\" | sed \"s\/unlock_time[[:space:]]*=[[:space:]]*[0-9]*\/unlock_time=$_arg_loginAttemptLockTime\/g\")\r\n  if ! sed -i \"s\/$existingPreAuthLine\/$newLockTimePreAuthLine\/g\" \"\/etc\/pam.d\/common-auth\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to modify the lock time in the PAM authentication policy.\" 1\r\n  fi\r\n\r\n  # Find and replace the unlock_time in the authfail line\r\n  existingAuthFailLine=$(grep -v \"^#\" \/etc\/pam.d\/common-auth | grep -v '^\\s*$' | grep -e \"pam_faillock\\.so [[:space:]]*authfail\")\r\n  newLockTimeAuthFailLine=$(echo \"$existingAuthFailLine\" | sed \"s\/unlock_time[[:space:]]*=[[:space:]]*[0-9]*\/unlock_time=$_arg_loginAttemptLockTime\/g\")\r\n  if ! sed -i \"s\/$existingAuthFailLine\/$newLockTimeAuthFailLine\/g\" \"\/etc\/pam.d\/common-auth\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to modify the lock time in the PAM authentication policy.\" 1\r\n  fi\r\n\r\n  # Confirm the lock time modification\r\n  echo \"Successfully modified the current lock time.\"\r\n  newLockTime=$(grep -v \"^#\" \/etc\/pam.d\/common-auth | grep -v '^\\s*$' | grep \"pam_faillock.so\" | grep \"preauth\" | grep -o -e \"unlock_time[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n  if [[ -n \"$newLockTime\" &amp;&amp; \"$newLockTime\" == \"$_arg_loginAttemptLockTime\" ]]; then\r\n    echo \"Successfully added the lock time to the PAM authentication policy.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Failed to configure the lock time in the PAM authentication policy.\" 1\r\n  fi\r\nfi\r\n\r\n# Check if minimum password length or password history arguments are specified\r\nif [[ -n \"$_arg_minimumPasswordLength\" || -n \"$_arg_passwordHistory\" ]]; then\r\n  echo \"\"\r\n  echo \"Retrieving the current PAM common password policy.\"\r\n\r\n  # Check if common-password file exists and is not empty\r\n  if [[ ! -f \"\/etc\/pam.d\/common-password\" ]]; then\r\n    _PRINT_HELP=no die \"[Error] The file '\/etc\/pam.d\/common-password' does not exist. Cannot read the current PAM common password policy.\" 1\r\n  fi\r\n  if [[ ! -s \"\/etc\/pam.d\/common-password\" ]]; then\r\n    _PRINT_HELP=no die \"[Error] The file '\/etc\/pam.d\/common-password' is empty. Cannot read the current PAM common password policy.\" 1\r\n  fi\r\n\r\n  # Check if pam_unix.so module is present in the file\r\n  if ! grep -v \"^#\" \/etc\/pam.d\/common-password | grep -v '^\\s*$' | grep \"pam_unix.so\" 1&gt;\/dev\/null; then\r\n    _PRINT_HELP=no die \"[Error] The 'pam_unix.so' module is missing. Cannot append the minimum password length.\" 1\r\n  fi\r\n\r\n  # Retrieve current settings for minimum length and password history\r\n  currentMinimumLength=$(grep -v \"^#\" \/etc\/pam.d\/common-password | grep -v '^\\s*$' | grep \"pam_unix.so\" | grep -o -e \"minlen[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n  currentPasswordHistory=$(grep -v \"^#\" \/etc\/pam.d\/common-password | grep -v '^\\s*$' | grep \"pam_unix.so\" | grep -o -e \"remember[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n\r\n  echo \"Successfully retrieved the current PAM common password policy.\"\r\n\r\n  # Skip minimum length setting if it matches the current configuration\r\n  if [[ -n \"$_arg_minimumPasswordLength\" &amp;&amp; -n $currentMinimumLength &amp;&amp; \"$_arg_minimumPasswordLength\" == \"$currentMinimumLength\" ]]; then\r\n    echo \"The minimum password length is already '$_arg_minimumPasswordLength'. Skipping.\"\r\n    _arg_minimumPasswordLength=\r\n  fi\r\n\r\n  # Skip password history setting if it matches the current configuration\r\n  if [[ -n \"$_arg_passwordHistory\" &amp;&amp; -n $currentPasswordHistory &amp;&amp; \"$_arg_passwordHistory\" == \"$currentPasswordHistory\" ]]; then\r\n    echo \"The password history requirement is already set to remember the past '$_arg_passwordHistory' passwords. Skipping.\"\r\n    _arg_passwordHistory=\r\n  fi\r\nfi\r\n\r\n# Create a backup of common-password file if either minimum length or password history needs to be set\r\nif [[ -n \"$_arg_minimumPasswordLength\" || -n \"$_arg_passwordHistory\" ]]; then\r\n  commonPasswordBackup=\"\/etc\/pam.d\/$today-common-password.backup\"\r\n  echo \"Creating a backup of '\/etc\/pam.d\/common-password' to '$commonPasswordBackup'.\"\r\n\r\n  # Exit if a backup file already exists\r\n  if [[ -f \"$commonPasswordBackup\" ]]; then\r\n    _PRINT_HELP=no die \"[Error] The backup file '$commonPasswordBackup' already exists. Unable to backup common-password.\" 1\r\n  fi\r\n\r\n  # Attempt to create a backup, exiting if it fails\r\n  if ! cp \/etc\/pam.d\/common-password \"$commonPasswordBackup\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to create a backup of 'common-password' to '$commonPasswordBackup'.\" 1\r\n  fi\r\n\r\n  # Confirm successful backup creation\r\n  if [[ -f \"$commonPasswordBackup\" ]]; then\r\n    echo \"Backup created successfully.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Failed to create a backup of 'common-password' to '$commonPasswordBackup'.\" 1\r\n  fi\r\nfi\r\n\r\n# Set the minimum password length if it does not currently exist in the file\r\nif [[ -n \"$_arg_minimumPasswordLength\" &amp;&amp; -z \"$currentMinimumLength\" ]]; then\r\n  echo \"Setting the minimum password length to '$_arg_minimumPasswordLength'.\"\r\n\r\n  # Find the line with pam_unix.so and append minlen setting\r\n  currentPasswordLine=$(grep -v \"^#\" \/etc\/pam.d\/common-password | grep -v '^\\s*$' | grep \"pam_unix.so\")\r\n  currentPasswordLine=$(echo \"$currentPasswordLine\" | sed 's\/\\[\/\\\\[\/g' | sed 's\/\\]\/\\\\]\/g')\r\n  newMinLengthLine=\"$currentPasswordLine minlen=$_arg_minimumPasswordLength\"\r\n  newMinLengthLine=${newMinLengthLine\/\/\\\\\/}\r\n\r\n  if ! sed -i \"s\/$currentPasswordLine\/$newMinLengthLine\/g\" \"\/etc\/pam.d\/common-password\"; then\r\n    _PRINT_HELP=no die \"[Error] Unable to set the minimum password length in '\/etc\/pam.d\/common-password'.\" 1\r\n  fi\r\n\r\n  # Verify the setting was applied successfully\r\n  newMinimumLength=$(grep -v \"^#\" \/etc\/pam.d\/common-password | grep -v '^\\s*$' | grep \"pam_unix.so\" | grep -o -e \"minlen[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n  if [[ -n \"$newMinimumLength\" &amp;&amp; \"$newMinimumLength\" == \"$_arg_minimumPasswordLength\" ]]; then\r\n    echo \"Successfully set the minimum password length.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Unable to set the minimum password length in '\/etc\/pam.d\/common-password'.\" 1\r\n  fi\r\nfi\r\n\r\n# Update minimum password length if it already exists but differs from desired value\r\nif [[ -n \"$_arg_minimumPasswordLength\" &amp;&amp; -n \"$currentMinimumLength\" ]]; then\r\n  echo \"Updating the minimum password length from '$currentMinimumLength' to '$_arg_minimumPasswordLength'.\"\r\n\r\n  # Modify the existing minlen setting\r\n  currentMinLengthLine=$(grep -v \"^#\" \/etc\/pam.d\/common-password | grep -v '^\\s*$' | grep \"pam_unix.so\" | grep \"minlen\")\r\n  currentMinLengthLine=$(echo \"$currentMinLengthLine\" | sed 's\/\\[\/\\\\[\/g' | sed 's\/\\]\/\\\\]\/g')\r\n  newMinLengthLine=$(echo \"$currentMinLengthLine\" | sed \"s\/minlen[[:space:]]*=[[:space:]]*[0-9]*\/minlen=$_arg_minimumPasswordLength\/g\")\r\n  newMinLengthLine=${newMinLengthLine\/\/\\\\\/}\r\n\r\n  if ! sed -i \"s\/$currentMinLengthLine\/$newMinLengthLine\/g\" \"\/etc\/pam.d\/common-password\"; then\r\n    _PRINT_HELP=no die \"[Error] Unable to update the minimum password length in '\/etc\/pam.d\/common-password'.\" 1\r\n  fi\r\n\r\n  # Verify the updated setting\r\n  newMinimumLength=$(grep -v \"^#\" \/etc\/pam.d\/common-password | grep -v '^\\s*$' | grep \"pam_unix.so\" | grep -o -e \"minlen[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n  if [[ -n \"$newMinimumLength\" &amp;&amp; \"$newMinimumLength\" == \"$_arg_minimumPasswordLength\" ]]; then\r\n    echo \"Successfully modified the minimum password length required.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Unable to update the minimum password length in '\/etc\/pam.d\/common-password'.\" 1\r\n  fi\r\nfi\r\n\r\n# Set or modify the password history requirement\r\nif [[ -n \"$_arg_passwordHistory\" &amp;&amp; -z \"$currentPasswordHistory\" ]]; then\r\n  echo \"Setting the password history requirement.\"\r\n\r\n  currentPasswordLine=$(grep -v \"^#\" \/etc\/pam.d\/common-password | grep -v '^\\s*$' | grep \"pam_unix.so\")\r\n  currentPasswordLine=$(echo \"$currentPasswordLine\" | sed 's\/\\[\/\\\\[\/g' | sed 's\/\\]\/\\\\]\/g')\r\n  newPasswordHistoryLine=\"$currentPasswordLine remember=$_arg_passwordHistory\"\r\n  newPasswordHistoryLine=${newPasswordHistoryLine\/\/\\\\\/}\r\n\r\n  if ! sed -i \"s\/$currentPasswordLine\/$newPasswordHistoryLine\/g\" \"\/etc\/pam.d\/common-password\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to set the password history requirement in '\/etc\/pam.d\/common-password'.\" 1\r\n  fi\r\n\r\n  # Confirm the new setting\r\n  newPasswordHistory=$(grep -v \"^#\" \/etc\/pam.d\/common-password | grep -v '^\\s*$' | grep \"pam_unix.so\" | grep -o -e \"remember[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n  if [[ -n \"$newPasswordHistory\" &amp;&amp; \"$newPasswordHistory\" == \"$_arg_passwordHistory\" ]]; then\r\n    echo \"Successfully set the password history requirement.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Failed to set the password history requirement in '\/etc\/pam.d\/common-password'.\" 1\r\n  fi\r\nfi\r\n\r\n# Modify the password history setting if it already exists but differs from the new desired value\r\nif [[ -n \"$_arg_passwordHistory\" &amp;&amp; -n \"$currentPasswordHistory\" &amp;&amp; \"$_arg_passwordHistory\" != \"$currentPasswordHistory\" ]]; then\r\n  echo \"Updating the password history requirement from remembering the last '$currentPasswordHistory' passwords to the last '$_arg_passwordHistory' passwords.\"\r\n\r\n  currentPasswordLine=$(grep -v \"^#\" \/etc\/pam.d\/common-password | grep -v '^\\s*$' | grep \"pam_unix.so\" | grep \"minlen\")\r\n  currentPasswordLine=$(echo \"$currentPasswordLine\" | sed 's\/\\[\/\\\\[\/g' | sed 's\/\\]\/\\\\]\/g')\r\n  newPasswordHistoryLine=$(echo \"$currentPasswordLine\" | sed \"s\/remember[[:space:]]*=[[:space:]]*[0-9]*\/remember=$_arg_passwordHistory\/g\")\r\n  newPasswordHistoryLine=${newPasswordHistoryLine\/\/\\\\\/}\r\n\r\n  if ! sed -i \"s\/$currentPasswordLine\/$newPasswordHistoryLine\/g\" \"\/etc\/pam.d\/common-password\"; then\r\n    _PRINT_HELP=no die \"[Error] Failed to change the password history requirement in '\/etc\/pam.d\/common-password'.\" 1\r\n  fi\r\n\r\n  # Confirm the updated setting\r\n  newPasswordHistory=$(grep -v \"^#\" \/etc\/pam.d\/common-password | grep -v '^\\s*$' | grep \"pam_unix.so\" | grep -o -e \"remember[[:space:]]*=[[:space:]]*[0-9]*\" | grep -o -e \"[0-9]*\")\r\n  if [[ -n \"$newPasswordHistory\" &amp;&amp; \"$newPasswordHistory\" == \"$_arg_passwordHistory\" ]]; then\r\n    echo \"Successfully modified the password history requirement.\"\r\n  else\r\n    _PRINT_HELP=no die \"[Error] Failed to change the password history requirement in '\/etc\/pam.d\/common-password'.\" 1\r\n  fi\r\nfi<\/pre>\n<p>&nbsp;<\/p>\n\n<h2>Description d\u00e9taill\u00e9e<\/h2>\n<p>Le script remplit les fonctions suivantes :<\/p>\n<h3>1. Analyse et validation des arguments<\/h3>\n<p>Il accepte des param\u00e8tres tels que :<\/p>\n<ul>\n<li>&#8211;maxLoginAttempts : Nombre de tentatives \u00e9chou\u00e9es autoris\u00e9es avant le verrouillage.<\/li>\n<li>&#8211;loginAttemptLockTime : Dur\u00e9e (en minutes) du blocage du compte.<\/li>\n<li>&#8211;daysUntilPasswordExpiration : Politique d&rsquo;expiration des mots de passe.<\/li>\n<li>&#8211;minimumPasswordLength: Longueur du mot de passe requis.<\/li>\n<li>&#8211;passwordHistory: Nombre de mots de passe pr\u00e9c\u00e9dents m\u00e9moris\u00e9s.<\/li>\n<\/ul>\n<p>Chaque valeur est strictement valid\u00e9e afin d&rsquo;\u00e9viter toute erreur de configuration.<\/p>\n<h3>2. Contr\u00f4le de l&rsquo;autorisation<\/h3>\n<p>Le script doit \u00eatre ex\u00e9cut\u00e9 avec les privil\u00e8ges de root. Il v\u00e9rifie l&rsquo;id -u et s&rsquo;arr\u00eate dans le cas contraire.<\/p>\n<h3>3. D\u00e9tection de la plateforme<\/h3>\n<p>Il d\u00e9tecte s&rsquo;il faut utiliser :<\/p>\n<ul>\n<li>authselect (syst\u00e8mes modernes bas\u00e9s sur RHEL),<\/li>\n<li>authconfig (anciens syst\u00e8mes bas\u00e9s sur RHEL),<\/li>\n<li>Ou \u00e9diter directement les fichiers PAM pour les syst\u00e8mes bas\u00e9s sur Debian.<\/li>\n<\/ul>\n<h3>4. Application de la strat\u00e9gie<\/h3>\n<p>En fonction du syst\u00e8me de configuration disponible, le script :<\/p>\n<ul>\n<li>Active la fonction faillock si n\u00e9cessaire.<\/li>\n<li>Met \u00e0 jour \/etc\/security\/faillock.conf, pwquality.conf, et pwhistory.conf.<\/li>\n<li>Applique les r\u00e8gles d&rsquo;expiration des mots de passe via \/etc\/login.defs et chage.<\/li>\n<li>Sauvegarde les fichiers de configuration avant toute modification afin d&rsquo;assurer une capacit\u00e9 de retour en arri\u00e8re.<\/li>\n<\/ul>\n<h3>5. Retour \u00e0 la configuration manuelle<\/h3>\n<p>Si ni authconfig ni authselect ne sont disponibles, le script modifie les modules PAM tels que \/etc\/pam.d\/common-auth et \/etc\/pam.d\/common-password.<\/p>\n<h2>Cas d&rsquo;utilisation potentiels<\/h2>\n<h3>Cas de figure\u00a0:<\/h3>\n<p>Un MSP g\u00e9rant plus de 1000 serveurs Linux \u00e0 distribution mixte souhaite appliquer :<\/p>\n<ul>\n<li>Expiration du mot de passe tous les 90 jours.<\/li>\n<li>Verrouiller les comptes pendant 10 minutes apr\u00e8s 5 tentatives de connexion infructueuses.<\/li>\n<li>Emp\u00eacher les utilisateurs de r\u00e9utiliser les cinq derniers mots de passe.<\/li>\n<\/ul>\n<h3>Solution\u00a0:<\/h3>\n<p>Ils d\u00e9ploient ce script via le moteur de script de NinjaOne, en passant des arguments comme :<\/p>\n<p>bash<\/p>\n<p>CopyEdit<\/p>\n<p>&#8211;maxLoginAttempts 5 &#8211;loginAttemptLockTime 10 &#8211;daysUntilPasswordExpiration 90 &#8211;minimumPasswordLength 12 &#8211;passwordHistory 5<\/p>\n<p>Avec une seule ex\u00e9cution de la politique, les normes de mot de passe sont appliqu\u00e9es de mani\u00e8re coh\u00e9rente sur les syst\u00e8mes Debian et RHEL.<\/p>\n<h3>Comparaisons<\/h3>\n<table>\n<tbody>\n<tr>\n<td style=\"text-align: center;\"><strong>M\u00e9thode<\/strong><\/td>\n<td style=\"text-align: center;\"><strong>Avantages<\/strong><\/td>\n<td style=\"text-align: center;\"><strong>Inconv\u00e9nients<\/strong><\/td>\n<\/tr>\n<tr>\n<td>Configuration manuelle<\/td>\n<td>Contr\u00f4le total<\/td>\n<td>Prend du temps et est sujet \u00e0 des erreurs<\/td>\n<\/tr>\n<tr>\n<td>Outils PAM GUI<\/td>\n<td>Facilit\u00e9 d&rsquo;utilisation<\/td>\n<td>Limit\u00e9 dans les environnements sans t\u00eate\/serveur<\/td>\n<\/tr>\n<tr>\n<td>Gestion des configurations (par exemple, Ansible)<\/td>\n<td>\u00c9volutif<\/td>\n<td>N\u00e9cessite une infrastructure et des scripts<\/td>\n<\/tr>\n<tr>\n<td><strong>Ce script Shell<\/strong><\/td>\n<td>L\u00e9ger, multiplateforme, facile \u00e0 sauvegarder<\/td>\n<td>N\u00e9cessite des connaissances de base en mati\u00e8re de racine et de Bash<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Ce\u00a0<strong>script shell de politique de mot de passe Linux<\/strong>\u00a0offre un \u00e9quilibre entre flexibilit\u00e9 et simplicit\u00e9, ce qui le rend id\u00e9al pour les \u00e9quipes informatiques qui ne disposent pas d&rsquo;une pile DevOps compl\u00e8te.<\/p>\n<h2>FAQ<\/h2>\n<h3>Question 1\u00a0: Ce script fonctionnera-t-il sur toutes les versions de Linux ?<\/h3>\n<p>Il prend en charge Debian 11+ et RHEL 8+ en particulier. Les distributions plus anciennes peuvent ne pas disposer de modules n\u00e9cessaires comme authselect.<\/p>\n<h3>Question 2\u00a0: Puis-je l&rsquo;utiliser dans une t\u00e2che cron pour une application p\u00e9riodique ?<\/h3>\n<p>Oui, mais soyez prudents. L&rsquo;\u00e9crasement r\u00e9p\u00e9t\u00e9 des politiques de mot de passe peut entra\u00eener des blocages inattendus s&rsquo;il n&rsquo;est pas test\u00e9 correctement.<\/p>\n<h3>Question 3\u00a0: Que se passe-t-il si je n&rsquo;ai pas\u00a0authconfig\u00a0ou\u00a0authselect ?<\/h3>\n<p>Le script se rabat gracieusement sur les modifications directes de PAM en utilisant \/etc\/pam.d\/common-auth et les fichiers connexes.<\/p>\n<h3>Question 4\u00a0: Un red\u00e9marrage est-il n\u00e9cessaire apr\u00e8s l&rsquo;ex\u00e9cution de ce programme ?<\/h3>\n<p>Non. Les modifications prennent effet imm\u00e9diatement pour les nouvelles sessions.<\/p>\n<h2>Implications<\/h2>\n<p>Des politiques de mot de passe mal configur\u00e9es peuvent soit affaiblir la s\u00e9curit\u00e9 (si elles sont trop laxistes), soit entraver la productivit\u00e9 des utilisateurs (si elles sont trop strictes). En automatisant ces param\u00e8tres, les administrateurs informatiques garantissent une base de s\u00e9curit\u00e9 dans leur environnement. De plus, la conservation de l&rsquo;historique des mots de passe et l&rsquo;application de politiques d&rsquo;expiration permettent de r\u00e9duire les vuln\u00e9rabilit\u00e9s telles que la r\u00e9utilisation des mots de passe et les attaques par force brute.<\/p>\n<p>Du point de vue de la conformit\u00e9, le script facilite le respect des normes CIS, PCI-DSS et <a href=\"https:\/\/www.ninjaone.com\/blog\/hipaa-compliance\/\">HIPAA<\/a>, qui exigent souvent des contr\u00f4les de vieillissement et de complexit\u00e9 des mots de passe.<\/p>\n<h2>Recommandations<\/h2>\n<ul>\n<li><strong>Testez dans un environnement d&rsquo;essai<\/strong>\u00a0avant de le d\u00e9ployer dans la production.<\/li>\n<li><strong>Utilisez le moteur de planification de NinjaOne<\/strong>\u00a0pour automatiser les audits p\u00e9riodiques.<\/li>\n<li><strong>Conservez des sauvegardes<\/strong>\u00a0des fichiers de configuration comme le fait le script.<\/li>\n<li><strong>Combinez avec les outils de surveillance des comptes<\/strong>\u00a0pour une approche compl\u00e8te de la s\u00e9curit\u00e9.<\/li>\n<li>Assurer la synchronisation de l&rsquo;heure entre les appareils pour une application pr\u00e9cise des politiques.<\/li>\n<\/ul>\n<h2>Conclusion<\/h2>\n<p>La gestion des politiques de mots de passe \u00e0 grande \u00e9chelle ne doit pas \u00eatre un probl\u00e8me. Avec ce\u00a0<strong>script shell de politique de mot de passe pour Linux<\/strong>, les \u00e9quipes informatiques et les MSP disposent d&rsquo;un moyen fiable et contr\u00f4l\u00e9 par version de mettre en \u0153uvre des normes de s\u00e9curit\u00e9 essentielles sur les syst\u00e8mes Linux distribu\u00e9s. Int\u00e9gr\u00e9 \u00e0\u00a0NinjaOne, ce script devient encore plus puissant. <a href=\"https:\/\/www.ninjaone.fr\/\" target=\"_blank\" rel=\"noopener\">NinjaOne<\/a> permet un d\u00e9ploiement transparent des scripts, une application centralis\u00e9e des politiques et des rapports de conformit\u00e9 en temps r\u00e9el, ce qui permet aux professionnels de l&rsquo;informatique de garder une longueur d&rsquo;avance sur l&rsquo;\u00e9volution des exigences en mati\u00e8re de s\u00e9curit\u00e9.<\/p>\n<p>En utilisant\u00a0<strong>shell scripting pour d\u00e9finir la politique de mot de passe pour les appareils Linux<\/strong>, vous <a href=\"https:\/\/www.ninjaone.com\/blog\/how-human-error-relates-to-cybersecurity-risks\/\">r\u00e9duisez l&rsquo;erreur humaine<\/a>, garantissez la coh\u00e9rence et renforcez consid\u00e9rablement vos terminaux. Cette approche est indispensable \u00e0 tout outil informatique moderne.<\/p>\n","protected":false},"author":35,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_relevanssi_hide_post":"","_relevanssi_hide_content":"","_relevanssi_pin_for_all":"","_relevanssi_pin_keywords":"","_relevanssi_unpin_keywords":"","_relevanssi_related_keywords":"","_relevanssi_related_include_ids":"","_relevanssi_related_exclude_ids":"","_relevanssi_related_no_append":"","_relevanssi_related_not_related":"","_relevanssi_related_posts":"","_relevanssi_noindex_reason":"","_lmt_disableupdate":"no","_lmt_disable":""},"operating_system":[4211],"use_cases":[4281],"class_list":["post-513821","script_hub","type-script_hub","status-publish","hentry","script_hub_category-linux","use_cases-configuration-generale"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/script_hub\/513821","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/script_hub"}],"about":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/types\/script_hub"}],"author":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/users\/35"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/comments?post=513821"}],"wp:attachment":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/media?parent=513821"}],"wp:term":[{"taxonomy":"script_hub_category","embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/operating_system?post=513821"},{"taxonomy":"use_cases","embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/use_cases?post=513821"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}