86 lines
4.0 KiB
Bash
86 lines
4.0 KiB
Bash
#!/usr/bin/env bash
|
|
# policy: usr_ctl_netman — grant specific IPA users the ability to modify this
|
|
# device's NON-WI-FI NetworkManager connections (IP address, gateway, DNS,
|
|
# routes, etc.) — NOT a blanket sudo/root grant, and deliberately NOT extended
|
|
# to Wi-Fi connections (see usr_ctl_wifi for that, kept separate on purpose).
|
|
#
|
|
# Mechanism: NetworkManager already lets a connection's designated non-root
|
|
# "permitted user" modify/activate THAT connection without a password
|
|
# (org.freedesktop.NetworkManager.settings.modify.own — allowed for local
|
|
# users by default on every mainstream distro's polkit rules). This policy
|
|
# adds the member to the `connection.permissions` list of every EXISTING
|
|
# non-Wi-Fi connection; Wi-Fi connections are left completely untouched, so
|
|
# a member can repoint the wired IP/gateway but cannot touch Wi-Fi settings.
|
|
#
|
|
# Requires: NetworkManager (nmcli) on the client.
|
|
# Note: applies to connections that exist at enforcement time; a brand-new
|
|
# wired connection created afterwards is picked up on the next 30-min tick.
|
|
# Users can already create/manage their OWN new connections by default
|
|
# (standard NetworkManager multi-user behavior) — this policy is specifically
|
|
# about granting access to EXISTING, previously root-owned connections.
|
|
|
|
NETMAN_STATE="$STATE_DIR/netman-acl-users"
|
|
[[ -f "$NETMAN_STATE" ]] || touch "$NETMAN_STATE"
|
|
|
|
if ! command -v nmcli &>/dev/null; then
|
|
warn "usr_ctl_netman: nmcli not found (NetworkManager not installed) — skipping"
|
|
else
|
|
_netman_grp_exists=false
|
|
grep -qxF "usr_ctl_netman" <<< "$_ALL_USER_GROUPS" && _netman_grp_exists=true
|
|
|
|
_NETMAN_USERS=()
|
|
if [[ "$_netman_grp_exists" == true ]]; then
|
|
while IFS= read -r _u; do
|
|
[[ -z "$_u" ]] && continue
|
|
_NETMAN_USERS+=("$_u")
|
|
done < <(_ipa_group_member_users usr_ctl_netman)
|
|
fi
|
|
|
|
_netman_in_desired() {
|
|
local n="$1"
|
|
for _d in "${_NETMAN_USERS[@]+"${_NETMAN_USERS[@]}"}"; do [[ "$_d" == "$n" ]] && return 0; done
|
|
return 1
|
|
}
|
|
|
|
# Every current non-Wi-Fi connection UUID (ethernet, bridge, bond, vlan, ...).
|
|
_NON_WIFI_UUIDS=()
|
|
while IFS=: read -r _type _uuid; do
|
|
[[ -z "$_uuid" ]] && continue
|
|
[[ "$_type" == "wifi" || "$_type" == "802-11-wireless" ]] && continue
|
|
_NON_WIFI_UUIDS+=("$_uuid")
|
|
done < <(nmcli -t -f TYPE,UUID connection show 2>/dev/null)
|
|
|
|
# Grant: add each desired user to every non-Wi-Fi connection's permissions.
|
|
for _u in "${_NETMAN_USERS[@]+"${_NETMAN_USERS[@]}"}"; do
|
|
getent passwd "$_u" &>/dev/null || continue
|
|
for _uuid in "${_NON_WIFI_UUIDS[@]+"${_NON_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_netman: granted $_u modify access to connection $_uuid"
|
|
fi
|
|
done
|
|
done
|
|
|
|
# Revert: strip any previously-granted user from every non-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 ! _netman_in_desired "$_old_u"; then
|
|
for _uuid in "${_NON_WIFI_UUIDS[@]+"${_NON_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_netman: revoked $_old_u network-modify access (left usr_ctl_netman)"
|
|
fi
|
|
done < "$NETMAN_STATE"
|
|
|
|
if [[ ${#_NETMAN_USERS[@]} -gt 0 ]]; then
|
|
printf '%s\n' "${_NETMAN_USERS[@]}" | sort -u > "$NETMAN_STATE"
|
|
else
|
|
> "$NETMAN_STATE"
|
|
fi
|
|
unset _netman_grp_exists _NETMAN_USERS _NON_WIFI_UUIDS _u _uuid _perms _old_u
|
|
fi
|