Example #1
0
int
main(int argc, char *argv[])
{
	int ch, rv, action = VND_CONFIG;

	while ((ch = getopt(argc, argv, "Fcf:lrt:uvz")) != -1) {
		switch (ch) {
		case 'F':
			force = 1;
			break;
		case 'c':
			action = VND_CONFIG;
			break;
		case 'f':
			if (setdisktab(optarg) == -1)
				usage();
			break;
		case 'l':
			action = VND_GET;
			break;
		case 'r':
			readonly = 1;
			break;
		case 't':
			tabname = optarg;
			break;
		case 'u':
			action = VND_UNCONFIG;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'z':
			compressed = 1;
			readonly = 1;
			break;
		default:
		case '?':
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	if (action == VND_CONFIG) {
		if ((argc < 2 || argc > 3) ||
		    (argc == 3 && tabname != NULL))
			usage();
		rv = config(argv[0], argv[1], (argc == 3) ? argv[2] : NULL,
		    action);
	} else if (action == VND_UNCONFIG) {
		if (argc != 1 || tabname != NULL)
			usage();
		rv = config(argv[0], NULL, NULL, action);
	} else { /* VND_GET */
		int n, v;
		const char *vn;
		char path[64];

		if (argc != 0 && argc != 1)
			usage();

		vn = argc ? argv[0] : "vnd0";

		v = opendisk(vn, O_RDONLY, path, sizeof(path), 0);
		if (v == -1)
			err(1, "open: %s", vn);

		if (argc)
			show(v, -1);
		else {
			DIR *dirp;
			struct dirent *dp;
			__BITMAP_TYPE(, uint32_t, 65536) bm;

			__BITMAP_ZERO(&bm);

			if ((dirp = opendir(_PATH_DEV)) == NULL)
				err(1, "opendir: %s", _PATH_DEV);

			while ((dp = readdir(dirp)) != NULL) {
				if (strncmp(dp->d_name, "rvnd", 4) != 0)
					continue;
				n = atoi(dp->d_name + 4);
				if (__BITMAP_ISSET(n, &bm))
					continue;
				__BITMAP_SET(n, &bm);
				show(v, n);
			}

			closedir(dirp);
		}
		close(v);
		rv = 0;
	}
	return rv;
}
Example #2
0
/*
 * Check whether the port picked by the port randomizer is available
 * and whether KAUTH approves of our choice. This part of the code
 * shamelessly copied from in_pcb.c.
 */
static bool
check_suitable_port(uint16_t port, struct inpcb_hdr *inp_hdr, kauth_cred_t cred)
{
	struct inpcbtable * const table = inp_hdr->inph_table;
#ifdef INET
	vestigial_inpcb_t vestigial;
#endif
	int error;
#ifdef INET6
	struct socket *so;
	int wild = 0;
#endif

	DPRINTF("%s called for argument %d\n", __func__, port);

	switch (inp_hdr->inph_af) {
#ifdef INET
	case AF_INET: { /* IPv4 */
		struct inpcb *inp = (struct inpcb *)(void *)inp_hdr;
		struct inpcb *pcb;
		struct sockaddr_in sin;

		if (__BITMAP_ISSET(port, &inet4_reserve))
			return false;

		sin.sin_addr = inp->inp_laddr;
		pcb = in_pcblookup_port(table, sin.sin_addr, htons(port), 1,
		    &vestigial);

		DPRINTF("%s in_pcblookup_port returned %p and "
		    "vestigial.valid %d\n",
		    __func__, pcb, vestigial.valid);

		if ((!pcb) && (!vestigial.valid)) {
			enum kauth_network_req req;

			/* We have a free port. Check with the secmodel. */
			if (inp->inp_flags & INP_LOWPORT) {
#ifndef IPNOPRIVPORTS
				req = KAUTH_REQ_NETWORK_BIND_PRIVPORT;
#else
				req = KAUTH_REQ_NETWORK_BIND_PORT;
#endif
			} else
				req = KAUTH_REQ_NETWORK_BIND_PORT;

			sin.sin_port = port;
			error = kauth_authorize_network(cred,
			    KAUTH_NETWORK_BIND,
			    req, inp->inp_socket, &sin, NULL);
			DPRINTF("%s kauth_authorize_network returned %d\n",
			    __func__, error);

			if (error == 0) {
				DPRINTF("%s port approved\n", __func__);
				return true;	/* KAUTH agrees */
			}
		}
		break;
	}
#endif
#ifdef INET6
	case AF_INET6: { /* IPv6 */
		struct in6pcb *in6p = (struct in6pcb *)(void *)inp_hdr;
		struct sockaddr_in6 sin6;
		void *t;

		if (__BITMAP_ISSET(port, &inet6_reserve))
			return false;

		sin6.sin6_addr = in6p->in6p_laddr;
		so = in6p->in6p_socket;

		/* XXX: this is redundant when called from in6_pcbbind */
		if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 &&
		    ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
			(so->so_options & SO_ACCEPTCONN) == 0))
			wild = 1;

#ifdef INET
		if (IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
			t = in_pcblookup_port(table,
			    *(struct in_addr *)&sin6.sin6_addr.s6_addr32[3],
			    htons(port), wild, &vestigial);
			if (!t && vestigial.valid) {
				DPRINTF("%s in_pcblookup_port returned "
				    "a result\n", __func__);
				return false;
			}
		} else
#endif
		{
			t = in6_pcblookup_port(table, &sin6.sin6_addr,
			    htons(port), wild, &vestigial);
			if (!t && vestigial.valid) {
				DPRINTF("%s in6_pcblookup_port returned "
				    "a result\n", __func__);
				return false;
			}
		}
		if (t == NULL) {
			enum kauth_network_req req;

			/* We have a free port. Check with the secmodel. */
			if (in6p->in6p_flags & IN6P_LOWPORT) {
#ifndef IPNOPRIVPORTS
				req = KAUTH_REQ_NETWORK_BIND_PRIVPORT;
#else
				req = KAUTH_REQ_NETWORK_BIND_PORT;
#endif
			} else {
				req = KAUTH_REQ_NETWORK_BIND_PORT;
			}

			sin6.sin6_port = port;
			error = kauth_authorize_network(cred,
			    KAUTH_NETWORK_BIND, req, so, &sin6, NULL);
			if (error) {
				/* Secmodel says no. Keep looking. */
				DPRINTF("%s secmodel says no\n", __func__);
				return false;
			}
			DPRINTF("%s port approved\n", __func__);
			return true;
		}
		break;
	}
#endif
	default:
		DPRINTF("%s unknown address family\n", __func__);
		return false;
	}
	return false;
}