I've still no decision about the following - let me add one note to it:
Patch 2 of the series contained a bug - take the attached file as a
replacement.
Markus Steinborn wrote:
What about the following patches?
Markus Steinborn wrote
Hi,
I'd like to remember of the following bug report and to announce that
I have finished patches for all these issues.
I have submitted my patches to redhat (as they currently apply clean
on a redhat patched tar 1.27.1). See
https://bugzilla.redhat.com/show_bug.cgi?id=1052876 for them.
If you are ready to accept that patches (and only then, currently I
have quite limited time) I would rebase the patches to tar master.
I also want to remind of
http://lists.gnu.org/archive/html/bug-tar/2013-04/msg00024.html:
where "Paul Eggert" writes "That sort of thing all sounds reasonable,
I guess. I'd like Sergey's opinion though.". What is your opinion to
this, Sergey?
Greetings from Germany
Markus Steinborn
GNU gv maintainer
Markus Steinborn schrieb:
Hi everybody,
Today I noticed that GNU tar (git master) now supports XATTRs, ACLs
and SELINUX-Attributes. I am really pleased to read this in "git
log". Congratualtions for this improvement. The improvements do not
break star und redhat tar compatibility.
Having used Redhats patch for many years now (and an improved
version which I made), I am able to enumerate a few points that IMHO
need improvement:
(1) tar archive creation with "--numeric-owner" option:
In this case, users are expectiing that the archive does not contain
any symbolic owner name, so it can be extracted to an emoty hard
disc on a system bootet e. g. by a rescue cd from Redhat. Current
sitation is that ACLs still include the symbolic owner and not the
numeric owner.
This is quite trivial to fix:
Replace all ocurences of "val = acl_to_text(acl, &len);" by "val =
acl_to_any_text(acl, 0, ',', (
numeric_owner_option?TEXT_NUMERIC_IDS:0));" and followed by
"len=strlen(val);" after the "if (!val)" error-handling.
Effect: Numeric owner is stored.
I'd like to note that this improvement is essential to me.
(2a) tar archive creation without "--numeric-owner" option:
In GNU tar 1.26, for every file the owner is stored both, symbolic
and numeric. I would expect that ACLs are stored in both ways, too.
star shows us how to do that:
star stores the numeric owner in a forth field of an acl: (e.g.
"u:msteinbo:rwx:500").
(2b) tar extract should use the 4th field (discussed in point 2) in
presence of "-numeric-owner".
This together with point (2) enabled users to restore an backup
created without numeric owner option on a clean hard disc without
passwd entries for the users (let's assume that /etc/passwd is
contained in the archive so the operation makes sense).
I'd like to mention that this point would increase star
compatibility a lot.
Optional (3): Do not store ACLs iff ACL contains just the normal
user, group and other permissions, i. .e. the ACL is an
compatibility ACL.
What is your opinion on these points?
Greetings from Germany
Markus Steinborn
GNU gv maintainer
PS: "iff" is the usual abbreviation for "if and only if" and not a
typo.
>From 28e41ac29753a2b00fb3a6602206ba81f0d0f879 Mon Sep 17 00:00:00 2001
From: Markus Steinborn <gnugv_maintai...@yahoo.de>
Date: Sun, 6 Oct 2013 11:50:07 +0200
Subject: [PATCH 2/5] tar archive creation without "--numeric-owner" option
In GNU tar 1.26, for every file the owner is stored both, symbolic and
numeric. I would expect that ACLs are stored in both ways, too. star shows
us how to do that:
star stores the numeric owner in a forth field of an acl:
(e.g. "u:msteinbo:rwx:500").
ACLs: tar archive creation with "--numeric-owner" option
In this case, users are expectiing that the archive does not contain any
symbolic owner name, so it can be extracted to an emoty hard disc on a
---
src/xattrs.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 200 insertions(+), 2 deletions(-)
diff --git a/src/xattrs.c b/src/xattrs.c
index c06878e..945c6c0 100644
--- a/src/xattrs.c
+++ b/src/xattrs.c
@@ -53,6 +53,7 @@ static struct
#ifdef HAVE_POSIX_ACLS
# include "acl.h"
# include <sys/acl.h>
+# include <acl/libacl.h>
#endif
#ifdef HAVE_POSIX_ACLS
@@ -497,12 +498,179 @@ xattrs__acls_set (struct tar_stat_info const *st,
acl_free (acl);
}
+bool name2uid(char *name, unsigned long *uidp)
+{
+ struct passwd *pw;
+
+ if (!*name)
+ return false;
+
+ if ((pw = getpwnam(name)) != NULL) {
+ *uidp = pw->pw_uid;
+ return true;
+ } else {
+ *uidp = 0;
+ return false;
+ }
+}
+
+bool name2gid(char* name, unsigned long *gidp)
+{
+ struct group *gr;
+
+ if (!*name)
+ return false;
+
+ if ((gr = getgrnam(name)) != NULL) {
+ *gidp = gr->gr_gid;
+ return true;
+ } else {
+ *gidp = 0;
+ return false;
+ }
+}
+
+static bool acl_add_ids(char* acltext, char** retInfotext)
+{
+ int ret, dstlen;
+ char *tmp, *tmp2, *src, *dst;
+ tmp = malloc( 1+strlen(acltext) );
+ acl_check_ids( acltext, tmp );
+ src=tmp;
+
+ dstlen = 1024;
+ dst=tmp2=malloc(dstlen);
+
+ while (*src)
+ {
+ char *end, *end1, *f1, *f2, *f3, *tmpx;
+ int isNum, len;
+ end = src;
+ while (*end && *end != ',')
+ end++;
+ end1 = end;
+ if (*end)
+ *(end++) = 0;
+ f1 = src;
+ f2 = f1;
+ while (*f2 != ':')
+ f2++;
+ *f2 = 0;
+ f3 = ++f2;
+ while (*f3 != ':')
+ f3++;
+ *f3 = 0;
+ ++f3;
+
+ isNum = 1;
+ tmpx = f2;
+ while (*tmpx)
+ {
+ if (*tmpx < '0' || *tmpx >'9')
+ isNum = 0;
+ tmpx++;
+ }
+
+ if (isNum)
+ {
+ int size, si;
+ size = snprintf(dst, 0, "%s:%s:%s", f1, f2, f3);
+ si = (dst-tmp2) + size + 1;
+
+ if ( si >= dstlen )
+ {
+ int siz = dst-tmp2;
+ while (si >= dstlen)
+ dstlen *= 2;
+
+ tmp2 = realloc(tmp2, dstlen);
+ dst = tmp2+siz;
+ }
+
+ sprintf(dst, "%s:%s:%s", f1, f2, f3);
+ }
+ else
+ {
+ unsigned long f4 = 0;
+ int ok = 0;
+
+ if (*f1 == 'u')
+ {
+ ok = name2uid(f2, &f4);
+ }
+ if (*f1 == 'g')
+ {
+ ok = name2gid(f2, &f4);
+ }
+
+ if (ok)
+ {
+ int size, si;
+
+ if (numeric_owner_option)
+ size = snprintf(dst, 0, "%s:%li:%s", f1, f4, f3);
+ else
+ size = snprintf(dst, 0, "%s:%s:%s:%li", f1, f2, f3, f4);
+ si = (dst-tmp2) + size + 1;
+
+ if ( si >= dstlen )
+ {
+ int siz = dst-tmp2;
+ while (si >= dstlen)
+ dstlen *= 2;
+
+ tmp2 = realloc(tmp2, dstlen);
+ dst = tmp2+siz;
+ }
+
+ if (numeric_owner_option)
+ sprintf(dst, "%s:%li:%s", f1, f4, f3);
+ else
+ sprintf(dst, "%s:%s:%s:%li", f1, f2, f3, f4);
+ }
+ else
+ {
+ int size, si;
+ size = snprintf(dst, 0, "%s:%s:%s", f1, f2, f3);
+ si = (dst-tmp2) + size + 1;
+
+ if ( si >= dstlen )
+ {
+ int siz = dst-tmp2;
+ while (si >= dstlen)
+ dstlen *= 2;
+
+ tmp2 = realloc(tmp2, dstlen);
+ dst = tmp2+siz;
+ }
+
+ sprintf(dst, "%s:%s:%s", f1, f2, f3);
+ }
+ }
+ dst +=strlen(dst);
+ if (end != end1)
+ *(dst++) = ',';
+
+ src = end;
+ }
+ *dst = 0;
+
+ free(tmp);
+ *retInfotext = strdup(tmp2);
+ free(tmp2);
+ return true;
+}
+
static void
xattrs__acls_get_a (int parentfd, const char *file_name,
struct tar_stat_info *st,
char **ret_ptr, size_t * ret_len)
{
char *val = NULL;
+ char* text;
+ char* c;
+ void* toFree = 0;
+
ssize_t len;
acl_t acl;
@@ -513,7 +681,18 @@ xattrs__acls_get_a (int parentfd, const char *file_name,
return;
}
- val = acl_to_text (acl, &len);
+ text = acl_to_text(acl, &len);
+ if (text)
+ {
+ if (!acl_add_ids(text, &val)) {
+ acl_free((acl_t)text);
+ *ret_ptr = 0;
+ *ret_len = 0;
+ return;
+ }
+ acl_free(text);
+ len = strlen(val);
+ }
acl_free (acl);
if (!val)
@@ -522,6 +701,8 @@ xattrs__acls_get_a (int parentfd, const char *file_name,
return;
}
+ len = strlen(val);
+
*ret_ptr = xstrdup (val);
*ret_len = len;
@@ -535,6 +716,10 @@ xattrs__acls_get_d (int parentfd, char const *file_name,
char **ret_ptr, size_t * ret_len)
{
char *val = NULL;
+ char* text;
+ char* c;
+ void* toFree = 0;
+
ssize_t len;
acl_t acl;
@@ -545,7 +730,18 @@ xattrs__acls_get_d (int parentfd, char const *file_name,
return;
}
- val = acl_to_text (acl, &len);
+ text = acl_to_text(acl, &len);
+ if (text)
+ {
+ if (!acl_add_ids(text, &val)) {
+ acl_free((acl_t)text);
+ *ret_ptr = 0;
+ *ret_len = 0;
+ return;
+ }
+ acl_free(text);
+ len = strlen(val);
+ }
acl_free (acl);
if (!val)
@@ -554,6 +750,8 @@ xattrs__acls_get_d (int parentfd, char const *file_name,
return;
}
+ len = strlen(val);
+
*ret_ptr = xstrdup (val);
*ret_len = len;
--
2.0.0