示例#1
0
/*
 * Called by nfssvc() for nfsds. Just loops around servicing rpc requests
 * until it is killed by a signal.
 */
int
nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
{
	char principal[MAXHOSTNAMELEN + 5];
	int error = 0;
	bool_t ret2, ret3, ret4;

	error = copyinstr(args->principal, principal, sizeof (principal),
	    NULL);
	if (error)
		goto out;

	/*
	 * Only the first nfsd actually does any work. The RPC code
	 * adds threads to it as needed. Any extra processes offered
	 * by nfsd just exit. If nfsd is new enough, it will call us
	 * once with a structure that specifies how many threads to
	 * use.
	 */
	NFSD_LOCK();
	if (newnfs_numnfsd == 0) {
		newnfs_numnfsd++;

		NFSD_UNLOCK();

		/* An empty string implies AUTH_SYS only. */
		if (principal[0] != '\0') {
			ret2 = rpc_gss_set_svc_name_call(principal,
			    "kerberosv5", GSS_C_INDEFINITE, NFS_PROG, NFS_VER2);
			ret3 = rpc_gss_set_svc_name_call(principal,
			    "kerberosv5", GSS_C_INDEFINITE, NFS_PROG, NFS_VER3);
			ret4 = rpc_gss_set_svc_name_call(principal,
			    "kerberosv5", GSS_C_INDEFINITE, NFS_PROG, NFS_VER4);

			if (!ret2 || !ret3 || !ret4)
				printf("nfsd: can't register svc name\n");
		}

		nfsrvd_pool->sp_minthreads = args->minthreads;
		nfsrvd_pool->sp_maxthreads = args->maxthreads;
			
		svc_run(nfsrvd_pool);

		if (principal[0] != '\0') {
			rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER2);
			rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER3);
			rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER4);
		}

		NFSD_LOCK();
		newnfs_numnfsd--;
		nfsrvd_init(1);
	}
	NFSD_UNLOCK();

out:
	NFSEXITCODE(error);
	return (error);
}
示例#2
0
/*
 * Called by nfssvc() for nfscbds. Just loops around servicing rpc requests
 * until it is killed by a signal.
 *
 * For now, only support callbacks via RPCSEC_GSS if there is a KerberosV
 * keytab entry with a host based entry in it on the client. (I'm not even
 * sure that getting Acceptor credentials for a user principal with a
 * credentials cache is possible, but even if it is, major changes to the
 * kgssapi would be required.)
 * I don't believe that this is a serious limitation since, as of 2009, most
 * NFSv4 servers supporting callbacks are using AUTH_SYS for callbacks even
 * when the client is using RPCSEC_GSS. (This BSD server uses AUTH_SYS
 * for callbacks unless nfsrv_gsscallbackson is set non-zero.)
 */
int
nfscbd_nfsd(struct thread *td, struct nfsd_nfscbd_args *args)
{
	char principal[128];
	int error;

	if (args != NULL) {
		error = copyinstr(args->principal, principal,
		    sizeof(principal), NULL);
		if (error)
			return (error);
	} else {
		principal[0] = '\0';
	}

	/*
	 * Only the first nfsd actually does any work. The RPC code
	 * adds threads to it as needed. Any extra processes offered
	 * by nfsd just exit. If nfsd is new enough, it will call us
	 * once with a structure that specifies how many threads to
	 * use.
	 */
	NFSD_LOCK();
	if (nfs_numnfscbd == 0) {
		nfs_numnfscbd++;

		NFSD_UNLOCK();

		if (principal[0] != '\0')
			rpc_gss_set_svc_name_call(principal, "kerberosv5",
			    GSS_C_INDEFINITE, NFS_CALLBCKPROG, NFSV4_CBVERS);

		nfscbd_pool->sp_minthreads = 4;
		nfscbd_pool->sp_maxthreads = 4;
			
		svc_run(nfscbd_pool);

		rpc_gss_clear_svc_name_call(NFS_CALLBCKPROG, NFSV4_CBVERS);

		NFSD_LOCK();
		nfs_numnfscbd--;
		nfsrvd_cbinit(1);
	}
	NFSD_UNLOCK();

	return (0);
}