/*
 * Copy NFS uid, gids to the cred structure.
 */
void
newnfs_copycred(struct nfscred *nfscr, struct ucred *cr)
{

	cr->cr_uid = nfscr->nfsc_uid;
	crsetgroups(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups);
}
Exemplo n.º 2
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);
    }
}
Exemplo n.º 3
0
/*
 * Copy NFS uid, gids to the cred structure.
 */
void
newnfs_copycred(struct nfscred *nfscr, struct ucred *cr)
{

	KASSERT(nfscr->nfsc_ngroups >= 0,
	    ("newnfs_copycred: negative nfsc_ngroups"));
	cr->cr_uid = nfscr->nfsc_uid;
	crsetgroups(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups);
}
Exemplo n.º 4
0
/*
 * 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);
}
Exemplo n.º 5
0
/*
 * Allocate a Solaris cred and initialize it based on the access token.
 *
 * If the user can be mapped to a non-ephemeral ID, the cred gid is set
 * to the Solaris user's primary group.
 *
 * If the mapped UID is ephemeral, or the primary group could not be
 * obtained, the cred gid is set to whatever Solaris group is mapped
 * to the token's primary group.
 */
cred_t *
smb_cred_create(smb_token_t *token)
{
	ksid_t			ksid;
	ksidlist_t		*ksidlist = NULL;
	smb_posix_grps_t	*posix_grps;
	cred_t			*cr;
	gid_t			gid;

	ASSERT(token);
	ASSERT(token->tkn_posix_grps);
	posix_grps = token->tkn_posix_grps;

	cr = crget();
	ASSERT(cr != NULL);

	if (!IDMAP_ID_IS_EPHEMERAL(token->tkn_user.i_id) &&
	    (posix_grps->pg_ngrps != 0)) {
		gid = posix_grps->pg_grps[0];
	} else {
		gid = token->tkn_primary_grp.i_id;
	}

	if (crsetugid(cr, token->tkn_user.i_id, gid) != 0) {
		crfree(cr);
		return (NULL);
	}

	if (crsetgroups(cr, posix_grps->pg_ngrps, posix_grps->pg_grps) != 0) {
		crfree(cr);
		return (NULL);
	}

	smb_cred_set_sid(&token->tkn_user, &ksid);
	crsetsid(cr, &ksid, KSID_USER);
	smb_cred_set_sid(&token->tkn_primary_grp, &ksid);
	crsetsid(cr, &ksid, KSID_GROUP);
	smb_cred_set_sid(&token->tkn_owner, &ksid);
	crsetsid(cr, &ksid, KSID_OWNER);
	ksidlist = smb_cred_set_sidlist(&token->tkn_win_grps);
	crsetsidlist(cr, ksidlist);

	/*
	 * In the AD world, "take ownership privilege" is very much
	 * like having Unix "root" privileges.  It's normally given
	 * to members of the "Administrators" group, which normally
	 * includes the the local Administrator (like root) and when
	 * joined to a domain, "Domain Admins".
	 */
	if (smb_token_query_privilege(token, SE_TAKE_OWNERSHIP_LUID)) {
		(void) crsetpriv(cr,
		    PRIV_FILE_CHOWN,
		    PRIV_FILE_DAC_READ,
		    PRIV_FILE_DAC_SEARCH,
		    PRIV_FILE_DAC_WRITE,
		    PRIV_FILE_OWNER,
		    NULL);
	}

	return (cr);
}