コード例 #1
0
int
svc_getcred(struct svc_req *rqst, struct ucred **crp, int *flavorp)
{
    struct ucred *cr = NULL;
    int flavor;
    struct xucred *xcr;

    flavor = rqst->rq_cred.oa_flavor;
    if (flavorp)
        *flavorp = flavor;

    switch (flavor) {
    case AUTH_UNIX:
        xcr = (struct xucred *) rqst->rq_clntcred;
        cr = crget();
        cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xcr->cr_uid;
        crsetgroups(cr, xcr->cr_ngroups, xcr->cr_groups);
        cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0];
        cr->cr_prison = &prison0;
        prison_hold(cr->cr_prison);
        *crp = cr;
        return (TRUE);

    case RPCSEC_GSS:
        if (!_svcauth_rpcsec_gss_getcred)
            return (FALSE);
        return (_svcauth_rpcsec_gss_getcred(rqst, crp, flavorp));

    default:
        return (FALSE);
    }
}
コード例 #2
0
/*
 * Called with a modifying token held, but must still obtain p_spin to
 * actually replace p_ucred to handle races against syscall entry from
 * other threads which cache p_ucred->td_ucred.
 *
 * (the threads will only get the spin-lock, and they only need to in
 *  the case where td_ucred != p_ucred so this is optimal).
 */
struct ucred *
cratom_proc(struct proc *p)
{
	struct ucred *oldcr;
	struct ucred *newcr;

	oldcr = p->p_ucred;
	if (oldcr->cr_ref == 1)
		return(oldcr);

	newcr = crget();	/* this might block */
	oldcr = p->p_ucred;	/* so re-cache oldcr (do not re-test) */
	*newcr = *oldcr;
	if (newcr->cr_uidinfo)
		uihold(newcr->cr_uidinfo);
	if (newcr->cr_ruidinfo)
		uihold(newcr->cr_ruidinfo);
	if (jailed(newcr))
		prison_hold(newcr->cr_prison);
	newcr->cr_ref = 1;

	spin_lock(&p->p_spin);
	p->p_ucred = newcr;
	spin_unlock(&p->p_spin);
	crfree(oldcr);

	return newcr;
}
コード例 #3
0
ファイル: kern_prot.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * Dup cred struct to a new held one.
 */
struct ucred *
crdup(struct ucred *cr)
{
	struct ucred *newcr;

	newcr = crget();
	*newcr = *cr;
	if (newcr->cr_uidinfo)
		uihold(newcr->cr_uidinfo);
	if (newcr->cr_ruidinfo)
		uihold(newcr->cr_ruidinfo);
	if (jailed(newcr))
		prison_hold(newcr->cr_prison);
	newcr->cr_ref = 1;
	return (newcr);
}
コード例 #4
0
ファイル: kern_prot.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * Copy cred structure to a new one and free the old one.
 *
 * MPSAFE (*cr must be stable)
 */
struct ucred *
crcopy(struct ucred *cr)
{
	struct ucred *newcr;

	if (cr->cr_ref == 1)
		return (cr);
	newcr = crget();
	*newcr = *cr;
	if (newcr->cr_uidinfo)
		uihold(newcr->cr_uidinfo);
	if (newcr->cr_ruidinfo)
		uihold(newcr->cr_ruidinfo);
	if (jailed(newcr))
		prison_hold(newcr->cr_prison);
	newcr->cr_ref = 1;
	crfree(cr);
	return (newcr);
}
コード例 #5
0
ファイル: kern_prot.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * Atomize a cred structure so it can be modified without polluting
 * other references to it.
 *
 * MPSAFE (however, *pcr must be stable)
 */
struct ucred *
cratom(struct ucred **pcr)
{
	struct ucred *oldcr;
	struct ucred *newcr;

	oldcr = *pcr;
	if (oldcr->cr_ref == 1)
		return (oldcr);
	newcr = crget();
	*newcr = *oldcr;
	if (newcr->cr_uidinfo)
		uihold(newcr->cr_uidinfo);
	if (newcr->cr_ruidinfo)
		uihold(newcr->cr_ruidinfo);
	if (jailed(newcr))
		prison_hold(newcr->cr_prison);
	newcr->cr_ref = 1;
	crfree(oldcr);
	*pcr = newcr;
	return (newcr);
}
コード例 #6
0
/*
 * Atomize a cred structure so it can be modified without polluting
 * other references to it.
 *
 * MPSAFE (however, *pcr must be stable)
 */
struct ucred *
cratom(struct ucred **pcr)
{
	struct ucred *oldcr;
	struct ucred *newcr;

	oldcr = *pcr;
	if (oldcr->cr_ref == 1)
		return (oldcr);
	newcr = crget();	/* this might block */
	oldcr = *pcr;		/* re-cache after potentially blocking */
	*newcr = *oldcr;
	if (newcr->cr_uidinfo)
		uihold(newcr->cr_uidinfo);
	if (newcr->cr_ruidinfo)
		uihold(newcr->cr_ruidinfo);
	if (jailed(newcr))
		prison_hold(newcr->cr_prison);
	newcr->cr_ref = 1;
	crfree(oldcr);
	*pcr = newcr;

	return (newcr);
}
コード例 #7
0
ファイル: vfs_export.c プロジェクト: coyizumi/cs111
/*
 * Build hash lists of net addresses and hang them off the mount point.
 * Called by vfs_export() to set up the lists of export addresses.
 */
static int
vfs_hang_addrlist(struct mount *mp, struct netexport *nep,
    struct export_args *argp)
{
	register struct netcred *np;
	register struct radix_node_head *rnh;
	register int i;
	struct radix_node *rn;
	struct sockaddr *saddr, *smask = 0;
	struct domain *dom;
	int error;

	/*
	 * XXX: This routine converts from a `struct xucred'
	 * (argp->ex_anon) to a `struct ucred' (np->netc_anon).  This
	 * operation is questionable; for example, what should be done
	 * with fields like cr_uidinfo and cr_prison?  Currently, this
	 * routine does not touch them (leaves them as NULL).
	 */
	if (argp->ex_anon.cr_version != XUCRED_VERSION) {
		vfs_mount_error(mp, "ex_anon.cr_version: %d != %d",
		    argp->ex_anon.cr_version, XUCRED_VERSION);
		return (EINVAL);
	}

	if (argp->ex_addrlen == 0) {
		if (mp->mnt_flag & MNT_DEFEXPORTED) {
			vfs_mount_error(mp,
			    "MNT_DEFEXPORTED already set for mount %p", mp);
			return (EPERM);
		}
		np = &nep->ne_defexported;
		np->netc_exflags = argp->ex_flags;
		np->netc_anon = crget();
		np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
		crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
		    argp->ex_anon.cr_groups);
		np->netc_anon->cr_prison = &prison0;
		prison_hold(np->netc_anon->cr_prison);
		np->netc_numsecflavors = argp->ex_numsecflavors;
		bcopy(argp->ex_secflavors, np->netc_secflavors,
		    sizeof(np->netc_secflavors));
		MNT_ILOCK(mp);
		mp->mnt_flag |= MNT_DEFEXPORTED;
		MNT_IUNLOCK(mp);
		return (0);
	}

#if MSIZE <= 256
	if (argp->ex_addrlen > MLEN) {
		vfs_mount_error(mp, "ex_addrlen %d is greater than %d",
		    argp->ex_addrlen, MLEN);
		return (EINVAL);
	}
#endif

	i = sizeof(struct netcred) + argp->ex_addrlen + argp->ex_masklen;
	np = (struct netcred *) malloc(i, M_NETADDR, M_WAITOK | M_ZERO);
	saddr = (struct sockaddr *) (np + 1);
	if ((error = copyin(argp->ex_addr, saddr, argp->ex_addrlen)))
		goto out;
	if (saddr->sa_family == AF_UNSPEC || saddr->sa_family > AF_MAX) {
		error = EINVAL;
		vfs_mount_error(mp, "Invalid saddr->sa_family: %d");
		goto out;
	}
	if (saddr->sa_len > argp->ex_addrlen)
		saddr->sa_len = argp->ex_addrlen;
	if (argp->ex_masklen) {
		smask = (struct sockaddr *)((caddr_t)saddr + argp->ex_addrlen);
		error = copyin(argp->ex_mask, smask, argp->ex_masklen);
		if (error)
			goto out;
		if (smask->sa_len > argp->ex_masklen)
			smask->sa_len = argp->ex_masklen;
	}
	i = saddr->sa_family;
	if ((rnh = nep->ne_rtable[i]) == NULL) {
		/*
		 * Seems silly to initialize every AF when most are not used,
		 * do so on demand here
		 */
		for (dom = domains; dom; dom = dom->dom_next) {
			KASSERT(((i == AF_INET) || (i == AF_INET6)), 
			    ("unexpected protocol in vfs_hang_addrlist"));
			if (dom->dom_family == i && dom->dom_rtattach) {
				/*
				 * XXX MRT 
				 * The INET and INET6 domains know the
				 * offset already. We don't need to send it
				 * So we just use it as a flag to say that
				 * we are or are not setting up a real routing
				 * table. Only IP and IPV6 need have this
				 * be 0 so all other protocols can stay the 
				 * same (ABI compatible).
				 */ 
				dom->dom_rtattach(
				    (void **) &nep->ne_rtable[i], 0);
				break;
			}
		}
		if ((rnh = nep->ne_rtable[i]) == NULL) {
			error = ENOBUFS;
			vfs_mount_error(mp, "%s %s %d",
			    "Unable to initialize radix node head ",
			    "for address family", i);
			goto out;
		}
	}
	RADIX_NODE_HEAD_LOCK(rnh);
	rn = (*rnh->rnh_addaddr)(saddr, smask, rnh, np->netc_rnodes);
	RADIX_NODE_HEAD_UNLOCK(rnh);
	if (rn == NULL || np != (struct netcred *)rn) {	/* already exists */
		error = EPERM;
		vfs_mount_error(mp, "Invalid radix node head, rn: %p %p",
		    rn, np);
		goto out;
	}
	np->netc_exflags = argp->ex_flags;
	np->netc_anon = crget();
	np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
	crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
	    argp->ex_anon.cr_groups);
	np->netc_anon->cr_prison = &prison0;
	prison_hold(np->netc_anon->cr_prison);
	np->netc_numsecflavors = argp->ex_numsecflavors;
	bcopy(argp->ex_secflavors, np->netc_secflavors,
	    sizeof(np->netc_secflavors));
	return (0);
out:
	free(np, M_NETADDR);
	return (error);
}