diff options
Diffstat (limited to 'usr/src/cmd')
-rw-r--r-- | usr/src/cmd/cpio/cpio.c | 69 | ||||
-rw-r--r-- | usr/src/cmd/mv/mv.c | 40 | ||||
-rw-r--r-- | usr/src/cmd/tar/tar.c | 104 |
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); } |