1171 lines
35 KiB
Diff
1171 lines
35 KiB
Diff
diff -Naur bacula-5.2.7.old/src/filed/xattr.c bacula-5.2.7/src/filed/xattr.c
|
|
--- bacula-5.2.7.old/src/filed/xattr.c 2012-06-04 13:45:31.371417399 +0200
|
|
+++ bacula-5.2.7/src/filed/xattr.c 2012-06-06 18:11:06.866015637 +0200
|
|
@@ -48,7 +48,7 @@
|
|
* - Tru64 (Extended Attributes)
|
|
*
|
|
* Written by Marco van Wieringen, November 2008
|
|
- * Major overhaul January 2012
|
|
+ * Major overhaul January 2012 + June 2012
|
|
*/
|
|
|
|
#include "bacula.h"
|
|
@@ -340,14 +340,15 @@
|
|
|
|
static bxattr_exit_code aix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt)
|
|
{
|
|
+ char *bp;
|
|
bool skip_xattr;
|
|
- char *xattr_list, *bp;
|
|
+ char *xattr_list = NULL;
|
|
int cnt, xattr_count = 0;
|
|
uint32_t name_length;
|
|
int32_t xattr_list_len,
|
|
xattr_value_len;
|
|
uint32_t expected_serialize_len = 0;
|
|
- xattr_t *current_xattr = NULL;
|
|
+ xattr_t *current_xattr;
|
|
alist *xattr_value_list = NULL;
|
|
bxattr_exit_code retval = bxattr_exit_error;
|
|
|
|
@@ -362,7 +363,8 @@
|
|
switch (errno) {
|
|
case ENOENT:
|
|
case EFORMAT:
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
+ goto bail_out;
|
|
case ENOTSUP:
|
|
/*
|
|
* If the filesystem reports it doesn't support XATTRs we clear the
|
|
@@ -371,19 +373,21 @@
|
|
* when we change from one filesystem to an other.
|
|
*/
|
|
jcr->xattr_data->flags &= ~BXATTR_FLAG_SAVE_NATIVE;
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
+ goto bail_out;
|
|
default:
|
|
Mmsg2(jcr->errmsg,
|
|
_("llistea error on file \"%s\": ERR=%s\n"),
|
|
jcr->last_fname, be.bstrerror());
|
|
Dmsg2(100, "llistea error file=%s ERR=%s\n",
|
|
jcr->last_fname, be.bstrerror());
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
break;
|
|
}
|
|
case 0:
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
+ goto bail_out;
|
|
default:
|
|
break;
|
|
}
|
|
@@ -426,8 +430,9 @@
|
|
* Walk the list of extended attributes names and retrieve the data.
|
|
* We already count the bytes needed for serializing the stream later on.
|
|
*/
|
|
- bp = xattr_list;
|
|
- while ((bp - xattr_list) + 1 < xattr_list_len) {
|
|
+ for (bp = xattr_list;
|
|
+ (bp - xattr_list) + 1 < xattr_list_len;
|
|
+ bp = strchr(bp, '\0') + 1) {
|
|
skip_xattr = false;
|
|
|
|
/*
|
|
@@ -440,29 +445,10 @@
|
|
name_length = strlen(bp);
|
|
if (skip_xattr || name_length == 0) {
|
|
Dmsg1(100, "Skipping xattr named %s\n", bp);
|
|
- bp = strchr(bp, '\0') + 1;
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
- * Each xattr valuepair starts with a magic so we can parse it easier.
|
|
- */
|
|
- current_xattr = (xattr_t *)malloc(sizeof(xattr_t));
|
|
- memset(current_xattr, 0, sizeof(xattr_t));
|
|
- current_xattr->magic = XATTR_MAGIC;
|
|
- expected_serialize_len += sizeof(current_xattr->magic);
|
|
-
|
|
- /*
|
|
- * Allocate space for storing the name.
|
|
- */
|
|
- current_xattr->name_length = name_length;
|
|
- current_xattr->name = (char *)malloc(current_xattr->name_length);
|
|
- memcpy(current_xattr->name, bp, current_xattr->name_length);
|
|
-
|
|
- expected_serialize_len += sizeof(current_xattr->name_length) +
|
|
- current_xattr->name_length;
|
|
-
|
|
- /*
|
|
* First see how long the value is for the extended attribute.
|
|
*/
|
|
xattr_value_len = lgetea(jcr->last_fname, bp, NULL, 0);
|
|
@@ -485,6 +471,28 @@
|
|
}
|
|
break;
|
|
}
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Each xattr valuepair starts with a magic so we can parse it easier.
|
|
+ */
|
|
+ current_xattr = (xattr_t *)malloc(sizeof(xattr_t));
|
|
+ current_xattr->magic = XATTR_MAGIC;
|
|
+ expected_serialize_len += sizeof(current_xattr->magic);
|
|
+
|
|
+ /*
|
|
+ * Allocate space for storing the name.
|
|
+ */
|
|
+ current_xattr->name_length = name_length;
|
|
+ current_xattr->name = (char *)malloc(current_xattr->name_length);
|
|
+ memcpy(current_xattr->name, bp, current_xattr->name_length);
|
|
+
|
|
+ expected_serialize_len += sizeof(current_xattr->name_length) +
|
|
+ current_xattr->name_length;
|
|
+
|
|
+ switch (xattr_value_len) {
|
|
case 0:
|
|
current_xattr->value = NULL;
|
|
current_xattr->value_length = 0;
|
|
@@ -505,15 +513,23 @@
|
|
case ENOENT:
|
|
case EFORMAT:
|
|
retval = bxattr_exit_ok;
|
|
- goto bail_out;
|
|
+ break;
|
|
default:
|
|
Mmsg2(jcr->errmsg,
|
|
_("lgetea error on file \"%s\": ERR=%s\n"),
|
|
jcr->last_fname, be.bstrerror());
|
|
Dmsg2(100, "lgetea error file=%s ERR=%s\n",
|
|
jcr->last_fname, be.bstrerror());
|
|
- goto bail_out;
|
|
+ break;
|
|
}
|
|
+
|
|
+ /*
|
|
+ * Default failure path out when retrieval of attr fails.
|
|
+ */
|
|
+ free(current_xattr->value);
|
|
+ free(current_xattr->name);
|
|
+ free(current_xattr);
|
|
+ goto bail_out;
|
|
}
|
|
/*
|
|
* Store the actual length of the value.
|
|
@@ -521,16 +537,6 @@
|
|
current_xattr->value_length = xattr_value_len;
|
|
expected_serialize_len += sizeof(current_xattr->value_length) +
|
|
current_xattr->value_length;
|
|
-
|
|
- /*
|
|
- * Protect ourself against things getting out of hand.
|
|
- */
|
|
- if (expected_serialize_len >= MAX_XATTR_STREAM) {
|
|
- Mmsg2(jcr->errmsg,
|
|
- _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
|
|
- jcr->last_fname, MAX_XATTR_STREAM);
|
|
- goto bail_out;
|
|
- }
|
|
break;
|
|
}
|
|
|
|
@@ -539,9 +545,17 @@
|
|
}
|
|
|
|
xattr_value_list->append(current_xattr);
|
|
- current_xattr = NULL;
|
|
xattr_count++;
|
|
- bp = strchr(bp, '\0') + 1;
|
|
+
|
|
+ /*
|
|
+ * Protect ourself against things getting out of hand.
|
|
+ */
|
|
+ if (expected_serialize_len >= MAX_XATTR_STREAM) {
|
|
+ Mmsg2(jcr->errmsg,
|
|
+ _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
|
|
+ jcr->last_fname, MAX_XATTR_STREAM);
|
|
+ goto bail_out;
|
|
+ }
|
|
}
|
|
|
|
free(xattr_list);
|
|
@@ -574,21 +588,13 @@
|
|
}
|
|
|
|
bail_out:
|
|
- if (current_xattr != NULL) {
|
|
- if (current_xattr->value != NULL) {
|
|
- free(current_xattr->value);
|
|
- }
|
|
- if (current_xattr->name != NULL) {
|
|
- free(current_xattr->name);
|
|
- }
|
|
- free(current_xattr);
|
|
- }
|
|
if (xattr_list != NULL) {
|
|
free(xattr_list);
|
|
}
|
|
if (xattr_value_list != NULL) {
|
|
xattr_drop_internal_table(xattr_value_list);
|
|
}
|
|
+
|
|
return retval;
|
|
}
|
|
|
|
@@ -599,6 +605,7 @@
|
|
{
|
|
xattr_t *current_xattr;
|
|
alist *xattr_value_list;
|
|
+ bxattr_exit_code retval = bxattr_exit_error;
|
|
|
|
xattr_value_list = New(alist(10, not_owned_by_alist));
|
|
|
|
@@ -606,8 +613,7 @@
|
|
content,
|
|
content_length,
|
|
xattr_value_list) != bxattr_exit_ok) {
|
|
- xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
|
|
foreach_alist(current_xattr, xattr_value_list) {
|
|
@@ -642,12 +648,12 @@
|
|
}
|
|
}
|
|
|
|
- xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
|
|
bail_out:
|
|
xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_error;
|
|
+
|
|
+ return retval;
|
|
}
|
|
|
|
/*
|
|
@@ -697,11 +703,12 @@
|
|
|
|
static bxattr_exit_code irix_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt)
|
|
{
|
|
+ char dummy[32];
|
|
int cnt, length, xattr_count = 0;
|
|
attrlist_cursor_t cursor;
|
|
attrlist_t *attrlist;
|
|
attrlist_ent_t *attrlist_ent;
|
|
- xattr_t *current_xattr = NULL;
|
|
+ xattr_t *current_xattr;
|
|
alist *xattr_value_list = NULL;
|
|
uint32_t expected_serialize_len = 0;
|
|
bxattr_exit_code retval = bxattr_exit_error;
|
|
@@ -737,10 +744,39 @@
|
|
attrlist_ent = ATTR_ENTRY(xattrbuf, cnt);
|
|
|
|
/*
|
|
+ * First determine if we can retrieve the xattr and how big it really is.
|
|
+ */
|
|
+ length = sizeof(dummy);
|
|
+ if (attr_get(jcr->last_fname, attrlist_ent->a_name, dummy,
|
|
+ &length, xattr_naming_spaces[cnt].flags) != 0) {
|
|
+ berrno be;
|
|
+
|
|
+ switch (errno) {
|
|
+ case ENOENT:
|
|
+ case ENOATTR:
|
|
+ retval = bxattr_exit_ok;
|
|
+ goto bail_out;
|
|
+ case E2BIG:
|
|
+ /*
|
|
+ * Size of the xattr is bigger then the 32 bytes dummy which is
|
|
+ * likely. As length now contains its actual length we can allocate
|
|
+ * a properly size buffer for the real retrieval.
|
|
+ */
|
|
+ break;
|
|
+ default:
|
|
+ Mmsg2(jcr->errmsg,
|
|
+ _("attr_list error on file \"%s\": ERR=%s\n"),
|
|
+ jcr->last_fname, be.bstrerror());
|
|
+ Dmsg2(100, "attr_list error file=%s ERR=%s\n",
|
|
+ jcr->last_fname, be.bstrerror());
|
|
+ goto bail_out;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /*
|
|
* Each xattr valuepair starts with a magic so we can parse it easier.
|
|
*/
|
|
current_xattr = (xattr_t *)malloc(sizeof(xattr_t));
|
|
- memset(current_xattr, 0, sizeof(xattr_t));
|
|
current_xattr->magic = XATTR_MAGIC;
|
|
expected_serialize_len += sizeof(current_xattr->magic);
|
|
|
|
@@ -757,7 +793,7 @@
|
|
expected_serialize_len += sizeof(current_xattr->name_length) +
|
|
current_xattr->name_length;
|
|
|
|
- current_xattr->value_length = attrlist_ent->a_valuelen;
|
|
+ current_xattr->value_length = length;
|
|
current_xattr->value = (char *)malloc(current_xattr->value_length);
|
|
|
|
/*
|
|
@@ -771,33 +807,35 @@
|
|
case ENOENT:
|
|
case ENOATTR:
|
|
retval = bxattr_exit_ok;
|
|
- goto bail_out;
|
|
+ break;
|
|
case E2BIG:
|
|
/*
|
|
* The buffer for the xattr isn't big enough. the value of
|
|
* current_xattr->value_length is updated with the actual size
|
|
* of the xattr. So we free the old buffer and create a new one
|
|
- * and try again.
|
|
+ * and try again. Normally this cannot happen as we size the
|
|
+ * buffer using a call to attr_get before but in case of an
|
|
+ * race condition it might happen.
|
|
*/
|
|
free(current_xattr->value);
|
|
- current_xattr->value = (char *)malloc(current_xattr->value_length);
|
|
+ current_xattr->value = (char *)malloc(length);
|
|
if (attr_get(jcr->last_fname, attrlist_ent->a_name, current_xattr->value,
|
|
&length, xattr_naming_spaces[cnt].flags) != 0) {
|
|
switch (errno) {
|
|
case ENOENT:
|
|
case ENOATTR:
|
|
retval = bxattr_exit_ok;
|
|
- goto bail_out;
|
|
+ break;
|
|
default:
|
|
Mmsg2(jcr->errmsg,
|
|
_("attr_list error on file \"%s\": ERR=%s\n"),
|
|
jcr->last_fname, be.bstrerror(errno));
|
|
Dmsg2(100, "attr_list error file=%s ERR=%s\n",
|
|
jcr->last_fname, be.bstrerror());
|
|
- goto bail_out;
|
|
+ break;
|
|
}
|
|
} else {
|
|
- current_xattr->value_length = length;
|
|
+ goto ok_continue;
|
|
}
|
|
break;
|
|
default:
|
|
@@ -806,15 +844,30 @@
|
|
jcr->last_fname, be.bstrerror());
|
|
Dmsg2(100, "attr_list error file=%s ERR=%s\n",
|
|
jcr->last_fname, be.bstrerror());
|
|
- goto bail_out;
|
|
+ break;
|
|
}
|
|
- } else {
|
|
- current_xattr->value_length = length;
|
|
+
|
|
+ /*
|
|
+ * Default failure path out when retrieval of attr fails.
|
|
+ */
|
|
+ free(current_xattr->value);
|
|
+ free(current_xattr->name);
|
|
+ free(current_xattr);
|
|
+ goto bail_out;
|
|
}
|
|
|
|
+ok_continue:
|
|
+ current_xattr->value_length = length;
|
|
expected_serialize_len += sizeof(current_xattr->value_length) +
|
|
current_xattr->value_length;
|
|
|
|
+ if (xattr_value_list == NULL) {
|
|
+ xattr_value_list = New(alist(10, not_owned_by_alist));
|
|
+ }
|
|
+
|
|
+ xattr_value_list->append(current_xattr);
|
|
+ xattr_count++;
|
|
+
|
|
/*
|
|
* Protect ourself against things getting out of hand.
|
|
*/
|
|
@@ -824,14 +877,6 @@
|
|
jcr->last_fname, MAX_XATTR_STREAM);
|
|
goto bail_out;
|
|
}
|
|
-
|
|
- if (xattr_value_list == NULL) {
|
|
- xattr_value_list = New(alist(10, not_owned_by_alist));
|
|
- }
|
|
-
|
|
- xattr_value_list->append(current_xattr);
|
|
- current_xattr = NULL;
|
|
- xattr_count++;
|
|
}
|
|
|
|
/*
|
|
@@ -870,20 +915,12 @@
|
|
}
|
|
|
|
bail_out:
|
|
- if (current_xattr != NULL) {
|
|
- if (current_xattr->value != NULL) {
|
|
- free(current_xattr->value);
|
|
- }
|
|
- if (current_xattr->name != NULL) {
|
|
- free(current_xattr->name);
|
|
- }
|
|
- free(current_xattr);
|
|
- }
|
|
free_pool_memory(xattrbuf);
|
|
|
|
if (xattr_value_list != NULL) {
|
|
xattr_drop_internal_table(xattr_value_list);
|
|
}
|
|
+
|
|
return retval;
|
|
}
|
|
|
|
@@ -904,8 +941,7 @@
|
|
content,
|
|
content_length,
|
|
xattr_value_list) != bxattr_exit_ok) {
|
|
- xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
|
|
foreach_alist(current_xattr, xattr_value_list) {
|
|
@@ -980,12 +1016,12 @@
|
|
}
|
|
}
|
|
|
|
- xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
|
|
bail_out:
|
|
xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_error;
|
|
+
|
|
+ return retval;
|
|
}
|
|
|
|
/*
|
|
@@ -1073,14 +1109,15 @@
|
|
|
|
static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt)
|
|
{
|
|
+ char *bp;
|
|
bool skip_xattr;
|
|
- char *xattr_list, *bp;
|
|
+ char *xattr_list = NULL;
|
|
int cnt, xattr_count = 0;
|
|
uint32_t name_length;
|
|
int32_t xattr_list_len,
|
|
xattr_value_len;
|
|
uint32_t expected_serialize_len = 0;
|
|
- xattr_t *current_xattr = NULL;
|
|
+ xattr_t *current_xattr;
|
|
alist *xattr_value_list = NULL;
|
|
bxattr_exit_code retval = bxattr_exit_error;
|
|
|
|
@@ -1094,7 +1131,8 @@
|
|
|
|
switch (errno) {
|
|
case ENOENT:
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
+ goto bail_out;
|
|
case BXATTR_ENOTSUP:
|
|
/*
|
|
* If the filesystem reports it doesn't support XATTRs we clear
|
|
@@ -1104,19 +1142,21 @@
|
|
* change from one filesystem to an other.
|
|
*/
|
|
jcr->xattr_data->flags &= ~BXATTR_FLAG_SAVE_NATIVE;
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
+ goto bail_out;
|
|
default:
|
|
Mmsg2(jcr->errmsg,
|
|
_("llistxattr error on file \"%s\": ERR=%s\n"),
|
|
jcr->last_fname, be.bstrerror());
|
|
Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
|
|
jcr->last_fname, be.bstrerror());
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
break;
|
|
}
|
|
case 0:
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
+ goto bail_out;
|
|
default:
|
|
break;
|
|
}
|
|
@@ -1158,8 +1198,9 @@
|
|
* Walk the list of extended attributes names and retrieve the data.
|
|
* We already count the bytes needed for serializing the stream later on.
|
|
*/
|
|
- bp = xattr_list;
|
|
- while ((bp - xattr_list) + 1 < xattr_list_len) {
|
|
+ for (bp = xattr_list;
|
|
+ (bp - xattr_list) + 1 < xattr_list_len;
|
|
+ bp = strchr(bp, '\0') + 1) {
|
|
skip_xattr = false;
|
|
|
|
/*
|
|
@@ -1191,28 +1232,10 @@
|
|
name_length = strlen(bp);
|
|
if (skip_xattr || name_length == 0) {
|
|
Dmsg1(100, "Skipping xattr named %s\n", bp);
|
|
- bp = strchr(bp, '\0') + 1;
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
- * Each xattr valuepair starts with a magic so we can parse it easier.
|
|
- */
|
|
- current_xattr = (xattr_t *)malloc(sizeof(xattr_t));
|
|
- memset(current_xattr, 0, sizeof(xattr_t));
|
|
- current_xattr->magic = XATTR_MAGIC;
|
|
- expected_serialize_len += sizeof(current_xattr->magic);
|
|
-
|
|
- /*
|
|
- * Allocate space for storing the name.
|
|
- */
|
|
- current_xattr->name_length = name_length;
|
|
- current_xattr->name = (char *)malloc(current_xattr->name_length);
|
|
- memcpy(current_xattr->name, bp, current_xattr->name_length);
|
|
-
|
|
- expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length;
|
|
-
|
|
- /*
|
|
* First see how long the value is for the extended attribute.
|
|
*/
|
|
xattr_value_len = lgetxattr(jcr->last_fname, bp, NULL, 0);
|
|
@@ -1234,6 +1257,28 @@
|
|
}
|
|
break;
|
|
}
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Each xattr valuepair starts with a magic so we can parse it easier.
|
|
+ */
|
|
+ current_xattr = (xattr_t *)malloc(sizeof(xattr_t));
|
|
+ current_xattr->magic = XATTR_MAGIC;
|
|
+ current_xattr->value = NULL;
|
|
+ expected_serialize_len += sizeof(current_xattr->magic);
|
|
+
|
|
+ /*
|
|
+ * Allocate space for storing the name.
|
|
+ */
|
|
+ current_xattr->name_length = name_length;
|
|
+ current_xattr->name = (char *)malloc(current_xattr->name_length);
|
|
+ memcpy(current_xattr->name, bp, current_xattr->name_length);
|
|
+
|
|
+ expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length;
|
|
+
|
|
+ switch (xattr_value_len) {
|
|
case 0:
|
|
current_xattr->value = NULL;
|
|
current_xattr->value_length = 0;
|
|
@@ -1253,31 +1298,31 @@
|
|
switch (errno) {
|
|
case ENOENT:
|
|
retval = bxattr_exit_ok;
|
|
- goto bail_out;
|
|
+ break;
|
|
default:
|
|
Mmsg2(jcr->errmsg,
|
|
_("lgetxattr error on file \"%s\": ERR=%s\n"),
|
|
jcr->last_fname, be.bstrerror());
|
|
Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
|
|
jcr->last_fname, be.bstrerror());
|
|
- goto bail_out;
|
|
+ break;
|
|
}
|
|
+
|
|
+ /*
|
|
+ * Default failure path out when retrieval of attr fails.
|
|
+ */
|
|
+ free(current_xattr->value);
|
|
+ free(current_xattr->name);
|
|
+ free(current_xattr);
|
|
+ goto bail_out;
|
|
}
|
|
+
|
|
/*
|
|
* Store the actual length of the value.
|
|
*/
|
|
current_xattr->value_length = xattr_value_len;
|
|
expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length;
|
|
-
|
|
- /*
|
|
- * Protect ourself against things getting out of hand.
|
|
- */
|
|
- if (expected_serialize_len >= MAX_XATTR_STREAM) {
|
|
- Mmsg2(jcr->errmsg,
|
|
- _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
|
|
- jcr->last_fname, MAX_XATTR_STREAM);
|
|
- goto bail_out;
|
|
- }
|
|
+ break;
|
|
}
|
|
|
|
if (xattr_value_list == NULL) {
|
|
@@ -1285,10 +1330,17 @@
|
|
}
|
|
|
|
xattr_value_list->append(current_xattr);
|
|
- current_xattr = NULL;
|
|
xattr_count++;
|
|
- bp = strchr(bp, '\0') + 1;
|
|
- break;
|
|
+
|
|
+ /*
|
|
+ * Protect ourself against things getting out of hand.
|
|
+ */
|
|
+ if (expected_serialize_len >= MAX_XATTR_STREAM) {
|
|
+ Mmsg2(jcr->errmsg,
|
|
+ _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
|
|
+ jcr->last_fname, MAX_XATTR_STREAM);
|
|
+ goto bail_out;
|
|
+ }
|
|
}
|
|
|
|
free(xattr_list);
|
|
@@ -1321,21 +1373,13 @@
|
|
}
|
|
|
|
bail_out:
|
|
- if (current_xattr != NULL) {
|
|
- if (current_xattr->value != NULL) {
|
|
- free(current_xattr->value);
|
|
- }
|
|
- if (current_xattr->name != NULL) {
|
|
- free(current_xattr->name);
|
|
- }
|
|
- free(current_xattr);
|
|
- }
|
|
if (xattr_list != NULL) {
|
|
free(xattr_list);
|
|
}
|
|
if (xattr_value_list != NULL) {
|
|
xattr_drop_internal_table(xattr_value_list);
|
|
}
|
|
+
|
|
return retval;
|
|
}
|
|
|
|
@@ -1346,6 +1390,7 @@
|
|
{
|
|
xattr_t *current_xattr;
|
|
alist *xattr_value_list;
|
|
+ bxattr_exit_code retval = bxattr_exit_error;
|
|
|
|
xattr_value_list = New(alist(10, not_owned_by_alist));
|
|
|
|
@@ -1353,8 +1398,7 @@
|
|
content,
|
|
content_length,
|
|
xattr_value_list) != bxattr_exit_ok) {
|
|
- xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
|
|
foreach_alist(current_xattr, xattr_value_list) {
|
|
@@ -1385,12 +1429,12 @@
|
|
}
|
|
}
|
|
|
|
- xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
|
|
bail_out:
|
|
xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_error;
|
|
+
|
|
+ return retval;
|
|
}
|
|
|
|
/*
|
|
@@ -1485,7 +1529,7 @@
|
|
static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
|
|
{
|
|
bool skip_xattr;
|
|
- char *xattr_list;
|
|
+ char *xattr_list = NULL;
|
|
int cnt, index, xattr_count = 0;
|
|
int32_t xattr_list_len,
|
|
xattr_value_len;
|
|
@@ -1494,7 +1538,7 @@
|
|
int attrnamespace;
|
|
char *current_attrnamespace = NULL;
|
|
char current_attrname[XATTR_BUFSIZ], current_attrtuple[XATTR_BUFSIZ];
|
|
- xattr_t *current_xattr = NULL;
|
|
+ xattr_t *current_xattr;
|
|
alist *xattr_value_list = NULL;
|
|
bxattr_exit_code retval = bxattr_exit_error;
|
|
|
|
@@ -1655,24 +1699,6 @@
|
|
}
|
|
|
|
/*
|
|
- * Each xattr valuepair starts with a magic so we can parse it easier.
|
|
- */
|
|
- current_xattr = (xattr_t *)malloc(sizeof(xattr_t));
|
|
- memset(current_xattr, 0, sizeof(xattr_t));
|
|
- current_xattr->magic = XATTR_MAGIC;
|
|
- expected_serialize_len += sizeof(current_xattr->magic);
|
|
-
|
|
- /*
|
|
- * Allocate space for storing the name.
|
|
- */
|
|
- current_xattr->name_length = strlen(current_attrtuple);
|
|
- current_xattr->name = (char *)malloc(current_xattr->name_length);
|
|
- memcpy(current_xattr->name, current_attrtuple, current_xattr->name_length);
|
|
-
|
|
- expected_serialize_len += sizeof(current_xattr->name_length) +
|
|
- current_xattr->name_length;
|
|
-
|
|
- /*
|
|
* First see how long the value is for the extended attribute.
|
|
*/
|
|
xattr_value_len = extattr_get_link(jcr->last_fname, attrnamespace,
|
|
@@ -1695,6 +1721,29 @@
|
|
}
|
|
break;
|
|
}
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Each xattr valuepair starts with a magic so we can parse it easier.
|
|
+ */
|
|
+ current_xattr = (xattr_t *)malloc(sizeof(xattr_t));
|
|
+ current_xattr->magic = XATTR_MAGIC;
|
|
+ current_xattr->value = NULL;
|
|
+ expected_serialize_len += sizeof(current_xattr->magic);
|
|
+
|
|
+ /*
|
|
+ * Allocate space for storing the name.
|
|
+ */
|
|
+ current_xattr->name_length = strlen(current_attrtuple);
|
|
+ current_xattr->name = (char *)malloc(current_xattr->name_length);
|
|
+ memcpy(current_xattr->name, current_attrtuple, current_xattr->name_length);
|
|
+
|
|
+ expected_serialize_len += sizeof(current_xattr->name_length) +
|
|
+ current_xattr->name_length;
|
|
+
|
|
+ switch (xattr_value_len) {
|
|
case 0:
|
|
current_xattr->value = NULL;
|
|
current_xattr->value_length = 0;
|
|
@@ -1716,15 +1765,23 @@
|
|
switch (errno) {
|
|
case ENOENT:
|
|
retval = bxattr_exit_ok;
|
|
- goto bail_out;
|
|
+ break;
|
|
default:
|
|
Mmsg2(jcr->errmsg,
|
|
_("extattr_get_link error on file \"%s\": ERR=%s\n"),
|
|
jcr->last_fname, be.bstrerror());
|
|
Dmsg2(100, "extattr_get_link error file=%s ERR=%s\n",
|
|
jcr->last_fname, be.bstrerror());
|
|
- goto bail_out;
|
|
+ break;
|
|
}
|
|
+
|
|
+ /*
|
|
+ * Default failure path out when retrieval of attr fails.
|
|
+ */
|
|
+ free(current_xattr->value);
|
|
+ free(current_xattr->name);
|
|
+ free(current_xattr);
|
|
+ goto bail_out;
|
|
}
|
|
|
|
/*
|
|
@@ -1733,16 +1790,6 @@
|
|
current_xattr->value_length = xattr_value_len;
|
|
expected_serialize_len += sizeof(current_xattr->value_length) +
|
|
current_xattr->value_length;
|
|
-
|
|
- /*
|
|
- * Protect ourself against things getting out of hand.
|
|
- */
|
|
- if (expected_serialize_len >= MAX_XATTR_STREAM) {
|
|
- Mmsg2(jcr->errmsg,
|
|
- _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
|
|
- jcr->last_fname, MAX_XATTR_STREAM);
|
|
- goto bail_out;
|
|
- }
|
|
break;
|
|
}
|
|
|
|
@@ -1751,9 +1798,17 @@
|
|
}
|
|
|
|
xattr_value_list->append(current_xattr);
|
|
- current_xattr = NULL;
|
|
xattr_count++;
|
|
|
|
+ /*
|
|
+ * Protect ourself against things getting out of hand.
|
|
+ */
|
|
+ if (expected_serialize_len >= MAX_XATTR_STREAM) {
|
|
+ Mmsg2(jcr->errmsg,
|
|
+ _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
|
|
+ jcr->last_fname, MAX_XATTR_STREAM);
|
|
+ goto bail_out;
|
|
+ }
|
|
}
|
|
|
|
/*
|
|
@@ -1799,21 +1854,13 @@
|
|
if (current_attrnamespace != NULL) {
|
|
actuallyfree(current_attrnamespace);
|
|
}
|
|
- if (current_xattr != NULL) {
|
|
- if (current_xattr->value != NULL) {
|
|
- free(current_xattr->value);
|
|
- }
|
|
- if (current_xattr->name != NULL) {
|
|
- free(current_xattr->name);
|
|
- }
|
|
- free(current_xattr);
|
|
- }
|
|
if (xattr_list != NULL) {
|
|
free(xattr_list);
|
|
}
|
|
if (xattr_value_list != NULL) {
|
|
xattr_drop_internal_table(xattr_value_list);
|
|
}
|
|
+
|
|
return retval;
|
|
}
|
|
|
|
@@ -1826,6 +1873,7 @@
|
|
alist *xattr_value_list;
|
|
int current_attrnamespace, cnt;
|
|
char *attrnamespace, *attrname;
|
|
+ bxattr_exit_code retval = bxattr_exit_error;
|
|
|
|
xattr_value_list = New(alist(10, not_owned_by_alist));
|
|
|
|
@@ -1833,8 +1881,7 @@
|
|
content,
|
|
content_length,
|
|
xattr_value_list) != bxattr_exit_ok) {
|
|
- xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
|
|
foreach_alist(current_xattr, xattr_value_list) {
|
|
@@ -1889,12 +1936,12 @@
|
|
}
|
|
}
|
|
|
|
- xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
|
|
bail_out:
|
|
xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_error;
|
|
+
|
|
+ return retval;
|
|
}
|
|
|
|
/*
|
|
@@ -1950,7 +1997,7 @@
|
|
xattrbuf_size,
|
|
xattrbuf_min_size;
|
|
uint32_t expected_serialize_len = 0;
|
|
- xattr_t *current_xattr = NULL;
|
|
+ xattr_t *current_xattr;
|
|
alist *xattr_value_list = NULL;
|
|
struct proplistname_args prop_args;
|
|
bxattr_exit_code retval = bxattr_exit_error;
|
|
@@ -2086,7 +2133,6 @@
|
|
* Each xattr valuepair starts with a magic so we can parse it easier.
|
|
*/
|
|
current_xattr = (xattr_t *)malloc(sizeof(xattr_t));
|
|
- memset(current_xattr, 0, sizeof(xattr_t));
|
|
current_xattr->magic = XATTR_MAGIC;
|
|
expected_serialize_len += sizeof(current_xattr->magic);
|
|
|
|
@@ -2103,6 +2149,13 @@
|
|
expected_serialize_len += sizeof(current_xattr->value_length) +
|
|
current_xattr->value_length;
|
|
|
|
+ if (xattr_value_list == NULL) {
|
|
+ xattr_value_list = New(alist(10, not_owned_by_alist));
|
|
+ }
|
|
+
|
|
+ xattr_value_list->append(current_xattr);
|
|
+ xattr_count++;
|
|
+
|
|
/*
|
|
* Protect ourself against things getting out of hand.
|
|
*/
|
|
@@ -2112,14 +2165,6 @@
|
|
jcr->last_fname, MAX_XATTR_STREAM);
|
|
goto bail_out;
|
|
}
|
|
-
|
|
- if (xattr_value_list == NULL) {
|
|
- xattr_value_list = New(alist(10, not_owned_by_alist));
|
|
- }
|
|
-
|
|
- xattr_value_list->append(current_xattr);
|
|
- current_xattr = NULL;
|
|
- xattr_count++;
|
|
}
|
|
|
|
/*
|
|
@@ -2149,15 +2194,6 @@
|
|
}
|
|
|
|
bail_out:
|
|
- if (current_xattr != NULL) {
|
|
- if (current_xattr->value != NULL) {
|
|
- free(current_xattr->value);
|
|
- }
|
|
- if (current_xattr->name != NULL) {
|
|
- free(current_xattr->name);
|
|
- }
|
|
- free(current_xattr);
|
|
- }
|
|
if (xattr_value_list != NULL) {
|
|
xattr_drop_internal_table(xattr_value_list);
|
|
}
|
|
@@ -2183,8 +2219,7 @@
|
|
content,
|
|
content_length,
|
|
xattr_value_list) != bxattr_exit_ok) {
|
|
- xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
|
|
/*
|
|
@@ -2253,17 +2288,15 @@
|
|
break;
|
|
}
|
|
|
|
- free(xattrbuf);
|
|
-
|
|
- xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
|
|
bail_out:
|
|
if (xattrbuf) {
|
|
free(xattrbuf);
|
|
}
|
|
xattr_drop_internal_table(xattr_value_list);
|
|
- return bxattr_exit_error;
|
|
+
|
|
+ return retval;
|
|
}
|
|
|
|
/*
|
|
@@ -2521,6 +2554,7 @@
|
|
|
|
static bxattr_exit_code solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char **acl_text)
|
|
{
|
|
+ bxattr_exit_code retval = bxattr_exit_error;
|
|
#ifdef HAVE_ACL
|
|
#ifdef HAVE_EXTENDED_ACL
|
|
int flags;
|
|
@@ -2540,14 +2574,15 @@
|
|
|
|
switch (errno) {
|
|
case ENOENT:
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
+ goto bail_out;
|
|
default:
|
|
Mmsg3(jcr->errmsg,
|
|
_("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"),
|
|
attrname, jcr->last_fname, be.bstrerror());
|
|
Dmsg3(100, "facl_get/acl_get of xattr %s on \"%s\" failed: ERR=%s\n",
|
|
attrname, jcr->last_fname, be.bstrerror());
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
}
|
|
|
|
@@ -2569,7 +2604,7 @@
|
|
} else {
|
|
*acl_text = NULL;
|
|
}
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
#else /* HAVE_EXTENDED_ACL */
|
|
int n;
|
|
aclent_t *acls = NULL;
|
|
@@ -2592,7 +2627,8 @@
|
|
switch (errno) {
|
|
case ENOENT:
|
|
free(acls);
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
+ goto bail_out;
|
|
default:
|
|
Mmsg3(jcr->errmsg,
|
|
_("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"),
|
|
@@ -2600,7 +2636,7 @@
|
|
Dmsg3(100, "facl/acl of xattr %s on \"%s\" failed: ERR=%s\n",
|
|
attrname, jcr->last_fname, be.bstrerror());
|
|
free(acls);
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
}
|
|
|
|
@@ -2617,7 +2653,7 @@
|
|
Dmsg3(100, "acltotext of xattr %s on \"%s\" failed: ERR=%s\n",
|
|
attrname, jcr->last_fname, be.bstrerror());
|
|
free(acls);
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
} else {
|
|
*acl_text = NULL;
|
|
@@ -2627,12 +2663,15 @@
|
|
} else {
|
|
*acl_text = NULL;
|
|
}
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
#endif /* HAVE_EXTENDED_ACL */
|
|
|
|
#else /* HAVE_ACL */
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
#endif /* HAVE_ACL */
|
|
+
|
|
+bail_out:
|
|
+ return retval;
|
|
}
|
|
|
|
/*
|
|
@@ -3655,7 +3694,7 @@
|
|
{
|
|
char cwd[PATH_MAX];
|
|
bool is_extensible = false;
|
|
- bxattr_exit_code retval;
|
|
+ bxattr_exit_code retval = bxattr_exit_error;
|
|
|
|
/*
|
|
* First make sure we can restore xattr on the filesystem.
|
|
@@ -3669,7 +3708,7 @@
|
|
jcr->last_fname);
|
|
Dmsg1(100, "Unable to restore extensible attributes on file \"%s\", filesystem doesn't support this\n",
|
|
jcr->last_fname);
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
|
|
is_extensible = true;
|
|
@@ -3682,11 +3721,11 @@
|
|
jcr->last_fname);
|
|
Dmsg1(100, "Unable to restore extended attributes on file \"%s\", filesystem doesn't support this\n",
|
|
jcr->last_fname);
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
break;
|
|
default:
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
|
|
/*
|
|
@@ -3696,6 +3735,8 @@
|
|
getcwd(cwd, sizeof(cwd));
|
|
retval = solaris_restore_xattrs(jcr, is_extensible, content, content_length);
|
|
chdir(cwd);
|
|
+
|
|
+bail_out:
|
|
return retval;
|
|
}
|
|
|
|
@@ -3751,6 +3792,7 @@
|
|
int ret;
|
|
struct stat st;
|
|
unsigned int cnt;
|
|
+ bxattr_exit_code retval = bxattr_exit_error;
|
|
|
|
/*
|
|
* See if we are changing from one device to an other.
|
|
@@ -3765,14 +3807,15 @@
|
|
|
|
switch (errno) {
|
|
case ENOENT:
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
+ goto bail_out;
|
|
default:
|
|
Mmsg2(jcr->errmsg,
|
|
_("Unable to stat file \"%s\": ERR=%s\n"),
|
|
jcr->last_fname, be.bstrerror());
|
|
Dmsg2(100, "Unable to stat file \"%s\": ERR=%s\n",
|
|
jcr->last_fname, be.bstrerror());
|
|
- return bxattr_exit_error;
|
|
+ goto bail_out;
|
|
}
|
|
break;
|
|
}
|
|
@@ -3801,7 +3844,8 @@
|
|
*/
|
|
for (cnt = 0; cnt < sizeof(os_default_xattr_streams) / sizeof(int); cnt++) {
|
|
if (os_default_xattr_streams[cnt] == stream) {
|
|
- return os_parse_xattr_streams(jcr, stream, content, content_length);
|
|
+ retval = os_parse_xattr_streams(jcr, stream, content, content_length);
|
|
+ goto bail_out;
|
|
}
|
|
}
|
|
} else {
|
|
@@ -3809,15 +3853,18 @@
|
|
* Increment error count but don't log an error again for the same filesystem.
|
|
*/
|
|
jcr->xattr_data->u.parse->nr_errors++;
|
|
- return bxattr_exit_ok;
|
|
+ retval = bxattr_exit_ok;
|
|
+ goto bail_out;
|
|
}
|
|
|
|
/*
|
|
* Issue a warning and discard the message. But pretend the restore was ok.
|
|
*/
|
|
Jmsg2(jcr, M_WARNING, 0,
|
|
- _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
|
|
- jcr->last_fname, stream);
|
|
- return bxattr_exit_error;
|
|
+ _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
|
|
+ jcr->last_fname, stream);
|
|
+
|
|
+bail_out:
|
|
+ return retval;
|
|
}
|
|
#endif
|