void runas(char *user, char *cmd) { if(becomeuser(user) < 0) sysfatal("can't change uid for %s: %r", user); putenv("service", "rx"); execl("/bin/rc", "rc", "-lc", cmd, nil); sysfatal("exec /bin/rc: %r"); }
static int remotecmd(char *rhost, char *luser, char *ruser, char *cmd) { int desc; #if defined(DIRECT_RCMD) static int port = -1; #endif /* DIRECT_RCMD */ debugmsg(DM_MISC, "local user = %s remote user = %s\n", luser, ruser); debugmsg(DM_MISC, "Remote command = '%s'\n", cmd); (void) fflush(stdout); (void) fflush(stderr); (void) signal(SIGALRM, sighandler); (void) alarm(RTIMEOUT); #if defined(DIRECT_RCMD) (void) signal(SIGPIPE, sighandler); if (port < 0) { struct servent *sp; if ((sp = getservbyname("shell", "tcp")) == NULL) fatalerr("shell/tcp: unknown service"); port = sp->s_port; } if (becomeroot() != 0) exit(1); desc = rcmd(&rhost, port, luser, ruser, cmd, 0); if (becomeuser() != 0) exit(1); #else /* !DIRECT_RCMD */ debugmsg(DM_MISC, "Remote shell command = '%s'\n", path_remsh ? path_remsh : "default"); (void) signal(SIGPIPE, SIG_IGN); desc = rcmdsh(&rhost, -1, luser, ruser, cmd, path_remsh); if (desc > 0) (void) signal(SIGPIPE, sighandler); #endif /* DIRECT_RCMD */ (void) alarm(0); return(desc); }
void rexec(User *user, Job *j) { char buf[8*1024]; int n, fd; AuthInfo *ai; switch(rfork(RFPROC|RFNOWAIT|RFNAMEG|RFENVG|RFFDG)){ case 0: break; case -1: clog("can't fork a job for %s: %r\n", user->name); default: return; } if(!mkcmd(j->cmd, buf, sizeof buf)){ clog("internal error: cmd buffer overflow"); _exits(0); } /* * local call, auth, cmd with no i/o */ if(strcmp(j->host, "local") == 0){ if(becomeuser(user->name) < 0){ clog("%s: can't change uid for %s on %s: %r", user->name, j->cmd, j->host); _exits(0); } putenv("service", "rx"); clog("%s: ran '%s' on %s", user->name, j->cmd, j->host); execl("/bin/rc", "rc", "-lc", buf, nil); clog("%s: exec failed for %s on %s: %r", user->name, j->cmd, j->host); _exits(0); } /* * remote call, auth, cmd with no i/o * give it 2 min to complete */ alarm(2*Minute*1000); fd = call(j->host); if(fd < 0){ if(fd == -2) clog("%s: dangerous host %s", user->name, j->host); clog("%s: can't call %s: %r", user->name, j->host); _exits(0); } clog("%s: called %s on %s", user->name, j->cmd, j->host); if(becomeuser(user->name) < 0){ clog("%s: can't change uid for %s on %s: %r", user->name, j->cmd, j->host); _exits(0); } ai = auth_proxy(fd, nil, "proto=p9any role=client"); if(ai == nil){ clog("%s: can't authenticate for %s on %s: %r", user->name, j->cmd, j->host); _exits(0); } clog("%s: authenticated %s on %s", user->name, j->cmd, j->host); write(fd, buf, strlen(buf)+1); write(fd, buf, 0); while((n = read(fd, buf, sizeof(buf)-1)) > 0){ buf[n] = 0; clog("%s: %s\n", j->cmd, buf); } _exits(0); }