Extended the capabilities of iso_node_set_attrs() and

mentioned the new error codes in the error text generator
This commit is contained in:
Thomas Schmitt 2009-02-06 11:41:24 +01:00
parent f66e3b8e2f
commit c974365b16
4 changed files with 216 additions and 43 deletions

View File

@ -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 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 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 Name and Value.
ALCs. The meaning of any other name is not specified by this document. 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 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. entry with CONTINUE set to 0 indicates the end of the Attribute List.

View File

@ -4205,7 +4205,8 @@ void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
/* ts A90121 */ /* 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 #define ISO_AAIP_IGNORED 0xB030FEB0
/* ts A90130 */ /* 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 #define ISO_AAIP_BAD_ACL_TEXT 0xE830FEAE
/* ts A90130 */ /* 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 #define ISO_AAIP_NOT_ENABLED 0xE830FEAD
/* ts A90130 */ /* 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 #define ISO_AAIP_BAD_AASTRING 0xE830FEAC
/* ts A90131 */ /* 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) */ /** Error with attaching ACL or xattr to local file (FAILURE, HIGH, -342) */
#define ISO_AAIP_NO_SET_LOCAL 0xE830FEAA #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 --------------------------------- */ /* --------------------------------- AAIP --------------------------------- */
@ -4407,6 +4413,12 @@ int iso_node_get_attrs(IsoNode *node, size_t *num_attrs,
* Bitfield for control purposes * Bitfield for control purposes
* bit0= Do not maintain eventual existing ACL of the node. * bit0= Do not maintain eventual existing ACL of the node.
* Set eventual new ACL from value of empty name. * 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 * @return
* 1 = ok * 1 = ok
* < 0 = error * < 0 = error

View File

@ -211,9 +211,21 @@ const char *iso_error_to_msg(int errcode)
case ISO_DATA_SOURCE_FATAL: case ISO_DATA_SOURCE_FATAL:
return "Read error occured with IsoDataSource"; return "Read error occured with IsoDataSource";
case ISO_AAIP_IGNORED: 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: case ISO_AAIP_BAD_ACL:
return "Error with decoding ACL from AAIP info"; 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: default:
return "Unknown error"; return "Unknown error";
} }

View File

@ -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 */ /* ts A90121 */
int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names, int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag) 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 #ifdef Libisofs_with_aaiP
int ret; int ret;
size_t sret, result_len; size_t sret, result_len, m_num = 0, *m_value_lengths = NULL, i;
unsigned char *result; 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)) if (!(flag & 1))
iso_node_get_acl_text(node, &a_acl, &d_acl, 16); 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) { if (num_attrs == 0) {
ret = iso_node_remove_xinfo(node, aaip_xinfo_func); ret = iso_node_remove_xinfo(node, aaip_xinfo_func);
if (ret < 0) if (ret < 0)
return ret; goto ex;
if (!(flag & 1)) { if (!(flag & 1)) {
ret = iso_node_set_acl_text(node, a_acl, d_acl, 0); ret = iso_node_set_acl_text(node, a_acl, d_acl, 0);
if (ret < 0) if (ret < 0)
return ret; goto ex;
} }
return 1; ret = 1;
goto ex;
} }
sret = aaip_encode(num_attrs, names, value_lengths, values, sret = aaip_encode(num_attrs, names, value_lengths, values,
&result_len, &result, 0); &result_len, &result, 0);
if (sret == 0) if (sret == 0) {
return ISO_OUT_OF_MEM; ret = ISO_OUT_OF_MEM;
goto ex;
}
ret = iso_node_remove_xinfo(node, aaip_xinfo_func); ret = iso_node_remove_xinfo(node, aaip_xinfo_func);
if (ret < 0) if (ret < 0)
return ret; goto ex;
ret = iso_node_add_xinfo(node, aaip_xinfo_func, result); ret = iso_node_add_xinfo(node, aaip_xinfo_func, result);
if (ret < 0) if (ret < 0)
return ret; goto ex;
if (ret == 0) { if (ret == 0) {
/* >>> something is messed up with xinfo */; /* >>> something is messed up with xinfo */;
return ISO_ERROR; ret = ISO_ERROR;
goto ex;
} }
if (!(flag & 1)) { if (!(flag & 1)) {
ret = iso_node_set_acl_text(node, a_acl, d_acl, 0); ret = iso_node_set_acl_text(node, a_acl, d_acl, 0);
if (ret < 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 */ #else /* Libisofs_with_aaiP */
@ -1579,7 +1738,7 @@ int iso_node_get_acl_text(IsoNode *node,
*access_text = *default_text = NULL; *access_text = *default_text = NULL;
ret = iso_node_get_attrs(node, &num_attrs, &names, ret = iso_node_get_attrs(node, &num_attrs, &names,
&value_lengths, &values, 0); &value_lengths, &values, 1);
if (ret < 0) if (ret < 0)
return ret; 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 a_text_fill = 0, d_text_fill = 0;
size_t v_len, acl_len= 0; size_t v_len, acl_len= 0;
char **names = NULL, **values = NULL, *a_text = NULL, *d_text = NULL; 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; unsigned char *v_data, *acl= NULL;
int ret; int ret;
mode_t st_mode; 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, ret = iso_node_get_attrs(node, &num_attrs, &names,
&value_lengths, &values, 0); &value_lengths, &values, 1);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -1721,6 +1879,9 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
if (values[i] != NULL) if (values[i] != NULL)
free(values[i]); free(values[i]);
if(acl == NULL) { /* delete whole ACL attribute */ if(acl == NULL) { /* delete whole ACL attribute */
/* >>> update S_IRWXG by eventual group:: ACL entry */;
for (j = i + 1; j < num_attrs; j++) { for (j = i + 1; j < num_attrs; j++) {
names[j - 1] = names[j]; names[j - 1] = names[j];
value_lengths[j - 1] = value_lengths[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 */ /* Encode attributes and attach to node */
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values, ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
0); 1 | 8);
if (ret <= 0) if (ret <= 0)
goto ex; goto ex;
goto update_perms; goto update_perms;
@ -1754,26 +1915,9 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
goto ex; goto ex;
} }
/* Enlarge attribute list */ ret = attr_enlarge_list(&names, &value_lengths, &values, num_attrs + 1, 0);
new_names = realloc(names, (num_attrs + 1) * sizeof(char *)); if (ret < 0)
if (new_names == NULL) {
ret = ISO_OUT_OF_MEM;
goto ex; 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 */ /* Set new ACL attribute */
names[num_attrs] = strdup(""); names[num_attrs] = strdup("");
@ -1787,7 +1931,8 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
num_attrs++; num_attrs++;
/* Encode attributes and attach to node */ /* 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) if (ret < 0)
goto ex; goto ex;