예제 #1
0
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;
}
예제 #2
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);
}
예제 #3
0
_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);
}
예제 #4
0
_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);
}
예제 #5
0
_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);
}
예제 #6
0
_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);
}
예제 #7
0
_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);
}
예제 #8
0
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;
}
예제 #9
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;
}