#include #include #include #include #include #include #include #include "util.h" #ifdef HAVE_CONFIG_H #include "../config.h" #endif static void usage(); static void printJailIds(); static void runJailPs(int argc, char* argv[]); int main(int argc, char* argv[]) { int ch = 0; int simple = 0; int jid = 0; while((ch = getopt(argc, argv, "x")) != -1) { switch(ch) { case 'x': simple = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; /* Make sure we have a jail name or id */ if(argc == 0) usage(); if(running_in_jail()) errx(1, "can't run from inside jail"); /* Translate the jail name into an id if neccessary */ name = argv[0]; jid = translate_jail_name(argv[0]); if(jid == -1) errx(1, "unknown jail host name: %s", argv[0]); argc--; argv++; /* Go into the jail */ if(jail_attach(jid) == -1) err(1, "couldn't attach to jail"); if(simple) { if(argc > 0) usage(); print_jail_ids(); } else { /* This function never returns */ run_jail_ps(argc, argv); } return 0; } static void usage() { fprintf(stderr, "usage: jps [-x] jail [ ps_options ... ]\n"); exit(2); } static void run_jail_ps(int argc, char* argv[]) { char* args[]; int i; if(!check_jail_command(NULL, "/bin/ps")) exit(1); /* * TODO: We need to purge down the environment here. * If the jail is in any way malicious or compromised * then it could have replaced /bin/ps which we run... */ args = alloca(sizeof(char*) * (argc + 2)); args[0] = "ps"; for(i = 0; i < argc; i++) args[i + 1] = argv[i]; args[i + 1] = NULL; run_jail_command(NULL, "/bin/ps", args, 0); } static void print_jail_ids() { kvm_t* kd; struct kinfo_proc* kp; char errbuf[_POSIX2_LINE_MAX]; /* Open kernel interface */ kd = kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, _PATH_DEVNULL, O_RDONLY, errbuf); if(kd == NULL) errx(1, "couldn't connect to kernel: %s", errbuf); /* Get all processes and print the pids */ if((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nentries)) == 0) errx(1, "couldn't list processes: %s", kvm_geterr(kd)); for(i = 0; i < nentries; i++) printf("%d ", (int)(kp[i].ki_pid)); fputc(stdout, '\n'); kvm_close(kd); }