Comment restaurer la propriété par défaut du groupe / utilisateur de tous les fichiers sous / var?

13

J'ai accidentellement changé le /varpropriétaire / groupe en mon nom d'utilisateur, puis je l'ai changé à nouveau en tant que root, mais tous les /varpropriétaires des dossiers ne sont pas root. Ou au moins les fichiers / dossiers créés par les packages?

sepehr
la source
2
Modifié parce que votre question générale était un double exact de la commande Comment revenir à la chowncommande? et aurait été fermé.
jw013
Il semble qu'il existe des moyens de résoudre ce problème comme celui-ci, mais pas seulement pour / var et pas seulement pour les distributions basées sur rpm.
sepehr
Quelle distribution utilisez-vous?
derobert
@derobert debian testing aka wheezy
sepehr

Réponses:

6

Semblable à l'une des réponses ci-dessus, si vous avez une copie du répertoire avec les autorisations correctes nommées «var» dans votre répertoire local, vous pouvez utiliser les deux commandes suivantes pour restaurer les autorisations dans le répertoire / var.

sudo find var -exec chown --reference="{}" "/{}" \;
sudo find var -exec chmod --reference="{}" "/{}" \;
Nathan Buesgens
la source
10

La réponse la plus simple (et probablement la plus correcte) est "Vous ne pouvez pas", mais si vous voulez essayer, voici un script bash qui corrigera les autorisations des fichiers sous / var appartenant aux packages .deb.

REMARQUES:

  • il ne corrigera pas les perms pour les fichiers n'appartenant pas à un package.
  • il ne corrigera pas les perms pour les fichiers où le package n'est plus disponible au téléchargement par apt-get - par exemple les packages hérités ou tiers.
  • AFAIK, aucun fichier dans les paquets Debian n'a d'onglets dans le nom de fichier, j'ai donc utilisé TAB comme IFS pour la boucle en lecture. J'ai vérifié Contents-amd64.gz et Contents-i386.gz pour le debian sid et confirmé qu'il n'y a pas d'onglets, mais les paquets tiers peuvent en avoir.

Le script fonctionne en générant une liste des packages installés qui ont des fichiers en var, en téléchargeant ces packages, puis en les utilisant dpkg-deb -cpour savoir quelles devraient être les autorisations.

La partie la plus difficile a été d'écrire la fonction pour convertir la chaîne d'autorisations (telle qu'affichée par ls -lou tar v) en mode numérique octal, y compris la restauration de setuid, setgid et des bits collants .... certaines choses qui seraient faciles à écrire avec un algorithme agréable dans, disons, perl pose trop de problèmes dans bash, il est donc plus facile de simplement le forcer brutalement.

Enfin, le script est écrit pour être en mode "debug-mode" ou "dry-run". Pour qu'il change réellement le propriétaire / groupe / perms, mettez en commentaire ou supprimez les deux lignes avec les __EOF__marqueurs de document ici dessus.

#! /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

Le script pourrait, bien sûr, être assez facilement adapté pour corriger les perms de fichiers empaquetés dans n'importe quel autre répertoire, ou dans tous les répertoires.

Ce script aurait été beaucoup plus simple si les fichiers $ packagename.list en /var/lib/dpkg/infoavaient le propriétaire, le groupe et les autorisations octales ainsi que le nom de fichier ... mais ils n'en ont pas.

cas
la source
1
Agréable. Vous pouvez également remplacer votre grep via * .list par dpkg -S /var. De plus, après avoir appliqué ce script, il faut vérifier dpkg-statoverride --list '/var/*'.
derobert
C'est vrai, mais dpkg -Sc'est lent (c'est pourquoi j'ai écrit dlocate). Bon point dpkg-statoverridecependant ... et le format de sortie est parfait.
cas
1
Merci pour le script. Il y a une faute de frappe dans l'une des invocations sed, où le blanc est changé en tab, il manque le '/' final. (et tant que nous y sommes, pourquoi ne pas simplement écrire: sed -e 's / + / \ t / g' | \
Chelmite
3

Vous pourriez.

Installez la même distribution sur une autre machine ou une machine virtuelle et utilisez le chmod --referpour synchroniser les autorisations pour/var

Marguerite
la source
1

La réponse simple est "vous ne pouvez pas".

Mais .... si vous avez un système de fichiers comme JFS qui a un journal, vous pouvez le restaurer avec ses outils. Certains gestionnaires de packages vous permettent de réintégrer ses packages et peut-être de cette façon, vous pouvez récupérer le propriétaire de vos fichiers.

Une autre manière, mais plus lourde, est que vous pouvez monter le / var sur un autre périphérique et que les programmes recréeront le répertoire manquant.

Hola Soy Edu Feliz Navidad
la source