|
|
researchv10 Norman
/* usage: dispatch <ipc args> */
/* TODO: connect input to /dev/null if peer wants no output,
connect output to logfile if peer wants no input. */
#include <string.h>
#include <stdio.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include "../paths.h"
int
main(int argc, char *argv[])
{
char c, d;
char *args[4];
int fd, i, sz;
struct sockaddr_in sin;
struct hostent *h;
char locname[16], remname[16];
struct passwd *pw;
if (chdir(LDIR) < 0)
exit(1);
sz = sizeof sin;
if (getpeername(0, (struct sockaddr *) &sin, &sz) < 0)
exit(1);
if (ntohs(sin.sin_port) >= 1024)
exit(1);
if (!(h = gethostbyaddr(&sin.sin_addr, sizeof sin.sin_addr, sin.sin_family)))
exit(1); /* another silent exit */
/* execute the rsh authentication protocol */
if (read(0, locname, 1) != 1 || locname[0] != '\0')
exit(1);
for (i = 0; i < sizeof remname; ++i)
if (read(0, remname + i, 1) == 1 && remname[i] == '\0')
break;
if (i == sizeof remname)
exit(1);
for (i = 0; i < sizeof locname; ++i)
if (read(0, locname + i, 1) == 1 && locname[i] == '\0')
break;
if (i == sizeof locname)
exit(1);
if (strcmp(locname, remname) != 0)
exit(1);
if (!(pw = getpwnam(locname)))
exit(1);
if (ruserok(h->h_name, pw->pw_uid == 0, remname, locname) != 0)
exit(1);
write(0, "", 1); /* a NUL byte */
setgid(pw->pw_gid);
setuid(pw->pw_uid);
args[1] = h->h_name;
args[2] = pw->pw_name;
args[3] = 0;
if (read(0, &c, 1) != 1)
return 1;
do
if (read(0, &d, 1) != 1)
return 1;
while (d);
dup2(0, 1);
fd = open("/dev/null", 1);
dup2(fd, 2);
if (fd > 2)
close(fd);
switch (c) {
case 's':
args[0] = "showq";
execv("showq", args);
break;
case 't':
args[0] = "transmit";
execv("transmit", args);
break;
case 'n':
args[0] = "notice";
execv("notice", args);
break;
}
return 1;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.