Come eseguire comandi con privilegi di uno specifico utente in C and Python su Linux
Inviato da Matteo Mattei ~ 27th luglio 2011
Se avete accesso da root ma avete bisogno di eseguire alcuni applicazioni o script con credenziali di altri utenti potete semplicemente farlo direttamente dalla shell con:
su - username -c "command to execute"
Ma se invece avete bisogno di eseguire tale programma dalla vostra applicazione C/C++ avete bisogno di seguire questa procedura:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
int main(int argc, char* argv[])
{
if(argc != 3)
{
printf("Usage: %s [USERNAME] [COMMAND]\n",argv[0]);
return 1;
}
char *env[16];
char envc[16][64];
struct passwd *pw = getpwnam(argv[1]);
if(pw==NULL)
{
printf("User %s does not exists!\n",argv[1]);
return 1;
}
sprintf(env[0]=envc[0],"TERM=xterm");
sprintf(env[1]=envc[1],"USER=%s",pw->pw_name);
sprintf(env[2]=envc[2],"HOME=%s",pw->pw_dir);
sprintf(env[3]=envc[3],"SHELL=%s",pw->pw_shell);
sprintf(env[4]=envc[4],"LOGNAME=%s",pw->pw_name);
sprintf(env[5]=envc[5],"PATH=/usr/bin:/bin:/opt/bin");
env[6]=0;
initgroups(argv[1],pw->pw_gid);
setgid(pw->pw_gid);
setuid(pw->pw_uid);
execve(argv[2],NULL,env);
return 0;
}
Potete compilare ed eseguire il codice in questo modo:
[root@barracuda ~]# gcc mysu.c -o mysu [root@barracuda ~]# id uid=0(root) gid=0(root) gruppi=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),19(log) [root@barracuda ~]# ./mysu matteo /bin/bash [matteo@barracuda /root]$ id uid=1000(matteo) gid=100(users) groups=100(users),3(sys),10(wheel),14(uucp),91(video),92(audio),93(optical),95(storage),96(scanner),97(camera),98(power),108(vboxusers)
Lo stesso risultato si puo’ ottenere anche in Python con pochissimo sforzo:
#!/usr/bin/env python
import sys,pwd,os
pw = pwd.getpwnam(sys.argv[1])
os.initgroups(sys.argv[1],pw.pw_gid)
env={"TERM":"xterm","USER":pw.pw_name,"HOME":pw.pw_dir,"SHELL":pw.pw_shell,"LOGNAME":pw.pw_name,"PATH":"/usr/bin:/bin:/opt/bin"};
os.setgid(pw.pw_gid);
os.setuid(pw.pw_uid);
os.execve(sys.argv[2],[],env);