Пример #1
0
int portal_file(struct portal_cred *pcr,
    char *key, char **v, int so __unused, int *fdp)
{
	int fd;
	char pbuf[MAXPATHLEN];
	int error;
	struct portal_cred save_area;

	pbuf[0] = '/';
	strcpy(pbuf+1, key + (v[1] ? strlen(v[1]) : 0));

#ifdef DEBUG
	printf("path = %s, uid = %d, gid = %d\n", pbuf, pcr->pcr_uid, pcr->pcr_groups[0]);
	printf ("fflag = %x, oflag = %x\n", pcr->pcr_flag, (pcr->pcr_flag)-1);
#endif

	if (set_user_credentials(pcr, &save_area) < 0)
		return (errno);

	/* dmb convert kernel flags to oflags, see <fcntl.h> */
	fd = open(pbuf, (pcr->pcr_flag)-1, 0777);
	if (fd < 0)
		error = errno;
	else
		error = 0;

	if (restore_credentials(&save_area) < 0) {
		error = errno;
		if (fd >= 0) {
			(void) close(fd);
			fd = -1;
		}
	}

	if (error == 0)
		*fdp = fd;

#ifdef DEBUG
	fprintf(stderr, "pt_file returns *fdp = %d, error = %d\n", *fdp, error);
#endif

	return (error);
}
Пример #2
0
int portal_pipe(struct portal_cred *pcr, char *key, char **v,
    int kso __unused, int *fdp)
{
	int fd[2];		/* Pipe endpoints. */
	int caller_end;		/* The pipe end we will use. */
	int process_end;	/* The pipe end the spawned process will use. */
	int redirect_fd;	/* The fd to redirect on the spawned process. */
	char pbuf[MAXPATHLEN];
	int error = 0;
	int i;
	char **argv;
	int argc;
	struct portal_cred save_area;

	/* Validate open mode, and assign roles. */
	if ((pcr->pcr_flag & FWRITE) && (pcr->pcr_flag & FREAD))
		/* Don't allow both on a single fd. */
		return (EINVAL);
	else if (pcr->pcr_flag & FREAD) {
		/*
		 * The caller reads from the pipe,
		 * the spawned process writes to it.
		 */
		caller_end = READ_END;
		process_end = WRITE_END;
		redirect_fd = STDOUT_FILENO;
	} else if (pcr->pcr_flag & FWRITE) {
		/*
		 * The caller writes to the pipe,
		 * the spawned process reads from it.
		 */
		caller_end = WRITE_END;
		process_end = READ_END;
		redirect_fd = STDIN_FILENO;
	} else
		return (EINVAL);

	/* Get and check command line. */
	pbuf[0] = '/';
	strcpy(pbuf+1, key + (v[1] ? strlen(v[1]) : 0));
	argc = parse_argv(pbuf, NULL);
	if (argc == 0)
		return (ENOENT);

	/* Swap priviledges. */
	if (set_user_credentials(pcr, &save_area) < 0)
		return (errno);

	/* Redirect and spawn the specified process. */
	fd[READ_END] = fd[WRITE_END] = -1;
	if (pipe(fd) < 0) {
		error = errno;
		goto done;
	}
	switch (fork()) {
	case -1: /* Error */
		error = errno;
		break;
	default: /* Parent */
		(void)close(fd[process_end]);
		break;
	case 0: /* Child */
		argv = (char **)malloc((argc + 1) * sizeof(char *));
		if (argv == 0) {
			syslog(LOG_ALERT,
			    "malloc: failed to get space for %d pointers",
			    argc + 1);
			exit(EXIT_FAILURE);
		}
		parse_argv(pbuf, argv);

		if (dup2(fd[process_end], redirect_fd) < 0) {
			syslog(LOG_ERR, "dup2: %m");
			exit(EXIT_FAILURE);
		}
		(void)close(fd[caller_end]);
		(void)close(fd[process_end]);
		if (errlog() < 0) {
			syslog(LOG_ERR, "errlog: %m");
			exit(EXIT_FAILURE);
		}
		if (execv(argv[0], argv) < 0) {
			syslog(LOG_ERR, "execv(%s): %m", argv[0]);
			exit(EXIT_FAILURE);
		}
		/* NOTREACHED */
	}

done:
	/* Re-establish our priviledges. */
	if (restore_credentials(&save_area) < 0)
		error = errno;

	/* Set return fd value. */
	if (error == 0)
		*fdp = fd[caller_end];
	else {
		for (i = 0; i < 2; i++)
			if (fd[i] >= 0)
				(void)close(fd[i]);
		*fdp = -1;
	}

	return (error);
}