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 -c
pour 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 -l
ou 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/info
avaient le propriétaire, le groupe et les autorisations octales ainsi que le nom de fichier ... mais ils n'en ont pas.
chown
commande? et aurait été fermé.