gitee.com/mysnapcore/mysnapd@v0.1.0/cmd/snap-mgmt/snap-mgmt-selinux.sh.in (about)

     1  #!/bin/bash
     2  
     3  set -e
     4  set +x
     5  
     6  SNAP_MOUNT_DIR="@SNAP_MOUNT_DIR@"
     7  
     8  show_help() {
     9      exec cat <<'EOF'
    10  Usage: snap-mgmt-selinux.sh [OPTIONS]
    11  
    12  A helper script to manage SELinux contexts used by snapd
    13  
    14  Arguments:
    15    --snap-mount-dir=<path>                   Provide a path to be used as $SNAP_MOUNT_DIR
    16    --patch-selinux-mount-context=<context>   Add SELinux context to mount units
    17    --remove-selinux-mount-context=<context>  Remove SELinux context from mount units
    18  EOF
    19  }
    20  
    21  SNAP_UNIT_PREFIX="$(systemd-escape -p ${SNAP_MOUNT_DIR})"
    22  
    23  patch_selinux_mount_context() {
    24      if ! command -v selinuxenabled > /dev/null; then
    25          return
    26      fi
    27      if ! selinuxenabled; then
    28          # The tools are there, but SELinux is not enabled
    29          return
    30      fi
    31  
    32      selinux_mount_context="$1"
    33      remove="$2"
    34      if ! echo "$selinux_mount_context" | grep -qE '[a-zA-Z0-9_]+(:[a-zA-Z0-9_]+){2,3}'; then
    35          echo "invalid mount context '$selinux_mount_context'"
    36          exit 1
    37      fi
    38      context_opt="context=$selinux_mount_context"
    39  
    40      mounts=$(systemctl list-unit-files --no-legend --full "$SNAP_UNIT_PREFIX-*.mount" | cut -f1 -d ' ' || true)
    41      changed_mounts=
    42      for unit in $mounts; do
    43          # Ensure its really a snap mount unit or systemd unit
    44          if ! grep -q 'What=/var/lib/snapd/snaps/' "/etc/systemd/system/$unit" && ! grep -q 'X-Snappy=yes' "/etc/systemd/system/$unit"; then
    45              echo "Skipping non-snapd systemd unit $unit"
    46              continue
    47          fi
    48  
    49          if [ "$remove" == "" ]; then
    50              if grep -q "Options=.*,$context_opt" < "/etc/systemd/system/$unit"; then
    51                  # already patched
    52                  continue
    53              fi
    54  
    55              if ! sed -i -e "s#^\\(Options=nodev.*\\)#\\1,$context_opt#" "/etc/systemd/system/$unit"; then
    56                  echo "Cannot patch $unit"
    57              fi
    58  
    59              changed_mounts="$changed_mounts $unit"
    60          elif [ "$remove" == "remove" ]; then
    61              if ! grep -q "Options=.*,$context_opt" < "/etc/systemd/system/$unit"; then
    62                  # Not patched
    63                  continue
    64              fi
    65  
    66              if ! sed -i -e "s#^\\(Options=nodev.*\\),$context_opt\\(,.*\\)\\?#\\1\\2#" "/etc/systemd/system/$unit"; then
    67                  echo "Cannot patch $unit"
    68              fi
    69  
    70              changed_mounts="$changed_mounts $unit"
    71          fi
    72      done
    73  
    74      if [ -z "$changed_mounts" ]; then
    75          # Nothing changed, no need to reload
    76          return
    77      fi
    78  
    79      systemctl daemon-reload
    80  
    81      for unit in $changed_mounts; do
    82          if ! systemctl try-restart "$unit" ; then
    83              echo "Cannot restart $unit"
    84          fi
    85      done
    86  }
    87  
    88  while [ -n "$1" ]; do
    89      case "$1" in
    90          --help)
    91              show_help
    92              exit
    93              ;;
    94          --snap-mount-dir=*)
    95              SNAP_MOUNT_DIR=${1#*=}
    96              SNAP_UNIT_PREFIX=$(systemd-escape -p "$SNAP_MOUNT_DIR")
    97              shift
    98              ;;
    99          --patch-selinux-mount-context=*)
   100              patch_selinux_mount_context "${1#*=}"
   101              shift
   102              ;;
   103          --remove-selinux-mount-context=*)
   104              patch_selinux_mount_context "${1#*=}" remove
   105              shift
   106              ;;
   107          *)
   108              echo "Unknown command: $1"
   109              exit 1
   110              ;;
   111      esac
   112  done