ufs_vnops.c (163841) | ufs_vnops.c (164033) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1989, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 21 unchanged lines hidden (view full) --- 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 35 */ 36 37#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1989, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 21 unchanged lines hidden (view full) --- 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 35 */ 36 37#include <sys/cdefs.h> |
38__FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_vnops.c 163841 2006-10-31 21:48:54Z pjd $"); | 38__FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_vnops.c 164033 2006-11-06 13:42:10Z rwatson $"); |
39 40#include "opt_mac.h" 41#include "opt_quota.h" 42#include "opt_suiddir.h" 43#include "opt_ufs.h" 44#include "opt_ffs.h" 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/malloc.h> 49#include <sys/namei.h> 50#include <sys/kernel.h> 51#include <sys/fcntl.h> 52#include <sys/stat.h> 53#include <sys/bio.h> 54#include <sys/buf.h> 55#include <sys/mount.h> | 39 40#include "opt_mac.h" 41#include "opt_quota.h" 42#include "opt_suiddir.h" 43#include "opt_ufs.h" 44#include "opt_ffs.h" 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/malloc.h> 49#include <sys/namei.h> 50#include <sys/kernel.h> 51#include <sys/fcntl.h> 52#include <sys/stat.h> 53#include <sys/bio.h> 54#include <sys/buf.h> 55#include <sys/mount.h> |
56#include <sys/priv.h> |
|
56#include <sys/refcount.h> 57#include <sys/unistd.h> 58#include <sys/vnode.h> 59#include <sys/dirent.h> 60#include <sys/lockf.h> 61#include <sys/conf.h> 62#include <sys/acl.h> 63#include <sys/jail.h> --- 424 unchanged lines hidden (view full) --- 488 * Unprivileged processes are not permitted to unset system 489 * flags, or modify flags if any system flags are set. 490 * Privileged non-jail processes may not modify system flags 491 * if securelevel > 0 and any existing system flags are set. 492 * Privileged jail processes behave like privileged non-jail 493 * processes if the security.jail.chflags_allowed sysctl is 494 * is non-zero; otherwise, they behave like unprivileged 495 * processes. | 57#include <sys/refcount.h> 58#include <sys/unistd.h> 59#include <sys/vnode.h> 60#include <sys/dirent.h> 61#include <sys/lockf.h> 62#include <sys/conf.h> 63#include <sys/acl.h> 64#include <sys/jail.h> --- 424 unchanged lines hidden (view full) --- 489 * Unprivileged processes are not permitted to unset system 490 * flags, or modify flags if any system flags are set. 491 * Privileged non-jail processes may not modify system flags 492 * if securelevel > 0 and any existing system flags are set. 493 * Privileged jail processes behave like privileged non-jail 494 * processes if the security.jail.chflags_allowed sysctl is 495 * is non-zero; otherwise, they behave like unprivileged 496 * processes. |
497 * 498 * XXXRW: Move implementation of jail_chflags_allowed to 499 * kern_jail.c. |
|
496 */ | 500 */ |
497 if (!suser_cred(cred, | 501 if (!priv_check_cred(cred, PRIV_VFS_SYSFLAGS, |
498 jail_chflags_allowed ? SUSER_ALLOWJAIL : 0)) { 499 if (ip->i_flags 500 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) { 501 error = securelevel_gt(cred, 0); 502 if (error) 503 return (error); 504 } 505 /* Snapshot flag cannot be set or cleared */ --- 74 unchanged lines hidden (view full) --- 580 return (EPERM); 581 /* 582 * From utimes(2): 583 * If times is NULL, ... The caller must be the owner of 584 * the file, have permission to write the file, or be the 585 * super-user. 586 * If times is non-NULL, ... The caller must be the owner of 587 * the file or be the super-user. | 502 jail_chflags_allowed ? SUSER_ALLOWJAIL : 0)) { 503 if (ip->i_flags 504 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) { 505 error = securelevel_gt(cred, 0); 506 if (error) 507 return (error); 508 } 509 /* Snapshot flag cannot be set or cleared */ --- 74 unchanged lines hidden (view full) --- 584 return (EPERM); 585 /* 586 * From utimes(2): 587 * If times is NULL, ... The caller must be the owner of 588 * the file, have permission to write the file, or be the 589 * super-user. 590 * If times is non-NULL, ... The caller must be the owner of 591 * the file or be the super-user. |
592 * 593 * Possibly for historical reasons, try to use VADMIN in 594 * preference to VADMIN for a NULL timestamp. This means we 595 * will return EACCES in preference to EPERM if neither 596 * check succeeds. |
|
588 */ | 597 */ |
589 if ((error = VOP_ACCESS(vp, VADMIN, cred, td)) && 590 ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || 591 (error = VOP_ACCESS(vp, VWRITE, cred, td)))) | 598 if (vap->va_vaflags & VA_UTIMES_NULL) { 599 error = VOP_ACCESS(vp, VADMIN, cred, td); 600 if (error) 601 error = VOP_ACCESS(vp, VWRITE, cred, td); 602 } else 603 error = VOP_ACCESS(vp, VADMIN, cred, td); 604 if (error) |
592 return (error); 593 if (vap->va_atime.tv_sec != VNOVAL) 594 ip->i_flag |= IN_ACCESS; 595 if (vap->va_mtime.tv_sec != VNOVAL) 596 ip->i_flag |= IN_CHANGE | IN_UPDATE; 597 if (vap->va_birthtime.tv_sec != VNOVAL && 598 ip->i_ump->um_fstype == UFS2) 599 ip->i_flag |= IN_MODIFIED; --- 49 unchanged lines hidden (view full) --- 649 return (error); 650 /* 651 * Privileged processes may set the sticky bit on non-directories, 652 * as well as set the setgid bit on a file with a group that the 653 * process is not a member of. Both of these are allowed in 654 * jail(8). 655 */ 656 if (vp->v_type != VDIR && (mode & S_ISTXT)) { | 605 return (error); 606 if (vap->va_atime.tv_sec != VNOVAL) 607 ip->i_flag |= IN_ACCESS; 608 if (vap->va_mtime.tv_sec != VNOVAL) 609 ip->i_flag |= IN_CHANGE | IN_UPDATE; 610 if (vap->va_birthtime.tv_sec != VNOVAL && 611 ip->i_ump->um_fstype == UFS2) 612 ip->i_flag |= IN_MODIFIED; --- 49 unchanged lines hidden (view full) --- 662 return (error); 663 /* 664 * Privileged processes may set the sticky bit on non-directories, 665 * as well as set the setgid bit on a file with a group that the 666 * process is not a member of. Both of these are allowed in 667 * jail(8). 668 */ 669 if (vp->v_type != VDIR && (mode & S_ISTXT)) { |
657 if (suser_cred(cred, SUSER_ALLOWJAIL)) | 670 if (priv_check_cred(cred, PRIV_VFS_STICKYFILE, 671 SUSER_ALLOWJAIL)) |
658 return (EFTYPE); 659 } 660 if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) { | 672 return (EFTYPE); 673 } 674 if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) { |
661 error = suser_cred(cred, SUSER_ALLOWJAIL); | 675 error = priv_check_cred(cred, PRIV_VFS_SETGID, 676 SUSER_ALLOWJAIL); |
662 if (error) 663 return (error); 664 } 665 ip->i_mode &= ~ALLPERMS; 666 ip->i_mode |= (mode & ALLPERMS); 667 DIP_SET(ip, i_mode, ip->i_mode); 668 ip->i_flag |= IN_CHANGE; 669 return (0); --- 20 unchanged lines hidden (view full) --- 690 ufs2_daddr_t change; 691#endif 692 693 if (uid == (uid_t)VNOVAL) 694 uid = ip->i_uid; 695 if (gid == (gid_t)VNOVAL) 696 gid = ip->i_gid; 697 /* | 677 if (error) 678 return (error); 679 } 680 ip->i_mode &= ~ALLPERMS; 681 ip->i_mode |= (mode & ALLPERMS); 682 DIP_SET(ip, i_mode, ip->i_mode); 683 ip->i_flag |= IN_CHANGE; 684 return (0); --- 20 unchanged lines hidden (view full) --- 705 ufs2_daddr_t change; 706#endif 707 708 if (uid == (uid_t)VNOVAL) 709 uid = ip->i_uid; 710 if (gid == (gid_t)VNOVAL) 711 gid = ip->i_gid; 712 /* |
698 * To modify the ownership of a file, must possess VADMIN 699 * for that file. | 713 * To modify the ownership of a file, must possess VADMIN for that 714 * file. |
700 */ 701 if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) 702 return (error); 703 /* | 715 */ 716 if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) 717 return (error); 718 /* |
704 * To change the owner of a file, or change the group of a file 705 * to a group of which we are not a member, the caller must 706 * have privilege. | 719 * To change the owner of a file, or change the group of a file to a 720 * group of which we are not a member, the caller must have 721 * privilege. |
707 */ 708 if ((uid != ip->i_uid || 709 (gid != ip->i_gid && !groupmember(gid, cred))) && | 722 */ 723 if ((uid != ip->i_uid || 724 (gid != ip->i_gid && !groupmember(gid, cred))) && |
710 (error = suser_cred(cred, SUSER_ALLOWJAIL))) | 725 (error = priv_check_cred(cred, PRIV_VFS_CHOWN, SUSER_ALLOWJAIL))) |
711 return (error); 712 ogid = ip->i_gid; 713 ouid = ip->i_uid; 714#ifdef QUOTA 715 if ((error = getinoquota(ip)) != 0) 716 return (error); 717 if (ouid == uid) { 718 dqrele(vp, ip->i_dquot[USRQUOTA]); --- 54 unchanged lines hidden (view full) --- 773 (void) getinoquota(ip); 774 } 775 return (error); 776good: 777 if (getinoquota(ip)) 778 panic("ufs_chown: lost quota"); 779#endif /* QUOTA */ 780 ip->i_flag |= IN_CHANGE; | 726 return (error); 727 ogid = ip->i_gid; 728 ouid = ip->i_uid; 729#ifdef QUOTA 730 if ((error = getinoquota(ip)) != 0) 731 return (error); 732 if (ouid == uid) { 733 dqrele(vp, ip->i_dquot[USRQUOTA]); --- 54 unchanged lines hidden (view full) --- 788 (void) getinoquota(ip); 789 } 790 return (error); 791good: 792 if (getinoquota(ip)) 793 panic("ufs_chown: lost quota"); 794#endif /* QUOTA */ 795 ip->i_flag |= IN_CHANGE; |
781 if (suser_cred(cred, SUSER_ALLOWJAIL) && (ouid != uid || ogid != gid)) { | 796 if (priv_check_cred(cred, PRIV_VFS_CLEARSUGID, SUSER_ALLOWJAIL) && 797 (ouid != uid || ogid != gid)) { |
782 ip->i_mode &= ~(ISUID | ISGID); 783 DIP_SET(ip, i_mode, ip->i_mode); 784 } 785 return (0); 786} 787 788static int 789ufs_remove(ap) --- 1562 unchanged lines hidden (view full) --- 2352#endif 2353 tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */ 2354 ip->i_effnlink = 1; 2355 ip->i_nlink = 1; 2356 DIP_SET(ip, i_nlink, 1); 2357 if (DOINGSOFTDEP(tvp)) 2358 softdep_change_linkcnt(ip); 2359 if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) && | 798 ip->i_mode &= ~(ISUID | ISGID); 799 DIP_SET(ip, i_mode, ip->i_mode); 800 } 801 return (0); 802} 803 804static int 805ufs_remove(ap) --- 1562 unchanged lines hidden (view full) --- 2368#endif 2369 tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */ 2370 ip->i_effnlink = 1; 2371 ip->i_nlink = 1; 2372 DIP_SET(ip, i_nlink, 1); 2373 if (DOINGSOFTDEP(tvp)) 2374 softdep_change_linkcnt(ip); 2375 if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) && |
2360 suser_cred(cnp->cn_cred, SUSER_ALLOWJAIL)) { | 2376 priv_check_cred(cnp->cn_cred, PRIV_VFS_SETGID, 2377 SUSER_ALLOWJAIL)) { |
2361 ip->i_mode &= ~ISGID; 2362 DIP_SET(ip, i_mode, ip->i_mode); 2363 } 2364 2365 if (cnp->cn_flags & ISWHITEOUT) { 2366 ip->i_flags |= UF_OPAQUE; 2367 DIP_SET(ip, i_flags, ip->i_flags); 2368 } --- 142 unchanged lines hidden --- | 2378 ip->i_mode &= ~ISGID; 2379 DIP_SET(ip, i_mode, ip->i_mode); 2380 } 2381 2382 if (cnp->cn_flags & ISWHITEOUT) { 2383 ip->i_flags |= UF_OPAQUE; 2384 DIP_SET(ip, i_flags, ip->i_flags); 2385 } --- 142 unchanged lines hidden --- |