int main(int argc, char *argv[]) { int ch, login; if ((euid = geteuid()) != 0) warnx("need root permissions to function properly, check setuid bit"); if (seteuid(getuid()) < 0) err(1, "seteuid"); if ((pwd = getpwuid(getuid())) == NULL) errx(1, "unknown user"); login = 0; while ((ch = getopt(argc, argv, "-l")) != -1) { switch (ch) { case '-': /* Obsolescent */ case 'l': login = 1; break; default: usage(); } } argc -= optind; argv += optind; switch (argc) { case 0: restoregrps(); break; case 1: addgroup(*argv); break; default: usage(); } if (seteuid(euid) < 0) err(1, "seteuid"); if (setuid(getuid()) < 0) err(1, "setuid"); if (login) loginshell(); else doshell(); /*NOTREACHED*/ exit(1); }
/* The 'channel_exec' function executes new process. If terminal is requsted, than users shell is executed, if exec is requested, than command 'cmd' is executed. Process is executed under appropriate users UID. */ int channel_exec(const char *cmd) { char *run[4]; char *shell; char *name; int fd[3]; char ln[32]; if (channel.maxpacket == 0) bug_proto(); if (channel.pid != 0 ) bug_proto(); if (channel.flagterminal) { channel.pid = channel_forkpty(fd, channel.master, channel.slave); if (channel.pid > 0) { name = ptsname(fd[0]); if (!name) bug(); if (!str_copyn(channel.termname, sizeof channel.termname, name)) bug_nomem(); } } else { channel.pid = channel_fork(fd); } if (channel.pid == -1) return 0; if (channel.pid == 0) { logsys_login(channel.user, channel.remoteip, 0, 0); if (!channel_droppriv(channel.user, &shell)) _exit(111); if (cmd) { run[0] = shell; run[1] = (char *)"-c"; run[2] = (char *)cmd; run[3] = 0; } else { if (!loginshell(ln, sizeof ln, shell)) bug(); run[0] = ln; run[1] = 0; } signal(SIGPIPE, SIG_DFL); newenv_exec(shell, run); _exit(111); } channel.fd0 = fd[0]; channel.fd1 = fd[1]; channel.fd2 = fd[2]; channel.len0 = 0; newenv_purge(); if (channel.flagterminal && channel.pid > 0) channel_ptyresize(channel.a, channel.b, channel.x, channel.y); return 1; }