Existe uma razão específica pela qual o iptables retornaria um código de saída 3 (em vez de 1?) quando executado sem privilégios suficientes?

3

Eu simplesmente esqueci de usar sudo :

usr@arch ~[0] $ iptables -L
iptables v1.4.21: can't initialize iptables table 'filter': Permission
denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded.
usr@arch ~[3] $ <---

Meu prompt bash PS1 ecoa o status de saída do último comando ($?). Os iptables manpages não se referem a um código de retorno de 3:

Various error messages are printed to standard error. The exit code is 0 for correct functioning. Errors which appear to be caused by invalid or abused command line parameters cause an exit code of 2, and other errors cause an exit code of 1.

O SUSv3 / POSIX discute o status de saída dos comandos . 1 Um comando como mount - que possui 7 estados de saída diferentes para condições de erro - executados sem privilégios retorna 1; algo que está documentado em suas páginas de trabalho: invocação ou permissões incorretas .

Q. Então, por que iptables e mount diferem nesse aspecto - é puramente específico para aplicativos ? Por que é que fazer um strace no primeiro gera coisas como: socket (PF_INET, SOCK_RAW, IPPROTO_RAW) = -1 EPERM (Operação não permitida) - não deveria ser o EACCES? Por que é que rastrear mount de chamadas não privilegiadas não revela erros semelhantes e estes têm um impacto no status de saída; ou é -1 uma falha, seja qual for o motivo? De onde vem esse 3?

1. Também: GNU Bash ; mais geralmente ; aleatório estranheza ; pergunta recente com referência a códigos que são específicos da aplicação + histórico / usr / incluir / sysexits.h etc.

    
por jus cogens prime 06.11.2014 / 14:53

2 respostas

4

A documentação está incompleta. O código contém a seguinte lista de códigos de erro usados internamente:

enum xtables_exittype {
    OTHER_PROBLEM = 1,
    PARAMETER_PROBLEM,
    VERSION_PROBLEM,
    RESOURCE_PROBLEM,
    XTF_ONLY_ONCE,
    XTF_NO_INVERT,
    XTF_BAD_VALUE,
    XTF_ONE_ACTION,
};

E quando tenta inicializar, faz:

if (!*handle)
    xtables_error(VERSION_PROBLEM,
           "can't initialize iptables table '%s': %s",
           *table, iptc_strerror(errno));

xtables_error imprime a mensagem de erro e sai com o código de saída fornecido.

O código parece ser deficiente, IMHO, ao assumir que uma falha aqui é devido a um problema de versão, sem verificar o errno para ver se ele é realmente EPERM .

    
por 06.11.2014 / 18:25
1

A única regra para códigos de saída é que 0 significa sucesso e qualquer outro valor significa falha. Essa regra vai além do unix: também é uma convenção comum em outros sistemas operacionais (incluindo DOS, Windows e muitos sistemas incorporados que têm uma noção de código de saída, mas o VMS faz as coisas de maneira diferente). Nos sistemas Unix, ele é incorporado nas construções booleanas do shell ( if , while , && , || , ! , set -e ,…), em make e seguido por todo o padrão Serviços de utilidade pública. Nos programas POSIX C, EXIT_SUCCESS é 0 e EXIT_FAILURE é algum não- valor zero (geralmente 1).

Não há regra ou convenção generalizada sobre a escolha de códigos de saída para falha. Apenas alguns utilitários POSIX exigem códigos de status de falha específicos:

  • cmp e diff retorna 1 para arquivos diferentes e ≥2 para condições de erro.
  • expr retorna 1 se a expressão for avaliada como zero ou nula, 2 para uma expressão inválida e ≥3 para outros erros.
  • grep retorna 1 para “não encontrado” e ≥2 para condições de erro. Muitos comandos de pesquisa seguem isso (mas não find , que retorna 0 se nenhum arquivo corresponder).
  • mesg retorna 0 para sim, 1 para não e ≥2 para erro.
  • patch retorna 1 se um grupo foi rejeitado e ≥2 para outros erros.
  • sort -c retorna 1 se os dados do arquivo não estiverem classificados e ≥2 para erros.
  • compress e localedef define alguns valores pequenos para erros específicos.

Existe uma ideia comum, mas não universal, de que valores maiores significam piores falhas. Para comandos que testam uma condição booleana como grep (este padrão está presente?) E diff (são esses arquivos idênticos), 1 significa “não” e valores mais altos indicam um erro. Além disso, os valores de até 126 são raramente usados, já que eles são incorporados no shell (e command , env , nice , nohup e time ): 126 e 127 indicam uma falha ao invocar um comando externo e valores acima de 128 em $? indicam um comando que foi finalizado por um sinal. /usr/include/sysexits.h é do sendmail e eu só vi isso seguido em sistemas de e-mail, especialmente por agentes de entrega de e-mail, como o procmail.

Muitos programas sempre retornam 1 ou sempre retornam 2 para qualquer falha. Acontece que iptables define alguns códigos de erro diferentes.

Os valores de retorno mostrados por strace são de chamadas de sistema . As chamadas do sistema retornam -1 para indicar um erro e armazenam o código de erro na variável errno . Strace mostra o valor de errno entre parênteses após o código de retorno. A distinção entre EACCES ("Permissão negada") e EPERM ("Operação não permitida") é um pouco sutil; a idéia geral é que EACCES indica que as permissões no objeto de destino não permitem a ação, enquanto EPERM indica algum outro problema de permissão (por exemplo, o objeto não pode ser acessado, ou a operação é restrita à raiz ).

    
por 07.11.2014 / 04:44