--- main.c.orig Wed Jan 19 08:25:24 2000 +++ main.c Wed Jan 19 08:28:20 2000 @@ -54,7 +54,10 @@ #include #include #include - +#include +#include +#include +#include #include "shell.h" #include "main.h" @@ -107,6 +110,141 @@ struct stackmark smark; volatile int state; char *shinit; + char pidfile[256]; + char pidname[256]; + char accessline[4096]; + char *username; + int ppid; + int fd; + int uid; + FILE *flist; + struct passwd *pw; + + /* + * Start of sh-log+access patch + * - Deny list is hardcoded to /etc/sh.deny + * - Logs process ID, parent process ID, parent process name, + * user ID, username, and login name to syslog. + * - Omachonu Ogali + */ + + /* + * Start of pid resolving code. + * - Omachonu Ogali + */ + + if (!(ppid = getppid())) { + perror("getppid()"); + return -1; + } + + fd = 0; + bzero(pidfile, sizeof(pidfile)); + + snprintf(pidfile, sizeof(pidfile), "/proc/%d/cmdline", ppid); + if ((fd = open(pidfile, O_RDONLY)) == -1) { + /* + * We can't return an error and die because we + * essentially break /bin/sh until /proc is mounted, + * so we're just going to copy 'unknown' and get over + * with it. (Still have to let the user know what's + * going on though). + */ + + perror("open()"); + strncpy(pidname, "UNKNOWN", sizeof(pidname)); + } else { + read(fd, pidname, sizeof(pidname)); + close(fd); + + /* + * Workaround for certain BSD procfs filesystems. + */ + + if (pidname[strlen(pidname) - 1] == 0x0a) { + pidname[strlen(pidname) - 1] = NULL; + } + } + + /* + * End of pid resolving code. + */ + + openlog("sh", LOG_CONS || LOG_PID, LOG_AUTH); + + /* + * Start of uid resolving code. + */ + + if ((uid = getuid()) < 0) { + perror("getuid()"); + return -1; + } + + if ((pw = getpwuid(uid)) == NULL) { + perror("getpwuid()"); + return -1; + } + + /* + * End of uid resolving code + */ + + if ((username = getlogin()) == NULL) { + perror("getlogin()"); + return -1; + } + + /* Access list to prevent unwanted execution of sh, yes we could + * use permissions, but that wouldn't help against compromises, + * since most of the times root access is gained. + * - Omachonu Ogali + */ + + if ((flist = fopen("/etc/sh.deny", "r")) == NULL) { + perror("fopen(/etc/sh.deny)"); + return -1; + } + + while (fgets(accessline, sizeof(accessline), flist) != NULL) { + if (accessline[strlen(accessline) - 1] == 0x0a) { + accessline[strlen(accessline) - 1] = NULL; + } + + if (strcmp(accessline, pidname) == 0) { + syslog(LOG_WARNING || LOG_ERR, "rejected pid %d (%s), uid %d (%s/%s)\n", ppid, pidname, uid, pw->pw_name, username); + printf("rejected pid %d (%s), uid %d (%s/%s)\n", ppid, pidname, uid, pw->pw_name, username); + closelog(); + return -1; + } + } + + if (fclose(flist) < 0) { + perror("fclose(/etc/sh.deny)"); + return -1; + } + + /* + * End of access list code + */ + + /* + * When spawned, we log our pid and parent pid to syslog + * in case we need it to find the origin of an intrusion. + * - Omachonu Ogali + */ + + syslog(LOG_WARNING, "spawned by pid %d (%s), uid %d (%s/%s)\n", ppid, +pidname, uid, pw->pw_name, username); + closelog(); + + /* + * End of parent logging code + */ + + /* + * End of sh-log+access patch + */ #if PROFILE monitor(4, etext, profile_buf, sizeof profile_buf, 50);