FreeBSD/sys/fs/tmpfs/tmpfs_subr.c
/*
 * Change ownership of the given vnode.  At least one of uid or gid must
 * be different than VNOVAL.  If one is set to that value, the attribute
 * is unchanged.
 * Caller should execute tmpfs_update on vp after a successful execution.
 * The vnode must be locked on entry and remain locked on exit.
 */
Change ownership of the given vnode.  At least one of uid or gid must
be different than VNOVAL.  If one is set to that value, the attribute
is unchanged.
Caller should execute tmpfs_update on vp after a successful execution.
The vnode must be locked on entry and remain locked on exit.
Change ownership of the given vnode . At least one of uid or gid must be different than VNOVAL . If one is set to that value the attribute is unchanged . Caller should execute tmpfs_update on vp after a successful execution . The vnode must be locked on entry and remain locked on exit .
int
tmpfs_chown(struct vnode *vp, uid_t uid, gid_t gid, struct ucred *cred,
    struct thread *p)
{
	int error;
	struct tmpfs_node *node;
	uid_t ouid;
	gid_t ogid;
	MPASS(VOP_ISLOCKED(vp));
	node = VP_TO_TMPFS_NODE(vp);
	MPASS(uid != VNOVAL || gid != VNOVAL);
	if (uid == VNOVAL)
		uid = node->tn_uid;
	if (gid == VNOVAL)
		gid = node->tn_gid;
	MPASS(uid != VNOVAL && gid != VNOVAL);
	if (vp->v_mount->mnt_flag & MNT_RDONLY)
		return EROFS;
	if (node->tn_flags & (IMMUTABLE | APPEND))
		return EPERM;
	if ((error = VOP_ACCESS(vp, VADMIN, cred, p)))
		return (error);
	if ((uid != node->tn_uid ||
	    (gid != node->tn_gid && !groupmember(gid, cred))) &&
	    (error = priv_check_cred(cred, PRIV_VFS_CHOWN, 0)))
		return (error);
	ogid = node->tn_gid;
	ouid = node->tn_uid;
	node->tn_uid = uid;
	node->tn_gid = gid;
	node->tn_status |= TMPFS_NODE_CHANGED;
	if ((node->tn_mode & (S_ISUID | S_ISGID)) && (ouid != uid || ogid != gid)) {
		if (priv_check_cred(cred, PRIV_VFS_RETAINSUGID, 0))
			node->tn_mode &= ~(S_ISUID | S_ISGID);
	}
	MPASS(VOP_ISLOCKED(vp));
	return 0;
}
int tmpfs_chown ( struct vnode * vp , uid_t uid , gid_t gid , struct ucred * cred , struct thread * p ) { int error ; struct tmpfs_node * node ; uid_t ouid ; gid_t ogid ; MPASS ( VOP_ISLOCKED ( vp ) ) ; node = VP_TO_TMPFS_NODE ( vp ) ; MPASS ( uid != VNOVAL || gid != VNOVAL ) ; if ( uid == VNOVAL ) uid = node -> tn_uid ; if ( gid == VNOVAL ) gid = node -> tn_gid ; MPASS ( uid != VNOVAL && gid != VNOVAL ) ; if ( vp -> v_mount -> mnt_flag & MNT_RDONLY ) return EROFS ; if ( node -> tn_flags & ( IMMUTABLE | APPEND ) ) return EPERM ; if ( ( error = VOP_ACCESS ( vp , VADMIN , cred , p ) ) ) return ( error ) ; if ( ( uid != node -> tn_uid || ( gid != node -> tn_gid && ! groupmember ( gid , cred ) ) ) && ( error = priv_check_cred ( cred , PRIV_VFS_CHOWN , 0 ) ) ) return ( error ) ; ogid = node -> tn_gid ; ouid = node -> tn_uid ; node -> tn_uid = uid ; node -> tn_gid = gid ; node -> tn_status |= TMPFS_NODE_CHANGED ; if ( ( node -> tn_mode & ( S_ISUID | S_ISGID ) ) && ( ouid != uid || ogid != gid ) ) { if ( priv_check_cred ( cred , PRIV_VFS_RETAINSUGID , 0 ) ) node -> tn_mode &= ~ ( S_ISUID | S_ISGID ) ; } MPASS ( VOP_ISLOCKED ( vp ) ) ; return 0 ; }
Change ownership of the given vnode.
Change ownership of the given vnode .
/* Assign default values if they are unknown. */ /* Disallow this operation if the file system is mounted read-only. */ /* Immutable or append-only files cannot be modified, either. */ /*
	 * To modify the ownership of a file, must possess VADMIN for that
	 * file.
	 */ /*
	 * 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.
	 */