146 lines
5.4 KiB
Bash
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
|