summaryrefslogtreecommitdiffstats
path: root/bin/pax/file_subs.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/pax/file_subs.c')
-rw-r--r--bin/pax/file_subs.c63
1 files changed, 55 insertions, 8 deletions
diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
index b3126f5..a13238e 100644
--- a/bin/pax/file_subs.c
+++ b/bin/pax/file_subs.c
@@ -54,6 +54,7 @@ static const char rcsid[] =
#include <sys/uio.h>
#include <stdlib.h>
#include "pax.h"
+#include "options.h"
#include "extern.h"
static int
@@ -122,7 +123,7 @@ file_creat(arcn)
file_mode)) >= 0)
break;
oerrno = errno;
- if (chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
+ if (nodirs || chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
syswarn(1, oerrno, "Unable to create %s", arcn->name);
return(-1);
}
@@ -356,7 +357,7 @@ mk_link(to, to_sb, from, ign)
if (link(to, from) == 0)
break;
oerrno = errno;
- if (chk_path(from, to_sb->st_uid, to_sb->st_gid) == 0)
+ if (!nodirs && chk_path(from, to_sb->st_uid, to_sb->st_gid) == 0)
continue;
if (!ign) {
syswarn(1, oerrno, "Could not link to %s from %s", to,
@@ -431,8 +432,7 @@ node_creat(arcn)
arcn->name);
return(-1);
case PAX_SLK:
- if ((res = symlink(arcn->ln_name, arcn->name)) == 0)
- return(0);
+ res = symlink(arcn->ln_name, arcn->name);
break;
case PAX_CTG:
case PAX_HLK:
@@ -465,7 +465,7 @@ node_creat(arcn)
if (++pass <= 1)
continue;
- if (chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
+ if (nodirs || chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
syswarn(1, oerrno, "Could not create: %s", arcn->name);
return(-1);
}
@@ -475,11 +475,19 @@ node_creat(arcn)
* we were able to create the node. set uid/gid, modes and times
*/
if (pids)
- res = set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid);
+ res = ((arcn->type == PAX_SLK) ?
+ set_lids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid) :
+ set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid));
else
res = 0;
/*
+ * symlinks are done now.
+ */
+ if (arcn->type == PAX_SLK)
+ return(0);
+
+ /*
* IMPORTANT SECURITY NOTE:
* if not preserving mode or we cannot set uid/gid, then PROHIBIT any
* set uid/gid bits
@@ -489,7 +497,7 @@ node_creat(arcn)
if (pmode)
set_pmode(arcn->name, arcn->sb.st_mode);
- if (arcn->type == PAX_DIR) {
+ if (arcn->type == PAX_DIR && strcmp(NM_CPIO, argv0) != 0) {
/*
* Dirs must be processed again at end of extract to set times
* and modes to agree with those stored in the archive. However
@@ -752,7 +760,46 @@ set_ids(fnm, uid, gid)
#endif
{
if (chown(fnm, uid, gid) < 0) {
- syswarn(1, errno, "Unable to set file uid/gid of %s", fnm);
+ /*
+ * ignore EPERM unless in verbose mode or being run by root.
+ * if running as pax, POSIX requires a warning.
+ */
+ if (strcmp(NM_PAX, argv0) == 0 || errno != EPERM || vflag ||
+ geteuid() == 0)
+ syswarn(1, errno, "Unable to set file uid/gid of %s",
+ fnm);
+ return(-1);
+ }
+ return(0);
+}
+
+/*
+ * set_lids()
+ * set the uid and gid of a file system node
+ * Return:
+ * 0 when set, -1 on failure
+ */
+
+#ifdef __STDC__
+int
+set_lids(char *fnm, uid_t uid, gid_t gid)
+#else
+int
+set_lids(fnm, uid, gid)
+ char *fnm;
+ uid_t uid;
+ gid_t gid;
+#endif
+{
+ if (lchown(fnm, uid, gid) < 0) {
+ /*
+ * ignore EPERM unless in verbose mode or being run by root.
+ * if running as pax, POSIX requires a warning.
+ */
+ if (strcmp(NM_PAX, argv0) == 0 || errno != EPERM || vflag ||
+ geteuid() == 0)
+ syswarn(1, errno, "Unable to set file uid/gid of %s",
+ fnm);
return(-1);
}
return(0);
OpenPOWER on IntegriCloud