Rilascia i privilegi di processo


12

Ho un processo che viene avviato da un damon in esecuzione come root, ora voglio "declassare" i privilegi di questo processo a quelli dell'utente medio. È possibile? Se si come?

PS: esegue unix su un mac

Risposte:


5

Il processo stesso deve chiamare setuid (2). Dovresti anche investigare eseguendolo all'interno di chroot (8) se non lo sei già. Per quanto ne so, non c'è modo per root di cambiare l'UID di un altro processo.

Se il motivo per cui lo stai eseguendo come root è il bind delle porte, ti suggerirei di eseguirlo come un normale utente su una porta superiore e di usare ipfw (8) su OS X per inoltrare la porta 80/443 / etc alla porta superiore:

http://support.crashplanpro.com/doku.php/recipe/forward_port_443_to_pro_server_on_mac_osx


Ho messo setuid (uid) nel mio programma che gira come root ma ne ho bisogno per funzionare come un normale utente e non succede nulla, cioè continua a funzionare come root
Samantha Catania,

Probabilmente dovrai quindi rilevare gli errori da esso (forse stai ottenendo un EINVAL per l'UID). Il suo improbabile setuid è rotto sul tuo computer che puoi verificare vedendo se apache funziona come _www. Documenti del programmatore: developer.apple.com/library/mac/#documentation/Darwin/Reference/…
polinomio

hai ragione, dà un errore di sintassi dall'UID anche se è corretto. è questo il giusto formato setuid (500)?
Samantha Catania,

trovato il problema: stavo cercando di eseguire il comando tramite system () ma ho appena eseguito il comando funziona e ho risolto il mio problema; grazie per l'aiuto
Samantha Catania,

No. Questo non è un buon consiglio: chiamare setuid()da soli non è assolutamente sufficiente.
Nicholas Wilson,

13

sudo tcpdump -Z usa initgroups (3), setgid (2) e setuid (2) per eliminare i privilegi di root del proprio processo.

# code taken from: 
# http://www.opensource.apple.com/source/tcpdump/tcpdump-32/tcpdump/tcpdump.c

/* Drop root privileges and chroot if necessary */
static void
droproot(const char *username, const char *chroot_dir)
{
...
            if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
               setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
                    fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
                        username, 
                        (unsigned long)pw->pw_uid,
                        (unsigned long)pw->pw_gid,
                        pcap_strerror(errno));
                    exit(1);
            }
...
}

2
Corretta. initgroups, setgid, setuid(Finalmente!) È proprio il paradigma destra su UNIX, e dovrebbe sempre essere seguita. Inoltre, una funzione "droproot" responsabile verifica che i suoi uid e gid siano stati effettivamente impostati, anche se tutte e tre le funzioni primarie hanno dato esito positivo.
Nicholas Wilson,

3

Puoi eseguire comandi come altri utenti usando su:

 su USERNAME -c COMMAND

Funzionerà COMMANDcon i privilegi rilasciati a USER.


Si noti che, per impostazione predefinita, suverrà utilizzato l'interprete della shell dell'utente di destinazione per eseguire il comando. Al contrario, il comportamento predefinito di sudoè di trattare il COMMANDprogramma come un programma autonomo, che viene eseguito l'ambiente corrente. Naturalmente questi comportamenti predefiniti possono essere modificati con vari switch e variabili d'ambiente.


Sembra suche non funzioni se USERNAME non ha una shell definita (o /bin/false) mentre sudo funziona.
Aif,

1
@Aif Se all'utente non è consentito eseguire comandi interattivi, il comportamento predefinitosu lo rifletterà. Tuttavia, si può sempre ignorare quello usando l' -sinterruttore. Si noti che lo scopo di suè imitare il comportamento di un determinato utente, che è normalmente influenzato dalla sua shell. Al contrario, sudo(per impostazione predefinita) ignorerebbe l'impostazione della shell dell'utente di destinazione.
rozcietrzewiacz,

No, per favore non eseguire cose usando una shell semplicemente per eliminare i privilegi. Ciò lascia troppo al controllo di un utente malintenzionato, leggendo in vari file di configurazione che non si desidera toccare.
Nicholas Wilson,

2

Per eliminare i privilegi, è necessario un utente non root a cui accedere. Quindi è solo una questione di passare a quell'utente:

#define UNPRIV_UID  48
#define UNPRIV_GID  48

if (getuid() == 0) { // we are root
    // setting UID/GID requires root privileges, so if you don't set
    // the GID first, you won't be able to do it at all.
    if (setgid(UNPRIV_GID)!=0) die("Failed to set nonroot GID");
    if (setuid(UNPRIV_UID)!=0) die("Failed to set nonroot UID");
}

ASSERT(getuid() != 0); 

Si noti che ciò avviene all'interno del programma stesso, piuttosto che in uno script wrapper. Molti programmi richiedono i privilegi di root per uno scopo specifico (ad es. Per associarsi a una porta con numero basso), ma dopo non hanno bisogno di root. Quindi questi programmi inizieranno come root, ma poi lasceranno cadere i privilegi quando non saranno più necessari.

Se non hai affatto bisogno dei privilegi di root, non eseguirlo come root. Per esempio:

# Change this:
myprog -C /my/config/file

# To this:
sudo -u someuser myprog -C /my/config/file
# Or this
su someuser -c "myprog -C /my/config/file"

1
Si noti che ciò consente al processo di ripristinare i privilegi, se lo desidera! La setuidfunzione imposta solo l' UID effettivo , non l'UID reale. Dovresti usarlo setreuidse non vuoi che il processo sia in grado di recuperare i privilegi. (E il codice sopra non si occupa nemmeno dei privilegi di gruppo supplementari. È adatto solo per il lancio di codice per lo più fidato.)
David Schwartz,

Il codice @David Schwartz è stato intenzionalmente semplificato per mostrare il meccanismo utilizzato.
Tylerl,

Se avete intenzione di semplificare il codice di sicurezza-critical, è necessario rendere molto chiaro che questo è quello che stai facendo. E dovresti dire cose come "è solo una questione di" quando non lo è.
David Schwartz,

2
@David In realtà, setuid()imposta userid reali e salvati; potresti pensare seteuid(). Non tutti i sistemi hanno setreuid(), quindi non può essere usato abbastanza dappertutto. La semantica esatta di setuid()è complicata, ma se hai euid 0, sarai in grado di eliminare tutti i privilegi di id utente tradizionali setuid(). La più grande omissione in questa risposta è che initgroupso setgroupsdeve essere chiamata così come setgide setuid, e che alla fine dovrebbero essere fatte affermazioni più approfondite.
Nicholas Wilson,

0

Se stai eseguendo un altro eseguibile, cioè stai chiamando execveo un'altra della execfamiglia di funzioni, forse indirettamente attraverso una funzione come systemo popen, e il processo figlio dovrebbe essere eseguito senza privilegi dall'inizio, allora il modo più semplice è ottenere un shell coinvolta e chiama su. Ecco una panoramica di come potrebbe apparire il codice in Perl, mostrando le quotazioni necessarie per:

$shell_command = quotemeta($path_to_executable) . " --option";
$shell_command =~ s/'/'\\''/; # protect single quotes for the use as argument to su
$su_command = sprintf("su -c '%s' %s", $shell_command, quotemeta($user_name));
open(PIPE, "$su_command |") or die;

Se il processo figlio deve iniziare come root ma eliminare i privilegi in un secondo momento, vedere il codice in questa risposta , che illustra come eseguire il downgrade dei privilegi in un processo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.