Execute o script Python Portio como usuário normal sem acesso root

4

Eu sei que há riscos em executar um script raiz como um usuário normal, mas, neste caso, não tenho escolha e o que estou fazendo é relacionado à máquina. Eu tenho um computador de placa pequena que tem portas GPIO e eu preciso usar uma das saídas para redefinir um dispositivo, alternando uma linha de desligamento. Essa parte funciona bem e o dispositivo é redefinido como deveria.

Meu problema é que eu escrevi um script python para redefinir o dispositivo e ele funciona, mas eu tenho que executá-lo como root ou "sudo program name, enter password". Mas eu preciso que isso funcione como um usuário normal sem permissões de root. Em outras palavras, adicionei um usuário normal e não posso executar o script, não importa o que eu faça.

Eu tentei adicionar o usuário ao arquivo sudoer, mas isso não funcionou e foi completamente ignorado. Alterei as permissões, defini o bit SUID e tudo o mais que posso imaginar, mas ele ainda pede uma senha de root. A única coisa que funcionou foi quando eu abri User and Groups e adicionei o usuário ao grupo Sudo, mas o usuário tinha acesso a programas que eu preferia que ele não fizesse, pois era como o meu usuário admin padrão. Isso não é o que eu quero. Eu gostaria de limitar de alguma forma o que esse usuário tem acesso a um único script ou programa.

Eu já tive outras pessoas sugerindo que eu preciso escrever um driver, mas eu realmente não sei como fazer isso ou exatamente o que elas significam e geralmente elas não querem elaborar. Embora eu tenha usado o Linux, eu não me consideraria nem especialista especialmente nessa área. Alguém tem alguma idéia de como fazer isso?

    
por user5881 18.08.2011 / 18:43

2 respostas

5

Encontrou a solução aqui .

O que você quer fazer é escrever um programa de habilitação de E / S confiável em C que permita acesso apenas às portas desejadas, e então use execvp () para executar seu script no espaço de endereço do chamador. Você irá então setuid root para o enabler de E / S compilado.

Veja um exemplo de código adaptado da fonte acima (não se esqueça de usar um bloco de endereço que você não se importa de escrever):

#include <stdio.h>
#include <stdlib.h>
#include <sys/io.h>

#define DESIRED_PORT    0x300
#define NUM_BYTES       8

int main(int argc, char*argv[])
{
    if (argc < 2) {
        printf("Error: no target program specified.\n");
        exit(1);
    }

    if (ioperm(DESIRED_PORT, NUM_BYTES, 1)) {
        printf("Error: couldn't set port permissions.\n");
        exit(1);
    }

    // Set uid to current user's id before executing the script
    setgid(getgid());
    setuid(getuid());

    if (execvp(argv[1], &argv[1]) < 0) {
        printf("Error: target program execution error.\n");
        exit(1);
    }
}

Vamos chamá-lo de io_enable.c, depois compilar e setuid root:

$ gcc io_enable.c -o io_enable
$ sudo chown root io_enable
$ sudo chmod u+s io_enable

Em seguida, podemos testá-lo com o seguinte script python:

#!/usr/bin/python
import portio

ADDR = 0x300

fd = open('/tmp/portio.log', 'w')

for i in range(10):
    portio.outb(i, ADDR)
    fd.write('Wrote %d, read %d.\n' % (i, portio.inb(ADDR)))

fd.close()

Estou chamando de io_test.py e, em seguida, estou executando da seguinte forma:

$ ./io_enable python io_test.py

Parece que funciona:

$ cat /tmp/portio.log
Wrote 0, read 0.
Wrote 1, read 1.
Wrote 2, read 2.
Wrote 3, read 3.
Wrote 4, read 4.
Wrote 5, read 5.
Wrote 6, read 6.
Wrote 7, read 7.
Wrote 8, read 8.
Wrote 9, read 9.
    
por 05.03.2012 / 23:55
3

Adicione esta linha ao arquivo sudoers (use o programa visudo , nunca edite o arquivo sudoers diretamente), onde bob é o nome do usuário que deve ter permissão para executar o script:

bob ALL = (root) NOPASSWD: /path/to/my/script

Se você quiser isso para vários usuários, coloque-os em um grupo resetters e faça com que sudoers line

%resetters ALL = (root) NOPASSWD: /path/to/my/script

Se houver outras regras envolvendo bob , tome cuidado para que a última correspondência conta no arquivo sudoers . Então, coloque as regras com NOPASSWD: abaixo das regras sem ele.

    
por 18.08.2011 / 21:52