2009-06-26 16 views
11

Ho dovuto fare uno scribacchino Linux per qualcuno in modo che potessero avviare una stampante con il comando della shell cupsenable printername pur essendo un utente non root. Non volevo che fossero in grado di utilizzare la totalità della sintassi cupsenable come root, quindi ho appena scritto un wrapper C che sanifica l'input in e chiama system("cupsenable sanitizedprintername").Perché ho bisogno di setuid (0) all'interno di un programma C setuid-root che chiama un programma amministrativo con system()?

Ho creato il programma setuid root, ma anche così, cupsenable non è riuscito con "autorizzazione negata". Quindi ho inserito una chiamata setuid(0) prima dello system() e, ecco, ha funzionato.

Ignora il problema di un modo migliore per consentire agli utenti di controllare la stampante. Probabilmente c'è un modo migliore. Quello che mi interessa sono le complessità di chmod u+s vs. setuid(0) vs. system(). Perché si è comportato in quel modo?

risposta

17

Da man system:

Non utilizzare system() da un programma con set-user-ID e set-group-ID privilegi, perché i valori strani per alcune variabili d'ambiente potrebbero essere utilizzati per sovvertire l'integrità del sistema. Utilizzare invece la famiglia di funzioni exec(3) ma non execlp(3) o execvp(3). system(), infatti, non funzionerà correttamente da programmi con i privilegi set-user-ID o set-group-ID su sistemi su cui /bin/sh è la versione 2 di bash, poiché bash 2 rilascia i privilegi all'avvio.

E da man bash:

Se la shell viene avviato con l'id effettivo dell'utente (gruppo) non è uguale a l'utente reale (gruppo) id, e l'opzione -p non viene fornito, nessun avvio i file vengono letti, le funzioni di shell non vengono ereditate dall'ambiente, la variabile SHELLOPTS, se viene visualizzata nell'ambiente, viene ignorata e l'ID utente effettivo viene impostato sull'ID utente reale.

Sembra che la vostra chiamata setuid(0) abbia eluso tale protezione.

+2

Whoa. Bene, ho detto che era sporco. Sembra che quello che ho fatto sia stato convincere il processo di bash generato da system() che in realtà, davvero, onestamente era root, giuro su Dio. Sembra che un po 'di refactoring sia in ordine. – JCCyC