Esempio n. 1
0
/* wait for incoming connection requests */
void wait_for_connections(void){
	struct sockaddr_in myname;
	struct sockaddr_in *nptr;
	struct sockaddr addr;
	int rc;
	int sock, new_sd;
	unsigned int addrlen;
	char connecting_host[16];
	pid_t pid;
	int flag=1;

	/* create a socket for listening */
	sock=socket(TCPIP$C_AUXS,SOCK_STREAM,0);

	/* exit if we couldn't create the socket */
	if(sock<0){
	        syslog(LOG_ERR,"Network server socket failure (%d: %s)",errno,strerror(errno));
	        exit (STATE_CRITICAL);
		}

		/* find out who just connected... */
		addrlen=sizeof(addr);
		rc=getpeername(sock,&addr,&addrlen);

		if(rc<0){
			/* log error to syslog facility */
			syslog(LOG_ERR,"Error: Network server getpeername() failure (%d: %s)",errno,strerror(errno));

		        /* close socket prior to exiting */
			close(sock);

			return;
		        }

		nptr=(struct sockaddr_in *)&addr;

		/* log info to syslog facility */
		if(debug==TRUE)
			syslog(LOG_DEBUG,"Connection from %s port %d",inet_ntoa(nptr->sin_addr),nptr->sin_port);

		/* is this is a blessed machine? */
		//snprintf(connecting_host,sizeof(connecting_host),"%s",inet_ntoa(nptr->sin_addr));
		sprintf(connecting_host,"%s",inet_ntoa(nptr->sin_addr));
		connecting_host[sizeof(connecting_host)-1]='\x0';

		if(!is_an_allowed_host(connecting_host)){
			/* log error to syslog facility */
			syslog(LOG_ERR,"Host %s is not allowed to talk to us!",connecting_host);
			}
		else{
			/* log info to syslog facility */
			if(debug==TRUE)
				syslog(LOG_DEBUG,"Host address checks out ok");

		        /* handle the client connection */
			handle_connection(sock);
	                }

		/* log info to syslog facility */
		if(debug==TRUE)
			syslog(LOG_DEBUG,"Connection from %s closed.",connecting_host);

		/* close socket prior to exiting */
		close(sock);

	/* we shouldn't ever get here... */
	syslog(LOG_NOTICE,"Terminating");

	return;

}
Esempio n. 2
0
/* wait for incoming connection requests */
void wait_for_connections(void){
	struct sockaddr_in6 myname6;
	struct sockaddr_in6 src_sin;
	socklen_t socklen = sizeof(src_sin);
	struct sockaddr *remoteaddr = (struct sockaddr *)&src_sin;
	int rc;
	int sock, new_sd;
	pid_t pid;
	int flag=1;
	int max_fd = 0;
	int i = 0, j = 0;
	fd_set fdread;
	struct timeval timeout;
	int retval;
#ifdef HAVE_LIBWRAP
	struct request_info req;
#endif

	int rval;
	struct addrinfo addrinfo;
	struct addrinfo *res, *r;

	memset(&addrinfo, 0, sizeof(addrinfo));
	addrinfo.ai_family=AF_UNSPEC;
	addrinfo.ai_socktype=SOCK_STREAM;
	addrinfo.ai_protocol=IPPROTO_TCP;

	if(!server_address || !strlen(server_address)) {
		server_address = NULL;
		addrinfo.ai_flags=AI_PASSIVE;
		}
	if (rval = getaddrinfo(server_address, server_port, &addrinfo, &res) != 0) {
		syslog(LOG_ERR,"Invalid server_address (%d: %s)",errno,strerror(errno));
		exit(STATE_CRITICAL);
		}
	else {
		for (r=res; r; r = r->ai_next){
			if (r->ai_family != AF_INET && r->ai_family != AF_INET6)
				continue;
			if (num_listen_socks >= MAX_LISTEN_SOCKS){
				syslog(LOG_ERR,"Too many listen sockets. Enlarge MAX_LISTEN_SOCKS\n");
				exit(STATE_UNKNOWN);
				}
			sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
			if (sock < 0)
				/* kernel may not support ipv6 */
				continue;
			/* socket should be non-blocking */
			fcntl(sock,F_SETFL,O_NONBLOCK);
			/* set the reuse address flag so we don't get errors when restarting */
			flag=1;
			if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){
				syslog(LOG_ERR,"Could not set reuse address option on socket!\n");
				exit(STATE_UNKNOWN);
				}
#ifdef IPV6_V6ONLY
			/* Only communicate in IPv6 over AF_INET6 sockets. */
			flag=1;
			if (r->ai_family == AF_INET6)
				if(setsockopt(sock,IPPROTO_IPV6,IPV6_V6ONLY,(char *)&flag,sizeof(flag))<0) {
					syslog(LOG_ERR,"Could not set IPV6_V6ONLY option on socket!\n");
					exit(STATE_UNKNOWN);
					}
#endif
			if(bind(sock, r->ai_addr, r->ai_addrlen) < 0) {
				syslog(LOG_ERR,"Network server bind failure (%d: %s)\n",errno,strerror(errno));
				(void) close(sock);
				exit(STATE_CRITICAL);
				}
			listen_socks[num_listen_socks] = sock;
			num_listen_socks++;
			if (listen(sock, 5) < 0){
				syslog(LOG_ERR,"Network server listen failure (%d: %s)\n",errno,strerror(errno));
	        		exit(STATE_CRITICAL);
				}
			if(sock > max_fd)
				max_fd = sock;
			}
		freeaddrinfo(res);
		if(num_listen_socks == 0) {
			exit(STATE_CRITICAL);
			}
		}


	/* log warning about command arguments */
#ifdef ENABLE_COMMAND_ARGUMENTS
	if(allow_arguments==TRUE)
		syslog(LOG_NOTICE,"Warning: Daemon is configured to accept command arguments from clients!");
#endif

	syslog(LOG_INFO,"Listening for connections on port %s\n",server_port);

	if(allowed_hosts)
		syslog(LOG_INFO,"Allowing connections from: %s\n",allowed_hosts);

	/* listen for connection requests - fork() if we get one */
	while(1){

		/* wait for a connection request */

		/* wait until there's something to do */
		FD_ZERO(&fdread);
		for(i=0; i < num_listen_socks; i++)
			FD_SET(listen_socks[i],&fdread);

		timeout.tv_sec=0;
		timeout.tv_usec=500000;
		retval=select(max_fd+1,&fdread,NULL,NULL,&timeout);
		/* bail out if necessary */
		if(sigrestart==TRUE || sigshutdown==TRUE)
			break;

		/* error */
		if(retval<0)
			continue;

		/* accept a new connection request */
		for (i = 0; i < num_listen_socks; i++){
			if (!FD_ISSET(listen_socks[i], &fdread))
				continue;
			new_sd=accept(listen_socks[i], remoteaddr, &socklen);

			/* some kind of error occurred... */
			if(new_sd<0){
				/* bail out if necessary */
				if(sigrestart==TRUE || sigshutdown==TRUE)
					break;

				/* retry */
				if(errno==EWOULDBLOCK || errno==EINTR)
					continue;

				/* socket is nonblocking and we don't have a connection yet */
				if(errno==EAGAIN)
					continue;

				/* fix for HP-UX 11.0 - just retry */
				if(errno==ENOBUFS)
					continue;

			        }		

			/* bail out if necessary */
			if(sigrestart==TRUE || sigshutdown==TRUE)
				break;

			/* child process should handle the connection */
	    		pid=fork();
	    		if(pid==0){

				/* fork again so we don't create zombies */
				pid=fork();
				if(pid==0){
					/* hey, there was an error... */
					if(new_sd<0){

						/* log error to syslog facility */
						syslog(LOG_ERR,"Network server accept failure (%d: %s)",errno,strerror(errno));

						/* close sockets prioer to exiting */
						for(j=0; j < num_listen_socks; j++)
							close(listen_socks[j]);
			
						return;
					        }

					/* handle siOAgnals */
					signal(SIGQUIT,child_sighandler);
					signal(SIGTERM,child_sighandler);
					signal(SIGHUP,child_sighandler);

					/* grandchild does not need to listen for connections, so close the sockets */
					for(j=0; j < num_listen_socks; j++)
						close(listen_socks[j]);

					/* log info to syslog facility */
					if(debug==TRUE)
						syslog(LOG_DEBUG,"Connection from %s port %d",get_ip_str(remoteaddr, buf, BUFLEN),get_port(remoteaddr));

                                	/* is this is a blessed machine? */
					if(allowed_hosts){
						if(!is_an_allowed_host(remoteaddr)){
							/* log error to syslog facility */
							syslog(LOG_ERR,"Host %s is not allowed to talk to us!",get_ip_str(remoteaddr, buf, BUFLEN));

							/* log info to syslog facility */
							if(debug==TRUE)
								syslog(LOG_DEBUG,"Connection from %s closed.",get_ip_str(remoteaddr, buf, BUFLEN));

							/* close socket prior to exiting */
							close(new_sd);

							exit(STATE_OK);
							}
						else{

							/* log info to syslog facility */
							if(debug==TRUE)
							syslog(LOG_DEBUG,"Host address is in allowed_hosts");
							}
						}

#ifdef HAVE_LIBWRAP

					/* Check whether or not connections are allowed from this host */
					request_init(&req,RQ_DAEMON,"nrpe",RQ_FILE,new_sd,0);
					fromhost(&req);

					if(!hosts_access(&req)){

						syslog(LOG_DEBUG,"Connection refused by TCP wrapper");

						/* refuse the connection */
						refuse(&req);
						close(new_sd);

						/* should not be reached */
						syslog(LOG_ERR,"libwrap refuse() returns!");
						exit(STATE_CRITICAL);
						}
#endif

					/* handle the client connection */
					handle_connection(new_sd);

					/* log info to syslog facility */
					if(debug==TRUE)
						syslog(LOG_DEBUG,"Connection from %s closed.",get_ip_str(remoteaddr, buf, BUFLEN));

					/* close socket prior to exiting */
					close(new_sd);

					exit(STATE_OK);
    			        	}

				/* first child returns immediately, grandchild is inherited by INIT process -> no zombies... */
				else
					exit(STATE_OK);
		        	}
		
			/* parent ... */
			else{
				/* parent doesn't need the new connection */
				close(new_sd);

				/* parent waits for first child to exit */
				waitpid(pid,NULL,0);
		        	}
  			}
		}
		/* close the sockets we're listening on */
		for(j=0; j < num_listen_socks; j++)
			close(listen_socks[j]);

		return;
	}
Esempio n. 3
0
/* wait for incoming connection requests */
void wait_for_connections(void){
	struct sockaddr_in myname;
	struct sockaddr_in *nptr;
	struct sockaddr addr;
	int rc;
	int sock, new_sd;
	socklen_t addrlen;
	pid_t pid;
	int flag=1;
	fd_set fdread;
	struct timeval timeout;
	int retval;
#ifdef HAVE_LIBWRAP
	struct request_info req;
#endif

	/* create a socket for listening */
	sock=socket(AF_INET,SOCK_STREAM,0);

	/* exit if we couldn't create the socket */
	if(sock<0){
	        syslog(LOG_ERR,"Network server socket failure (%d: %s)",errno,strerror(errno));
	        exit(STATE_CRITICAL);
		}

	/* socket should be non-blocking */
	fcntl(sock,F_SETFL,O_NONBLOCK);

        /* set the reuse address flag so we don't get errors when restarting */
        flag=1;
        if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){
		syslog(LOG_ERR,"Could not set reuse address option on socket!\n");
		exit(STATE_UNKNOWN);
	        }

	myname.sin_family=AF_INET;
	myname.sin_port=htons(server_port);
 	bzero(&myname.sin_zero,8);

	/* what address should we bind to? */
        if(!strlen(server_address))
		myname.sin_addr.s_addr=INADDR_ANY;

	else if(!my_inet_aton(server_address,&myname.sin_addr)){
		syslog(LOG_ERR,"Server address is not a valid IP address\n");
		exit(STATE_CRITICAL);
                }

	/* bind the address to the Internet socket */
	if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){
		syslog(LOG_ERR,"Network server bind failure (%d: %s)\n",errno,strerror(errno));
	        exit(STATE_CRITICAL);
	        }

	/* open the socket for listening */
	if(listen(sock,5)<0){
	    	syslog(LOG_ERR,"Network server listen failure (%d: %s)\n",errno,strerror(errno));
	        exit(STATE_CRITICAL);
		}

	/* log warning about command arguments */
#ifdef ENABLE_COMMAND_ARGUMENTS
	if(allow_arguments==TRUE)
		syslog(LOG_NOTICE,"Warning: Daemon is configured to accept command arguments from clients!");
#ifdef ENABLE_BASH_COMMAND_SUBSTITUTION
	if(TRUE==allow_bash_command_substitution) {
		if(TRUE==allow_arguments)
			syslog(LOG_NOTICE,"Warning: Daemon is configured to accept command arguments with bash command substitutions!");
		else
			syslog(LOG_NOTICE,"Warning: Daemon is configured to accept command arguments with bash command substitutions, but is not configured to accept command argements from clients. Enable command arguments if you wish to allow command arguments with bash command substitutions.");
		}
#endif
#endif

	syslog(LOG_INFO,"Listening for connections on port %d\n",htons(myname.sin_port));

	if(allowed_hosts)
		syslog(LOG_INFO,"Allowing connections from: %s\n",allowed_hosts);

	/* listen for connection requests - fork() if we get one */
	while(1){

		/* wait for a connection request */
	        while(1){

			/* wait until there's something to do */
			FD_ZERO(&fdread);
			FD_SET(sock,&fdread);
			timeout.tv_sec=0;
			timeout.tv_usec=500000;
			retval=select(sock+1,&fdread,NULL,&fdread,&timeout);

			/* bail out if necessary */
			if(sigrestart==TRUE || sigshutdown==TRUE)
				break;

			/* error */
			if(retval<0)
				continue;

			/* accept a new connection request */
			new_sd=accept(sock,0,0);

			/* some kind of error occurred... */
			if(new_sd<0){

				/* bail out if necessary */
				if(sigrestart==TRUE || sigshutdown==TRUE)
					break;

				/* retry */
				if(errno==EWOULDBLOCK || errno==EINTR)
					continue;

				/* socket is nonblocking and we don't have a connection yet */
				if(errno==EAGAIN)
					continue;

				/* fix for HP-UX 11.0 - just retry */
				if(errno==ENOBUFS)
					continue;

				/* else handle the error later */
				break;
			        }

			/* connection was good */
			break;
		        }

		/* bail out if necessary */
		if(sigrestart==TRUE || sigshutdown==TRUE)
			break;

		/* child process should handle the connection */
    		pid=fork();
    		if(pid==0){

			/* fork again so we don't create zombies */
			pid=fork();
			if(pid==0){

				/* hey, there was an error... */
				if(new_sd<0){

					/* log error to syslog facility */
					syslog(LOG_ERR,"Network server accept failure (%d: %s)",errno,strerror(errno));

					/* close socket prioer to exiting */
					close(sock);
			
					return;
				        }

				/* handle signals */
				signal(SIGQUIT,child_sighandler);
				signal(SIGTERM,child_sighandler);
				signal(SIGHUP,child_sighandler);

				/* grandchild does not need to listen for connections, so close the socket */
				close(sock);  

				/* find out who just connected... */
				addrlen=sizeof(addr);
				rc=getpeername(new_sd,&addr,&addrlen);

				if(rc<0){

				        /* log error to syslog facility */
					syslog(LOG_ERR,"Error: Network server getpeername() failure (%d: %s)",errno,strerror(errno));

				        /* close socket prior to exiting */
					close(new_sd);

					return;
		                        }

				nptr=(struct sockaddr_in *)&addr;

				/* log info to syslog facility */
				if(debug==TRUE)
					syslog(LOG_DEBUG,"Connection from %s port %d",inet_ntoa(nptr->sin_addr),nptr->sin_port);

				/* is this is a blessed machine? */
				if(allowed_hosts){
                	switch(nptr->sin_family) {
                    	case AF_INET:
                        	if(!is_an_allowed_host(nptr->sin_addr)) {
                            	/* log error to syslog facility */
                            	syslog(LOG_ERR,"Host %s is not allowed to talk to us!",inet_ntoa(nptr->sin_addr));

								/* log info to syslog facility */
								if ( debug==TRUE )
                                	syslog(LOG_DEBUG,"Connection from %s closed.",inet_ntoa(nptr->sin_addr));

								/* close socket prior to exiting */
								close(new_sd);
								exit(STATE_OK);
								} else {
									/* log info to syslog facility */
									if(debug==TRUE)
										syslog(LOG_DEBUG,"Host address is in allowed_hosts");

								}
							break;
                           
						case AF_INET6:
							syslog(LOG_DEBUG,"Connection from %s closed. We don't support AF_INET6 addreess family in ACL\n", inet_ntoa(nptr->sin_addr));
							break;
					}
				}

#ifdef HAVE_LIBWRAP

				/* Check whether or not connections are allowed from this host */
				request_init(&req,RQ_DAEMON,"nrpe",RQ_FILE,new_sd,0);
				fromhost(&req);

				if(!hosts_access(&req)){

					syslog(LOG_DEBUG,"Connection refused by TCP wrapper");

					/* refuse the connection */
					refuse(&req);
					close(new_sd);

					/* should not be reached */
					syslog(LOG_ERR,"libwrap refuse() returns!");
					exit(STATE_CRITICAL);
					}
#endif

				/* handle the client connection */
				handle_connection(new_sd);

				/* log info to syslog facility */
				if(debug==TRUE)
					syslog(LOG_DEBUG,"Connection from %s closed.",inet_ntoa(nptr->sin_addr));

				/* close socket prior to exiting */
				close(new_sd);

				exit(STATE_OK);
    			        }

			/* first child returns immediately, grandchild is inherited by INIT process -> no zombies... */
			else
				exit(STATE_OK);
		        }
		
		/* parent ... */
		else{
			/* parent doesn't need the new connection */
			close(new_sd);

			/* parent waits for first child to exit */
			waitpid(pid,NULL,0);
		        }
  		}

	/* close the socket we're listening on */
	close(sock);

	return;
	}