/* Privileged: called by monitor_loop. */ static void m_priv_pfkey_open(void) { int fd, err = 0; fd = pf_key_v2_open(); if (fd < 0) err = -1; must_write(&err, sizeof err); if (fd > 0 && mm_send_fd(m_state.s, fd)) { log_error("m_priv_pfkey_open: read/write operation failed"); close(fd); return; } close(fd); }
/* Privileged: called by monitor_loop. */ static void m_priv_getfd(void) { char path[MAXPATHLEN]; size_t len; int v, flags, ret; int err = 0; mode_t mode; must_read(&len, sizeof len); if (len == 0 || len >= sizeof path) log_fatal("m_priv_getfd: invalid pathname length"); must_read(path, len); path[len] = '\0'; if (strlen(path) != len) log_fatal("m_priv_getfd: invalid pathname"); must_read(&flags, sizeof flags); must_read(&mode, sizeof mode); if ((ret = m_priv_local_sanitize_path(path, sizeof path, flags)) != 0) { if (ret == 1) log_print("m_priv_getfd: illegal path \"%s\"", path); err = EACCES; v = -1; } else { if ((v = open(path, flags, mode)) == -1) err = errno; } must_write(&err, sizeof err); if (v != -1) { if (mm_send_fd(m_state.s, v) == -1) log_error("m_priv_getfd: sending fd failed"); close(v); } }
int mm_answer_pty(int sock, Buffer *m) { extern struct monitor *pmonitor; Session *s; int res, fd0; debug3("%s entering", __func__); buffer_clear(m); s = session_new(); if (s == NULL) goto error; s->authctxt = authctxt; s->pw = authctxt->pw; s->pid = pmonitor->m_pid; res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); if (res == 0) goto error; pty_setowner(authctxt->pw, s->tty); buffer_put_int(m, 1); buffer_put_cstring(m, s->tty); /* We need to trick ttyslot */ if (dup2(s->ttyfd, 0) == -1) fatal("%s: dup2", __func__); mm_record_login(s, authctxt->pw); /* Now we can close the file descriptor again */ close(0); /* send messages generated by record_login */ buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); buffer_clear(&loginmsg); mm_request_send(sock, MONITOR_ANS_PTY, m); mm_send_fd(sock, s->ptyfd); mm_send_fd(sock, s->ttyfd); /* make sure nothing uses fd 0 */ if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); if (fd0 != 0) error("%s: fd0 %d != 0", __func__, fd0); /* slave is not needed */ close(s->ttyfd); s->ttyfd = s->ptyfd; /* no need to dup() because nobody closes ptyfd */ s->ptymaster = s->ptyfd; debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd); return (0); error: if (s != NULL) mm_session_close(s); buffer_put_int(m, 0); mm_request_send(sock, MONITOR_ANS_PTY, m); return (0); }
static void m_priv_req_readdir() { size_t len; char path[MAXPATHLEN]; DIR *dp; struct dirent *file; struct stat sb; int off, size, fd, ret, serrno; must_read(&len, sizeof len); if (len == 0 || len >= sizeof path) log_fatal("m_priv_req_readdir: invalid pathname length"); must_read(path, len); path[len] = '\0'; if (strlen(path) != len) log_fatal("m_priv_req_readdir: invalid pathname"); off = strlen(path); size = sizeof path - off; if ((dp = opendir(path)) == NULL) { serrno = errno; ret = -1; must_write(&ret, sizeof ret); must_write(&serrno, sizeof serrno); return; } /* report opendir() success */ ret = 0; must_write(&ret, sizeof ret); while ((file = readdir(dp)) != NULL) { strlcpy(path + off, file->d_name, size); if (m_priv_local_sanitize_path(path, sizeof path, O_RDONLY) != 0) continue; fd = open(path, O_RDONLY, 0); if (fd == -1) { log_error("m_priv_req_readdir: open " "(\"%s\", O_RDONLY, 0) failed", path); continue; } if ((fstat(fd, &sb) == -1) || !(S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode))) { close(fd); continue; } len = strlen(path); must_write(&len, sizeof len); must_write(path, len); mm_send_fd(m_state.s, fd); close(fd); } closedir(dp); len = 0; must_write(&len, sizeof len); }