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

82 lines
3.5 KiB
Bash

#!/usr/bin/env bash
# policy: usr_ctl_wifi — grant specific IPA users the ability to modify this
# device's Wi-Fi NetworkManager connections (SSID, PSK/security, etc.). Kept
# as its own group deliberately separate from usr_ctl_netman (wired IP/gateway
# control) — a user can be in either, both, or neither.
#
# Mechanism: identical to usr_ctl_netman but filtered to ONLY Wi-Fi
# connections — adds the member to `connection.permissions` on every existing
# Wi-Fi connection, relying on NetworkManager's own
# org.freedesktop.NetworkManager.settings.modify.own polkit rule (allowed for
# local users by default) to let them edit/activate those connections without
# a password. Wired/other connections are left completely untouched.
#
# Requires: NetworkManager (nmcli) on the client.
# Note: applies to connections that exist at enforcement time; a brand-new
# Wi-Fi connection created afterwards is picked up on the next 30-min tick.
WIFI_STATE="$STATE_DIR/wifi-acl-users"
[[ -f "$WIFI_STATE" ]] || touch "$WIFI_STATE"
if ! command -v nmcli &>/dev/null; then
warn "usr_ctl_wifi: nmcli not found (NetworkManager not installed) — skipping"
else
_wifi_grp_exists=false
grep -qxF "usr_ctl_wifi" <<< "$_ALL_USER_GROUPS" && _wifi_grp_exists=true
_WIFI_USERS=()
if [[ "$_wifi_grp_exists" == true ]]; then
while IFS= read -r _u; do
[[ -z "$_u" ]] && continue
_WIFI_USERS+=("$_u")
done < <(_ipa_group_member_users usr_ctl_wifi)
fi
_wifi_in_desired() {
local n="$1"
for _d in "${_WIFI_USERS[@]+"${_WIFI_USERS[@]}"}"; do [[ "$_d" == "$n" ]] && return 0; done
return 1
}
# Every current Wi-Fi connection UUID.
_WIFI_UUIDS=()
while IFS=: read -r _type _uuid; do
[[ -z "$_uuid" ]] && continue
[[ "$_type" == "wifi" || "$_type" == "802-11-wireless" ]] || continue
_WIFI_UUIDS+=("$_uuid")
done < <(nmcli -t -f TYPE,UUID connection show 2>/dev/null)
# Grant: add each desired user to every Wi-Fi connection's permissions.
for _u in "${_WIFI_USERS[@]+"${_WIFI_USERS[@]}"}"; do
getent passwd "$_u" &>/dev/null || continue
for _uuid in "${_WIFI_UUIDS[@]+"${_WIFI_UUIDS[@]}"}"; do
_perms=$(nmcli -t -g connection.permissions connection show "$_uuid" 2>/dev/null)
if [[ "$_perms" != *"user:${_u}:"* ]]; then
nmcli connection modify "$_uuid" +connection.permissions "user:${_u}:" &>/dev/null \
&& log "usr_ctl_wifi: granted $_u modify access to Wi-Fi connection $_uuid"
fi
done
done
# Revert: strip any previously-granted user from every Wi-Fi connection
# once they're no longer in the group (or the group is gone).
while IFS= read -r _old_u; do
[[ -z "$_old_u" ]] && continue
if ! _wifi_in_desired "$_old_u"; then
for _uuid in "${_WIFI_UUIDS[@]+"${_WIFI_UUIDS[@]}"}"; do
_perms=$(nmcli -t -g connection.permissions connection show "$_uuid" 2>/dev/null)
[[ "$_perms" == *"user:${_old_u}:"* ]] && \
nmcli connection modify "$_uuid" -connection.permissions "user:${_old_u}:" &>/dev/null
done
log "usr_ctl_wifi: revoked $_old_u Wi-Fi-modify access (left usr_ctl_wifi)"
fi
done < "$WIFI_STATE"
if [[ ${#_WIFI_USERS[@]} -gt 0 ]]; then
printf '%s\n' "${_WIFI_USERS[@]}" | sort -u > "$WIFI_STATE"
else
> "$WIFI_STATE"
fi
unset _wifi_grp_exists _WIFI_USERS _WIFI_UUIDS _u _uuid _perms _old_u
fi