Beispiel #1
0
/*
 * Auth too weak error reply
 */
void
svcerr_weakauth(
	SVCXPRT *xprt )
{

	svcerr_auth(xprt, AUTH_TOOWEAK);
}
Beispiel #2
0
void svcerr_weakauth
   (
      register SVCXPRT_PTR xprt
            /* [IN] - transport handle */
   )
{ /* Body */
   svcerr_auth(xprt, AUTH_TOOWEAK);
} /* Endbody */
Beispiel #3
0
ypresp_all *
ypproc_all_2_svc(ypreq_nokey *arg, struct svc_req *req)
{
	static struct ypresp_all	res;

	if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1)
		return (&res);

	svcerr_auth(req->rq_xprt, AUTH_FAILED);
	return (NULL);
}
Beispiel #4
0
static void 
sm_prog_1_wrapper (struct svc_req *rqstp, register SVCXPRT *transp)
{
	struct sockaddr_in *sin = nfs_getrpccaller_in(transp);

	/* remote host authorization check */
	if (sin->sin_family == AF_INET &&
	    !check_default("statd", sin, rqstp->rq_proc, SM_PROG)) {
		svcerr_auth (transp, AUTH_FAILED);
		return;
	}

	sm_prog_1 (rqstp, transp);
}
Beispiel #5
0
/* Server callback to check that the request comes from an allowed IP
 * address.  A call to here is inserted in the rpcgen-generated
 * server-side dispatch code by the build process.
 */
int ippool_api_rpc_check_request(SVCXPRT *xprt)
{
	/* If remote RPC is not enabled and the request is from a 
	 * non-loopback interface, reject the request.
	 */
	if ((!ippool_opt_remote_rpc) &&
	    ((xprt->xp_raddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) &&
	     (xprt->xp_raddr.sin_addr.s_addr != htonl(INADDR_ANY)))) {
		if (ippool_opt_debug) {
			ippool_log(LOG_ERR, "Rejecting RPC request from %s", inet_ntoa(xprt->xp_raddr.sin_addr));
		}
		svcerr_auth(xprt, AUTH_TOOWEAK);
		return -EPERM;
	}

	return 0;
}
Beispiel #6
0
/*
 * rpcb_check; the rpcbind/portmap access check function.
 */
boolean_t
rpcb_check(SVCXPRT *transp, rpcproc_t procnum, boolean_t ispmap)
{
    struct netconfig *conf;
    boolean_t res = B_TRUE;

    if ((conf = rpcbind_get_conf(transp->xp_netid)) == 0) {
        syslog(LOG_ERR,
               "rpcbind_get_conf failed: no client address checks");
        return (B_TRUE);
    }

    /*
     * Require IPv4 for pmap calls; they're not defined for anything else.
     */
    if (ispmap && strcmp(conf->nc_protofmly, "inet") != 0) {
        res = B_FALSE;
    } else if (strcmp(conf->nc_protofmly, "inet") == 0 ||
               strcmp(conf->nc_protofmly, "inet6") == 0) {
        const char *addr_string = sgen_toa(svc_getgencaller(transp));

        if (!localxprt(transp, ispmap) &&
                (local_only ||
                 hosts_ctl("rpcbind", addr_string, addr_string, "") == 0)) {
            res = B_FALSE;
        }
    }
out:
    if (!res)
        svcerr_auth(transp, AUTH_FAILED);

    if (verboselog || !res)
        rpcb_log(res, transp, procnum, 0, ispmap);

    return (res);
}
Beispiel #7
0
static void
nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
{
	struct nfsrv_descript nd;
	struct nfsrvcache *rp = NULL;
	int cacherep, credflavor;

	memset(&nd, 0, sizeof(nd));
	if (rqst->rq_vers == NFS_VER2) {
		if (rqst->rq_proc > NFSV2PROC_STATFS) {
			svcerr_noproc(rqst);
			svc_freereq(rqst);
			goto out;
		}
		nd.nd_procnum = newnfs_nfsv3_procid[rqst->rq_proc];
		nd.nd_flag = ND_NFSV2;
	} else if (rqst->rq_vers == NFS_VER3) {
		if (rqst->rq_proc >= NFS_V3NPROCS) {
			svcerr_noproc(rqst);
			svc_freereq(rqst);
			goto out;
		}
		nd.nd_procnum = rqst->rq_proc;
		nd.nd_flag = ND_NFSV3;
	} else {
		if (rqst->rq_proc != NFSPROC_NULL &&
		    rqst->rq_proc != NFSV4PROC_COMPOUND) {
			svcerr_noproc(rqst);
			svc_freereq(rqst);
			goto out;
		}
		nd.nd_procnum = rqst->rq_proc;
		nd.nd_flag = ND_NFSV4;
	}

	/*
	 * Note: we want rq_addr, not svc_getrpccaller for nd_nam2 -
	 * NFS_SRVMAXDATA uses a NULL value for nd_nam2 to detect TCP
	 * mounts.
	 */
	nd.nd_mrep = rqst->rq_args;
	rqst->rq_args = NULL;
	newnfs_realign(&nd.nd_mrep, M_WAITOK);
	nd.nd_md = nd.nd_mrep;
	nd.nd_dpos = mtod(nd.nd_md, caddr_t);
	nd.nd_nam = svc_getrpccaller(rqst);
	nd.nd_nam2 = rqst->rq_addr;
	nd.nd_mreq = NULL;
	nd.nd_cred = NULL;

	if (nfs_privport && (nd.nd_flag & ND_NFSV4) == 0) {
		/* Check if source port is privileged */
		u_short port;
		struct sockaddr *nam = nd.nd_nam;
		struct sockaddr_in *sin;

		sin = (struct sockaddr_in *)nam;
		/*
		 * INET/INET6 - same code:
		 *    sin_port and sin6_port are at same offset
		 */
		port = ntohs(sin->sin_port);
		if (port >= IPPORT_RESERVED &&
		    nd.nd_procnum != NFSPROC_NULL) {
#ifdef INET6
			char b6[INET6_ADDRSTRLEN];
#if defined(KLD_MODULE)
			/* Do not use ip6_sprintf: the nfs module should work without INET6. */
#define	ip6_sprintf(buf, a)						\
			(sprintf((buf), "%x:%x:%x:%x:%x:%x:%x:%x",	\
			    (a)->s6_addr16[0], (a)->s6_addr16[1],	\
			    (a)->s6_addr16[2], (a)->s6_addr16[3],	\
			    (a)->s6_addr16[4], (a)->s6_addr16[5],	\
			    (a)->s6_addr16[6], (a)->s6_addr16[7]),	\
			    (buf))
#endif
#endif
			printf("NFS request from unprivileged port (%s:%d)\n",
#ifdef INET6
			    sin->sin_family == AF_INET6 ?
			    ip6_sprintf(b6, &satosin6(sin)->sin6_addr) :
#if defined(KLD_MODULE)
#undef ip6_sprintf
#endif
#endif
			    inet_ntoa(sin->sin_addr), port);
			svcerr_weakauth(rqst);
			svc_freereq(rqst);
			m_freem(nd.nd_mrep);
			goto out;
		}
	}

	if (nd.nd_procnum != NFSPROC_NULL) {
		if (!svc_getcred(rqst, &nd.nd_cred, &credflavor)) {
			svcerr_weakauth(rqst);
			svc_freereq(rqst);
			m_freem(nd.nd_mrep);
			goto out;
		}

		/* Set the flag based on credflavor */
		if (credflavor == RPCSEC_GSS_KRB5) {
			nd.nd_flag |= ND_GSS;
		} else if (credflavor == RPCSEC_GSS_KRB5I) {
			nd.nd_flag |= (ND_GSS | ND_GSSINTEGRITY);
		} else if (credflavor == RPCSEC_GSS_KRB5P) {
			nd.nd_flag |= (ND_GSS | ND_GSSPRIVACY);
		} else if (credflavor != AUTH_SYS) {
			svcerr_weakauth(rqst);
			svc_freereq(rqst);
			m_freem(nd.nd_mrep);
			goto out;
		}

#ifdef MAC
		mac_cred_associate_nfsd(nd.nd_cred);
#endif
		/*
		 * Get a refcnt (shared lock) on nfsd_suspend_lock.
		 * NFSSVC_SUSPENDNFSD will take an exclusive lock on
		 * nfsd_suspend_lock to suspend these threads.
		 * This must be done here, before the check of
		 * nfsv4root exports by nfsvno_v4rootexport().
		 */
		NFSLOCKV4ROOTMUTEX();
		nfsv4_getref(&nfsd_suspend_lock, NULL, NFSV4ROOTLOCKMUTEXPTR,
		    NULL);
		NFSUNLOCKV4ROOTMUTEX();

		if ((nd.nd_flag & ND_NFSV4) != 0) {
			nd.nd_repstat = nfsvno_v4rootexport(&nd);
			if (nd.nd_repstat != 0) {
				NFSLOCKV4ROOTMUTEX();
				nfsv4_relref(&nfsd_suspend_lock);
				NFSUNLOCKV4ROOTMUTEX();
				svcerr_weakauth(rqst);
				svc_freereq(rqst);
				m_freem(nd.nd_mrep);
				goto out;
			}
		}

		cacherep = nfs_proc(&nd, rqst->rq_xid, xprt, &rp);
		NFSLOCKV4ROOTMUTEX();
		nfsv4_relref(&nfsd_suspend_lock);
		NFSUNLOCKV4ROOTMUTEX();
	} else {
		NFSMGET(nd.nd_mreq);
		nd.nd_mreq->m_len = 0;
		cacherep = RC_REPLY;
	}
	if (nd.nd_mrep != NULL)
		m_freem(nd.nd_mrep);

	if (nd.nd_cred != NULL)
		crfree(nd.nd_cred);

	if (cacherep == RC_DROPIT) {
		if (nd.nd_mreq != NULL)
			m_freem(nd.nd_mreq);
		svc_freereq(rqst);
		goto out;
	}

	if (nd.nd_mreq == NULL) {
		svcerr_decode(rqst);
		svc_freereq(rqst);
		goto out;
	}

	if (nd.nd_repstat & NFSERR_AUTHERR) {
		svcerr_auth(rqst, nd.nd_repstat & ~NFSERR_AUTHERR);
		if (nd.nd_mreq != NULL)
			m_freem(nd.nd_mreq);
	} else if (!svc_sendreply_mbuf(rqst, nd.nd_mreq)) {
		svcerr_systemerr(rqst);
	}
	if (rp != NULL) {
		nfsrvd_sentcache(rp, (rqst->rq_reply_seq != 0 ||
		    SVC_ACK(xprt, NULL)), rqst->rq_reply_seq);
	}
	svc_freereq(rqst);

out:
	NFSEXITCODE(0);
}
Beispiel #8
0
/*
 * Handles server to client callbacks.
 */
static void
nfscb_program(struct svc_req *rqst, SVCXPRT *xprt)
{
	struct nfsrv_descript nd;
	int cacherep, credflavor;

	memset(&nd, 0, sizeof(nd));
	if (rqst->rq_proc != NFSPROC_NULL &&
	    rqst->rq_proc != NFSV4PROC_CBCOMPOUND) {
		svcerr_noproc(rqst);
		svc_freereq(rqst);
		return;
	}
	nd.nd_procnum = rqst->rq_proc;
	nd.nd_flag = (ND_NFSCB | ND_NFSV4);

	/*
	 * Note: we want rq_addr, not svc_getrpccaller for nd_nam2 -
	 * NFS_SRVMAXDATA uses a NULL value for nd_nam2 to detect TCP
	 * mounts.
	 */
	nd.nd_mrep = rqst->rq_args;
	rqst->rq_args = NULL;
	newnfs_realign(&nd.nd_mrep, M_WAITOK);
	nd.nd_md = nd.nd_mrep;
	nd.nd_dpos = mtod(nd.nd_md, caddr_t);
	nd.nd_nam = svc_getrpccaller(rqst);
	nd.nd_nam2 = rqst->rq_addr;
	nd.nd_mreq = NULL;
	nd.nd_cred = NULL;

	NFSCL_DEBUG(1, "cbproc=%d\n",nd.nd_procnum);
	if (nd.nd_procnum != NFSPROC_NULL) {
		if (!svc_getcred(rqst, &nd.nd_cred, &credflavor)) {
			svcerr_weakauth(rqst);
			svc_freereq(rqst);
			m_freem(nd.nd_mrep);
			return;
		}

		/* For now, I don't care what credential flavor was used. */
#ifdef notyet
#ifdef MAC
		mac_cred_associate_nfsd(nd.nd_cred);
#endif
#endif
		cacherep = nfs_cbproc(&nd, rqst->rq_xid);
	} else {
		NFSMGET(nd.nd_mreq);
		nd.nd_mreq->m_len = 0;
		cacherep = RC_REPLY;
	}
	if (nd.nd_mrep != NULL)
		m_freem(nd.nd_mrep);

	if (nd.nd_cred != NULL)
		crfree(nd.nd_cred);

	if (cacherep == RC_DROPIT) {
		if (nd.nd_mreq != NULL)
			m_freem(nd.nd_mreq);
		svc_freereq(rqst);
		return;
	}

	if (nd.nd_mreq == NULL) {
		svcerr_decode(rqst);
		svc_freereq(rqst);
		return;
	}

	if (nd.nd_repstat & NFSERR_AUTHERR) {
		svcerr_auth(rqst, nd.nd_repstat & ~NFSERR_AUTHERR);
		if (nd.nd_mreq != NULL)
			m_freem(nd.nd_mreq);
	} else if (!svc_sendreply_mbuf(rqst, nd.nd_mreq))
		svcerr_systemerr(rqst);
	else
		NFSCL_DEBUG(1, "cbrep sent\n");
	svc_freereq(rqst);
}
Beispiel #9
0
void
svc_getreq_common (const int fd)
{
  enum xprt_stat stat;
  struct rpc_msg msg;
  register SVCXPRT *xprt;
  char cred_area[2 * MAX_AUTH_BYTES + RQCRED_SIZE];
  msg.rm_call.cb_cred.oa_base = cred_area;
  msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);

  xprt = xports[fd];
  /* Do we control fd? */
  if (xprt == NULL)
     return;

  /* now receive msgs from xprtprt (support batch calls) */
  do
    {
      if (SVC_RECV (xprt, &msg))
	{
	  /* now find the exported program and call it */
	  struct svc_callout *s;
	  struct svc_req r;
	  enum auth_stat why;
	  rpcvers_t low_vers;
	  rpcvers_t high_vers;
	  int prog_found;

	  r.rq_clntcred = &(cred_area[2 * MAX_AUTH_BYTES]);
	  r.rq_xprt = xprt;
	  r.rq_prog = msg.rm_call.cb_prog;
	  r.rq_vers = msg.rm_call.cb_vers;
	  r.rq_proc = msg.rm_call.cb_proc;
	  r.rq_cred = msg.rm_call.cb_cred;

	  /* first authenticate the message */
	  /* Check for null flavor and bypass these calls if possible */

	  if (msg.rm_call.cb_cred.oa_flavor == AUTH_NULL)
	    {
	      r.rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
	      r.rq_xprt->xp_verf.oa_length = 0;
	    }
	  else if ((why = INTUSE(_authenticate) (&r, &msg)) != AUTH_OK)
	    {
	      svcerr_auth (xprt, why);
	      goto call_done;
	    }

	  /* now match message with a registered service */
	  prog_found = FALSE;
	  low_vers = 0 - 1;
	  high_vers = 0;

	  for (s = svc_head; s != NULL_SVC; s = s->sc_next)
	    {
	      if (s->sc_prog == r.rq_prog)
		{
		  if (s->sc_vers == r.rq_vers)
		    {
		      (*s->sc_dispatch) (&r, xprt);
		      goto call_done;
		    }
		  /* found correct version */
		  prog_found = TRUE;
		  if (s->sc_vers < low_vers)
		    low_vers = s->sc_vers;
		  if (s->sc_vers > high_vers)
		    high_vers = s->sc_vers;
		}
	      /* found correct program */
	    }
	  /* if we got here, the program or version
	     is not served ... */
	  if (prog_found)
	    svcerr_progvers (xprt, low_vers, high_vers);
	  else
	    svcerr_noprog (xprt);
	  /* Fall through to ... */
	}
    call_done:
      if ((stat = SVC_STAT (xprt)) == XPRT_DIED)
	{
	  SVC_DESTROY (xprt);
	  break;
	}
    }
  while (stat == XPRT_MOREREQS);
}
Beispiel #10
0
void
svc_getreq_common(int fd)
{
	enum xprt_stat stat;
	struct rpc_msg msg;
	int prog_found;
	u_long low_vers;
	u_long high_vers;
	struct svc_req r;
	SVCXPRT *xprt;
	char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];

	msg.rm_call.cb_cred.oa_base = cred_area;
	msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
	r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);

	/* sock has input waiting */
	xprt = xports[fd];
	if (xprt == NULL)
		/* But do we control the fd? */
		return;
	/* now receive msgs from xprtprt (support batch calls) */
	do {
		if (SVC_RECV(xprt, &msg)) {
			/* find the exported program and call it */
			struct svc_callout *s;
			enum auth_stat why;

			r.rq_xprt = xprt;
			r.rq_prog = msg.rm_call.cb_prog;
			r.rq_vers = msg.rm_call.cb_vers;
			r.rq_proc = msg.rm_call.cb_proc;
			r.rq_cred = msg.rm_call.cb_cred;
			/* first authenticate the message */
			if ((why= _authenticate(&r, &msg)) != AUTH_OK) {
				svcerr_auth(xprt, why);
				goto call_done;
			}
			/* now match message with a registered service*/
			prog_found = FALSE;
			low_vers = (u_long) -1;
			high_vers = 0;
			for (s = svc_head; s != NULL; s = s->sc_next) {
				if (s->sc_prog == r.rq_prog) {
					if (s->sc_vers == r.rq_vers) {
						(*s->sc_dispatch)(&r, xprt);
						goto call_done;
					}  /* found correct version */
					prog_found = TRUE;
					if (s->sc_vers < low_vers)
						low_vers = s->sc_vers;
					if (s->sc_vers > high_vers)
						high_vers = s->sc_vers;
				}   /* found correct program */
			}
			/*
			 * if we got here, the program or version
			 * is not served ...
			 */
			if (prog_found)
				svcerr_progvers(xprt, low_vers, high_vers);
			else
				 svcerr_noprog(xprt);
			/* Fall through to ... */
		}
	call_done:
		if ((stat = SVC_STAT(xprt)) == XPRT_DIED){
			SVC_DESTROY(xprt);
			break;
		}
	} while (stat == XPRT_MOREREQS);
}
Beispiel #11
0
//****************************************//
//***       Dispatch Function          ***//
//****************************************//
void rcp_service(register struct svc_req *rqstp, register SVCXPRT *transp)
{
	//printf("* in Dispatch Func.\n");
	/*union {
		int varIn;
	} argument;*/

	char *result;
	xdrproc_t xdr_argument;
	xdrproc_t xdr_result;
	char *(*proc)(union u_argument *, SVCXPRT *);
	enum auth_stat why;

    switch (rqstp->rq_proc)
    {
		case PROCSIMPLEPING:
		{
			//printf("** in PROCSIMPLEPING dispatch Func.\n");
			xdr_argument = (xdrproc_t)xdr_int;
			xdr_result   = (xdrproc_t)xdr_int;
			proc         = (char *(*)(union u_argument *, SVCXPRT *))simplePing;
			break;
		}
		case SVCGETCALLTEST:
		{
			//printf("** in SVCGETCALLTEST dispatch Func.\n");
			xdr_argument = (xdrproc_t)xdr_int;
			xdr_result   = (xdrproc_t)xdr_int;
			proc         = (char *(*)(union u_argument *, SVCXPRT *))svc_getcaller_test;
			break;
		}
		case PROGSYSERROR:
		{
			//printf("** in PROGSYSERROR dispatch Func.\n");
			//Simulate an error
			svcerr_systemerr(transp);
			return;
		}
		case PROGAUTHERROR:
		{
			//printf("** in PROGAUTHERROR dispatch Func.\n");
			//Simulate an authentification error
			svcerr_auth(transp, why);
			return;
		}
		case PROGWKAUTHERROR:
		{
			//printf("** in PROGWKAUTHERROR dispatch Func.\n");
			//Simulate an authentification error
			svcerr_weakauth(transp);
			return;
		}
		case INTPROCNUM:
		{
			//printf("** in INTPROCNUM dispatch Func.\n");
			xdr_argument = (xdrproc_t)xdr_int;
			xdr_result   = (xdrproc_t)xdr_int;
			proc         = (char *(*)(union u_argument *, SVCXPRT *))intTestProc;
						 //(char *(*)(union u_argument *))
			break;
		}
		case DBLPROCNUM:
		{
			//printf("** in DBLPROCNUM dispatch Func.\n");
			xdr_argument = (xdrproc_t)xdr_double;
			xdr_result   = (xdrproc_t)xdr_double;
			proc         = (char *(*)(union u_argument *, SVCXPRT *))dblTestProc;
			break;
		}
		case LNGPROCNUM:
		{
			//printf("** in LNGPROCNUM dispatch Func.\n");
			xdr_argument = (xdrproc_t)xdr_long;
			xdr_result   = (xdrproc_t)xdr_long;
			proc         = (char *(*)(union u_argument *, SVCXPRT *))lngTestProc;
			break;
		}
		case STRPROCNUM:
		{
			//printf("** in STRPROCNUM dispatch Func.\n");
			xdr_argument = (xdrproc_t)xdr_wrapstring;
			xdr_result   = (xdrproc_t)xdr_wrapstring;
			proc         = (char *(*)(union u_argument *, SVCXPRT *))strTestProc;
			break;
		}
		case SVCGETARGSPROC:
		{
			//printf("** in SVCGETARGSPROC dispatch Func.\n");
			xdr_argument = (xdrproc_t)xdr_int;
			xdr_result   = (xdrproc_t)xdr_int;
			proc         = (char *(*)(union u_argument *, SVCXPRT *))svcGetargsProc;
			break;
		}
		default:
		{
			//printf("** in NOT DEFINED dispatch Func.\n");
			//Proc is unavaible
      		svcerr_noproc(transp);
      		return;
      	}
    }

    memset((char *)&argument, (int)0, sizeof(argument));
	if (svc_getargs(transp, xdr_argument, (char *)&argument) == FALSE)
	{
		svcerr_decode(transp);
		return;
	}

	result = (char *)(*proc)((union u_argument *)&argument, transp);

	if ((result != NULL) && (svc_sendreply(transp, xdr_result, result) == FALSE))
	{
		svcerr_systemerr(transp);
	}
	if (svc_freeargs(transp, xdr_argument, (char *)&argument) == FALSE) {
		(void)fprintf(stderr, "unable to free arguments\n");
		exit(1);
	}
}