summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/cpio/cpio.c69
-rw-r--r--usr/src/cmd/mv/mv.c40
-rw-r--r--usr/src/cmd/tar/tar.c104
3 files changed, 157 insertions, 56 deletions
diff --git a/usr/src/cmd/cpio/cpio.c b/usr/src/cmd/cpio/cpio.c
index 88026ab580..6f8e97a199 100644
--- a/usr/src/cmd/cpio/cpio.c
+++ b/usr/src/cmd/cpio/cpio.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -117,6 +117,8 @@ typedef ulong_t u_off_t;
#define ASC_OFFSET_MAX 0XFFFFFFFF /* 8 hexadecimal digits */
#define BIN_OFFSET_MAX LONG_MAX /* signed long max value */
+#define POSIXMODES 07777
+
static char aclchar = ' ';
static struct Lnk *add_lnk(struct Lnk **);
@@ -3574,7 +3576,6 @@ gethdr(void)
if (Hdr_type != USTAR && Hdr_type != TAR) {
Gen.g_mode = Gen.g_mode & (~_XATTR_CPIO_MODE);
Gen.g_mode |= attrmode(xattrp->h_typeflag);
-
} else if (Hdr_type == USTAR || Hdr_type == TAR) {
Thdr_p->tbuf.t_typeflag = xattrp->h_typeflag;
}
@@ -5754,7 +5755,7 @@ write_hdr(int secflag, off_t len)
*/
if (G_p->g_attrnam_p != (char *)NULL && Hdr_type != USTAR &&
Hdr_type != TAR) {
- mode = (G_p->g_mode & S_IAMB) | _XATTR_CPIO_MODE;
+ mode = (G_p->g_mode & POSIXMODES) | _XATTR_CPIO_MODE;
} else {
mode = G_p->g_mode;
}
@@ -7429,6 +7430,8 @@ retry_attrdir_open(char *name)
struct timeval times[2];
mode_t newmode;
struct stat parentstat;
+ acl_t *aclp = NULL;
+ int error;
/*
* We couldn't get to attrdir. See if its
@@ -7436,43 +7439,63 @@ retry_attrdir_open(char *name)
* for example: a mode such as r-xr--r--
* won't let us create an attribute dir
* if it doesn't already exist.
+ *
+ * If file has a non-trivial ACL, then save it
+ * off so that we can place it back on after doing
+ * chmod's.
*/
if (stat(name, &parentstat) == -1) {
msg(ERRN, "Cannot stat file %s", name);
return (-1);
}
+
+ if ((error = acl_get(name, ACL_NO_TRIVIAL, &aclp)) != 0) {
+ msg(ERRN,
+ "Failed to retrieve ACL on %s %s", name, strerror(errno));
+ return (-1);
+ }
+
newmode = S_IWUSR | parentstat.st_mode;
if (chmod(name, newmode) == -1) {
msg(ERRN, "Cannot change mode of file %s to %o", name, newmode);
+ if (aclp)
+ acl_free(aclp);
return (-1);
}
dirfd = attropen(name, ".", O_RDONLY);
- if (dirfd == -1) {
- msg(ERRN, "Cannot open attribute directory of file %s", name);
- return (-1);
- } else {
- /*
- * Put mode back to original
- */
- if (chmod(name, parentstat.st_mode) != 0) {
- msg(ERRN, "Cannot restore permissions of file %s to %o",
- name, parentstat.st_mode);
- }
+ /*
+ * Don't print error here, caller will handle printing out
+ * can't open message.
+ */
- /*
- * Put back time stamps
- */
+ /*
+ * Put mode back to original
+ */
+ if (chmod(name, parentstat.st_mode) != 0) {
+ msg(ERRN, "Cannot restore permissions of file %s to %o",
+ name, parentstat.st_mode);
+ }
- times[0].tv_sec = parentstat.st_atime;
- times[0].tv_usec = 0;
- times[1].tv_sec = parentstat.st_mtime;
- times[1].tv_usec = 0;
- if (utimes(name, times) != 0) {
- msg(ERRN, "Cannot reset timestamps on file %s");
+ if (aclp) {
+ error = acl_set(name, aclp);
+ if (error) {
+ msg(ERRN, "failed to set ACL on %s", name);
}
+ acl_free(aclp);
+ }
+ /*
+ * Put back time stamps
+ */
+
+ times[0].tv_sec = parentstat.st_atime;
+ times[0].tv_usec = 0;
+ times[1].tv_sec = parentstat.st_mtime;
+ times[1].tv_usec = 0;
+ if (utimes(name, times) != 0) {
+ msg(ERRN, "Cannot reset timestamps on file %s");
}
return (dirfd);
diff --git a/usr/src/cmd/mv/mv.c b/usr/src/cmd/mv/mv.c
index 3cdceeafb4..0e5fe13d32 100644
--- a/usr/src/cmd/mv/mv.c
+++ b/usr/src/cmd/mv/mv.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -872,6 +872,25 @@ copy:
if ((ret = chg_mode(target, UID(s1), GID(s1),
FMODE(s1))) > 0)
return (1);
+ /*
+ * Reapply ACL, since chmod may have
+ * altered ACL
+ */
+ if (s1acl != NULL) {
+ if ((acl_set(target, s1acl)) < 0) {
+ if (pflg || mve) {
+ (void) fprintf(
+ stderr,
+ "%s: failed to set acl entries on %s\n",
+ cmd,
+ target);
+ }
+ /*
+ * else: silent and
+ * continue
+ */
+ }
+ }
if ((ret = chg_time(target, s1)) > 0)
return (1);
}
@@ -1620,6 +1639,10 @@ copydir(char *source, char *target)
* ACL for directory
*/
if (pflg || mve) {
+ if ((pret = chg_mode(target, UID(s1save), GID(s1save),
+ FMODE(s1save))) == 0)
+ pret = chg_time(target, s1save);
+ ret += pret;
if (s1acl_save != NULL) {
if (acl_set(target, s1acl_save) < 0) {
#ifdef XPG4
@@ -1641,10 +1664,6 @@ copydir(char *source, char *target)
acl_free(s1acl_save);
s1acl_save = NULL;
}
- if ((pret = chg_mode(target, UID(s1save), GID(s1save),
- FMODE(s1save))) == 0)
- pret = chg_time(target, s1save);
- ret += pret;
} else if (fixmode != (mode_t)0)
(void) chmod(target, fixmode & MODEBITS);
@@ -2157,6 +2176,17 @@ copyattributes(char *source, char *target)
}
}
}
+ if (xacl && ((facl_set(targattrfd, xacl)) < 0)) {
+ if (!attrsilent) {
+ (void) fprintf(stderr, gettext(
+ "%s: failed to set acl entries on"
+ " attribute %s for"
+ "%s\n"), cmd, dp->d_name, target);
+ ++error;
+ }
+ acl_free(xacl);
+ xacl = NULL;
+ }
}
next:
if (xacl != NULL) {
diff --git a/usr/src/cmd/tar/tar.c b/usr/src/cmd/tar/tar.c
index d546fa2b4d..76ca6b5a5d 100644
--- a/usr/src/cmd/tar/tar.c
+++ b/usr/src/cmd/tar/tar.c
@@ -1404,7 +1404,7 @@ top:
xattrp->h_typeflag == '5') {
Hiddendir = 1;
sp->st_mode =
- (S_IFDIR | (sp->st_mode & S_IAMB));
+ (S_IFDIR | (sp->st_mode & POSIXMODES));
}
dblock.dbuf.typeflag = xattrp->h_typeflag;
}
@@ -2461,9 +2461,32 @@ doxtract(char *argv[])
}
#endif
if (dirfd == -1) {
- (void) fprintf(stderr, gettext(
- "tar: cannot open %s %s\n"), dirp,
- strerror(errno));
+#if defined(O_XATTR)
+ if (xattrp) {
+ (void) fprintf(vfile,
+ gettext("tar: cannot open "
+ "attribute %s of file %s: %s\n"),
+ xattraname, dirp, strerror(errno));
+ /*
+ * Reset typeflag back to real
+ * value so passtape will skip
+ * ahead correctly.
+ */
+ dblock.dbuf.typeflag = _XATTR_HDRTYPE;
+ free(xattrhead);
+ xattrp = NULL;
+ xattr_linkp = NULL;
+ xattrhead = NULL;
+ } else {
+ fprintf(vfile,
+ gettext("tar: cannot open %s %s\n"),
+ dirp, strerror(errno));
+ }
+#else
+ fprintf(vfile,
+ gettext("tar: cannot open %s %s\n"),
+ dirp, strerror(errno));
+#endif
passtape();
continue;
}
@@ -6534,7 +6557,6 @@ getstat(int dirfd, char *longname, char *shortname)
else
i = fstatat(dirfd, shortname, &stbuf, 0);
-
if (i < 0) {
/* Initialize flag to print error mesg. */
printerr = 1;
@@ -6881,6 +6903,7 @@ read_xattr_hdr()
} else {
xattr_linkaname = NULL;
}
+
return (0);
}
#else
@@ -6981,6 +7004,8 @@ retry_attrdir_open(char *name)
struct timeval times[2];
mode_t newmode;
struct stat parentstat;
+ acl_t *aclp = NULL;
+ int error;
/*
* We couldn't get to attrdir. See if its
@@ -6988,46 +7013,69 @@ retry_attrdir_open(char *name)
* for example: a mode such as r-xr--r--
* won't let us create an attribute dir
* if it doesn't already exist.
+ *
+ * If file has a non-trivial ACL, then save it
+ * off so that we can place it back on after doing
+ * chmod's.
*/
if (stat(name, &parentstat) == -1) {
- (void) fprintf(stderr, gettext("Cannot stat file %s %s\n"),
+ (void) fprintf(stderr, gettext("tar: cannot stat file %s %s\n"),
name, strerror(errno));
- return (1);
+ return (-1);
}
+ if ((error = acl_get(name, ACL_NO_TRIVIAL, &aclp)) != 0) {
+ (void) fprintf(stderr, gettext("tar: failed to retrieve ACL on"
+ " %s %s\n"), name, strerror(errno));
+ return (-1);
+ }
+
newmode = S_IWUSR | parentstat.st_mode;
if (chmod(name, newmode) == -1) {
(void) fprintf(stderr,
- gettext("Cannot chmod file %s to %o %s\n"),
+ gettext("tar: cannot chmod file %s to %o %s\n"),
name, newmode, strerror(errno));
- return (1);
-
+ if (aclp)
+ acl_free(aclp);
+ return (-1);
}
dirfd = attropen(name, ".", O_RDONLY);
- if (dirfd == -1) {
- (void) fprintf(stderr,
- gettext("Cannot open attribute directory of"
- " file %s %s\n"), name, strerror(errno));
- return (1);
- } else {
- /*
- * Put mode back to original
- */
- (void) chmod(name, parentstat.st_mode);
+ /*
+ * Don't print error message if attropen() failed,
+ * caller will print message.
+ */
- /*
- * Put back time stamps
- */
+ /*
+ * Put mode back to original
+ */
+ if (chmod(name, parentstat.st_mode) == -1) {
+ (void) fprintf(stderr,
+ gettext("tar: cannot chmod file %s to %o %s\n"),
+ name, newmode, strerror(errno));
+ }
- times[0].tv_sec = parentstat.st_atime;
- times[0].tv_usec = 0;
- times[1].tv_sec = parentstat.st_mtime;
- times[1].tv_usec = 0;
- (void) utimes(name, times);
+ if (aclp) {
+ error = acl_set(name, aclp);
+ if (error) {
+ (void) fprintf(stderr,
+ gettext("tar: %s: failed to set acl entries\n"),
+ name);
+ }
+ acl_free(aclp);
}
+ /*
+ * Put back time stamps
+ */
+
+ times[0].tv_sec = parentstat.st_atime;
+ times[0].tv_usec = 0;
+ times[1].tv_sec = parentstat.st_mtime;
+ times[1].tv_usec = 0;
+ (void) utimes(name, times);
+
return (dirfd);
}