E se eu acidentalmente executar o comando “chmod -R” nos diretórios do sistema (/, / etc,…)

54

Eu corri acidentalmente

sudo chmod 755 -R /

em vez de

sudo chmod 755 -R ./

Parei depois de alguns segundos, mas agora há alguns problemas, como

sudo: must be setuid root

Como posso reverter as permissões?

    
por fl00r 18.05.2011 / 15:15

8 respostas

54

Resumindo: você não pode reinstalar o sistema.

Quero dizer, as permissões Posix são usadas e confiadas strongmente; há uma infinidade de lugares no sistema de arquivos onde as permissões erradas quebrariam o sistema operacional (sinalizadores SUID) ou, pior, o tornariam exposto em termos de segurança ( /etc/ssh/ssh_host_rsa_key ) enquanto parece estar funcionando bem.

Portanto, é difícil fazer essa recuperação adequadamente. Senhorita uma coisa - e você estraga tudo. Você estragou o comando sudo chmod (se esse é seu amigo ao invés de você, ela também pode aprender algumas lições sobre o Linux) - e isso é muito simples um comando. Recuperação adequada exigiria muito mais comandos e muito mais vigilância. Mesmo se você usar o script de algum cara.

Então confie em mim, apenas reinstale. É uma aposta segura e garantida para mantê-lo longe de problemas.

Finalmente, algumas dicas são relevantes aqui.

Primeiro: as reinstalações serão menos dolorosas se você configure seu /home em uma partição separada na próxima vez. Na verdade, será uma brisa.

Segundo: considere fazer ciência Linux louca em uma máquina virtual como o VirtualBox, e faça seus instantâneos.

Terceiro: chmod -R . funciona. Não há necessidade real de anexar essa barra. Você poderia ter evitado o risco catastrófico de pular o ponto de forma imediata; mero chmod: missing operand after ‘755’ VS um sistema arruinado.

    
por ulidtko 18.05.2011 / 15:19
24

Eu escrevi e tenho usado há vários anos alguns scripts Ruby com rsync de permissões e propriedade. O script get-filesystem-acl coleta todas as informações percorrendo recursivamente todos os arquivos e coloca tudo no arquivo .acl . O script .acl-restore lerá .acl e aplicará todos os chown e chmod .

Você pode executar get-filesystem-acl em uma instalação semelhante do Ubuntu e copiar o arquivo .acl para sua caixa danificada pelo chmod, colocar .acl e .acl-restore em / e executar .acl-restore .

Você precisará ter root, então corrija seu sudo como Marco Ceppi sugeriu.

Eu posso gerar e dar a você o arquivo .acl para o meu Ubuntu.

get-filesystem-acl

#!/usr/bin/ruby

RM   = "/bin/rm"
SORT = "/usr/bin/sort"
TMP  = "/tmp/get_acl_#{Time.now.to_i}_#{rand * 899 + 100}"

require 'find'

IGNORE = [".git"]

def numeric2human(m)
  return sprintf("%c%c%c%c%c%c%c%c%c",
            (m & 0400 == 0 ? ?- : ?r),
            (m & 0200 == 0 ? ?- : ?w),
            (m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :
                             (m & 04000 == 0 ? ?x : ?s)),
            (m & 0040 == 0 ? ?- : ?r),
            (m & 0020 == 0 ? ?- : ?w),
            (m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :
                             (m & 02000 == 0 ? ?x : ?s)),
            (m & 0004 == 0 ? ?- : ?r),
            (m & 0002 == 0 ? ?- : ?w),
            (m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :
                             (m & 01000 == 0 ? ?x : ?t)))
end


File.open(TMP, "w") do |acl_file|

  # TODO: Instead of the current dir, find the .git dir, which could be
  #       the same or outside of the current dir
  Find.find(".") do |path|

    next if IGNORE.collect {|ig| !!(path[2..-1] =~ /\A#{ig}/)}.include? true
    next if File.symlink?(path)

    stat = File.lstat(path)
    group_id = stat.gid
    rules    = "#{type}#{numeric2human(stat.mode)}" 

    acl_file.puts "#{path} #{rules} #{owner_id} #{group_id}"
  end
end

'#{SORT} #{TMP} > .acl'
'#{RM}   #{TMP}'

.acl-restore

#!/usr/bin/ruby

# This script will only work with .acl_ids

# Restore from...
FROM  = ".acl"

MKDIR = "/bin/mkdir"
CHMOD = "/bin/chmod"
CHOWN = "/bin/chown"
known_content_missing = false


def numeric2human(m)
  return sprintf("%c%c%c%c%c%c%c%c%c",
            (m & 0400 == 0 ? ?- : ?r),
            (m & 0200 == 0 ? ?- : ?w),
            (m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :
                             (m & 04000 == 0 ? ?x : ?s)),
            (m & 0040 == 0 ? ?- : ?r),
            (m & 0020 == 0 ? ?- : ?w),
            (m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :
                             (m & 02000 == 0 ? ?x : ?s)),
            (m & 0004 == 0 ? ?- : ?r),
            (m & 0002 == 0 ? ?- : ?w),
            (m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :
                             (m & 01000 == 0 ? ?x : ?t)))
end

def human2chmod(mode)
  raise unless mode =~ /([r-][w-][xtsTS-])([r-][w-][xtsTS-])([r-][w-][xtsTS-])/
  triple = [$1, $2, $3]
  u,g,o = triple.collect do |i|
    i.sub('s', 'sx').sub('t', 'tx').downcase.gsub('-', '')
  end

  return "u=#{u},g=#{g},o=#{o}" 
end



File.open(FROM).each do |acl|
  raise unless acl =~ /\A(([^ ]*? )+)([^ ]+) ([^ ]+) ([^ ]+)\Z/
  path, rules, owner_id, group_id = $1, $3, $4, $5
  path = path.strip
  owner_id = owner_id.to_i
  group_id = group_id.to_i

  if !File.exists?(path) and !File.symlink?(path)
    if rules =~ /\Ad/
      STDERR.puts "Restoring a missing directory: #{path}"
      STDERR.puts "Probably it was an empty directory. Git goes not track them."
      '#{MKDIR} -p '#{path}'' # Creating the any parents
    else
      known_content_missing = true
      STDERR.puts "ERROR: ACL is listed but the file is missing: #{path}"
      next
    end
  end

  s = File.lstat(path)
  t = s.ftype[0..0].sub('f', '-') # Single character for the file type
                                  # But a "-" istead of "f"

  # Actual, but not neccesarely Desired 
  actual_rules    = "#{t}#{numeric2human(s.mode)}"
  actual_owner_id = s.uid 
  actual_group_id = s.gid 

  unless [actual_rules, actual_owner_id, actual_group_id] ==
    [rules, owner_id, group_id]

    chmod_argument = human2chmod(rules)

    # Debug
    #p chmod_argument
    #p s.mode

    ## Verbose
    puts path
    puts "Wrong: #{[actual_rules, actual_owner_id, actual_group_id].inspect}"
    puts "Fixed: #{[rules, owner_id, group_id].inspect}"
    '#{CHMOD} #{chmod_argument} '#{path}''

    #puts
  end

end

if known_content_missing
  STDERR.puts "-" * 80 
  STDERR.puts "Some files that are listed in #{FROM.inspect} are missing in " +
              "the current directory."
  STDERR.puts
  STDERR.puts "Is #{FROM.inspect} outdated?"
  STDERR.puts "(Try retrograding the current directory to an earlier version)"
  STDERR.puts
  STDERR.puts "Or is the current directory incomplete?"
  STDERR.puts "(Try to recover the current directory)"
  STDERR.puts "-" * 80 
end
    
por Aleksandr Levchuk 18.05.2011 / 16:13
12

Em muito tempo: você pode. Você precisará montar o sistema de arquivos a partir do Live CD e começar a reverter as permissões nos locais apropriados. No mínimo, para obter o sudo de volta, você vai querer executar sudo chmod u+s /usr/bin/sudo enquanto estiver na sessão do LiveCD - isso consertará a raiz do setuid.

No entanto, provavelmente seria mais fácil simplesmente reinstalar o sistema.

    
por Marco Ceppi 18.05.2011 / 15:50
3

(Eu sei que não devo comentar em uma resposta, mas não há reputação suficiente para comentar.)

A resposta do blade19899 funcionou para mim, exceto pelos links simbólicos. Por exemplo. ele aplicou 755 a / bin / bash, mas então aplicou o 777 ao symlink / bin / rbash, efetivamente 777-ing / bin / bash.

Como eu já tinha o arquivo fileper.log, modifiquei o comando destination-end:

while IFS=: read -r -d '' perm file; do  
    if [[ ! -L "$file" ]]; then    
        chmod "$perm" "$file"
    fi
done < /tmp/fileper.log 
    
por Marjan 21.07.2016 / 12:38
3

Eu tentaria reinstalar todos os pacotes com apt-get install --reinstall , possivelmente usando a saída de dpkg --get-selections | grep install para obter uma lista deles.

    
por Adam Byrtek 18.05.2011 / 15:59
3

Tudo bem, eu não testei isso (portanto, use a seu próprio risco), mas ainda assim pode funcionar. Eu testarei isso em uma máquina virtual quando tiver a chance de:

Primeiro, em um sistema ainda em funcionamento, fiz o seguinte para obter todas as permissões de arquivo em uma lista, ignorando o diretório /home/ :

sudo find / -not -path /home -printf "%m:%p
while IFS=: read -r -d '' perm file; do  
    chmod "$perm" "$file"
done < /tmp/fileper.log 
" > /tmp/fileper.log

Isso imprimirá as permissões e o nome do arquivo para cada arquivo ou diretório no sistema, seguido por um caractere fileper.log (isso é necessário mais tarde para lidar com nomes de arquivos estranhos, como aqueles que contêm novas linhas).

Em um sistema onde as permissões do arquivo foram comprometidas:

sudo find / -not -path /home -printf "%m:%p
while IFS=: read -r -d '' perm file; do  
    chmod "$perm" "$file"
done < /tmp/fileper.log 
" > /tmp/fileper.log

Isso lerá cada linha de $perm , salvando as permissões como $file e o nome do arquivo como fileper.log e, em seguida, definirá as permissões do arquivo (ou diretório) para o que foi listado no /tmp/fileper.log

Algumas coisas a serem observadas aqui:

  • Durante a saída para o arquivo: / , você pode estar listando configurações personalizadas e proc, etc.
  • talvez você não consiga inicializar ou executar comandos,

O que eu sugiro é inicializar um LiveCD com a versão do Linux que você tem em seu disco, executar o comando, modificar o caminho para onde você tem o disco local montado e executar o segundo comando!

Eu testei que quando inicializado a partir de um CD / USB do Ubuntu, posso escolher não formatar o disco, o que significa que ele substituirá tudo no diretório /home/ , MAS pula o diretório chmod . Ou seja, seus usuários terão a configuração de apps / DATA (Music, Video, Documents) ainda intacta. E, substituindo os arquivos do sistema, o %code% está definido para o número correto.

    
por blade19899 11.05.2016 / 22:37
2

Você pode tentar restaurar as permissões com apt-get .

Se você não puder executar esses comandos com o sudo, pode ser necessário inicializar no modo de recuperação e executá-los como root.

Para inicializar no modo de recuperação, consulte link .

De link

Nota: Isto foi originalmente publicado nos fóruns do Ubuntu, mas não consigo encontrar o post original.

Tente, em ordem,

sudo apt-get --reinstall install 'dpkg --get-selections | grep install | grep -v deinstall | cut -f1'

Se isso falhar:

sudo apt-get --reinstall install 'dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | egrep -v '(package1|package2)''

E finalmente, como último recurso,

sudo dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | xargs apt-get --reinstall -y --force-yes install

Usando o apt-get

Aqui está o recorte relevante, EDITADO PARA CORREÇÃO e reformatado:

sudo apt-get --reinstall install 'dpkg --get-selections | grep install | grep -v deinstall | cut -f1'

Let's say you get messages about some packages that can't be reinstalled, and the command fails. Here's one way to fix it by skipping the packages in question:

sudo apt-get --reinstall install 'dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | egrep -v '(package1|package2)''

And finally, if you should somehow have so many things installed that the above command fails saying your argument list is too long, here's the fix, which will run apt-get many more times than you might like:

sudo dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | xargs apt-get --reinstall -y --force-yes install

Note the -y and --force-yes options, which will stop apt-get from prompting you over and over again. These are always fun options, if you're sure you know what you're doing.

    
por Panther 24.08.2017 / 20:42
0

Muitas das respostas são problemáticas porque exigem sudo , mas sudo está corrompido. Você não pode usar sudo para corrigir sudo . Outras respostas exigem a reinicialização do computador usando um Live CD ou modo de recuperação, o que é inconveniente.

Outra opção é usar pkexec para chegar a um shell com permissões de root.

  1. Execute pkexec bash em um terminal para obter um shell com permissões de root.

  2. Defina o bit setuid:

    chmod u+s /usr/bin/sudo
    
  3. sudo agora deve estar disponível para qualquer outro reparo que possa ser necessário.

por 09.01.2019 / 09:28