Permitir que outro usuário execute um script específico como meu ID

3

Eu tenho um script em algum lugar no meu diretório pessoal. Eu preciso dar a outro usuário ou a um grupo permissões para que, quando executarem esse script específico, ele seja executado como se eu estivesse logado e tivesse todas as permissões que o meu ID tivesse. Eu não quero usar o sudo ou o su e passar a defini-los como sudoers ou a digitar senhas.

    
por Krishna 02.06.2015 / 21:47

2 respostas

8

Com o sudo, você pode ficar muito granular com suas permissões. Se você quer dar a um usuário permissão para apenas executar seu script e nada mais, você pode adicionar esta linha ao seu / etc / sudoers:

user ALL=(yourusername) NOPASSWD: /path/to/your/script

Então, como o outro uso, você executaria:

sudo -u yourusername /path/to/your/script
    
por 02.06.2015 / 22:20
1

Usar o sudo é a maneira mais fácil. Mas requer a cooperação do administrador do sistema para configurar.

Se você quiser fazer isso sem privilégios especiais, você pode usar um executável setuid , mas precisa ser cuidadoso para não permitir que o chamador faça mais do que você pretendia.

A maioria das variantes do Unix proíbe scripts de shell setuid ; por exemplo, no Linux, o kernel sempre ignora o bit setuid em um script. Então você precisa de um wrapper em código nativo.

Tome cuidado para que o wrapper remova tudo o que permitir ao usuário invocá-lo para executar o código. Por exemplo, variáveis de ambiente da lista de permissões; qualquer coisa que não seja conhecida como segura (por exemplo, TERM ) deve ser usada.

Aqui está uma proposta para um wrapper setuid que retenha apenas a variável de ambiente TERM . Cuidado com o fato de eu não ter revisado ou testado; feedback bem-vindo.

/* Compilation command:
   c99 -DTARGET='"/absolute/path/to/script"' -o setuid-wrapper setuid-wrapper.c
 */

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

void die(const char *argv0, const char *obj, const char *msg) {
    if (msg == NULL) msg = strerror(errno);
    fprintf(stderr, "%s: %s: %s\n", argv0, obj, msg);
    exit(127);
}

int env_want(const char *entry) {
    size_t n;
    for (n = 0; entry[n]; n++) {
        if (entry[n] == '=') {
            break;
        } else if (!(isalnum(entry[n]) || entry[n] == '_')) {
            return 0;
        }
    }
    if ((n == 7 && !strncmp(entry, "DISPLAY", n)) ||
        (n == 10 && !strncmp(entry, "XAUTHORITY", n))) {
        return 1;
    }
    if ((n == 4 && !strncmp(entry, "LANG", n)) ||
        (n >= 3 && !strncmp(entry, "LC_", 3)) ||
        (n == 2 && !strncmp(entry, "TZ", n))) {
        return !strpbrk(entry, "/%");
    }
    return 0;
}

int main(int argc, char *argv[], char **environ) {
    size_t i, j;
    const char *program_name = argv[0];
    if (program_name == NULL) program_name = "setuid-wrapper";
    /* Drop privileges */
    if (setgid(getegid())) die(program_name, "setgid", NULL);
    /*if (setgroups(0, NULL)) die(program_name, "setgroups", NULL);*/
    if (setuid(geteuid())) die(program_name, "setuid", NULL);
    /* Sanitize the environment */
    for (i = j = 0; environ[i]; i++) {
        if (env_want(environ[i])) {
            environ[j] = environ[i];
            j++;
        }
    }
    environ[j] = NULL;
    /* Execute the command */
    execle(TARGET, TARGET, NULL, environ);
    die(program_name, TARGET, NULL);
}

Observe que o programa de destino será executado com os grupos suplementares do chamador, porque você não pode eliminar grupos suplementares sem ser root.

Uma abordagem alternativa seria executar um servidor (por exemplo, um servidor da Web) e invocar seu script desse servidor. Existem vários pequenos servidores HTTP que suportam scripts CGI. A principal vantagem dessa abordagem é que é mais fácil proteger, porque o servidor está em execução em um contexto escolhido pelo destino (a parte em cujo contexto de segurança o código é executado), não pelo cliente.

Uma variante dessa abordagem seria acionar a execução do script por meio de um sistema de arquivos FUSE . Por exemplo, monte um diretório scriptfs contendo seu script com a opção allow_other mount. Isso requer que a opção user_allow_other seja definida em /etc/fuse.conf .

    
por 03.06.2015 / 10:20