Example #1
0
/*
 * Create an rpc client attached to the mount daemon.
 */
CLIENT *
get_mount_client(char *host, struct sockaddr_in *unused_sin, struct timeval *tv, int *sock, u_long mnt_version)
{
  CLIENT *client;
  struct netbuf nb;
  struct netconfig *nc = NULL;
  struct sockaddr_in sin;

  nb.maxlen = sizeof(sin);
  nb.buf = (char *) &sin;

  /*
   * First try a TCP handler
   */

  /*
   * Find mountd address on TCP
   */
  if ((nc = getnetconfigent(NC_TCP)) == NULL) {
    plog(XLOG_ERROR, "getnetconfig for tcp failed: %s", nc_sperror());
    goto tryudp;
  }
  if (!rpcb_getaddr(MOUNTPROG, mnt_version, nc, &nb, host)) {
    /*
     * don't print error messages here, since mountd might legitimately
     * serve udp only
     */
    goto tryudp;
  }
  /*
   * Create privileged TCP socket
   */
  *sock = t_open(nc->nc_device, O_RDWR, 0);

  if (*sock < 0) {
    plog(XLOG_ERROR, "t_open %s: %m", nc->nc_device);
    goto tryudp;
  }
  if (bind_resv_port(*sock, (u_short *) NULL) < 0)
    plog(XLOG_ERROR, "couldn't bind mountd socket to privileged port");

  if ((client = clnt_vc_create(*sock, &nb, MOUNTPROG, mnt_version, 0, 0))
      == (CLIENT *) NULL) {
    plog(XLOG_ERROR, "clnt_vc_create failed");
    t_close(*sock);
    goto tryudp;
  }
  /* tcp succeeded */
  dlog("get_mount_client: using tcp, port %d", sin.sin_port);
  if (nc)
    freenetconfigent(nc);
  return client;

tryudp:
  /* first free possibly previously allocated netconfig entry */
  if (nc)
    freenetconfigent(nc);

  /*
   * TCP failed so try UDP
   */

  /*
   * Find mountd address on UDP
   */
  if ((nc = getnetconfigent(NC_UDP)) == NULL) {
    plog(XLOG_ERROR, "getnetconfig for udp failed: %s", nc_sperror());
    goto badout;
  }
  if (!rpcb_getaddr(MOUNTPROG, mnt_version, nc, &nb, host)) {
    plog(XLOG_ERROR, "%s",
	 clnt_spcreateerror("couldn't get mountd address on udp"));
    goto badout;
  }
  /*
   * Create privileged UDP socket
   */
  *sock = t_open(nc->nc_device, O_RDWR, 0);

  if (*sock < 0) {
    plog(XLOG_ERROR, "t_open %s: %m", nc->nc_device);
    goto badout;		/* neither tcp not udp succeeded */
  }
  if (bind_resv_port(*sock, (u_short *) NULL) < 0)
    plog(XLOG_ERROR, "couldn't bind mountd socket to privileged port");

  if ((client = clnt_dg_create(*sock, &nb, MOUNTPROG, mnt_version, 0, 0))
      == (CLIENT *) NULL) {
    plog(XLOG_ERROR, "clnt_dg_create failed");
    t_close(*sock);
    goto badout;		/* neither tcp not udp succeeded */
  }
  if (clnt_control(client, CLSET_RETRY_TIMEOUT, (char *) tv) == FALSE) {
    plog(XLOG_ERROR, "clnt_control CLSET_RETRY_TIMEOUT for udp failed");
    clnt_destroy(client);
    goto badout;		/* neither tcp not udp succeeded */
  }
  /* udp succeeded */
  dlog("get_mount_client: using udp, port %d", sin.sin_port);
  return client;

badout:
  /* failed */
  if (nc)
    freenetconfigent(nc);
  return NULL;
}
Example #2
0
int rpcclt_initialize(rpcclt_t * client, const char *host, unsigned long prog,
        unsigned long vers, unsigned int sendsz,
        unsigned int recvsz, uint32_t port_num, struct timeval timeout) {
    int status = -1;
    struct sockaddr_in server;
    struct hostent *hp;
    int one = 1;
    int port = 0;
    DEBUG_FUNCTION;


    if (client->sock >= 0) {
      /* 
      ** socket reference should be set to -1 at initialization or when released
      ** if rpcclt_initialize is called with socket not set to -1 we may be loosing
      ** a socket
      */
      warning("rpcclt_initialize - dest %s:%d - prg 0x%8.8x - socket %d may be lost", 
              host,port_num,(unsigned int)prog,client->sock);
    }
    client->client = 0;
    client->sock = -1;
    server.sin_family = AF_INET;

    if ((hp = gethostbyname(host)) == 0) {
        severe("gethostbyname failed for host : %s, %s", host,
                strerror(errno));
        goto out;
    }

    bcopy((char *) hp->h_addr, (char *) &server.sin_addr, hp->h_length);

    if (port_num == 0) {
        if ((port = pmap_getport(&server, prog, vers, IPPROTO_TCP)) == 0) {
            warning("pmap_getport failed%s", clnt_spcreateerror(""));
            errno = EPROTO;
            goto out;
        }
        server.sin_port = htons(port);
    } else {
        server.sin_port = htons(port_num);
    }

    if ((client->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        goto out;
    }
    // Allows other sockets to bind() to this port, unless there is an active
    // listening socket bound to the port already.
    if (setsockopt
            (client->sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
            sizeof (int)) < 0) {
        goto out;
    }
    // Set a timeout value for output operations
    if (setsockopt
            (client->sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout,
            sizeof (timeout)) < 0) {
        goto out;
    }
    // This option specifies what should happen when the socket
    // of a type that promises reliable delivery still has untransmitted
    // messages when it is closed
    struct linger linger;
    linger.l_onoff = 1; //0 = off (l_linger ignored), nonzero = on
    linger.l_linger = 0; //0 = discard data, nonzero = wait for data sent
    if (setsockopt
            (client->sock, SOL_SOCKET, SO_LINGER, &linger, sizeof (linger)) < 0) {
        goto out;
    }
    // If set, disable the Nagle algorithm. This means that segments are always
    // sent as soon as possible, even if there is only a small amount of data.
    if (setsockopt
            (client->sock, SOL_TCP, TCP_NODELAY, (char *) &one,
            sizeof (int)) < 0) {
        goto out;
    }

    if ((client->sock < 0) ||
            (connect(client->sock, (struct sockaddr *) &server, sizeof (server)) <
            0)) {
        status = -1;
        goto out;
    }

    if ((client->client =
            clnttcp_create(&server, prog, vers, &client->sock, sendsz,
            recvsz)) == NULL) {
        errno = EPROTO;
        goto out;
    }
    // Set TIMEOUT for this connection
    clnt_control(client->client, CLSET_TIMEOUT, (char *) &timeout);

    status = 0;
out:
    if (status != 0)
        rpcclt_release(client);
    return status;
}
static int
yppasswd_remote(ypclnt_t *ypclnt, const struct passwd *pwd, const char *passwd)
{
	struct yppasswd yppwd;
	struct rpc_err rpcerr;
	CLIENT *clnt = NULL;
	int ret, *result;

	/* fill the yppasswd structure */
	memset(&yppwd, 0, sizeof yppwd);
	yppwd.newpw.pw_uid = pwd->pw_uid;
	yppwd.newpw.pw_gid = pwd->pw_gid;
	if ((yppwd.newpw.pw_name = strdup(pwd->pw_name)) == NULL ||
	    (yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd)) == NULL ||
	    (yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos)) == NULL ||
	    (yppwd.newpw.pw_dir = strdup(pwd->pw_dir)) == NULL ||
	    (yppwd.newpw.pw_shell = strdup(pwd->pw_shell)) == NULL ||
	    (yppwd.oldpass = strdup(passwd ? passwd : "")) == NULL) {
		ypclnt_error(ypclnt, __func__, "%s", strerror(errno));
		ret = -1;
		goto done;
	}

	/* connect to rpc.yppasswdd */
	clnt = clnt_create(ypclnt->server, YPPASSWDPROG, YPPASSWDVERS, "udp");
	if (clnt == NULL) {
		ypclnt_error(ypclnt, __func__,
		    "failed to connect to rpc.yppasswdd: %s",
		    clnt_spcreateerror(ypclnt->server));
		ret = -1;
		goto done;
	}
	clnt->cl_auth = authunix_create_default();

	/* request the update */
	result = yppasswdproc_update_1(&yppwd, clnt);

	/* check for RPC errors */
	clnt_geterr(clnt, &rpcerr);
	if (rpcerr.re_status != RPC_SUCCESS) {
		ypclnt_error(ypclnt, __func__,
		    "NIS password update failed: %s",
		    clnt_sperror(clnt, ypclnt->server));
		ret = -1;
		goto done;
	}

	/* check the result of the update */
	if (result == NULL || *result != 0) {
		ypclnt_error(ypclnt, __func__,
		    "NIS password update failed");
		/* XXX how do we get more details? */
		ret = -1;
		goto done;
	}

	ypclnt_error(ypclnt, NULL, NULL);
	ret = 0;

 done:
	if (clnt != NULL) {
		auth_destroy(clnt->cl_auth);
		clnt_destroy(clnt);
	}
	free(yppwd.newpw.pw_name);
	if (yppwd.newpw.pw_passwd != NULL) {
		memset(yppwd.newpw.pw_passwd, 0, strlen(yppwd.newpw.pw_passwd));
		free(yppwd.newpw.pw_passwd);
	}
	free(yppwd.newpw.pw_gecos);
	free(yppwd.newpw.pw_dir);
	free(yppwd.newpw.pw_shell);
	if (yppwd.oldpass != NULL) {
		memset(yppwd.oldpass, 0, strlen(yppwd.oldpass));
		free(yppwd.oldpass);
	}
	return (ret);
}
Example #4
0
void
clnt_pcreateerror(char *s)
{
	(void) fprintf(stderr,"%s",clnt_spcreateerror(s));
}
Example #5
0
int main (int argc, char *argv[])
{
	int err;
	nfs_fh3 fh;
	size_t length;
	char *fh_v;
	char *svraddr = NULL;
	CLIENT *p_clntp = NULL;
	char *fpath =NULL;
	struct hsfs_inode root;    
	struct hsfs_super super;
	struct statvfs stbuf;
	root.sb = &super;
	char *cliname = basename (argv[0]);

	if (argc <3){
		err = EINVAL;
		fprintf(stderr, "%s $svraddr $fpath.\n", cliname);
		goto exit;
	}
	svraddr = argv[1];
	fpath = argv[2];
	p_clntp = clnt_create(svraddr, NFS_PROGRAM, NFS_V3,"udp");
	if (NULL == p_clntp){
		fprintf(stderr, "%s: Create handle to RPC server"\
				"(%s, %u, %u) failed: (%s).\n",cliname,
				svraddr, NFSPROC3_FSSTAT, NFS_V3,clnt_spcreateerror(cliname));
		err = ENXIO;
		goto exit;

	}
	err = map_path_to_nfs3fh (svraddr, fpath, &length, &fh_v);
	if (err!= 0){
		printf("map_path_to_nfs3fh failed! err:%d\n",err);
		goto exit;
	}
	memset (&fh,0,sizeof(fh));
	fh.data.data_len=length;
	fh.data.data_val=fh_v;
	root.fh = fh;

	super.clntp = p_clntp;
	err = hsi_nfs3_statfs(&root);
	if (err){
		printf("hsi_nfs3_statfs failed! err:%d\n",err);
		goto exit;
	}
	printf ("\ttbytes=%u\n\tfbytes=%u\n\tabytes=%u\n\ttfiles=%u\n\tffiles=%u\n\tafiles=%u\n",
			root.sb->tbytes,root.sb->fbytes,root.sb->abytes,root.sb->tfiles,root.sb->ffiles,root.sb->afiles);

	err = hsi_super2statvfs (root.sb, &stbuf);
	if (err){
		goto exit;
	}
	printf ("\tf_bsize=%u\n\tf_frsize=%u\n\tf_blocks=%u\n\tf_bfree=%u\n\tf_bavail=%u\n\tf_files=%u\n",
			stbuf.f_bsize,stbuf.f_frsize,stbuf.f_blocks,stbuf.f_bfree,stbuf.f_bavail,stbuf.f_files);
	printf ("\tf_ffree=%u\n\tf_favail=%u\n\tf_fsid=%u\n\tf_flag=%u\n\tf_namemax=%u\n",
			stbuf.f_ffree,stbuf.f_favail,stbuf.f_fsid,stbuf.f_flag,stbuf.f_namemax);

exit:
	exit (err);
}
static int
yppasswd_local(ypclnt_t *ypclnt, const struct passwd *pwd)
{
	struct master_yppasswd yppwd;
	struct rpc_err rpcerr;
	struct netconfig *nc = NULL;
	void *localhandle = NULL;
	CLIENT *clnt = NULL;
	int ret, *result;

	/* fill the master_yppasswd structure */
	memset(&yppwd, 0, sizeof yppwd);
	yppwd.newpw.pw_uid = pwd->pw_uid;
	yppwd.newpw.pw_gid = pwd->pw_gid;
	yppwd.newpw.pw_change = pwd->pw_change;
	yppwd.newpw.pw_expire = pwd->pw_expire;
	yppwd.newpw.pw_fields = pwd->pw_fields;
	yppwd.oldpass = strdup("");
	yppwd.domain = strdup(ypclnt->domain);
	if ((yppwd.newpw.pw_name = strdup(pwd->pw_name)) == NULL ||
	    (yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd)) == NULL ||
	    (yppwd.newpw.pw_class = strdup(pwd->pw_class)) == NULL ||
	    (yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos)) == NULL ||
	    (yppwd.newpw.pw_dir = strdup(pwd->pw_dir)) == NULL ||
	    (yppwd.newpw.pw_shell = strdup(pwd->pw_shell)) == NULL) {
		ypclnt_error(ypclnt, __func__, "%s", strerror(errno));
		ret = -1;
		goto done;
	}

	/* connect to rpc.yppasswdd */
	localhandle = setnetconfig();
	while ((nc = getnetconfig(localhandle)) != NULL) {
		if (nc->nc_protofmly != NULL &&
		    strcmp(nc->nc_protofmly, NC_LOOPBACK) == 0)
			break;
	}
	if (nc == NULL) {
		ypclnt_error(ypclnt, __func__,
		    "getnetconfig: %s", nc_sperror());
		ret = -1;
		goto done;
	}
	if ((clnt = clnt_tp_create(NULL, MASTER_YPPASSWDPROG,
	    MASTER_YPPASSWDVERS, nc)) == NULL) {
		ypclnt_error(ypclnt, __func__,
		    "failed to connect to rpc.yppasswdd: %s",
		    clnt_spcreateerror(ypclnt->server));
		ret = -1;
		goto done;
	}
	clnt->cl_auth = authunix_create_default();

	/* request the update */
	result = yppasswdproc_update_master_1(&yppwd, clnt);

	/* check for RPC errors */
	clnt_geterr(clnt, &rpcerr);
	if (rpcerr.re_status != RPC_SUCCESS) {
		ypclnt_error(ypclnt, __func__,
		    "NIS password update failed: %s",
		    clnt_sperror(clnt, ypclnt->server));
		ret = -1;
		goto done;
	}

	/* check the result of the update */
	if (result == NULL || *result != 0) {
		ypclnt_error(ypclnt, __func__,
		    "NIS password update failed");
		/* XXX how do we get more details? */
		ret = -1;
		goto done;
	}

	ypclnt_error(ypclnt, NULL, NULL);
	ret = 0;

 done:
	if (clnt != NULL) {
		auth_destroy(clnt->cl_auth);
		clnt_destroy(clnt);
	}
	endnetconfig(localhandle);
	free(yppwd.newpw.pw_name);
	if (yppwd.newpw.pw_passwd != NULL) {
		memset(yppwd.newpw.pw_passwd, 0, strlen(yppwd.newpw.pw_passwd));
		free(yppwd.newpw.pw_passwd);
	}
	free(yppwd.newpw.pw_class);
	free(yppwd.newpw.pw_gecos);
	free(yppwd.newpw.pw_dir);
	free(yppwd.newpw.pw_shell);
	if (yppwd.oldpass != NULL) {
		memset(yppwd.oldpass, 0, strlen(yppwd.oldpass));
		free(yppwd.oldpass);
	}
	return (ret);
}
Example #7
0
/*
 * Create an RPC connection and establish an authenticated
 * gss context with a server.
 */
static int
create_auth_rpc_client(struct clnt_info *clp,
		       char *tgtname,
		       CLIENT **clnt_return,
		       AUTH **auth_return,
		       uid_t uid,
		       int authtype,
		       gss_cred_id_t cred)
{
	CLIENT			*rpc_clnt = NULL;
	struct rpc_gss_sec	sec;
	AUTH			*auth = NULL;
	int			retval = -1;
	OM_uint32		min_stat;
	char			rpc_errmsg[1024];
	int			protocol;
	struct timeval	timeout;
	struct sockaddr		*addr = (struct sockaddr *) &clp->addr;
	socklen_t		salen;

	sec.qop = GSS_C_QOP_DEFAULT;
	sec.svc = RPCSEC_GSS_SVC_NONE;
	sec.cred = cred;
	sec.req_flags = 0;
	if (authtype == AUTHTYPE_KRB5) {
		sec.mech = (gss_OID)&krb5oid;
		sec.req_flags = GSS_C_MUTUAL_FLAG;
	}
	else {
		printerr(0, "ERROR: Invalid authentication type (%d) "
			"in create_auth_rpc_client\n", authtype);
		goto out_fail;
	}


	if (authtype == AUTHTYPE_KRB5) {
#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
		/*
		 * Do this before creating rpc connection since we won't need
		 * rpc connection if it fails!
		 */
		if (limit_krb5_enctypes(&sec)) {
			printerr(1, "WARNING: Failed while limiting krb5 "
				    "encryption types for user with uid %d\n",
				 uid);
			goto out_fail;
		}
#endif
	}

	/* create an rpc connection to the nfs server */

	printerr(2, "creating %s client for server %s\n", clp->protocol,
			clp->servername);

	protocol = IPPROTO_TCP;
	if ((strcmp(clp->protocol, "udp")) == 0)
		protocol = IPPROTO_UDP;

	switch (addr->sa_family) {
	case AF_INET:
		salen = sizeof(struct sockaddr_in);
		break;
#ifdef IPV6_SUPPORTED
	case AF_INET6:
		salen = sizeof(struct sockaddr_in6);
		break;
#endif /* IPV6_SUPPORTED */
	default:
		printerr(1, "ERROR: Unknown address family %d\n",
			 addr->sa_family);
		goto out_fail;
	}

	if (!populate_port(addr, salen, clp->prog, clp->vers, protocol))
		goto out_fail;

	/* set the timeout according to the requested valued */
	timeout.tv_sec = (long) rpc_timeout;
	timeout.tv_usec = (long) 0;

	rpc_clnt = nfs_get_rpcclient(addr, salen, protocol, clp->prog,
				     clp->vers, &timeout);
	if (!rpc_clnt) {
		snprintf(rpc_errmsg, sizeof(rpc_errmsg),
			 "WARNING: can't create %s rpc_clnt to server %s for "
			 "user with uid %d",
			 protocol == IPPROTO_TCP ? "tcp" : "udp",
			 clp->servername, uid);
		printerr(0, "%s\n",
			 clnt_spcreateerror(rpc_errmsg));
		goto out_fail;
	}
	if (!tgtname)
		tgtname = clp->servicename;

	printerr(2, "creating context with server %s\n", tgtname);
	auth = authgss_create_default(rpc_clnt, tgtname, &sec);
	if (!auth) {
		/* Our caller should print appropriate message */
		printerr(1, "WARNING: Failed to create krb5 context for "
			    "user with uid %d for server %s\n",
			 uid, tgtname);
		goto out_fail;
	}

	/* Success !!! */
	rpc_clnt->cl_auth = auth;
	*clnt_return = rpc_clnt;
	*auth_return = auth;
	retval = 0;

  out:
	if (sec.cred != GSS_C_NO_CREDENTIAL)
		gss_release_cred(&min_stat, &sec.cred);
	return retval;

  out_fail:
	/* Only destroy here if failure.  Otherwise, caller is responsible */
	if (rpc_clnt) clnt_destroy(rpc_clnt);

	goto out;
}
Example #8
0
/*
 * NFS stuff and unmount(2) call
 */
int
umountfs(struct statfs *sfs)
{
	char fsidbuf[64];
	enum clnt_stat clnt_stat;
	struct timeval try;
	struct addrinfo *ai, hints;
	int do_rpc;
	CLIENT *clp;
	char *nfsdirname, *orignfsdirname;
	char *hostp, *delimp;

	ai = NULL;
	do_rpc = 0;
	hostp = NULL;
	nfsdirname = delimp = orignfsdirname = NULL;
	memset(&hints, 0, sizeof hints);

	if (strcmp(sfs->f_fstypename, "nfs") == 0) {
		if ((nfsdirname = strdup(sfs->f_mntfromname)) == NULL)
			err(1, "strdup");
		orignfsdirname = nfsdirname;
		if (*nfsdirname == '[' &&
		    (delimp = strchr(nfsdirname + 1, ']')) != NULL &&
		    *(delimp + 1) == ':') {
			hostp = nfsdirname + 1;
			nfsdirname = delimp + 2;
		} else if ((delimp = strrchr(nfsdirname, ':')) != NULL) {
			hostp = nfsdirname;
			nfsdirname = delimp + 1;
		}
		if (hostp != NULL) {
			*delimp = '\0';
			getaddrinfo(hostp, NULL, &hints, &ai);
			if (ai == NULL) {
				warnx("can't get net id for host");
			}
		}

		/*
		 * Check if we have to start the rpc-call later.
		 * If there are still identical nfs-names mounted,
		 * we skip the rpc-call. Obviously this has to
		 * happen before unmount(2), but it should happen
		 * after the previous namecheck.
		 * A non-NULL return means that this is the last
		 * mount from mntfromname that is still mounted.
		 */
		if (getmntentry(sfs->f_mntfromname, NULL, NULL,
		    CHECKUNIQUE) != NULL)
			do_rpc = 1;
	}

	if (!namematch(ai)) {
		free(orignfsdirname);
		return (1);
	}
	/* First try to unmount using the file system ID. */
	snprintf(fsidbuf, sizeof(fsidbuf), "FSID:%d:%d", sfs->f_fsid.val[0],
	    sfs->f_fsid.val[1]);
	if (unmount(fsidbuf, fflag | MNT_BYFSID) != 0) {
		/* XXX, non-root users get a zero fsid, so don't warn. */
		if (errno != ENOENT || sfs->f_fsid.val[0] != 0 ||
		    sfs->f_fsid.val[1] != 0)
			warn("unmount of %s failed", sfs->f_mntonname);
		if (errno != ENOENT) {
			free(orignfsdirname);
			return (1);
		}
		/* Compatibility for old kernels. */
		if (sfs->f_fsid.val[0] != 0 || sfs->f_fsid.val[1] != 0)
			warnx("retrying using path instead of file system ID");
		if (unmount(sfs->f_mntonname, fflag) != 0) {
			warn("unmount of %s failed", sfs->f_mntonname);
			free(orignfsdirname);
			return (1);
		}
	}
	/* Mark this this file system as unmounted. */
	getmntentry(NULL, NULL, &sfs->f_fsid, REMOVE);
	if (vflag)
		(void)printf("%s: unmount from %s\n", sfs->f_mntfromname,
		    sfs->f_mntonname);
	/*
	 * Report to mountd-server which nfsname
	 * has been unmounted.
	 */
	if (ai != NULL && !(fflag & MNT_FORCE) && do_rpc) {
		clp = clnt_create(hostp, MOUNTPROG, MOUNTVERS3, "udp");
		if (clp  == NULL) {
			warnx("%s: %s", hostp,
			    clnt_spcreateerror("MOUNTPROG"));
			free(orignfsdirname);
			return (1);
		}
		clp->cl_auth = authsys_create_default();
		try.tv_sec = 20;
		try.tv_usec = 0;
		clnt_stat = clnt_call(clp, MOUNTPROC_UMNT, (xdrproc_t)xdr_dir,
		    nfsdirname, (xdrproc_t)xdr_void, (caddr_t)0, try);
		if (clnt_stat != RPC_SUCCESS) {
			warnx("%s: %s", hostp,
			    clnt_sperror(clp, "RPCMNT_UMOUNT"));
			free(orignfsdirname);
			return (1);
		}
		/*
		 * Remove the unmounted entry from /var/db/mounttab.
		 */
		if (read_mtab()) {
			clean_mtab(hostp, nfsdirname, vflag);
			if(!write_mtab(vflag))
				warnx("cannot remove mounttab entry %s:%s",
				    hostp, nfsdirname);
			free_mtab();
		}
		auth_destroy(clp->cl_auth);
		clnt_destroy(clp);
	}
Example #9
0
int
main(int argc, char *argv[])
{
	spraycumul	host_stats;
	sprayarr	host_array;
	CLIENT *cl;
	int c;
	u_int i;
	u_int count = 0;
	int delay = 0;
	int length = 0;
	double xmit_time;			/* time to receive data */

	while ((c = getopt(argc, argv, "c:d:l:")) != -1) {
		switch (c) {
		case 'c':
			count = atoi(optarg);
			break;
		case 'd':
			delay = atoi(optarg);
			break;
		case 'l':
			length = atoi(optarg);
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	if (argc != 1) {
		usage();
		/* NOTREACHED */
	}


	/* Correct packet length. */
	if (length > SPRAYMAX) {
		length = SPRAYMAX;
	} else if (length < SPRAYOVERHEAD) {
		length = SPRAYOVERHEAD;
	} else {
		/* The RPC portion of the packet is a multiple of 32 bits. */
		length -= SPRAYOVERHEAD - 3;
		length &= ~3;
		length += SPRAYOVERHEAD;
	}


	/*
	 * The default value of count is the number of packets required
	 * to make the total stream size 100000 bytes.
	 */
	if (!count) {
		count = 100000 / length;
	}

	/* Initialize spray argument */
	host_array.sprayarr_len = length - SPRAYOVERHEAD;
	host_array.sprayarr_val = spray_buffer;
	

	/* create connection with server */
	cl = clnt_create(*argv, SPRAYPROG, SPRAYVERS, "udp");
	if (cl == NULL)
		errx(1, "%s", clnt_spcreateerror(""));


	/*
	 * For some strange reason, RPC 4.0 sets the default timeout, 
	 * thus timeouts specified in clnt_call() are always ignored.  
	 *
	 * The following (undocumented) hack resets the internal state
	 * of the client handle.
	 */
	clnt_control(cl, CLSET_TIMEOUT, &NO_DEFAULT);


	/* Clear server statistics */
	if (clnt_call(cl, SPRAYPROC_CLEAR, (xdrproc_t)xdr_void, NULL,
		(xdrproc_t)xdr_void, NULL, TIMEOUT) != RPC_SUCCESS)
		errx(1, "%s", clnt_sperror(cl, ""));


	/* Spray server with packets */
	printf ("sending %u packets of lnth %d to %s ...", count, length,
	    *argv);
	fflush (stdout);

	for (i = 0; i < count; i++) {
		clnt_call(cl, SPRAYPROC_SPRAY, (xdrproc_t)xdr_sprayarr,
		    &host_array, (xdrproc_t)xdr_void, NULL, ONE_WAY);

		if (delay) {
			usleep(delay);
		}
	}


	/* Collect statistics from server */
	if (clnt_call(cl, SPRAYPROC_GET, (xdrproc_t)xdr_void, NULL,
		(xdrproc_t)xdr_spraycumul, &host_stats, TIMEOUT) != RPC_SUCCESS)
		errx(1, "%s", clnt_sperror(cl, ""));

	xmit_time = host_stats.clock.sec +
			(host_stats.clock.usec / 1000000.0);

	printf ("\n\tin %.2f seconds elapsed time\n", xmit_time);


	/* report dropped packets */
	if (host_stats.counter != count) {
		int packets_dropped = count - host_stats.counter;

		printf("\t%d packets (%.2f%%) dropped\n",
			packets_dropped,
			100.0 * packets_dropped / count );
	} else {
		printf("\tno packets dropped\n");
	}

	printf("Sent:");
	print_xferstats(count, length, xmit_time);

	printf("Rcvd:");
	print_xferstats(host_stats.counter, length, xmit_time);
	
	exit (0);
}
Example #10
0
CLIENT * Creer_RPCClient( unsigned int adresse, unsigned int programme, unsigned int version, 
                          unsigned short port, int sockfd )
{
  struct sockaddr_in adresse_rpc ;
  int                sock = 0 ;
  CLIENT *           client ;
  struct timeval     intervalle ;
  int                rc ;
  struct             netconfig * nconf ;
  struct netbuf      netbuf ;
 
  memset( &adresse_rpc, 0, (size_t)sizeof( adresse_rpc ) ) ;
  adresse_rpc.sin_port        = port ;
  adresse_rpc.sin_family      = AF_INET ;
  adresse_rpc.sin_addr.s_addr = adresse ;

  sock               = sockfd ;
  intervalle.tv_sec  = TIMEOUT_SEC ;
  intervalle.tv_usec = 0 ;
  
  if( sock > 0 )
    {
      if( port > 0 )
        {
          /* En tcp, il faut que la socket soit connectee sur le service en face si on n'utilise pas RPC_ANYSOCK 
           * ATTENTION, ceci est une feature non documentee des RPC clientes (j'ai vu ca dans les sources) */
          if( connect( sock, (struct sockaddr *)&adresse_rpc, sizeof( adresse_rpc ) ) < 0 )
            fprintf( stderr, "connect impossible sur le serveur RPC\n" ) ;
        }
      else
        {
          /* Dans ce cas, on ne connait pas le port en face, donc connect impossible, on prend RPC_ANYSOCK 
           * mais uniquement apres avoir ferme la socket 'sock' qui ne sert a rien ici */
          close( sock ) ;
          sock = RPC_ANYSOCK ;
        }
    }

  /* initialisation des structures de TI-RPC */
  if( ( nconf = (struct netconfig *)getnetconfigent( "tcp" ) ) == NULL )
   {
     fprintf( stderr, "Erreur de getnetconfigent\n" ) ;
     exit( 1 ) ;
   }

  netbuf.maxlen = sizeof( adresse_rpc );
  netbuf.len    = sizeof( adresse_rpc );
  netbuf.buf    = &adresse_rpc;

  /* Creation et allocation du client */
  if( ( client = clnt_tli_create( sock, 
                                  nconf, 
                                  &netbuf, 
                                  programme,  
                                  version, 
                                  SEND_SIZE,  
                                  RECV_SIZE ) ) == NULL )
   {
      char erreur[100] ;
      char entete[100] ;
      
      sprintf( entete, "Creation RPC %d|%d|0x%x:%d|%d", programme, version, adresse, port, sock ) ;
      strcpy( erreur, clnt_spcreateerror( entete ) ) ;
          fprintf( stderr, "%s", erreur ) ;
          
          return NULL ;
    }
  
  return client ;
} /* Creer_RPCClient */
Example #11
0
main( int argc, char * argv[] ) 
{
  struct timeval   intervalle = { TIMEOUT_SEC, 0 };
  CLIENT *         client ;
  int              c ;  
  struct rpcent *  etc_rpc ;               /* pour consulter /etc/rpc ou rpc.bynumber */
  unsigned int     adresse_serveur ;  /* Au format NET */
  struct hostent * hp ;
  char             nom_exec[MAXPATHLEN] ;
  char             machine_locale[256] ;
  char *           tempo_nom_exec  = NULL ;
  unsigned int     rpc_service_num = DEFAULT_RPC_SERVICE ;
  unsigned int     rpc_version = V1 ;
  unsigned int     rpcproc = PROC_PLUS1 ;
  unsigned short   port =  ntohs( DEFAULT_PORT ) ;
  int              val = 2 ;
  int              rc ;
  char             gss_service[1024] ;


  
   /* On recupere le nom de l'executable */
  if( ( tempo_nom_exec = strrchr( argv[0], '/' ) ) != NULL )
    strcpy( (char *)nom_exec, tempo_nom_exec + 1 ) ;
  
  while( ( c = getopt( argc, argv, options ) ) != EOF )
    {
      switch( c )
        {
        case 'd':
          /* Cette option permet de recuperer un nom pour la machine distante */
          if( isalpha( *optarg ) )
            {
              /* Recuperation de l'adresse de la machine serveur */
              if( ( hp = gethostbyname( optarg ) ) == NULL )
                {
                  fprintf( stderr, "error gethostbyname errono=%u|%s\n", errno, strerror( errno ) ) ;
                  exit( 1 ) ; 
                }
              
              memcpy( &adresse_serveur, hp->h_addr, hp->h_length ) ;
            }
          else
            {
              adresse_serveur = inet_addr( optarg ) ;
            }
          break;

        case 's':
          /* Un nom ou un numero de service a ete indique */
          if( isalpha( (int)*optarg ) )
            {
              /* Ca commence pas par un chiffre donc c'est un nom service */
              if( ( etc_rpc = getrpcbyname( optarg ) ) == NULL )
                {
                  fprintf( stderr, "Impossible de resoudre le service %s\n", optarg ) ;
                }
              else
                {
                  rpc_service_num = etc_rpc->r_number ;
                }
            }
          else
            {
              /* C'est un numero de service qui est indique */
              rpc_service_num = atoi( optarg ) ;
            }
          break ;

        case 'v':
           /* numero de version */
           rpc_version = atoi( optarg ) ;
           break ;

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

        case 'h':
        case '?':
        default:
          /* Affichage de l'aide en ligne */
          fprintf( stderr, utilisation, nom_exec ) ;
          exit( 0 ) ;
          break ;
        }
    }
  
  if( ( client = Creer_RPCClient( adresse_serveur, rpc_service_num, rpc_version, port , RPC_ANYSOCK ) ) == NULL )
    {
      char erreur[100] ;
      strcpy( erreur, clnt_spcreateerror( "Creation RPC" ) ) ;
      fprintf( stderr, "Creation RPC: %s\n", erreur ) ;
      exit( 1 ) ;
    }

  client->cl_auth = authunix_create_default();

  val = 2 ;
  fprintf( stderr, "J'envoie la valeur %d\n", val ) ;
  if( ( rc = clnt_call( client, rpcproc, 
                        (xdrproc_t)xdr_int, (caddr_t)&val, 
                        (xdrproc_t)xdr_int, (caddr_t)&val, 
                        intervalle ) ) != RPC_SUCCESS )
    {
      clnt_perror( client, "appel a  FIXE_RET\n" ) ;
      exit ( 1 ) ;
    }
  fprintf( stderr, "Je recois la valeur %d\n", val ) ;

  auth_destroy( client->cl_auth ) ;  
  clnt_destroy( client ) ;
}