Esempio n. 1
0
void
abort()
{
	struct sigaction act;

	/*
	 * POSIX requires we flush stdio buffers on abort.
	 * XXX ISO C requires that abort() be async-signal-safe.
	 */
	if (__cleanup)
		(*__cleanup)();

	sigfillset(&act.sa_mask);
	/*
	 * Don't block SIGABRT to give any handler a chance; we ignore
	 * any errors -- ISO C doesn't allow abort to return anyway.
	 */
	sigdelset(&act.sa_mask, SIGABRT);
	(void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
	(void)raise(SIGABRT);

	/*
	 * If SIGABRT was ignored, or caught and the handler returns, do
	 * it again, only harder.
	 */
	act.sa_handler = SIG_DFL;
	act.sa_flags = 0;
	sigfillset(&act.sa_mask);
	(void)_sigaction(SIGABRT, &act, NULL);
	sigdelset(&act.sa_mask, SIGABRT);
	(void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
	(void)raise(SIGABRT);
	exit(1);
}
Esempio n. 2
0
int
ucbsigblock(int mask)
{
	sigset_t oset;
	sigset_t nset;

	(void) _sigprocmask(0, (sigset_t *)0, &nset);
	mask2set(mask, &nset);
	(void) _sigprocmask(SIG_BLOCK, &nset, &oset);
	return (set2mask(&oset));
}
Esempio n. 3
0
int
ucbsigpause(int mask)
{
	sigset_t set, oset;
	int ret;

	(void) _sigprocmask(0, (sigset_t *)0, &set);
	oset = set;
	mask2set(mask, &set);
	ret = sigsuspend(&set);
	(void) _sigprocmask(SIG_SETMASK, &oset, (sigset_t *)0);
	return (ret);
}
Esempio n. 4
0
/*
 * Save the calling context in (oucp) then switch to (ucp).
 *
 * Block all signals while switching contexts.  get_mcontext() returns zero
 * when retrieving a context.
 *
 * When some other thread calls set_mcontext() to resume our thread, 
 * the resume point causes get_mcontext() to return non-zero to us.
 * Signals will be blocked and we must restore the signal mask before
 * returning.
 */
int
_swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
{
	int ret;

	ret = _sigprocmask(SIG_BLOCK, &sigset_block_all, &oucp->uc_sigmask);
	if (ret == 0) {
		if (get_mcontext(&oucp->uc_mcontext) == 0) {
			ret = set_mcontext(&ucp->uc_mcontext);
		} else {
			ret = _sigprocmask(SIG_SETMASK, &oucp->uc_sigmask, NULL);
		}
	}
	return(ret);
}
Esempio n. 5
0
int
__system(const char *command)
{
	pid_t pid, savedpid;
	int pstat;
	struct sigaction ign, intact, quitact;
	sigset_t newsigblock, oldsigblock;

	if (!command)		/* just checking... */
		return(1);

	(void)sigemptyset(&newsigblock);
	(void)sigaddset(&newsigblock, SIGCHLD);
	(void)sigaddset(&newsigblock, SIGINT);
	(void)sigaddset(&newsigblock, SIGQUIT);
	(void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
	switch(pid = vfork()) {
	case -1:			/* error */
		(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
		return (-1);
	case 0:				/* child */
		/*
		 * Restore original signal dispositions and exec the command.
		 */
		(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
		execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL);
		_exit(127);
	}
	/* 
	 * If we are running means that the child has either completed
	 * its execve, or has failed.
	 * Block SIGINT/QUIT because sh -c handles it and wait for
	 * it to clean up.
	 */
	memset(&ign, 0, sizeof(ign));
	ign.sa_handler = SIG_IGN;
	(void)sigemptyset(&ign.sa_mask);
	(void)_sigaction(SIGINT, &ign, &intact);
	(void)_sigaction(SIGQUIT, &ign, &quitact);
	savedpid = pid;
	do {
		pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0);
	} while (pid == -1 && errno == EINTR);
	(void)_sigaction(SIGINT, &intact, NULL);
	(void)_sigaction(SIGQUIT,  &quitact, NULL);
	(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
	return(pid == -1 ? -1 : pstat);
}
Esempio n. 6
0
int
__system(const char *command)
{
	pid_t pid, savedpid;
	int pstat;
	struct sigaction ign, intact, quitact;
	sigset_t newsigblock, oldsigblock;

	if (!command)		/* just checking... */
		return(1);

	/*
	 * Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save
	 * existing signal dispositions.
	 */
	ign.sa_handler = SIG_IGN;
	(void)sigemptyset(&ign.sa_mask);
	ign.sa_flags = 0;
	(void)_sigaction(SIGINT, &ign, &intact);
	(void)_sigaction(SIGQUIT, &ign, &quitact);
	(void)sigemptyset(&newsigblock);
	(void)sigaddset(&newsigblock, SIGCHLD);
	(void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
	switch(pid = fork()) {
	case -1:			/* error */
		break;
	case 0:				/* child */
		/*
		 * Restore original signal dispositions and exec the command.
		 */
		(void)_sigaction(SIGINT, &intact, NULL);
		(void)_sigaction(SIGQUIT,  &quitact, NULL);
		(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
		execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL);
		_exit(127);
	default:			/* parent */
		savedpid = pid;
		do {
			pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0);
		} while (pid == -1 && errno == EINTR);
		break;
	}
	(void)_sigaction(SIGINT, &intact, NULL);
	(void)_sigaction(SIGQUIT,  &quitact, NULL);
	(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
	return(pid == -1 ? -1 : pstat);
}
Esempio n. 7
0
/*
 * Backwards compatible pause.
 */
int
__pause()
{
	sigset_t oset;

	if (_sigprocmask(SIG_BLOCK, NULL, &oset) == -1)
		return (-1);
	return (_sigsuspend(&oset));
}
Esempio n. 8
0
FILE *
tmpfile()
{
	sigset_t set, oset;
	FILE *fp;
	int fd, sverrno;
#define	TRAILER	"tmp.XXXXXX"
	char *buf;
	const char *tmpdir;

	tmpdir = NULL;
	if (issetugid() == 0)
		tmpdir = getenv("TMPDIR");
	if (tmpdir == NULL)
		tmpdir = _PATH_TMP;

	(void)asprintf(&buf, "%s%s%s", tmpdir,
	    (tmpdir[strlen(tmpdir) - 1] == '/') ? "" : "/", TRAILER);
	if (buf == NULL)
		return (NULL);

	sigfillset(&set);
	(void)_sigprocmask(SIG_BLOCK, &set, &oset);

	fd = mkstemp(buf);
	if (fd != -1)
		(void)unlink(buf);

	free(buf);

	(void)_sigprocmask(SIG_SETMASK, &oset, NULL);

	if (fd == -1)
		return (NULL);

	if ((fp = fdopen(fd, "w+")) == NULL) {
		sverrno = errno;
		(void)_close(fd);
		errno = sverrno;
		return (NULL);
	}
	return (fp);
}
Esempio n. 9
0
/*
 * Switch to the target context.  The current signal mask is saved in ucp
 * and all signals are blocked.  The call to set_mcontext() causes the
 * specified context to be switched to (usually resuming as a return from
 * the get_mcontext() procedure).  The current context is thrown away.
 *
 * The target context being resumed is responsible for restoring the
 * signal mask appropriate for the target context.
 */
int
_setcontext(ucontext_t *ucp)
{
	int ret;

	ret = _sigprocmask(SIG_BLOCK, &sigset_block_all, &ucp->uc_sigmask);
	if (ret == 0)
		ret = set_mcontext(&ucp->uc_mcontext);
	return(ret);
}
Esempio n. 10
0
static int
tmp(void)
{
	sigset_t set, oset;
	int fd, len;
	char *envtmp = NULL;
	char path[MAXPATHLEN];

	if (issetugid() == 0)
		envtmp = getenv("TMPDIR");
	len = snprintf(path,
	    sizeof(path), "%s/bt.XXXXXXXXXX", envtmp ? envtmp : "/tmp");
	if (len < 0 || len >= (int)sizeof(path)) {
		errno = ENAMETOOLONG;
		return(-1);
	}

	(void)sigfillset(&set);
	(void)_sigprocmask(SIG_BLOCK, &set, &oset);
	if ((fd = mkostemp(path, O_CLOEXEC)) != -1)
		(void)unlink(path);
	(void)_sigprocmask(SIG_SETMASK, &oset, NULL);
	return(fd);
}
Esempio n. 11
0
static void
__fail(const char *msg)
{
    struct sigaction sa;
    sigset_t mask;

    /* Immediately block all signal handlers from running code */
    sigfillset(&mask);
    sigdelset(&mask, SIGABRT);
    _sigprocmask(SIG_BLOCK, &mask, NULL);

    /* This may fail on a chroot jail... */
    syslog(LOG_CRIT, "%s", msg);

    bzero(&sa, sizeof(struct sigaction));
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sa.sa_handler = SIG_DFL;
    __sys_sigaction(SIGABRT, &sa, NULL);
    kill(getpid(), SIGABRT);
    _exit(127);
}
Esempio n. 12
0
int
rcmd_af(char **ahost, int rport, const char *locuser, const char *remuser,
	const char *cmd, int *fd2p, int af)
{
	struct addrinfo hints, *res, *ai;
	struct sockaddr_storage from;
	fd_set reads;
	sigset_t oldmask, newmask;
	pid_t pid;
	int s, aport, lport, timo, error;
	char c, *p;
	int refused, nres;
	char num[8];
	static char canonnamebuf[MAXDNAME];	/* is it proper here? */

	/* call rcmdsh() with specified remote shell if appropriate. */
	if (!issetugid() && (p = getenv("RSH"))) {
		struct servent *sp = getservbyname("shell", "tcp");

		if (sp && sp->s_port == rport)
			return (rcmdsh(ahost, rport, locuser, remuser,
			    cmd, p));
	}

	/* use rsh(1) if non-root and remote port is shell. */
	if (geteuid()) {
		struct servent *sp = getservbyname("shell", "tcp");

		if (sp && sp->s_port == rport)
			return (rcmdsh(ahost, rport, locuser, remuser,
			    cmd, NULL));
	}

	pid = getpid();

	memset(&hints, 0, sizeof(hints));
	hints.ai_flags = AI_CANONNAME;
	hints.ai_family = af;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = 0;
	snprintf(num, sizeof(num), "%d", ntohs(rport));
	error = getaddrinfo(*ahost, num, &hints, &res);
	if (error) {
		fprintf(stderr, "rcmd: getaddrinfo: %s\n",
			gai_strerror(error));
		if (error == EAI_SYSTEM)
			fprintf(stderr, "rcmd: getaddrinfo: %s\n",
				strerror(errno));
		return (-1);
	}

	if (res->ai_canonname &&
	    strlen(res->ai_canonname) + 1 < sizeof(canonnamebuf)) {
		strncpy(canonnamebuf, res->ai_canonname, sizeof(canonnamebuf));
		*ahost = canonnamebuf;
	}
	nres = 0;
	for (ai = res; ai; ai = ai->ai_next)
		nres++;
	ai = res;
	refused = 0;
	sigemptyset(&newmask);
	sigaddset(&newmask, SIGURG);
	_sigprocmask(SIG_BLOCK, (const sigset_t *)&newmask, &oldmask);
	for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
		s = rresvport_af(&lport, ai->ai_family);
		if (s < 0) {
			if (errno != EAGAIN && ai->ai_next) {
				ai = ai->ai_next;
				continue;
			}
			if (errno == EAGAIN)
				fprintf(stderr,
				    "rcmd: socket: All ports in use\n");
			else
				fprintf(stderr, "rcmd: socket: %s\n",
				    strerror(errno));
			freeaddrinfo(res);
			_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask,
			    NULL);
			return (-1);
		}
		_fcntl(s, F_SETOWN, pid);
		if (_connect(s, ai->ai_addr, ai->ai_addrlen) >= 0)
			break;
		_close(s);
		if (errno == EADDRINUSE) {
			lport--;
			continue;
		}
		if (errno == ECONNREFUSED)
			refused = 1;
		if (ai->ai_next == NULL && (!refused || timo > 16)) {
			fprintf(stderr, "%s: %s\n", *ahost, strerror(errno));
			freeaddrinfo(res);
			_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask,
			    NULL);
			return (-1);
		}
		if (nres > 1) {
			int oerrno = errno;

			getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr,
			    sizeof(paddr), NULL, 0, NI_NUMERICHOST);
			fprintf(stderr, "connect to address %s: ", paddr);
			errno = oerrno;
			perror(0);
		}
		if ((ai = ai->ai_next) == NULL) {
			/* refused && timo <= 16 */
			struct timespec time_to_sleep, time_remaining;

			time_to_sleep.tv_sec = timo;
			time_to_sleep.tv_nsec = 0;
			_nanosleep(&time_to_sleep, &time_remaining);
			timo *= 2;
			ai = res;
			refused = 0;
		}
		if (nres > 1) {
			getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr,
			    sizeof(paddr), NULL, 0, NI_NUMERICHOST);
			fprintf(stderr, "Trying %s...\n", paddr);
		}
	}
	lport--;
	if (fd2p == 0) {
		_write(s, "", 1);
		lport = 0;
	} else {
		int s2 = rresvport_af(&lport, ai->ai_family), s3;
		socklen_t len = ai->ai_addrlen;
		int nfds;

		if (s2 < 0)
			goto bad;
		_listen(s2, 1);
		snprintf(num, sizeof(num), "%d", lport);
		if (_write(s, num, strlen(num)+1) != strlen(num)+1) {
			fprintf(stderr,
			    "rcmd: write (setting up stderr): %s\n",
			    strerror(errno));
			_close(s2);
			goto bad;
		}
		nfds = max(s, s2)+1;
		if(nfds > FD_SETSIZE) {
			fprintf(stderr, "rcmd: too many files\n");
			_close(s2);
			goto bad;
		}
again:
		FD_ZERO(&reads);
		FD_SET(s, &reads);
		FD_SET(s2, &reads);
		errno = 0;
		if (_select(nfds, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)){
			if (errno != 0)
				fprintf(stderr,
				    "rcmd: select (setting up stderr): %s\n",
				    strerror(errno));
			else
				fprintf(stderr,
				"select: protocol failure in circuit setup\n");
			_close(s2);
			goto bad;
		}
		s3 = _accept(s2, (struct sockaddr *)&from, &len);
		switch (from.ss_family) {
		case AF_INET:
			aport = ntohs(((struct sockaddr_in *)&from)->sin_port);
			break;
#ifdef INET6
		case AF_INET6:
			aport = ntohs(((struct sockaddr_in6 *)&from)->sin6_port);
			break;
#endif
		default:
			aport = 0;	/* error */
			break;
		}
		/*
		 * XXX careful for ftp bounce attacks. If discovered, shut them
		 * down and check for the real auxiliary channel to connect.
		 */
		if (aport == 20) {
			_close(s3);
			goto again;
		}
		_close(s2);
		if (s3 < 0) {
			fprintf(stderr,
			    "rcmd: accept: %s\n", strerror(errno));
			lport = 0;
			goto bad;
		}
		*fd2p = s3;
		if (aport >= IPPORT_RESERVED || aport < IPPORT_RESERVED / 2) {
			fprintf(stderr,
			    "socket: protocol failure in circuit setup.\n");
			goto bad2;
		}
	}
	_write(s, locuser, strlen(locuser)+1);
	_write(s, remuser, strlen(remuser)+1);
	_write(s, cmd, strlen(cmd)+1);
	if (_read(s, &c, 1) != 1) {
		fprintf(stderr,
		    "rcmd: %s: %s\n", *ahost, strerror(errno));
		goto bad2;
	}
	if (c != 0) {
		while (_read(s, &c, 1) == 1) {
			_write(STDERR_FILENO, &c, 1);
			if (c == '\n')
				break;
		}
		goto bad2;
	}
	_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL);
	freeaddrinfo(res);
	return (s);
bad2:
	if (lport)
		_close(*fd2p);
bad:
	_close(s);
	_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL);
	freeaddrinfo(res);
	return (-1);
}
Esempio n. 13
0
int rcmd_af(char **ahost, unsigned short rport, const char *locuser,
    const char *remuser, const char *cmd, int *fd2p, int af)
{
	int s, timo = 1;
	ssize_t retval;
	pid_t pid;
	struct sockaddr_storage caddr, faddr;
	struct sockaddr_in *sin;
	struct sockaddr_in6 *sin6;
	struct addrinfo hints;
	struct addrinfo *res, *resp;
	size_t addrlen;
	int rc;
#define	MAX_SHORTSTRLEN 6
	char aport[MAX_SHORTSTRLEN];
	char c;
	int lport = 0;
#ifdef SYSV
	sigset_t oldmask;
	sigset_t newmask;
	struct sigaction oldaction;
	struct sigaction newaction;
#else
	int oldmask;
#endif /* SYSV */
	fd_set fdset;
	int selret;
	char *addr;
	static char hostname[MAXHOSTNAMELEN];
	socklen_t len;
	char abuf[INET6_ADDRSTRLEN];

	if (!(af == AF_INET || af == AF_INET6 || af == AF_UNSPEC)) {
		errno = EAFNOSUPPORT;
		return (-1);
	}

	pid = getpid();
	memset(&hints, 0, sizeof (hints));
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_CANONNAME;
	if (af == AF_INET6) {
		hints.ai_flags |= AI_V4MAPPED;
		hints.ai_family = AF_UNSPEC;
	} else {
		hints.ai_family = af;
	}
	(void) snprintf(aport, MAX_SHORTSTRLEN, "%u", ntohs(rport));
	rc = getaddrinfo(*ahost, aport, &hints, &res);
	if (rc != 0) {
		(void) fprintf(stderr,
		    _dgettext(TEXT_DOMAIN, "%s: unknown host%s\n"),
		    *ahost, rc == EAI_AGAIN ? " (try again later)" : "");
		return (-1);
	}
	resp = res;
	(void) strlcpy(hostname, res->ai_canonname, MAXHOSTNAMELEN);
	*ahost = hostname;
#ifdef SYSV
	/* ignore SIGPIPE */
	bzero((char *)&newaction, sizeof (newaction));
	newaction.sa_handler = SIG_IGN;
	(void) _sigaction(SIGPIPE, &newaction, &oldaction);

	/* block SIGURG */
	bzero((char *)&newmask, sizeof (newmask));
	(void) _sigaddset(&newmask, SIGURG);
	(void) _sigprocmask(SIG_BLOCK, &newmask, &oldmask);
#else
	oldmask = _sigblock(sigmask(SIGURG));
#endif /* SYSV */
	for (;;) {
		s = rresvport_af(&lport, res->ai_family);
		if (s < 0) {
			int af = res->ai_family;

			/*
			 * See if we have any addresses of a different type
			 * to try.
			 */
			while (res != NULL && res->ai_family == af)
				res = res->ai_next;

			if (res != NULL)
				continue;

			if (errno == EAGAIN)
				(void) fprintf(stderr,
				    _dgettext(TEXT_DOMAIN,
				    "socket: All ports in use\n"));
			else
				perror("rcmd: socket");
#ifdef SYSV
			/* restore original SIGPIPE handler */
			(void) _sigaction(SIGPIPE, &oldaction,
			    (struct sigaction *)0);

			/* restore original signal mask */
			(void) _sigprocmask(SIG_SETMASK, &oldmask,
			    (sigset_t *)0);
#else
			sigsetmask(oldmask);
#endif /* SYSV */
			freeaddrinfo(resp);
			return (-1);
		}
		bzero((char *)&caddr, sizeof (caddr));
		bcopy(res->ai_addr, &caddr, res->ai_addrlen);
		addrlen = res->ai_addrlen;
		if (af == AF_INET6 && res->ai_addr->sa_family == AF_INET) {
			struct in6_addr ia6;
			struct sockaddr_in6 *in6addr;
			IN6_INADDR_TO_V4MAPPED(&((struct sockaddr_in *)
			    res->ai_addr)->sin_addr, &ia6);
			in6addr = (struct sockaddr_in6 *)&caddr;
			in6addr->sin6_addr = ia6;
			in6addr->sin6_family = AF_INET6;
			addrlen = sizeof (struct sockaddr_in6);
		}
		(void) _fcntl(s, F_SETOWN, pid);
		if (connect(s, (struct sockaddr *)&caddr, addrlen) >= 0)
			break;
		(void) close(s);
		if (errno == EADDRINUSE) {
			lport = 0;
			continue;
		}
		if (errno == ECONNREFUSED && timo <= 16) {
			(void) sleep(timo);
			timo *= 2;
			continue;
		}
		if (res->ai_next != NULL) {
			int oerrno = errno;
			if (res->ai_addr->sa_family == AF_INET6)
				addr = (char *)&((struct sockaddr_in6 *)
				    res->ai_addr)->sin6_addr;
			else
				addr = (char *)&((struct sockaddr_in *)
				    res->ai_addr)->sin_addr;
			(void) fprintf(stderr,
			    _dgettext(TEXT_DOMAIN, "connect to address %s: "),
			    inet_ntop(res->ai_addr->sa_family, addr,
			    abuf, sizeof (abuf)));
			errno = oerrno;
			perror(0);
			res = res->ai_next;
			if (res->ai_addr->sa_family == AF_INET6)
				addr = (char *)&((struct sockaddr_in6 *)
				    res->ai_addr)->sin6_addr;
			else
				addr = (char *)&((struct sockaddr_in *)
				    res->ai_addr)->sin_addr;
			(void) fprintf(stderr,
			    _dgettext(TEXT_DOMAIN, "Trying %s...\n"),
			    inet_ntop(res->ai_addr->sa_family, addr,
			    abuf, sizeof (abuf)));
			continue;
		}
		perror(*ahost);
		freeaddrinfo(resp);
#ifdef SYSV
		/* restore original SIGPIPE handler */
		(void) _sigaction(SIGPIPE, &oldaction,
		    (struct sigaction *)0);

		/* restore original signal mask */
		(void) _sigprocmask(SIG_SETMASK, &oldmask, (sigset_t *)0);
#else
		sigsetmask(oldmask);
#endif /* SYSV */
		return (-1);
	}
	lport = 0;
	if (fd2p == 0) {
		(void) write(s, "", 1);
	} else {
		int s2 = rresvport_af(&lport, res->ai_family), s3;

		len = (socklen_t)sizeof (faddr);

		if (s2 < 0)
			goto bad;
		(void) listen(s2, 1);
		(void) snprintf(aport, MAX_SHORTSTRLEN, "%d", lport);
		if (write(s, aport, strlen(aport)+1) != strlen(aport)+1) {
			perror(_dgettext(TEXT_DOMAIN,
			    "write: setting up stderr"));
			(void) close(s2);
			goto bad;
		}
		FD_ZERO(&fdset);
		FD_SET(s, &fdset);
		FD_SET(s2, &fdset);
		while ((selret = select(FD_SETSIZE, &fdset, (fd_set *)0,
		    (fd_set *)0, (struct timeval *)0)) > 0) {
			if (FD_ISSET(s, &fdset)) {
				/*
				 *	Something's wrong:  we should get no
				 *	data on this connection at this point,
				 *	so we assume that the connection has
				 *	gone away.
				 */
				(void) close(s2);
				goto bad;
			}
			if (FD_ISSET(s2, &fdset)) {
				/*
				 *	We assume this is an incoming connect
				 *	request and proceed normally.
				 */
				s3 = accept(s2, (struct sockaddr *)&faddr,
				    &len);
				FD_CLR(s2, &fdset);
				(void) close(s2);
				if (s3 < 0) {
					perror("accept");
					lport = 0;
					goto bad;
				}
				else
					break;
			}
		}
		if (selret == -1) {
			/*
			 *	This should not happen, and we treat it as
			 *	a fatal error.
			 */
			(void) close(s2);
			goto bad;
		}

		*fd2p = s3;
		switch (faddr.ss_family) {
		case AF_INET:
			sin = (struct sockaddr_in *)&faddr;
			if (ntohs(sin->sin_port) >= IPPORT_RESERVED) {
				(void) fprintf(stderr,
				    _dgettext(TEXT_DOMAIN,
					"socket: protocol failure in circuit "
					"setup.\n"));
				goto bad2;
			}
			break;
		case AF_INET6:
			sin6 = (struct sockaddr_in6 *)&faddr;
			if (ntohs(sin6->sin6_port) >= IPPORT_RESERVED) {
				(void) fprintf(stderr,
				    _dgettext(TEXT_DOMAIN,
					"socket: protocol failure in circuit "
					"setup.\n"));
				goto bad2;
			}
			break;
		default:
			(void) fprintf(stderr,
			    _dgettext(TEXT_DOMAIN,
			    "socket: protocol failure in circuit setup.\n"));
			goto bad2;
		}
	}
	(void) write(s, locuser, strlen(locuser)+1);
	(void) write(s, remuser, strlen(remuser)+1);
	(void) write(s, cmd, strlen(cmd)+1);
	retval = read(s, &c, 1);
	if (retval != 1) {
		if (retval == 0) {
			(void) fprintf(stderr,
			    _dgettext(TEXT_DOMAIN,
			    "Protocol error, %s closed connection\n"),
			    *ahost);
		} else if (retval < 0) {
			perror(*ahost);
		} else {
			(void) fprintf(stderr,
			    _dgettext(TEXT_DOMAIN,
			    "Protocol error, %s sent %d bytes\n"),
			    *ahost, retval);
		}
		goto bad2;
	}
	if (c != 0) {
		while (read(s, &c, 1) == 1) {
			(void) write(2, &c, 1);
			if (c == '\n')
				break;
		}
		goto bad2;
	}
#ifdef SYSV
	/* restore original SIGPIPE handler */
	(void) _sigaction(SIGPIPE, &oldaction, (struct sigaction *)0);

	/* restore original signal mask */
	(void) _sigprocmask(SIG_SETMASK, &oldmask, (sigset_t *)0);
#else
	sigsetmask(oldmask);
#endif /* SYSV */
	freeaddrinfo(resp);
	return (s);
bad2:
	if (lport)
		(void) close(*fd2p);
bad:
	(void) close(s);
#ifdef SYSV
	/* restore original SIGPIPE handler */
	(void) _sigaction(SIGPIPE, &oldaction, (struct sigaction *)0);

	/* restore original signal mask */
	(void) _sigprocmask(SIG_SETMASK, &oldmask, (sigset_t *)0);
#else
	sigsetmask(oldmask);
#endif /* SYSV */
	freeaddrinfo(resp);
	return (-1);
}
Esempio n. 14
0
int
grantpt(int fildes) {
    int retval, serrno, status;
    pid_t pid, spid;
    gid_t gid;
    char* slave;
    sigset_t oblock, nblock;
    struct group* grp;
    retval = -1;
    serrno = errno;

    if ((slave = ptsname(fildes)) != NULL) {
        /*
         * Block SIGCHLD.
         */
        (void)sigemptyset(&nblock);
        (void)sigaddset(&nblock, SIGCHLD);
        (void)_sigprocmask(SIG_BLOCK, &nblock, &oblock);

        switch (pid = fork()) {
        case -1:
            break;

        case 0:     /* child */
            /*
             * pt_chown expects the master pseudo TTY to be its
             * standard input.
             */
            (void)_dup2(fildes, STDIN_FILENO);
            (void)_sigprocmask(SIG_SETMASK, &oblock, NULL);
            execl(_PATH_PTCHOWN, _PATH_PTCHOWN, (char*)NULL);
            _exit(EX_UNAVAILABLE);

        /* NOTREACHED */
        default:    /* parent */

            /*
             * Just wait for the process.  Error checking is
             * done below.
             */
            while ((spid = _waitpid(pid, &status, 0)) == -1 &&
                    (errno == EINTR))
                ;

            if (spid != -1 && WIFEXITED(status) &&
                    WEXITSTATUS(status) == EX_OK) {
                retval = 0;
            } else {
                errno = EACCES;
            }

            break;
        }

        /*
         * Restore process's signal mask.
         */
        (void)_sigprocmask(SIG_SETMASK, &oblock, NULL);

        if (retval) {
            /*
             * pt_chown failed.  Try to manually change the
             * permissions for the slave.
             */
            gid = (grp = getgrnam("tty")) ? grp->gr_gid : -1;

            if (chown(slave, getuid(), gid) == -1 ||
                    chmod(slave, S_IRUSR | S_IWUSR | S_IWGRP) == -1) {
                errno = EACCES;
            } else {
                retval = 0;
            }
        }
    }

    if (!retval) {
        errno = serrno;
    }

    return (retval);
}
Esempio n. 15
0
void
__oldsigset(sigset_t *p)
{
	_sigprocmask(SIG_SETMASK, p, NULL);
}
Esempio n. 16
0
void
__newsigset(sigset_t *p)
{
	/* The SIG_SETMASK is not significant */
	_sigprocmask(SIG_SETMASK, NULL, p);
}