Пример #1
0
static void listener(void)
{
    int sock;

    sock = open_socket_in(SOCK_STREAM, TCP_PORT);

    if (listen(sock, 20) == -1) {
        fprintf(stderr,"listen failed\n");
        exit(1);
    }

    printf("waiting for connections\n");

    signal(SIGCHLD, SIG_IGN);

    while (1) {
        struct sockaddr addr;
        socklen_t in_addrlen = sizeof(addr);
        int fd;

        while (waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0) ;

        fd = accept(sock, &addr, &in_addrlen);

        if (fd != -1) {
            if (fork() == 0) server(fd);
            close(fd);
        }
    }
}
Пример #2
0
int main(int argc, char *argv[])
{
	int listen_port;
	char *host1, *host2;
	int sock_in;

	if (argc < 4) {
		printf("Usage: udpproxy <port> <host1> <host2>\n");
		exit(1);
	}

	listen_port = atoi(argv[1]);
	host1 = argv[2];
	host2 = argv[3];

	sock_in = open_socket_in(listen_port);
	if (sock_in == -1) {
		fprintf(stderr,"sock on port %d failed - %s\n", 
			listen_port, strerror(errno));
		exit(1);
	}

	main_loop(sock_in, host1, host2);

	return 0;
}
Пример #3
0
static bool open_sockets(void)
{
	struct sockaddr_storage ss;
	const char *sock_addr = lp_nbt_client_socket_address();

	if (!interpret_string_addr(&ss, sock_addr,
				AI_NUMERICHOST|AI_PASSIVE)) {
		DEBUG(0,("open_sockets: unable to get socket address "
					"from string %s", sock_addr));
		return false;
	}
	ServerFD = open_socket_in( SOCK_DGRAM,
				(RootPort ? 137 : 0),
				(RootPort ?   0 : 3),
				&ss, true );

	if (ServerFD == -1) {
		return false;
	}

	set_socket_options( ServerFD, "SO_BROADCAST" );

	DEBUG(3, ("Socket opened.\n"));
	return true;
}
Пример #4
0
void start_accept_loop(int port, int (*fn)(int ))
{
	int s;

	/* open an incoming socket */
	s = open_socket_in(SOCK_STREAM, port);
	if (s == -1)
		exit_cleanup(RERR_SOCKETIO);

	/* ready to listen */
	if (listen(s, 5) == -1) {
		close(s);
		exit_cleanup(RERR_SOCKETIO);
	}


	/* now accept incoming connections - forking a new process
	   for each incoming connection */
	while (1) {
		fd_set fds;
		int fd;
		struct sockaddr addr;
		int in_addrlen = sizeof(addr);

		FD_ZERO(&fds);
		FD_SET(s, &fds);

		if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
			continue;
		}

		if(!FD_ISSET(s, &fds)) continue;

		fd = accept(s,&addr,&in_addrlen);

		if (fd == -1) continue;

		signal(SIGCHLD, SIG_IGN);

		/* we shouldn't have any children left hanging around
		   but I have had reports that on Digital Unix zombies
		   are produced, so this ensures that they are reaped */
#ifdef WNOHANG
		waitpid(-1, NULL, WNOHANG);
#endif

		if (fork()==0) {
			close(s);

			set_nonblocking(fd);

			_exit(fn(fd));
		}

		close(fd);
	}
}
Пример #5
0
int main(int argc, char *argv[])
{
	int listen_port, dest_port;
	char *host;
	int sock_in;
	int sock_out;
	int listen_fd;
	struct sockaddr addr;
	int in_addrlen = sizeof(addr);

	if (argc < 4) {
		printf("Usage: sockspy <inport> <host> <port>\n");
		exit(1);
	}

	listen_port = atoi(argv[1]);
	host = argv[2];
	dest_port = atoi(argv[3]);

	listen_fd = open_socket_in(listen_port);

	if (listen_fd == -1) {
		fprintf(stderr,"listen on port %d failed - %s\n", 
			listen_port, strerror(errno));
		exit(1);
	}

	if (listen(listen_fd, 100) == -1) {
		fprintf(stderr,"listen failed\n");
		exit(1);
	}

	while (1) {
		sock_in = accept(listen_fd,&addr,&in_addrlen);
		if (sock_in == -1) {
			fprintf(stderr,"accept on port %d failed - %s\n", 
				listen_port, strerror(errno));
			exit(1);
		}

		if (fork() == 0) {
			close(listen_fd);

			sock_out = open_socket_out(host, dest_port);
			if (sock_out == -1) {
				exit(1);
			}

			main_loop(sock_in, sock_out);
			_exit(0);
		}

		close(sock_in);
	}

	return 0;
}
Пример #6
0
static BOOL open_sockets(BOOL isdaemon, int port)
{
	/*
	 * The sockets opened here will be used to receive broadcast
	 * packets *only*. Interface specific sockets are opened in
	 * make_subnet() in namedbsubnet.c. Thus we bind to the
	 * address "0.0.0.0". The parameter 'socket address' is
	 * now deprecated.
	 */

	if ( isdaemon )
		ClientNMB = open_socket_in(SOCK_DGRAM, port,
					   0, interpret_addr(lp_socket_address()),
					   True);
	else
		ClientNMB = 0;
  
	ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
					   3, interpret_addr(lp_socket_address()),
					   True);

	if ( ClientNMB == -1 )
		return( False );

#ifndef _XBOX
	/* we are never interested in SIGPIPE */
	BlockSignals(True,SIGPIPE);
#endif

	set_socket_options( ClientNMB,   "SO_BROADCAST" );
	set_socket_options( ClientDGRAM, "SO_BROADCAST" );

	/* Ensure we're non-blocking. */
	set_blocking( ClientNMB, False);
	set_blocking( ClientDGRAM, False);

	DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
	return( True );
}
Пример #7
0
static struct subnet_record *make_subnet(char *name, enum subnet_type type,
                                         struct in_addr myip, struct in_addr bcast_ip, 
                                         struct in_addr mask_ip)
{
  struct subnet_record *subrec = NULL;
  int nmb_sock, dgram_sock;

  /* Check if we are creating a non broadcast subnet - if so don't create
     sockets.
   */

  if(type != NORMAL_SUBNET)
  {
    nmb_sock = -1;
    dgram_sock = -1;
  }
  else
  {
    /*
     * Attempt to open the sockets on port 137/138 for this interface
     * and bind them.
     * Fail the subnet creation if this fails.
     */

    if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr)) == -1)
    {
      DEBUG(0,("make_subnet: Failed to open nmb socket on interface %s \
for port %d. Error was %s\n", inet_ntoa(myip), global_nmb_port, strerror(errno)));
      return NULL;
    }

    if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr)) == -1)
    {
      DEBUG(0,("make_subnet: Failed to open dgram socket on interface %s \
for port %d. Error was %s\n", inet_ntoa(myip), DGRAM_PORT, strerror(errno)));
      return NULL;
    }
Пример #8
0
/****************************************************************************
  open the socket communication
  **************************************************************************/
static BOOL open_sockets(void)
{
  ServerFD = open_socket_in( SOCK_DGRAM,
                             (RootPort ? 137 : 0),
                             (RootPort ?   0 : 3),
                             interpret_addr(lp_socket_address()), True );

  if (ServerFD == -1)
    return(False);

  set_socket_options( ServerFD, "SO_BROADCAST" );

  DEBUG(3, ("Socket opened.\n"));
  return True;
}
Пример #9
0
/********************************************************
resolve via "wins" method
*********************************************************/
static BOOL
resolve_wins (const char *name, struct in_addr *return_ip, int name_type)
{
    int sock;
    struct in_addr wins_ip;
    BOOL wins_ismyip;

    /*
     * "wins" means do a unicast lookup to the WINS server.
     * Ignore if there is no WINS server specified or if the
     * WINS server is one of our interfaces (if we're being
     * called from within nmbd - we can't do this call as we
     * would then block).
     */

    DEBUG (3, ("resolve_name: Attempting wins lookup for name %s<0x%x>\n", name, name_type));

    if (!*lp_wins_server ())
    {
        DEBUG (3, ("resolve_name: WINS server resolution selected and no WINS server present.\n"));
        return False;
    }

    wins_ip = *interpret_addr2 (lp_wins_server ());
    wins_ismyip = ismyip (wins_ip);

    if ((wins_ismyip && !global_in_nmbd) || !wins_ismyip)
    {
        sock = open_socket_in (SOCK_DGRAM, 0, 3, interpret_addr (lp_socket_address ()), True);

        if (sock != -1)
        {
            struct in_addr *iplist = NULL;
            int count;
            iplist = name_query (sock, name, name_type, False, True, wins_ip, &count, NULL);
            if (iplist != NULL)
            {
                *return_ip = iplist[0];
                free ((char *) iplist);
                close (sock);
                return True;
            }
            close (sock);
        }
    }

    return False;
}
Пример #10
0
static void start_filter(char *desthost)
{
	int s, c;
	struct in_addr dest_ip;

	CatchChild();

	/* start listening on port 445 locally */
	s = open_socket_in(SOCK_STREAM, 445, 0, 0, True);
	
	if (s == -1) {
		d_printf("bind failed\n");
		exit(1);
	}

	if (listen(s, 5) == -1) {
		d_printf("listen failed\n");
	}

	if (!resolve_name(desthost, &dest_ip, 0x20)) {
		d_printf("Unable to resolve host %s\n", desthost);
		exit(1);
	}

	while (1) {
		fd_set fds;
		int num;
		struct sockaddr addr;
		socklen_t in_addrlen = sizeof(addr);
		
		FD_ZERO(&fds);
		FD_SET(s, &fds);

		num = sys_select_intr(s+1,&fds,NULL,NULL,NULL);
		if (num > 0) {
			c = accept(s, &addr, &in_addrlen);
			if (c != -1) {
				if (fork() == 0) {
					close(s);
					filter_child(c, dest_ip);
					exit(0);
				} else {
					close(c);
				}
			}
		}
	}
}
static void start_filter(char *desthost)
{
	int s, c;
	struct sockaddr_storage dest_ss;
	struct sockaddr_storage my_ss;

	CatchChild();

	/* start listening on port 445 locally */

	zero_sockaddr(&my_ss);
	s = open_socket_in(SOCK_STREAM, TCP_SMB_PORT, 0, &my_ss, True);

	if (s == -1) {
		d_printf("bind failed\n");
		exit(1);
	}

	if (listen(s, 5) == -1) {
		d_printf("listen failed\n");
	}

	if (!resolve_name(desthost, &dest_ss, 0x20, false)) {
		d_printf("Unable to resolve host %s\n", desthost);
		exit(1);
	}

	while (1) {
		int num, revents;
		struct sockaddr_storage ss;
		socklen_t in_addrlen = sizeof(ss);

		num = poll_intr_one_fd(s, POLLIN|POLLHUP, -1, &revents);
		if ((num > 0) && (revents & (POLLIN|POLLHUP|POLLERR))) {
			c = accept(s, (struct sockaddr *)&ss, &in_addrlen);
			if (c != -1) {
				if (fork() == 0) {
					close(s);
					filter_child(c, &dest_ss);
					exit(0);
				} else {
					close(c);
				}
			}
		}
	}
}
Пример #12
0
/* check to see if nmbd is running on localhost by looking for a __SAMBA__
   response */
BOOL nmbd_running(void)
{
	int fd, count, flags;
	struct in_addr *ip_list;

	if ((fd = open_socket_in(SOCK_DGRAM, 0, 3,
				 interpret_addr("127.0.0.1"), True)) != -1) {
		if ((ip_list = name_query(fd, "__SAMBA__", 0, 
					  True, True, loopback_ip,
					  &count, &flags, NULL)) != NULL) {
			SAFE_FREE(ip_list);
			close(fd);
			return True;
		}
		close (fd);
	}

	return False;
}
Пример #13
0
/********************************************************
resolve via "bcast" method
*********************************************************/
static BOOL
resolve_bcast (const char *name, struct in_addr *return_ip, int name_type)
{
    int sock, i;

    /*
     * "bcast" means do a broadcast lookup on all the local interfaces.
     */

    DEBUG (3, ("resolve_name: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));

    sock = open_socket_in (SOCK_DGRAM, 0, 3, interpret_addr (lp_socket_address ()), True);

    if (sock != -1)
    {
        struct in_addr *iplist = NULL;
        int count;
        int num_interfaces = iface_count ();
        static char so_broadcast[] = "SO_BROADCAST";
        set_socket_options (sock, so_broadcast);
        /*
         * Lookup the name on all the interfaces, return on
         * the first successful match.
         */
        for (i = 0; i < num_interfaces; i++)
        {
            struct in_addr sendto_ip;
            /* Done this way to fix compiler error on IRIX 5.x */
            sendto_ip = *iface_bcast (*iface_n_ip (i));
            iplist = name_query (sock, name, name_type, True, True, sendto_ip, &count, NULL);
            if (iplist != NULL)
            {
                *return_ip = iplist[0];
                free ((char *) iplist);
                close (sock);
                return True;
            }
        }
        close (sock);
    }

    return False;
}
Пример #14
0
static struct subnet_record *make_subnet(const char *name, enum subnet_type type,
					 struct in_addr myip, struct in_addr bcast_ip, 
					 struct in_addr mask_ip)
{
	struct subnet_record *subrec = NULL;
	int nmb_sock, dgram_sock;

	/* Check if we are creating a non broadcast subnet - if so don't create
		sockets.  */

	if(type != NORMAL_SUBNET) {
		nmb_sock = -1;
		dgram_sock = -1;
	} else {
		/*
		 * Attempt to open the sockets on port 137/138 for this interface
		 * and bind them.
		 * Fail the subnet creation if this fails.
		 */

		if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,True)) == -1) {
			if( DEBUGLVL( 0 ) ) {
				Debug1( "nmbd_subnetdb:make_subnet()\n" );
				Debug1( "  Failed to open nmb socket on interface %s ", inet_ntoa(myip) );
				Debug1( "for port %d.  ", global_nmb_port );
				Debug1( "Error was %s\n", strerror(errno) );
			}
			return NULL;
		}

		if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr,True)) == -1) {
			if( DEBUGLVL( 0 ) ) {
				Debug1( "nmbd_subnetdb:make_subnet()\n" );
				Debug1( "  Failed to open dgram socket on interface %s ", inet_ntoa(myip) );
				Debug1( "for port %d.  ", DGRAM_PORT );
				Debug1( "Error was %s\n", strerror(errno) );
			}
			return NULL;
		}

		/* Make sure we can broadcast from these sockets. */
		set_socket_options(nmb_sock,"SO_BROADCAST");
		set_socket_options(dgram_sock,"SO_BROADCAST");

		/* Set them non-blocking. */
		set_blocking(nmb_sock, False);
		set_blocking(dgram_sock, False);
	}

	subrec = SMB_MALLOC_P(struct subnet_record);
	if (!subrec) {
		DEBUG(0,("make_subnet: malloc fail !\n"));
		close(nmb_sock);
		close(dgram_sock);
		return(NULL);
	}
  
	ZERO_STRUCTP(subrec);

	if((subrec->subnet_name = SMB_STRDUP(name)) == NULL) {
		DEBUG(0,("make_subnet: malloc fail for subnet name !\n"));
		close(nmb_sock);
		close(dgram_sock);
		ZERO_STRUCTP(subrec);
		SAFE_FREE(subrec);
		return(NULL);
	}

	DEBUG(2, ("making subnet name:%s ", name ));
	DEBUG(2, ("Broadcast address:%s ", inet_ntoa(bcast_ip)));
	DEBUG(2, ("Subnet mask:%s\n", inet_ntoa(mask_ip)));
 
	subrec->namelist_changed = False;
	subrec->work_changed = False;
 
	subrec->bcast_ip = bcast_ip;
	subrec->mask_ip  = mask_ip;
	subrec->myip = myip;
	subrec->type = type;
	subrec->nmb_sock = nmb_sock;
	subrec->dgram_sock = dgram_sock;
  
	return subrec;
}
Пример #15
0
int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind)
{
#ifndef EMBED
  struct hostent *hp;
  pstring host_name;
#endif
  struct sockaddr_in sock;
  int res;

#ifndef EMBED
  /* get my host name */
  if (gethostname(host_name, MAXHOSTNAMELEN) == -1) 
    { DEBUG(0,("gethostname failed\n")); return -1; } 

  /* get host info */
  if ((hp = Get_Hostbyname(host_name)) == 0) 
    {
      DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
      return -1;
    }
#endif
  
  memset((char *)&sock,'\0',sizeof(sock));
#ifdef EMBED
  sock.sin_addr.s_addr = htonl(INADDR_ANY);
#else
  memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
#endif

#ifdef HAVE_SOCK_SIN_LEN
  sock.sin_len = sizeof(sock);
#endif
  sock.sin_port = htons( port );
#ifdef EMBED
  sock.sin_family = AF_INET;
#else
  sock.sin_family = hp->h_addrtype;
#endif
  sock.sin_addr.s_addr = socket_addr;
#ifdef EMBED
  res = socket(AF_INET, type, 0);
#else
  res = socket(hp->h_addrtype, type, 0);
#endif
  if (res == -1) 
    { DEBUG(0,("socket failed\n")); return -1; }

  {
    int val=1;
	if(rebind)
		val=1;
	else
		val=0;
    if(setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1)
		DEBUG(dlevel,("setsockopt: SO_REUSEADDR=%d on port %d failed with error = %s\n",
			val, port, strerror(errno) ));
#ifdef SO_REUSEPORT
    if(setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1)
		DEBUG(dlevel,("setsockopt: SO_REUSEPORT=%d on port %d failed with error = %s\n",
			val, port, strerror(errno) ));
#endif /* SO_REUSEPORT */
  }

  /* now we've got a socket - we need to bind it */
  if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
    { 
      if (port) {
	if (port == SMB_PORT || port == NMB_PORT)
	  DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
			port,inet_ntoa(sock.sin_addr),strerror(errno))); 
	close(res); 

	if (dlevel > 0 && port < 1000)
	  port = 7999;

	if (port >= 1000 && port < 9000)
	  return(open_socket_in(type,port+1,dlevel,socket_addr,rebind));
      }

      return(-1); 
    }
  DEBUG(3,("bind succeeded on port %d\n",port));

  return res;
}
Пример #16
0
static bool smbd_open_one_socket(struct smbd_parent_context *parent,
				 struct tevent_context *ev_ctx,
				 struct messaging_context *msg_ctx,
				 const struct sockaddr_storage *ifss,
				 uint16_t port)
{
	struct smbd_open_socket *s;

	s = talloc(parent, struct smbd_open_socket);
	if (!s) {
		return false;
	}

	s->parent = parent;
	s->fd = open_socket_in(SOCK_STREAM,
			       port,
			       parent->sockets == NULL ? 0 : 2,
			       ifss,
			       true);
	if (s->fd == -1) {
		DEBUG(0,("smbd_open_once_socket: open_socket_in: "
			"%s\n", strerror(errno)));
		TALLOC_FREE(s);
		/*
		 * We ignore an error here, as we've done before
		 */
		return true;
	}

	/* ready to listen */
	set_socket_options(s->fd, "SO_KEEPALIVE");
	set_socket_options(s->fd, lp_socket_options());

	/* Set server socket to
	 * non-blocking for the accept. */
	set_blocking(s->fd, False);

	if (listen(s->fd, SMBD_LISTEN_BACKLOG) == -1) {
		DEBUG(0,("open_sockets_smbd: listen: "
			"%s\n", strerror(errno)));
			close(s->fd);
		TALLOC_FREE(s);
		return false;
	}

	s->msg_ctx = msg_ctx;
	s->fde = tevent_add_fd(ev_ctx,
			       s,
			       s->fd, TEVENT_FD_READ,
			       smbd_accept_connection,
			       s);
	if (!s->fde) {
		DEBUG(0,("open_sockets_smbd: "
			 "tevent_add_fd: %s\n",
			 strerror(errno)));
		close(s->fd);
		TALLOC_FREE(s);
		return false;
	}
	tevent_fd_set_close_fn(s->fde, smbd_open_socket_close_fn);

	DLIST_ADD_END(parent->sockets, s, struct smbd_open_socket *);

	return true;
}
Пример #17
0
static struct subnet_record *make_subnet(const char *name, enum subnet_type type,
					 struct in_addr myip, struct in_addr bcast_ip, 
					 struct in_addr mask_ip)
{
	struct subnet_record *subrec = NULL;
	int nmb_sock = -1;
	int dgram_sock = -1;
	int nmb_bcast = -1;
	int dgram_bcast = -1;
	bool bind_bcast = lp_nmbd_bind_explicit_broadcast();

	/* Check if we are creating a non broadcast subnet - if so don't create
		sockets.  */

	if (type == NORMAL_SUBNET) {
		struct sockaddr_storage ss;
		struct sockaddr_storage ss_bcast;

		in_addr_to_sockaddr_storage(&ss, myip);
		in_addr_to_sockaddr_storage(&ss_bcast, bcast_ip);

		/*
		 * Attempt to open the sockets on port 137/138 for this interface
		 * and bind them.
		 * Fail the subnet creation if this fails.
		 */

		nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,
					  0, &ss, true);
		if (nmb_sock == -1) {
			DEBUG(0,   ("nmbd_subnetdb:make_subnet()\n"));
			DEBUGADD(0,("  Failed to open nmb socket on interface %s ",
				    inet_ntoa(myip)));
			DEBUGADD(0,("for port %d.  ", global_nmb_port));
			DEBUGADD(0,("Error was %s\n", strerror(errno)));
			goto failed;
		}
		set_socket_options(nmb_sock,"SO_BROADCAST");
		set_blocking(nmb_sock, false);

		if (bind_bcast) {
			nmb_bcast = open_socket_in(SOCK_DGRAM, global_nmb_port,
						   0, &ss_bcast, true);
			if (nmb_bcast == -1) {
				DEBUG(0,   ("nmbd_subnetdb:make_subnet()\n"));
				DEBUGADD(0,("  Failed to open nmb bcast socket on interface %s ",
					    inet_ntoa(bcast_ip)));
				DEBUGADD(0,("for port %d.  ", global_nmb_port));
				DEBUGADD(0,("Error was %s\n", strerror(errno)));
				goto failed;
			}
			set_socket_options(nmb_bcast, "SO_BROADCAST");
			set_blocking(nmb_bcast, false);
		}

		dgram_sock = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
					    3, &ss, true);
		if (dgram_sock == -1) {
			DEBUG(0,   ("nmbd_subnetdb:make_subnet()\n"));
			DEBUGADD(0,("  Failed to open dgram socket on interface %s ",
				    inet_ntoa(myip)));
			DEBUGADD(0,("for port %d.  ", DGRAM_PORT));
			DEBUGADD(0,("Error was %s\n", strerror(errno)));
			goto failed;
		}
		set_socket_options(dgram_sock, "SO_BROADCAST");
		set_blocking(dgram_sock, false);

		if (bind_bcast) {
			dgram_bcast = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
						     3, &ss_bcast, true);
			if (dgram_bcast == -1) {
				DEBUG(0,   ("nmbd_subnetdb:make_subnet()\n"));
				DEBUGADD(0,("  Failed to open dgram bcast socket on interface %s ",
					    inet_ntoa(bcast_ip)));
				DEBUGADD(0,("for port %d.  ", DGRAM_PORT));
				DEBUGADD(0,("Error was %s\n", strerror(errno)));
				goto failed;
			}
			set_socket_options(dgram_bcast, "SO_BROADCAST");
			set_blocking(dgram_bcast, false);
		}
	}

	subrec = SMB_MALLOC_P(struct subnet_record);
	if (!subrec) {
		DEBUG(0,("make_subnet: malloc fail !\n"));
		goto failed;
	}
  
	ZERO_STRUCTP(subrec);

	if((subrec->subnet_name = SMB_STRDUP(name)) == NULL) {
		DEBUG(0,("make_subnet: malloc fail for subnet name !\n"));
		goto failed;
	}

	DEBUG(2, ("making subnet name:%s ", name ));
	DEBUG(2, ("Broadcast address:%s ", inet_ntoa(bcast_ip)));
	DEBUG(2, ("Subnet mask:%s\n", inet_ntoa(mask_ip)));
 
	subrec->namelist_changed = False;
	subrec->work_changed = False;
 
	subrec->bcast_ip = bcast_ip;
	subrec->mask_ip  = mask_ip;
	subrec->myip = myip;
	subrec->type = type;
	subrec->nmb_sock = nmb_sock;
	subrec->nmb_bcast = nmb_bcast;
	subrec->dgram_sock = dgram_sock;
	subrec->dgram_bcast = dgram_bcast;

	return subrec;

failed:
	SAFE_FREE(subrec);
	if (nmb_sock != -1) {
		close(nmb_sock);
	}
	if (nmb_bcast != -1) {
		close(nmb_bcast);
	}
	if (dgram_sock != -1) {
		close(dgram_sock);
	}
	if (dgram_bcast != -1) {
		close(dgram_bcast);
	}
	return NULL;
}
Пример #18
0
static bool open_sockets(bool isdaemon, int port)
{
	struct sockaddr_storage ss;
	const char *sock_addr = lp_socket_address();

	/*
	 * The sockets opened here will be used to receive broadcast
	 * packets *only*. Interface specific sockets are opened in
	 * make_subnet() in namedbsubnet.c. Thus we bind to the
	 * address "0.0.0.0". The parameter 'socket address' is
	 * now deprecated.
	 */

	if (!interpret_string_addr(&ss, sock_addr,
				AI_NUMERICHOST|AI_PASSIVE)) {
		DEBUG(0,("open_sockets: unable to get socket address "
			"from string %s", sock_addr));
		return false;
	}
	if (ss.ss_family != AF_INET) {
		DEBUG(0,("open_sockets: unable to use IPv6 socket"
			"%s in nmbd\n",
			sock_addr));
		return false;
	}

	if (isdaemon) {
		ClientNMB = open_socket_in(SOCK_DGRAM, port,
					   0, &ss,
					   true);
	} else {
		ClientNMB = 0;
	}

	if (ClientNMB == -1) {
		return false;
	}

	ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
					   3, &ss,
					   true);

	if (ClientDGRAM == -1) {
		if (ClientNMB != 0) {
			close(ClientNMB);
		}
		return false;
	}

	/* we are never interested in SIGPIPE */
	BlockSignals(True,SIGPIPE);

	set_socket_options( ClientNMB,   "SO_BROADCAST" );
	set_socket_options( ClientDGRAM, "SO_BROADCAST" );

	/* Ensure we're non-blocking. */
	set_blocking( ClientNMB, False);
	set_blocking( ClientDGRAM, False);

	DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
	return( True );
}
Пример #19
0
static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ports)
{
	int num_interfaces = iface_count();
	int num_sockets = 0;
	int fd_listenset[FD_SETSIZE];
	fd_set listen_set;
	int s;
	int maxfd = 0;
	int i;
	char *ports;

	if (!is_daemon) {
		return open_sockets_inetd();
	}

		
#ifdef HAVE_ATEXIT
	{
		static int atexit_set;
		if(atexit_set == 0) {
			atexit_set=1;
			atexit(killkids);
		}
	}
#endif

#ifndef _XBOX
	/* Stop zombies */
	CatchChild();
#endif

	FD_ZERO(&listen_set);

	/* use a reasonable default set of ports - listing on 445 and 139 */
	if (!smb_ports) {
		ports = lp_smb_ports();
		if (!ports || !*ports) {
			ports = smb_xstrdup(SMB_PORTS);
		} else {
			ports = smb_xstrdup(ports);
		}
	} else {
		ports = smb_xstrdup(smb_ports);
	}

	if (lp_interfaces() && lp_bind_interfaces_only()) {
		/* We have been given an interfaces line, and been 
		   told to only bind to those interfaces. Create a
		   socket per interface and bind to only these.
		*/
		
		/* Now open a listen socket for each of the
		   interfaces. */
		for(i = 0; i < num_interfaces; i++) {
			struct in_addr *ifip = iface_n_ip(i);
			fstring tok;
			const char *ptr;

			if(ifip == NULL) {
				DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
				continue;
			}

			for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
				unsigned port = atoi(tok);
				if (port == 0) {
					continue;
				}
				s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
				if(s == -1)
					return False;

				/* ready to listen */
				set_socket_options(s,"SO_KEEPALIVE"); 
				set_socket_options(s,user_socket_options);
     
				/* Set server socket to non-blocking for the accept. */
				set_blocking(s,False); 
 
				if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
					DEBUG(0,("listen: %s\n",strerror(errno)));
					close(s);
					return False;
				}
				FD_SET(s,&listen_set);
				maxfd = MAX( maxfd, s);

				num_sockets++;
				if (num_sockets >= FD_SETSIZE) {
					DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
					return False;
				}
			}
		}
	} else {
		/* Just bind to 0.0.0.0 - accept connections
		   from anywhere. */

		fstring tok;
		const char *ptr;

		num_interfaces = 1;
		
		for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
			unsigned port = atoi(tok);
			if (port == 0) continue;
			/* open an incoming socket */
			s = open_socket_in(SOCK_STREAM, port, 0,
					   interpret_addr(lp_socket_address()),True);
			if (s == -1)
				return(False);
		
			/* ready to listen */
#ifndef _XBOX
			set_socket_options(s,"SO_KEEPALIVE"); 
#endif
			set_socket_options(s,user_socket_options);
			
			/* Set server socket to non-blocking for the accept. */
			set_blocking(s,False); 
 
			if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
				DEBUG(0,("open_sockets_smbd: listen: %s\n",
					 strerror(errno)));
				close(s);
				return False;
			}

			fd_listenset[num_sockets] = s;
			FD_SET(s,&listen_set);
			maxfd = MAX( maxfd, s);

			num_sockets++;

			if (num_sockets >= FD_SETSIZE) {
				DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
				return False;
			}
		}
	} 

	SAFE_FREE(ports);

        /* Listen to messages */

        message_register(MSG_SMB_SAM_SYNC, msg_sam_sync);
        message_register(MSG_SMB_SAM_REPL, msg_sam_repl);
        message_register(MSG_SHUTDOWN, msg_exit_server);
        message_register(MSG_SMB_FILE_RENAME, msg_file_was_renamed);
	message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated); 

#ifdef DEVELOPER
	message_register(MSG_SMB_INJECT_FAULT, msg_inject_fault); 
#endif

	/* now accept incoming connections - forking a new process
	   for each incoming connection */
	DEBUG(2,("waiting for a connection\n"));
	while (1) {
		fd_set lfds;
		int num;
		
		/* Free up temporary memory from the main smbd. */
		lp_TALLOC_FREE();

		/* Ensure we respond to PING and DEBUG messages from the main smbd. */
		message_dispatch();

		memcpy((char *)&lfds, (char *)&listen_set, 
		       sizeof(listen_set));
		
		num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL);
		
		if (num == -1 && errno == EINTR) {
			if (got_sig_term) {
				exit_server_cleanly(NULL);
			}

			/* check for sighup processing */
			if (reload_after_sighup) {
				change_to_root_user();
				DEBUG(1,("Reloading services after SIGHUP\n"));
				reload_services(False);
				reload_after_sighup = 0;
			}

			continue;
		}
		
		/* check if we need to reload services */
		check_reload(time(NULL));

		/* Find the sockets that are read-ready -
		   accept on these. */
		for( ; num > 0; num--) {
			struct sockaddr addr;
			socklen_t in_addrlen = sizeof(addr);

			s = -1;
			for(i = 0; i < num_sockets; i++) {
				if(FD_ISSET(fd_listenset[i],&lfds)) {
					s = fd_listenset[i];
					/* Clear this so we don't look
					   at it again. */
					FD_CLR(fd_listenset[i],&lfds);
					break;
				}
			}

			smbd_set_server_fd(accept(s,&addr,&in_addrlen));
			
			if (smbd_server_fd() == -1 && errno == EINTR)
				continue;
			
			if (smbd_server_fd() == -1) {
				DEBUG(0,("open_sockets_smbd: accept: %s\n",
					 strerror(errno)));
				continue;
			}

			/* Ensure child is set to blocking mode */
			set_blocking(smbd_server_fd(),True);

			if (smbd_server_fd() != -1 && interactive) {
#ifdef _XBOX
				xb_IncClientCount();
#endif
				return True;
			}
			
			if (allowable_number_of_smbd_processes() && smbd_server_fd() != -1 && sys_fork()==0) {


				/* Child code ... */			

				/* close the listening socket(s) */
				for(i = 0; i < num_sockets; i++)
					close(fd_listenset[i]);
				
				/* close our standard file
				   descriptors */
				close_low_fds(False);
				am_parent = 0;
				
				set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
				set_socket_options(smbd_server_fd(),user_socket_options);
				
				/* this is needed so that we get decent entries
				   in smbstatus for port 445 connects */
				set_remote_machine_name(get_peer_addr(smbd_server_fd()), False);
				
				/* Reset the state of the random
				 * number generation system, so
				 * children do not get the same random
				 * numbers as each other */

				set_need_random_reseed();
				/* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */
				if (tdb_reopen_all(1) == -1) {
					DEBUG(0,("tdb_reopen_all failed.\n"));
					smb_panic("tdb_reopen_all failed.");
				}

				return True; 
			}
			/* The parent doesn't need this socket */
			close(smbd_server_fd()); 

			/* Sun May 6 18:56:14 2001 [email protected]:
				Clear the closed fd info out of server_fd --
				and more importantly, out of client_fd in
				util_sock.c, to avoid a possible
				getpeername failure if we reopen the logs
				and use %I in the filename.
			*/

			smbd_set_server_fd(-1);

			/* Force parent to check log size after
			 * spawning child.  Fix from
			 * [email protected].  The
			 * parent smbd will log to logserver.smb.  It
			 * writes only two messages for each child
			 * started/finished. But each child writes,
			 * say, 50 messages also in logserver.smb,
			 * begining with the debug_count of the
			 * parent, before the child opens its own log
			 * file logserver.client. In a worst case
			 * scenario the size of logserver.smb would be
			 * checked after about 50*50=2500 messages
			 * (ca. 100kb).
			 * */
			force_check_log_size();
 
		} /* end for num */
	} /* end while 1 */

/* NOTREACHED	return True; */
}
Пример #20
0
static int init_sockets_smbd(const char *smb_ports, int listenset[FD_SETSIZE])
{
	int num_interfaces = iface_count();
	char * ports;
	int num_sockets = 0;
	int i, s;

	/* use a reasonable default set of ports - listing on 445 and 139 */
	if (!smb_ports) {
		ports = lp_smb_ports();
		if (!ports || !*ports) {
			ports = smb_xstrdup(SMB_PORTS);
		} else {
			ports = smb_xstrdup(ports);
		}
	} else {
		ports = smb_xstrdup(smb_ports);
	}

	if (lp_interfaces() && lp_bind_interfaces_only()) {
		/* We have been given an interfaces line, and been
		   told to only bind to those interfaces. Create a
		   socket per interface and bind to only these.
		*/

		/* Now open a listen socket for each of the
		   interfaces. */
		for(i = 0; i < num_interfaces; i++) {
			struct in_addr *ifip = iface_n_ip(i);
			fstring tok;
			const char *ptr;

			if(ifip == NULL) {
				DEBUG(0,("init_sockets_smbd: interface %d has NULL IP address !\n", i));
				continue;
			}

			for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
				unsigned port = atoi(tok);
				if (port == 0) {
					continue;
				}
				s = listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
				if (s < 0 || s >= FD_SETSIZE)
					return 0;

				/* ready to listen */
				set_socket_options(s,"SO_KEEPALIVE");
				set_socket_options(s,user_socket_options);

				/* Set server socket to non-blocking for the accept. */
				set_blocking(s,False);

				if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
					DEBUG(0,("listen: %s\n",strerror(errno)));
					close(s);
					return 0;
				}

				num_sockets++;
				if (num_sockets >= FD_SETSIZE) {
					DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
					return 0;
				}
			}
		}
	} else {
		/* Just bind to 0.0.0.0 - accept connections
		   from anywhere. */

		fstring tok;
		const char *ptr;

		num_interfaces = 1;

		for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
			unsigned port = atoi(tok);
			if (port == 0) continue;
			/* open an incoming socket */
			s = open_socket_in(SOCK_STREAM, port, 0,
					   interpret_addr(lp_socket_address()),True);
			if (s < 0 || s >= FD_SETSIZE)
				return 0;

			/* ready to listen */
			set_socket_options(s,"SO_KEEPALIVE");
			set_socket_options(s,user_socket_options);

			/* Set server socket to non-blocking for the accept. */
			set_blocking(s,False);

			if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
				DEBUG(0,("init_sockets_smbd: listen: %s\n",
					 strerror(errno)));
				close(s);
				return 0;
			}

			listenset[num_sockets] = s;
			num_sockets++;

			if (num_sockets >= FD_SETSIZE) {
				DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
				return 0;
			}
		}
	}

	SAFE_FREE(ports);
	return num_sockets;
}
Пример #21
0
void start_accept_loop(int port, int (*fn)(int ))
{
	int s;
	extern char *bind_address;
	extern int default_af_hint;

	/* open an incoming socket */
	s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
	if (s == -1)
		exit_cleanup(RERR_SOCKETIO);

	/* ready to listen */
	if (listen(s, 5) == -1) {
		close(s);
		exit_cleanup(RERR_SOCKETIO);
	}


	/* now accept incoming connections - forking a new process
	   for each incoming connection */
	while (1) {
		fd_set fds;
		pid_t pid;
		int fd;
		struct sockaddr_storage addr;
		socklen_t addrlen = sizeof addr;

		/* close log file before the potentially very long select so
		   file can be trimmed by another process instead of growing
		   forever */
		log_close();

		FD_ZERO(&fds);
		FD_SET(s, &fds);

		if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
			continue;
		}

		if(!FD_ISSET(s, &fds)) continue;

		fd = accept(s,(struct sockaddr *)&addr,&addrlen);

		if (fd == -1) continue;

		signal(SIGCHLD, SIG_IGN);

		/* we shouldn't have any children left hanging around
		   but I have had reports that on Digital Unix zombies
		   are produced, so this ensures that they are reaped */
#ifdef WNOHANG
                while (waitpid(-1, NULL, WNOHANG) > 0);
#endif

		if ((pid = fork()) == 0) {
			close(s);
			/* open log file in child before possibly giving
			   up privileges  */
			log_open();
			_exit(fn(fd));
		} else if (pid < 0) {
			rprintf(FERROR,
				RSYNC_NAME
				": could not create child server process: %s\n",
				strerror(errno));
			close(fd);
			/* This might have happened because we're
			 * overloaded.  Sleep briefly before trying to
			 * accept again. */
			sleep(2);
		} else {
			/* Parent doesn't need this fd anymore. */
			close(fd);
		}
	}
}