/* * 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); }
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); } }
/* * 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); }
/* * 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); }
/* * 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); }