Example #1
0
/*
 * find the IP address that can be used to connect to the local host
 */
void
amu_get_myaddress(struct in_addr *iap, const char *preferred_localhost)
{
  int ret;
  voidp handlep;
  struct netconfig *ncp;
  struct nd_addrlist *addrs = (struct nd_addrlist *) NULL;
  struct nd_hostserv service;

  handlep = setnetconfig();
  ncp = getnetconfig(handlep);
  service.h_host = (preferred_localhost ? (char *) preferred_localhost : HOST_SELF_CONNECT);
  service.h_serv = (char *) NULL;

  ret = netdir_getbyname(ncp, &service, &addrs);

  if (ret || !addrs || addrs->n_cnt < 1) {
    plog(XLOG_FATAL, "cannot get local host address. using 127.0.0.1");
    iap->s_addr = htonl(INADDR_LOOPBACK);
  } else {
    /*
     * XXX: there may be more more than one address for this local
     * host.  Maybe something can be done with those.
     */
    struct sockaddr_in *sinp = (struct sockaddr_in *) addrs->n_addrs[0].buf;
    char dq[20];
    if (preferred_localhost)
      plog(XLOG_INFO, "localhost_address \"%s\" requested, using %s",
	   preferred_localhost, inet_dquad(dq, sizeof(dq), iap->s_addr));
    iap->s_addr = sinp->sin_addr.s_addr; /* XXX: used to be htonl() */
  }

  endnetconfig(handlep);	/* free's up internal resources too */
  netdir_free((voidp) addrs, ND_ADDRLIST);
}
Example #2
0
/*
 * find the IP address that can be used to connect to the local host
 */
void
amu_get_myaddress(struct in_addr *iap, const char *preferred_localhost)
{
  struct hostent *hp;
  char dq[20];

#ifdef DEBUG_off
#error this code is old and probably not useful any longer.
#error Erez, Jan 21, 2004.
  struct sockaddr_in sin;

  /*
   * Most modern systems should use 127.0.0.1 as the localhost address over
   * which you can do NFS mounts.  In the past we found that some NFS
   * clients may not allow mounts from localhost.  So we used
   * get_myaddress() and that seemed to work.  Alas, on some other systems,
   * get_myaddress() may return one of the interface addresses at random,
   * and thus use a less efficient IP address than 127.0.0.1.  The solution
   * is to hard-code 127.0.0.1, but still check if get_myaddress() returns a
   * different value and warn about it.
   */
  memset((char *) &sin, 0, sizeof(sin));
  get_myaddress(&sin);
  if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
    dlog("amu_get_myaddress: myaddress conflict (0x%x vs. 0x%lx)",
	 sin.sin_addr.s_addr, (u_long) htonl(INADDR_LOOPBACK));
#endif /* DEBUG_off */

  if (preferred_localhost == NULL)
    goto out;

  /* if specified preferred locahost, then try to use it */
  hp = gethostbyname(preferred_localhost);
  if (hp == NULL) {
    /* XXX: if hstrerror()/h_errno aren't portable, then need to port the next statement */
    plog(XLOG_ERROR, "Unable to resolve localhost_address \"%s\" (%s): using default",
	 preferred_localhost, hstrerror(h_errno));
    goto out;
  }
  if (hp->h_addr_list == NULL) {
    plog(XLOG_ERROR, "localhost_address \"%s\" has no IP addresses: using default",
	 preferred_localhost);
    goto out;
  }
  if (hp->h_addr_list[1] != NULL) {
    plog(XLOG_ERROR, "localhost_address \"%s\" has more than one IP addresses: using first",
	 preferred_localhost);
    goto out;
  }
  memmove((voidp) &iap->s_addr, (voidp) hp->h_addr_list[0], sizeof(iap->s_addr));
  plog(XLOG_INFO, "localhost_address \"%s\" requested, using %s",
       preferred_localhost, inet_dquad(dq, sizeof(dq), iap->s_addr));
  return;

 out:
  iap->s_addr = htonl(INADDR_LOOPBACK);
}
Example #3
0
void
nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
{
  union {
    am_nfs_fh		nfsproc_getattr_2_arg;
    nfssattrargs	nfsproc_setattr_2_arg;
    nfsdiropargs	nfsproc_lookup_2_arg;
    am_nfs_fh		nfsproc_readlink_2_arg;
    nfsreadargs		nfsproc_read_2_arg;
    nfswriteargs	nfsproc_write_2_arg;
    nfscreateargs	nfsproc_create_2_arg;
    nfsdiropargs	nfsproc_remove_2_arg;
    nfsrenameargs	nfsproc_rename_2_arg;
    nfslinkargs		nfsproc_link_2_arg;
    nfssymlinkargs	nfsproc_symlink_2_arg;
    nfscreateargs	nfsproc_mkdir_2_arg;
    nfsdiropargs	fsproc_rmdir_2_arg;
    nfsreaddirargs	nfsproc_readdir_2_arg;
    am_nfs_fh		nfsproc_statfs_2_arg;
  } argument;
  char *result;
  xdrproc_t xdr_argument, xdr_result;
  nfssvcproc_t local;

#ifdef HAVE_TRANSPORT_TYPE_TLI
  /*
   * On TLI systems we don't use an INET network type, but a "ticlts" (see
   * /etc/netconfig and conf/transp_tli.c:create_nfs_service).  This means
   * that packets could only come from the loopback interface, and we don't
   * need to check them and filter possibly spoofed packets.  Therefore we
   * only need to check if the UID caller is correct.
   */
# ifdef HAVE___RPC_GET_LOCAL_UID
  uid_t u;
  /* extern definition for an internal libnsl function */
  extern int __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid);
  if (__rpc_get_local_uid(transp, &u) >= 0  &&  u != 0) {
    plog(XLOG_WARNING, "ignoring request from UID %ld, must be 0", (long) u);
    return;
  }
# else /* not HAVE___RPC_GET_LOCAL_UID */
  dlog("cannot verify local uid for rpc request");
# endif /* HAVE___RPC_GET_LOCAL_UID */
#else /* not HAVE_TRANPORT_TYPE_TLI */
  struct sockaddr_in *sinp;
  char dq[20], dq2[28];
  sinp = amu_svc_getcaller(rqstp->rq_xprt);
# ifdef MNT2_NFS_OPT_RESVPORT
  /* Verify that the request comes from a reserved port */
  if (sinp &&
      ntohs(sinp->sin_port) >= IPPORT_RESERVED &&
      !(gopt.flags & CFM_NFS_INSECURE_PORT)) {
    plog(XLOG_WARNING, "ignoring request from %s:%u, port not reserved",
	 inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
	 ntohs(sinp->sin_port));
    return;
  }
# endif /* MNT2_NFS_OPT_RESVPORT */
  /* if the address does not match, ignore the request */
  if (sinp && (sinp->sin_addr.s_addr != myipaddr.s_addr)) {
    if (gopt.flags & CFM_NFS_ANY_INTERFACE) {
      if (!is_interface_local(sinp->sin_addr.s_addr)) {
	plog(XLOG_WARNING, "ignoring request from %s:%u, not a local interface",
	     inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
	     ntohs(sinp->sin_port));
      }
    } else {
      plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s",
	   inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
	   ntohs(sinp->sin_port),
	   inet_dquad(dq2, sizeof(dq2), myipaddr.s_addr));
      return;
    }
  }
#endif /* not HAVE_TRANPORT_TYPE_TLI */

  current_transp = NULL;

  switch (rqstp->rq_proc) {

  case NFSPROC_NULL:
    xdr_argument = (xdrproc_t) xdr_void;
    xdr_result = (xdrproc_t) xdr_void;
    local = (nfssvcproc_t) nfsproc_null_2_svc;
    break;

  case NFSPROC_GETATTR:
    xdr_argument = (xdrproc_t) xdr_nfs_fh;
    xdr_result = (xdrproc_t) xdr_attrstat;
    local = (nfssvcproc_t) nfsproc_getattr_2_svc;
    break;

  case NFSPROC_SETATTR:
    xdr_argument = (xdrproc_t) xdr_sattrargs;
    xdr_result = (xdrproc_t) xdr_attrstat;
    local = (nfssvcproc_t) nfsproc_setattr_2_svc;
    break;

  case NFSPROC_ROOT:
    xdr_argument = (xdrproc_t) xdr_void;
    xdr_result = (xdrproc_t) xdr_void;
    local = (nfssvcproc_t) nfsproc_root_2_svc;
    break;

  case NFSPROC_LOOKUP:
    xdr_argument = (xdrproc_t) xdr_diropargs;
    xdr_result = (xdrproc_t) xdr_diropres;
    local = (nfssvcproc_t) nfsproc_lookup_2_svc;
    /*
     * Cheap way to pass transp down to amfs_auto_lookuppn so it can
     * be stored in the am_node structure and later used for
     * quick_reply().
     */
    current_transp = transp;
    break;

  case NFSPROC_READLINK:
    xdr_argument = (xdrproc_t) xdr_nfs_fh;
    xdr_result = (xdrproc_t) xdr_readlinkres;
    local = (nfssvcproc_t) nfsproc_readlink_2_svc;
    break;

  case NFSPROC_READ:
    xdr_argument = (xdrproc_t) xdr_readargs;
    xdr_result = (xdrproc_t) xdr_readres;
    local = (nfssvcproc_t) nfsproc_read_2_svc;
    break;

  case NFSPROC_WRITECACHE:
    xdr_argument = (xdrproc_t) xdr_void;
    xdr_result = (xdrproc_t) xdr_void;
    local = (nfssvcproc_t) nfsproc_writecache_2_svc;
    break;

  case NFSPROC_WRITE:
    xdr_argument = (xdrproc_t) xdr_writeargs;
    xdr_result = (xdrproc_t) xdr_attrstat;
    local = (nfssvcproc_t) nfsproc_write_2_svc;
    break;

  case NFSPROC_CREATE:
    xdr_argument = (xdrproc_t) xdr_createargs;
    xdr_result = (xdrproc_t) xdr_diropres;
    local = (nfssvcproc_t) nfsproc_create_2_svc;
    break;

  case NFSPROC_REMOVE:
    xdr_argument = (xdrproc_t) xdr_diropargs;
    xdr_result = (xdrproc_t) xdr_nfsstat;
    local = (nfssvcproc_t) nfsproc_remove_2_svc;
    break;

  case NFSPROC_RENAME:
    xdr_argument = (xdrproc_t) xdr_renameargs;
    xdr_result = (xdrproc_t) xdr_nfsstat;
    local = (nfssvcproc_t) nfsproc_rename_2_svc;
    break;

  case NFSPROC_LINK:
    xdr_argument = (xdrproc_t) xdr_linkargs;
    xdr_result = (xdrproc_t) xdr_nfsstat;
    local = (nfssvcproc_t) nfsproc_link_2_svc;
    break;

  case NFSPROC_SYMLINK:
    xdr_argument = (xdrproc_t) xdr_symlinkargs;
    xdr_result = (xdrproc_t) xdr_nfsstat;
    local = (nfssvcproc_t) nfsproc_symlink_2_svc;
    break;

  case NFSPROC_MKDIR:
    xdr_argument = (xdrproc_t) xdr_createargs;
    xdr_result = (xdrproc_t) xdr_diropres;
    local = (nfssvcproc_t) nfsproc_mkdir_2_svc;
    break;

  case NFSPROC_RMDIR:
    xdr_argument = (xdrproc_t) xdr_diropargs;
    xdr_result = (xdrproc_t) xdr_nfsstat;
    local = (nfssvcproc_t) nfsproc_rmdir_2_svc;
    break;

  case NFSPROC_READDIR:
    xdr_argument = (xdrproc_t) xdr_readdirargs;
    xdr_result = (xdrproc_t) xdr_readdirres;
    local = (nfssvcproc_t) nfsproc_readdir_2_svc;
    break;

  case NFSPROC_STATFS:
    xdr_argument = (xdrproc_t) xdr_nfs_fh;
    xdr_result = (xdrproc_t) xdr_statfsres;
    local = (nfssvcproc_t) nfsproc_statfs_2_svc;
    break;

  default:
    svcerr_noproc(transp);
    return;
  }

  memset((char *) &argument, 0, sizeof(argument));
  if (!svc_getargs(transp,
		   (XDRPROC_T_TYPE) xdr_argument,
		   (SVC_IN_ARG_TYPE) &argument)) {
    plog(XLOG_ERROR,
	 "NFS xdr decode failed for %d %d %d",
	 (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc);
    svcerr_decode(transp);
    return;
  }
  result = (*local) (&argument, rqstp);

  current_transp = NULL;

  if (result != NULL && !svc_sendreply(transp,
				       (XDRPROC_T_TYPE) xdr_result,
				       result)) {
    svcerr_systemerr(transp);
  }
  if (!svc_freeargs(transp,
		    (XDRPROC_T_TYPE) xdr_argument,
		    (SVC_IN_ARG_TYPE) & argument)) {
    plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_2");
    going_down(1);
  }
}