>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