Extended the capabilities of iso_node_set_attrs() and
mentioned the new error codes in the error text generator
This commit is contained in:
parent
f66e3b8e2f
commit
c974365b16
@ -45,8 +45,12 @@ The reader shall be prepared to detect and handle oversized data.
|
||||
|
||||
One or more AA entries form the Attribute List of a file object with
|
||||
an even number of components. Each two consequtive components form a pair of
|
||||
Name and Value. The empty name is reserved for a compact representation of
|
||||
ALCs. The meaning of any other name is not specified by this document.
|
||||
Name and Value.
|
||||
Names which do not contain a perisod character "." are reserved for
|
||||
registration at libburnia.org. The meaning of any other names is not
|
||||
specified by this document.
|
||||
For now only one name is registered:
|
||||
The empty name indicates that the value is a compact representation of ALCs.
|
||||
|
||||
All AA entries except the last one shall have the CONTINUE flag set. An AA
|
||||
entry with CONTINUE set to 0 indicates the end of the Attribute List.
|
||||
|
@ -4205,7 +4205,8 @@ void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
||||
|
||||
|
||||
/* ts A90121 */
|
||||
/** AAIP info is present in ISO image but will be ignored (NOTE, HIGH, -336) */
|
||||
/** AAIP info with ACL or xattr in ISO image will be ignored
|
||||
(NOTE, HIGH, -336) */
|
||||
#define ISO_AAIP_IGNORED 0xB030FEB0
|
||||
|
||||
/* ts A90130 */
|
||||
@ -4217,11 +4218,12 @@ void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
||||
#define ISO_AAIP_BAD_ACL_TEXT 0xE830FEAE
|
||||
|
||||
/* ts A90130 */
|
||||
/** No AAIP processing enabled at compile time (FAILURE, HIGH, -339) */
|
||||
/** AAIP processing for ACL and xattr not enabled at compile time
|
||||
(FAILURE, HIGH, -339) */
|
||||
#define ISO_AAIP_NOT_ENABLED 0xE830FEAD
|
||||
|
||||
/* ts A90130 */
|
||||
/** Error with decoding attribute list AAIP info (FAILURE, HIGH, -340) */
|
||||
/** Error with decoding AAIP info for ACL or xattr (FAILURE, HIGH, -340) */
|
||||
#define ISO_AAIP_BAD_AASTRING 0xE830FEAC
|
||||
|
||||
/* ts A90131 */
|
||||
@ -4232,6 +4234,10 @@ void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
||||
/** Error with attaching ACL or xattr to local file (FAILURE, HIGH, -342) */
|
||||
#define ISO_AAIP_NO_SET_LOCAL 0xE830FEAA
|
||||
|
||||
/* ts A90206 */
|
||||
/** Unallowed attempt to set an xattr with non-user name
|
||||
(FAILURE, HIGH, -343) */
|
||||
#define ISO_AAIP_NON_USER_NAME 0xE830FEA9
|
||||
|
||||
|
||||
/* --------------------------------- AAIP --------------------------------- */
|
||||
@ -4407,6 +4413,12 @@ int iso_node_get_attrs(IsoNode *node, size_t *num_attrs,
|
||||
* Bitfield for control purposes
|
||||
* bit0= Do not maintain eventual existing ACL of the node.
|
||||
* Set eventual new ACL from value of empty name.
|
||||
* bit1= Do not clear the existing attribute list but merge it with
|
||||
* the list given by this call
|
||||
* bit2= Delete the attributes with the given names
|
||||
* bit3= Allow non-user attribute.
|
||||
* I.e. those with a non-empty name which does not begin by "user."
|
||||
* (The empty name is always allowed and governed by bit0.)
|
||||
* @return
|
||||
* 1 = ok
|
||||
* < 0 = error
|
||||
|
@ -211,9 +211,21 @@ const char *iso_error_to_msg(int errcode)
|
||||
case ISO_DATA_SOURCE_FATAL:
|
||||
return "Read error occured with IsoDataSource";
|
||||
case ISO_AAIP_IGNORED:
|
||||
return "AAIP info is present in ISO image but will be ignored";
|
||||
return "AAIP info with ACL or xattr in ISO image will be ignored";
|
||||
case ISO_AAIP_BAD_ACL:
|
||||
return "Error with decoding ACL from AAIP info";
|
||||
case ISO_AAIP_BAD_ACL_TEXT:
|
||||
return "Error with encoding ACL for AAIP";
|
||||
case ISO_AAIP_NOT_ENABLED:
|
||||
return "AAIP processing for ACL and xattr not enabled at compile time";
|
||||
case ISO_AAIP_BAD_AASTRING:
|
||||
return "Error with decoding AAIP info for ACL or xattr";
|
||||
case ISO_AAIP_NO_GET_LOCAL:
|
||||
return "Error with reading ACL or xattr from local file";
|
||||
case ISO_AAIP_NO_SET_LOCAL:
|
||||
return "Error with attaching ACL or xattr to local file";
|
||||
case ISO_AAIP_NON_USER_NAME:
|
||||
return "Unallowed attempt to set an xattr with non-user name";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
219
libisofs/node.c
219
libisofs/node.c
@ -1462,6 +1462,138 @@ int iso_node_get_attrs(IsoNode *node, size_t *num_attrs,
|
||||
}
|
||||
|
||||
|
||||
/* ts A90205 */
|
||||
/* Enlarge attribute list */
|
||||
static
|
||||
int attr_enlarge_list(char ***names, size_t **value_lengths, char ***values,
|
||||
size_t new_num, int flag)
|
||||
{
|
||||
void *newpt;
|
||||
|
||||
newpt = realloc(*names, new_num * sizeof(char *));
|
||||
if (newpt == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
*names = (char **) newpt;
|
||||
newpt = realloc(*values, new_num * sizeof(char *));
|
||||
if (newpt == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
*values = (char **) newpt;
|
||||
newpt = realloc(*value_lengths, new_num * sizeof(size_t));
|
||||
if (newpt == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
*value_lengths = (size_t *) newpt;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A90205 */
|
||||
/* Merge attribute list of node and given new attribute list into
|
||||
attribute list returned by m_* parameters.
|
||||
The m_* paramters have finally to be freed by a call with bit15 set.
|
||||
@param flag Bitfield for control purposes
|
||||
bit2= delete rather than overwrite
|
||||
bit15= release memory and return 1
|
||||
*/
|
||||
static
|
||||
int iso_node_merge_xattr(IsoNode *node, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values,
|
||||
size_t *m_num_attrs, char ***m_names,
|
||||
size_t **m_value_lengths, char ***m_values, int flag)
|
||||
{
|
||||
int ret;
|
||||
size_t new_names = 0, deleted = 0, i, j, w;
|
||||
|
||||
if (flag & (1 << 15)) {
|
||||
iso_node_get_attrs(node, m_num_attrs, m_names, m_value_lengths,
|
||||
m_values, 1 << 15);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = iso_node_get_attrs(node, m_num_attrs, m_names, m_value_lengths,
|
||||
m_values, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Handle existing names, count non-existing names */
|
||||
for (i = 0; i < num_attrs; i++) {
|
||||
for (j = 0; j < *m_num_attrs; j++) {
|
||||
if (names[i] == NULL || (*m_names)[j] == NULL)
|
||||
continue;
|
||||
if (strcmp(names[i], (*m_names)[j]) == 0) {
|
||||
if ((*m_values)[j] != NULL)
|
||||
free((*m_values)[j]);
|
||||
(*m_values)[j] = NULL;
|
||||
(*m_value_lengths)[j] = 0;
|
||||
if (flag & 4) {
|
||||
/* Delete pair */
|
||||
free((*m_names)[j]);
|
||||
(*m_names)[j] = NULL;
|
||||
deleted++;
|
||||
} else {
|
||||
(*m_values)[j] = calloc(value_lengths[i] + 1, 1);
|
||||
if ((*m_values)[j] == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy((*m_values)[j], values[i], value_lengths[i]);
|
||||
(*m_values)[j][value_lengths[i]] = 0;
|
||||
(*m_value_lengths)[j] = value_lengths[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j >= *m_num_attrs)
|
||||
new_names++;
|
||||
}
|
||||
if (new_names > 0 && (flag & 4)) {
|
||||
|
||||
/* >>> warn of non-existing name on delete ? */;
|
||||
|
||||
} else if (new_names > 0) {
|
||||
ret = attr_enlarge_list(m_names, m_value_lengths, m_values,
|
||||
*m_num_attrs + new_names, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Set new pairs */;
|
||||
w = *m_num_attrs;
|
||||
for (i = 0; i < num_attrs; i++) {
|
||||
for (j = 0; j < *m_num_attrs; j++) {
|
||||
if (names[i] == NULL || (*m_names)[j] == NULL)
|
||||
continue;
|
||||
if (strcmp(names[i], (*m_names)[j]) == 0)
|
||||
continue;
|
||||
}
|
||||
if (j < *m_num_attrs) /* Name is not new */
|
||||
continue;
|
||||
(*m_names)[w] = strdup(names[i]);
|
||||
if ((*m_names)[w] == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
(*m_values)[w] = calloc(value_lengths[i] + 1, 1);
|
||||
if ((*m_values)[w] == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy((*m_values)[w], values[i], value_lengths[i]);
|
||||
(*m_values)[w][value_lengths[i]] = 0;
|
||||
(*m_value_lengths)[w] = value_lengths[i];
|
||||
w++;
|
||||
}
|
||||
*m_num_attrs = w;
|
||||
}
|
||||
if (deleted > 0) {
|
||||
/* Garbage collection */
|
||||
w = 0;
|
||||
for (j = 0; j < *m_num_attrs; j++) {
|
||||
if ((*m_names)[j] == NULL)
|
||||
continue;
|
||||
(*m_names)[w] = (*m_names)[j];
|
||||
(*m_values)[w] = (*m_values)[j];
|
||||
(*m_value_lengths)[w] = (*m_value_lengths)[j];
|
||||
w++;
|
||||
}
|
||||
*m_num_attrs = w;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A90121 */
|
||||
int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values, int flag)
|
||||
@ -1470,47 +1602,74 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
|
||||
#ifdef Libisofs_with_aaiP
|
||||
|
||||
int ret;
|
||||
size_t sret, result_len;
|
||||
size_t sret, result_len, m_num = 0, *m_value_lengths = NULL, i;
|
||||
unsigned char *result;
|
||||
char *a_acl= NULL, *d_acl= NULL;
|
||||
char *a_acl = NULL, *d_acl = NULL, **m_names = NULL, **m_values = NULL;
|
||||
|
||||
if (!(flag & 8))
|
||||
for (i = 0; i < num_attrs; i++)
|
||||
if (strncmp(names[i], "user.", 5) != 0 && names[i][0] != 0)
|
||||
return ISO_AAIP_NON_USER_NAME;
|
||||
|
||||
if (!(flag & 1))
|
||||
iso_node_get_acl_text(node, &a_acl, &d_acl, 16);
|
||||
|
||||
if (flag & (2 | 4)) {
|
||||
/* Merge old and new lists */
|
||||
ret = iso_node_merge_xattr(
|
||||
node, num_attrs, names, value_lengths, values,
|
||||
&m_num, &m_names, &m_value_lengths, &m_values, flag & 4);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
num_attrs = m_num;
|
||||
names = m_names;
|
||||
value_lengths = m_value_lengths;
|
||||
values = m_values;
|
||||
}
|
||||
|
||||
if (num_attrs == 0) {
|
||||
ret = iso_node_remove_xinfo(node, aaip_xinfo_func);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
if (!(flag & 1)) {
|
||||
ret = iso_node_set_acl_text(node, a_acl, d_acl, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
return 1;
|
||||
ret = 1;
|
||||
goto ex;
|
||||
}
|
||||
sret = aaip_encode(num_attrs, names, value_lengths, values,
|
||||
&result_len, &result, 0);
|
||||
if (sret == 0)
|
||||
return ISO_OUT_OF_MEM;
|
||||
if (sret == 0) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
ret = iso_node_remove_xinfo(node, aaip_xinfo_func);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
ret = iso_node_add_xinfo(node, aaip_xinfo_func, result);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
if (ret == 0) {
|
||||
|
||||
/* >>> something is messed up with xinfo */;
|
||||
|
||||
return ISO_ERROR;
|
||||
ret = ISO_ERROR;
|
||||
goto ex;
|
||||
}
|
||||
if (!(flag & 1)) {
|
||||
ret = iso_node_set_acl_text(node, a_acl, d_acl, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
return 1;
|
||||
ret = 1;
|
||||
ex:;
|
||||
/* Dispose eventual merged list */
|
||||
iso_node_merge_xattr(node, num_attrs, names, value_lengths, values,
|
||||
&m_num, &m_names, &m_value_lengths, &m_values, 1 << 15);
|
||||
return ret;
|
||||
|
||||
#else /* Libisofs_with_aaiP */
|
||||
|
||||
@ -1579,7 +1738,7 @@ int iso_node_get_acl_text(IsoNode *node,
|
||||
*access_text = *default_text = NULL;
|
||||
|
||||
ret = iso_node_get_attrs(node, &num_attrs, &names,
|
||||
&value_lengths, &values, 0);
|
||||
&value_lengths, &values, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -1650,8 +1809,7 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
|
||||
size_t a_text_fill = 0, d_text_fill = 0;
|
||||
size_t v_len, acl_len= 0;
|
||||
char **names = NULL, **values = NULL, *a_text = NULL, *d_text = NULL;
|
||||
char **new_names, **new_values;
|
||||
size_t *new_value_lengths;
|
||||
|
||||
unsigned char *v_data, *acl= NULL;
|
||||
int ret;
|
||||
mode_t st_mode;
|
||||
@ -1664,7 +1822,7 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
|
||||
}
|
||||
|
||||
ret = iso_node_get_attrs(node, &num_attrs, &names,
|
||||
&value_lengths, &values, 0);
|
||||
&value_lengths, &values, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -1721,6 +1879,9 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
|
||||
if (values[i] != NULL)
|
||||
free(values[i]);
|
||||
if(acl == NULL) { /* delete whole ACL attribute */
|
||||
|
||||
/* >>> update S_IRWXG by eventual group:: ACL entry */;
|
||||
|
||||
for (j = i + 1; j < num_attrs; j++) {
|
||||
names[j - 1] = names[j];
|
||||
value_lengths[j - 1] = value_lengths[j];
|
||||
@ -1735,7 +1896,7 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
|
||||
|
||||
/* Encode attributes and attach to node */
|
||||
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
|
||||
0);
|
||||
1 | 8);
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
goto update_perms;
|
||||
@ -1754,26 +1915,9 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* Enlarge attribute list */
|
||||
new_names = realloc(names, (num_attrs + 1) * sizeof(char *));
|
||||
if (new_names == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
ret = attr_enlarge_list(&names, &value_lengths, &values, num_attrs + 1, 0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
names = new_names;
|
||||
new_values = realloc(values, (num_attrs + 1) * sizeof(char *));
|
||||
if (new_values == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto ex;
|
||||
}
|
||||
values = new_values;
|
||||
new_value_lengths = realloc(value_lengths,
|
||||
(num_attrs + 1) * sizeof(size_t));
|
||||
if (new_value_lengths == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto ex;
|
||||
}
|
||||
value_lengths = new_value_lengths;
|
||||
|
||||
/* Set new ACL attribute */
|
||||
names[num_attrs] = strdup("");
|
||||
@ -1787,7 +1931,8 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
|
||||
num_attrs++;
|
||||
|
||||
/* Encode attributes and attach to node */
|
||||
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values, 0);
|
||||
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
|
||||
1 | 8);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user