96 lines
3.4 KiB
Bash
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
|