diff --git a/bin/chflags/chflags.1 b/bin/chflags/chflags.1 index 9c808a0094b3..9ab880f597b8 100644 --- a/bin/chflags/chflags.1 +++ b/bin/chflags/chflags.1 @@ -83,9 +83,12 @@ arch set the archived flag (super-user only) dump set the dump flag sappnd set the system append-only flag (super-user only) schg set the system immutable flag (super-user only) +sunlnk set the system undeletable flag (super-user only) uappnd set the user append-only flag (owner or super-user only) uchg set the user immutable flag (owner or super-user only) -archived, sappend, schange, simmutable, uappend, uchange, uimmutable +uunlnk set the user undeletable flag (owner or super-user only) +archived, sappend, schange, simmutable, uappend, uchange, uimmutable, +sunlink, uunlink aliases for the above .Ed .Pp diff --git a/bin/ls/stat_flags.c b/bin/ls/stat_flags.c index f0092fed9c49..b1e70628e527 100644 --- a/bin/ls/stat_flags.c +++ b/bin/ls/stat_flags.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: stat_flags.c,v 1.5 1997/02/22 14:04:02 peter Exp $ */ #ifndef lint @@ -69,6 +69,8 @@ flags_to_string(flags, def) SAPPEND("uappnd"); if (flags & UF_IMMUTABLE) SAPPEND("uchg"); + if (flags & UF_NOUNLINK) + SAPPEND("uunlnk"); if (flags & UF_NODUMP) SAPPEND("nodump"); if (flags & UF_OPAQUE) @@ -79,6 +81,8 @@ flags_to_string(flags, def) SAPPEND("arch"); if (flags & SF_IMMUTABLE) SAPPEND("schg"); + if (flags & SF_NOUNLINK) + SAPPEND("sunlnk"); return (prefix == NULL && def != NULL ? def : string); } @@ -139,6 +143,8 @@ string_to_flags(stringp, setp, clrp) TEST(p, "schg", SF_IMMUTABLE); TEST(p, "schange", SF_IMMUTABLE); TEST(p, "simmutable", SF_IMMUTABLE); + TEST(p, "sunlnk", SF_NOUNLINK); + TEST(p, "sunlink", SF_NOUNLINK); return (1); case 'u': TEST(p, "uappnd", UF_APPEND); @@ -146,6 +152,8 @@ string_to_flags(stringp, setp, clrp) TEST(p, "uchg", UF_IMMUTABLE); TEST(p, "uchange", UF_IMMUTABLE); TEST(p, "uimmutable", UF_IMMUTABLE); + TEST(p, "uunlnk", UF_NOUNLINK); + TEST(p, "uunlink", UF_NOUNLINK); /* FALLTHROUGH */ default: return (1); diff --git a/lib/libc/gen/setflags.c b/lib/libc/gen/setflags.c index f0092fed9c49..b1e70628e527 100644 --- a/lib/libc/gen/setflags.c +++ b/lib/libc/gen/setflags.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: stat_flags.c,v 1.5 1997/02/22 14:04:02 peter Exp $ */ #ifndef lint @@ -69,6 +69,8 @@ flags_to_string(flags, def) SAPPEND("uappnd"); if (flags & UF_IMMUTABLE) SAPPEND("uchg"); + if (flags & UF_NOUNLINK) + SAPPEND("uunlnk"); if (flags & UF_NODUMP) SAPPEND("nodump"); if (flags & UF_OPAQUE) @@ -79,6 +81,8 @@ flags_to_string(flags, def) SAPPEND("arch"); if (flags & SF_IMMUTABLE) SAPPEND("schg"); + if (flags & SF_NOUNLINK) + SAPPEND("sunlnk"); return (prefix == NULL && def != NULL ? def : string); } @@ -139,6 +143,8 @@ string_to_flags(stringp, setp, clrp) TEST(p, "schg", SF_IMMUTABLE); TEST(p, "schange", SF_IMMUTABLE); TEST(p, "simmutable", SF_IMMUTABLE); + TEST(p, "sunlnk", SF_NOUNLINK); + TEST(p, "sunlink", SF_NOUNLINK); return (1); case 'u': TEST(p, "uappnd", UF_APPEND); @@ -146,6 +152,8 @@ string_to_flags(stringp, setp, clrp) TEST(p, "uchg", UF_IMMUTABLE); TEST(p, "uchange", UF_IMMUTABLE); TEST(p, "uimmutable", UF_IMMUTABLE); + TEST(p, "uunlnk", UF_NOUNLINK); + TEST(p, "uunlink", UF_NOUNLINK); /* FALLTHROUGH */ default: return (1); diff --git a/lib/libc/gen/setflagsbyname.c b/lib/libc/gen/setflagsbyname.c index f0092fed9c49..b1e70628e527 100644 --- a/lib/libc/gen/setflagsbyname.c +++ b/lib/libc/gen/setflagsbyname.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: stat_flags.c,v 1.5 1997/02/22 14:04:02 peter Exp $ */ #ifndef lint @@ -69,6 +69,8 @@ flags_to_string(flags, def) SAPPEND("uappnd"); if (flags & UF_IMMUTABLE) SAPPEND("uchg"); + if (flags & UF_NOUNLINK) + SAPPEND("uunlnk"); if (flags & UF_NODUMP) SAPPEND("nodump"); if (flags & UF_OPAQUE) @@ -79,6 +81,8 @@ flags_to_string(flags, def) SAPPEND("arch"); if (flags & SF_IMMUTABLE) SAPPEND("schg"); + if (flags & SF_NOUNLINK) + SAPPEND("sunlnk"); return (prefix == NULL && def != NULL ? def : string); } @@ -139,6 +143,8 @@ string_to_flags(stringp, setp, clrp) TEST(p, "schg", SF_IMMUTABLE); TEST(p, "schange", SF_IMMUTABLE); TEST(p, "simmutable", SF_IMMUTABLE); + TEST(p, "sunlnk", SF_NOUNLINK); + TEST(p, "sunlink", SF_NOUNLINK); return (1); case 'u': TEST(p, "uappnd", UF_APPEND); @@ -146,6 +152,8 @@ string_to_flags(stringp, setp, clrp) TEST(p, "uchg", UF_IMMUTABLE); TEST(p, "uchange", UF_IMMUTABLE); TEST(p, "uimmutable", UF_IMMUTABLE); + TEST(p, "uunlnk", UF_NOUNLINK); + TEST(p, "uunlink", UF_NOUNLINK); /* FALLTHROUGH */ default: return (1); diff --git a/lib/libc/gen/strtofflags.c b/lib/libc/gen/strtofflags.c index f0092fed9c49..b1e70628e527 100644 --- a/lib/libc/gen/strtofflags.c +++ b/lib/libc/gen/strtofflags.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: stat_flags.c,v 1.5 1997/02/22 14:04:02 peter Exp $ */ #ifndef lint @@ -69,6 +69,8 @@ flags_to_string(flags, def) SAPPEND("uappnd"); if (flags & UF_IMMUTABLE) SAPPEND("uchg"); + if (flags & UF_NOUNLINK) + SAPPEND("uunlnk"); if (flags & UF_NODUMP) SAPPEND("nodump"); if (flags & UF_OPAQUE) @@ -79,6 +81,8 @@ flags_to_string(flags, def) SAPPEND("arch"); if (flags & SF_IMMUTABLE) SAPPEND("schg"); + if (flags & SF_NOUNLINK) + SAPPEND("sunlnk"); return (prefix == NULL && def != NULL ? def : string); } @@ -139,6 +143,8 @@ string_to_flags(stringp, setp, clrp) TEST(p, "schg", SF_IMMUTABLE); TEST(p, "schange", SF_IMMUTABLE); TEST(p, "simmutable", SF_IMMUTABLE); + TEST(p, "sunlnk", SF_NOUNLINK); + TEST(p, "sunlink", SF_NOUNLINK); return (1); case 'u': TEST(p, "uappnd", UF_APPEND); @@ -146,6 +152,8 @@ string_to_flags(stringp, setp, clrp) TEST(p, "uchg", UF_IMMUTABLE); TEST(p, "uchange", UF_IMMUTABLE); TEST(p, "uimmutable", UF_IMMUTABLE); + TEST(p, "uunlnk", UF_NOUNLINK); + TEST(p, "uunlink", UF_NOUNLINK); /* FALLTHROUGH */ default: return (1); diff --git a/lib/libc/sys/chflags.2 b/lib/libc/sys/chflags.2 index 94b744ca9c80..3305b3a2aef5 100644 --- a/lib/libc/sys/chflags.2 +++ b/lib/libc/sys/chflags.2 @@ -65,6 +65,8 @@ Do not dump the file. The file may not be changed. .It UF_APPEND The file may only be appended to. +.It UF_NOUNLINK +The file may not be renamed or deleted. .It UF_OPAQUE The directory is opaque when viewed through a union stack. .\".It ARCHIVED @@ -73,18 +75,24 @@ The directory is opaque when viewed through a union stack. The file may not be changed. .It SF_APPEND The file may only be appended to. +.It SF_NOUNLINK +The file may not be renamed or deleted. .El .Pp The .Dq UF_IMMUTABLE -and +, .Dq UF_APPEND +and +.Dq UF_NOUNLINK flags may be set or unset by either the owner of a file or the super-user. .Pp The .Dq SF_IMMUTABLE -and +, .Dq SF_APPEND +and +.Dq SF_NOUNLINK flags may only be set or unset by the super-user. Attempts by the non-super-user to set the super-user only flags are silently ignored. diff --git a/lib/libutil/stat_flags.c b/lib/libutil/stat_flags.c index f0092fed9c49..b1e70628e527 100644 --- a/lib/libutil/stat_flags.c +++ b/lib/libutil/stat_flags.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: stat_flags.c,v 1.5 1997/02/22 14:04:02 peter Exp $ */ #ifndef lint @@ -69,6 +69,8 @@ flags_to_string(flags, def) SAPPEND("uappnd"); if (flags & UF_IMMUTABLE) SAPPEND("uchg"); + if (flags & UF_NOUNLINK) + SAPPEND("uunlnk"); if (flags & UF_NODUMP) SAPPEND("nodump"); if (flags & UF_OPAQUE) @@ -79,6 +81,8 @@ flags_to_string(flags, def) SAPPEND("arch"); if (flags & SF_IMMUTABLE) SAPPEND("schg"); + if (flags & SF_NOUNLINK) + SAPPEND("sunlnk"); return (prefix == NULL && def != NULL ? def : string); } @@ -139,6 +143,8 @@ string_to_flags(stringp, setp, clrp) TEST(p, "schg", SF_IMMUTABLE); TEST(p, "schange", SF_IMMUTABLE); TEST(p, "simmutable", SF_IMMUTABLE); + TEST(p, "sunlnk", SF_NOUNLINK); + TEST(p, "sunlink", SF_NOUNLINK); return (1); case 'u': TEST(p, "uappnd", UF_APPEND); @@ -146,6 +152,8 @@ string_to_flags(stringp, setp, clrp) TEST(p, "uchg", UF_IMMUTABLE); TEST(p, "uchange", UF_IMMUTABLE); TEST(p, "uimmutable", UF_IMMUTABLE); + TEST(p, "uunlnk", UF_NOUNLINK); + TEST(p, "uunlink", UF_NOUNLINK); /* FALLTHROUGH */ default: return (1); diff --git a/sys/sys/stat.h b/sys/sys/stat.h index e017fd098ca0..fb156045d06c 100644 --- a/sys/sys/stat.h +++ b/sys/sys/stat.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)stat.h 8.12 (Berkeley) 6/16/95 - * $Id: stat.h,v 1.11 1997/02/22 09:45:58 peter Exp $ + * $Id: stat.h,v 1.12 1997/04/09 16:32:23 bde Exp $ */ #ifndef _SYS_STAT_H_ @@ -175,6 +175,7 @@ struct stat { #define UF_IMMUTABLE 0x00000002 /* file may not be changed */ #define UF_APPEND 0x00000004 /* writes to file may only append */ #define UF_OPAQUE 0x00000008 /* directory is opaque wrt. union */ +#define UF_NOUNLINK 0x00000010 /* file may not be removed or renamed */ /* * Super-user changeable flags. */ @@ -182,6 +183,7 @@ struct stat { #define SF_ARCHIVED 0x00010000 /* file is archived */ #define SF_IMMUTABLE 0x00020000 /* file may not be changed */ #define SF_APPEND 0x00040000 /* writes to file may only append */ +#define SF_NOUNLINK 0x00100000 /* file may not be removed or renamed */ #ifdef KERNEL /* @@ -190,6 +192,7 @@ struct stat { #define OPAQUE (UF_OPAQUE) #define APPEND (UF_APPEND | SF_APPEND) #define IMMUTABLE (UF_IMMUTABLE | SF_IMMUTABLE) +#define NOUNLINK (UF_NOUNLINK | SF_NOUNLINK) #endif #endif /* !_POSIX_SOURCE */ diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index e1e6ebc9a289..8180761377bf 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 - * $Id: ufs_vnops.c,v 1.49 1997/03/31 12:02:53 peter Exp $ + * $Id: ufs_vnops.c,v 1.50 1997/05/17 18:32:53 phk Exp $ */ #include "opt_quota.h" @@ -376,12 +376,14 @@ ufs_setattr(ap) (error = suser(cred, &p->p_acflag))) return (error); if (cred->cr_uid == 0) { - if ((ip->i_flags & (SF_IMMUTABLE | SF_APPEND)) && + if ((ip->i_flags + & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) && securelevel > 0) return (EPERM); ip->i_flags = vap->va_flags; } else { - if (ip->i_flags & (SF_IMMUTABLE | SF_APPEND) || + if (ip->i_flags + & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND) || (vap->va_flags & UF_SETTABLE) != vap->va_flags) return (EPERM); ip->i_flags &= SF_SETTABLE; @@ -674,7 +676,7 @@ ufs_remove(ap) int error; ip = VTOI(vp); - if ((ip->i_flags & (IMMUTABLE | APPEND)) || + if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) || (VTOI(dvp)->i_flags & APPEND)) { error = EPERM; goto out; @@ -904,7 +906,7 @@ ufs_rename(ap) return (error); } - if (tvp && ((VTOI(tvp)->i_flags & (IMMUTABLE | APPEND)) || + if (tvp && ((VTOI(tvp)->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) || (VTOI(tdvp)->i_flags & APPEND))) { error = EPERM; goto abortit; @@ -965,7 +967,8 @@ ufs_rename(ap) goto abortit; dp = VTOI(fdvp); ip = VTOI(fvp); - if ((ip->i_flags & (IMMUTABLE | APPEND)) || (dp->i_flags & APPEND)) { + if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) + || (dp->i_flags & APPEND)) { VOP_UNLOCK(fvp, 0, p); error = EPERM; goto abortit; @@ -1504,7 +1507,8 @@ ufs_rmdir(ap) error = ENOTEMPTY; goto out; } - if ((dp->i_flags & APPEND) || (ip->i_flags & (IMMUTABLE | APPEND))) { + if ((dp->i_flags & APPEND) + || (ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))) { error = EPERM; goto out; } diff --git a/usr.bin/chflags/chflags.1 b/usr.bin/chflags/chflags.1 index 9c808a0094b3..9ab880f597b8 100644 --- a/usr.bin/chflags/chflags.1 +++ b/usr.bin/chflags/chflags.1 @@ -83,9 +83,12 @@ arch set the archived flag (super-user only) dump set the dump flag sappnd set the system append-only flag (super-user only) schg set the system immutable flag (super-user only) +sunlnk set the system undeletable flag (super-user only) uappnd set the user append-only flag (owner or super-user only) uchg set the user immutable flag (owner or super-user only) -archived, sappend, schange, simmutable, uappend, uchange, uimmutable +uunlnk set the user undeletable flag (owner or super-user only) +archived, sappend, schange, simmutable, uappend, uchange, uimmutable, +sunlink, uunlink aliases for the above .Ed .Pp