unit
posix_tty_tcsetattr(cerr er, int fd, int action, ptr_t termiorep, string cc)
{
	struct termios termios;
	int e = termioset(&termios,termiorep,cc);
	if(e)
		send_errno(er,e);
	else if(tcsetattr(fd, action, &termios) == -1)
		send_errno(er,errno);
	return empty_record;
}
unit
posix_io_fcntl_sfl(cerr er, int fd, word flags)
{
	if(fcntl(fd, F_SETFL, flags) == -1)
		send_errno(er,errno);
	return empty_record;
}
unit
posix_tty_tcflow(cerr er, int fd, int action)
{
	if(tcflow(fd, action) == -1)
		send_errno(er,errno);
	return empty_record;
}
unit
posix_io_fcntl_sfd(cerr er, int fd, word flag)
{
	if(fcntl(fd, F_SETFD, flag) == -1)	/* mask with FD_CLOEXEC? */
		send_errno(er,errno);
	return empty_record;
}
unit
posix_io_dup2(cerr er, int oldfd, int newfd)
{
	if(dup2(oldfd,newfd)==-1)
		send_errno(er,errno);
	return empty_record;
}
unit
posix_tty_tcsendbreak(cerr er, int fd, int duration)
{
	if(tcsendbreak(fd, duration) == -1)
		send_errno(er,errno);
	return empty_record;
}
unit
posix_io_close(cerr er, int fd)
{
	if(close(fd)==-1)
		send_errno(er,errno);
	return empty_record;
}
unit
posix_tty_tcsetpgrp(cerr er, int fd, int pgid)
{
	if(tcsetpgrp(fd, (pid_t) pgid) == -1)
		send_errno(er,errno);
	return empty_record;
}
unit
posix_tty_tcdrain(cerr er, int fd)
{
	if(tcdrain(fd) == -1)
		send_errno(er,errno);
	return empty_record;
}
unit
posix_tty_tcflush(cerr er, int fd, int queue_selector)
{
	if(tcflush(fd, queue_selector) == -1)
		send_errno(er,errno);
	return empty_record;
}
Exemple #11
0
unit
posix_io_fsync(cerr er, int fd)
{
	if(fsync(fd) == -1)
		send_errno(er,errno);
	return empty_record;
}
void handle_request(char *request, const struct ucred *src) {
	char *buff;
	int omode;

	if ((buff = strdup(request)) == NULL) {
		perror("strdup(3) couldn't allocate memory");
		return;
	}

	if (sscanf(request, "open %s %d", buff, &omode) != 2) {
		fprintf(stderr, "Invalid request: %s\n", request);
		goto outbuff;
	}

	if (!can_access(buff, src)) {
		errno = EACCES;
		if (send_errno(STDOUT_FILENO) < 0) {
			fprintf(stderr, "send_errno() failed attempting to notify client: %s\n",
				strerror(errno));
			fprintf(stderr, "Note: Permission denied for pid %ld to open %s (euid = %ld, egid = %ld)\n",
				(long) src->pid, buff, (long) src->uid, (long) src->gid);
		}
		goto outbuff;
	}

	int fd = open(buff, omode);

	if (fd < 0) {
		int open_error = errno;
		if (send_errno(STDOUT_FILENO) < 0) {
			fprintf(stderr, "send_errno() failed attempting to notify client: %s\n",
				strerror(errno));
			fprintf(stderr, "Note: couldn't open %s: %s\n", buff, strerror(open_error));
		}
		goto outbuff;
	}
	if (send_fd(STDOUT_FILENO, fd) < 0) {
		fprintf(stderr, "send_fd() failed attempting to send fd for %s: %s\n",
			buff, strerror(errno));
		goto outclose;
	}

outclose:
	close(fd);
outbuff:
	free(buff);
}
int
posix_tty_tcgetpgrp(cerr er, int fd)
{
	pid_t pid = tcgetpgrp(fd);
	if(pid == (pid_t)-1)
		send_errno(er,errno);
	return (int)pid;
}
Exemple #14
0
ptr_t
posix_io_fcntl_l(cerr er, int fd, int cmd, ptr_t flockrep)
{
	struct flock flock;
	if(fcntl(fd, cmd, flockset(&flock, flockrep)) == -1)
		send_errno(er,errno);
	return Flockrep(&flock);
}
uct
posix_tty_tcgetattr(cerr er, int fd)
{
	struct termios* termios = enew_atomic(struct termios);
	if(tcgetattr(fd, termios) == -1)
		send_errno(er,errno);
	return (uct)termios;
}
Exemple #16
0
int
posix_io_fcntl_d(cerr er, int fd, int basefd)
{
	int newfd = fcntl(fd, F_DUPFD, basefd);
	if(newfd == -1)
		send_errno(er,errno);
	return newfd;
}
Exemple #17
0
int
posix_io_writebuf(cerr er, int fd, word8array buf, int len, int start)
{
	int written = write(fd, (stringbuf(buf)) + start, len);
	if(written == -1)
		send_errno(er,errno);
	return written;
}
Exemple #18
0
word
posix_io_fcntl_gfd(cerr er, int fd)
{
	int r = fcntl(fd, F_GETFD);
	if(r == -1)
		send_errno(er,errno);
	return r;	/* mask with FD_CLOEXEC? */
}
Exemple #19
0
int
posix_io_dup(cerr er, int fd)
{
	int newfd = dup(fd);
	if(newfd == -1)
		send_errno(er,errno);
	return newfd;
}
Exemple #20
0
int
posix_io_lseek(cerr er, int filedes, int argoffset, int whence)
{
	off_t offset = lseek(filedes, argoffset, whence);
	if(offset == (off_t)-1)
		send_errno(er,errno);
	return offset;
}
Exemple #21
0
int
posix_io_readbuf(cerr er, int fd, word8array buf, int len, int start)
{ 
	int bytes_read = read(fd, (stringbuf(buf)) + start, len);
	if(bytes_read == -1)
		send_errno(er,errno);
	return bytes_read;
}
Exemple #22
0
intpair
posix_io_pipe(cerr er, unit unused)
{
	int fds[2];
	ptr_t pair;
	if(pipe(fds) == -1)
		send_errno(er, errno);
	pair = alloc_intint(fds[0], fds[1]);
	return pair;
}
Exemple #23
0
string
posix_io_read(cerr er, int fd, int size)
{
	char* buf = NULL;
	string vec = alloc_uninit_string(size,&buf);
	int bytes_read = read(fd,buf,size);
	if(bytes_read==-1)
		send_errno(er,errno);
	else
		adjust_stringlen(vec,bytes_read);
	return vec;
}
Exemple #24
0
wordpair
posix_io_fcntl_gfl(cerr er, int fd)
{
	int r = fcntl(fd, F_GETFL);
	word flags;
	word mode;
	ptr_t pair;

	if(r == -1)
		send_errno(er,errno);
	flags = r & (~O_ACCMODE);
	mode = r & O_ACCMODE;
	pair = alloc_intint(flags, mode);
	return pair;
}
void handle_client_request(int clientfd) {
	static char req_buff[2048];

	struct iovec iov;
	iov.iov_base = req_buff;
	iov.iov_len = sizeof(req_buff)-1;

	unsigned char cmsg_buff[CMSG_SPACE(sizeof(struct ucred))];

	struct msghdr msg;
	msg.msg_name = NULL;
	msg.msg_namelen = 0;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = cmsg_buff;
	msg.msg_controllen = sizeof(cmsg_buff);
	msg.msg_flags = 0;

	ssize_t n;
	n = recvmsg(clientfd, &msg, 0);

	if (n == 0) {
		syslog(LOG_INFO, "Ignoring empty message from client.\n");
		return;
	} else if (n < 0) {
		syslog(LOG_ERR, "Error retrieving message from client: %s\n", strerror(errno));
		return;
	}

	if (msg.msg_controllen != sizeof(cmsg_buff)) {
		errno = EINVAL;
		if (send_errno(clientfd) < 0) {
			syslog(LOG_ERR, "send_errno() failed when attempting to notify client of invalid or non-existent cmsg: %s\n",
			       strerror(errno));
		}
	} else {
		struct ucred *ucredptr;
		ucredptr = (struct ucred *) CMSG_DATA((struct cmsghdr *) cmsg_buff);
		serve_client_request(clientfd, req_buff, ucredptr);
	}
}
string
os_filesys_tmpname(cerr er)
{
	#ifdef AVOID_TMPNAM
		char buf[] = "/tmp/tnXXXXXX";
		int fd = mkstemp(buf);
		if(fd == -1){
			send_errno(er,errno);
			*buf = 0;
		}
		else
			close(fd);
		return cstring2mlstring_alloc(buf);
	#else
		char* buf;
		string res = alloc_uninit_string(L_tmpnam,&buf);
		char *result = tmpnam(buf);
		assert(result == buf);
		adjust_stringlen(res,strlen(buf));
		return res;
	#endif
}
int main(void) {

	struct stat statbuf;
	if (fstat(STDIN_FILENO, &statbuf) < 0) {
		perror("fstat(2) failed for stdin");
		exit(EXIT_FAILURE);
	}
	if (!S_ISSOCK(statbuf.st_mode)) {
		fprintf(stderr, "Fatal: stdin is not a socket\n");
		exit(EXIT_FAILURE);
	}
	if (fstat(STDOUT_FILENO, &statbuf) < 0) {
		perror("fstat(2) failed for stdout");
		exit(EXIT_FAILURE);
	}
	if (!S_ISSOCK(statbuf.st_mode)) {
		fprintf(stderr, "Fatal: stdout is not a socket\n");
		exit(EXIT_FAILURE);
	}

	int optval = 1;	
	if (setsockopt(STDOUT_FILENO, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) < 0) {
		perror("setsockopt(2) failed when trying to set SO_PASSCRED");
		exit(EXIT_FAILURE);
	}

	static char linebuff[LINE_MAX];
	ssize_t msg_len;

	unsigned char cmsg_buff[CMSG_SPACE(sizeof(struct ucred))];

	struct iovec iov;
	iov.iov_base = linebuff;
	iov.iov_len = sizeof(linebuff)-1;

	struct msghdr msg;
	msg.msg_name = NULL;
	msg.msg_namelen = 0;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = cmsg_buff;
	msg.msg_controllen = CMSG_LEN(sizeof(struct ucred));
	msg.msg_flags = 0;

	while ((msg_len = recvmsg(STDIN_FILENO, &msg, 0)) > 0) {
		char *request = iov.iov_base;
		if (request[msg_len-1] == '\n')
			request[--msg_len] = '\0';
		if (msg.msg_controllen != CMSG_LEN(sizeof(struct ucred))) {
			errno = EINVAL;
			if (send_errno(STDOUT_FILENO) < 0) {
				fprintf(stderr, "send_errno() failed when attempting to notify client of invalid or non-existent cmsg: %s\n",
					strerror(errno));
			}
		} else {
			struct ucred *ucredptr;
			ucredptr = (struct ucred *) CMSG_DATA((struct cmsghdr *) cmsg_buff);
			handle_request(request, ucredptr);
		}

		iov.iov_base = linebuff;
		iov.iov_len = sizeof(linebuff)-1;
		msg.msg_name = NULL;
		msg.msg_namelen = 0;
		msg.msg_iov = &iov;
		msg.msg_iovlen = 1;
		msg.msg_control = cmsg_buff;
		msg.msg_controllen = CMSG_LEN(sizeof(struct ucred));
		msg.msg_flags = 0;
	}

	if (msg_len < 0) {
		perror("recvmsg(2) error");
		exit(EXIT_FAILURE);
	}

	return 0;
}