Exemple #1
0
int
sys_select_ms(struct lwp *l, const struct sys_select_ms_args *uap, register_t *retval)
{
	struct timeval tv;
	struct sys_select_args a = {
		.a = {
			.nfds = SCARG(uap, nfds),
			.readfds = SCARG(uap, readfds),
			.writefds = SCARG(uap, writefds),
			.exceptfds = SCARG(uap, exceptfds),
		}
	};

	if (SCARG(uap, tmout) == TMO_FEVR) {
		a.a.tv = NULL;
	}
	else if (SCARG(uap, tmout) >= 0) {
		tv.tv_sec = SCARG(uap, tmout) / 1000;
		tv.tv_usec = (SCARG(uap, tmout) % 1000) * 1000;
		a.a.tv = &tv;
	}
	else {
		return EINVAL;
	}

	return sys_select(l, &a, retval);
}
Exemple #2
0
/****************************************************************************
wait for keyboard activity, swallowing network packets
****************************************************************************/
static void wait_keyboard(struct cli_state *cli)
{
  fd_set fds;
  struct timeval timeout;
  
  while (1) 
    {
      FD_ZERO(&fds);
      FD_SET(cli->fd,&fds);
      FD_SET(fileno(stdin),&fds);

      timeout.tv_sec = 20;
      timeout.tv_usec = 0;
      sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,&timeout);
      
      if (FD_ISSET(fileno(stdin),&fds))
  	return;

      /* We deliberately use receive_smb instead of
         client_receive_smb as we want to receive
         session keepalives and then drop them here.
       */
      if (FD_ISSET(cli->fd,&fds))
  	receive_smb(cli->fd,cli->inbuf,0);
    }  
}
Exemple #3
0
asmlinkage int old_select(struct sel_arg_struct *arg)
{
	struct sel_arg_struct a;

	if (copy_from_user(&a, arg, sizeof(a)))
		return -EFAULT;
	/* sys_select() does the appropriate kernel locking */
	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
}
Exemple #4
0
static void do_smb_resolve(struct mdns_smbsrv_result *browsesrv)
{
	DNSServiceRef mdns_conn_sdref = NULL;
	int mdnsfd;
	int fdsetsz;
	int ret;
	fd_set *fdset = NULL;
	struct timeval tv;
	DNSServiceErrorType err;

	TALLOC_CTX * ctx = talloc_tos();

	err = DNSServiceResolve(&mdns_conn_sdref, 0 /* flags */,
		browsesrv->ifIndex,
		browsesrv->serviceName, browsesrv->regType, browsesrv->domain,
		do_smb_resolve_reply, NULL);

	if (err != kDNSServiceErr_NoError) {
		return;
	}

	mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref);
	for (;;)  {
		if (fdset != NULL) {
			TALLOC_FREE(fdset);
		}

		if (mdnsfd < 0 || mdnsfd >= FD_SETSIZE) {
			errno = EBADF;
			break;
		}

		fdsetsz = howmany(mdnsfd + 1, NFDBITS) * sizeof(fd_mask);
		fdset = TALLOC_ZERO(ctx, fdsetsz);
		FD_SET(mdnsfd, fdset);

		tv.tv_sec = 1;
		tv.tv_usec = 0;

		/* Wait until response received from mDNS daemon */
		ret = sys_select(mdnsfd + 1, fdset, NULL, NULL, &tv);
		if (ret <= 0 && errno != EINTR) {
			break;
		}

		if (FD_ISSET(mdnsfd, fdset)) {
			/* Invoke callback function */
			DNSServiceProcessResult(mdns_conn_sdref);
			break;
		}
	}

	TALLOC_FREE(fdset);
	DNSServiceRefDeallocate(mdns_conn_sdref);
}
Exemple #5
0
static void filter_child(int c, struct in_addr dest_ip)
{
	int s;

	/* we have a connection from a new client, now connect to the server */
	s = open_socket_out(SOCK_STREAM, &dest_ip, 139, LONG_CONNECT_TIMEOUT);

	if (s == -1) {
		DEBUG(0,("Unable to connect to %s\n", inet_ntoa(dest_ip)));
		exit(1);
	}

	while (c != -1 || s != -1) {
		fd_set fds;
		int num;
		
		FD_ZERO(&fds);
		if (s != -1) FD_SET(s, &fds);
		if (c != -1) FD_SET(c, &fds);

		num = sys_select(MAX(s+1, c+1),&fds,NULL);
		if (num <= 0) continue;
		
		if (c != -1 && FD_ISSET(c, &fds)) {
			if (!receive_smb(c, packet, 0)) {
				DEBUG(0,("client closed connection\n"));
				exit(0);
			}
			filter_request(packet);
			if (!send_smb(s, packet)) {
				DEBUG(0,("server is dead\n"));
				exit(1);
			}			
		}
		if (s != -1 && FD_ISSET(s, &fds)) {
			if (!receive_smb(s, packet, 0)) {
				DEBUG(0,("server closed connection\n"));
				exit(0);
			}
			filter_reply(packet);
			if (!send_smb(c, packet)) {
				DEBUG(0,("client is dead\n"));
				exit(1);
			}			
		}
	}
	DEBUG(0,("Connection closed\n"));
	exit(0);
}
Exemple #6
0
static void start_filter(char *desthost)
{
	int s, c;
	struct in_addr dest_ip;

	CatchChild();

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

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

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

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

		num = sys_select(s+1,&fds,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);
				}
			}
		}
	}
}
Exemple #7
0
/*
 * Due to some executables calling the wrong select we sometimes
 * get wrong args.  This determines how the args are being passed
 * (a single ptr to them all args passed) then calls
 * sys_select() with the appropriate args. -- Cort
 */
int
ppc_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
{
	if ( (unsigned long)n >= 4096 )
	{
		unsigned long *buffer = (unsigned long *)n;
		if (verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long))
		    || __get_user(n, buffer)
		    || __get_user(inp, ((fd_set **)(buffer+1)))
		    || __get_user(outp, ((fd_set **)(buffer+2)))
		    || __get_user(exp, ((fd_set **)(buffer+3)))
		    || __get_user(tvp, ((struct timeval **)(buffer+4))))
			return -EFAULT;
	}
	return sys_select(n, inp, outp, exp, tvp);
}
asmlinkage int sunos_select(int width, fd_set __user *inp, fd_set __user *outp,
                            fd_set __user *exp, struct timeval __user *tvp)
{
    int ret;

    /* SunOS binaries expect that select won't change the tvp contents */
    ret = sys_select (width, inp, outp, exp, tvp);
    if (ret == -EINTR && tvp) {
        time_t sec, usec;

        __get_user(sec, &tvp->tv_sec);
        __get_user(usec, &tvp->tv_usec);

        if (sec == 0 && usec == 0)
            ret = 0;
    }
    return ret;
}
Exemple #9
0
asmlinkage int old_select(unsigned long *buffer)
{
	int n;
	fd_set *inp;
	fd_set *outp;
	fd_set *exp;
	struct timeval *tvp;

	n = verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long));
	if (n)
		return n;
	n = get_user(buffer);
	inp = (fd_set *) get_user(buffer+1);
	outp = (fd_set *) get_user(buffer+2);
	exp = (fd_set *) get_user(buffer+3);
	tvp = (struct timeval *) get_user(buffer+4);
	return sys_select(n, inp, outp, exp, tvp);
}
ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
{
  fd_set fds;
  int selrtn;
  ssize_t readret;
  size_t nread = 0;
  struct timeval timeout;

  /* just checking .... */
  if (maxcnt <= 0)
    return(0);

  /* Blocking read */
  if (time_out <= 0) {
    if (mincnt == 0) mincnt = maxcnt;

    while (nread < mincnt) {
#ifdef WITH_SSL
      if(fd == sslFd){
        readret = SSL_read(ssl, buf + nread, maxcnt - nread);
      }else{
        readret = read(fd, buf + nread, maxcnt - nread);
      }
#else /* WITH_SSL */
      readret = read(fd, buf + nread, maxcnt - nread);
#endif /* WITH_SSL */

      if (readret <= 0)
	return readret;

      nread += readret;
    }
    return((ssize_t)nread);
  }
  
  /* Most difficult - timeout read */
  /* If this is ever called on a disk file and 
     mincnt is greater then the filesize then
     system performance will suffer severely as 
     select always returns true on disk files */

  /* Set initial timeout */
  timeout.tv_sec = (time_t)(time_out / 1000);
  timeout.tv_usec = (long)(1000 * (time_out % 1000));

  for (nread=0; nread < mincnt; ) {      
    FD_ZERO(&fds);
    FD_SET(fd,&fds);
      
    selrtn = sys_select(fd+1,&fds,&timeout);

    if(selrtn <= 0)
      return selrtn;
      
#ifdef WITH_SSL
    if(fd == sslFd){
      readret = SSL_read(ssl, buf + nread, maxcnt - nread);
    }else{
      readret = read(fd, buf + nread, maxcnt - nread);
    }
#else /* WITH_SSL */
    readret = read(fd, buf+nread, maxcnt-nread);
#endif /* WITH_SSL */

    if (readret <= 0)
      return readret;

    nread += readret;
  }

  /* Return the number we got */
  return((ssize_t)nread);
}
static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
{
  fd_set fds;
  int selrtn;
  ssize_t readret;
  size_t nread = 0;
  struct timeval timeout;

  /* just checking .... */
  if (maxcnt <= 0)
    return(0);

  smb_read_error = 0;

  /* Blocking read */
  if (time_out <= 0) {
    if (mincnt == 0) mincnt = maxcnt;

    while (nread < mincnt) {
#ifdef WITH_SSL
      if(fd == sslFd){
        readret = SSL_read(ssl, buf + nread, maxcnt - nread);
      }else{
        readret = read(fd, buf + nread, maxcnt - nread);
      }
#else /* WITH_SSL */
      readret = read(fd, buf + nread, maxcnt - nread);
#endif /* WITH_SSL */

      if (readret == 0) {
        DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
        smb_read_error = READ_EOF;
        return -1;
      }

      if (readret == -1) {
        DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
        smb_read_error = READ_ERROR;
        return -1;
      }
      nread += readret;
    }
    return((ssize_t)nread);
  }
  
  /* Most difficult - timeout read */
  /* If this is ever called on a disk file and 
     mincnt is greater then the filesize then
     system performance will suffer severely as 
     select always returns true on disk files */

  /* Set initial timeout */
  timeout.tv_sec = (time_t)(time_out / 1000);
  timeout.tv_usec = (long)(1000 * (time_out % 1000));

  for (nread=0; nread < mincnt; ) {      
    FD_ZERO(&fds);
    FD_SET(fd,&fds);
      
    selrtn = sys_select(fd+1,&fds,&timeout);

    /* Check if error */
    if(selrtn == -1) {
      /* something is wrong. Maybe the socket is dead? */
      DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
      smb_read_error = READ_ERROR;
      return -1;
    }

    /* Did we timeout ? */
    if (selrtn == 0) {
      DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
      smb_read_error = READ_TIMEOUT;
      return -1;
    }
      
#ifdef WITH_SSL
    if(fd == sslFd){
      readret = SSL_read(ssl, buf + nread, maxcnt - nread);
    }else{
      readret = read(fd, buf + nread, maxcnt - nread);
    }
#else /* WITH_SSL */
    readret = read(fd, buf+nread, maxcnt-nread);
#endif /* WITH_SSL */

    if (readret == 0) {
      /* we got EOF on the file descriptor */
      DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
      smb_read_error = READ_EOF;
      return -1;
    }

    if (readret == -1) {
      /* the descriptor is probably dead */
      DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
      smb_read_error = READ_ERROR;
      return -1;
    }
      
    nread += readret;
  }

  /* Return the number we got */
  return((ssize_t)nread);
}
static void wait_keyboard(char *buffer)
#endif
{
  fd_set fds;
  int selrtn;
  struct timeval timeout;
  
#ifdef CLIX
  int delay = 0;
#endif
  
  while (1) 
    {
      extern int Client;
      FD_ZERO(&fds);
      FD_SET(Client,&fds);
#ifndef CLIX
      FD_SET(fileno(stdin),&fds);
#endif

      timeout.tv_sec = 20;
      timeout.tv_usec = 0;
#ifdef CLIX
      timeout.tv_sec = 0;
#endif
      selrtn = sys_select(&fds,&timeout);
      
#ifndef CLIX
      if (FD_ISSET(fileno(stdin),&fds))
  	return;
#else
      {
	char ch;
	int readret;

    set_blocking(fileno(stdin), False);	
	readret = read_data( fileno(stdin), &ch, 1);
	set_blocking(fileno(stdin), True);
	if (readret == -1)
	  {
	    if (errno != EAGAIN)
	      {
		/* should crash here */
		DEBUG(1,("readchar stdin failed\n"));
	      }
	  }
	else if (readret != 0)
	  {
	    return ch;
	  }
      }
#endif

      /* We deliberately use receive_smb instead of
         client_receive_smb as we want to receive
         session keepalives and then drop them here.
       */
      if (FD_ISSET(Client,&fds))
  	receive_smb(Client,buffer,0);
      
#ifdef CLIX
      delay++;
      if (delay > 100000)
	{
	  delay = 0;
	  chkpath("\\",False);
	}
#else
      chkpath("\\",False);
#endif
    }  
}
Exemple #13
0
int
so_socksys(struct socksysreq *req)
{
	int err = -EINVAL;
	int cmd = req->args[0];

	if ((1 << cmd) & ((1 << SO_ACCEPT) | (1 << SO_BIND) | (1 << SO_CONNECT) |
			  (1 << SO_GETPEERNAME) | (1 << SO_GETSOCKNAME) | (1 << SO_GETSOCKOPT) |
			  (1 << SO_LISTEN) | (1 << SO_RECV) | (1 << SO_RECVFROM) | (1 << SO_SEND) |
			  (1 << SO_SENDTO) | (1 << SO_SETSOCKOPT) | (1 << SO_SHUTDOWN) |
			  (1 << SO_RECVMSG) | (1 << SO_SENDMSG))) {
		int fd = req->args[1];

		(void) fd;
		/* These are all socket related and accept a file (socket) descriptor as their
		   first argument.  In situations where we are incapable of providing back a real
		   socket, we must here first distinguish if the file descriptor corresponds to a
		   socket or a stream. */
#if 0
		if (it_is_a_socket) {
#endif
			/* In this case, we have a real socket from the operating system's
			   perspective and we can simply pass the arguments to the appropriate
			   system call. */
#if 0
			switch (cmd) {
			case SO_ACCEPT:
				/* FIXME: 32/64 conversion */
				err = sys_accept(fd, (struct sockaddr *) req->args[2],
						 req->args[3]);
				break;
			case SO_BIND:
				/* FIXME: 32/64 conversion */
				err = sys_bind(fd, (struct sockaddr *) req->args[2], req->args[3]);
				break;
			case SO_CONNECT:
				/* FIXME: 32/64 conversion */
				err = sys_connect(fd, (struct sockaddr *) req->args[2],
						  req->args[3]);
				break;
			case SO_GETPEERNAME:
				/* FIXME: 32/64 conversion */
				err = sys_getpeername(fd, (struct sockaddr *) req->args[2],
						      (int *) req->args[3]);
				break;
			case SO_GETSOCKNAME:
				/* FIXME: 32/64 conversion */
				err = sys_getsockname(fd, (struct sockaddr *) req->args[2],
						      (int *) req->args[3]);
				break;
			case SO_GETSOCKOPT:
				/* FIXME: 32/64 conversion */
				err = sys_getsockopt(fd, req->args[2], req->args[3],
						     (char *) req->args[4], (int *) req->args[5]);
				break;
			case SO_LISTEN:
				/* FIXME: 32/64 conversion */
				err = sys_listen(fd, req->args[2]);
				break;
			case SO_RECV:
				/* FIXME: 32/64 conversion */
				err = sys_recv(fd, (void *) req->args[2], req->args[3],
					       req->args[4]);
				break;
			case SO_RECVFROM:
				/* FIXME: 32/64 conversion */
				err = sys_recvfrom(fd, (void *) req->args[2], req->args[3],
						   req->args[4], (struct sockaddr *) req->args[5],
						   (int *) req->args[6]);
				break;
			case SO_SEND:
				/* FIXME: 32/64 conversion */
				err = sys_send(fd, (void *) req->args[2], req->args[3],
					       req->args[4]);
				break;
			case SO_SENDTO:
				/* FIXME: 32/64 conversion */
				err = sys_sendto(fd, (void *) req->args[2], req->args[3],
						 req->args[4], (struct sockaddr *) req->args[5],
						 req->args[6]);
				break;
			case SO_SETSOCKOPT:
				/* FIXME: 32/64 conversion */
				err = sys_setsockopt(fd, req->args[2], req->args[3],
						     (char *) req->args[4], req->args[5]);
				break;
			case SO_SHUTDOWN:
				/* FIXME: 32/64 conversion */
				err = sys_shutdown(fd, req->args[2]);
				break;
			case SO_RECVMSG:
				/* FIXME: 32/64 conversion */
				err = sys_recvmsg(fd, (struct msghdr *) req->args[2], req->args[3]);
				break;
			case SO_SENDMSG:
				/* FIXME: 32/64 conversion */
				err = sys_sendmsg(fd, (struct msghdr *) req->args[2], req->args[3]);
				break;
			}
#endif
#if 0
		} else {
			/* In this case, we do not have a real socket, but have a TPI stream from
			   the operating system's perspective, and we will directly call the
			   associated TPI routine. */
			switch (cmd) {
			case SO_ACCEPT:
				/* FIXME: 32/64 conversion */
				err = tpi_accept(fd, (struct sockaddr *) req->args[2],
						 req->args[3]);
				break;
			case SO_BIND:
				/* FIXME: 32/64 conversion */
				err = tpi_bind(fd, (struct sockaddr *) req->args[2], req->args[3]);
				break;
			case SO_CONNECT:
				/* FIXME: 32/64 conversion */
				err = tpi_connect(fd, (struct sockaddr *) req->args[2],
						  req->args[3]);
				break;
			case SO_GETPEERNAME:
				/* FIXME: 32/64 conversion */
				err = tpi_getpeername(fd, (struct sockaddr *) req->args[2],
						      (int *) req->args[3]);
				break;
			case SO_GETSOCKNAME:
				/* FIXME: 32/64 conversion */
				err = tpi_getsockname(fd, (struct sockaddr *) req->args[2],
						      (int *) req->args[3]);
				break;
			case SO_GETSOCKOPT:
				/* FIXME: 32/64 conversion */
				err = tpi_getsockopt(fd, req->args[2], req->args[3],
						     (char *) req->args[4], (int *) req->args[5]);
				break;
			case SO_LISTEN:
				/* FIXME: 32/64 conversion */
				err = tpi_listen(fd, req->args[2]);
				break;
			case SO_RECV:
				/* FIXME: 32/64 conversion */
				err = tpi_recv(fd, (void *) req->args[2], req->args[3],
					       req->args[4]);
				break;
			case SO_RECVFROM:
				/* FIXME: 32/64 conversion */
				err = tpi_recvfrom(fd, (void *) req->args[2], req->args[3],
						   req->args[4], (struct sockaddr *) req->args[5],
						   (int *) req->args[6]);
				break;
			case SO_SEND:
				/* FIXME: 32/64 conversion */
				err = tpi_send(fd, (void *) req->args[2], req->args[3],
					       req->args[4]);
				break;
			case SO_SENDTO:
				/* FIXME: 32/64 conversion */
				err = tpi_sendto(fd, (void *) req->args[2], req->args[3],
						 req->args[4], (struct sockaddr *) req->args[5],
						 req->args[6]);
				break;
			case SO_SETSOCKOPT:
				/* FIXME: 32/64 conversion */
				err = tpi_setsockopt(fd, req->args[2], req->args[3],
						     (char *) req->args[4], req->args[5]);
				break;
			case SO_SHUTDOWN:
				/* FIXME: 32/64 conversion */
				err = tpi_shutdown(fd, req->args[2]);
				break;
			case SO_RECVMSG:
				/* FIXME: 32/64 conversion */
				err = tpi_recvmsg(fd, (struct msghdr *) req->args[2], req->args[3]);
				break;
			case SO_SENDMSG:
				/* FIXME: 32/64 conversion */
				err = tpi_sendmsg(fd, (struct msghdr *) req->args[2], req->args[3]);
				break;
			}
		}
#endif
	}
	if ((1 << cmd) & ((1 << SO_SOCKET) | (1 << SO_SOCKPAIR) | (1 << SO_SELECT) |
			  (1 << SO_GETIPDOMAIN) | (1 << SO_SETIPDOMAIN) | (1 << SO_ADJTIME) |
			  (1 << SO_SETREUID) | (1 << SO_SETREGID) | (1 << SO_GETTIME) |
			  (1 << SO_SETTIME) | (1 << SO_GETITIMER) | (1 << SO_SETITIMER))) {
		/* These are BSD compatibiltiy functions and are how we create sockets in the first
		   place.  The BSD compatibility functions all have system calls in Linux, but we
		   provide them for backward compatibility (to what!?). */
#if 0
		switch (cmd) {
		case SO_SOCKET:
			/* FIXME: 32/64 conversion */
			/* XXX: don't think so..., after checking for a stream */
			err = sys_socket(req->args[1], req->args[2], req->args[3]);
			break;
		case SO_SOCKPAIR:
			/* FIXME: 32/64 conversion */
			/* XXX: don't think so..., after checking for a stream */
			err = sys_socketpair(req->args[1], req->args[2], req->args[3],
					     (int *) req->args[4]);
			err = -EOPNOTSUPP;
			break;
		case SO_SELECT:
			/* FIXME: 32/64 conversion */
			err = sys_select(req->args[1], (fd_set *) req->args[2],
					 (fd_set *) req->args[3], (fd_set *) req->args[4],
					 (struct timeval *) req->args[5]);
			break;
		case SO_GETIPDOMAIN:
			/* FIXME: 32/64 conversion */
			todo(("Process SO_GETIPDOMAIN for compatibility.\n"));
			/* does not exist in Linux, need to use sys_newuname and copy the
			   domainname portion */
			err = -ENOSYS;
			break;
		case SO_SETIPDOMAIN:
			/* FIXME: 32/64 conversion */
			err = sys_setdomainname((char *) req->args[1], req->args[2]);
			break;
		case SO_ADJTIME:
			/* FIXME: 32/64 conversion */
			err = sys_admtimex((struct timex *) req->args[1]);
			break;
		case SO_SETREUID:
			/* FIXME: 32/64 conversion */
			err = sys_setreuid(req->args[1], req->args[2]);
			break;
		case SO_SETREGID:
			/* FIXME: 32/64 conversion */
			err = sys_setregid(req->args[1], req->args[2]);
			break;
		case SO_GETTIME:
			/* FIXME: 32/64 conversion */
			err = sys_gettimeofday((struct timeval *) req->args[1],
					       (struct timezone *) req->args[2]);
			break;
		case SO_SETTIME:
			/* FIXME: 32/64 conversion */
			err = sys_settimeofday((struct timeval *) req->args[1],
					       (struct timezone *) req->args[2]);
			break;
		case SO_GETITIMER:
			/* FIXME: 32/64 conversion */
			err = sys_getitimer(req->args[1], (struct itimerval *) req->args[2]);
			break;
		case SO_SETITIMER:
			/* FIXME: 32/64 conversion */
			err = sys_getitimer(req->args[1], (struct itimerval *) req->args[2],
					    (struct itimerval *) req->args[3]);
			break;
		}
#endif
	}

	return (err);
}
Exemple #14
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; */
}
Exemple #15
0
BOOL receive_local_message( char *buffer, int buffer_len, int timeout)
{
    struct sockaddr_in from;
    socklen_t fromlen = sizeof(from);
    int32 msg_len = 0;
    fd_set fds;
    int selrtn = -1;

    FD_ZERO(&fds);
    smb_read_error = 0;

    /*
     * We need to check for kernel oplocks before going into the select
     * here, as the EINTR generated by the linux kernel oplock may have
     * already been eaten. JRA.
     */

    if (koplocks && koplocks->msg_waiting(&fds)) {
        return koplocks->receive_message(&fds, buffer, buffer_len);
    }

    while (timeout > 0 && selrtn == -1) {
        struct timeval to;
        int maxfd = oplock_sock;
        time_t starttime = time(NULL);

        FD_ZERO(&fds);
        maxfd = setup_oplock_select_set(&fds);

        to.tv_sec = timeout / 1000;
        to.tv_usec = (timeout % 1000) * 1000;

        DEBUG(5,("receive_local_message: doing select with timeout of %d ms\n", timeout));

        selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to);

        if (selrtn == -1 && errno == EINTR) {

            /* could be a kernel oplock interrupt */
            if (koplocks && koplocks->msg_waiting(&fds)) {
                return koplocks->receive_message(&fds, buffer, buffer_len);
            }

            /*
             * Linux 2.0.x seems to have a bug in that
             * it can return -1, EINTR with a timeout of zero.
             * Make sure we bail out here with a read timeout
             * if we got EINTR on a timeout of 1 or less.
             */

            if (timeout <= 1) {
                smb_read_error = READ_TIMEOUT;
                return False;
            }

            /* Not a kernel interrupt - could be a SIGUSR1 message. We must restart. */
            /* We need to decrement the timeout here. */
            timeout -= ((time(NULL) - starttime)*1000);
            if (timeout < 0)
                timeout = 1;

            DEBUG(5,("receive_local_message: EINTR : new timeout %d ms\n", timeout));
            continue;
        }

        /* Check if error */
        if(selrtn == -1) {
            /* something is wrong. Maybe the socket is dead? */
            smb_read_error = READ_ERROR;
            return False;
        }

        /* Did we timeout ? */
        if (selrtn == 0) {
            smb_read_error = READ_TIMEOUT;
            return False;
        }
    }

    if (koplocks && koplocks->msg_waiting(&fds)) {
        return koplocks->receive_message(&fds, buffer, buffer_len);
    }

    if (!FD_ISSET(oplock_sock, &fds))
        return False;

    /*
     * From here down we deal with the smbd <--> smbd
     * oplock break protocol only.
     */

    /*
     * Read a loopback udp message.
     */
    msg_len = sys_recvfrom(oplock_sock, &buffer[OPBRK_CMD_HEADER_LEN],
                           buffer_len - OPBRK_CMD_HEADER_LEN, 0, (struct sockaddr *)&from, &fromlen);

    if(msg_len < 0) {
        DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
        return False;
    }

    /* Validate message length. */
    if(msg_len > (buffer_len - OPBRK_CMD_HEADER_LEN)) {
        DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n", msg_len,
                 buffer_len  - OPBRK_CMD_HEADER_LEN));
        return False;
    }

    /* Validate message from address (must be localhost). */
    if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
        DEBUG(0,("receive_local_message: invalid 'from' address \
(was %lx should be 127.0.0.1)\n", (long)from.sin_addr.s_addr));
        return False;
    }
Exemple #16
0
int do_smb_browse(void)
{
	int mdnsfd;
	int fdsetsz;
	int ret;
	fd_set *fdset = NULL;
	struct mdns_browse_state bstate;
	struct mdns_smbsrv_result *resptr;
	struct timeval tv;
	DNSServiceRef mdns_conn_sdref = NULL;
	DNSServiceErrorType err;

	TALLOC_CTX * ctx = talloc_stackframe();

	ZERO_STRUCT(bstate);

	err = DNSServiceBrowse(&mdns_conn_sdref, 0, 0, "_smb._tcp", "",
			do_smb_browse_reply, &bstate);

	if (err != kDNSServiceErr_NoError) {
		d_printf("Error connecting to the Multicast DNS daemon\n");
		TALLOC_FREE(ctx);
		return 1;
	}

	mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref);
	for (;;)  {
		if (fdset != NULL) {
			TALLOC_FREE(fdset);
		}

		fdsetsz = howmany(mdnsfd + 1, NFDBITS) * sizeof(fd_mask);
		fdset = TALLOC_ZERO(ctx, fdsetsz);
		FD_SET(mdnsfd, fdset);

		tv.tv_sec = 1;
		tv.tv_usec = 0;

		/* Wait until response received from mDNS daemon */
		ret = sys_select(mdnsfd + 1, fdset, NULL, NULL, &tv);
		if (ret <= 0 && errno != EINTR) {
			break;
		}

		if (FD_ISSET(mdnsfd, fdset)) {
			/* Invoke callback function */
			if (DNSServiceProcessResult(mdns_conn_sdref)) {
				break;
			}
			if (bstate.browseDone) {
				break;
			}
		}
	}

	DNSServiceRefDeallocate(mdns_conn_sdref);

	if (bstate.listhead != NULL) {
		resptr = bstate.listhead;
		while (resptr != NULL) {
			struct mdns_smbsrv_result *oldresptr;
			oldresptr = resptr;

			/* Resolve smb service instance */
			do_smb_resolve(resptr);

			resptr = resptr->nextResult;
		}
	}

	TALLOC_FREE(ctx);
	return 0;
}
Exemple #17
0
asmlinkage int sunos_select(int width, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
{
	/* SunOS binaries expect that select won't change the tvp contents */
	current->personality |= STICKY_TIMEOUTS;
	return sys_select (width, inp, outp, exp, tvp);
}
Exemple #18
0
BOOL receive_local_message(fd_set * fds, char *buffer, int buffer_len,
			   int timeout)
{
	struct sockaddr_in from;
	int fromlen = sizeof(from);
	int32 msg_len = 0;

	smb_read_error = 0;

	if (timeout != 0)
	{
		struct timeval to;
		int selrtn;
		int maxfd = oplock_sock;

		if (koplocks && koplocks->notification_fd != -1)
		{
			FD_SET(koplocks->notification_fd, fds);
			maxfd = MAX(maxfd, koplocks->notification_fd);
		}

		to.tv_sec = timeout / 1000;
		to.tv_usec = (timeout % 1000) * 1000;

		selrtn = sys_select(maxfd + 1, fds, &to);

		if (selrtn == -1 && errno == EINTR)
		{
			/* could be a kernel oplock interrupt */
			if (koplocks && koplocks->msg_waiting(fds))
			{
				return koplocks->receive_message(fds, buffer,
								 buffer_len);
			}
		}

		/* Check if error */
		if (selrtn == -1)
		{
			/* something is wrong. Maybe the socket is dead? */
			smb_read_error = READ_ERROR;
			return False;
		}

		/* Did we timeout ? */
		if (selrtn == 0)
		{
			smb_read_error = READ_TIMEOUT;
			return False;
		}
	}

	if (koplocks && koplocks->msg_waiting(fds))
	{
		return koplocks->receive_message(fds, buffer, buffer_len);
	}

	if (!FD_ISSET(oplock_sock, fds))
		return False;

	/*
	 * From here down we deal with the smbd <--> smbd
	 * oplock break protocol only.
	 */

	/*
	 * Read a loopback udp message.
	 */
	msg_len = recvfrom(oplock_sock, &buffer[OPBRK_CMD_HEADER_LEN],
			   buffer_len - OPBRK_CMD_HEADER_LEN, 0,
			   (struct sockaddr *)&from, &fromlen);

	if (msg_len < 0)
	{
		DEBUG(0,
		      ("receive_local_message. Error in recvfrom. (%s).\n",
		       strerror(errno)));
		return False;
	}

	/* Validate message length. */
	if (msg_len > (buffer_len - OPBRK_CMD_HEADER_LEN))
	{
		DEBUG(0,
		      ("receive_local_message: invalid msg_len (%d) max can be %d\n",
		       msg_len, buffer_len - OPBRK_CMD_HEADER_LEN));
		return False;
	}

	/* Validate message from address (must be localhost). */
	if (from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
	{
		DEBUG(0, ("receive_local_message: invalid 'from' address \
(was %lx should be 127.0.0.1\n", (long)from.sin_addr.s_addr));
		return False;
	}
Exemple #19
0
static void process_loop(void)
{
	/* We'll be doing this a lot */

	while (1) {
		struct winbindd_cli_state *state;
		fd_set r_fds, w_fds;
		int maxfd, listen_sock, listen_priv_sock, selret;
		struct timeval timeout;

		/* Handle messages */

		message_dispatch();

		/* refresh the trusted domain cache */
		   
		rescan_trusted_domains();

		/* Free up temporary memory */

		lp_talloc_free();
		main_loop_talloc_free();

		/* Initialise fd lists for select() */

		listen_sock = open_winbindd_socket();
		listen_priv_sock = open_winbindd_priv_socket();

		if (listen_sock == -1 || listen_priv_sock == -1) {
			perror("open_winbind_socket");
			exit(1);
		}

		maxfd = MAX(listen_sock, listen_priv_sock);

		FD_ZERO(&r_fds);
		FD_ZERO(&w_fds);
		FD_SET(listen_sock, &r_fds);
		FD_SET(listen_priv_sock, &r_fds);

		timeout.tv_sec = WINBINDD_ESTABLISH_LOOP;
		timeout.tv_usec = 0;

		if (opt_dual_daemon) {
			maxfd = dual_select_setup(&w_fds, maxfd);
		}

		/* Set up client readers and writers */

		state = winbindd_client_list();

		while (state) {

			/* Dispose of client connection if it is marked as 
			   finished */ 

			if (state->finished) {
				struct winbindd_cli_state *next = state->next;

				remove_client(state);
				state = next;
				continue;
			}

			/* Select requires we know the highest fd used */

			if (state->sock > maxfd)
				maxfd = state->sock;

			/* Add fd for reading */

			if (state->read_buf_len != sizeof(state->request))
				FD_SET(state->sock, &r_fds);

			/* Add fd for writing */

			if (state->write_buf_len)
				FD_SET(state->sock, &w_fds);

			state = state->next;
		}

		/* Call select */
        
		selret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);

		if (selret == 0)
			continue;

		if ((selret == -1 && errno != EINTR) || selret == 0) {

			/* Select error, something is badly wrong */

			perror("select");
			exit(1);
		}

		/* Create a new connection if listen_sock readable */

		if (selret > 0) {

			if (opt_dual_daemon) {
				dual_select(&w_fds);
			}

			if (FD_ISSET(listen_sock, &r_fds)) {
				while (winbindd_num_clients() > WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
					DEBUG(5,("winbindd: Exceeding %d client connections, removing idle connection.\n",
						WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
					if (!remove_idle_client()) {
						DEBUG(0,("winbindd: Exceeding %d client connections, no idle connection found\n",
							WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
						break;
					}
				}
				/* new, non-privileged connection */
				new_connection(listen_sock, False);
			}
            
			if (FD_ISSET(listen_priv_sock, &r_fds)) {
				while (winbindd_num_clients() > WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
					DEBUG(5,("winbindd: Exceeding %d client connections, removing idle connection.\n",
						WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
					if (!remove_idle_client()) {
						DEBUG(0,("winbindd: Exceeding %d client connections, no idle connection found\n",
							WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
						break;
					}
				}
				/* new, privileged connection */
				new_connection(listen_priv_sock, True);
			}
            
			/* Process activity on client connections */
            
			for (state = winbindd_client_list(); state; 
			     state = state->next) {
                
				/* Data available for reading */
                
				if (FD_ISSET(state->sock, &r_fds)) {
                    
					/* Read data */
                    
					winbind_client_read(state);

					/* 
					 * If we have the start of a
					 * packet, then check the
					 * length field to make sure
					 * the client's not talking
					 * Mock Swedish.
					 */

					if (state->read_buf_len >= sizeof(uint32)
					    && *(uint32 *) &state->request != sizeof(state->request)) {
						DEBUG(0,("process_loop: Invalid request size from pid %lu: %d bytes sent, should be %ld\n",
								(unsigned long)state->request.pid, *(uint32 *) &state->request, (unsigned long)sizeof(state->request)));
						DEBUGADD(0, ("This usually means that you are running old wbinfo, pam_winbind or libnss_winbind clients\n"));

						remove_client(state);
						break;
					}

					/* A request packet might be 
					   complete */
                    
					if (state->read_buf_len == 
					    sizeof(state->request)) {
						winbind_process_packet(state);
					}
				}
                
				/* Data available for writing */
                
				if (FD_ISSET(state->sock, &w_fds))
					client_write(state);
			}
		}

#if 0
		winbindd_check_cache_size(time(NULL));
#endif

		/* Check signal handling things */

		if (do_sigterm)
			terminate();

		if (do_sighup) {

			DEBUG(3, ("got SIGHUP\n"));

			msg_reload_services(MSG_SMB_CONF_UPDATED, (pid_t) 0, NULL, 0);
			do_sighup = False;
		}

		if (do_sigusr2) {
			print_winbindd_status();
			do_sigusr2 = False;
		}
	}
}