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

146 lines
5.4 KiB
Bash

#!/usr/bin/env bash
# policy: usr_prt — per-user printer auto-add via FreeIPA usr_prt_<printer> groups.
# Printer URI stored in IPA group description (ipps://... or similar).
# Logged-in members get the printer added to CUPS; leaving the group revokes access.
PRT_STATE_DIR="$STATE_DIR/printer-users"
PRT_DEFS_DIR="$STATE_DIR/printer-defs"
PRT_PROFILED="/etc/profile.d/ansipa-printers.sh"
PRT_SUDO_DROPIN="/etc/sudoers.d/ansipa-printers-trigger"
mkdir -p "$PRT_STATE_DIR" "$PRT_DEFS_DIR"
_prt_read_users() {
local sf="$PRT_STATE_DIR/${1}.users"
[[ -f "$sf" ]] && grep -v '^$' "$sf" | sort -u || true
}
_prt_write_users() {
local printer="$1"; shift
if [[ $# -gt 0 ]]; then
printf '%s\n' "$@" | sort -u > "$PRT_STATE_DIR/${printer}.users"
else
> "$PRT_STATE_DIR/${printer}.users"
fi
}
_prt_apply_acl() {
local printer="$1"
local -a users
mapfile -t users < <(_prt_read_users "$printer")
if [[ ${#users[@]} -gt 0 ]]; then
local allow_list
allow_list=$(IFS=','; echo "${users[*]}")
lpadmin -p "$printer" -u "allow:${allow_list}" 2>/dev/null \
|| warn "lpadmin ACL update failed for printer $printer"
else
lpadmin -x "$printer" 2>/dev/null \
&& log "Removed printer $printer (no authorized users remaining)" \
|| warn "lpadmin -x failed for printer $printer"
rm -f "$PRT_STATE_DIR/${printer}.users"
fi
}
_prt_is_active() {
local needle="$1"
for _ap in "${ACTIVE_PRT_PRINTERS[@]+"${ACTIVE_PRT_PRINTERS[@]}"}"; do
[[ "$_ap" == "$needle" ]] && return 0
done
return 1
}
if command -v lpadmin &>/dev/null; then
for _i in "${!ACTIVE_PRT_PRINTERS[@]}"; do
_PRT="${ACTIVE_PRT_PRINTERS[$_i]}"
_GRP="${ACTIVE_PRT_GROUPS[$_i]}"
_URI=$(ipa group-show "$_GRP" --all 2>/dev/null \
| awk -F': ' '/Description:/{print $2; exit}' \
| grep -E '^[a-z][a-z+.-]+://' || true)
if [[ -z "$_URI" ]]; then
warn "Group $_GRP has no printer URI in its description — set it with:"
warn " ipa group-mod $_GRP --desc='ipps://printserver/printers/$_PRT'"
continue
fi
echo "$_URI" > "$PRT_DEFS_DIR/${_GRP}.uri"
mapfile -t _CUR_USERS < <(_prt_read_users "$_PRT")
_UPDATED=false
while IFS= read -r _LUSER; do
[[ -z "$_LUSER" ]] && continue
id -Gn "$_LUSER" 2>/dev/null | tr ' ' '\n' | grep -qxF "$_GRP" || continue
printf '%s\n' "${_CUR_USERS[@]+"${_CUR_USERS[@]}"}" | grep -qxF "$_LUSER" && continue
if ! lpstat -p "$_PRT" &>/dev/null; then
log "Adding printer $_PRT (URI: $_URI)"
lpadmin -p "$_PRT" -v "$_URI" -m everywhere -E 2>/dev/null \
|| lpadmin -p "$_PRT" -v "$_URI" -E 2>/dev/null \
|| { warn "lpadmin failed to add printer $_PRT"; continue; }
fi
log "Granting printer $_PRT access to $_LUSER"
_CUR_USERS+=("$_LUSER")
_UPDATED=true
done < <(who -u 2>/dev/null | awk '{print $1}' | sort -u)
_VALID_USERS=()
for _U in "${_CUR_USERS[@]+"${_CUR_USERS[@]}"}"; do
if id -Gn "$_U" 2>/dev/null | tr ' ' '\n' | grep -qxF "$_GRP"; then
_VALID_USERS+=("$_U")
else
log "Revoking printer $_PRT access for $_U (no longer in $_GRP)"
_UPDATED=true
fi
done
if [[ "$_UPDATED" == true ]]; then
_prt_write_users "$_PRT" "${_VALID_USERS[@]+"${_VALID_USERS[@]}"}"
_prt_apply_acl "$_PRT"
fi
done
unset _i _PRT _GRP _URI _LUSER _U _CUR_USERS _VALID_USERS _UPDATED _ap
# Remove printers whose IPA group was deleted.
shopt -s nullglob
for _sf in "$PRT_STATE_DIR"/*.users; do
[[ -f "$_sf" ]] || continue
_PRT=$(basename "$_sf" .users)
_prt_is_active "$_PRT" && continue
log "Removing printer $_PRT (IPA group usr_prt_$_PRT deleted)"
lpadmin -x "$_PRT" 2>/dev/null || true
rm -f "$_sf"
done
shopt -u nullglob
unset _sf _PRT
if [[ ${#ACTIVE_PRT_PRINTERS[@]} -gt 0 ]]; then
if [[ ! -f "$PRT_SUDO_DROPIN" ]]; then
log "Installing ansipa-printers sudo trigger rule"
printf 'ALL ALL=(root) NOPASSWD: /usr/bin/systemctl start ansipa-enforce-policies.service\n' \
> "$PRT_SUDO_DROPIN"
chmod 440 "$PRT_SUDO_DROPIN"
fi
if [[ ! -f "$PRT_PROFILED" ]]; then
log "Installing /etc/profile.d/ansipa-printers.sh"
cat > "$PRT_PROFILED" <<'PROFILED'
# ansipa-printers: trigger policy enforcer at login to auto-add printers.
# Managed by ansipa-enforce-policies — do not edit manually.
sudo -n /usr/bin/systemctl start ansipa-enforce-policies.service 2>/dev/null &
disown 2>/dev/null || true
PROFILED
chmod 644 "$PRT_PROFILED"
fi
else
if [[ -f "$PRT_SUDO_DROPIN" ]]; then
rm -f "$PRT_SUDO_DROPIN"
log "Removed ansipa-printers sudo trigger (no active printer groups)"
fi
if [[ -f "$PRT_PROFILED" ]]; then
rm -f "$PRT_PROFILED"
log "Removed /etc/profile.d/ansipa-printers.sh (no active printer groups)"
fi
fi
else
[[ ${#ACTIVE_PRT_PRINTERS[@]} -gt 0 ]] && \
warn "lpadmin not found — install cups to enforce printer policies"
fi
unset _ap