#!/bin/bash # -- bash for arrays # Prepare pam, nss and sssd configs as appropriate export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin" declare -a auth declare -a account declare -a session declare -a nss declare -a dns # Add PAM and NSS modules for sssd add_sssd_modules() { auth+=("[success=%NUM% default=ignore] pam_sss.so use_first_pass") account+=("[success=%NUM% new_authtok_reqd=done default=ignore] pam_sss.so") nss+=("sss") # Skip sss if unix worked session+=("[success=1] pam_unix.so") session+=("optional pam_sss.so") } # Write a combined sssd config from all our /opt/openslx/pam/slx-ldap.d/* files write_sssd_config() { local file ok domains local tmpfile=$(mktemp) ok=0 domains= cat > "$tmpfile" <<-HERE # File generated $(date) -- # This file might get overwritten again as long as the above tag stays in it [sssd] config_file_version = 2 services = nss, pam domains = %DOMAIN_LIST% [nss] filter_users = root [pam] HERE for file in /opt/openslx/pam/slx-ldap.d/*; do [ -f "$file" ] || continue unset LDAP_ATTR_MOUNT_OPTS LDAP_URI LDAP_BASE SHARE_DOMAIN LDAP_CACERT . "$file" [ -z "$LDAP_URI" ] && continue [ -z "$LDAP_BASE" ] && continue ok=$(( ok + 1 )) domains="${domains}, dom$ok" cat >> "$tmpfile" <<-HERE [domain/dom$ok] id_provider = ldap auth_provider = ldap ldap_schema = rfc2307 ldap_user_email = bogusFieldName42 ldap_user_principal = bogusFieldName43 cache_credentials = true ldap_uri = $LDAP_URI ldap_search_base = $LDAP_BASE ldap_tls_reqcert = demand HERE [ -n "$LDAP_CACERT" ] && echo "ldap_tls_cacert = $LDAP_CACERT" >> "$tmpfile" done [ "$ok" = 0 ] && return 1 # No config mkdir -p "/etc/sssd" chmod 0755 "/etc/sssd" sed "s/%DOMAIN_LIST%/${domains#, }/" "${tmpfile}" > "/etc/sssd/sssd.conf" chmod 0600 "/etc/sssd/sssd.conf" rm -f -- "${tmpfile}" return 0 # OK } # unix auth+=("[success=%NUM% default=ignore] pam_unix.so nodelay") account+=("[success=%NUM% new_authtok_reqd=done default=ignore] pam_unix.so") nss+=("files" "cache") # Our plugin, but account ONLY since it's fast (it's not if not executed in root context so move after unix) account+=("[success=%NUM% new_authtok_reqd=done default=ignore] pam_exec.so quiet /opt/openslx/pam/exec_account") # check for bwIDM if [ -x "/opt/openslx/scripts/pam_bwidm" ]; then auth+=("[success=%NUM% default=ignore] pam_exec.so quiet expose_authtok /opt/openslx/scripts/pam_bwidm") account+=("[success=%NUM% new_authtok_reqd=done default=ignore] pam_exec.so quiet /opt/openslx/scripts/pam_bwidm") fi # Insert kerberos before our auth module if [ -s "/etc/krb5.conf" ]; then auth+=("optional pam_krb5.so minimum_uid=1000 use_first_pass ccache=FILE:/run/user/krb5cc_%u_XXXXXX ccname_template=FILE:/run/user/krb5cc_%U_XXXXXX") session+=("optional pam_krb5.so minimum_uid=1000") fi # Our plugin, auth now auth+=("[success=%NUM% default=ignore] pam_exec.so quiet expose_authtok /opt/openslx/pam/exec_auth") # sssd if reasonable if systemctl is-enabled -q sssd.service && grep -q -e '^\s*id_provider' -e '^\s*auth_provider' "/etc/sssd/sssd.conf" \ && ! grep -q -F '' "/etc/sssd/sssd.conf"; then # sssd is configured and doesn't have our marker - just add pam and nss config but leave sssd.conf alone add_sssd_modules elif ! systemctl show sssd.service | grep -q '^LoadError='; then # We have sssd available and unconfigured, or marked with our config tag, if write_sssd_config; then add_sssd_modules systemctl enable sssd.service systemctl restart --no-block sssd.service else # Nothing to configure, don't use sssd session+=("optional pam_unix.so") fi else session+=("optional pam_unix.so") fi # DNS dns+=("files" "cache") if systemctl is-enabled -q systemd-resolved; then dns+=("resolve") fi dns+=("dns") session+=("optional pam_exec.so quiet /opt/openslx/pam/exec_session") # # Write pam configs tmpfile=$(mktemp) # common-auth if grep -q '' "/etc/pam.d/common-auth"; then skip=$(( ${#auth[@]} + 1 )) echo "# Generated $(date)" > "$tmpfile" for line in "${auth[@]}"; do echo "auth ${line//%NUM%/$skip}" skip=$(( skip - 1 )) done >> "$tmpfile" cat >> "$tmpfile" <<-HERE auth optional pam_faildelay.so delay=2123123 auth requisite pam_deny.so auth optional pam_exec.so quiet /opt/openslx/pam/exec_auth_final auth required pam_permit.so auth optional pam_cap.so HERE cp -f -- "$tmpfile" "/etc/pam.d/common-auth" chmod 0644 "/etc/pam.d/common-auth" fi # common-account if grep -q '' "/etc/pam.d/common-account"; then skip=${#account[@]} echo "# Generated $(date)" > "$tmpfile" for line in "${account[@]}"; do echo "account ${line//%NUM%/$skip}" skip=$(( skip - 1 )) done >> "$tmpfile" cat >> "$tmpfile" <<-HERE account requisite pam_deny.so account required pam_permit.so HERE cp -f -- "$tmpfile" "/etc/pam.d/common-account" chmod 0644 "/etc/pam.d/common-account" fi # common-session if grep -q '' "/etc/pam.d/common-session"; then cat > "$tmpfile" <<-HERE # Generated $(date) session required pam_permit.so session optional pam_umask.so session required pam_systemd.so session optional pam_env.so readenv=1 session optional pam_env.so readenv=1 envfile=/etc/default/locale session optional pam_exec.so quiet /opt/openslx/pam/mkhome HERE for line in "${session[@]}"; do echo "session $line" done >> "$tmpfile" cp -f -- "$tmpfile" "/etc/pam.d/common-session" chmod 0644 "/etc/pam.d/common-session" fi # # Write nsswitch.conf if grep -q '' "/etc/nsswitch.conf"; then cat > "/etc/nsswitch.conf" <<-HERE # Generated $(date) passwd: ${nss[@]} group: ${nss[@]} shadow: files hosts: ${dns[@]} networks: files protocols: db files services: db files ethers: db files rpc: db files netgroup: nis HERE chmod 0644 "/etc/nsswitch.conf" fi rm -f -- "$tmpfile" exit 0