Dotfiles/setup/modules/FreeipaAnsible/ansible/policies.d/dev_ssh.sh

96 lines
3.4 KiB
Bash

#!/usr/bin/env bash
# policy: dev_ssh — distribute IPA user SSH public keys to authorized_keys.
# dev_ssh_<userid>: 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