summaryrefslogtreecommitdiff
path: root/bin/pax/tar.c
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2004-10-23 19:34:15 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2004-10-23 19:34:15 +0000
commit29a4aa4260f12e8c09814084194a98ae921c5ea6 (patch)
tree7175d5d421aa6f0db821145e9f59ee55d0c5608b /bin/pax/tar.c
parent9ff025b30bf9e39d0e58e13d50a8c276bbe80525 (diff)
If a uid or gid does not fit into into the tar header, issue a warning
and use the uid/gid of nobody. Spotted by and ok drahn@, ok millert@
Diffstat (limited to 'bin/pax/tar.c')
-rw-r--r--bin/pax/tar.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/bin/pax/tar.c b/bin/pax/tar.c
index 58027859461..80913a3eba0 100644
--- a/bin/pax/tar.c
+++ b/bin/pax/tar.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tar.c,v 1.33 2004/04/16 22:50:23 deraadt Exp $ */
+/* $OpenBSD: tar.c,v 1.34 2004/10/23 19:34:14 otto Exp $ */
/* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */
/*-
@@ -38,7 +38,7 @@
#if 0
static const char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94";
#else
-static const char rcsid[] = "$OpenBSD: tar.c,v 1.33 2004/04/16 22:50:23 deraadt Exp $";
+static const char rcsid[] = "$OpenBSD: tar.c,v 1.34 2004/10/23 19:34:14 otto Exp $";
#endif
#endif /* not lint */
@@ -66,6 +66,11 @@ static int ul_oct(u_long, char *, int, int);
static int uqd_oct(u_quad_t, char *, int, int);
#endif
+static uid_t uid_nobody;
+static uid_t uid_warn;
+static gid_t gid_nobody;
+static gid_t gid_warn;
+
/*
* Routines common to all versions of tar
*/
@@ -1026,9 +1031,35 @@ ustar_wr(ARCHD *arcn)
* set the remaining fields. Some versions want all 16 bits of mode
* we better humor them (they really do not meet spec though)....
*/
+ if (ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3)) {
+ if (uid_nobody == 0) {
+ if (uid_name("nobody", &uid_nobody) == -1)
+ goto out;
+ }
+ if (uid_warn != arcn->sb.st_uid) {
+ uid_warn = arcn->sb.st_uid;
+ paxwarn(1,
+ "Ustar header field is too small for uid %lu, "
+ "using nobody", (u_long)arcn->sb.st_uid);
+ }
+ if (ul_oct((u_long)uid_nobody, hd->uid, sizeof(hd->uid), 3))
+ goto out;
+ }
+ if (ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3)) {
+ if (gid_nobody == 0) {
+ if (gid_name("nobody", &gid_nobody) == -1)
+ goto out;
+ }
+ if (gid_warn != arcn->sb.st_gid) {
+ gid_warn = arcn->sb.st_gid;
+ paxwarn(1,
+ "Ustar header field is too small for gid %lu, "
+ "using nobody", (u_long)arcn->sb.st_gid);
+ }
+ if (ul_oct((u_long)gid_nobody, hd->gid, sizeof(hd->gid), 3))
+ goto out;
+ }
if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3) ||
- ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3) ||
- ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3) ||
ul_oct((u_long)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3))
goto out;
strncpy(hd->uname, name_uid(arcn->sb.st_uid, 0), sizeof(hd->uname));