コード例 #1
0
/*
 * Change the mode on a file.
 * Inode must be locked before calling.
 */
static int
ext2_chmod(struct vnode *vp, int mode, struct ucred *cred, struct thread *td)
{
	struct inode *ip = VTOI(vp);
	int error;

	/*
	 * To modify the permissions on a file, must possess VADMIN
	 * for that file.
	 */
	if ((error = VOP_ACCESS(vp, VADMIN, cred, td)))
		return (error);
	/*
	 * Privileged processes may set the sticky bit on non-directories,
	 * as well as set the setgid bit on a file with a group that the
	 * process is not a member of.
	 */
	if (vp->v_type != VDIR && (mode & S_ISTXT)) {
		error = priv_check_cred(cred, PRIV_VFS_STICKYFILE, 0);
		if (error)
			return (EFTYPE);
	}
	if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) {
		error = priv_check_cred(cred, PRIV_VFS_SETGID, 0);
		if (error)
			return (error);
	}
	ip->i_mode &= ~ALLPERMS;
	ip->i_mode |= (mode & ALLPERMS);
	ip->i_flag |= IN_CHANGE;
	return (0);
}
コード例 #2
0
static int 
random_ioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, struct ucred *cred)
{
	int error;
	int intr;
	
	/*
	 * Even inspecting the state is privileged, since it gives a hint
	 * about how easily the randomness might be guessed.
	 */
	error = 0;

	switch (cmd) {
	/* Really handled in upper layer */
	case FIOASYNC:
		break;
	case MEM_SETIRQ:
		intr = *(int16_t *)data;
		if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0)
			break;
		if (intr < 0 || intr >= MAX_INTS)
			return (EINVAL);
		register_randintr(intr);
		break;
	case MEM_CLEARIRQ:
		intr = *(int16_t *)data;
		if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0)
			break;
		if (intr < 0 || intr >= MAX_INTS)
			return (EINVAL);
		unregister_randintr(intr);
		break;
	case MEM_RETURNIRQ:
		error = ENOTSUP;
		break;
	case MEM_FINDIRQ:
		intr = *(int16_t *)data;
		if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0)
			break;
		if (intr < 0 || intr >= MAX_INTS)
			return (EINVAL);
		intr = next_registered_randintr(intr);
		if (intr == MAX_INTS)
			return (ENOENT);
		*(u_int16_t *)data = intr;
		break;
	default:
		error = ENOTSUP;
		break;
	}
	return (error);
}
コード例 #3
0
static int
mmopen(struct dev_open_args *ap)
{
	cdev_t dev = ap->a_head.a_dev;
	int error;

	switch (minor(dev)) {
	case 0:
	case 1:
		if (ap->a_oflags & FWRITE) {
			if (securelevel > 0 || kernel_mem_readonly)
				return (EPERM);
		}
		error = 0;
		break;
	case 14:
		error = priv_check_cred(ap->a_cred, PRIV_ROOT, 0);
		if (error != 0)
			break;
		if (securelevel > 0 || kernel_mem_readonly) {
			error = EPERM;
			break;
		}
		error = cpu_set_iopl();
		break;
	default:
		error = 0;
		break;
	}
	return (error);
}
コード例 #4
0
ファイル: kern_overrides.c プロジェクト: Bitesher/xnu
/* system call implementation */
int
system_override(__unused struct proc *p, struct system_override_args * uap, __unused int32_t *retval)
{
	uint64_t timeout = uap->timeout;
	uint64_t flags = uap->flags;
	int error = 0;

	/* Check credentials for caller. Only entitled processes are allowed to make this call. */
	if ((error = priv_check_cred(kauth_cred_get(), PRIV_SYSTEM_OVERRIDE, 0))) {
		goto out;
	}	

	/* Check to see if some flags are specified. Zero flags are invalid. */
	if ((flags == 0) || ((flags & ~SYS_OVERRIDE_FLAGS_MASK) != 0)) {
		error = EINVAL;
		goto out;
	}

	lck_mtx_lock(&sys_override_lock);

	enable_system_override(flags);

	PROCESS_OVERRIDING_SYSTEM_DEFAULTS(timeout);

	disable_system_override(flags);

	lck_mtx_unlock(&sys_override_lock);

out:
	return error;
}
コード例 #5
0
ファイル: vm_mmap.c プロジェクト: wan721/DragonFlyBSD
/*
 * mlockall(int how)
 *
 * No requirements
 */
int
sys_mlockall(struct mlockall_args *uap)
{
	struct thread *td = curthread;
	struct proc *p = td->td_proc;
	vm_map_t map = &p->p_vmspace->vm_map;
	vm_map_entry_t entry;
	int how = uap->how;
	int rc = KERN_SUCCESS;

	if (((how & MCL_CURRENT) == 0) && ((how & MCL_FUTURE) == 0))
		return (EINVAL);

	rc = priv_check_cred(td->td_ucred, PRIV_ROOT, 0);
	if (rc) 
		return (rc);

	vm_map_lock(map);
	do {
		if (how & MCL_CURRENT) {
			for(entry = map->header.next;
			    entry != &map->header;
			    entry = entry->next);

			rc = ENOSYS;
			break;
		}
	
		if (how & MCL_FUTURE)
			map->flags |= MAP_WIREFUTURE;
	} while(0);
	vm_map_unlock(map);

	return (rc);
}
コード例 #6
0
ファイル: opensolaris_zone.c プロジェクト: 151706061/osv
int
zone_dataset_attach(struct ucred *cred, const char *dataset, int jailid)
{
	struct zone_dataset_head *head;
	zone_dataset_t *zd, *zd2;
	struct prison *pr;
	int dofree, error;

	if ((error = priv_check_cred(cred, PRIV_ZFS_JAIL, 0)) != 0)
		return (error);

	/* Allocate memory before we grab prison's mutex. */
	zd = malloc(sizeof(*zd) + strlen(dataset) + 1, M_ZONES, M_WAITOK);

	sx_slock(&allprison_lock);
	pr = prison_find(jailid);	/* Locks &pr->pr_mtx. */
	sx_sunlock(&allprison_lock);
	if (pr == NULL) {
		free(zd, M_ZONES);
		return (ENOENT);
	}

	head = osd_jail_get(pr, zone_slot);
	if (head != NULL) {
		dofree = 0;
		LIST_FOREACH(zd2, head, zd_next) {
			if (strcmp(dataset, zd2->zd_dataset) == 0) {
				free(zd, M_ZONES);
				error = EEXIST;
				goto end;
			}
		}
	} else {
コード例 #7
0
int
sys_osethostname(struct sethostname_args *uap)
{
	struct thread *td = curthread;
	size_t len;
	char *hostname;
	int name[2];
	int error;

	name[0] = CTL_KERN;
	name[1] = KERN_HOSTNAME;
	error = priv_check_cred(td->td_ucred, PRIV_SETHOSTNAME, 0);
	if (error)
		return (error);
	len = MIN(uap->len, MAXHOSTNAMELEN);
	hostname = kmalloc(MAXHOSTNAMELEN, M_TEMP, M_WAITOK);

	error = copyin(uap->hostname, hostname, len);
	if (error) {
		kfree(hostname, M_TEMP);
		return (error);
	}

	error = kernel_sysctl(name, 2, NULL, 0, hostname, len, NULL);

	kfree(hostname, M_TEMP);
	return (error);
}
コード例 #8
0
ファイル: kern_prot.c プロジェクト: AhmadTux/DragonFlyBSD
int
sys_setegid(struct setegid_args *uap)
{
	struct proc *p = curproc;
	struct ucred *cr;
	gid_t egid;
	int error;

	lwkt_gettoken(&proc_token);
	cr = p->p_ucred;
	egid = uap->egid;
	if (egid != cr->cr_rgid &&		/* allow setegid(getgid()) */
	    egid != cr->cr_svgid &&		/* allow setegid(saved gid) */
	    (error = priv_check_cred(cr, PRIV_CRED_SETEGID, 0))) {
		goto done;
	}
	if (cr->cr_groups[0] != egid) {
		cr = cratom(&p->p_ucred);
		cr->cr_groups[0] = egid;
		setsugid();
	}
	error = 0;
done:
	lwkt_reltoken(&proc_token);
	return (error);
}
コード例 #9
0
/* ARGSUSED */
int
setauid(struct thread *td, struct setauid_args *uap)
{
	struct ucred *newcred, *oldcred;
	au_id_t id;
	int error;

	if (jailed(td->td_ucred))
		return (ENOSYS);
	error = copyin(uap->auid, &id, sizeof(id));
	if (error)
		return (error);
	audit_arg_auid(id);
	newcred = crget();
	PROC_LOCK(td->td_proc);
	oldcred = td->td_proc->p_ucred;
	crcopy(newcred, oldcred);
#ifdef MAC
	error = mac_cred_check_setauid(oldcred, id);
	if (error)
		goto fail;
#endif
	error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0);
	if (error)
		goto fail;
	newcred->cr_audit.ai_auid = id;
	td->td_proc->p_ucred = newcred;
	PROC_UNLOCK(td->td_proc);
	crfree(oldcred);
	return (0);
fail:
	PROC_UNLOCK(td->td_proc);
	crfree(newcred);
	return (error);
}
コード例 #10
0
ファイル: kern_prot.c プロジェクト: AhmadTux/DragonFlyBSD
int
sys_seteuid(struct seteuid_args *uap)
{
	struct proc *p = curproc;
	struct ucred *cr;
	uid_t euid;
	int error;

	lwkt_gettoken(&proc_token);
	cr = p->p_ucred;
	euid = uap->euid;
	if (euid != cr->cr_ruid &&		/* allow seteuid(getuid()) */
	    euid != cr->cr_svuid &&		/* allow seteuid(saved uid) */
	    (error = priv_check_cred(cr, PRIV_CRED_SETEUID, 0))) {
		lwkt_reltoken(&proc_token);
		return (error);
	}

	/*
	 * Everything's okay, do it.  Copy credentials so other references do
	 * not see our changes.
	 */
	if (cr->cr_uid != euid) {
		change_euid(euid);
		setsugid();
	}
	lwkt_reltoken(&proc_token);
	return (0);
}
コード例 #11
0
ファイル: uipc_sem.c プロジェクト: rchander/freebsd
static int
ksem_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
    struct thread *td)
{
	struct ksem *ks;
	int error;

	error = 0;
	ks = fp->f_data;
	mtx_lock(&sem_lock);
#ifdef MAC
	error = mac_posixsem_check_setowner(active_cred, ks, uid, gid);
	if (error != 0)
		goto out;
#endif
	if (uid == (uid_t)-1)
		uid = ks->ks_uid;
	if (gid == (gid_t)-1)
                 gid = ks->ks_gid;
	if (((uid != ks->ks_uid && uid != active_cred->cr_uid) ||
	    (gid != ks->ks_gid && !groupmember(gid, active_cred))) &&
	    (error = priv_check_cred(active_cred, PRIV_VFS_CHOWN, 0)))
		goto out;
	ks->ks_uid = uid;
	ks->ks_gid = gid;
out:
	mtx_unlock(&sem_lock);
	return (error);
}
コード例 #12
0
int
vop_helper_setattr_flags(u_int32_t *ino_flags, u_int32_t vaflags,
			 uid_t uid, struct ucred *cred)
{
	int error;

	/*
	 * If uid doesn't match only a privileged user can change the flags
	 */
	if (cred->cr_uid != uid &&
	    (error = priv_check_cred(cred, PRIV_VFS_SYSFLAGS, 0))) {
		return(error);
	}
	if (cred->cr_uid == 0 &&
	    (!jailed(cred)|| jail_chflags_allowed)) {
		if ((*ino_flags & (SF_NOUNLINK|SF_IMMUTABLE|SF_APPEND)) &&
		    securelevel > 0)
			return (EPERM);
		*ino_flags = vaflags;
	} else {
		if (*ino_flags & (SF_NOUNLINK|SF_IMMUTABLE|SF_APPEND) ||
		    (vaflags & UF_SETTABLE) != vaflags)
			return (EPERM);
		*ino_flags &= SF_SETTABLE;
		*ino_flags |= vaflags & UF_SETTABLE;
	}
	return(0);
}
コード例 #13
0
ファイル: mac_seeotheruids.c プロジェクト: 2asoft/freebsd
static int
seeotheruids_check(struct ucred *cr1, struct ucred *cr2)
{

	if (!seeotheruids_enabled)
		return (0);

	if (primarygroup_enabled) {
		if (cr1->cr_rgid == cr2->cr_rgid)
			return (0);
	}

	if (specificgid_enabled) {
		if (cr1->cr_rgid == specificgid ||
		    groupmember(specificgid, cr1))
			return (0);
	}

	if (cr1->cr_ruid == cr2->cr_ruid)
		return (0);

	if (suser_privileged) {
		if (priv_check_cred(cr1, PRIV_SEEOTHERUIDS, 0) == 0)
			return (0);
	}

	return (ESRCH);
}
コード例 #14
0
/*
 * Object-specific entry points are sorted alphabetically by object type name
 * and then by operation.
 */
static int
partition_cred_check_relabel(struct ucred *cred, struct label *newlabel)
{
	int error;

	error = 0;

	/*
	 * Treat "0" as a no-op request because it reflects an unset
	 * partition label.  If we ever want to support switching back to an
	 * unpartitioned state for a process, we'll need to differentiate the
	 * "not in a partition" and "no partition defined during internalize"
	 * conditions.
	 */
	if (SLOT(newlabel) != 0) {
		/*
		 * Require BSD privilege in order to change the partition.
		 * Originally we also required that the process not be in a
		 * partition in the first place, but this didn't interact
		 * well with sendmail.
		 */
		error = priv_check_cred(cred, PRIV_MAC_PARTITION, 0);
	}

	return (error);
}
コード例 #15
0
ファイル: uipc_shm.c プロジェクト: BillTheBest/libuinet
static int
shm_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
    struct thread *td)
{
	struct shmfd *shmfd;
	int error;

	error = 0;
	shmfd = fp->f_data;
	mtx_lock(&shm_timestamp_lock);
#ifdef MAC
	error = mac_posixshm_check_setowner(active_cred, shmfd, uid, gid);
	if (error != 0)
		goto out;
#endif
	if (uid == (uid_t)-1)
		uid = shmfd->shm_uid;
	if (gid == (gid_t)-1)
                 gid = shmfd->shm_gid;
	if (((uid != shmfd->shm_uid && uid != active_cred->cr_uid) ||
	    (gid != shmfd->shm_gid && !groupmember(gid, active_cred))) &&
	    (error = priv_check_cred(active_cred, PRIV_VFS_CHOWN, 0)))
		goto out;
	shmfd->shm_uid = uid;
	shmfd->shm_gid = gid;
out:
	mtx_unlock(&shm_timestamp_lock);
	return (error);
}
コード例 #16
0
ファイル: kern_prot.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * Test whether the specified credentials have the privilege
 * in question.
 *
 * A kernel thread without a process context is assumed to have 
 * the privilege in question.  In situations where the caller always 
 * expect a cred to exist, the cred should be passed separately and 
 * priv_check_cred() should be used instead of priv_check().
 *
 * Returns 0 or error.
 *
 * MPSAFE
 */
int
priv_check(struct thread *td, int priv)
{
	if (td->td_lwp != NULL)
		return priv_check_cred(td->td_ucred, priv, 0);
	return (0);
}
コード例 #17
0
ファイル: kern_prot.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * Set login name.
 */
int
sys_setlogin(struct setlogin_args *uap)
{
	struct thread *td = curthread;
	struct proc *p;
	struct ucred *cred;
	char buf[MAXLOGNAME];
	int error;

	cred = td->td_ucred;
	p = td->td_proc;

	if ((error = priv_check_cred(cred, PRIV_PROC_SETLOGIN, 0)))
		return (error);
	bzero(buf, sizeof(buf));
	error = copyinstr(uap->namebuf, buf, sizeof(buf), NULL);
	if (error == ENAMETOOLONG)
		error = EINVAL;
	if (error == 0) {
		lwkt_gettoken(&proc_token);
		memcpy(p->p_pgrp->pg_session->s_login, buf, sizeof(buf));
		lwkt_reltoken(&proc_token);
	}
	return (error);
}
コード例 #18
0
ファイル: kern_priv.c プロジェクト: 2asoft/freebsd
int
priv_check(struct thread *td, int priv)
{

	KASSERT(td == curthread, ("priv_check: td != curthread"));

	return (priv_check_cred(td->td_ucred, priv, 0));
}
コード例 #19
0
int
secpolicy_vnode_setdac(kauth_cred_t cred, uid_t owner)
{

	if (owner == cred->cr_uid)
		return (0);
	return (priv_check_cred(cred, PRIV_VFS_ADMIN, 0));
}
コード例 #20
0
ファイル: uipc_sem.c プロジェクト: rchander/freebsd
/*
 * Determine if the credentials have sufficient permissions for read
 * and write access.
 */
static int
ksem_access(struct ksem *ks, struct ucred *ucred)
{
	int error;

	error = vaccess(VREG, ks->ks_mode, ks->ks_uid, ks->ks_gid,
	    VREAD | VWRITE, ucred, NULL);
	if (error)
		error = priv_check_cred(ucred, PRIV_SEM_WRITE, 0);
	return (error);
}
コード例 #21
0
/*
 * Perform chown operation on inode ip;
 * inode must be locked prior to call.
 */
static int
ext2_chown(struct vnode *vp, uid_t uid, gid_t gid, struct ucred *cred,
    struct thread *td)
{
	struct inode *ip = VTOI(vp);
	uid_t ouid;
	gid_t ogid;
	int error = 0;

	if (uid == (uid_t)VNOVAL)
		uid = ip->i_uid;
	if (gid == (gid_t)VNOVAL)
		gid = ip->i_gid;
	/*
	 * To modify the ownership of a file, must possess VADMIN
	 * for that file.
	 */
	if ((error = VOP_ACCESS(vp, VADMIN, cred, td)))
		return (error);
	/*
	 * To change the owner of a file, or change the group of a file
	 * to a group of which we are not a member, the caller must
	 * have privilege.
	 */
	if (uid != ip->i_uid || (gid != ip->i_gid &&
	    !groupmember(gid, cred))) {
		error = priv_check_cred(cred, PRIV_VFS_CHOWN, 0);
		if (error)
			return (error);
	}
	ogid = ip->i_gid;
	ouid = ip->i_uid;
	ip->i_gid = gid;
	ip->i_uid = uid;
	ip->i_flag |= IN_CHANGE;
	if ((ip->i_mode & (ISUID | ISGID)) && (ouid != uid || ogid != gid)) {
		if (priv_check_cred(cred, PRIV_VFS_RETAINSUGID, 0) != 0)
			ip->i_mode &= ~(ISUID | ISGID);
	}
	return (0);
}
コード例 #22
0
ファイル: tmpfs_vnops.c プロジェクト: ChaosJohn/freebsd
static int
tmpfs_write(struct vop_write_args *v)
{
	struct vnode *vp;
	struct uio *uio;
	struct tmpfs_node *node;
	off_t oldsize;
	int error, ioflag;
	boolean_t extended;

	vp = v->a_vp;
	uio = v->a_uio;
	ioflag = v->a_ioflag;
	error = 0;
	node = VP_TO_TMPFS_NODE(vp);
	oldsize = node->tn_size;

	if (uio->uio_offset < 0 || vp->v_type != VREG)
		return (EINVAL);
	if (uio->uio_resid == 0)
		return (0);
	if (ioflag & IO_APPEND)
		uio->uio_offset = node->tn_size;
	if (uio->uio_offset + uio->uio_resid >
	  VFS_TO_TMPFS(vp->v_mount)->tm_maxfilesize)
		return (EFBIG);
	if (vn_rlimit_fsize(vp, uio, uio->uio_td))
		return (EFBIG);
	extended = uio->uio_offset + uio->uio_resid > node->tn_size;
	if (extended) {
		error = tmpfs_reg_resize(vp, uio->uio_offset + uio->uio_resid,
		    FALSE);
		if (error != 0)
			goto out;
	}

	error = uiomove_object(node->tn_reg.tn_aobj, node->tn_size, uio);
	node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED |
	    (extended ? TMPFS_NODE_CHANGED : 0);
	if (node->tn_mode & (S_ISUID | S_ISGID)) {
		if (priv_check_cred(v->a_cred, PRIV_VFS_RETAINSUGID, 0))
			node->tn_mode &= ~(S_ISUID | S_ISGID);
	}
	if (error != 0)
		(void)tmpfs_reg_resize(vp, oldsize, TRUE);

out:
	MPASS(IMPLIES(error == 0, uio->uio_resid == 0));
	MPASS(IMPLIES(error != 0, oldsize == node->tn_size));

	return (error);
}
コード例 #23
0
void
secpolicy_setid_clear(struct vattr *vap, kauth_cred_t cred)
{

	if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL))
		return;

	if ((vap->va_mode & (S_ISUID | S_ISGID)) != 0) {
		if (priv_check_cred(cred, PRIV_VFS_RETAINSUGID, 0)) {
			vap->va_mask |= AT_MODE;
			vap->va_mode &= ~(S_ISUID|S_ISGID);
		}
	}
}
コード例 #24
0
ファイル: ng_socket.c プロジェクト: wan721/DragonFlyBSD
static void
ngc_attach(netmsg_t msg)
{
	struct socket *so = msg->attach.base.nm_so;
	struct pru_attach_info *ai = msg->attach.nm_ai;
	struct ngpcb *const pcbp = sotongpcb(so);
	int error;

	if (priv_check_cred(ai->p_ucred, PRIV_ROOT, NULL_CRED_OKAY) != 0)
		error = EPERM;
	else if (pcbp != NULL)
		error = EISCONN;
	else
		error = ng_attach_cntl(so);
	lwkt_replymsg(&msg->attach.base.lmsg, error);
}
コード例 #25
0
ファイル: vm_mmap.c プロジェクト: wan721/DragonFlyBSD
/*
 * mlock system call handler
 *
 * mlock_args(const void *addr, size_t len)
 *
 * No requirements
 */
int
sys_mlock(struct mlock_args *uap)
{
	vm_offset_t addr;
	vm_offset_t tmpaddr;
	vm_size_t size, pageoff;
	struct thread *td = curthread;
	struct proc *p = td->td_proc;
	int error;

	addr = (vm_offset_t) uap->addr;
	size = uap->len;

	pageoff = (addr & PAGE_MASK);
	addr -= pageoff;
	size += pageoff;
	size = (vm_size_t) round_page(size);
	if (size < uap->len)		/* wrap */
		return(EINVAL);
	tmpaddr = addr + size;		/* workaround gcc4 opt */
	if (tmpaddr < addr)		/* wrap */
		return (EINVAL);

	if (atop(size) + vmstats.v_wire_count > vm_page_max_wired)
		return (EAGAIN);

	/* 
	 * We do not need to synchronize against other threads updating ucred;
	 * they update p->ucred, which is synchronized into td_ucred ourselves.
	 */
#ifdef pmap_wired_count
	if (size + ptoa(pmap_wired_count(vm_map_pmap(&p->p_vmspace->vm_map))) >
	    p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur) {
		return (ENOMEM);
	}
#else
	error = priv_check_cred(td->td_ucred, PRIV_ROOT, 0);
	if (error) {
		return (error);
	}
#endif
	error = vm_map_unwire(&p->p_vmspace->vm_map, addr, addr + size, FALSE);
	return (error == KERN_SUCCESS ? 0 : ENOMEM);
}
コード例 #26
0
ファイル: kern_prot.c プロジェクト: AhmadTux/DragonFlyBSD
int
sys_setgroups(struct setgroups_args *uap)
{
	struct proc *p = curproc;
	struct ucred *cr;
	u_int ngrp;
	int error;

	lwkt_gettoken(&proc_token);
	cr = p->p_ucred;

	if ((error = priv_check_cred(cr, PRIV_CRED_SETGROUPS, 0)))
		goto done;
	ngrp = uap->gidsetsize;
	if (ngrp > NGROUPS) {
		error = EINVAL;
		goto done;
	}
	/*
	 * XXX A little bit lazy here.  We could test if anything has
	 * changed before cratom() and setting P_SUGID.
	 */
	cr = cratom(&p->p_ucred);
	if (ngrp < 1) {
		/*
		 * setgroups(0, NULL) is a legitimate way of clearing the
		 * groups vector on non-BSD systems (which generally do not
		 * have the egid in the groups[0]).  We risk security holes
		 * when running non-BSD software if we do not do the same.
		 */
		cr->cr_ngroups = 1;
	} else {
		error = copyin(uap->gidset, cr->cr_groups,
			       ngrp * sizeof(gid_t));
		if (error)
			goto done;
		cr->cr_ngroups = ngrp;
	}
	setsugid();
	error = 0;
done:
	lwkt_reltoken(&proc_token);
	return (error);
}
コード例 #27
0
ファイル: kern_prot.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * Return zero if p1 can fondle p2, return errno (EPERM/ESRCH) otherwise.
 */
int
p_trespass(struct ucred *cr1, struct ucred *cr2)
{
	if (cr1 == cr2)
		return (0);
	if (!PRISON_CHECK(cr1, cr2))
		return (ESRCH);
	if (cr1->cr_ruid == cr2->cr_ruid)
		return (0);
	if (cr1->cr_uid == cr2->cr_ruid)
		return (0);
	if (cr1->cr_ruid == cr2->cr_uid)
		return (0);
	if (cr1->cr_uid == cr2->cr_uid)
		return (0);
	if (priv_check_cred(cr1, PRIV_PROC_TRESPASS, 0) == 0)
		return (0);
	return (EPERM);
}
コード例 #28
0
ファイル: kern_prot.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * setresgid(rgid, egid, sgid) is like setregid except control over the
 * saved gid is explicit.
 */
int
sys_setresgid(struct setresgid_args *uap)
{
	struct proc *p = curproc;
	struct ucred *cr;
	gid_t rgid, egid, sgid;
	int error;

	lwkt_gettoken(&proc_token);
	cr = p->p_ucred;
	rgid = uap->rgid;
	egid = uap->egid;
	sgid = uap->sgid;
	if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && rgid != cr->cr_svgid &&
	      rgid != cr->cr_groups[0]) ||
	     (egid != (gid_t)-1 && egid != cr->cr_rgid && egid != cr->cr_svgid &&
	      egid != cr->cr_groups[0]) ||
	     (sgid != (gid_t)-1 && sgid != cr->cr_rgid && sgid != cr->cr_svgid &&
	      sgid != cr->cr_groups[0])) &&
	    (error = priv_check_cred(cr, PRIV_CRED_SETRESGID, 0)) != 0) {
		goto done;
	}

	if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) {
		cr = cratom(&p->p_ucred);
		cr->cr_groups[0] = egid;
		setsugid();
	}
	if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) {
		cr = cratom(&p->p_ucred);
		cr->cr_rgid = rgid;
		setsugid();
	}
	if (sgid != (gid_t)-1 && cr->cr_svgid != sgid) {
		cr = cratom(&p->p_ucred);
		cr->cr_svgid = sgid;
		setsugid();
	}
	error = 0;
done:
	lwkt_reltoken(&proc_token);
	return (error);
}
コード例 #29
0
/* ARGSUSED */
int
setaudit(struct thread *td, struct setaudit_args *uap)
{
	struct ucred *newcred, *oldcred;
	struct auditinfo ai;
	int error;

	if (jailed(td->td_ucred))
		return (ENOSYS);
	error = copyin(uap->auditinfo, &ai, sizeof(ai));
	if (error)
		return (error);
	audit_arg_auditinfo(&ai);
	newcred = crget();
	PROC_LOCK(td->td_proc);
	oldcred = td->td_proc->p_ucred;
	crcopy(newcred, oldcred);
#ifdef MAC
	error = mac_cred_check_setaudit(oldcred, &ai);
	if (error)
		goto fail;
#endif
	error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0);
	if (error)
		goto fail;
	bzero(&newcred->cr_audit, sizeof(newcred->cr_audit));
	newcred->cr_audit.ai_auid = ai.ai_auid;
	newcred->cr_audit.ai_mask = ai.ai_mask;
	newcred->cr_audit.ai_asid = ai.ai_asid;
	newcred->cr_audit.ai_termid.at_addr[0] = ai.ai_termid.machine;
	newcred->cr_audit.ai_termid.at_port = ai.ai_termid.port;
	newcred->cr_audit.ai_termid.at_type = AU_IPv4;
	td->td_proc->p_ucred = newcred;
	PROC_UNLOCK(td->td_proc);
	crfree(oldcred);
	return (0);
fail:
	PROC_UNLOCK(td->td_proc);
	crfree(newcred);
	return (error);
}
コード例 #30
0
ファイル: kern_prot.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * setresuid(ruid, euid, suid) is like setreuid except control over the
 * saved uid is explicit.
 */
int
sys_setresuid(struct setresuid_args *uap)
{
	struct proc *p = curproc;
	struct ucred *cr;
	uid_t ruid, euid, suid;
	int error;

	lwkt_gettoken(&proc_token);
	cr = p->p_ucred;

	ruid = uap->ruid;
	euid = uap->euid;
	suid = uap->suid;
	if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && ruid != cr->cr_svuid &&
	      ruid != cr->cr_uid) ||
	     (euid != (uid_t)-1 && euid != cr->cr_ruid && euid != cr->cr_svuid &&
	      euid != cr->cr_uid) ||
	     (suid != (uid_t)-1 && suid != cr->cr_ruid && suid != cr->cr_svuid &&
	      suid != cr->cr_uid)) &&
	    (error = priv_check_cred(cr, PRIV_CRED_SETRESUID, 0)) != 0) {
		goto done;
	}
	if (euid != (uid_t)-1 && cr->cr_uid != euid) {
		cr = change_euid(euid);
		setsugid();
	}
	if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) {
		cr = change_ruid(ruid);
		setsugid();
	}
	if (suid != (uid_t)-1 && cr->cr_svuid != suid) {
		cr = cratom(&p->p_ucred);
		cr->cr_svuid = suid;
		setsugid();
	}
	error = 0;
done:
	lwkt_reltoken(&proc_token);
	return (error);
}