>From 28e41ac29753a2b00fb3a6602206ba81f0d0f879 Mon Sep 17 00:00:00 2001
From: Markus Steinborn
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
+# include
#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