/*
 * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include <sys/types.h>
#include <sys/param.h>
#include <sys/priv.h>
#include <sys/vnode.h>
#include <sys/mntent.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/jail.h>
#include <sys/policy.h>
#include <sys/zfs_vfsops.h>
#include <sys/zfs_znode.h>


int
secpolicy_nfs(cred_t *cr)
{

	return (spl_priv_check_cred(cr, PRIV_NFS_DAEMON));
}

int
secpolicy_zfs(cred_t *cr)
{

	return (spl_priv_check_cred(cr, PRIV_VFS_MOUNT));
}

int
secpolicy_zfs_proc(cred_t *cr, proc_t *proc)
{

	return (spl_priv_check_cred(cr, PRIV_VFS_MOUNT));
}

int
secpolicy_sys_config(cred_t *cr, int checkonly __unused)
{

	return (spl_priv_check_cred(cr, PRIV_ZFS_POOL_CONFIG));
}

int
secpolicy_zinject(cred_t *cr)
{

	return (spl_priv_check_cred(cr, PRIV_ZFS_INJECT));
}

int
secpolicy_fs_unmount(cred_t *cr, struct mount *vfsp __unused)
{

	return (spl_priv_check_cred(cr, PRIV_VFS_UNMOUNT));
}

int
secpolicy_fs_owner(struct mount *mp, cred_t *cr)
{

	if (zfs_super_owner) {
		if (cr->cr_uid == mp->mnt_cred->cr_uid &&
		    cr->cr_prison == mp->mnt_cred->cr_prison) {
			return (0);
		}
	}
	return (EPERM);
}

/*
 * This check is done in kern_link(), so we could just return 0 here.
 */
extern int hardlink_check_uid;
int
secpolicy_basic_link(vnode_t *vp, cred_t *cr)
{

	if (!hardlink_check_uid)
		return (0);
	if (secpolicy_fs_owner(vp->v_mount, cr) == 0)
		return (0);
	return (spl_priv_check_cred(cr, PRIV_VFS_LINK));
}

int
secpolicy_vnode_stky_modify(cred_t *cr)
{

	return (EPERM);
}

int
secpolicy_vnode_remove(vnode_t *vp, cred_t *cr)
{

	if (secpolicy_fs_owner(vp->v_mount, cr) == 0)
		return (0);
	return (spl_priv_check_cred(cr, PRIV_VFS_ADMIN));
}

int
secpolicy_vnode_access(cred_t *cr, vnode_t *vp, uid_t owner, accmode_t accmode)
{

	if (secpolicy_fs_owner(vp->v_mount, cr) == 0)
		return (0);

	if ((accmode & VREAD) && spl_priv_check_cred(cr, PRIV_VFS_READ) != 0)
		return (EACCES);
	if ((accmode & VWRITE) &&
	    spl_priv_check_cred(cr, PRIV_VFS_WRITE) != 0) {
		return (EACCES);
	}
	if (accmode & VEXEC) {
		if (vp->v_type == VDIR) {
			if (spl_priv_check_cred(cr, PRIV_VFS_LOOKUP) != 0)
				return (EACCES);
		} else {
			if (spl_priv_check_cred(cr, PRIV_VFS_EXEC) != 0)
				return (EACCES);
		}
	}
	return (0);
}

/*
 * Like secpolicy_vnode_access() but we get the actual wanted mode and the
 * current mode of the file, not the missing bits.
 */
int
secpolicy_vnode_access2(cred_t *cr, vnode_t *vp, uid_t owner,
    accmode_t curmode, accmode_t wantmode)
{
	accmode_t mode;

	mode = ~curmode & wantmode;

	if (mode == 0)
		return (0);

	return (secpolicy_vnode_access(cr, vp, owner, mode));
}

int
secpolicy_vnode_any_access(cred_t *cr, vnode_t *vp, uid_t owner)
{
	static int privs[] = {
	    PRIV_VFS_ADMIN,
	    PRIV_VFS_READ,
	    PRIV_VFS_WRITE,
	    PRIV_VFS_EXEC,
	    PRIV_VFS_LOOKUP
	};
	int i;

	if (secpolicy_fs_owner(vp->v_mount, cr) == 0)
		return (0);

	/* Same as secpolicy_vnode_setdac */
	if (owner == cr->cr_uid)
		return (0);

	for (i = 0; i < sizeof (privs)/sizeof (int); i++) {
		int priv;

		switch (priv = privs[i]) {
		case PRIV_VFS_EXEC:
			if (vp->v_type == VDIR)
				continue;
			break;
		case PRIV_VFS_LOOKUP:
			if (vp->v_type != VDIR)
				continue;
			break;
		}
		if (spl_priv_check_cred(cr, priv) == 0)
			return (0);
	}
	return (EPERM);
}

int
secpolicy_vnode_setdac(vnode_t *vp, cred_t *cr, uid_t owner)
{

	if (owner == cr->cr_uid)
		return (0);
	if (secpolicy_fs_owner(vp->v_mount, cr) == 0)
		return (0);
	return (spl_priv_check_cred(cr, PRIV_VFS_ADMIN));
}

int
secpolicy_vnode_setattr(cred_t *cr, vnode_t *vp, struct vattr *vap,
    const struct vattr *ovap, int flags,
    int unlocked_access(void *, int, cred_t *), void *node)
{
	int mask = vap->va_mask;
	int error;

	if (mask & AT_SIZE) {
		if (vp->v_type == VDIR)
			return (EISDIR);
		error = unlocked_access(node, VWRITE, cr);
		if (error)
			return (error);
	}
	if (mask & AT_MODE) {
		/*
		 * If not the owner of the file then check privilege
		 * for two things: the privilege to set the mode at all
		 * and, if we're setting setuid, we also need permissions
		 * to add the set-uid bit, if we're not the owner.
		 * In the specific case of creating a set-uid root
		 * file, we need even more permissions.
		 */
		error = secpolicy_vnode_setdac(vp, cr, ovap->va_uid);
		if (error)
			return (error);
		error = secpolicy_setid_setsticky_clear(vp, vap, ovap, cr);
		if (error)
			return (error);
	} else {
		vap->va_mode = ovap->va_mode;
	}
	if (mask & (AT_UID | AT_GID)) {
		error = secpolicy_vnode_setdac(vp, cr, ovap->va_uid);
		if (error)
			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 (((mask & AT_UID) && vap->va_uid != ovap->va_uid) ||
		    ((mask & AT_GID) && vap->va_gid != ovap->va_gid &&
		    !groupmember(vap->va_gid, cr))) {
			if (secpolicy_fs_owner(vp->v_mount, cr) != 0) {
				error = spl_priv_check_cred(cr, PRIV_VFS_CHOWN);
				if (error)
					return (error);
			}
		}

		if (((mask & AT_UID) && vap->va_uid != ovap->va_uid) ||
		    ((mask & AT_GID) && vap->va_gid != ovap->va_gid)) {
			secpolicy_setid_clear(vap, vp, cr);
		}
	}
	if (mask & (AT_ATIME | AT_MTIME)) {
		/*
		 * From utimes(2):
		 * If times is NULL, ... The caller must be the owner of
		 * the file, have permission to write the file, or be the
		 * super-user.
		 * If times is non-NULL, ... The caller must be the owner of
		 * the file or be the super-user.
		 */
		error = secpolicy_vnode_setdac(vp, cr, ovap->va_uid);
		if (error && (vap->va_vaflags & VA_UTIMES_NULL))
			error = unlocked_access(node, VWRITE, cr);
		if (error)
			return (error);
	}
	return (0);
}

int
secpolicy_vnode_create_gid(cred_t *cr)
{

	return (EPERM);
}

int
secpolicy_vnode_setids_setgids(vnode_t *vp, cred_t *cr, gid_t gid)
{

	if (groupmember(gid, cr))
		return (0);
	if (secpolicy_fs_owner(vp->v_mount, cr) == 0)
		return (0);
	return (spl_priv_check_cred(cr, PRIV_VFS_SETGID));
}

int
secpolicy_vnode_setid_retain(znode_t *zp, cred_t *cr,
    boolean_t issuidroot __unused)
{

	if (secpolicy_fs_owner(ZTOV(zp)->v_mount, cr) == 0)
		return (0);
	return (spl_priv_check_cred(cr, PRIV_VFS_RETAINSUGID));
}

void
secpolicy_setid_clear(struct vattr *vap, vnode_t *vp, cred_t *cr)
{

	if (secpolicy_fs_owner(vp->v_mount, cr) == 0)
		return;

	if ((vap->va_mode & (S_ISUID | S_ISGID)) != 0) {
		if (spl_priv_check_cred(cr, PRIV_VFS_RETAINSUGID)) {
			vap->va_mask |= AT_MODE;
			vap->va_mode &= ~(S_ISUID|S_ISGID);
		}
	}
}

int
secpolicy_setid_setsticky_clear(vnode_t *vp, struct vattr *vap,
    const struct vattr *ovap, cred_t *cr)
{
	int error;

	if (secpolicy_fs_owner(vp->v_mount, cr) == 0)
		return (0);

	/*
	 * 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 (spl_priv_check_cred(cr, PRIV_VFS_STICKYFILE))
			return (EFTYPE);
	}
	/*
	 * Check for privilege if attempting to set the
	 * group-id bit.
	 */
	if ((vap->va_mode & S_ISGID) != 0) {
		error = secpolicy_vnode_setids_setgids(vp, cr, ovap->va_gid);
		if (error)
			return (error);
	}
	/*
	 * Deny setting setuid if we are not the file owner.
	 */
	if ((vap->va_mode & S_ISUID) && ovap->va_uid != cr->cr_uid) {
		error = spl_priv_check_cred(cr, PRIV_VFS_ADMIN);
		if (error)
			return (error);
	}
	return (0);
}

int
secpolicy_fs_mount(cred_t *cr, vnode_t *mvp, struct mount *vfsp)
{

	return (spl_priv_check_cred(cr, PRIV_VFS_MOUNT));
}

int
secpolicy_vnode_owner(vnode_t *vp, cred_t *cr, uid_t owner)
{

	if (owner == cr->cr_uid)
		return (0);
	if (secpolicy_fs_owner(vp->v_mount, cr) == 0)
		return (0);

	/* XXX: vfs_suser()? */
	return (spl_priv_check_cred(cr, PRIV_VFS_MOUNT_OWNER));
}

int
secpolicy_vnode_chown(vnode_t *vp, cred_t *cr, uid_t owner)
{

	if (secpolicy_fs_owner(vp->v_mount, cr) == 0)
		return (0);
	return (spl_priv_check_cred(cr, PRIV_VFS_CHOWN));
}

void
secpolicy_fs_mount_clearopts(cred_t *cr, struct mount *vfsp)
{

	if (spl_priv_check_cred(cr, PRIV_VFS_MOUNT_NONUSER) != 0) {
		MNT_ILOCK(vfsp);
		vfsp->vfs_flag |= VFS_NOSETUID | MNT_USER;
		vfs_clearmntopt(vfsp, MNTOPT_SETUID);
		vfs_setmntopt(vfsp, MNTOPT_NOSETUID, NULL, 0);
		MNT_IUNLOCK(vfsp);
	}
}

/*
 * Check privileges for setting xvattr attributes
 */
int
secpolicy_xvattr(vnode_t *vp, xvattr_t *xvap, uid_t owner, cred_t *cr,
    vtype_t vtype)
{

	if (secpolicy_fs_owner(vp->v_mount, cr) == 0)
		return (0);
	return (spl_priv_check_cred(cr, PRIV_VFS_SYSFLAGS));
}

int
secpolicy_smb(cred_t *cr)
{

	return (spl_priv_check_cred(cr, PRIV_NETSMB));
}
