diff -up shadow-4.1.4.2/libmisc/copydir.c.acl shadow-4.1.4.2/libmisc/copydir.c --- shadow-4.1.4.2/libmisc/copydir.c.acl 2011-02-09 17:35:23.455413575 +0100 +++ shadow-4.1.4.2/libmisc/copydir.c 2011-02-09 17:49:17.606330202 +0100 @@ -45,6 +45,9 @@ #ifdef WITH_SELINUX #include #endif +#include +#include + static /*@null@*/const char *src_orig; static /*@null@*/const char *dst_orig; @@ -70,7 +73,7 @@ static int copy_symlink (const char *src #endif static int copy_hardlink (const char *src, const char *dst, struct link_name *lp); -static int copy_special (const char *dst, +static int copy_special (const char *src, const char *dst, const struct stat *statp, const struct timeval mt[], long int uid, long int gid); static int copy_file (const char *src, const char *dst, @@ -78,6 +81,28 @@ static int copy_file (const char *src, c long int uid, long int gid); #ifdef WITH_SELINUX + +void error (struct error_context *ctx, const char *fmt, ...) +{ + va_list ap; + + /* ignore the case when destination does not support ACLs */ + if(errno==EOPNOTSUPP) + return; + + va_start (ap, fmt); + (void) fprintf (stderr, _("%s: "), Prog); + if (vfprintf (stderr, fmt, ap) != 0) { + (void) fputs (_(": "), stderr); + } + (void) fprintf (stderr, "%s\n", strerror (errno)); + va_end (ap); +} + +struct error_context ctx = { + error +}; + /* * selinux_file_context - Set the security context before any file or * directory creation. @@ -369,7 +394,7 @@ static int copy_entry (const char *src, */ else if (!S_ISREG (sb.st_mode)) { - err = copy_special (dst, &sb, mt, uid, gid); + err = copy_special (src, dst, &sb, mt, uid, gid); } /* @@ -413,8 +438,20 @@ static int copy_dir (const char *src, co || (chown (dst, (uid == - 1) ? statp->st_uid : (uid_t) uid, (gid == - 1) ? statp->st_gid : (gid_t) gid) != 0) - || (chmod (dst, statp->st_mode) != 0) - || (copy_tree (src, dst, uid, gid) != 0) + || (chmod (dst, statp->st_mode) != 0)) { + err = -1; + return err; + } + + /* ignore the case when destination does not support ACLs */ + if (perm_copy_file (src, dst, &ctx) != 0) { + if (errno!=EOPNOTSUPP) { + err = -1; + return err; + } + } + + if ((copy_tree (src, dst, uid, gid) != 0) || (utimes (dst, mt) != 0)) { err = -1; } @@ -514,6 +551,13 @@ static int copy_symlink (const char *src || (lchown (dst, (uid == -1) ? statp->st_uid : (uid_t) uid, (gid == -1) ? statp->st_gid : (gid_t) gid) != 0)) { + /* FIXME: there are no modes on symlinks, right? + * ACL could be copied, but this would be much more + * complex than calling perm_copy_file. + * Ditto for Extended Attributes. + * We currently only document that ACL and Extended + * Attributes are not copied. + */ free (oldlink); return -1; } @@ -542,7 +586,7 @@ static int copy_symlink (const char *src static int copy_hardlink (const char *src, const char *dst, struct link_name *lp) { - /* TODO: selinux needed? */ + /* TODO: selinux, ACL, Extended Attributes needed? */ if (link (lp->ln_name, dst) != 0) { return -1; @@ -574,7 +618,7 @@ static int copy_hardlink (const char *sr * * Return 0 on success, -1 on error. */ -static int copy_special (const char *dst, +static int copy_special (const char *src, const char *dst, const struct stat *statp, const struct timeval mt[], long int uid, long int gid) { @@ -628,11 +672,18 @@ static int copy_file (const char *src, c || (fchown (ofd, (uid == -1) ? statp->st_uid : (uid_t) uid, (gid == -1) ? statp->st_gid : (gid_t) gid) != 0) - || (fchmod (ofd, statp->st_mode & 07777) != 0)) { + || (fchmod (ofd, statp->st_mode & 07777) != 0)) { (void) close (ifd); return -1; } + if (perm_copy_fd (src, ifd, dst, ofd, &ctx) != 0) { + if (errno!=EOPNOTSUPP) { + (void) close (ifd); + return -1; + } + } + while ((cnt = read (ifd, buf, sizeof buf)) > 0) { if (write (ofd, buf, (size_t)cnt) != cnt) { return -1; diff -up shadow-4.1.4.2/src/Makefile.in.acl shadow-4.1.4.2/src/Makefile.in --- shadow-4.1.4.2/src/Makefile.in.acl 2009-07-24 03:16:00.000000000 +0200 +++ shadow-4.1.4.2/src/Makefile.in 2011-02-09 17:35:23.470411800 +0100 @@ -430,9 +430,9 @@ su_SOURCES = \ su_LDADD = $(LDADD) $(LIBPAM) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) sulogin_LDADD = $(LDADD) $(LIBCRYPT) -useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) -userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) -usermod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) +useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) -lacl +userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) -lacl +usermod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) -lacl vipw_LDADD = $(LDADD) $(LIBSELINUX) all: all-am