#!/usr/bin/env bash # policy: dev_ssh — distribute IPA user SSH public keys to authorized_keys. # dev_ssh_: writes the IPA user's keys in an ansipa-managed section. # Leaving the host-group removes only the ansipa section; manual keys are preserved. SSH_KEY_STATE="$STATE_DIR/ssh-keys" [[ -f "$SSH_KEY_STATE" ]] || touch "$SSH_KEY_STATE" _ssh_write_keys() { local _u="$1" _h="$2"; shift 2 local _auth="$_h/.ssh/authorized_keys" mkdir -p "$_h/.ssh" chmod 700 "$_h/.ssh" [[ -f "$_auth" ]] || touch "$_auth" local _rest _rest=$(awk ' /^# BEGIN ansipa-ssh-managed$/ { skip=1; next } skip && /^# END ansipa-ssh-managed$/ { skip=0; next } !skip ' "$_auth" 2>/dev/null || true) if [[ $# -gt 0 ]]; then { [[ -n "$_rest" ]] && printf '%s\n' "$_rest"; \ echo "# BEGIN ansipa-ssh-managed"; \ printf '%s\n' "$@"; \ echo "# END ansipa-ssh-managed"; } > "$_auth" else [[ -n "$_rest" ]] && printf '%s\n' "$_rest" > "$_auth" || > "$_auth" fi chmod 600 "$_auth" chown "$_u:$_u" "$_h/.ssh" "$_auth" 2>/dev/null || true } declare -A _SSH_APPLIED for _SSH_UID in "${ACTIVE_SSH_USERS[@]+"${ACTIVE_SSH_USERS[@]}"}"; do ipa user-show "$_SSH_UID" &>/dev/null || { warn "dev_ssh_${_SSH_UID}: IPA user '$_SSH_UID' not found — skipping" continue } _SSH_KEYS=() mapfile -t _SSH_KEYS < <( ipa user-show "$_SSH_UID" --all 2>/dev/null \ | grep "^ SSH public key:" | grep -v "fingerprint" \ | sed 's/^ SSH public key: //' || true ) if [[ ${#_SSH_KEYS[@]} -eq 0 ]]; then warn "dev_ssh_${_SSH_UID}: '$_SSH_UID' has no SSH keys in IPA — add via:" warn " ipa user-mod $_SSH_UID --sshpubkey='ssh-ed25519 AAAA...'" continue fi _SSH_HOME=$(getent passwd "$_SSH_UID" 2>/dev/null | cut -d: -f6 || true) if [[ -z "$_SSH_HOME" ]]; then warn "dev_ssh_${_SSH_UID}: '$_SSH_UID' not resolvable via getent — is SSSD running?" continue fi if [[ ! -d "$_SSH_HOME" ]]; then log "Creating home dir for $_SSH_UID: $_SSH_HOME" mkdir -p "$_SSH_HOME" chown "$_SSH_UID:$_SSH_UID" "$_SSH_HOME" 2>/dev/null || true chmod 700 "$_SSH_HOME" fi _ssh_write_keys "$_SSH_UID" "$_SSH_HOME" "${_SSH_KEYS[@]}" log "SSH keys for $_SSH_UID: ${#_SSH_KEYS[@]} key(s) written to $_SSH_HOME/.ssh/authorized_keys" _SSH_APPLIED["$_SSH_UID"]=1 grep -qxF "$_SSH_UID" "$SSH_KEY_STATE" 2>/dev/null || echo "$_SSH_UID" >> "$SSH_KEY_STATE" done unset _SSH_UID _SSH_KEYS _SSH_HOME # Revert: remove ansipa keys for users whose dev_ssh_* group was removed from this host. _NEW_SSH_STATE=() while IFS= read -r _OLD_SSH_UID; do [[ -z "$_OLD_SSH_UID" ]] && continue if [[ -n "${_SSH_APPLIED[$_OLD_SSH_UID]+x}" ]]; then _NEW_SSH_STATE+=("$_OLD_SSH_UID") else _OLD_SSH_HOME=$(getent passwd "$_OLD_SSH_UID" 2>/dev/null | cut -d: -f6 || true) if [[ -n "$_OLD_SSH_HOME" ]]; then _ssh_write_keys "$_OLD_SSH_UID" "$_OLD_SSH_HOME" log "Removed ansipa SSH keys for $_OLD_SSH_UID (host left dev_ssh_${_OLD_SSH_UID})" fi fi done < "$SSH_KEY_STATE" unset _OLD_SSH_UID _OLD_SSH_HOME if [[ ${#_NEW_SSH_STATE[@]} -gt 0 ]]; then printf '%s\n' "${_NEW_SSH_STATE[@]}" | sort -u > "$SSH_KEY_STATE" else > "$SSH_KEY_STATE" fi unset _SSH_APPLIED _NEW_SSH_STATE