Пример #1
0
static krb5_socket_t
make_signal_socket (krb5_context context)
{
#ifndef NO_UNIX_SOCKETS
    struct sockaddr_un addr;
    const char *fn;
    krb5_socket_t fd;

    fn = kadm5_log_signal_socket(context);

    fd = socket (AF_UNIX, SOCK_DGRAM, 0);
    if (fd < 0)
	krb5_err (context, 1, errno, "socket AF_UNIX");
    memset (&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strlcpy (addr.sun_path, fn, sizeof(addr.sun_path));
    unlink (addr.sun_path);
    if (bind (fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	krb5_err (context, 1, errno, "bind %s", addr.sun_path);
    return fd;
#else
    struct addrinfo *ai = NULL;
    krb5_socket_t fd;

    kadm5_log_signal_socket_info(context, 1, &ai);

    fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
    if (rk_IS_BAD_SOCKET(fd))
	krb5_err (context, 1, rk_SOCK_ERRNO, "socket AF=%d", ai->ai_family);

    if (rk_IS_SOCKET_ERROR( bind (fd, ai->ai_addr, ai->ai_addrlen) ))
	krb5_err (context, 1, rk_SOCK_ERRNO, "bind");
    return fd;
#endif
}
Пример #2
0
static void
socket_free(krb5_storage * sp)
{
    int save_errno = errno;
    if (rk_IS_SOCKET_ERROR(rk_closesocket(SOCK(sp))))
        errno = rk_SOCK_ERRNO;
    else
        errno = save_errno;
}
Пример #3
0
static void
wait_for_connection(krb5_context context,
		    krb5_socket_t *socks, unsigned int num_socks)
{
    unsigned int i;
    int e;
    fd_set orig_read_set, read_set;
    int status, max_fd = -1;

    FD_ZERO(&orig_read_set);

    for(i = 0; i < num_socks; i++) {
#ifdef FD_SETSIZE
	if (socks[i] >= FD_SETSIZE)
	    errx (1, "fd too large");
#endif
	FD_SET(socks[i], &orig_read_set);
	max_fd = max(max_fd, socks[i]);
    }

    pgrp = getpid();

    if(setpgid(0, pgrp) < 0)
	err(1, "setpgid");

    signal(SIGTERM, terminate);
    signal(SIGINT, terminate);
    signal(SIGCHLD, sigchld);

    while (term_flag == 0) {
	read_set = orig_read_set;
	e = select(max_fd + 1, &read_set, NULL, NULL, NULL);
	if(rk_IS_SOCKET_ERROR(e)) {
	    if(rk_SOCK_ERRNO != EINTR)
		krb5_warn(context, rk_SOCK_ERRNO, "select");
	} else if(e == 0)
	    krb5_warnx(context, "select returned 0");
	else {
	    for(i = 0; i < num_socks; i++) {
		if(FD_ISSET(socks[i], &read_set))
		    if(spawn_child(context, socks, num_socks, i) == 0)
			return;
	    }
	}
    }
    signal(SIGCHLD, SIG_IGN);

    while ((waitpid(-1, &status, WNOHANG)) > 0)
	;

    exit(0);
}
Пример #4
0
ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL
net_read(rk_socket_t sock, void *buf, size_t nbytes)
{
    char *cbuf = (char *)buf;
    ssize_t count;
    size_t rem = nbytes;

#ifdef SOCKET_IS_NOT_AN_FD
    int use_read = 0;
#endif

    while (rem > 0) {
#ifdef SOCKET_IS_NOT_AN_FD
        if (use_read)
            count = _read (sock, cbuf, rem);
        else
            count = recv (sock, cbuf, rem, 0);

        if (use_read == 0 &&
                rk_IS_SOCKET_ERROR(count) &&
                (rk_SOCK_ERRNO == WSANOTINITIALISED ||
                 rk_SOCK_ERRNO == WSAENOTSOCK)) {
            use_read = 1;

            count = _read (sock, cbuf, rem);
        }
#else
        count = recv (sock, cbuf, rem, 0);
#endif
        if (count < 0) {

            /* With WinSock, the error EINTR (WSAEINTR), is used to
               indicate that a blocking call was cancelled using
               WSACancelBlockingCall(). */

#ifndef HAVE_WINSOCK
            if (rk_SOCK_ERRNO == EINTR)
                continue;
#endif
            return count;
        } else if (count == 0) {
            return count;
        }
        cbuf += count;
        rem -= count;
    }
    return nbytes;
}
Пример #5
0
void
start_server(krb5_context context, const char *port_str)
{
    int e;
    struct kadm_port *p;

    krb5_socket_t *socks = NULL, *tmp;
    unsigned int num_socks = 0;
    int i;

    if (port_str == NULL)
	port_str = "+";

    parse_ports(context, port_str);

    for(p = kadm_ports; p; p = p->next) {
	struct addrinfo hints, *ai, *ap;
	char portstr[32];
	memset (&hints, 0, sizeof(hints));
	hints.ai_flags    = AI_PASSIVE;
	hints.ai_socktype = SOCK_STREAM;

	e = getaddrinfo(NULL, p->port, &hints, &ai);
	if(e) {
	    snprintf(portstr, sizeof(portstr), "%u", p->def_port);
	    e = getaddrinfo(NULL, portstr, &hints, &ai);
	}

	if(e) {
	    krb5_warn(context, krb5_eai_to_heim_errno(e, errno),
		      "%s", portstr);
	    continue;
	}
	i = 0;
	for(ap = ai; ap; ap = ap->ai_next)
	    i++;
	tmp = realloc(socks, (num_socks + i) * sizeof(*socks));
	if(tmp == NULL) {
	    krb5_warnx(context, "failed to reallocate %lu bytes",
		       (unsigned long)(num_socks + i) * sizeof(*socks));
	    continue;
	}
	socks = tmp;
	for(ap = ai; ap; ap = ap->ai_next) {
	    krb5_socket_t s = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
	    if(rk_IS_BAD_SOCKET(s)) {
		krb5_warn(context, rk_SOCK_ERRNO, "socket");
		continue;
	    }

	    socket_set_reuseaddr(s, 1);
	    socket_set_ipv6only(s, 1);

	    if (rk_IS_SOCKET_ERROR(bind (s, ap->ai_addr, ap->ai_addrlen))) {
		krb5_warn(context, rk_SOCK_ERRNO, "bind");
		rk_closesocket(s);
		continue;
	    }
	    if (rk_IS_SOCKET_ERROR(listen (s, SOMAXCONN))) {
		krb5_warn(context, rk_SOCK_ERRNO, "listen");
		rk_closesocket(s);
		continue;
	    }
	    socks[num_socks++] = s;
	}
	freeaddrinfo (ai);
    }
    if(num_socks == 0)
	krb5_errx(context, 1, "no sockets to listen to - exiting");

    wait_for_connection(context, socks, num_socks);
}
Пример #6
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_genaddrs(krb5_context context,
		       krb5_auth_context auth_context,
		       krb5_socket_t fd, int flags)
{
    krb5_error_code ret;
    krb5_address local_k_address, remote_k_address;
    krb5_address *lptr = NULL, *rptr = NULL;
    struct sockaddr_storage ss_local, ss_remote;
    struct sockaddr *local  = (struct sockaddr *)&ss_local;
    struct sockaddr *remote = (struct sockaddr *)&ss_remote;
    socklen_t len;

    if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR) {
	if (auth_context->local_address == NULL) {
	    len = sizeof(ss_local);
	    if(rk_IS_SOCKET_ERROR(getsockname(fd, local, &len))) {
		char buf[128];
		ret = rk_SOCK_ERRNO;
		rk_strerror_r(ret, buf, sizeof(buf));
		krb5_set_error_message(context, ret, "getsockname: %s", buf);
		goto out;
	    }
	    ret = krb5_sockaddr2address (context, local, &local_k_address);
	    if(ret) goto out;
	    if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) {
		krb5_sockaddr2port (context, local, &auth_context->local_port);
	    } else
		auth_context->local_port = 0;
	    lptr = &local_k_address;
	}
    }
    if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) {
	len = sizeof(ss_remote);
	if(rk_IS_SOCKET_ERROR(getpeername(fd, remote, &len))) {
	    char buf[128];
	    ret = rk_SOCK_ERRNO;
	    rk_strerror_r(ret, buf, sizeof(buf));
	    krb5_set_error_message(context, ret, "getpeername: %s", buf);
	    goto out;
	}
	ret = krb5_sockaddr2address (context, remote, &remote_k_address);
	if(ret) goto out;
	if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) {
	    krb5_sockaddr2port (context, remote, &auth_context->remote_port);
	} else
	    auth_context->remote_port = 0;
	rptr = &remote_k_address;
    }
    ret = krb5_auth_con_setaddrs (context,
				  auth_context,
				  lptr,
				  rptr);
  out:
    if (lptr)
	krb5_free_address (context, lptr);
    if (rptr)
	krb5_free_address (context, rptr);
    return ret;

}
Пример #7
0
KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
krb5_net_write_block(krb5_context context,
		     void *p_fd,
		     const void *buf,
		     size_t len,
		     time_t timeout)
{
  krb5_socket_t fd = *((krb5_socket_t *)p_fd);
  int ret;
  struct timeval tv, *tvp;
  const char *cbuf = (const char *)buf;
  size_t rem = len;
  ssize_t count;
  fd_set wfds;

  do {
      FD_ZERO(&wfds);
      FD_SET(fd, &wfds);

      if (timeout != 0) {
	  tv.tv_sec = timeout;
	  tv.tv_usec = 0;
	  tvp = &tv;
      } else
	  tvp = NULL;

      ret = select(fd + 1, NULL, &wfds, NULL, tvp);
      if (rk_IS_SOCKET_ERROR(ret)) {
	  if (rk_SOCK_ERRNO == EINTR)
	      continue;
	  return -1;
      } 

#ifdef HAVE_WINSOCK
      if (ret == 0) {
	  WSASetLastError( WSAETIMEDOUT );
	  return 0;
      }

      count = send (fd, cbuf, rem, 0);

      if (rk_IS_SOCKET_ERROR(count)) {
	  return -1;
      }

#else
      if (ret == 0) {
	  return 0;
      }

      if (!FD_ISSET(fd, &wfds)) {
	  errno = ETIMEDOUT;
	  return -1;
      }

      count = write (fd, cbuf, rem);

      if (count < 0) {
	  if (errno == EINTR)
	      continue;
	  else
	      return count;
      }

#endif

      cbuf += count;
      rem -= count;

  } while (rem > 0);

  return len;
}