Ejemplo n.º 1
0
int
main(int argc, char **argv)
{
	int jid;

	if (argc < 3)
		usage();
	jid = getjailid(argv[1]);
	if (jail_attach(jid) == -1)
		err(1, "jail_attach(%d) failed", jid);
	if (chdir("/") == -1)
		err(1, "chdir(\"/\") failed");
	if (execvp(argv[2], argv + 2) == -1)
		err(1, "execvp(%s) failed", argv[2]);
	exit(0);
}
Ejemplo n.º 2
0
int
main(int ac, char **av)
{
	struct kinfo_proc *procs, *newprocs;
	struct stat	sb;
	struct passwd	*pw;
	regex_t		rgx;
	regmatch_t	pmatch;
	int		i, j, ch;
	char		buf[256];
	char		first;
	char		*user = NULL;
	char		*tty = NULL;
	char		*cmd = NULL;
	int		vflag = 0;
	int		sflag = 0;
	int		dflag = 0;
	int		eflag = 0;
	int		Iflag = 0;
	int		jflag = 0;
	int		mflag = 0;
	int		zflag = 0;
	uid_t		uid = 0;
	dev_t		tdev = 0;
	pid_t		mypid;
	char		thiscmd[MAXCOMLEN + 1];
	pid_t		thispid;
	uid_t		thisuid;
	dev_t		thistdev;
	int		sig = SIGTERM;
	const char *const *p;
	char		*ep;
	int		errors = 0;
	int		jid;
	int		mib[4];
	size_t		miblen;
	int		st, nprocs;
	size_t		size;
	int		matched;
	int		killed = 0;

	setlocale(LC_ALL, "");

	av++;
	ac--;

	while (ac > 0) {
		if (strcmp(*av, "-l") == 0) {
			printsig(stdout);
			exit(0);
		}
		if (strcmp(*av, "-help") == 0)
			usage();
		if (**av == '-') {
			++*av;
			switch (**av) {
			case 'I':
				Iflag = 1;
				break;
			case 'j':
				++*av;
				if (**av == '\0') {
					++av;
					--ac;
				}
				jflag++;
				if (*av == NULL)
				    	errx(1, "must specify jail");
				jid = jail_getid(*av);
				if (jid < 0)
					errx(1, "%s", jail_errmsg);
				if (jail_attach(jid) == -1)
					err(1, "jail_attach(%d)", jid);
				break;
			case 'u':
				++*av;
				if (**av == '\0') {
					++av;
					--ac;
				}
				if (*av == NULL)
				    	errx(1, "must specify user");
				user = *av;
				break;
			case 't':
				++*av;
				if (**av == '\0') {
					++av;
					--ac;
				}
				if (*av == NULL)
				    	errx(1, "must specify tty");
				tty = *av;
				break;
			case 'c':
				++*av;
				if (**av == '\0') {
					++av;
					--ac;
				}
				if (*av == NULL)
				    	errx(1, "must specify procname");
				cmd = *av;
				break;
			case 'v':
				vflag++;
				break;
			case 's':
				sflag++;
				break;
			case 'd':
				dflag++;
				break;
			case 'e':
				eflag++;
				break;
			case 'm':
				mflag++;
				break;
			case 'z':
				zflag++;
				break;
			default:
				if (isalpha((unsigned char)**av)) {
					if (strncasecmp(*av, "SIG", 3) == 0)
						*av += 3;
					for (sig = NSIG, p = sys_signame + 1;
					     --sig; ++p)
						if (strcasecmp(*p, *av) == 0) {
							sig = p - sys_signame;
							break;
						}
					if (!sig)
						nosig(*av);
				} else if (isdigit((unsigned char)**av)) {
					sig = strtol(*av, &ep, 10);
					if (!*av || *ep)
						errx(1, "illegal signal number: %s", *av);
					if (sig < 0 || sig >= NSIG)
						nosig(*av);
				} else
					nosig(*av);
			}
			++av;
			--ac;
		} else {
			break;
		}
	}

	if (user == NULL && tty == NULL && cmd == NULL && !jflag && ac == 0)
		usage();

	if (tty) {
		if (strncmp(tty, "/dev/", 5) == 0)
			snprintf(buf, sizeof(buf), "%s", tty);
		else if (strncmp(tty, "tty", 3) == 0)
			snprintf(buf, sizeof(buf), "/dev/%s", tty);
		else
			snprintf(buf, sizeof(buf), "/dev/tty%s", tty);
		if (stat(buf, &sb) < 0)
			err(1, "stat(%s)", buf);
		if (!S_ISCHR(sb.st_mode))
			errx(1, "%s: not a character device", buf);
		tdev = sb.st_rdev;
		if (dflag)
			printf("ttydev:0x%x\n", tdev);
	}
	if (user) {
		uid = strtol(user, &ep, 10);
		if (*user == '\0' || *ep != '\0') { /* was it a number? */
			pw = getpwnam(user);
			if (pw == NULL)
				errx(1, "user %s does not exist", user);
			uid = pw->pw_uid;
			if (dflag)
				printf("uid:%d\n", uid);
		}
	} else {
		uid = getuid();
		if (uid != 0) {
			pw = getpwuid(uid);
			if (pw)
				user = pw->pw_name;
			if (dflag)
				printf("uid:%d\n", uid);
		}
	}
	size = 0;
	mib[0] = CTL_KERN;
	mib[1] = KERN_PROC;

	if (user) {
		mib[2] = eflag ? KERN_PROC_UID : KERN_PROC_RUID;
		mib[3] = uid;
		miblen = 4;
	} else if (tty) {
		mib[2] = KERN_PROC_TTY;
		mib[3] = tdev;
		miblen = 4;
	} else {
		mib[2] = KERN_PROC_PROC;
		mib[3] = 0;
		miblen = 3;
	}

	procs = NULL;
	st = sysctl(mib, miblen, NULL, &size, NULL, 0);
	do {
		size += size / 10;
		newprocs = realloc(procs, size);
		if (newprocs == NULL) {
			free(procs);
			err(1, "could not reallocate memory");
		}
		procs = newprocs;
		st = sysctl(mib, miblen, procs, &size, NULL, 0);
	} while (st == -1 && errno == ENOMEM);
	if (st == -1)
		err(1, "could not sysctl(KERN_PROC)");
	if (size % sizeof(struct kinfo_proc) != 0) {
		fprintf(stderr, "proc size mismatch (%zu total, %zu chunks)\n",
			size, sizeof(struct kinfo_proc));
		fprintf(stderr, "userland out of sync with kernel\n");
		exit(1);
	}
	nprocs = size / sizeof(struct kinfo_proc);
	if (dflag)
		printf("nprocs %d\n", nprocs);
	mypid = getpid();

	for (i = 0; i < nprocs; i++) {
		if (procs[i].ki_stat == SZOMB && !zflag)
			continue;
		thispid = procs[i].ki_pid;
		strlcpy(thiscmd, procs[i].ki_comm, sizeof(thiscmd));
		thistdev = procs[i].ki_tdev;
		if (eflag)
			thisuid = procs[i].ki_uid;	/* effective uid */
		else
			thisuid = procs[i].ki_ruid;	/* real uid */

		if (thispid == mypid)
			continue;
		matched = 1;
		if (user) {
			if (thisuid != uid)
				matched = 0;
		}
		if (tty) {
			if (thistdev != tdev)
				matched = 0;
		}
		if (cmd) {
			if (mflag) {
				if (regcomp(&rgx, cmd,
				    REG_EXTENDED|REG_NOSUB) != 0) {
					mflag = 0;
					warnx("%s: illegal regexp", cmd);
				}
			}
			if (mflag) {
				pmatch.rm_so = 0;
				pmatch.rm_eo = strlen(thiscmd);
				if (regexec(&rgx, thiscmd, 0, &pmatch,
				    REG_STARTEND) != 0)
					matched = 0;
				regfree(&rgx);
			} else {
				if (strncmp(thiscmd, cmd, MAXCOMLEN) != 0)
					matched = 0;
			}
		}
		if (jflag && thispid == getpid())
			matched = 0;
		if (matched == 0)
			continue;
		if (ac > 0)
			matched = 0;
		for (j = 0; j < ac; j++) {
			if (mflag) {
				if (regcomp(&rgx, av[j],
				    REG_EXTENDED|REG_NOSUB) != 0) {
					mflag = 0;
					warnx("%s: illegal regexp", av[j]);
				}
			}
			if (mflag) {
				pmatch.rm_so = 0;
				pmatch.rm_eo = strlen(thiscmd);
				if (regexec(&rgx, thiscmd, 0, &pmatch,
				    REG_STARTEND) == 0)
					matched = 1;
				regfree(&rgx);
			} else {
				if (strcmp(thiscmd, av[j]) == 0)
					matched = 1;
			}
			if (matched)
				break;
		}
		if (matched != 0 && Iflag) {
			printf("Send signal %d to %s (pid %d uid %d)? ",
				sig, thiscmd, thispid, thisuid);
			fflush(stdout);
			first = ch = getchar();
			while (ch != '\n' && ch != EOF)
				ch = getchar();
			if (first != 'y' && first != 'Y')
				matched = 0;
		}
		if (matched == 0)
			continue;
		if (dflag)
			printf("sig:%d, cmd:%s, pid:%d, dev:0x%x uid:%d\n", sig,
			    thiscmd, thispid, thistdev, thisuid);

		if (vflag || sflag)
			printf("kill -%s %d\n", sys_signame[sig], thispid);

		killed++;
		if (!dflag && !sflag) {
			if (kill(thispid, sig) < 0 /* && errno != ESRCH */ ) {
				warn("warning: kill -%s %d",
				    sys_signame[sig], thispid);
				errors = 1;
			}
		}
	}
	if (killed == 0) {
		fprintf(stderr, "No matching processes %swere found\n",
		    getuid() != 0 ? "belonging to you " : "");
		errors = 1;
	}
	exit(errors);
}
Ejemplo n.º 3
0
Archivo: main.c Proyecto: toddnni/pkgng
int
main(int argc, char **argv)
{
    unsigned int i;
    struct commands *command = NULL;
    unsigned int ambiguous = 0;
    const char *chroot_path = NULL;
    int jid;
    const char *jail_str = NULL;
    size_t len;
    signed char ch;
    int debug = 0;
    int ret = EX_USAGE;

    if (argc < 2)
        usage();

    pkg_event_register(&event_callback, &debug);

    while ((ch = getopt(argc, argv, "dj:c:v")) != -1) {
        switch(ch) {
        case 'd':
            debug++;
            break;
        case 'c':
            chroot_path = optarg;
            break;
        case 'j':
            jail_str = optarg;
            break;
        case 'v':
            printf("%s %s\n", PKGVERSION, GITHASH);
            exit(EXIT_SUCCESS);
            break; /* NOT REACHED */
        default:
            break;
        }
    }
    argc -= optind;
    argv += optind;

    if (argc == 0)
        usage();

    /* reset getopt for the next call */
    optreset = 1;
    optind = 1;

    if (jail_str != NULL && chroot_path != NULL) {
        fprintf(stderr, "-j and -c cannot be used at the same time\n");
        usage();
    }

    if (chroot_path != NULL)
        if (chroot(chroot_path) == -1)
            errx(EX_SOFTWARE, "chroot failed");

    if (jail_str != NULL) {
        jid = jail_getid(jail_str);
        if (jid < 0)
            errx(1, "%s", jail_errmsg);

        if (jail_attach(jid) == -1)
            err(1, "jail_attach(%s)", jail_str);
    }

    if (jail_str != NULL || chroot_path != NULL)
        if (chdir("/") == -1)
            errx(EX_SOFTWARE, "chdir() failed");

    if (pkg_init(NULL) != EPKG_OK)
        errx(EX_SOFTWARE, "can not parse configuration file");

    len = strlen(argv[0]);
    for (i = 0; i < cmd_len; i++) {
        if (strncmp(argv[0], cmd[i].name, len) == 0) {
            /* if we have the exact cmd */
            if (len == strlen(cmd[i].name)) {
                command = &cmd[i];
                ambiguous = 0;
                break;
            }

            /*
             * we already found a partial match so `argv[0]' is
             * an ambiguous shortcut
             */
            ambiguous++;

            command = &cmd[i];
        }
    }

    if (command == NULL) {
        pkg_shutdown();
        usage();
        return (ret); /* Not reached but makes scanbuild happy */
    }

    if (ambiguous <= 1) {
        assert(command->exec != NULL);
        ret = command->exec(argc, argv);
    } else {
        warnx("'%s' is not a valid command.\n", argv[0]);

        fprintf(stderr, "See 'pkg help' for more information on the commands.\n\n");
        fprintf(stderr, "Command '%s' could be one of the following:\n", argv[0]);

        for (i = 0; i < cmd_len; i++)
            if (strncmp(argv[0], cmd[i].name, len) == 0)
                fprintf(stderr, "\t%s\n",cmd[i].name);
    }

    pkg_shutdown();
    return (ret);
}
Ejemplo n.º 4
0
int
main(int argc, char **argv)
{
	struct jailparam params[MAXPARAMS];
	char ifname[IFNAMSIZ];
	struct ifreq ifreq;
	vi_cmd_t newcmd, cmd;
	int recurse = 0;
	int verbose = 0;
	int jid, i, s, namelen;
	int vst_size, vst_last;
	vstat_t *vst;
	char *str;
	char ch;

	invocname = argv[0];

	newcmd = cmd = VI_SWITCHTO; /* Default if no modifiers specified. */
	while ((ch = getopt(argc, argv, "cdijlmrv")) != -1) {
		switch (ch) {
		case 'c':
			newcmd = VI_CREATE;
			break;
		case 'm':
			newcmd = VI_MODIFY;
			break;
		case 'd':
			newcmd = VI_DESTROY;
			break;
		case 'l':
			newcmd = VI_GET;
			break;
		case 'i':
			newcmd = VI_IFMOVE;
			break;
		case 'r':
			recurse = 1;
			break;
		case 'v':
			verbose++;
			break;
		case 'j':
			verbose = 2;
			break;
		default:
			usage();
		}
		if (cmd == VI_SWITCHTO || cmd == newcmd)
			cmd = newcmd;
		else
			usage();
	}
	argc -= optind;
	argv += optind;

	if ((cmd != VI_GET && (argc == 0 || recurse != 0 || verbose != 0)) ||
	    (cmd == VI_IFMOVE && (argc < 2 || argc > 3)) ||
	    (cmd == VI_MODIFY && argc < 2) || argc >= MAXPARAMS)
		usage();

	switch (cmd) {
	case VI_GET:
		vst_last = 0;
		vst_size = VST_SIZE_STEP;
		if ((vst = malloc(vst_size * sizeof(*vst))) == NULL)
			break;
		if (argc == 1)
			namelen = strlen(argv[0]);
		else
			namelen = 0;
		jid = 0;
		while ((jid = getjail(&vst[vst_last], jid, verbose)) > 0) {
			/* Skip jails which do not own vnets. */
			if (vst[vst_last].vnet != 1)
				continue;
			/* Skip non-matching vnames / hierarchies. */
			if (namelen &&
			    ((strlen(vst[vst_last].name) < namelen ||
			    strncmp(vst[vst_last].name, argv[0], namelen) != 0)
			    || (strlen(vst[vst_last].name) > namelen &&
			    vst[vst_last].name[namelen] != '.')))
				continue;
			/* Skip any sub-trees if -r not requested. */
			if (!recurse &&
			    (strlen(vst[vst_last].name) < namelen ||
			    strchr(&vst[vst_last].name[namelen], '.') != NULL))
				continue;
			/* Grow vst table if necessary. */
			if (++vst_last == vst_size) {
				vst_size += VST_SIZE_STEP;
				vst = realloc(vst, vst_size * sizeof(*vst));
				if (vst == NULL)
					break;
			}
		}
		if (vst == NULL)
			break;
		/* Sort: the key is the 1st field in *vst, i.e. vimage name. */
		qsort(vst, vst_last, sizeof(*vst), (void *) strcmp);
		for (i = 0; i < vst_last; i++) {
			if (!verbose) {
				printf("%s\n", vst[i].name);
				continue;
			}

			printf("%s:\n", vst[i].name);
			printf("    Path: %s\n", vst[i].path);
			printf("    Hostname: %s\n", vst[i].hostname);
			printf("    Domainname: %s\n", vst[i].domainname);
			printf("    Children: %d\n", vst[i].childcnt);

			if (verbose < 2)
				continue;

			printf("    Children limit: %d\n", vst[i].childmax);
			printf("    CPUsetID: %d\n", vst[i].cpuset);
			printf("    JID: %d\n", vst[i].jid);
			printf("    PJID: %d\n", vst[i].parentjid);
			printf("    Raw sockets allowed: %d\n", vst[i].rawsock);
			printf("    All AF allowed: %d\n", vst[i].socket_af);
			printf("    Mount allowed: %d\n", vst[i].mount);
		}
		free(vst);
		exit(0);

	case VI_IFMOVE:
		if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
			break;
		if ((jid = jail_getid(argv[0])) < 0)
			break;
		ifreq.ifr_jid = jid;
		strncpy(ifreq.ifr_name, argv[1], sizeof(ifreq.ifr_name));
		if (ioctl(s, SIOCSIFVNET, (caddr_t)&ifreq) < 0)
			break;
		close(s);
		if (argc == 3)
			snprintf(ifname, sizeof(ifname), "%s", argv[2]);
		else
			snprintf(ifname, sizeof(ifname), "eth0");
		ifreq.ifr_data = ifname;
		/* Do we need to rename the ifnet? */
		if (strcmp(ifreq.ifr_name, ifname) != 0) {
			/* Switch to the context of the target vimage. */
			if (jail_attach(jid) < 0)
				break;
			if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
				break;
			for (namelen = 0; isalpha(ifname[namelen]); namelen++);
			i = 0;
			/* Search for a free ifunit in target vnet.  Unsafe. */
			while (ioctl(s, SIOCSIFNAME, (caddr_t)&ifreq) < 0) {
				snprintf(&ifname[namelen],
				    sizeof(ifname) - namelen, "%d", i);
				/* Emergency brake. */
				if (i++ == IF_MAXUNIT)
					break;
			}
		}
		if (i < IF_MAXUNIT)
			printf("%s@%s\n", ifname, argv[0]);
		else
			printf("%s@%s\n", ifreq.ifr_name, argv[0]);
		exit(0);

	case VI_CREATE:
		if (jail_setv(JAIL_CREATE,
		    "name", argv[0],
		    "vnet", NULL,
		    "host", NULL,
		    "persist", NULL,
		    "allow.raw_sockets", "true",
		    "allow.socket_af", "true",
		    "allow.mount", "true",
		    NULL) < 0)
			break;
		if (argc == 1)
			exit(0);
		/* Not done yet, proceed to apply non-default parameters. */

	case VI_MODIFY:
		jailparam_init(&params[0], "name");
		jailparam_import(&params[0], argv[0]);
		for (i = 1; i < argc; i++) {
			for (str = argv[i]; *str != '=' && *str != 0; str++) {
				/* Do nothing - search for '=' delimeter. */
			}
			if (*str == 0)
				break;
			*str++ = 0;
			if (*str == 0)
				break;
			jailparam_init(&params[i], argv[i]);
			jailparam_import(&params[i], str);
		}
		if (i != argc)
			break;
		if (jailparam_set(params, i, JAIL_UPDATE) < 0)
			break;
		exit(0);

	case VI_DESTROY:
		if ((jid = jail_getid(argv[0])) < 0)
			break;
		if (jail_remove(jid) < 0)
			break;
		exit(0);

	case VI_SWITCHTO:
		if ((jid = jail_getid(argv[0])) < 0)
			break;
		if (jail_attach(jid) < 0)
			break;
		if (argc == 1) {
			printf("Switched to vimage %s\n", argv[0]);
			if ((str = getenv("SHELL")) == NULL)
				execlp("/bin/sh", invocname, NULL);
			else
				execlp(str, invocname, NULL);
		} else 
			execvp(argv[1], &argv[1]);
		break;

	default:
		/* Should be unreachable. */
		break;
	}

	if (jail_errmsg[0])
		fprintf(stderr, "Error: %s\n", jail_errmsg);
	else
		perror("Error");
	exit(1);
}
Ejemplo n.º 5
0
int
main(int ac, char **av)
{
	struct kinfo_proc *procs = NULL, *newprocs;
	struct stat	sb;
	struct passwd	*pw;
	regex_t		rgx;
	regmatch_t	pmatch;
	int		i, j;
	char		buf[256];
	char		*user = NULL;
	char		*tty = NULL;
	char		*cmd = NULL;
	int		vflag = 0;
	int		sflag = 0;
	int		dflag = 0;
	int		eflag = 0;
#ifndef __APPLE__
	int		jflag = 0;
#endif /* !__APPLE__*/
	int		mflag = 0;
	int		zflag = 0;
	uid_t		uid = 0;
	dev_t		tdev = 0;
	pid_t		mypid;
#ifdef __APPLE__
	char		*thiscmd;
#else /* !__APPLE__ */
	char		thiscmd[MAXCOMLEN + 1];
#endif /* __APPLE__ */
	pid_t		thispid;
#ifndef __APPLE__
	uid_t		thisuid;
#endif /* !__APPLE__ */
	dev_t		thistdev;
	int		sig = SIGTERM;
	char		*ep;
	int		errors = 0;
#ifndef __APPLE__
	int		jid;
#endif /* !__APPLE__ */
	int		mib[4];
	size_t		miblen;
	int		st, nprocs;
	size_t		size;
	int		matched;
	int		killed = 0;
	int		ch;

	setlocale(LC_ALL, "");

	kludge_signal_args(&ac, av, &sig);

	while ((ch = getopt(ac, av, OPTIONS)) != -1) {
		switch (ch) {
		case 'c':
			cmd = optarg;
			break;
		case 'd':
			dflag++;
			break;
		case 'e':
			eflag++;
			break;
#ifndef __APPLE__
		case 'j':
			jflag++;
			jid = strtol(optarg, &ep, 10);
			if (*ep)
				errx(1, "illegal jid: %s", optarg);
			if (jail_attach(jid) == -1)
				err(1, "jail_attach(): %d", jid);
			break;
#endif /* __APPLE__ */
		case 'l':
			printsig(stdout);
			exit(0);
		case 'm':
			mflag++;
			break;
		case 's':
			sflag++;
			break;
		case 't':
			tty = optarg;
			break;
		case 'u':
			user = optarg;
			break;
		case 'v':
			vflag++;
			break;
		case 'z':
			zflag++;
			break;
		default:
			usage();
		}
	}

	ac -= optind;
	av += optind;

#ifdef __APPLE__
	if (user == NULL && tty == NULL && cmd == NULL && ac == 0)
#else /* !__APPLE__*/
	if (user == NULL && tty == NULL && cmd == NULL && !jflag && ac == 0)
#endif /* __APPLE__ */
		usage();

	if (tty) {
		if (strncmp(tty, "/dev/", 5) == 0)
			snprintf(buf, sizeof(buf), "%s", tty);
		else if (strncmp(tty, "tty", 3) == 0)
			snprintf(buf, sizeof(buf), "/dev/%s", tty);
		else
			snprintf(buf, sizeof(buf), "/dev/tty%s", tty);
		if (stat(buf, &sb) < 0)
			err(1, "stat(%s)", buf);
		if (!S_ISCHR(sb.st_mode))
			errx(1, "%s: not a character device", buf);
		tdev = sb.st_rdev;
		if (dflag)
			printf("ttydev:0x%x\n", tdev);
	}
	if (user) {
		uid = strtol(user, &ep, 10);
		if (*user == '\0' || *ep != '\0') { /* was it a number? */
			pw = getpwnam(user);
			if (pw == NULL)
				errx(1, "user %s does not exist", user);
			uid = pw->pw_uid;
			if (dflag)
				printf("uid:%d\n", uid);
		}
	} else {
		uid = getuid();
		if (uid != 0) {
			pw = getpwuid(uid);
			if (pw)
				user = pw->pw_name;
			if (dflag)
				printf("uid:%d\n", uid);
		}
	}
	size = 0;
	mib[0] = CTL_KERN;
	mib[1] = KERN_PROC;
#ifdef __APPLE__
	mib[2] = KERN_PROC_ALL;
#else /* !__APPLE__ */
	mib[2] = KERN_PROC_PROC;
#endif /* __APPLE__ */
	mib[3] = 0;
	miblen = 3;

	if (user) {
		mib[2] = eflag ? KERN_PROC_UID : KERN_PROC_RUID;
		mib[3] = uid;
		miblen = 4;
	} else if (tty) {
		mib[2] = KERN_PROC_TTY;
		mib[3] = tdev;
		miblen = 4;
	}

	st = sysctl(mib, miblen, NULL, &size, NULL, 0);
	do {
		size += size / 10;
		newprocs = realloc(procs, size);
		if (newprocs == 0) {
			if (procs)
				free(procs);
			errx(1, "could not reallocate memory");
		}
		procs = newprocs;
		st = sysctl(mib, miblen, procs, &size, NULL, 0);
	} while (st == -1 && errno == ENOMEM);
	if (st == -1)
		err(1, "could not sysctl(KERN_PROC)");
	if (size % sizeof(struct kinfo_proc) != 0) {
		fprintf(stderr, "proc size mismatch (%zu total, %zu chunks)\n",
			size, sizeof(struct kinfo_proc));
		fprintf(stderr, "userland out of sync with kernel, recompile libkvm etc\n");
		exit(1);
	}
	nprocs = size / sizeof(struct kinfo_proc);
	if (dflag)
		printf("nprocs %d\n", nprocs);
	mypid = getpid();

	for (i = 0; i < nprocs; i++) {
#ifdef __APPLE__
		if (procs[i].kp_proc.p_stat == SZOMB && !zflag)
			continue;
		thispid = procs[i].kp_proc.p_pid;

		int mib[3], argmax;
		size_t syssize;
		char *procargs, *cp;

		mib[0] = CTL_KERN;
		mib[1] = KERN_ARGMAX;

		syssize = sizeof(argmax);
		if (sysctl(mib, 2, &argmax, &syssize, NULL, 0) == -1)
			continue;

		procargs = malloc(argmax);
		if (procargs == NULL)
			continue;

		mib[0] = CTL_KERN;
#if defined(__APPLE__) && TARGET_OS_EMBEDDED
		mib[1] = KERN_PROCARGS2;
#else
		mib[1] = KERN_PROCARGS;
#endif
		mib[2] = thispid;

		syssize = (size_t)argmax;
		if (sysctl(mib, 3, procargs, &syssize, NULL, 0) == -1) {
			free(procargs);
			continue;
		}

		for (cp = procargs; cp < &procargs[syssize]; cp++) {
			if (*cp == '\0') {
				break;
			}
		}

		if (cp == &procargs[syssize]) {
			free(procargs);
			continue;
		}

		for (; cp < &procargs[syssize]; cp++) {
			if (*cp != '\0') {
				break;
			}
		}

		if (cp == &procargs[syssize]) {
			free(procargs);
			continue;
		}

		/* Strip off any path that was specified */
		for (thiscmd = cp; (cp < &procargs[syssize]) && (*cp != '\0'); cp++) {
			if (*cp == '/') {
				thiscmd = cp + 1;
			}
		}

		thistdev = procs[i].kp_eproc.e_tdev;
#else /* !__APPLE__ */
		if (procs[i].ki_stat == SZOMB && !zflag)
			continue;
		thispid = procs[i].ki_pid;
		strncpy(thiscmd, procs[i].ki_comm, MAXCOMLEN);
		thiscmd[MAXCOMLEN] = '\0';
		thistdev = procs[i].ki_tdev;
#endif /* __APPLE__ */
#ifndef __APPLE__
		if (eflag)
			thisuid = procs[i].ki_uid;	/* effective uid */
		else
			thisuid = procs[i].ki_ruid;	/* real uid */
#endif /* !__APPLE__ */

		if (thispid == mypid) {
#ifdef __APPLE__
			free(procargs);
#endif /* __APPLE__ */
			continue;
		}
		matched = 1;
#ifndef __APPLE__
		if (user) {
			if (thisuid != uid)
				matched = 0;
		}
#endif /* !__APPLE__ */
		if (tty) {
			if (thistdev != tdev)
				matched = 0;
		}
		if (cmd) {
			if (mflag) {
				if (regcomp(&rgx, cmd,
				    REG_EXTENDED|REG_NOSUB) != 0) {
					mflag = 0;
					warnx("%s: illegal regexp", cmd);
				}
			}
			if (mflag) {
				pmatch.rm_so = 0;
				pmatch.rm_eo = strlen(thiscmd);
				if (regexec(&rgx, thiscmd, 0, &pmatch,
				    REG_STARTEND) != 0)
					matched = 0;
				regfree(&rgx);
			} else {
				if (strncmp(thiscmd, cmd, MAXCOMLEN) != 0)
					matched = 0;
			}
		}
#ifndef __APPLE__
		if (jflag && thispid == getpid())
			matched = 0;
#endif /* !__APPLE__ */
		if (matched == 0) {
#ifdef __APPLE__
			free(procargs);
#endif /* !__APPLE__ */
			continue;
		}
		if (ac > 0)
			matched = 0;
		for (j = 0; j < ac; j++) {
			if (mflag) {
				if (regcomp(&rgx, av[j],
				    REG_EXTENDED|REG_NOSUB) != 0) {
					mflag = 0;
					warnx("%s: illegal regexp", av[j]);
				}
			}
			if (mflag) {
				pmatch.rm_so = 0;
				pmatch.rm_eo = strlen(thiscmd);
				if (regexec(&rgx, thiscmd, 0, &pmatch,
				    REG_STARTEND) == 0)
					matched = 1;
				regfree(&rgx);
			} else {
				if (strcmp(thiscmd, av[j]) == 0)
					matched = 1;
			}
			if (matched)
				break;
		}
		if (matched == 0) {
#ifdef __APPLE__
			free(procargs);
#endif /* __APPLE__ */
			continue;
		}
		if (dflag)
#ifdef __APPLE__
			printf("sig:%d, cmd:%s, pid:%d, dev:0x%x\n", sig,
			    thiscmd, thispid, thistdev);
#else /* !__APPLE__ */
			printf("sig:%d, cmd:%s, pid:%d, dev:0x%x uid:%d\n", sig,
			    thiscmd, thispid, thistdev, thisuid);
#endif /* __APPLE__ */

		if (vflag || sflag)
			printf("kill -%s %d\n", upper(sys_signame[sig]),
			    thispid);

		killed++;
		if (!dflag && !sflag) {
			if (kill(thispid, sig) < 0 /* && errno != ESRCH */ ) {
				warn("warning: kill -%s %d",
				    upper(sys_signame[sig]), thispid);
				errors = 1;
			}
		}
#ifdef __APPLE__
		free(procargs);
#endif /* __APPLE__ */
	}
	if (killed == 0) {
		fprintf(stderr, "No matching processes %swere found\n",
		    getuid() != 0 ? "belonging to you " : "");
		errors = 1;
	}
	exit(errors);
}
Ejemplo n.º 6
0
int
main(int argc, char *argv[])
{
	int jid;
	login_cap_t *lcap = NULL;
	struct passwd *pwd = NULL;
	gid_t *groups = NULL;
	int ch, ngroups, uflag, Uflag;
	long ngroups_max;
	char *username;

	ch = uflag = Uflag = 0;
	username = NULL;
	ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
	if ((groups = malloc(sizeof(gid_t) * ngroups_max)) == NULL)
		err(1, "malloc");

	while ((ch = getopt(argc, argv, "nu:U:")) != -1) {
		switch (ch) {
		case 'n':
			/* Specified name, now unused */
			break;
		case 'u':
			username = optarg;
			uflag = 1;
			break;
		case 'U':
			username = optarg;
			Uflag = 1;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	if (argc < 2)
		usage();
	if (uflag && Uflag)
		usage();
	if (uflag)
		GET_USER_INFO;
	jid = jail_getid(argv[0]);
	if (jid < 0)
		errx(1, "%s", jail_errmsg);
	if (jail_attach(jid) == -1)
		err(1, "jail_attach(%d)", jid);
	if (chdir("/") == -1)
		err(1, "chdir(): /");
	if (username != NULL) {
		if (Uflag)
			GET_USER_INFO;
		if (setgroups(ngroups, groups) != 0)
			err(1, "setgroups");
		if (setgid(pwd->pw_gid) != 0)
			err(1, "setgid");
		if (setusercontext(lcap, pwd, pwd->pw_uid,
		    LOGIN_SETALL & ~LOGIN_SETGROUP & ~LOGIN_SETLOGIN) != 0)
			err(1, "setusercontext");
		login_close(lcap);
	}
	if (execvp(argv[1], argv + 1) == -1)
		err(1, "execvp(): %s", argv[1]);
	exit(0);
}
Ejemplo n.º 7
0
int
main(int argc, char *argv[])
{
	int jid;
	login_cap_t *lcap = NULL;
	int ch, clean, uflag, Uflag;
	char *cleanenv;
	const struct passwd *pwd = NULL;
	const char *username, *shell, *term;

	ch = clean = uflag = Uflag = 0;
	username = NULL;

	while ((ch = getopt(argc, argv, "lnu:U:")) != -1) {
		switch (ch) {
		case 'l':
			clean = 1;
			break;
		case 'n':
			/* Specified name, now unused */
			break;
		case 'u':
			username = optarg;
			uflag = 1;
			break;
		case 'U':
			username = optarg;
			Uflag = 1;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	if (argc < 1)
		usage();
	if (uflag && Uflag)
		usage();
	if (uflag || (clean && !Uflag))
		/* User info from the home environment */
		get_user_info(username, &pwd, &lcap);

	/* Attach to the jail */
	jid = jail_getid(argv[0]);
	if (jid < 0)
		errx(1, "%s", jail_errmsg);
	if (jail_attach(jid) == -1)
		err(1, "jail_attach(%d)", jid);
	if (chdir("/") == -1)
		err(1, "chdir(): /");

	/* Set up user environment */
	if (clean || username != NULL) {
		if (Uflag)
			/* User info from the jail environment */
			get_user_info(username, &pwd, &lcap);
		if (clean) {
			term = getenv("TERM");
			cleanenv = NULL;
			environ = &cleanenv;
			setenv("PATH", "/bin:/usr/bin", 1);
			if (term != NULL)
				setenv("TERM", term, 1);
		}
		if (setgid(pwd->pw_gid) != 0)
			err(1, "setgid");
		if (setusercontext(lcap, pwd, pwd->pw_uid, username
		    ? LOGIN_SETALL & ~LOGIN_SETGROUP & ~LOGIN_SETLOGIN
		    : LOGIN_SETPATH | LOGIN_SETENV) != 0)
			err(1, "setusercontext");
		login_close(lcap);
		setenv("USER", pwd->pw_name, 1);
		setenv("HOME", pwd->pw_dir, 1);
		setenv("SHELL",
		    *pwd->pw_shell ? pwd->pw_shell : _PATH_BSHELL, 1);
		if (clean && chdir(pwd->pw_dir) < 0)
			err(1, "chdir: %s", pwd->pw_dir);
		endpwent();
	}

	/* Run the specified command, or the shell */
	if (argc > 1) {
		if (execvp(argv[1], argv + 1) < 0)
			err(1, "execvp: %s", argv[1]);
	} else {
		if (!(shell = getenv("SHELL")))
			shell = _PATH_BSHELL;
		if (execlp(shell, shell, "-i", NULL) < 0)
			err(1, "execlp: %s", shell);
	}
	exit(0);
}