Configure /etc/login.defs

Related-Prod: PROD-21969

Change-Id: I1c30189ee85605a5c68861d98f00bf5ac5e772c2
diff --git a/.gitignore b/.gitignore
index aa8e42a..cc3ab8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,8 @@
 .kitchen
+.bundle
+bundle/
 tests/build/
 *.swp
 *.pyc
 .ropeproject
+Gemfile*
diff --git a/README.rst b/README.rst
index 50e1b13..e4accd7 100644
--- a/README.rst
+++ b/README.rst
@@ -1629,6 +1629,23 @@
             export FTP_PROXY=ftp://127.0.3.3:2121
             export NO_PROXY='.local'
 
+
+Configure login.defs parameters
+-------------------------------
+
+.. code-block:: yaml
+
+    linux:
+      system:
+        login_defs:
+          <opt_name>:
+            enabled: true
+            value: <opt_value>
+
+<opt_name> is a configurational option defined in 'man login.defs'.
+<opt_name> is case sensitive, should be UPPERCASE only!
+
+
 Linux with hosts
 
 Parameter ``purge_hosts`` will enforce whole ``/etc/hosts file``,
diff --git a/linux/files/login.defs.jinja b/linux/files/login.defs.jinja
new file mode 100644
index 0000000..945d3cb
--- /dev/null
+++ b/linux/files/login.defs.jinja
@@ -0,0 +1,62 @@
+{%- from "linux/map.jinja" import login_defs with context -%}
+# This file is managed by Salt, do not edit
+{%- set allowed_options = [
+    'CHFN_RESTRICT',
+    'CONSOLE_GROUPS',
+    'CREATE_HOME',
+    'DEFAULT_HOME',
+    'ENCRYPT_METHOD',
+    'ENV_HZ',
+    'ENV_PATH',
+    'ENV_SUPATH',
+    'ERASECHAR',
+    'FAIL_DELAY',
+    'FAKE_SHELL',
+    'GID_MAX',
+    'GID_MIN',
+    'HUSHLOGIN_FILE',
+    'KILLCHAR',
+    'LOG_OK_LOGINS',
+    'LOG_UNKFAIL_ENAB',
+    'LOGIN_RETRIES',
+    'LOGIN_TIMEOUT',
+    'MAIL_DIR',
+    'MAIL_FILE',
+    'MAX_MEMBERS_PER_GROUP',
+    'MD5_CRYPT_ENAB',
+    'PASS_MAX_DAYS',
+    'PASS_MIN_DAYS',
+    'PASS_WARN_AGE',
+    'SHA_CRYPT_MIN_ROUNDS',
+    'SHA_CRYPT_MAX_ROUNDS',
+    'SULOG_FILE',
+    'SU_NAME',
+    'SUB_GID_MIN',
+    'SUB_GID_MAX',
+    'SUB_GID_COUNT',
+    'SUB_UID_MIN',
+    'SUB_UID_MAX',
+    'SUB_UID_COUNT',
+    'SYS_GID_MAX',
+    'SYS_GID_MIN',
+    'SYS_UID_MAX',
+    'SYS_UID_MIN',
+    'SYSLOG_SG_ENAB',
+    'SYSLOG_SU_ENAB',
+    'TTYGROUP',
+    'TTYPERM',
+    'TTYTYPE_FILE',
+    'UID_MAX',
+    'UID_MIN',
+    'UMASK',
+    'USERDEL_CMD',
+    'USEGROUPS_ENAB'
+] %}
+{%- for opt_name in allowed_options %}
+  {%- if opt_name in login_defs %}
+    {%- set opt_params = login_defs.get(opt_name) %}
+    {%- if opt_params.get('enabled', true) %}
+{{ opt_name.ljust(20) }} {{ opt_params.value }}
+    {%- endif %}
+  {%- endif %}
+{%- endfor %}
diff --git a/linux/map.jinja b/linux/map.jinja
index 52d0e70..4f8b5b7 100644
--- a/linux/map.jinja
+++ b/linux/map.jinja
@@ -140,6 +140,70 @@
     },
 }, grain='os_family', merge=salt['pillar.get']('linux:system:auth:ldap')) %}
 
+{%- load_yaml as login_defs_defaults %}
+Debian:
+    CHFN_RESTRICT:
+        value: 'rwh'
+    DEFAULT_HOME:
+        value: 'yes'
+    ENCRYPT_METHOD:
+        value: 'SHA512'
+    ENV_PATH:
+        value: 'PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games'
+    ENV_SUPATH:
+        value: 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
+    ERASECHAR:
+        value: '0177'
+    FAILLOG_ENAB:
+        value: 'yes'
+    FTMP_FILE:
+        value: '/var/log/btmp'
+    GID_MAX:
+        value: '60000'
+    GID_MIN:
+        value: '1000'
+    HUSHLOGIN_FILE:
+        value: '.hushlogin'
+    KILLCHAR:
+        value: '025'
+    LOGIN_RETRIES:
+        value: '5'
+    LOGIN_TIMEOUT:
+        value: '60'
+    LOG_OK_LOGINS:
+        value: 'no'
+    LOG_UNKFAIL_ENAB:
+        value: 'no'
+    MAIL_DIR:
+        value: '/var/mail'
+    PASS_MAX_DAYS:
+        value: '99999'
+    PASS_MIN_DAYS:
+        value: '0'
+    PASS_WARN_AGE:
+        value: '7'
+    SU_NAME:
+        value: 'su'
+    SYSLOG_SG_ENAB:
+        value: 'yes'
+    SYSLOG_SU_ENAB:
+        value: 'yes'
+    TTYGROUP:
+        value: 'tty'
+    TTYPERM:
+        value: '0600'
+    UID_MAX:
+        value: '60000'
+    UID_MIN:
+        value: '1000'
+    UMASK:
+        value: '022'
+    USERGROUPS_ENAB:
+        value: 'yes'
+{%- endload %}
+{%- set login_defs = salt['grains.filter_by'](login_defs_defaults,
+    grain='os_family', merge=salt['pillar.get']('linux:system:login_defs')) %}
+
 {#    'network_name', #}
 
 {% set interface_params = [
diff --git a/linux/system/init.sls b/linux/system/init.sls
index 4f97fa0..cec6c18 100644
--- a/linux/system/init.sls
+++ b/linux/system/init.sls
@@ -3,6 +3,9 @@
 include:
 - linux.system.env
 - linux.system.profile
+{%- if system.login_defs is defined %}
+- linux.system.login_defs
+{%- endif %}
 - linux.system.at
 - linux.system.cron
 {%- if system.repo|length > 0 %}
diff --git a/linux/system/login_defs.sls b/linux/system/login_defs.sls
new file mode 100644
index 0000000..f94348a
--- /dev/null
+++ b/linux/system/login_defs.sls
@@ -0,0 +1,13 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+  {%- if system.login_defs is defined %}
+login_defs:
+  file.managed:
+    - name: /etc/login.defs
+    - source: salt://linux/files/login.defs.jinja
+    - template: jinja
+    - user: root
+    - group: root
+    - mode: 644
+  {%- endif %}
+{%- endif %}
diff --git a/tests/pillar/system.sls b/tests/pillar/system.sls
index 0b792b6..aa1c7ed 100644
--- a/tests/pillar/system.sls
+++ b/tests/pillar/system.sls
@@ -407,6 +407,9 @@
         - .local
       LANG: C
       LC_ALL: C
+    login_defs:
+      PASS_MAX_DAYS:
+        value: 99
     profile:
       vi_flavors.sh: |
         export PAGER=view