Пример #1
0
int validate_access(char *client_addr, char *client_name)
{
  int stat = 0;
#ifdef HAVE_LIBWRAP
  int i;

  if ( use_tcpwrap ) {
    /* proc ident pattern */
    stat = hosts_ctl(ident, client_name, client_addr, STRING_UNKNOWN);
    /* IP.PORT pattern */
    for (i = 0; i < serv_sock_ind; i++) {
      if (str_serv_sock[i] != NULL && str_serv_sock[i][0] != 0) {
	stat |= hosts_ctl(str_serv_sock[i],
			  client_name, client_addr, STRING_UNKNOWN);
      }
    }
  } else {
#endif /* HAVE_LIBWRAP */
    stat = 1;  /* allow access un-conditionaly */
#ifdef HAVE_LIBWRAP
  }
#endif /* HAVE_LIBWRAP */

  if (stat < 1) {
    msg_out(warn, "%s[%s] access denied.", client_name, client_addr);
  }

  return stat;
}
Пример #2
0
static int
check_host (struct sockaddr *sa)
{
  struct sockaddr_in *sin;
  struct hostent *hp;
  char *addr;

  if (sa->sa_family != AF_INET)
    return 1;

  sin = (struct sockaddr_in *)sa;
  hp = gethostbyaddr ((char *)&sin->sin_addr,
		      sizeof (struct in_addr), AF_INET);
  addr = inet_ntoa (sin->sin_addr);
  if (hp)
    {
      if (!hosts_ctl ("ftpd", hp->h_name, addr, STRING_UNKNOWN))
	{
	  syslog (LOG_NOTICE, "tcpwrappers rejected: %s [%s]",
		  hp->h_name, addr);
	  return 0;
	}
    }
  else
    {
      if (!hosts_ctl ("ftpd", STRING_UNKNOWN, addr, STRING_UNKNOWN))
	{
	  syslog (LOG_NOTICE, "tcpwrappers rejected: [%s]", addr);
	  return 0;
	}
    }
  return (1);
}
Пример #3
0
static int
good_client(struct sockaddr_in *addr)
{
	if (hosts_ctl("portmap", "", inet_ntoa(addr->sin_addr), ""))
		return 1;
#ifdef ENABLE_DNS
{
	struct hostent *hp;
	char **sp;
	char *tmpname;

	/* Check the hostname. */
	hp = gethostbyaddr ((const char *) &(addr->sin_addr),
			    sizeof (addr->sin_addr), AF_INET);

	if (!hp)
		return 0;

	/* must make sure the hostent is authoritative. */
	tmpname = alloca (strlen (hp->h_name) + 1);
	strcpy (tmpname, hp->h_name);
	hp = gethostbyname(tmpname);
	if (hp) {
		/* now make sure the "addr->sin_addr" is on the list */
		for (sp = hp->h_addr_list ; *sp ; sp++) {
			if (memcmp(*sp, &(addr->sin_addr), hp->h_length)==0)
				break;
		}
		if (!*sp)
			/* it was a FAKE. */
			return 0;
	} else
		/* never heard of it. misconfigured DNS? */
		return 0;

	/* Check the official name first. */
	if (hosts_ctl("portmap", "", hp->h_name, ""))
		return 1;

	/* Check aliases. */
	for (sp = hp->h_aliases; *sp ; sp++) {
		if (hosts_ctl("portmap", "", *sp, ""))
			return 1;
	}
}
#endif /* ENABLE_DNS */
	return 0;
}
Пример #4
0
static int
pre_parse(netsnmp_session * session, netsnmp_transport *transport,
          void *transport_data, int transport_data_length)
{
#if NETSNMP_USE_LIBWRAP
    char *addr_string = NULL;

    if (transport != NULL && transport->f_fmtaddr != NULL) {
        /*
         * Okay I do know how to format this address for logging.  
         */
        addr_string = transport->f_fmtaddr(transport, transport_data,
                                           transport_data_length);
        /*
         * Don't forget to free() it.  
         */
    }

    if (addr_string != NULL) {
      /* Catch udp,udp6,tcp,tcp6 transports using "[" */
      char *tcpudpaddr = strstr(addr_string, "[");
      if ( tcpudpaddr != 0 ) {
	char sbuf[64];
	char *xp;

	strlcpy(sbuf, tcpudpaddr + 1, sizeof(sbuf));
        xp = strstr(sbuf, "]");
        if (xp)
            *xp = '\0';

        if (hosts_ctl("snmptrapd", STRING_UNKNOWN, 
		      sbuf, STRING_UNKNOWN) == 0) {
            DEBUGMSGTL(("snmptrapd:libwrap", "%s rejected", addr_string));
            SNMP_FREE(addr_string);
            return 0;
        }
      }
      SNMP_FREE(addr_string);
    } else {
        if (hosts_ctl("snmptrapd", STRING_UNKNOWN,
                      STRING_UNKNOWN, STRING_UNKNOWN) == 0) {
            DEBUGMSGTL(("snmptrapd:libwrap", "[unknown] rejected"));
            return 0;
        }
    }
#endif/*  NETSNMP_USE_LIBWRAP  */
    return 1;
}
Пример #5
0
/**********************************************************************
 * Do authentication & authorization check
 **********************************************************************/
int is_authorized(osm_console_t * p_oct)
{
	/* allowed to use the console? */
	p_oct->authorized = !is_remote(p_oct->client_type) ||
	    hosts_ctl(OSM_DAEMON_NAME, p_oct->client_hn, p_oct->client_ip,
		      "STRING_UNKNOWN");
	return p_oct->authorized;
}
Пример #6
0
static int resolve_addr(server_conf_t *conf, req_t *req, int sd)
{
/*  Resolves the network information associated with the
 *    peer at the other end of the socket connection.
 *  Returns 0 if the remote client address is valid, or -1 on error.
 */
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);
    char buf[MAX_LINE];
    char *p;
    int gotHostName = 0;

    assert(sd >= 0);

    req->sd = sd;
    if (getpeername(sd, (struct sockaddr *) &addr, &addrlen) < 0)
        log_err(errno, "Unable to get address of remote peer");
    if (!inet_ntop(AF_INET, &addr.sin_addr, buf, sizeof(buf)))
        log_err(errno, "Unable to convert network address into string");
    req->port = ntohs(addr.sin_port);
    req->ip = create_string(buf);
    /*
     *  Attempt to resolve IP address.  If it succeeds, buf contains
     *    host string; if it fails, buf is unchanged with IP addr string.
     *    Either way, copy buf to prevent having to code everything as
     *    (req->host ? req->host : req->ip).
     */
    if ((host_addr4_to_name(&addr.sin_addr, buf, sizeof(buf)))) {
        gotHostName = 1;
        req->fqdn = create_string(buf);
        if ((p = strchr(buf, '.')))
            *p = '\0';
        req->host = create_string(buf);
    }
    else {
        req->fqdn = create_string(buf);
        req->host = create_string(buf);
    }

#if WITH_TCP_WRAPPERS
    /*
     *  Check via TCP-Wrappers.
     */
    if (conf->enableTCPWrap) {
        if (hosts_ctl(CONMAN_DAEMON_NAME,
          (gotHostName ? req->fqdn : STRING_UNKNOWN),
          req->ip, STRING_UNKNOWN) == 0) {
            log_msg(LOG_NOTICE,
                "TCP-Wrappers rejected connection from <%s:%d>",
                req->fqdn, req->port);
            return(-1);
        }
    }
#endif /* WITH_TCP_WRAPPERS */

    return(0);
}
Пример #7
0
/*
 * check if remote amq is authorized to access this amd.
 * Returns: 1=allowed, 0=denied.
 */
static int
amqsvc_is_client_allowed(const struct sockaddr_in *addr, char *remote)
{
  struct hostent *h;
  char *name = NULL, **ad;
  int ret = 0;			/* default is 0==denied */

  /* Check IP address */
  if (hosts_ctl(AMD_SERVICE_NAME, "", remote, "")) {
    ret = 1;
    goto out;
  }
  /* Get address */
  if (!(h = gethostbyaddr((const char *)&(addr->sin_addr),
                          sizeof(addr->sin_addr),
                          AF_INET)))
    goto out;
  if (!(name = strdup(h->h_name)))
    goto out;
  /* Paranoia check */
  if (!(h = gethostbyname(name)))
    goto out;
  for (ad = h->h_addr_list; *ad; ad++)
    if (!memcmp(*ad, &(addr->sin_addr), h->h_length))
      break;
  if (!*ad)
    goto out;
  if (hosts_ctl(AMD_SERVICE_NAME, "", h->h_name, "")) {
    return 1;
    goto out;
  }
  /* Check aliases */
  for (ad = h->h_aliases; *ad; ad++)
    if (hosts_ctl(AMD_SERVICE_NAME, "", *ad, "")) {
      return 1;
      goto out;
    }

 out:
  if (name)
    XFREE(name);
  return ret;
}
Пример #8
0
/*******************************************************************-o-******
 * snmp_check_packet
 *
 * Parameters:
 *	session, from
 *
 * Returns:
 *	1	On success.
 *	0	On error.
 *
 * Handler for all incoming messages (a.k.a. packets) for the agent.  If using
 * the libwrap utility, log the connection and deny/allow the access. Print
 * output when appropriate, and increment the incoming counter.
 *
 */
int
snmp_check_packet(struct snmp_session *session,
                  snmp_ipaddr from)
{
    struct sockaddr_in *fromIp = (struct sockaddr_in *)&from;

#ifdef USE_LIBWRAP
    const char *addr_string;
    /*
     * Log the message and/or dump the message.
     * Optionally cache the network address of the sender.
     */
    addr_string = inet_ntoa(fromIp->sin_addr);

    if(!addr_string) {
        addr_string = STRING_UNKNOWN;
    }
    if(hosts_ctl("snmpd", addr_string, addr_string, STRING_UNKNOWN)) {
        snmp_log(allow_severity, "Connection from %s\n", addr_string);
    } else {
        snmp_log(deny_severity, "Connection from %s REFUSED\n", addr_string);
        return(0);
    }
#endif	/* USE_LIBWRAP */

    snmp_increment_statistic(STAT_SNMPINPKTS);

    if (log_addresses || ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE)) {
        int count;

        for(count = 0; count < ADDRCACHE; count++) {
            if (addrCache[count].status > UNUSED /* used or old */
                    && fromIp->sin_addr.s_addr == addrCache[count].addr)
                break;
        }

        if (count >= ADDRCACHE ||
                ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE)) {
            snmp_log(LOG_INFO, "Received SNMP packet(s) from %s\n",
                     inet_ntoa(fromIp->sin_addr));
            for(count = 0; count < ADDRCACHE; count++) {
                if (addrCache[count].status == UNUSED) {
                    addrCache[count].addr = fromIp->sin_addr.s_addr;
                    addrCache[count].status = USED;
                    break;
                }
            }
        } else {
            addrCache[count].status = USED;
        }
    }

    return ( 1 );
}
Пример #9
0
/* Accept one connection on a ready fd and pass it on to the npfs 9P engine.
 */
void
diod_sock_accept_one (Npsrv *srv, int fd)
{
    struct sockaddr_storage addr;
    socklen_t addr_size = sizeof(addr);
    char host[NI_MAXHOST], ip[NI_MAXHOST], svc[NI_MAXSERV];
    int res;

    fd = accept (fd, (struct sockaddr *)&addr, &addr_size);
    if (fd < 0) {
        if (!(errno == EWOULDBLOCK || errno == ECONNABORTED || errno == EPROTO
                                                            || errno == EINTR))
            err ("accept");
        return;
    }
    if ((res = getnameinfo ((struct sockaddr *)&addr, addr_size,
                            ip, sizeof(ip), svc, sizeof(svc),
                            NI_NUMERICHOST | NI_NUMERICSERV))) {
        msg ("getnameinfo: %s", gai_strerror(res));
        close (fd);
        return;
    }
    if (addr.ss_family != AF_UNIX) {
        (void)_disable_nagle (fd);
        (void)_enable_keepalive (fd);
    }
    if ((res = getnameinfo ((struct sockaddr *)&addr, addr_size,
                            host, sizeof(host), NULL, 0, 0))) {
        msg ("getnameinfo: %s", gai_strerror(res));
        close (fd);
        return;
    }
#if HAVE_TCP_WRAPPERS
    res = hosts_ctl (DAEMON_NAME, host, ip, STRING_UNKNOWN);
    if (!res) {
        msg ("connect denied by wrappers: %s:%s", host, svc);
        close (fd);
        return;
    }
#endif
    diod_sock_startfd (srv, fd, fd, strlen(host) > 0 ? host : ip);
}
Пример #10
0
rfbBool
rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen)
{
    const int one = 1;
    int sock = -1;
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);

    if ((sock = accept(rfbScreen->listenSock,
		       (struct sockaddr *)&addr, &addrlen)) < 0) {
      rfbLogPerror("rfbCheckFds: accept");
      return FALSE;
    }

    if(!rfbSetNonBlocking(sock)) {
      closesocket(sock);
      return FALSE;
    }

    if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
		   (char *)&one, sizeof(one)) < 0) {
      rfbLogPerror("rfbCheckFds: setsockopt");
      closesocket(sock);
      return FALSE;
    }

#ifdef USE_LIBWRAP
    if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
		  STRING_UNKNOWN)) {
      rfbLog("Rejected connection from client %s\n",
	     inet_ntoa(addr.sin_addr));
      closesocket(sock);
      return FALSE;
    }
#endif

    rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));

    rfbNewClient(rfbScreen,sock);

    return TRUE;
}
Пример #11
0
Файл: server.c Проект: sdsc/base
/*
 * returns nonzero if tcpd/libwrap allows this connection
 * returns 0 if tcpd/libwrap denies this connection
 */
int tcpd_allowed(struct svc_req *rqstp)
{
    static char remhost[1024];
    int result;

    assert(rqstp);
    assert(rqstp->rq_xprt);

    /* get the hostname from the IP */
    result = getnameinfo( (struct sockaddr *) &(rqstp->rq_xprt->xp_raddr),
                          rqstp->rq_xprt->xp_addrlen,
                          remhost,1024,
                          NULL, 0, 0);

    /* stop here if getnameinfo blew up */
    if(result && result != EAI_AGAIN && result != EAI_NONAME)
    {
        syslog(LOG_DEBUG,"getnameinfo(%s) failed: %s",
               inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr),
               strerror(result));
        return 0;
    }

    /* do the libwrap check */
    result = hosts_ctl(SERVICE_NAME, remhost,
                       inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr),
                       STRING_UNKNOWN);

    if(result)
    {
        return result;
    }

    /* report failures */
    syslog(LOG_DEBUG,"hosts_ctl(\"%s\",%s,%s) rejected connection",
           SERVICE_NAME, remhost,
           inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));

    return 0;

}
Пример #12
0
/* libwrap (tcpd): check the connection is legal. This is necessary because
 * the actual server will only see a connection coming from localhost and can't
 * apply the rules itself.
 *
 * Returns -1 if access is denied, 0 otherwise
 */
int check_access_rights(int in_socket, const char* service)
{
#ifdef LIBWRAP
    union {
        struct sockaddr saddr;
        struct sockaddr_storage ss;
    } peer;
    socklen_t size = sizeof(peer);
    char addr_str[NI_MAXHOST], host[NI_MAXHOST];
    int res;

    res = getpeername(in_socket, &peer.saddr, &size);
    CHECK_RES_RETURN(res, "getpeername");

    /* extract peer address */
    res = getnameinfo(&peer.saddr, size, addr_str, sizeof(addr_str), NULL, 0, NI_NUMERICHOST);
    if (res) {
        if (verbose)
            fprintf(stderr, "getnameinfo(NI_NUMERICHOST):%s\n", gai_strerror(res));
        strcpy(addr_str, STRING_UNKNOWN);
    }
    /* extract peer name */
    strcpy(host, STRING_UNKNOWN);
    if (!numeric) {
        res = getnameinfo(&peer.saddr, size, host, sizeof(host), NULL, 0, NI_NAMEREQD);
        if (res) {
            if (verbose)
                fprintf(stderr, "getnameinfo(NI_NAMEREQD):%s\n", gai_strerror(res));
        }
    }

    if (!hosts_ctl(service, host, addr_str, STRING_UNKNOWN)) {
        if (verbose)
            fprintf(stderr, "access denied\n");
        log_message(LOG_INFO, "connection from %s(%s): access denied", host, addr_str);
        close(in_socket);
        return -1;
    }
#endif
    return 0;
}
Пример #13
0
/*
 * rpcb_check; the rpcbind/portmap access check function.
 */
boolean_t
rpcb_check(SVCXPRT *transp, rpcproc_t procnum, boolean_t ispmap)
{
    struct netconfig *conf;
    boolean_t res = B_TRUE;

    if ((conf = rpcbind_get_conf(transp->xp_netid)) == 0) {
        syslog(LOG_ERR,
               "rpcbind_get_conf failed: no client address checks");
        return (B_TRUE);
    }

    /*
     * Require IPv4 for pmap calls; they're not defined for anything else.
     */
    if (ispmap && strcmp(conf->nc_protofmly, "inet") != 0) {
        res = B_FALSE;
    } else if (strcmp(conf->nc_protofmly, "inet") == 0 ||
               strcmp(conf->nc_protofmly, "inet6") == 0) {
        const char *addr_string = sgen_toa(svc_getgencaller(transp));

        if (!localxprt(transp, ispmap) &&
                (local_only ||
                 hosts_ctl("rpcbind", addr_string, addr_string, "") == 0)) {
            res = B_FALSE;
        }
    }
out:
    if (!res)
        svcerr_auth(transp, AUTH_FAILED);

    if (verboselog || !res)
        rpcb_log(res, transp, procnum, 0, ispmap);

    return (res);
}
Пример #14
0
void
rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
{
    int nfds;
    fd_set fds;
    struct timeval tv;
#ifdef LIBVNCSERVER_IPv6
    struct sockaddr_storage addr;
#else
    struct sockaddr_in addr;
#endif
    socklen_t addrlen = sizeof(addr);

    if (!rfbScreen->httpDir)
	return;

    if (rfbScreen->httpListenSock < 0)
	return;

    FD_ZERO(&fds);
    FD_SET(rfbScreen->httpListenSock, &fds);
    if (rfbScreen->httpListen6Sock >= 0) {
	FD_SET(rfbScreen->httpListen6Sock, &fds);
    }
    if (rfbScreen->httpSock >= 0) {
	FD_SET(rfbScreen->httpSock, &fds);
    }
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    nfds = select(max(rfbScreen->httpListen6Sock, max(rfbScreen->httpSock,rfbScreen->httpListenSock)) + 1, &fds, NULL, NULL, &tv);
    if (nfds == 0) {
	return;
    }
    if (nfds < 0) {
#ifdef WIN32
		errno = WSAGetLastError();
#endif
	if (errno != EINTR)
		rfbLogPerror("httpCheckFds: select");
	return;
    }

    if ((rfbScreen->httpSock >= 0) && FD_ISSET(rfbScreen->httpSock, &fds)) {
	httpProcessInput(rfbScreen);
    }

    if (FD_ISSET(rfbScreen->httpListenSock, &fds) || FD_ISSET(rfbScreen->httpListen6Sock, &fds)) {
	if (rfbScreen->httpSock >= 0) close(rfbScreen->httpSock);

	if(FD_ISSET(rfbScreen->httpListenSock, &fds)) {
	    if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock, (struct sockaddr *)&addr, &addrlen)) < 0) {
	      rfbLogPerror("httpCheckFds: accept");
	      return;
	    }
	}
	else if(FD_ISSET(rfbScreen->httpListen6Sock, &fds)) {
	    if ((rfbScreen->httpSock = accept(rfbScreen->httpListen6Sock, (struct sockaddr *)&addr, &addrlen)) < 0) {
	      rfbLogPerror("httpCheckFds: accept");
	      return;
	    }
	}

#ifdef USE_LIBWRAP
	char host[1024];
#ifdef LIBVNCSERVER_IPv6
	if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) {
	  rfbLogPerror("httpCheckFds: error in getnameinfo");
	  host[0] = '\0';
	}
#else
	memcpy(host, inet_ntoa(addr.sin_addr), sizeof(host));
#endif
	if(!hosts_ctl("vnc",STRING_UNKNOWN, host,
		      STRING_UNKNOWN)) {
	  rfbLog("Rejected HTTP connection from client %s\n",
		 host);
	  close(rfbScreen->httpSock);
	  rfbScreen->httpSock=-1;
	  return;
	}
#endif
        if(!rfbSetNonBlocking(rfbScreen->httpSock)) {
	    close(rfbScreen->httpSock);
	    rfbScreen->httpSock=-1;
	    return;
	}
	/*AddEnabledDevice(httpSock);*/
    }
}
Пример #15
0
int
rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
{
    int nfds;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);
    char buf[6];
    const int one = 1;
    int sock;
    rfbClientIteratorPtr i;
    rfbClientPtr cl;
    struct timeval tv_msg;
    fd_set fds_msg;
    int nfds_msg;
    int result = 0;

    if (!rfbScreen->inetdInitDone && rfbScreen->inetdSock != -1) {
        rfbNewClientConnection(rfbScreen,rfbScreen->inetdSock);
        rfbScreen->inetdInitDone = TRUE;
    }

    do {
        memcpy((char *)&fds, (char *)&(rfbScreen->allFds), sizeof(fd_set));
        tv.tv_sec = 0;
        tv.tv_usec = usec;
        nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv);
        if (nfds == 0) {
            /* timed out, check for async events */
            i = rfbGetClientIterator(rfbScreen);
            while((cl = rfbClientIteratorNext(i))) {
                if (cl->onHold)
                    continue;
                if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
                    rfbSendFileTransferChunk(cl);
            }
            rfbReleaseClientIterator(i);
            return result;
        }

        if (nfds < 0) {
#ifdef WIN32
            errno = WSAGetLastError();
#endif
            if (errno != EINTR)
                rfbLogPerror("rfbCheckFds: select");
            return -1;
        }

        result += nfds;

        if (rfbScreen->listenSock != -1 && FD_ISSET(rfbScreen->listenSock, &fds)) {
            if ((sock = accept(rfbScreen->listenSock,
                               (struct sockaddr *)&addr, &addrlen)) < 0) {
                rfbLogPerror("rfbCheckFds: accept");
                return -1;
            }

#ifndef WIN32
            if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
                rfbLogPerror("rfbCheckFds: fcntl");
                closesocket(sock);
                return -1;
            }
#endif

            if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
                           (char *)&one, sizeof(one)) < 0) {
                rfbLogPerror("rfbCheckFds: setsockopt");
                closesocket(sock);
                return -1;
            }

#ifdef USE_LIBWRAP
            if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
                          STRING_UNKNOWN)) {
                rfbLog("Rejected connection from client %s\n",
                       inet_ntoa(addr.sin_addr));
                closesocket(sock);
                return -1;
            }
#endif

            rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));

            rfbNewClient(rfbScreen,sock);

            FD_CLR(rfbScreen->listenSock, &fds);
            if (--nfds == 0)
                return result;
        }

        if ((rfbScreen->udpSock != -1) && FD_ISSET(rfbScreen->udpSock, &fds)) {
            if(!rfbScreen->udpClient)
                rfbNewUDPClient(rfbScreen);
            if (recvfrom(rfbScreen->udpSock, buf, 1, MSG_PEEK,
                         (struct sockaddr *)&addr, &addrlen) < 0) {
                rfbLogPerror("rfbCheckFds: UDP: recvfrom");
                rfbDisconnectUDPSock(rfbScreen);
                rfbScreen->udpSockConnected = FALSE;
            } else {
                if (!rfbScreen->udpSockConnected ||
                        (memcmp(&addr, &rfbScreen->udpRemoteAddr, addrlen) != 0))
                {
                    /* new remote end */
                    rfbLog("rfbCheckFds: UDP: got connection\n");

                    memcpy(&rfbScreen->udpRemoteAddr, &addr, addrlen);
                    rfbScreen->udpSockConnected = TRUE;

                    if (connect(rfbScreen->udpSock,
                                (struct sockaddr *)&addr, addrlen) < 0) {
                        rfbLogPerror("rfbCheckFds: UDP: connect");
                        rfbDisconnectUDPSock(rfbScreen);
                        return -1;
                    }

                    rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock);
                }

                rfbProcessUDPInput(rfbScreen);
            }

            FD_CLR(rfbScreen->udpSock, &fds);
            if (--nfds == 0)
                return result;
        }

        i = rfbGetClientIterator(rfbScreen);
        while((cl = rfbClientIteratorNext(i))) {

            if (cl->onHold)
                continue;

            if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
            {
                if (FD_ISSET(cl->sock, &fds)) {
                    tv_msg.tv_sec = 0;
                    tv_msg.tv_usec = 0;
                    FD_ZERO(&fds_msg);
                    FD_SET(cl->sock, &fds_msg);
                    do {
                        /* drain all messages, speed up mouse move processing */
                        rfbProcessClientMessage(cl);
                        nfds_msg = select(cl->sock + 1, &fds_msg, NULL, NULL, &tv_msg);
                    } while (nfds_msg > 0);
                }
                else
                    rfbSendFileTransferChunk(cl);
            }
        }
        rfbReleaseClientIterator(i);
    } while(rfbScreen->handleEventsEagerly);
    return result;
}
Пример #16
0
void
rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
{
    int nfds;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);

    if (!rfbScreen->httpDir)
	return;

    if (rfbScreen->httpListenSock < 0)
	return;

    FD_ZERO(&fds);
    FD_SET(rfbScreen->httpListenSock, &fds);
    if (rfbScreen->httpSock >= 0) {
	FD_SET(rfbScreen->httpSock, &fds);
    }
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    nfds = select(max(rfbScreen->httpSock,rfbScreen->httpListenSock) + 1, &fds, NULL, NULL, &tv);
    if (nfds == 0) {
	return;
    }
    if (nfds < 0) {
#ifdef WIN32
		errno = WSAGetLastError();
#endif
	if (errno != EINTR)
		rfbLogPerror("httpCheckFds: select");
	return;
    }

    if ((rfbScreen->httpSock >= 0) && FD_ISSET(rfbScreen->httpSock, &fds)) {
	httpProcessInput(rfbScreen);
    }

    if (FD_ISSET(rfbScreen->httpListenSock, &fds)) {
	if (rfbScreen->httpSock >= 0) close(rfbScreen->httpSock);

	if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock,
			       (struct sockaddr *)&addr, &addrlen)) < 0) {
	    rfbLogPerror("httpCheckFds: accept");
	    return;
	}
#ifdef USE_LIBWRAP
	if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
		      STRING_UNKNOWN)) {
	  rfbLog("Rejected HTTP connection from client %s\n",
		 inet_ntoa(addr.sin_addr));
	  close(rfbScreen->httpSock);
	  rfbScreen->httpSock=-1;
	  return;
	}
#endif
        if(!rfbSetNonBlocking(rfbScreen->httpSock)) {
	    close(rfbScreen->httpSock);
	    rfbScreen->httpSock=-1;
	    return;
	}
	/*AddEnabledDevice(httpSock);*/
    }
}
Пример #17
0
rfbBool
rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen)
{
    const int one = 1;
    int sock = -1;
#ifdef LIBVNCSERVER_IPv6
    struct sockaddr_storage addr;
#else
    struct sockaddr_in addr;
#endif
    socklen_t addrlen = sizeof(addr);
    fd_set listen_fds; 
    int chosen_listen_sock = -1;

    /* Do another select() call to find out which listen socket
       has an incoming connection pending. We know that at least 
       one of them has, so this should not block for too long! */
    FD_ZERO(&listen_fds);  
    if(rfbScreen->listenSock >= 0) 
      FD_SET(rfbScreen->listenSock, &listen_fds);
    if(rfbScreen->listen6Sock >= 0) 
      FD_SET(rfbScreen->listen6Sock, &listen_fds);
    if (select(rfbScreen->maxFd+1, &listen_fds, NULL, NULL, NULL) == -1) {
      rfbLogPerror("rfbProcessNewConnection: error in select");
      return FALSE;
    }
    if (rfbScreen->listenSock >= 0 && FD_ISSET(rfbScreen->listenSock, &listen_fds))
      chosen_listen_sock = rfbScreen->listenSock;
    if (rfbScreen->listen6Sock >= 0 && FD_ISSET(rfbScreen->listen6Sock, &listen_fds))
      chosen_listen_sock = rfbScreen->listen6Sock;

    if ((sock = accept(chosen_listen_sock,
		       (struct sockaddr *)&addr, &addrlen)) < 0) {
      rfbLogPerror("rfbCheckFds: accept");
      return FALSE;
    }

    if(!rfbSetNonBlocking(sock)) {
      closesocket(sock);
      return FALSE;
    }

    if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
		   (char *)&one, sizeof(one)) < 0) {
      rfbLogPerror("rfbCheckFds: setsockopt");
      closesocket(sock);
      return FALSE;
    }

#ifdef USE_LIBWRAP
    if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
		  STRING_UNKNOWN)) {
      rfbLog("Rejected connection from client %s\n",
	     inet_ntoa(addr.sin_addr));
      closesocket(sock);
      return FALSE;
    }
#endif

#ifdef LIBVNCSERVER_IPv6
    {
        char host[1024];
        if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) {
            rfbLogPerror("rfbProcessNewConnection: error in getnameinfo");
        }
        rfbLog("Got connection from client %s\n", host);
    }
#else
    rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));
#endif

    rfbNewClient(rfbScreen,sock);

    return TRUE;
}
Пример #18
0
void
httpCheckFds(rfbScreenInfoPtr rfbScreen)
{
    int nfds;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);

    if (!rfbScreen->httpDir)
        return;

    FD_ZERO(&fds);
    FD_SET(rfbScreen->httpListenSock, &fds);
    if (rfbScreen->httpSock >= 0) {
        FD_SET(rfbScreen->httpSock, &fds);
    }
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    nfds = select(max(rfbScreen->httpSock,rfbScreen->httpListenSock) + 1, &fds, NULL, NULL, &tv);
    if (nfds == 0) {
        return;
    }
    if (nfds < 0) {
#ifdef WIN32
        errno = WSAGetLastError();
#endif
        rfbLogPerror("httpCheckFds: select");
        return;
    }

    if ((rfbScreen->httpSock >= 0) && FD_ISSET(rfbScreen->httpSock, &fds)) {
        httpProcessInput(rfbScreen);
    }

    if (FD_ISSET(rfbScreen->httpListenSock, &fds)) {
        int flags;
        if (rfbScreen->httpSock >= 0) close(rfbScreen->httpSock);

        if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock,
                                          (struct sockaddr *)&addr, &addrlen)) < 0) {
            rfbLogPerror("httpCheckFds: accept");
            return;
        }
#ifdef USE_LIBWRAP
        if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
                      STRING_UNKNOWN)) {
            rfbLog("Rejected connection from client %s\n",
                   inet_ntoa(addr.sin_addr));
#else
        if ((rfbScreen->httpFP = fdopen(rfbScreen->httpSock, "r+")) == NULL) {
            rfbLogPerror("httpCheckFds: fdopen");
#endif
            close(rfbScreen->httpSock);
            rfbScreen->httpSock = -1;
            return;
        }
        flags=fcntl(rfbScreen->httpSock,F_GETFL);
        if(flags==-1 ||
                fcntl(rfbScreen->httpSock,F_SETFL,flags|O_NONBLOCK)==-1) {
            rfbLogPerror("httpCheckFds: fcntl");
            close(rfbScreen->httpSock);
            rfbScreen->httpSock=-1;
            return;
        }

        /*AddEnabledDevice(httpSock);*/
    }
}


static void
httpCloseSock(rfbScreenInfoPtr rfbScreen)
{
    fclose(rfbScreen->httpFP);
    rfbScreen->httpFP = NULL;
    /*RemoveEnabledDevice(httpSock);*/
    rfbScreen->httpSock = -1;
}
Пример #19
0
int
snmp_read_packet(int sd)
{
    struct sockaddr_in	from;
    int length, out_length, fromlength;
    u_char  packet[1500], outpacket[1500];
#ifdef USE_LIBWRAP
    char *addr_string;
#endif
    fromlength = sizeof from;
    length = recvfrom(sd, (char *) packet, 1500, 0, (struct sockaddr *)&from,
		      &fromlength);
    if (length == -1)
	perror("recvfrom");

#ifdef USE_LIBWRAP
	addr_string = inet_ntoa(from.sin_addr);

	if(!addr_string) {
          addr_string = STRING_UNKNOWN;
	}
	if(hosts_ctl("snmpd", addr_string, addr_string, STRING_UNKNOWN)) {
          syslog(allow_severity, "Connection from %s", addr_string);
	} else {
          syslog(deny_severity, "Connection from %s refused", addr_string);
          return(0);
	}
#endif

#ifdef USING_MIBII_SNMP_MIB_MODULE       
    snmp_inpkts++;
#endif
    if (snmp_dump_packet){
	printf("\nreceived %d bytes from %s:\n", length,
	       inet_ntoa(from.sin_addr));
	xdump(packet, length, "");
	printf("\n");
        fflush(stdout);
    } else if (log_addresses){
	int count;
	
	for(count = 0; count < ADDRCACHE; count++){
	    if (addrCache[count].status > UNUSED /* used or old */
		&& from.sin_addr.s_addr == addrCache[count].addr)
		break;
	}
	if (count >= ADDRCACHE || verbose){
	    printf("%s Received SNMP packet(s) from %s\n",
		   sprintf_stamp(NULL), inet_ntoa(from.sin_addr));
	    for(count = 0; count < ADDRCACHE; count++){
		if (addrCache[count].status == UNUSED){
		    addrCache[count].addr = from.sin_addr.s_addr;
		    addrCache[count].status = USED;
		    break;
		}
	    }
	} else {
	    addrCache[count].status = USED;
	}
    }
    out_length = 1500;
    if (snmp_agent_parse(packet, length, outpacket, &out_length,
			 from.sin_addr.s_addr)){
	if (snmp_dump_packet){
	    printf("\nsent %d bytes to %s:\n", out_length,
		   inet_ntoa(from.sin_addr));
	    xdump(outpacket, out_length, "");
	    printf("\n");
            fflush(stdout);
	}
#ifdef USING_MIBII_SNMP_MIB_MODULE       
	snmp_outpkts++;
#endif
	if (sendto(sd, (char *)outpacket, out_length, 0,
		   (struct sockaddr *)&from, sizeof(from)) < 0){
	    perror("sendto");
	    return 0;
	}

    }
    return 1;
}
Пример #20
0
void
httpCheckFds()
{
    int nfds, n;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_in addr;
    int addrlen = sizeof(addr);

    if (!httpDir)
	return;

    FD_ZERO(&fds);
    FD_SET(httpListenSock, &fds);
    if (httpSock >= 0) {
	FD_SET(httpSock, &fds);
    }
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    nfds = select(max(httpSock,httpListenSock) + 1, &fds, NULL, NULL, &tv);
    if (nfds == 0) {
	return;
    }
    if (nfds < 0) {
	rfbLogPerror("httpCheckFds: select");
	return;
    }

    if ((httpSock >= 0) && FD_ISSET(httpSock, &fds)) {
	httpProcessInput();
    }

    if (FD_ISSET(httpListenSock, &fds)) {
	int flags;

	if (httpSock >= 0) close(httpSock);

	if ((httpSock = accept(httpListenSock,
			       (struct sockaddr *)&addr, &addrlen)) < 0) {
	    rfbLogPerror("httpCheckFds: accept");
	    return;
	}

#if USE_LIBWRAP
	if (!hosts_ctl("Xvnc", STRING_UNKNOWN, inet_ntoa(addr.sin_addr),
		       STRING_UNKNOWN)) {
	    rfbLog("Rejected HTTP connection from client %s\n",
		   inet_ntoa(addr.sin_addr));
	    close(httpSock);
	    httpSock = -1;
	    return;
	}
#endif

	flags = fcntl (httpSock, F_GETFL);

	if (flags == -1 ||
	fcntl (httpSock, F_SETFL, flags | O_NONBLOCK) == -1) {
	    rfbLogPerror("httpCheckFds: fcntl");
	    close (httpSock);
	    httpSock = -1;
	    return;
	}

	AddEnabledDevice(httpSock);
    }
}
Пример #21
0
static void *
slapd_daemon_task(
	void *ptr
)
{
	int l;
	time_t	last_idle_check = 0;
	struct timeval idle;
	time( &starttime );

#define SLAPD_IDLE_CHECK_LIMIT 4

	if ( global_idletimeout > 0 ) {
		last_idle_check = slap_get_time();
		/* Set the select timeout.
		 * Don't just truncate, preserve the fractions of
		 * seconds to prevent sleeping for zero time.
		 */
		idle.tv_sec = global_idletimeout/SLAPD_IDLE_CHECK_LIMIT;
		idle.tv_usec = global_idletimeout - idle.tv_sec * SLAPD_IDLE_CHECK_LIMIT;
		idle.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT;
	} else {
		idle.tv_sec = 0;
		idle.tv_usec = 0;
	}

	for ( l = 0; slap_listeners[l] != NULL; l++ ) {
		if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
			continue;
#ifdef LDAP_CONNECTIONLESS
		/* Since this is connectionless, the data port is the
		 * listening port. The listen() and accept() calls
		 * are unnecessary.
		 */
		if ( slap_listeners[l]->sl_is_udp ) {
			slapd_add( slap_listeners[l]->sl_sd );
			continue;
		}
#endif

		if ( listen( slap_listeners[l]->sl_sd, SLAPD_LISTEN ) == -1 ) {
			int err = sock_errno();

#ifdef LDAP_PF_INET6
			/* If error is EADDRINUSE, we are trying to listen to INADDR_ANY and
			 * we are already listening to in6addr_any, then we want to ignore
			 * this and continue.
			 */
			if ( err == EADDRINUSE ) {
				int i;
				struct sockaddr_in sa = slap_listeners[l]->sl_sa.sa_in_addr;
				struct sockaddr_in6 sa6;
				
				if ( sa.sin_family == AF_INET &&
				     sa.sin_addr.s_addr == htonl(INADDR_ANY) ) {
					for ( i = 0 ; i < l; i++ ) {
						sa6 = slap_listeners[i]->sl_sa.sa_in6_addr;
						if ( sa6.sin6_family == AF_INET6 &&
						     !memcmp( &sa6.sin6_addr, &in6addr_any, sizeof(struct in6_addr) ) )
							break;
					}

					if ( i < l ) {
						/* We are already listening to in6addr_any */
#ifdef NEW_LOGGING
						LDAP_LOG(CONNECTION, WARNING,
							   "slapd_daemon_task: Attempt to listen to 0.0.0.0 failed, already listening on ::, assuming IPv4 included\n", 0, 0, 0 );
#else
						Debug( LDAP_DEBUG_CONNS,
						       "daemon: Attempt to listen to 0.0.0.0 failed, already listening on ::, assuming IPv4 included\n",
						       0, 0, 0 );
#endif
						slapd_close( slap_listeners[l]->sl_sd );
						slap_listeners[l]->sl_sd = AC_SOCKET_INVALID;
						continue;
					}
				}
			}
#endif				
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, ERR, 
				"slapd_daemon_task: listen( %s, 5 ) failed errno=%d (%s)\n",
				slap_listeners[l]->sl_url.bv_val, err, sock_errstr(err) );
#else
			Debug( LDAP_DEBUG_ANY,
				"daemon: listen(%s, 5) failed errno=%d (%s)\n",
					slap_listeners[l]->sl_url.bv_val, err,
					sock_errstr(err) );
#endif
			return( (void*)-1 );
		}

		slapd_add( slap_listeners[l]->sl_sd );
	}

#ifdef HAVE_NT_SERVICE_MANAGER
	if ( started_event != NULL ) {
		ldap_pvt_thread_cond_signal( &started_event );
	}
#endif
	/* initialization complete. Here comes the loop. */

	while ( !slapd_shutdown ) {
		ber_socket_t i;
		int ns;
		int at;
		ber_socket_t nfds;
#define SLAPD_EBADF_LIMIT 16
		int ebadf = 0;

		time_t	now;

		fd_set			readfds;
		fd_set			writefds;
		Sockaddr		from;

		struct timeval		tv;
		struct timeval		*tvp;

		now = slap_get_time();

		if( ( global_idletimeout > 0 ) &&
			difftime( last_idle_check +
			global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 ) {
			connections_timeout_idle( now );
			last_idle_check = now;
		}
		tv = idle;

#ifdef SIGHUP
		if( slapd_gentle_shutdown ) {
			ber_socket_t active;

			if( slapd_gentle_shutdown == 1 ) {
				Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n", 0, 0, 0 );
				close_listeners( 1 );
				global_restrictops |= SLAP_RESTRICT_OP_WRITES;
				slapd_gentle_shutdown = 2;
			}

			ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
			active = slap_daemon.sd_nactives;
			ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
			if( active == 0 ) {
				slapd_shutdown = 2;
				break;
			}
		}
#endif

		FD_ZERO( &writefds );
		FD_ZERO( &readfds );

		at = 0;

		ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );

#ifdef FD_SET_MANUAL_COPY
		for( s = 0; s < nfds; s++ ) {
			if(FD_ISSET( &slap_sd_readers, s )) {
				FD_SET( s, &readfds );
			}
			if(FD_ISSET( &slap_sd_writers, s )) {
				FD_SET( s, &writefds );
			}
		}
#else
		AC_MEMCPY( &readfds, &slap_daemon.sd_readers, sizeof(fd_set) );
		AC_MEMCPY( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) );
#endif
		assert(!FD_ISSET(wake_sds[0], &readfds));
		FD_SET( wake_sds[0], &readfds );

		for ( l = 0; slap_listeners[l] != NULL; l++ ) {
			if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
				continue;
			if ( slap_listeners[l]->sl_is_mute )
				FD_CLR( slap_listeners[l]->sl_sd, &readfds );
			else
			if (!FD_ISSET(slap_listeners[l]->sl_sd, &readfds))
			    FD_SET( slap_listeners[l]->sl_sd, &readfds );
		}

#ifndef HAVE_WINSOCK
		nfds = slap_daemon.sd_nfds;
#else
		nfds = dtblsize;
#endif
		if ( global_idletimeout && slap_daemon.sd_nactives )
			at = 1;

		ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );

		if ( !at )
			at = ldap_pvt_thread_pool_backload(&connection_pool);

#if defined( HAVE_YIELDING_SELECT ) || defined( NO_THREADS )
		tvp = NULL;
#else
		tvp = at ? &tv : NULL;
#endif

		for ( l = 0; slap_listeners[l] != NULL; l++ ) {
			if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ||
			    slap_listeners[l]->sl_is_mute )
				continue;

#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL1, 
				"slapd_daemon_task: select: listen=%d "
				"active_threads=%d tvp=%s\n",
				slap_listeners[l]->sl_sd, at, tvp == NULL ? "NULL" : "idle" );
#else
			Debug( LDAP_DEBUG_CONNS,
				"daemon: select: listen=%d active_threads=%d tvp=%s\n",
					slap_listeners[l]->sl_sd, at,
					tvp == NULL ? "NULL" : "idle" );
#endif
		}

		switch(ns = select( nfds, &readfds,
#ifdef HAVE_WINSOCK
			/* don't pass empty fd_set */
			( writefds.fd_count > 0 ? &writefds : NULL ),
#else
			&writefds,
#endif
			NULL, tvp ))
		{
		case -1: {	/* failure - try again */
				int err = sock_errno();

				if( err == EBADF
#ifdef WSAENOTSOCK
					/* you'd think this would be EBADF */
					|| err == WSAENOTSOCK
#endif
				) {
					if (++ebadf < SLAPD_EBADF_LIMIT)
						continue;
				}

				if( err != EINTR ) {
#ifdef NEW_LOGGING
					LDAP_LOG( CONNECTION, INFO, 
						"slapd_daemon_task: select failed (%d): %s\n",
						err, sock_errstr(err), 0 );
#else
					Debug( LDAP_DEBUG_CONNS,
						"daemon: select failed (%d): %s\n",
						err, sock_errstr(err), 0 );
#endif
					slapd_shutdown = 2;
				}
			}
			continue;

		case 0:		/* timeout - let threads run */
			ebadf = 0;
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2,
				   "slapd_daemon_task: select timeout - yielding\n", 0, 0, 0 );
#else
			Debug( LDAP_DEBUG_CONNS, "daemon: select timeout - yielding\n",
			    0, 0, 0 );
#endif
			ldap_pvt_thread_yield();
			continue;

		default:	/* something happened - deal with it */
			if( slapd_shutdown ) continue;

			ebadf = 0;
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2, 
				   "slapd_daemon_task: activity on %d descriptors\n", ns, 0, 0 );
#else
			Debug( LDAP_DEBUG_CONNS, "daemon: activity on %d descriptors\n",
				ns, 0, 0 );
#endif
			/* FALL THRU */
		}

		if( FD_ISSET( wake_sds[0], &readfds ) ) {
			char c[BUFSIZ];
			tcp_read( wake_sds[0], c, sizeof(c) );
#if defined(NO_THREADS) || defined(HAVE_GNU_PTH)
			waking = 0;
#endif
			continue;
		}

		for ( l = 0; slap_listeners[l] != NULL; l++ ) {
			ber_socket_t s;
			socklen_t len = sizeof(from);
			long id;
			slap_ssf_t ssf = 0;
			char *authid = NULL;
#ifdef SLAPD_RLOOKUPS
			char hbuf[NI_MAXHOST];
#endif

			char	*dnsname = NULL;
			char	*peeraddr = NULL;
#ifdef LDAP_PF_LOCAL
			char	peername[MAXPATHLEN + sizeof("PATH=")];
#elif defined(LDAP_PF_INET6)
			char	peername[sizeof("IP=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535")];
#else
			char	peername[sizeof("IP=255.255.255.255:65336")];
#endif /* LDAP_PF_LOCAL */

			peername[0] = '\0';

			if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
				continue;

			if ( !FD_ISSET( slap_listeners[l]->sl_sd, &readfds ) )
				continue;

#ifdef LDAP_CONNECTIONLESS
			if ( slap_listeners[l]->sl_is_udp ) {
				/* The first time we receive a query, we set this
				 * up as a "connection". It remains open for the life
				 * of the slapd.
				 */
				if ( slap_listeners[l]->sl_is_udp < 2 ) {
				    id = connection_init(
					slap_listeners[l]->sl_sd,
				    	slap_listeners[l], "", "",
					2, ssf, authid );
				    slap_listeners[l]->sl_is_udp++;
				}
				continue;
			}
#endif

			/* Don't need to look at this in the data loops */
			FD_CLR( slap_listeners[l]->sl_sd, &readfds );
			FD_CLR( slap_listeners[l]->sl_sd, &writefds );

			s = accept( slap_listeners[l]->sl_sd,
				(struct sockaddr *) &from, &len );
			if ( s == AC_SOCKET_INVALID ) {
				int err = sock_errno();

				if(
#ifdef EMFILE
				    err == EMFILE ||
#endif
#ifdef ENFILE
				    err == ENFILE ||
#endif
				    0 )
				{
					ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
					emfile++;
					/* Stop listening until an existing session closes */
					slap_listeners[l]->sl_is_mute = 1;
					ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
				}

#ifdef NEW_LOGGING
				LDAP_LOG( CONNECTION, ERR, 
					"slapd_daemon_task: accept(%ld) failed errno=%d (%s)\n",
					(long)slap_listeners[l]->sl_sd, 
					err, sock_errstr(err) );
#else
				Debug( LDAP_DEBUG_ANY,
					"daemon: accept(%ld) failed errno=%d (%s)\n",
					(long) slap_listeners[l]->sl_sd, err,
					sock_errstr(err) );
#endif
				ldap_pvt_thread_yield();
				continue;
			}

#ifndef HAVE_WINSOCK
			/* make sure descriptor number isn't too great */
			if ( s >= dtblsize ) {
#ifdef NEW_LOGGING
				LDAP_LOG( CONNECTION, ERR, 
				   "slapd_daemon_task: %ld beyond descriptor table size %ld\n",
				   (long)s, (long)dtblsize, 0 );
#else
				Debug( LDAP_DEBUG_ANY,
					"daemon: %ld beyond descriptor table size %ld\n",
					(long) s, (long) dtblsize, 0 );
#endif

				slapd_close(s);
				ldap_pvt_thread_yield();
				continue;
			}
#endif

#ifdef LDAP_DEBUG
			ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );

			/* newly accepted stream should not be in any of the FD SETS */
			assert( !FD_ISSET( s, &slap_daemon.sd_actives) );
			assert( !FD_ISSET( s, &slap_daemon.sd_readers) );
			assert( !FD_ISSET( s, &slap_daemon.sd_writers) );

			ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
#endif

#if defined( SO_KEEPALIVE ) || defined( TCP_NODELAY )
#ifdef LDAP_PF_LOCAL
			/* for IPv4 and IPv6 sockets only */
			if ( from.sa_addr.sa_family != AF_LOCAL )
#endif /* LDAP_PF_LOCAL */
			{
				int rc;
				int tmp;
#ifdef SO_KEEPALIVE
				/* enable keep alives */
				tmp = 1;
				rc = setsockopt( s, SOL_SOCKET, SO_KEEPALIVE,
					(char *) &tmp, sizeof(tmp) );
				if ( rc == AC_SOCKET_ERROR ) {
					int err = sock_errno();
#ifdef NEW_LOGGING
					LDAP_LOG( CONNECTION, ERR, 
						"slapd_daemon_task: setsockopt( %ld, SO_KEEPALIVE)"
					   " failed errno=%d (%s)\n",
						(long)s, err, sock_errstr(err) );
#else
					Debug( LDAP_DEBUG_ANY,
						"slapd(%ld): setsockopt(SO_KEEPALIVE) failed "
						"errno=%d (%s)\n", (long) s, err, sock_errstr(err) );
#endif
				}
#endif
#ifdef TCP_NODELAY
				/* enable no delay */
				tmp = 1;
				rc = setsockopt( s, IPPROTO_TCP, TCP_NODELAY,
					(char *)&tmp, sizeof(tmp) );
				if ( rc == AC_SOCKET_ERROR ) {
					int err = sock_errno();
#ifdef NEW_LOGGING
					LDAP_LOG( CONNECTION, ERR, 
						"slapd_daemon_task: setsockopt( %ld, "
						"TCP_NODELAY) failed errno=%d (%s)\n",
						(long)s, err, sock_errstr(err) );
#else
					Debug( LDAP_DEBUG_ANY,
						"slapd(%ld): setsockopt(TCP_NODELAY) failed "
						"errno=%d (%s)\n", (long) s, err, sock_errstr(err) );
#endif
				}
#endif
			}
#endif

#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL1, 
				"slapd_daemon_task: new connection on %ld\n", (long)s, 0, 0 );
#else
			Debug( LDAP_DEBUG_CONNS, "daemon: new connection on %ld\n",
				(long) s, 0, 0 );
#endif
			switch ( from.sa_addr.sa_family ) {
#  ifdef LDAP_PF_LOCAL
			case AF_LOCAL:
				sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
				ssf = LDAP_PVT_SASL_LOCAL_SSF;
				{
					uid_t uid;
					gid_t gid;

					if( getpeereid( s, &uid, &gid ) == 0 ) {
						authid = ch_malloc(
							sizeof("uidnumber=4294967295+gidnumber=4294967295,"
								"cn=peercred,cn=external,cn=auth"));
						sprintf(authid, "uidnumber=%d+gidnumber=%d,"
							"cn=peercred,cn=external,cn=auth",
							(int) uid, (int) gid);
					}
				}
				dnsname = "local";
				break;
#endif /* LDAP_PF_LOCAL */

#  ifdef LDAP_PF_INET6
			case AF_INET6:
			if ( IN6_IS_ADDR_V4MAPPED(&from.sa_in6_addr.sin6_addr) ) {
				peeraddr = inet_ntoa( *((struct in_addr *)
							&from.sa_in6_addr.sin6_addr.s6_addr[12]) );
				sprintf( peername, "IP=%s:%d",
					 peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
					 (unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
			} else {
				char addr[INET6_ADDRSTRLEN];

				peeraddr = (char *) inet_ntop( AF_INET6,
						      &from.sa_in6_addr.sin6_addr,
						      addr, sizeof addr );
				sprintf( peername, "IP=%s %d",
					 peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
					 (unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
			}
			break;
#  endif /* LDAP_PF_INET6 */

			case AF_INET:
			peeraddr = inet_ntoa( from.sa_in_addr.sin_addr );
			sprintf( peername, "IP=%s:%d",
				peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
				(unsigned) ntohs( from.sa_in_addr.sin_port ) );
				break;

			default:
				slapd_close(s);
				continue;
			}

			if ( ( from.sa_addr.sa_family == AF_INET )
#ifdef LDAP_PF_INET6
				|| ( from.sa_addr.sa_family == AF_INET6 )
#endif
			) {
#ifdef SLAPD_RLOOKUPS
				if ( use_reverse_lookup ) {
					char *herr;
					if (ldap_pvt_get_hname( (const struct sockaddr *)&from, len, hbuf,
						sizeof(hbuf), &herr ) == 0) {
						ldap_pvt_str2lower( hbuf );
						dnsname = hbuf;
					}
				}
#else
				dnsname = NULL;
#endif /* SLAPD_RLOOKUPS */

#ifdef HAVE_TCPD
				if ( !hosts_ctl("slapd",
						dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
						peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
						SLAP_STRING_UNKNOWN ))
				{
					/* DENY ACCESS */
					Statslog( LDAP_DEBUG_STATS,
						"fd=%ld DENIED from %s (%s)\n",
						(long) s,
						dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
						peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
						0, 0 );
					slapd_close(s);
					continue;
				}
#endif /* HAVE_TCPD */
			}

			id = connection_init(s,
				slap_listeners[l],
				dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
				peername,
#ifdef HAVE_TLS
				slap_listeners[l]->sl_is_tls,
#else
				0,
#endif
				ssf,
				authid );

			if( authid ) ch_free(authid);

			if( id < 0 ) {
#ifdef NEW_LOGGING
				LDAP_LOG( CONNECTION, INFO, 
					"slapd_daemon_task: "
					"connection_init(%ld, %s, %s) "
					"failed.\n",
					(long)s, peername, 
					slap_listeners[l]->sl_name.bv_val );
#else
				Debug( LDAP_DEBUG_ANY,
					"daemon: connection_init(%ld, %s, %s) "
					"failed.\n",
					(long) s,
					peername,
					slap_listeners[l]->sl_name.bv_val );
#endif
				slapd_close(s);
				continue;
			}

			Statslog( LDAP_DEBUG_STATS,
				"conn=%ld fd=%ld ACCEPT from %s (%s)\n",
				id, (long) s,
				peername,
				slap_listeners[l]->sl_name.bv_val,
				0 );

			slapd_add( s );
			continue;
		}

#ifdef LDAP_DEBUG
#ifdef NEW_LOGGING
		LDAP_LOG( CONNECTION, DETAIL2,
			   "slapd_daemon_task: activity on ", 0, 0, 0 );
#else
		Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
#endif
#ifdef HAVE_WINSOCK
		for ( i = 0; i < readfds.fd_count; i++ ) {
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2, 
				" %d%s", readfds.fd_array[i], "r", 0, 0 );
#else
			Debug( LDAP_DEBUG_CONNS, " %d%s",
				readfds.fd_array[i], "r", 0 );
#endif
		}
		for ( i = 0; i < writefds.fd_count; i++ ) {
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2, 
				" %d%s", writefds.fd_array[i], "w" , 0 );
#else
			Debug( LDAP_DEBUG_CONNS, " %d%s",
				writefds.fd_array[i], "w", 0 );
#endif
		}

#else
		for ( i = 0; i < nfds; i++ ) {
			int	r, w;

			r = FD_ISSET( i, &readfds );
			w = FD_ISSET( i, &writefds );
			if ( r || w ) {
#ifdef NEW_LOGGING
				LDAP_LOG( CONNECTION, DETAIL2, 
					" %d%s%s", i, r ? "r" : "", w ? "w" : "" );
#else
				Debug( LDAP_DEBUG_CONNS, " %d%s%s", i,
				    r ? "r" : "", w ? "w" : "" );
#endif
			}
		}
#endif
#ifdef NEW_LOGGING
		LDAP_LOG( CONNECTION, DETAIL2, "\n", 0, 0, 0 );
#else
		Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
#endif

#endif

		/* loop through the writers */
#ifdef HAVE_WINSOCK
		for ( i = 0; i < writefds.fd_count; i++ )
#else
		for ( i = 0; i < nfds; i++ )
#endif
		{
			ber_socket_t wd;
#ifdef HAVE_WINSOCK
			wd = writefds.fd_array[i];
#else
			if( ! FD_ISSET( i, &writefds ) ) {
				continue;
			}
			wd = i;
#endif

#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2, 
				"slapd_daemon_task: write active on %d\n", wd, 0, 0 );
#else
			Debug( LDAP_DEBUG_CONNS,
				"daemon: write active on %d\n",
				wd, 0, 0 );
#endif
			/*
			 * NOTE: it is possible that the connection was closed
			 * and that the stream is now inactive.
			 * connection_write() must valid the stream is still
			 * active.
			 */

			if ( connection_write( wd ) < 0 ) {
				FD_CLR( (unsigned) wd, &readfds );
				slapd_close( wd );
			}
		}

#ifdef HAVE_WINSOCK
		for ( i = 0; i < readfds.fd_count; i++ )
#else
		for ( i = 0; i < nfds; i++ )
#endif
		{
			ber_socket_t rd;
#ifdef HAVE_WINSOCK
			rd = readfds.fd_array[i];
#else
			if( ! FD_ISSET( i, &readfds ) ) {
				continue;
			}
			rd = i;
#endif

#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2, 
				"slapd_daemon_task: read activity on %d\n", rd, 0, 0 );
#else
			Debug ( LDAP_DEBUG_CONNS,
				"daemon: read activity on %d\n", rd, 0, 0 );
#endif
			/*
			 * NOTE: it is possible that the connection was closed
			 * and that the stream is now inactive.
			 * connection_read() must valid the stream is still
			 * active.
			 */

			if ( connection_read( rd ) < 0 ) {
				slapd_close( rd );
			}
		}
		ldap_pvt_thread_yield();
	}

	if( slapd_shutdown == 1 ) {
#ifdef NEW_LOGGING
		LDAP_LOG( CONNECTION, CRIT,
		   "slapd_daemon_task: shutdown requested and initiated.\n", 0, 0, 0 );
#else
		Debug( LDAP_DEBUG_TRACE,
			"daemon: shutdown requested and initiated.\n",
			0, 0, 0 );
#endif

	} else if ( slapd_shutdown == 2 ) {
#ifdef HAVE_NT_SERVICE_MANAGER
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, CRIT,
			   "slapd_daemon_task: shutdown initiated by Service Manager.\n",
			   0, 0, 0);
#else
			Debug( LDAP_DEBUG_TRACE,
			       "daemon: shutdown initiated by Service Manager.\n",
			       0, 0, 0);
#endif
#else /* !HAVE_NT_SERVICE_MANAGER */
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, CRIT,
			   "slapd_daemon_task: abnormal condition, "
			   "shutdown initiated.\n", 0, 0, 0 );
#else
			Debug( LDAP_DEBUG_TRACE,
			       "daemon: abnormal condition, shutdown initiated.\n",
			       0, 0, 0 );
#endif
#endif /* !HAVE_NT_SERVICE_MANAGER */
	} else {
#ifdef NEW_LOGGING
		LDAP_LOG( CONNECTION, CRIT,
		   "slapd_daemon_task: no active streams, shutdown initiated.\n", 
		   0, 0, 0 );
#else
		Debug( LDAP_DEBUG_TRACE,
		       "daemon: no active streams, shutdown initiated.\n",
		       0, 0, 0 );
#endif
	}

	if( slapd_gentle_shutdown != 2 ) {
		close_listeners ( 0 );
	}

	free ( slap_listeners );
	slap_listeners = NULL;

	if( !slapd_gentle_shutdown ) {
		connections_shutdown();
	}

#ifdef NEW_LOGGING
	LDAP_LOG( CONNECTION, CRIT, 
		"slapd_daemon_task: shutdown waiting for %d threads to terminate.\n",
		ldap_pvt_thread_pool_backload(&connection_pool), 0, 0 );
#else
	Debug( LDAP_DEBUG_ANY,
	    "slapd shutdown: waiting for %d threads to terminate\n",
	    ldap_pvt_thread_pool_backload(&connection_pool), 0, 0 );
#endif
	ldap_pvt_thread_pool_destroy(&connection_pool, 1);

	return NULL;
}
Пример #22
0
void
rfbCheckFds()
{
    int nfds;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_storage addr;
    socklen_t addrlen = sizeof(addr);
    char addrStr[INET6_ADDRSTRLEN];
    char buf[6];
    const int one = 1;
    int sock;
    rfbClientPtr cl;
    static Bool inetdInitDone = FALSE;

    if (!inetdInitDone && inetdSock != -1) {
        rfbNewClientConnection(inetdSock);
        inetdInitDone = TRUE;
    }

    memcpy((char *)&fds, (char *)&allFds, sizeof(fd_set));
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    nfds = select(maxFd + 1, &fds, NULL, NULL, &tv);
    if (nfds == 0) {
        return;
    }
    if (nfds < 0) {
        rfbLogPerror("rfbCheckFds: select");
        return;
    }

    if (rfbListenSock != -1 && FD_ISSET(rfbListenSock, &fds)) {

        if ((sock = accept(rfbListenSock,
                           (struct sockaddr *)&addr, &addrlen)) < 0) {
            rfbLogPerror("rfbCheckFds: accept");
            return;
        }

        if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
            rfbLogPerror("rfbCheckFds: fcntl");
            close(sock);
            return;
        }

        if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
                       (char *)&one, sizeof(one)) < 0) {
            rfbLogPerror("rfbCheckFds: setsockopt");
            close(sock);
            return;
        }

        fprintf(stderr, "\n");

#if USE_LIBWRAP
        if (!hosts_ctl("Xvnc", STRING_UNKNOWN,
                       sockaddr_string(&addr, addrStr, INET6_ADDRSTRLEN),
                       STRING_UNKNOWN)) {
          rfbLog("Rejected connection from client %s\n",
                 sockaddr_string(&addr, addrStr, INET6_ADDRSTRLEN))
          close(sock);
          return;
        }
#endif

        rfbLog("Got connection from client %s\n",
               sockaddr_string(&addr, addrStr, INET6_ADDRSTRLEN));

        AddEnabledDevice(sock);
        FD_SET(sock, &allFds);
        maxFd = max(sock, maxFd);

        rfbNewClientConnection(sock);

        FD_CLR(rfbListenSock, &fds);
        if (--nfds == 0)
            return;
    }

    if ((udpSock != -1) && FD_ISSET(udpSock, &fds)) {

        if (recvfrom(udpSock, buf, 1, MSG_PEEK,
                     (struct sockaddr *)&addr, &addrlen) < 0) {

            rfbLogPerror("rfbCheckFds: UDP: recvfrom");
            rfbDisconnectUDPSock();

        } else {

            if (!udpSockConnected ||
                (memcmp(&addr, &udpRemoteAddr, addrlen) != 0))
            {
                /* new remote end */
                rfbLog("rfbCheckFds: UDP: got connection\n");

                memcpy(&udpRemoteAddr, &addr, addrlen);
                udpSockConnected = TRUE;

                if (connect(udpSock,
                            (struct sockaddr *)&addr, addrlen) < 0) {
                    rfbLogPerror("rfbCheckFds: UDP: connect");
                    rfbDisconnectUDPSock();
                    return;
                }

                rfbNewUDPConnection(udpSock);
            }

            rfbProcessUDPInput(udpSock);
        }

        FD_CLR(udpSock, &fds);
        if (--nfds == 0)
            return;
    }

    for (cl = rfbClientHead; cl; cl = cl->next) {
        if (FD_ISSET(cl->sock, &fds) && FD_ISSET(cl->sock, &allFds)) {
            rfbClientPtr cl2;
#if USETLS
            do {
                rfbProcessClientMessage(cl);
                /* Make sure cl hasn't been freed */
                for (cl2 = rfbClientHead; cl2; cl2 = cl2->next) {
                    if (cl2 == cl)
                        break;
                }
                if (cl2 == NULL) return;
            } while (cl->sslctx && rfbssl_pending(cl) > 0);
#else
            rfbProcessClientMessage(cl);
            for (cl2 = rfbClientHead; cl2; cl2 = cl2->next) {
                if (cl2 == cl)
                    break;
            }
            if (cl2 == NULL) return;
#endif
        }
    }
}
Пример #23
0
void server(int lpnumber)
{
	struct rlimit resourcelimit;
#ifdef	USE_GETPROTOBYNAME
	struct protoent *proto;
#endif
	int netfd = -1, fd, lp, one = 1;
	int open_sleep = 10;
	socklen_t clientlen;
	struct sockaddr_storage client;
	struct addrinfo hints, *res, *ressave;
	char pidfilename[sizeof(PIDFILE)];
	char service[10];	// 9100 (65535 max)
	FILE *f;
	const int bufsiz = 65536;

#ifndef	TESTING
	if (!log_to_stdout)
	{
		switch (fork()) {
		case -1:
			dolog(LOGOPTS, "fork: %m\n");
			exit(1);
		case 0:		/* child */
			break;
		default:		/* parent */
			exit(0);
		}
		/* Now in child process */
		resourcelimit.rlim_max = 0;
		if (getrlimit(RLIMIT_NOFILE, &resourcelimit) < 0) {
			dolog(LOGOPTS, "getrlimit: %m\n");
			exit(1);
		}
		for (fd = 0; fd < resourcelimit.rlim_max; ++fd)
			(void)close(fd);
		if (setsid() < 0) {
			dolog(LOGOPTS, "setsid: %m\n");
			exit(1);
		}
		(void)chdir("/");
		(void)umask(022);
		fd = open("/dev/null", O_RDWR);	/* stdin */
		(void)dup(fd);		/* stdout */
		(void)dup(fd);		/* stderr */
		(void)snprintf(pidfilename, sizeof(pidfilename), PIDFILE, lpnumber);
		if ((f = fopen(pidfilename, "w")) == NULL) {
			dolog(LOGOPTS, "%s: %m\n", pidfilename);
			exit(1);
		}
		(void)fprintf(f, "%d\n", getpid());
		(void)fclose(f);
	}
	if (get_lock(lpnumber) == 0)
		exit(1);
#endif
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_UNSPEC;
	hints.ai_flags = AI_PASSIVE;
	hints.ai_socktype = SOCK_STREAM;
	(void)snprintf(service, sizeof(service), "%hu", (BASEPORT + lpnumber - '0'));
	if (getaddrinfo(bindaddr, service, &hints, &res) != 0) {
		dolog(LOGOPTS, "getaddr: %m\n");
		exit(1);
	}
	ressave = res;
	while (res) {
#ifdef	USE_GETPROTOBYNAME
		if ((proto = getprotobyname("tcp6")) == NULL) {
			if ((proto = getprotobyname("tcp")) == NULL) {
				dolog(LOGOPTS, "Cannot find protocol for TCP!\n");
				exit(1);
			}
		}
		if ((netfd = socket(res->ai_family, res->ai_socktype, proto->p_proto)) < 0)
#else
		if ((netfd = socket(res->ai_family, res->ai_socktype, IPPROTO_IP)) < 0)
#endif
		{
			dolog(LOGOPTS, "socket: %m\n");
			close(netfd);
			res = res->ai_next;
			continue;
		}
		if (setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)) < 0) {
			dolog(LOGOPTS, "setsocketopt: SO_RCVBUF: %m\n");
			/* not fatal if it fails */
		}
		if (setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz)) < 0) {
			dolog(LOGOPTS, "setsocketopt: SO_SNDBUF: %m\n");
			/* not fatal if it fails */
		}
		if (setsockopt(netfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
			dolog(LOGOPTS, "setsocketopt: SO_REUSEADDR: %m\n");
			close(netfd);
			res = res->ai_next;
			continue;
		}
		if (bind(netfd, res->ai_addr, res->ai_addrlen) < 0) {
			dolog(LOGOPTS, "bind: %m\n");
			close(netfd);
			res = res->ai_next;
			continue;
		}
		if (listen(netfd, 5) < 0) {
			dolog(LOGOPTS, "listen: %m\n");
			close(netfd);
			res = res->ai_next;
			continue;
		}
		break;
	}
	freeaddrinfo(ressave);
	clientlen = sizeof(client);
	memset(&client, 0, sizeof(client));
	while ((fd = accept(netfd, (struct sockaddr *)&client, &clientlen)) >= 0) {
		char host[INET6_ADDRSTRLEN];
#ifdef	USE_LIBWRAP
		if (hosts_ctl("p910nd", STRING_UNKNOWN, get_ip_str((struct sockaddr *)&client, host, sizeof(host)), STRING_UNKNOWN) == 0) {
			dolog(LOGOPTS,
			       "Connection from %s port %hu rejected\n", get_ip_str((struct sockaddr *)&client, host, sizeof(host)), get_port((struct sockaddr *)&client));
			close(fd);
			continue;
		}
#endif
		dolog(LOG_NOTICE, "Connection from %s port %hu accepted\n", get_ip_str((struct sockaddr *)&client, host, sizeof(host)), get_port((struct sockaddr *)&client));
		/*write(fd, "Printing", 8); */

		/* Make sure lp device is open... */
		while ((lp = open_printer(lpnumber)) == -1) {
			sleep(open_sleep);
			if (open_sleep < 320) /* ~5 min interval to avoid spam in syslog */
				open_sleep *= 2;
		}
		open_sleep = 10;

		if (copy_stream(fd, lp) < 0)
			dolog(LOGOPTS, "copy_stream: %m\n");
		(void)close(fd);
		(void)close(lp);
	}
	dolog(LOGOPTS, "accept: %m\n");
	free_lock();
	exit(1);
}
Пример #24
0
void
rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
{
    int nfds;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);

    if (!rfbScreen->httpDir)
	return;

    if (rfbScreen->httpListenSock < 0)
	return;

    FD_ZERO(&fds);
    FD_SET(rfbScreen->httpListenSock, &fds);
    if (rfbScreen->httpSock >= 0) {
	FD_SET(rfbScreen->httpSock, &fds);
    }
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    nfds = select(max(rfbScreen->httpSock,rfbScreen->httpListenSock) + 1, &fds, NULL, NULL, &tv);
    if (nfds == 0) {
	return;
    }
    if (nfds < 0) {
#ifdef WIN32
		errno = WSAGetLastError();
#endif
	if (errno != EINTR)
		rfbLogPerror("httpCheckFds: select");
	return;
    }

    if ((rfbScreen->httpSock >= 0) && FD_ISSET(rfbScreen->httpSock, &fds)) {
	httpProcessInput(rfbScreen);
    }

    if (FD_ISSET(rfbScreen->httpListenSock, &fds)) {
        int flags;
	if (rfbScreen->httpSock >= 0) close(rfbScreen->httpSock);

	if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock,
			       (struct sockaddr *)&addr, &addrlen)) < 0) {
	    rfbLogPerror("httpCheckFds: accept");
	    return;
	}
#ifdef __MINGW32__
	rfbErr("O_NONBLOCK on MinGW32 NOT IMPLEMENTED");
#else
#ifdef USE_LIBWRAP
	if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
		      STRING_UNKNOWN)) {
	  rfbLog("Rejected HTTP connection from client %s\n",
		 inet_ntoa(addr.sin_addr));
#else
	flags = fcntl(rfbScreen->httpSock, F_GETFL);

	if (flags < 0 || fcntl(rfbScreen->httpSock, F_SETFL, flags | O_NONBLOCK) == -1) {
	    rfbLogPerror("httpCheckFds: fcntl");
#endif
	    close(rfbScreen->httpSock);
	    rfbScreen->httpSock = -1;
	    return;
	}

	flags=fcntl(rfbScreen->httpSock,F_GETFL);
	if(flags==-1 ||
	   fcntl(rfbScreen->httpSock,F_SETFL,flags|O_NONBLOCK)==-1) {
	  rfbLogPerror("httpCheckFds: fcntl");
	  close(rfbScreen->httpSock);
	  rfbScreen->httpSock=-1;
	  return;
	}
#endif

	/*AddEnabledDevice(httpSock);*/
    }
}


static void
httpCloseSock(rfbScreenInfoPtr rfbScreen)
{
    close(rfbScreen->httpSock);
    rfbScreen->httpSock = -1;
    buf_filled = 0;
}
Пример #25
0
/*
 * We will eventually be called from inetd or via the rc scripts directly
 * Parse arguments and act appropiately.
 */
int
main(int argc, char **argv)
{
    extern char *optarg;
    FILE *fp;
    int	c, *s, ns;
    struct pollfd *pfds;

#if PROFILE
    moncontrol(0);
#endif

    if ((progname = strrchr(*argv, '/')) != NULL) {
	progname++;
    } else
	progname = *argv;

    /* initialise global session data */
    memset(&session, 0, sizeof(session));
    session.peer = tac_strdup("unknown");


    if (argc <= 1) {
	usage();
	tac_exit(1);
    }

    while ((c = getopt(argc, argv, "B:C:d:hiPp:tGgvSsLw:u:")) != EOF)
	switch (c) {
	case 'B':		/* bind() address*/
	    bind_address = optarg;
	    break;
	case 'L':		/* lookup peer names via DNS */
	    lookup_peer = 1;
	    break;
	case 's':		/* don't respond to sendpass */
	    sendauth_only = 1;
	    break;
	case 'v':		/* print version and exit */
	    vers();
	    tac_exit(1);
	case 't':
	    console = 1;	/* log to console too */
	    break;
	case 'P':		/* Parse config file only */
	    parse_only = 1;
	    break;
	case 'G':		/* foreground */
	    opt_G = 1;
	    break;
	case 'g':		/* single threaded */
	    single = 1;
	    break;
	case 'p':		/* port */
	    port = atoi(optarg);
	    portstr = optarg;
	    break;
	case 'd':		/* debug */
	    debug |= atoi(optarg);
	    break;
	case 'C':		/* config file name */
	    session.cfgfile = tac_strdup(optarg);
	    break;
	case 'h':		/* usage */
	    usage();
	    tac_exit(0);
	case 'i':		/* inetd mode */
	    standalone = 0;
	    break;
	case 'S':		/* enable single-connection */
	    opt_S = 1;
	    break;
#ifdef MAXSESS
	case 'w':		/* wholog file */
	    wholog = tac_strdup(optarg);
	    break;
#endif
	case 'u':
	    wtmpfile = tac_strdup(optarg);
	    break;

	default:
	    fprintf(stderr, "%s: bad switch %c\n", progname, c);
	    usage();
	    tac_exit(1);
	}

    parser_init();

    /* read the configuration/etc */
    init();
#if defined(REAPCHILD) && defined(REAPSIGIGN)
    client_count_init();
#endif
    open_logfile();

    signal(SIGUSR1, handler);
    signal(SIGHUP, handler);
    signal(SIGUSR2, dump_clients_handler);
    signal(SIGTERM, die);
    signal(SIGPIPE, SIG_IGN);

    if (parse_only)
	tac_exit(0);

    if (debug)
	report(LOG_DEBUG, "tac_plus server %s starting", version);

    if (!standalone) {
	/* running under inetd */
	char host[NI_MAXHOST];
	int on;
#ifdef IPV6
	struct sockaddr_in6 name;
#else
  struct sockaddr_in name;
#endif
	socklen_t name_len;

	name_len = sizeof(name);
	session.flags |= SESS_NO_SINGLECONN;

	session.sock = 0;
#ifdef IPV6
	if (getpeername(session.sock, (struct sockaddr6 *)&name, &name_len)) {
	    report(LOG_ERR, "getpeername failure %s", strerror(errno));
#else
	if (getpeername(session.sock, (struct sockaddr *)&name, &name_len)) {
	    report(LOG_ERR, "getpeername failure %s", strerror(errno));
#endif
	} else {
	    if (lookup_peer)
		on = 0;
	    else
		on = NI_NUMERICHOST;
#ifdef IPV6
	    if (getnameinfo((struct sockaddr6 *)&name, name_len, host, 128,
			    NULL, 0, on)) {
#else
	    if (getnameinfo((struct sockaddr *)&name, name_len, host, 128,
			    NULL, 0, on)) {
#endif
		strncpy(host, "unknown", NI_MAXHOST - 1);
		host[NI_MAXHOST - 1] = '\0';
	    }
	    if (session.peer) free(session.peer);
	    session.peer = tac_strdup(host);

	    if (session.peerip) free(session.peerip);
#ifdef IPV6
	    session.peerip = tac_strdup((char *)inet_ntop(name.sin6_family,
					&name.sin6_addr, host, name_len));
#else
	    session.peerip = tac_strdup((char *)inet_ntop(name.sin_family,
					&name.sin_addr, host, name_len));
#endif
	    if (debug & DEBUG_AUTHEN_FLAG)
		report(LOG_INFO, "session.peerip is %s", session.peerip);
	}
#ifdef FIONBIO
	on = 1;
	if (ioctl(session.sock, FIONBIO, &on) < 0) {
	    report(LOG_ERR, "ioctl(FIONBIO) %s", strerror(errno));
	    tac_exit(1);
	}
#endif
	start_session();
	tac_exit(0);
 }

    if (single) {
	session.flags |= SESS_NO_SINGLECONN;
    } else {
	/*
	 * Running standalone; background ourselves and release controlling
	 * tty, unless -G option was specified to keep the parent in the
	 * foreground.
	 */
#ifdef SIGTTOU
	signal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
	signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGTSTP
	signal(SIGTSTP, SIG_IGN);
#endif
	if (!opt_S)
	    session.flags |= SESS_NO_SINGLECONN;

	if (!opt_G) {
	    if ((childpid = fork()) < 0)
		report(LOG_ERR, "Can't fork first child");
	    else if (childpid > 0)
		exit(0);		/* parent */

	    if (debug)
		report(LOG_DEBUG, "Backgrounded");

#if SETPGRP_VOID
	    if (setpgrp() == -1)
#else
	    if (setpgrp(0, getpid()) == -1)
#endif /* SETPGRP_VOID */
		report(LOG_ERR, "Can't change process group: %s",
		       strerror(errno));

	    /* XXX What does "REAPCHILD" have to do with TIOCNOTTY? */
#ifndef REAPCHILD
	    c = open("/dev/tty", O_RDWR);
	    if (c >= 0) {
		ioctl(c, TIOCNOTTY, (char *)0);
		(void) close(c);
	    }
#else /* REAPCHILD */
	    if ((childpid = fork()) < 0)
		report(LOG_ERR, "Can't fork second child");
	    else if (childpid > 0)
		exit(0);

	    if (debug & DEBUG_FORK_FLAG)
		report(LOG_DEBUG, "Forked grandchild");

#endif /* REAPCHILD */

	    /* some systems require this */
	    closelog();

	    for (c = getdtablesize(); c >= 0; c--)
		(void)close(c);

	    /*
	     * make sure we can still log to syslog now that we have closed
	     * everything
	     */
	    open_logfile();
	}
    }
#if REAPCHILD
#if REAPSIGIGN
    signal(SIGCHLD, reapchild);
#else
    signal(SIGCHLD, SIG_IGN);
#endif
#endif

    ostream = NULL;
    /* chdir("/"); */
    umask(022);
    errno = 0;

    get_socket(&s, &ns);

#ifndef SOMAXCONN
#define SOMAXCONN 5
#endif

    for (c = 0; c < ns; c++) {
	if (listen(s[c], SOMAXCONN) < 0) {
	    console = 1;
	report(LOG_ERR, "listen: %s", strerror(errno));
	tac_exit(1);
    }
    }

    if (port == TAC_PLUS_PORT) {
	if (bind_address == NULL) {
	    strncpy(pidfilebuf, TACPLUS_PIDFILE, PIDSZ);
	    if (pidfilebuf[PIDSZ - 1] != '\0')
		c = PIDSZ;
	    else
		c = PIDSZ - 1;
	} else
	    c = snprintf(pidfilebuf, PIDSZ, "%s.%s", TACPLUS_PIDFILE,
			 bind_address);
    } else {
	if (bind_address == NULL)
	    c = snprintf(pidfilebuf, PIDSZ, "%s.%d", TACPLUS_PIDFILE, port);
	else
	    c = snprintf(pidfilebuf, PIDSZ, "%s.%s.%d", TACPLUS_PIDFILE,
			 bind_address, port);
    }
    if (c >= PIDSZ) {
	pidfilebuf[PIDSZ - 1] = '\0';
	report(LOG_ERR, "pid filename truncated: %s", pidfilebuf);
	childpid = 0;
    } else {
	/* write process id to pidfile */
	if ((fp = fopen(pidfilebuf, "w")) != NULL) {
	    fprintf(fp, "%d\n", (int)getpid());
	    fclose(fp);
	    /*
	     * After forking to disassociate; make sure we know we're the
	     * mother so that we remove our pid file upon exit in die().
	     */
	    childpid = 1;
	} else {
	    report(LOG_ERR, "Cannot write pid to %s %s", pidfilebuf,
		   strerror(errno));
	    childpid = 0;
	}
    }
#ifdef TACPLUS_GROUPID
    if (setgid(TACPLUS_GROUPID))
	report(LOG_ERR, "Cannot set group id to %d %s",
	       TACPLUS_GROUPID, strerror(errno));
#endif

#ifdef TACPLUS_USERID
    if (setuid(TACPLUS_USERID))
	report(LOG_ERR, "Cannot set user id to %d %s",
	       TACPLUS_USERID, strerror(errno));
#endif

#ifdef MAXSESS
    maxsess_loginit();
#endif /* MAXSESS */

    report(LOG_DEBUG, "uid=%d euid=%d gid=%d egid=%d s=%d",
	   getuid(), geteuid(), getgid(), getegid(), s);

    pfds = malloc(sizeof(struct pollfd) * ns);
    if (pfds == NULL) {
	report(LOG_ERR, "malloc failure: %s", strerror(errno));
	tac_exit(1);
    }
    for (c = 0; c < ns; c++) {
	pfds[c].fd = s[c];
	pfds[c].events = POLLIN | POLLERR | POLLHUP | POLLNVAL;
    }

    for (;;) {
#if HAVE_PID_T
	pid_t pid;
#else
	int pid;
#endif
	char host[NI_MAXHOST];
#ifdef IPV6
	struct sockaddr_in6 from;
#else
	struct sockaddr_in from;
#endif
	socklen_t from_len;
	int newsockfd, status;
	int flags;
  int procs_for_client;

#if defined(REAPCHILD) && defined(REAPSIGIGN)
  if (reap_children)
    reapchildren();
#endif

	if (reinitialize)
	    init();

  if (dump_client_table) {
    report(LOG_ALERT, "Dumping Client Tables");
    dump_client_tables();
    dump_client_table = 0;
  }

	status = poll(pfds, ns, cfg_get_accepttimeout() * 1000);
	if (status == 0)
	    continue;
	if (status == -1)
	    if (errno == EINTR)
		continue;

	from_len = sizeof(from);
	memset((char *)&from, 0, from_len);
	for (c = 0; c < ns; c++) {
	    if (pfds[c].revents & POLLIN)
  #ifdef IPV6
		newsockfd = accept(s[c], (struct sockaddr6 *)&from, &from_len);
  #else
		newsockfd = accept(s[c], (struct sockaddr *)&from, &from_len);
  #endif
	    else if (pfds[c].revents & (POLLERR | POLLHUP | POLLNVAL)) {
		report(LOG_ERR, "exception on listen FD %d", s[c]);
		tac_exit(1);
	    }
	}

	if (newsockfd < 0) {
	    if (errno == EINTR)
		continue;

	    report(LOG_ERR, "accept: %s", strerror(errno));
	    continue;
	}

	if (lookup_peer)
	    flags = 0;
	else
	    flags = NI_NUMERICHOST;
#ifdef IPV6
	if (getnameinfo((struct sockaddr_in6 *)&from, from_len, host, 128, NULL, 0,
			flags)) {
#else
	if (getnameinfo((struct sockaddr_in *)&from, from_len, host, 128, NULL, 0,
			flags)) {
#endif
	    strncpy(host, "unknown", NI_MAXHOST - 1);
	    host[NI_MAXHOST - 1] = '\0';
	}

	if (session.peer) free(session.peer);
	session.peer = tac_strdup(host);

	if (session.peerip) free(session.peerip);
#ifdef IPV6
	session.peerip = tac_strdup((char *)inet_ntop(from.sin6_family,
          &from.sin6_addr, host, INET6_ADDRSTRLEN));
#else
	session.peerip = tac_strdup((char *)inet_ntop(from.sin_family,
          &from.sin_addr, host, INET_ADDRSTRLEN));
#endif
	if (debug & DEBUG_PACKET_FLAG)
	    report(LOG_DEBUG, "session request from %s sock=%d",
		   session.peer, newsockfd);

	if (!single) {
#if defined(REAPCHILD) && defined(REAPSIGIGN)
      /* first we check the tocal process count to see if we are at the limit */
      if (total_child_count >= cfg_get_maxprocs()) {
        report(LOG_ALERT, "refused connection from %s [%s] at global max procs [%d]",
          session.peer, session.peerip, total_child_count);
        shutdown(newsockfd, 2);
        close(newsockfd);
        continue;
      }
      /* no we check the process count per client */
      procs_for_client = get_client_count(session.peerip);
      report(LOG_ALERT, "connection [%d] from %s [%s]", procs_for_client + 1, session.peer, session.peerip);
      if (procs_for_client >= cfg_get_maxprocsperclt()) {
        report(LOG_ALERT, "refused connection from %s [%s] at client max procs [%d]",
          session.peer, session.peerip, procs_for_client);
        shutdown(newsockfd, 2);
        close(newsockfd);
        continue;
      }
#endif
	    pid = fork();
	    if (pid < 0) {
		    report(LOG_ERR, "fork error");
		    tac_exit(1);
	    }
	} else {
	    pid = 0;
	}
	if (pid == 0) {
	  /* child */
	  if (!single) {
            if (ns > 1) {
              for (c = 0; c < ns; c++) {
                close(s[c]);
              }
            }
          }
	  session.sock = newsockfd;
#ifdef LIBWRAP
	  if (! hosts_ctl(progname,session.peer,session.peerip,progname)) {
		  report(LOG_ALERT, "refused connection from %s [%s]",
		       session.peer, session.peerip);
      shutdown(session.sock, 2);
      close(session.sock);
      if (!single) {
          tac_exit(0);
      } else {
          close(session.sock);
          continue;
      }
    }
    if (debug)
      report(LOG_DEBUG, "connect from %s [%s]", session.peer, session.peerip);
#endif
#if PROFILE
	    moncontrol(1);
#endif

	    start_session();
	    shutdown(session.sock, 2);
	    close(session.sock);
	    if (!single)
		    tac_exit(0);
	} else {
	    /* parent */
#if defined(REAPCHILD) && defined(REAPSIGIGN)
      total_child_count++;
      procs_for_client = increment_client_count_for_proc(pid, session.peerip);
      snprintf(msgbuf, MSGBUFSZ, "forked %lu for %s, procs %d, procs for client %d",
            (long)pid, session.peerip, total_child_count, procs_for_client);
		    report(LOG_DEBUG, msgbuf);
#endif
	    close(newsockfd);
	}
    }
}