static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) { _cleanup_(stdout_stream_freep) StdoutStream *stream = NULL; sd_id128_t id; int r; assert(s); assert(fd >= 0); r = sd_id128_randomize(&id); if (r < 0) return log_error_errno(r, "Failed to generate stream ID: %m"); stream = new0(StdoutStream, 1); if (!stream) return log_oom(); stream->fd = -1; stream->priority = LOG_INFO; xsprintf(stream->id_field, "_STREAM_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id)); r = getpeercred(fd, &stream->ucred); if (r < 0) return log_error_errno(r, "Failed to determine peer credentials: %m"); if (mac_selinux_use()) { r = getpeersec(fd, &stream->label); if (r < 0 && r != -EOPNOTSUPP) (void) log_warning_errno(r, "Failed to determine peer security context: %m"); } (void) shutdown(fd, SHUT_WR); r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLIN, stdout_stream_process, stream); if (r < 0) return log_error_errno(r, "Failed to add stream to event loop: %m"); r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5); if (r < 0) return log_error_errno(r, "Failed to adjust stdout event source priority: %m"); stream->fd = fd; stream->server = s; LIST_PREPEND(stdout_stream, s->stdout_streams, stream); s->n_stdout_streams++; if (ret) *ret = stream; stream = NULL; return 0; }
_public_ int sd_peer_get_owner_uid(int fd, uid_t *uid) { struct ucred ucred; int r; assert_return(fd >= 0, -EINVAL); assert_return(uid, -EINVAL); r = getpeercred(fd, &ucred); if (r < 0) return r; return cg_pid_get_owner_uid(ucred.pid, uid); }
_public_ int sd_peer_get_session(int fd, char **session) { struct ucred ucred; int r; assert_return(fd >= 0, -EINVAL); assert_return(session, -EINVAL); r = getpeercred(fd, &ucred); if (r < 0) return r; return cg_pid_get_session(ucred.pid, session); }
_public_ int sd_peer_get_machine_name(int fd, char **machine) { struct ucred ucred; int r; assert_return(fd >= 0, -EINVAL); assert_return(machine, -EINVAL); r = getpeercred(fd, &ucred); if (r < 0) return r; return cg_pid_get_machine_name(ucred.pid, machine); }
_public_ int sd_peer_get_user_unit(int fd, char **unit) { struct ucred ucred; int r; assert_return(fd >= 0, -EINVAL); assert_return(unit, -EINVAL); r = getpeercred(fd, &ucred); if (r < 0) return r; return cg_pid_get_user_unit(ucred.pid, unit); }
_public_ int sd_peer_get_cgroup(int fd, char **cgroup) { struct ucred ucred; int r; assert_return(fd >= 0, -EBADF); assert_return(cgroup, -EINVAL); r = getpeercred(fd, &ucred); if (r < 0) return r; return sd_pid_get_cgroup(ucred.pid, cgroup); }
_public_ int sd_peer_get_user_slice(int fd, char **slice) { struct ucred ucred; int r; assert_return(fd >= 0, -EBADF); assert_return(slice, -EINVAL); r = getpeercred(fd, &ucred); if (r < 0) return r; return cg_pid_get_user_slice(ucred.pid, slice); }
static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revents, void *userdata) { _cleanup_close_ int fd = -1; Server *s = userdata; int r; assert(s); if (revents != EPOLLIN) { log_error("Got invalid event from epoll for stdout server fd: %"PRIx32, revents); return -EIO; } fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); if (fd < 0) { if (errno == EAGAIN) return 0; return log_error_errno(errno, "Failed to accept stdout connection: %m"); } if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) { struct ucred u; r = getpeercred(fd, &u); /* By closing fd here we make sure that the client won't wait too long for journald to * gather all the data it adds to the error message to find out that the connection has * just been refused. */ fd = safe_close(fd); server_driver_message(s, r < 0 ? 0 : u.pid, NULL, LOG_MESSAGE("Too many stdout streams, refusing connection."), NULL); return 0; } r = stdout_stream_install(s, fd, NULL); if (r < 0) return r; fd = -1; return 0; }
/* read a request message, returns <0 in case of errors, this function closes the socket */ static void handleconnection(int sock, MYLDAP_SESSION *session) { TFILE *fp; int32_t action; uid_t uid = (uid_t)-1; gid_t gid = (gid_t)-1; pid_t pid = (pid_t)-1; /* log connection */ if (getpeercred(sock, &uid, &gid, &pid)) log_log(LOG_DEBUG, "connection from unknown client: %s", strerror(errno)); else log_log(LOG_DEBUG, "connection from pid=%d uid=%d gid=%d", (int)pid, (int)uid, (int)gid); /* create a stream object */ if ((fp = tio_fdopen(sock, READ_TIMEOUT, WRITE_TIMEOUT, READBUFFER_MINSIZE, READBUFFER_MAXSIZE, WRITEBUFFER_MINSIZE, WRITEBUFFER_MAXSIZE)) == NULL) { log_log(LOG_WARNING, "cannot create stream for writing: %s", strerror(errno)); (void)close(sock); return; } /* read request */ if (read_header(fp, &action)) { (void)tio_close(fp); return; } /* handle request */ switch (action) { case NSLCD_ACTION_CONFIG_GET: (void)nslcd_config_get(fp, session); break; case NSLCD_ACTION_ALIAS_BYNAME: (void)nslcd_alias_byname(fp, session); break; case NSLCD_ACTION_ALIAS_ALL: (void)nslcd_alias_all(fp, session); break; case NSLCD_ACTION_ETHER_BYNAME: (void)nslcd_ether_byname(fp, session); break; case NSLCD_ACTION_ETHER_BYETHER: (void)nslcd_ether_byether(fp, session); break; case NSLCD_ACTION_ETHER_ALL: (void)nslcd_ether_all(fp, session); break; case NSLCD_ACTION_GROUP_BYNAME: (void)nslcd_group_byname(fp, session); break; case NSLCD_ACTION_GROUP_BYGID: (void)nslcd_group_bygid(fp, session); break; case NSLCD_ACTION_GROUP_BYMEMBER: (void)nslcd_group_bymember(fp, session); break; case NSLCD_ACTION_GROUP_ALL: (void)nslcd_group_all(fp, session); break; case NSLCD_ACTION_HOST_BYNAME: (void)nslcd_host_byname(fp, session); break; case NSLCD_ACTION_HOST_BYADDR: (void)nslcd_host_byaddr(fp, session); break; case NSLCD_ACTION_HOST_ALL: (void)nslcd_host_all(fp, session); break; case NSLCD_ACTION_NETGROUP_BYNAME: (void)nslcd_netgroup_byname(fp, session); break; case NSLCD_ACTION_NETGROUP_ALL: (void)nslcd_netgroup_all(fp, session); break; case NSLCD_ACTION_NETWORK_BYNAME: (void)nslcd_network_byname(fp, session); break; case NSLCD_ACTION_NETWORK_BYADDR: (void)nslcd_network_byaddr(fp, session); break; case NSLCD_ACTION_NETWORK_ALL: (void)nslcd_network_all(fp, session); break; case NSLCD_ACTION_PASSWD_BYNAME: (void)nslcd_passwd_byname(fp, session, uid); break; case NSLCD_ACTION_PASSWD_BYUID: (void)nslcd_passwd_byuid(fp, session, uid); break; case NSLCD_ACTION_PASSWD_ALL: (void)nslcd_passwd_all(fp, session, uid); break; case NSLCD_ACTION_PROTOCOL_BYNAME: (void)nslcd_protocol_byname(fp, session); break; case NSLCD_ACTION_PROTOCOL_BYNUMBER:(void)nslcd_protocol_bynumber(fp, session); break; case NSLCD_ACTION_PROTOCOL_ALL: (void)nslcd_protocol_all(fp, session); break; case NSLCD_ACTION_RPC_BYNAME: (void)nslcd_rpc_byname(fp, session); break; case NSLCD_ACTION_RPC_BYNUMBER: (void)nslcd_rpc_bynumber(fp, session); break; case NSLCD_ACTION_RPC_ALL: (void)nslcd_rpc_all(fp, session); break; case NSLCD_ACTION_SERVICE_BYNAME: (void)nslcd_service_byname(fp, session); break; case NSLCD_ACTION_SERVICE_BYNUMBER: (void)nslcd_service_bynumber(fp, session); break; case NSLCD_ACTION_SERVICE_ALL: (void)nslcd_service_all(fp, session); break; case NSLCD_ACTION_SHADOW_BYNAME: (void)nslcd_shadow_byname(fp, session, uid); break; case NSLCD_ACTION_SHADOW_ALL: (void)nslcd_shadow_all(fp, session, uid); break; case NSLCD_ACTION_PAM_AUTHC: (void)nslcd_pam_authc(fp, session, uid); break; case NSLCD_ACTION_PAM_AUTHZ: (void)nslcd_pam_authz(fp, session); break; case NSLCD_ACTION_PAM_SESS_O: (void)nslcd_pam_sess_o(fp, session); break; case NSLCD_ACTION_PAM_SESS_C: (void)nslcd_pam_sess_c(fp, session); break; case NSLCD_ACTION_PAM_PWMOD: (void)nslcd_pam_pwmod(fp, session, uid); break; case NSLCD_ACTION_USERMOD: (void)nslcd_usermod(fp, session, uid); break; default: log_log(LOG_WARNING, "invalid request id: 0x%08x", (unsigned int)action); break; } /* we're done with the request */ myldap_session_cleanup(session); (void)tio_close(fp); return; }