Example #1
0
int
secpolicy_setid_setsticky_clear(struct vnode *vp, struct vattr *vap,
    const struct vattr *ovap, kauth_cred_t cred)
{
	/*
	 * 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. Both of these are allowed in jail(8).
	 */
	if (vp->v_type != VDIR && (vap->va_mode & S_ISTXT)) {
		if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL))
			return (EFTYPE);
	}
	/*
	 * Check for privilege if attempting to set the
	 * group-id bit.
	 */
	if ((vap->va_mode & S_ISGID) != 0)
		return (secpolicy_vnode_setids_setgids(cred, ovap->va_gid));

	return (0);
}
Example #2
0
static int
xdirmakexnode(
	struct xmemnode *dir,
	struct xmount	*xm,
	struct vattr	*va,
	enum	de_op	op,
	struct xmemnode **newnode,
	struct cred	*cred)
{
	struct xmemnode *xp;
	enum vtype	type;

	ASSERT(va != NULL);
	ASSERT(op == DE_CREATE || op == DE_MKDIR);
	if (((va->va_mask & AT_ATIME) && TIMESPEC_OVERFLOW(&va->va_atime)) ||
	    ((va->va_mask & AT_MTIME) && TIMESPEC_OVERFLOW(&va->va_mtime)))
		return (EOVERFLOW);
	type = va->va_type;
	xp = xmem_memalloc(sizeof (struct xmemnode), 1);
	xp->xn_vnode = vn_alloc(KM_SLEEP);
	xmemnode_init(xm, xp, va, cred);
	if (type == VBLK || type == VCHR) {
		xp->xn_vnode->v_rdev = xp->xn_rdev = va->va_rdev;
	} else {
		xp->xn_vnode->v_rdev = xp->xn_rdev = NODEV;
	}
	xp->xn_vnode->v_type = type;
	xp->xn_uid = crgetuid(cred);

	/*
	 * To determine the group-id of the created file:
	 *   1) If the gid is set in the attribute list (non-Sun & pre-4.0
	 *	clients are not likely to set the gid), then use it if
	 *	the process is privileged, belongs to the target group,
	 *	or the group is the same as the parent directory.
	 *   2) If the filesystem was not mounted with the Old-BSD-compatible
	 *	GRPID option, and the directory's set-gid bit is clear,
	 *	then use the process's gid.
	 *   3) Otherwise, set the group-id to the gid of the parent directory.
	 */
	if ((va->va_mask & AT_GID) &&
	    ((va->va_gid == dir->xn_gid) || groupmember(va->va_gid, cred) ||
	    secpolicy_vnode_create_gid(cred) == 0)) {
		xp->xn_gid = va->va_gid;
	} else {
		if (dir->xn_mode & VSGID)
			xp->xn_gid = dir->xn_gid;
		else
			xp->xn_gid = crgetgid(cred);
	}
	/*
	 * If we're creating a directory, and the parent directory has the
	 * set-GID bit set, set it on the new directory.
	 * Otherwise, if the user is neither privileged nor a member of the
	 * file's new group, clear the file's set-GID bit.
	 */
	if (dir->xn_mode & VSGID && type == VDIR)
		xp->xn_mode |= VSGID;
	else if ((xp->xn_mode & VSGID) &&
		secpolicy_vnode_setids_setgids(cred, xp->xn_gid) != 0)
			xp->xn_mode &= ~VSGID;

	if (va->va_mask & AT_ATIME)
		xp->xn_atime = va->va_atime;
	if (va->va_mask & AT_MTIME)
		xp->xn_mtime = va->va_mtime;

	if (op == DE_MKDIR)
		xdirinit(dir, xp);

	*newnode = xp;
	return (0);
}