Beispiel #1
0
int
do_setresgid(struct lwp *l, gid_t r, gid_t e, gid_t sv, u_int flags)
{
	struct proc *p = l->l_proc;
	kauth_cred_t cred, ncred;

	ncred = kauth_cred_alloc();

	/* Get a write lock on the process credential. */
	proc_crmod_enter();
	cred = p->p_cred;

	/*
	 * check new value is one of the allowed existing values.
	 * otherwise, check if we have root privilege.
	 */
	if ((r != -1
	    && !((flags & ID_R_EQ_R) && r == kauth_cred_getgid(cred))
	    && !((flags & ID_R_EQ_E) && r == kauth_cred_getegid(cred))
	    && !((flags & ID_R_EQ_S) && r == kauth_cred_getsvgid(cred))) ||
	    (e != -1
	    && !((flags & ID_E_EQ_R) && e == kauth_cred_getgid(cred))
	    && !((flags & ID_E_EQ_E) && e == kauth_cred_getegid(cred))
	    && !((flags & ID_E_EQ_S) && e == kauth_cred_getsvgid(cred))) ||
	    (sv != -1
	    && !((flags & ID_S_EQ_R) && sv == kauth_cred_getgid(cred))
	    && !((flags & ID_S_EQ_E) && sv == kauth_cred_getegid(cred))
	    && !((flags & ID_S_EQ_S) && sv == kauth_cred_getsvgid(cred)))) {
		int error;

		error = kauth_authorize_process(cred, KAUTH_PROCESS_SETID,
		    p, NULL, NULL, NULL);
		if (error != 0) {
		 	proc_crmod_leave(cred, ncred, false);
			return error;
		}
	}

	/* If nothing has changed, short circuit the request */
	if ((r == -1 || r == kauth_cred_getgid(cred))
	    && (e == -1 || e == kauth_cred_getegid(cred))
	    && (sv == -1 || sv == kauth_cred_getsvgid(cred))) {
	 	proc_crmod_leave(cred, ncred, false);
		return 0;
	}

	kauth_cred_clone(cred, ncred);

	if (r != -1)
		kauth_cred_setgid(ncred, r);
	if (sv != -1)
		kauth_cred_setsvgid(ncred, sv);
	if (e != -1)
		kauth_cred_setegid(ncred, e);

	/* Broadcast our credentials to the process and other LWPs. */
 	proc_crmod_leave(ncred, cred, true);

	return 0;
}
Beispiel #2
0
kauth_cred_t
rump_cred_create(uid_t uid, gid_t gid, size_t ngroups, gid_t *groups)
{
	kauth_cred_t cred;
	int rv;

	cred = kauth_cred_alloc();
	kauth_cred_setuid(cred, uid);
	kauth_cred_seteuid(cred, uid);
	kauth_cred_setsvuid(cred, uid);
	kauth_cred_setgid(cred, gid);
	kauth_cred_setgid(cred, gid);
	kauth_cred_setegid(cred, gid);
	kauth_cred_setsvgid(cred, gid);
	rv = kauth_cred_setgroups(cred, groups, ngroups, 0, UIO_SYSSPACE);
	/* oh this is silly.  and by "this" I mean kauth_cred_setgroups() */
	assert(rv == 0);

	return cred;
}
Beispiel #3
0
/* ARGSUSED */
int
sys_setgroups(struct lwp *l, const struct sys_setgroups_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) gidsetsize;
		syscallarg(const gid_t *) gidset;
	} */
	kauth_cred_t ncred;
	int error;

	ncred = kauth_cred_alloc();
	error = kauth_cred_setgroups(ncred, SCARG(uap, gidset),
	    SCARG(uap, gidsetsize), -1, UIO_USERSPACE);
	if (error != 0) {
		kauth_cred_free(ncred);
		return error;
	}

	return kauth_proc_setgroups(l, ncred);
}
Beispiel #4
0
int
do_setresuid(struct lwp *l, uid_t r, uid_t e, uid_t sv, u_int flags)
{
	struct proc *p = l->l_proc;
	kauth_cred_t cred, ncred;

	ncred = kauth_cred_alloc();

	/* Get a write lock on the process credential. */
	proc_crmod_enter();
	cred = p->p_cred;

	/*
	 * Check that the new value is one of the allowed existing values,
	 * or that we have root privilege.
	 */
	if ((r != -1
	    && !((flags & ID_R_EQ_R) && r == kauth_cred_getuid(cred))
	    && !((flags & ID_R_EQ_E) && r == kauth_cred_geteuid(cred))
	    && !((flags & ID_R_EQ_S) && r == kauth_cred_getsvuid(cred))) ||
	    (e != -1
	    && !((flags & ID_E_EQ_R) && e == kauth_cred_getuid(cred))
	    && !((flags & ID_E_EQ_E) && e == kauth_cred_geteuid(cred))
	    && !((flags & ID_E_EQ_S) && e == kauth_cred_getsvuid(cred))) ||
	    (sv != -1
	    && !((flags & ID_S_EQ_R) && sv == kauth_cred_getuid(cred))
	    && !((flags & ID_S_EQ_E) && sv == kauth_cred_geteuid(cred))
	    && !((flags & ID_S_EQ_S) && sv == kauth_cred_getsvuid(cred)))) {
		int error;

		error = kauth_authorize_process(cred, KAUTH_PROCESS_SETID,
		    p, NULL, NULL, NULL);
		if (error != 0) {
		 	proc_crmod_leave(cred, ncred, false);
			return error;
		}
	}

	/* If nothing has changed, short circuit the request */
	if ((r == -1 || r == kauth_cred_getuid(cred))
	    && (e == -1 || e == kauth_cred_geteuid(cred))
	    && (sv == -1 || sv == kauth_cred_getsvuid(cred))) {
		proc_crmod_leave(cred, ncred, false);
		return 0;
	}

	kauth_cred_clone(cred, ncred);

	if (r != -1 && r != kauth_cred_getuid(ncred)) {
		u_long nlwps;

		/* Update count of processes for this user. */
		(void)chgproccnt(kauth_cred_getuid(ncred), -1);
		(void)chgproccnt(r, 1);

		/* The first LWP of a process is excluded. */
		KASSERT(mutex_owned(p->p_lock));
		nlwps = p->p_nlwps - 1;
		(void)chglwpcnt(kauth_cred_getuid(ncred), -nlwps);
		(void)chglwpcnt(r, nlwps);

		kauth_cred_setuid(ncred, r);
	}
	if (sv != -1)
		kauth_cred_setsvuid(ncred, sv);
	if (e != -1)
		kauth_cred_seteuid(ncred, e);

	/* Broadcast our credentials to the process and other LWPs. */
 	proc_crmod_leave(ncred, cred, true);

	return 0;
}
static void
ptyfs_getinfo(struct ptyfsnode *ptyfs, struct lwp *l)
{
	extern struct ptm_pty *ptyfs_save_ptm, ptm_ptyfspty;

	if (ptyfs->ptyfs_type == PTYFSroot) {
		ptyfs->ptyfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|
		    S_IROTH|S_IXOTH;
		goto out;
	} else
		ptyfs->ptyfs_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
		    S_IROTH|S_IWOTH;

	if (ptyfs_save_ptm != NULL && ptyfs_save_ptm != &ptm_ptyfspty) {
		int error;
		struct pathbuf *pb;
		struct nameidata nd;
		char ttyname[64];
		kauth_cred_t cred;
		struct vattr va;

		/*
		 * We support traditional ptys, so we copy the info
		 * from the inode
		 */
		if ((error = (*ptyfs_save_ptm->makename)(
			ptyfs_save_ptm, l, ttyname, sizeof(ttyname),
			ptyfs->ptyfs_pty, ptyfs->ptyfs_type == PTYFSpts ? 't'
			: 'p')) != 0)
				goto out;
		pb = pathbuf_create(ttyname);
		if (pb == NULL) {
			error = ENOMEM;
 			goto out;
		}
		NDINIT(&nd, LOOKUP, NOFOLLOW|LOCKLEAF, pb);
		if ((error = namei(&nd)) != 0) {
			pathbuf_destroy(pb);
			goto out;
		}
		cred = kauth_cred_alloc();
		error = VOP_GETATTR(nd.ni_vp, &va, cred);
		kauth_cred_free(cred);
		VOP_UNLOCK(nd.ni_vp);
		vrele(nd.ni_vp);
		pathbuf_destroy(pb);
		if (error)
			goto out;
		ptyfs->ptyfs_uid = va.va_uid;
		ptyfs->ptyfs_gid = va.va_gid;
		ptyfs->ptyfs_mode = va.va_mode;
		ptyfs->ptyfs_flags = va.va_flags;
		ptyfs->ptyfs_birthtime = va.va_birthtime;
		ptyfs->ptyfs_ctime = va.va_ctime;
		ptyfs->ptyfs_mtime = va.va_mtime;
		ptyfs->ptyfs_atime = va.va_atime;
		return;
	}
out:
	ptyfs->ptyfs_uid = ptyfs->ptyfs_gid = 0;
	ptyfs->ptyfs_status |= PTYFS_CHANGE;
	PTYFS_ITIMES(ptyfs, NULL, NULL, NULL);
	ptyfs->ptyfs_birthtime = ptyfs->ptyfs_mtime =
	    ptyfs->ptyfs_atime = ptyfs->ptyfs_ctime;
	ptyfs->ptyfs_flags = 0;
}
Beispiel #6
0
/*
 * nfs statvfs call
 */
int
nfs_statvfs(struct mount *mp, struct statvfs *sbp)
{
	struct lwp *l = curlwp;
	struct vnode *vp;
	struct nfs_statfs *sfp;
	char *cp;
	u_int32_t *tl;
	int32_t t1, t2;
	char *bpos, *dpos, *cp2;
	struct nfsmount *nmp = VFSTONFS(mp);
	int error = 0, retattr;
#ifdef NFS_V2_ONLY
	const int v3 = 0;
#else
	int v3 = (nmp->nm_flag & NFSMNT_NFSV3);
#endif
	struct mbuf *mreq, *mrep = NULL, *md, *mb;
	kauth_cred_t cred;
	u_quad_t tquad;
	struct nfsnode *np;

#ifndef nolint
	sfp = (struct nfs_statfs *)0;
#endif
	vp = nmp->nm_vnode;
	np = VTONFS(vp);
	cred = kauth_cred_alloc();
#ifndef NFS_V2_ONLY
	if (v3 && (nmp->nm_iflag & NFSMNT_GOTFSINFO) == 0)
		(void)nfs_fsinfo(nmp, vp, cred, l);
#endif
	nfsstats.rpccnt[NFSPROC_FSSTAT]++;
	nfsm_reqhead(np, NFSPROC_FSSTAT, NFSX_FH(v3));
	nfsm_fhtom(np, v3);
	nfsm_request(np, NFSPROC_FSSTAT, l, cred);
	if (v3)
		nfsm_postop_attr(vp, retattr, 0);
	if (error) {
		if (mrep != NULL) {
			if (mrep->m_next != NULL)
				printf("nfs_vfsops: nfs_statvfs would lose buffers\n");
			m_freem(mrep);
		}
		goto nfsmout;
	}
	nfsm_dissect(sfp, struct nfs_statfs *, NFSX_STATFS(v3));
	sbp->f_flag = nmp->nm_flag;
	sbp->f_iosize = min(nmp->nm_rsize, nmp->nm_wsize);
	if (v3) {
		sbp->f_frsize = sbp->f_bsize = NFS_FABLKSIZE;
		tquad = fxdr_hyper(&sfp->sf_tbytes);
		sbp->f_blocks = ((quad_t)tquad / (quad_t)NFS_FABLKSIZE);
		tquad = fxdr_hyper(&sfp->sf_fbytes);
		sbp->f_bfree = ((quad_t)tquad / (quad_t)NFS_FABLKSIZE);
		tquad = fxdr_hyper(&sfp->sf_abytes);
		tquad = ((quad_t)tquad / (quad_t)NFS_FABLKSIZE);
		sbp->f_bresvd = sbp->f_bfree - tquad;
		sbp->f_bavail = tquad;
		/* Handle older NFS servers returning negative values */
		if ((quad_t)sbp->f_bavail < 0)
			sbp->f_bavail = 0;
		tquad = fxdr_hyper(&sfp->sf_tfiles);
		sbp->f_files = tquad;
		tquad = fxdr_hyper(&sfp->sf_ffiles);
		sbp->f_ffree = tquad;
		sbp->f_favail = tquad;
		sbp->f_fresvd = 0;
		sbp->f_namemax = NFS_MAXNAMLEN;
	} else {
		sbp->f_bsize = NFS_FABLKSIZE;
		sbp->f_frsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
		sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
		sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree);
		sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail);
		sbp->f_fresvd = 0;
		sbp->f_files = 0;
		sbp->f_ffree = 0;
		sbp->f_favail = 0;
		sbp->f_fresvd = 0;
		sbp->f_namemax = NFS_MAXNAMLEN;
	}
	copy_statvfs_info(sbp, mp);
	nfsm_reqdone;
	kauth_cred_free(cred);
	return (error);
}