Beispiel #1
0
static void multi_server_execute(int unused_event, char *context)
{
    VSTREAM *stream = (VSTREAM *) context;
    HTABLE *attr = (vstream_flags(stream) == multi_server_saved_flags ?
		    (HTABLE *) vstream_context(stream) : 0);

    if (multi_server_lock != 0
	&& myflock(vstream_fileno(multi_server_lock), INTERNAL_LOCK,
		   MYFLOCK_OP_NONE) < 0)
	msg_fatal("select unlock: %m");

    /*
     * Do not bother the application when the client disconnected. Don't drop
     * the already accepted client request after "postfix reload"; that would
     * be rude.
     */
    if (peekfd(vstream_fileno(stream)) > 0) {
	if (master_notify(var_pid, multi_server_generation, MASTER_STAT_TAKEN) < 0)
	     /* void */ ;
	multi_server_service(stream, multi_server_name, multi_server_argv);
	if (master_notify(var_pid, multi_server_generation, MASTER_STAT_AVAIL) < 0)
	    multi_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT);
    } else {
	multi_server_disconnect(stream);
    }
    if (attr)
	htable_free(attr, myfree);
}
Beispiel #2
0
DELIVER_REQUEST *deliver_request_read(VSTREAM *stream)
{
    DELIVER_REQUEST *request;

    /*
     * Tell the queue manager that we are ready for this request.
     */
    if (deliver_request_initial(stream) != 0)
	return (0);

    /*
     * Be prepared for the queue manager to change its mind after contacting
     * us. This can happen when a transport or host goes bad.
     */
    (void) read_wait(vstream_fileno(stream), -1);
    if (peekfd(vstream_fileno(stream)) <= 0)
	return (0);

    /*
     * Allocate and read the queue manager's delivery request.
     */
#define XXX_DEFER_STATUS	-1

    request = deliver_request_alloc();
    if (deliver_request_get(stream, request) < 0) {
	deliver_request_done(stream, request, XXX_DEFER_STATUS);
	request = 0;
    }
    return (request);
}
Beispiel #3
0
int     fifo_listen(const char *path, int permissions, int block_mode)
{
    char    buf[BUF_LEN];
    static int open_mode = 0;
    char   *myname = "fifo_listen";
    struct stat st;
    int     fd;
    int     count;

    /*
     * Create a named pipe (fifo). Do whatever we can so we don't run into
     * trouble when this process is restarted after crash.  Make sure that we
     * open a fifo and not something else, then change permissions to what we
     * wanted them to be, because mkfifo() is subject to umask settings.
     * Instead we could zero the umask temporarily before creating the FIFO,
     * but that would cost even more system calls. Figure out if the fifo
     * needs to be opened O_RDWR or O_RDONLY. Some systems need one, some
     * need the other. If we choose the wrong mode, the fifo will stay
     * readable, causing the program to go into a loop.
     */
    if (unlink(path) && errno != ENOENT)
	msg_fatal("%s: remove %s: %m", myname, path);
    if (mkfifo(path, permissions) < 0)
	msg_fatal("%s: create fifo %s: %m", myname, path);
    switch (open_mode) {
    case 0:
	if ((fd = open(path, O_RDWR | O_NONBLOCK, 0)) < 0)
	    msg_fatal("%s: open %s: %m", myname, path);
	if (readable(fd) == 0) {
	    open_mode = O_RDWR | O_NONBLOCK;
	    break;
	} else {
	    open_mode = O_RDONLY | O_NONBLOCK;
	    if (msg_verbose)
		msg_info("open O_RDWR makes fifo readable - trying O_RDONLY");
	    (void) close(fd);
	    /* FALLTRHOUGH */
	}
    default:
	if ((fd = open(path, open_mode, 0)) < 0)
	    msg_fatal("%s: open %s: %m", myname, path);
	break;
    }

    /*
     * Make sure we opened a FIFO and skip any cruft that might have
     * accumulated before we opened it.
     */
    if (fstat(fd, &st) < 0)
	msg_fatal("%s: fstat %s: %m", myname, path);
    if (S_ISFIFO(st.st_mode) == 0)
	msg_fatal("%s: not a fifo: %s", myname, path);
    if (fchmod(fd, permissions) < 0)
	msg_fatal("%s: fchmod %s: %m", myname, path);
    non_blocking(fd, block_mode);
    while ((count = peekfd(fd)) > 0
	   && read(fd, buf, BUF_LEN < count ? BUF_LEN : count) > 0)
	 /* void */ ;
    return (fd);
}
Beispiel #4
0
int     mail_flow_count(void)
{
    char   *myname = "mail_flow_count";
    int     count;

    if ((count = peekfd(MASTER_FLOW_READ)) < 0)
	msg_warn("%s: %m", myname);
    return (count);
}
Beispiel #5
0
static int qmgr_deliver_initial_reply(VSTREAM *stream)
{
    int     stat;

    if (peekfd(vstream_fileno(stream)) < 0) {
	msg_warn("%s: premature disconnect", VSTREAM_PATH(stream));
	return (DELIVER_STAT_CRASH);
    } else if (attr_scan(stream, ATTR_FLAG_STRICT,
			 ATTR_TYPE_INT, MAIL_ATTR_STATUS, &stat,
			 ATTR_TYPE_END) != 1) {
	msg_warn("%s: malformed response", VSTREAM_PATH(stream));
	return (DELIVER_STAT_CRASH);
    } else {
	return (stat ? DELIVER_STAT_DEFER : 0);
    }
}
Beispiel #6
0
static int flush_request_receive(VSTREAM *client_stream, VSTRING *request)
{
    int     count;

    /*
     * Kluge: choose the protocol depending on the request size.
     */
    if (read_wait(vstream_fileno(client_stream), var_ipc_timeout) < 0) {
	msg_warn("timeout while waiting for data from %s",
		 VSTREAM_PATH(client_stream));
	return (-1);
    }
    if ((count = peekfd(vstream_fileno(client_stream))) < 0) {
	msg_warn("cannot examine read buffer of %s: %m",
		 VSTREAM_PATH(client_stream));
	return (-1);
    }

    /*
     * Short request: master trigger. Use the string+null protocol.
     */
    if (count <= 2) {
	if (vstring_get_null(request, client_stream) == VSTREAM_EOF) {
	    msg_warn("end-of-input while reading request from %s: %m",
		     VSTREAM_PATH(client_stream));
	    return (-1);
	}
    }

    /*
     * Long request: real flush client. Use the attribute list protocol.
     */
    else {
	if (attr_scan(client_stream,
		      ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
		      RECV_ATTR_STR(MAIL_ATTR_REQ, request),
		      ATTR_TYPE_END) != 1) {
	    return (-1);
	}
    }
    return (0);
}
Beispiel #7
0
int arpCheck()
{
  arpMessage ArpMsgSend,ArpMsgRecv;
#ifdef OLD_LINUX_VERSION
  struct sockaddr addr;
  int j;
#endif
  int i=0;

  memset(&ArpMsgSend,0,sizeof(arpMessage));
  memcpy(ArpMsgSend.ethhdr.ether_dhost,MAC_BCAST_ADDR,ETH_ALEN);
  memcpy(ArpMsgSend.ethhdr.ether_shost,ClientHwAddr,ETH_ALEN);
  ArpMsgSend.ethhdr.ether_type = htons(ETHERTYPE_ARP);

  ArpMsgSend.htype	= htons(ARPHRD_ETHER);
  ArpMsgSend.ptype	= htons(ETHERTYPE_IP);
  ArpMsgSend.hlen	= ETH_ALEN;
  ArpMsgSend.plen	= 4;
  ArpMsgSend.operation	= htons(ARPOP_REQUEST);
  memcpy(ArpMsgSend.sHaddr,ClientHwAddr,ETH_ALEN);
  memcpy(&ArpMsgSend.tInaddr,&DhcpIface.ciaddr,4);

  DebugSyslog(LOG_DEBUG,
    "broadcasting ARPOP_REQUEST for %u.%u.%u.%u\n",
    ArpMsgSend.tInaddr[0],ArpMsgSend.tInaddr[1],
    ArpMsgSend.tInaddr[2],ArpMsgSend.tInaddr[3]);
  do
    {
      do
    	{
      	  if ( i++ > 4 ) return 0; /*  5 probes  */
#ifdef OLD_LINUX_VERSION
      	  memset(&addr,0,sizeof(struct sockaddr));
      	  memcpy(addr.sa_data,IfName,IfName_len);
      	  if ( sendto(dhcpSocket,&ArpMsgSend,sizeof(arpMessage),0,
	   	&addr,sizeof(struct sockaddr)) == -1 )
#else
      	  if ( send(dhcpSocket,&ArpMsgSend,sizeof(arpMessage),0) == -1 )
#endif
	    {
	      syslog(LOG_ERR,"arpCheck: sendto: %m\n");
	      return -1;
	    }
    	}
      while ( peekfd(dhcpSocket,50000) ); /* 50 msec timeout */
      do
    	{
      	  if ( recv(dhcpSocket,&ArpMsgRecv,sizeof(arpMessage),0) == -1 )
    	    {
      	      syslog(LOG_ERR,"arpCheck: recv: %m\n");
      	      return -1;
    	    }
	  if ( ArpMsgRecv.ethhdr.ether_type != htons(ETHERTYPE_ARP) )
	    continue;
      	  if ( ArpMsgRecv.operation == htons(ARPOP_REPLY) )
	    {
	      DebugSyslog(LOG_DEBUG,
	      "ARPOP_REPLY received from %u.%u.%u.%u for %u.%u.%u.%u\n",
	      ArpMsgRecv.sInaddr[0],ArpMsgRecv.sInaddr[1],
	      ArpMsgRecv.sInaddr[2],ArpMsgRecv.sInaddr[3],
	      ArpMsgRecv.tInaddr[0],ArpMsgRecv.tInaddr[1],
	      ArpMsgRecv.tInaddr[2],ArpMsgRecv.tInaddr[3]);
	    }
      	  else
	    continue;
      	  if ( memcmp(ArpMsgRecv.tHaddr,ClientHwAddr,ETH_ALEN) )
	    {
	    	DebugSyslog(LOG_DEBUG,
	    	"target hardware address mismatch: %02X.%02X.%02X.%02X.%02X.%02X received, %02X.%02X.%02X.%02X.%02X.%02X expected\n",
	    	ArpMsgRecv.tHaddr[0],ArpMsgRecv.tHaddr[1],ArpMsgRecv.tHaddr[2],
	    	ArpMsgRecv.tHaddr[3],ArpMsgRecv.tHaddr[4],ArpMsgRecv.tHaddr[5],
	    	ClientHwAddr[0],ClientHwAddr[1],
	        ClientHwAddr[2],ClientHwAddr[3],
		ClientHwAddr[4],ClientHwAddr[5]);
	      continue;
	    }
      	  if ( memcmp(&ArpMsgRecv.sInaddr,&DhcpIface.ciaddr,4) )
	    {
	    	DebugSyslog(LOG_DEBUG,
	    	"sender IP address mismatch: %u.%u.%u.%u received, %u.%u.%u.%u expected\n",
	    	ArpMsgRecv.sInaddr[0],ArpMsgRecv.sInaddr[1],ArpMsgRecv.sInaddr[2],ArpMsgRecv.sInaddr[3],
	    	((unsigned char *)&DhcpIface.ciaddr)[0],
	    	((unsigned char *)&DhcpIface.ciaddr)[1],
	    	((unsigned char *)&DhcpIface.ciaddr)[2],
	    	((unsigned char *)&DhcpIface.ciaddr)[3]);
	      continue;
	    }
      	  return 1;
    	}
      while ( peekfd(dhcpSocket,50000) == 0 );
    }
  while ( 1 );
  return 0;
}
Beispiel #8
0
int arpCheck()
{
  arpMessage ArpMsgSend,ArpMsgRecv;
  struct sockaddr addr;
  int j,i=0,len=0;

  memset(&ArpMsgSend,0,sizeof(arpMessage));
  memcpy(ArpMsgSend.ethhdr.ether_dhost,MAC_BCAST_ADDR,ETH_ALEN);
  memcpy(ArpMsgSend.ethhdr.ether_shost,ClientHwAddr,ETH_ALEN);
  ArpMsgSend.ethhdr.ether_type = htons(ETHERTYPE_ARP);

  ArpMsgSend.htype	= (TokenRingIf) ? htons(ARPHRD_IEEE802_TR) : htons(ARPHRD_ETHER);
  ArpMsgSend.ptype	= htons(ETHERTYPE_IP);
  ArpMsgSend.hlen	= ETH_ALEN;
  ArpMsgSend.plen	= 4;
  ArpMsgSend.operation	= htons(ARPOP_REQUEST);
  memcpy(ArpMsgSend.sHaddr,ClientHwAddr,ETH_ALEN);
  memcpy(&ArpMsgSend.tInaddr,&DhcpIface.ciaddr,4);

  if ( DebugFlag ) syslog(LOG_DEBUG,
    "broadcasting ARPOP_REQUEST for %u.%u.%u.%u\n",
    ArpMsgSend.tInaddr[0],ArpMsgSend.tInaddr[1],
    ArpMsgSend.tInaddr[2],ArpMsgSend.tInaddr[3]);
  do
    {
      do
    	{
      	  if ( i++ > 4 ) return 0; /*  5 probes  */
      	  memset(&addr,0,sizeof(struct sockaddr));
      	  memcpy(addr.sa_data,IfName,IfName_len);
	  if ( TokenRingIf )
	    len = eth2tr(&ArpMsgSend.ethhdr,BasicArpLen(ArpMsgSend));
	  else
	    len = sizeof(arpMessage);
	  if ( sendto(dhcpSocket,&ArpMsgSend,len,0,
		&addr,sizeof(struct sockaddr)) == -1 )
	    {
	      syslog(LOG_ERR,"arpCheck: sendto: %m\n");
	      return -1;
	    }
    	}
      while ( peekfd(dhcpSocket,50000) ); /* 50 msec timeout */
      do
    	{
      	  memset(&ArpMsgRecv,0,sizeof(arpMessage));
      	  j=sizeof(struct sockaddr);
      	  if ( recvfrom(dhcpSocket,&ArpMsgRecv,sizeof(arpMessage),0,
		    (struct sockaddr *)&addr,&j) == -1 )
    	    {
      	      syslog(LOG_ERR,"arpCheck: recvfrom: %m\n");
      	      return -1;
    	    }
	  if ( TokenRingIf )
	    {
	      if ( tr2eth(&ArpMsgRecv.ethhdr) )  continue;
	    }
	  if ( ArpMsgRecv.ethhdr.ether_type != htons(ETHERTYPE_ARP) )
	    continue;
      	  if ( ArpMsgRecv.operation == htons(ARPOP_REPLY) )
	    {
	      if ( DebugFlag ) syslog(LOG_DEBUG,
	      "ARPOP_REPLY received from %u.%u.%u.%u for %u.%u.%u.%u\n",
	      ArpMsgRecv.sInaddr[0],ArpMsgRecv.sInaddr[1],
	      ArpMsgRecv.sInaddr[2],ArpMsgRecv.sInaddr[3],
	      ArpMsgRecv.tInaddr[0],ArpMsgRecv.tInaddr[1],
	      ArpMsgRecv.tInaddr[2],ArpMsgRecv.tInaddr[3]);
	    }
      	  else
	    continue;
      	  if ( memcmp(ArpMsgRecv.tHaddr,ClientHwAddr,ETH_ALEN) )
	    {
	      if ( DebugFlag )
	    	syslog(LOG_DEBUG,
	    	"target hardware address mismatch: %02X.%02X.%02X.%02X.%02X.%02X received, %02X.%02X.%02X.%02X.%02X.%02X expected\n",
	    	ArpMsgRecv.tHaddr[0],ArpMsgRecv.tHaddr[1],ArpMsgRecv.tHaddr[2],
	    	ArpMsgRecv.tHaddr[3],ArpMsgRecv.tHaddr[4],ArpMsgRecv.tHaddr[5],
	    	ClientHwAddr[0],ClientHwAddr[1],
	        ClientHwAddr[2],ClientHwAddr[3],
		ClientHwAddr[4],ClientHwAddr[5]);
	      continue;
	    }
      	  if ( memcmp(&ArpMsgRecv.sInaddr,&DhcpIface.ciaddr,4) )
	    {
	      if ( DebugFlag )
	    	syslog(LOG_DEBUG,
	    	"sender IP address mismatch: %u.%u.%u.%u received, %u.%u.%u.%u expected\n",
	    	ArpMsgRecv.sInaddr[0],ArpMsgRecv.sInaddr[1],ArpMsgRecv.sInaddr[2],ArpMsgRecv.sInaddr[3],
	    	((unsigned char *)&DhcpIface.ciaddr)[0],
	    	((unsigned char *)&DhcpIface.ciaddr)[1],
	    	((unsigned char *)&DhcpIface.ciaddr)[2],
	    	((unsigned char *)&DhcpIface.ciaddr)[3]);
	      continue;
	    }
      	  return 1;
    	}
      while ( peekfd(dhcpSocket,50000) == 0 );
    }
  while ( 1 );
  return 0;
}