Как восстановить принадлежность группы / пользователя по умолчанию ко всем файлам в / var?

13

Я случайно изменил /varвладельца / группу на свое имя пользователя, а затем изменил его обратно на root, но не все /varвладельцы папок являются корневыми, поэтому есть ли способ вернуть обратно владельца / группу файлов / папок в состояние по умолчанию? Или хотя бы те файлы / папки, которые создаются пакетами?

Sepehr
источник
2
Отредактировано, потому что ваш общий вопрос был точной копией Как вернуть chownкоманду? и был бы закрыт.
jw013
Кажется, есть некоторые способы исправить это, как этот, но не только для / var, а не только для дистрибутивов, основанных на rpm.
сентября
В каком дистрибутиве вы работаете?
Дероберт
Тестирование Debian @derobert aka wheezy
Sepehr

Ответы:

6

Подобно одному из ответов выше, если у вас есть копия каталога с правильными разрешениями с именем «var» в вашем локальном каталоге, вы можете использовать следующие две команды для восстановления разрешений для каталога / var.

sudo find var -exec chown --reference="{}" "/{}" \;
sudo find var -exec chmod --reference="{}" "/{}" \;
Натан Бюгенс
источник
10

Самый простой (и, вероятно, самый правильный) ответ - «Вы не можете», но если вы хотите попробовать, вот скрипт bash, который исправит права доступа к файлам в / var, принадлежащим пакетам .deb.

ПРИМЕЧАНИЯ:

  • это не исправит перми для файлов, не принадлежащих пакету.
  • он не исправляет права доступа для файлов, в которых пакет больше не доступен для загрузки с помощью apt-get - например, устаревшие или сторонние пакеты.
  • AFAIK, ни один файл в пакетах debian не имеет вкладок в имени файла, поэтому я использовал TAB в качестве IFS для цикла while-read. Я проверил Contents-amd64.gz и Contents-i386.gz на наличие Debian sid и подтвердил, что вкладок нет, но сторонние пакеты могут иметь некоторые.

Сценарий работает, генерируя список установленных пакетов с файлами в var, загружая эти пакеты, а затем используя, dpkg-deb -cчтобы узнать, какими должны быть разрешения.

Самым сложным было написание функции для преобразования строки разрешений (отображаемой с помощью ls -lили tar v) в восьмеричный числовой режим, включая обработку setuid, setgid и sticky-битов ... некоторые вещи, которые было бы легко написать с помощью хорошего алгоритма скажем, в Perl слишком много проблем в bash, так что проще просто перебрать его.

Наконец, сценарий написан в режиме «отладки» или «пробном запуске». Чтобы это действительно изменило владельца / группу / администрацию, закомментируйте или удалите две строки с указанными __EOF__здесь маркерами документа.

#! /bin/bash

perm_string_to_mode() {
  string="$1"
  let perms=0

  [[ "${string}" = ?r???????? ]] && perms=$(( perms +  400 ))
  [[ "${string}" = ??w??????? ]] && perms=$(( perms +  200 ))
  [[ "${string}" = ???x?????? ]] && perms=$(( perms +  100 ))
  [[ "${string}" = ???s?????? ]] && perms=$(( perms + 4100 ))
  [[ "${string}" = ???S?????? ]] && perms=$(( perms + 4000 ))
  [[ "${string}" = ????r????? ]] && perms=$(( perms +   40 ))
  [[ "${string}" = ?????w???? ]] && perms=$(( perms +   20 ))
  [[ "${string}" = ??????x??? ]] && perms=$(( perms +   10 ))
  [[ "${string}" = ??????s??? ]] && perms=$(( perms + 2010 ))
  [[ "${string}" = ??????S??? ]] && perms=$(( perms + 2000 ))
  [[ "${string}" = ???????r?? ]] && perms=$(( perms +    4 ))
  [[ "${string}" = ????????w? ]] && perms=$(( perms +    2 ))
  [[ "${string}" = ?????????x ]] && perms=$(( perms +    1 ))
  [[ "${string}" = ?????????t ]] && perms=$(( perms + 1001 ))
  [[ "${string}" = ?????????T ]] && perms=$(( perms + 1000 ))

  echo $perms
}

# generate a list of installed packages that have files etc in /var
grep -l /var/ /var/lib/dpkg/info/*.list  | \
  sed -e 's:/var/lib/dpkg/info/::' -e 's/\.list$//' | \
  xargs dpkg -l | \
  awk '/^[hi]/ {print $2}' > /tmp/packages.list

# clean out the apt cache, so we only have one version of each package
apt-get clean

# download the packages as if we were going to reinstall them
# NOTE: packages which are no longer available for download
# will not have their permissions fixed.  apt-get will complain about
# those packages, so you can get a list by redirecting or tee-ing the
# output of this script.
xargs apt-get -y -d -u --reinstall install < /tmp/packages.list

for pkg in $(cat /tmp/packages.list) ; do
   PKGFILE="/var/cache/apt/archives/${pkg}_*.deb"

   if [ -e $PKGFILE ] ; then

     dpkg-deb -c /var/cache/apt/archives/${pkg}_*.deb | \
       awk '/\.\/var\// {print $1, $2, $6}' | \
       sed -e 's/ /\t/' -e 's/ /\t' | \
       while IFS=$'\t' read permstring ownergroup filename ; do
          # don't change owner/group/perms on symlinks
          if ! [[ "${permstring}" =~ ^l ]] ; then
            mode=$(perm_string_to_mode $permstring)
            # change "owner/group" to "owner:group" for chown
            ownergroup=${ownergroup//\//:}
            # remove leading '.' from filename
            filename=${filename#?}
cat <<__EOF__
            chown "$ownergroup" "$filename"
            chmod "$mode" "$filename"
__EOF__ 
         fi
       done
     echo
   fi
done

Конечно, сценарий может быть довольно легко адаптирован для исправления ограничений в упакованных файлах в любом другом каталоге или во всех каталогах.

Этот сценарий был бы намного проще, если бы у файлов $ packagename.list в файле /var/lib/dpkg/infoбыли имя владельца, группа и восьмеричное число, а также имя файла ... но они этого не делают.

саз
источник
1
Ницца. Кроме того, вы можете заменить ваш grep через * .list на dpkg -S /var. Также после применения этого скрипта нужно проверить dpkg-statoverride --list '/var/*'.
Дероберт
Правда, но dpkg -Sмедленно (вот почему я написал dlocate). Хороший вопрос dpkg-statoverride, хотя .... и выходной формат идеален.
Cas
1
Спасибо за сценарий. В одном из вызовов sed есть опечатка, в которой пробел заменен на tab, в нем отсутствует последний символ '/'. (и пока мы на этом, почему бы просто не написать: sed -e 's / + / \ t / g' | \
Chelmite
3

Вы могли бы.

Установите тот же дистрибутив на другую машину или виртуальную машину и используйте chmod --referдля синхронизации разрешения для/var

маргаритка
источник
1

Простой ответ: «Вы не можете».

Но .... если у вас есть файловая система, такая как JFS, в которой есть журнал, вы можете восстановить его с помощью инструментов. Некоторые менеджеры пакетов позволяют переустановить их пакеты, и, возможно, таким образом вы сможете восстановить владельца файла.

Другой способ, но более обременительный, заключается в том, что вы можете смонтировать / var на другом устройстве, а затем программы воссоздают отсутствующий каталог.

Привет Сой Эду Фелиз Навидад
источник