New API call iso_node_set_acl_text()
and automatic update of ACL entries by iso_node_set_permissions()
This commit is contained in:
parent
d4ce4a7f88
commit
1150ee32a4
@ -173,9 +173,11 @@ The Value shall be an arbitrary number of ACL Entries:
|
|||||||
they are not aware of updates of this document which would
|
they are not aware of updates of this document which would
|
||||||
assign a meaning to them.
|
assign a meaning to them.
|
||||||
|
|
||||||
If any of ACL_USER_OBJ, ACL_GROUP_OBJ, ACL_OTHER are missing then the settings
|
The entries ACL_USER_OBJ, ACL_GROUP_OBJ, ACL_OTHER must match the permission
|
||||||
from the PX field shall get into effect. If they exist then they shall override
|
bits of the PX field. This shall obey the peculiar rule that
|
||||||
the PX field.
|
ACL_USER_OBJ must match S_IRWXU, ACL_OTHER must match S_IRWXO,
|
||||||
|
ACL_MASK - if present - must match S_IRWXG, else ACL_GROUP must match S_IRWXG.
|
||||||
|
If there is ACL_USER_OBJ or ACL_GROUP_OBJ there must also be ACL_MASK.
|
||||||
|
|
||||||
A numeric qualifier is a binary number of variable length. The Most Significant
|
A numeric qualifier is a binary number of variable length. The Most Significant
|
||||||
Byte comes first. The number shall be the "POSIX File User ID" resp.
|
Byte comes first. The number shall be the "POSIX File User ID" resp.
|
||||||
|
@ -63,7 +63,7 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
|||||||
if(flag & 16) {
|
if(flag & 16) {
|
||||||
ret= stat(path, &stbuf);
|
ret= stat(path, &stbuf);
|
||||||
if(ret != -1) {
|
if(ret != -1) {
|
||||||
ret = aaip_cleanout_st_mode(*text, stbuf.st_mode, 2);
|
ret = aaip_cleanout_st_mode(*text, &(stbuf.st_mode), 2);
|
||||||
if(!(ret & (7 | 64)))
|
if(!(ret & (7 | 64)))
|
||||||
(*text)[0]= 0;
|
(*text)[0]= 0;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
|||||||
if(flag & 16) {
|
if(flag & 16) {
|
||||||
ret= stat(path, &stbuf);
|
ret= stat(path, &stbuf);
|
||||||
if(ret != -1) {
|
if(ret != -1) {
|
||||||
ret = aaip_cleanout_st_mode(*text, stbuf.st_mode, 2);
|
ret = aaip_cleanout_st_mode(*text, &(stbuf.st_mode), 2);
|
||||||
if(!(ret & (7 | 64)))
|
if(!(ret & (7 | 64)))
|
||||||
(*text)[0]= 0;
|
(*text)[0]= 0;
|
||||||
}
|
}
|
||||||
@ -99,9 +99,18 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
int ret, retry= 0;
|
int ret, retry= 0;
|
||||||
char *list= NULL;
|
char *list= NULL;
|
||||||
ssize_t list_size= 0, i, num_names= 0, value_ret;
|
ssize_t list_size= 0, i, num_names= 0, value_ret;
|
||||||
size_t a_acl_len= 0, d_acl_len= 0, acl_len= 0;
|
size_t acl_len= 0;
|
||||||
unsigned char *a_acl= NULL, *d_acl= NULL, *acl= NULL;
|
unsigned char *acl= NULL;
|
||||||
|
|
||||||
|
#define Aaip_os_linux_use_both_acL yes
|
||||||
|
|
||||||
|
#ifdef Aaip_os_linux_use_both_acL
|
||||||
|
char *a_acl_text= NULL, *d_acl_text= NULL;
|
||||||
|
#else
|
||||||
char *acl_text= NULL;
|
char *acl_text= NULL;
|
||||||
|
size_t a_acl_len= 0, d_acl_len= 0;
|
||||||
|
unsigned char *a_acl= NULL, *d_acl= NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(flag & (1 << 15)) { /* Free memory */
|
if(flag & (1 << 15)) { /* Free memory */
|
||||||
if(*names != NULL)
|
if(*names != NULL)
|
||||||
@ -177,6 +186,21 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(flag & 1) { /* Obtain ACL */
|
if(flag & 1) { /* Obtain ACL */
|
||||||
|
|
||||||
|
#ifdef Aaip_os_linux_use_both_acL
|
||||||
|
|
||||||
|
/* access-ACL */
|
||||||
|
aaip_get_acl_text(path, &a_acl_text, flag & 16);
|
||||||
|
aaip_get_acl_text(path, &d_acl_text, 1);
|
||||||
|
if(a_acl_text == NULL && d_acl_text == NULL)
|
||||||
|
{ret= 1; goto ex;}
|
||||||
|
ret= aaip_encode_both_acl(a_acl_text, d_acl_text,
|
||||||
|
&acl_len, &acl, (flag & 2));
|
||||||
|
if(ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
#else /* Aaip_os_linux_use_both_acL */
|
||||||
|
|
||||||
/* access-ACL */
|
/* access-ACL */
|
||||||
ret= aaip_get_acl_text(path, &acl_text, flag & 16);
|
ret= aaip_get_acl_text(path, &acl_text, flag & 16);
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
@ -209,24 +233,40 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
acl_len= a_acl_len;
|
acl_len= a_acl_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* ! Aaip_os_linux_use_both_acL */
|
||||||
|
|
||||||
/* Set as attribute with empty name */;
|
/* Set as attribute with empty name */;
|
||||||
(*names)[*num_attrs]= strdup("");
|
(*names)[*num_attrs]= strdup("");
|
||||||
if((*names)[*num_attrs] == NULL)
|
if((*names)[*num_attrs] == NULL)
|
||||||
{ret= -1; goto ex;}
|
{ret= -1; goto ex;}
|
||||||
(*values)[*num_attrs]= (char *) acl;
|
(*values)[*num_attrs]= (char *) acl;
|
||||||
|
acl= NULL;
|
||||||
(*value_lengths)[*num_attrs]= acl_len;
|
(*value_lengths)[*num_attrs]= acl_len;
|
||||||
(*num_attrs)++;
|
(*num_attrs)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret= 1;
|
ret= 1;
|
||||||
ex:;
|
ex:;
|
||||||
|
#ifdef Aaip_os_linux_use_both_acL
|
||||||
|
|
||||||
|
if(a_acl_text != NULL)
|
||||||
|
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
|
||||||
|
if(d_acl_text != NULL)
|
||||||
|
aaip_get_acl_text("", &d_acl_text, 1 << 15); /* free */
|
||||||
|
|
||||||
|
#else /* Aaip_os_linux_use_both_acL */
|
||||||
|
|
||||||
if(a_acl != NULL)
|
if(a_acl != NULL)
|
||||||
free(a_acl);
|
free(a_acl);
|
||||||
if(d_acl != NULL)
|
if(d_acl != NULL)
|
||||||
free(d_acl);
|
free(d_acl);
|
||||||
|
if(acl != NULL)
|
||||||
|
free(acl);
|
||||||
if(acl_text != NULL)
|
if(acl_text != NULL)
|
||||||
aaip_get_acl_text("", &acl_text, 1 << 15); /* free */
|
aaip_get_acl_text("", &acl_text, 1 << 15); /* free */
|
||||||
|
|
||||||
|
#endif /* ! Aaip_os_linux_use_both_acL */
|
||||||
|
|
||||||
if(ret <= 0 || (flag & (1 << 15))) {
|
if(ret <= 0 || (flag & (1 << 15))) {
|
||||||
if(list != NULL)
|
if(list != NULL)
|
||||||
free(list);
|
free(list);
|
||||||
|
@ -65,10 +65,10 @@ static int aaip_encode_pair(char *name, size_t attr_length, char *attr,
|
|||||||
@return >0 is the number of SUSP fields generated,
|
@return >0 is the number of SUSP fields generated,
|
||||||
0 means error
|
0 means error
|
||||||
*/
|
*/
|
||||||
unsigned int aaip_encode(char aa_name[2],
|
size_t aaip_encode(char aa_name[2],
|
||||||
unsigned int num_attrs, char **names,
|
size_t num_attrs, char **names,
|
||||||
size_t *value_lengths, char **values,
|
size_t *value_lengths, char **values,
|
||||||
size_t *result_len, unsigned char **result, int flag)
|
size_t *result_len, unsigned char **result, int flag)
|
||||||
{
|
{
|
||||||
size_t mem_size= 0, comp_size;
|
size_t mem_size= 0, comp_size;
|
||||||
unsigned int number_of_fields, i, num_recs, total_recs= 0, ret;
|
unsigned int number_of_fields, i, num_recs, total_recs= 0, ret;
|
||||||
@ -426,50 +426,174 @@ group_by_name:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Remove the entries user::??? , group::??? , other::??? , other:???
|
int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text,
|
||||||
from an ACL in long text form if they match the bits in st_mode.
|
size_t *result_len, unsigned char **result, int flag)
|
||||||
@param flag bit0= do not remove entries, only determine return value
|
{
|
||||||
bit1= like bit0 but return immediately if non-st_mode
|
int ret;
|
||||||
ACL entry is found
|
size_t a_acl_len= 0, d_acl_len= 0, acl_len= 0;
|
||||||
|
unsigned char *a_acl= NULL, *d_acl= NULL, *acl= NULL;
|
||||||
|
|
||||||
|
if(a_acl_text != NULL) {
|
||||||
|
ret= aaip_encode_acl(a_acl_text, &a_acl_len, &a_acl, flag & 3);
|
||||||
|
if(ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
if(d_acl_text != NULL) {
|
||||||
|
ret= aaip_encode_acl(d_acl_text, &d_acl_len, &d_acl, (flag & 3) | 4);
|
||||||
|
if(ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
if(a_acl == NULL) {
|
||||||
|
acl= d_acl;
|
||||||
|
d_acl= NULL;
|
||||||
|
acl_len= d_acl_len;
|
||||||
|
} else if (d_acl == NULL) {
|
||||||
|
acl= a_acl;
|
||||||
|
a_acl= NULL;
|
||||||
|
acl_len= a_acl_len;
|
||||||
|
} else {
|
||||||
|
acl= calloc(a_acl_len + d_acl_len + 1, 1);
|
||||||
|
if(acl == NULL)
|
||||||
|
{ret = -1; goto ex;}
|
||||||
|
memcpy(acl, a_acl, a_acl_len);
|
||||||
|
memcpy(acl + a_acl_len, d_acl, d_acl_len);
|
||||||
|
acl_len= a_acl_len + d_acl_len;
|
||||||
|
}
|
||||||
|
*result= acl;
|
||||||
|
*result_len= acl_len;
|
||||||
|
ret= 1;
|
||||||
|
ex:;
|
||||||
|
if(a_acl != NULL)
|
||||||
|
free(a_acl);
|
||||||
|
if(d_acl != NULL)
|
||||||
|
free(d_acl);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Linux man 5 acl says:
|
||||||
|
The permissions defined by ACLs are a superset of the permissions speci-
|
||||||
|
fied by the file permission bits. The permissions defined for the file
|
||||||
|
owner correspond to the permissions of the ACL_USER_OBJ entry. The per-
|
||||||
|
missions defined for the file group correspond to the permissions of the
|
||||||
|
ACL_GROUP_OBJ entry, if the ACL has no ACL_MASK entry. If the ACL has an
|
||||||
|
ACL_MASK entry, then the permissions defined for the file group corre-
|
||||||
|
spond to the permissions of the ACL_MASK entry. The permissions defined
|
||||||
|
for the other class correspond to the permissions of the ACL_OTHER_OBJ
|
||||||
|
entry.
|
||||||
|
|
||||||
|
Modification of the file permission bits results in the modification of
|
||||||
|
the permissions in the associated ACL entries. Modification of the per-
|
||||||
|
missions in the ACL entries results in the modification of the file per-
|
||||||
|
mission bits.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
int aaip_cleanout_st_mode(char *acl_text, mode_t st_mode, int flag)
|
/* Analyze occurence of ACL tag types in long text form. If not disabled by
|
||||||
|
parameter flag remove the entries of type "user::" , "group::" , "other::" ,
|
||||||
|
or "other:" from an ACL in long text form if they match the bits in st_mode
|
||||||
|
as described by man 2 stat and man 5 acl.
|
||||||
|
@param acl_text The text to be analyzed and eventually shortened.
|
||||||
|
@param st_mode The component of struct stat which tells POSIX permission
|
||||||
|
bits and eventually shall take equivalent bits as read
|
||||||
|
from the ACL. The caller should submit a pointer
|
||||||
|
to the st_mode variable which holds permissions as
|
||||||
|
indicated by stat(2) resp. ECMA-119 and RRIP data.
|
||||||
|
@param flag bit0= do not remove entries, only determine return value
|
||||||
|
bit1= like bit0 but return immediately if a non-st_mode
|
||||||
|
ACL entry is found
|
||||||
|
bit2= update *st_mode by acl_text
|
||||||
|
("user::" -> S_IRWXU, "mask::"|"group::" -> S_IRWXG,
|
||||||
|
"other::" -> S_IRWXO)
|
||||||
|
bit3= update acl_text by *st_mode (same mapping as bit 2
|
||||||
|
but with reversed transfer direction)
|
||||||
|
@return <0 failure
|
||||||
|
>=0 tells in its bits which tag types were found.
|
||||||
|
The first three tell which types deviate from the
|
||||||
|
corresponding st_mode settings:
|
||||||
|
bit0= "other::" overrides S_IRWXO
|
||||||
|
bit1= "group::" overrides S_IRWXG (no "mask::" found)
|
||||||
|
bit2= "user::" overrides S_IRWXU
|
||||||
|
The second three tell which types comply with st_mode:
|
||||||
|
bit3= "other::" matches S_IRWXO
|
||||||
|
bit4= "group::" matches S_IRWXG (no "mask::" found)
|
||||||
|
bit5= "user::" matches S_IRWXU
|
||||||
|
Given the nature of ACLs nearly all combinations are
|
||||||
|
possible although some would come from invalid ACLs.
|
||||||
|
bit6= other ACL tag types are present. Particularly:
|
||||||
|
bit7= "user:...:" is present
|
||||||
|
bit8= "group:...:" is present
|
||||||
|
bit9= "mask::" is present
|
||||||
|
*/
|
||||||
|
int aaip_cleanout_st_mode(char *acl_text, mode_t *in_st_mode, int flag)
|
||||||
{
|
{
|
||||||
char *rpt, *wpt, *npt, *cpt;
|
char *rpt, *wpt, *npt, *cpt;
|
||||||
mode_t m;
|
mode_t m, list_mode, st_mode;
|
||||||
int overriders= 0;
|
int tag_types= 0, has_mask= 0, do_cleanout = 0;
|
||||||
|
|
||||||
|
list_mode= st_mode= *in_st_mode;
|
||||||
|
do_cleanout = !(flag & 15);
|
||||||
|
|
||||||
|
has_mask= strncmp(acl_text, "mask:", 5) == 0 ||
|
||||||
|
strstr(acl_text, "\nmask:") != NULL;
|
||||||
|
if(has_mask && (flag & 2))
|
||||||
|
return(64 | 512);
|
||||||
|
|
||||||
for(npt= wpt= rpt= acl_text; *npt != 0; rpt= npt + 1) {
|
for(npt= wpt= rpt= acl_text; *npt != 0; rpt= npt + 1) {
|
||||||
npt= strchr(rpt, '\n');
|
npt= strchr(rpt, '\n');
|
||||||
if(npt == NULL)
|
if(npt == NULL)
|
||||||
npt= rpt + strlen(rpt);
|
npt= rpt + strlen(rpt);
|
||||||
if(strncmp(rpt, "user::", 6) == 0 && npt - rpt == 9) {
|
if(strncmp(rpt, "user:", 5) == 0) {
|
||||||
cpt= rpt + 6;
|
if(rpt[5] == ':' && npt - rpt == 9) {
|
||||||
m= 0;
|
cpt= rpt + 6;
|
||||||
if(cpt[0] == 'r')
|
m= 0;
|
||||||
m|= S_IRUSR;
|
if(cpt[0] == 'r')
|
||||||
if(cpt[1] == 'w')
|
m|= S_IRUSR;
|
||||||
m|= S_IWUSR;
|
if(cpt[1] == 'w')
|
||||||
if(cpt[2] == 'x')
|
m|= S_IWUSR;
|
||||||
m|= S_IXUSR;
|
if(cpt[2] == 'x')
|
||||||
if((st_mode & S_IRWXU) == (m & S_IRWXU)) {
|
m|= S_IXUSR;
|
||||||
overriders|= 32;
|
list_mode= (list_mode & ~S_IRWXU) | m;
|
||||||
|
if((st_mode & S_IRWXU) == (m & S_IRWXU)) {
|
||||||
|
tag_types|= 32;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
if(flag & 8) {
|
||||||
|
cpt[0]= st_mode & S_IRUSR ? 'r' : '-';
|
||||||
|
cpt[1]= st_mode & S_IWUSR ? 'w' : '-';
|
||||||
|
cpt[2]= st_mode & S_IXUSR ? 'x' : '-';
|
||||||
|
}
|
||||||
|
tag_types|= 4;
|
||||||
|
} else {
|
||||||
|
tag_types|= 64 | 128;
|
||||||
}
|
}
|
||||||
overriders|= 4;
|
} else if(strncmp(rpt, "group:", 6) == 0) {
|
||||||
} else if(strncmp(rpt, "group::", 7) == 0 && npt - rpt == 10) {
|
if(rpt[6] == ':' && npt - rpt == 10 && !has_mask) {
|
||||||
cpt= rpt + 7;
|
/* oddly: mask overrides group in st_mode */
|
||||||
m= 0;
|
cpt= rpt + 7;
|
||||||
if(cpt[0] == 'r')
|
m= 0;
|
||||||
m|= S_IRGRP;
|
if(cpt[0] == 'r')
|
||||||
if(cpt[1] == 'w')
|
m|= S_IRGRP;
|
||||||
m|= S_IWGRP;
|
if(cpt[1] == 'w')
|
||||||
if(cpt[2] == 'x')
|
m|= S_IWGRP;
|
||||||
m|= S_IXGRP;
|
if(cpt[2] == 'x')
|
||||||
if((st_mode & S_IRWXG) == (m & S_IRWXG)) {
|
m|= S_IXGRP;
|
||||||
overriders|= 16;
|
list_mode= (list_mode & ~S_IRWXG) | m;
|
||||||
|
if((st_mode & S_IRWXG) == (m & S_IRWXG)) {
|
||||||
|
tag_types|= 16;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
if(flag & 8) {
|
||||||
|
cpt[0]= st_mode & S_IRGRP ? 'r' : '-';
|
||||||
|
cpt[1]= st_mode & S_IWGRP ? 'w' : '-';
|
||||||
|
cpt[2]= st_mode & S_IXGRP ? 'x' : '-';
|
||||||
|
}
|
||||||
|
tag_types|= 2;
|
||||||
|
} else {
|
||||||
|
if(rpt[6] == ':' && npt - rpt == 10)
|
||||||
|
tag_types|= 1024;
|
||||||
|
else
|
||||||
|
tag_types|= 64 | 256;
|
||||||
}
|
}
|
||||||
overriders|= 2;
|
|
||||||
} else if(strncmp(rpt, "other::", 7) == 0 && npt - rpt == 10) {
|
} else if(strncmp(rpt, "other::", 7) == 0 && npt - rpt == 10) {
|
||||||
cpt= rpt + 7;
|
cpt= rpt + 7;
|
||||||
others_st_mode:;
|
others_st_mode:;
|
||||||
@ -480,66 +604,103 @@ others_st_mode:;
|
|||||||
m|= S_IWOTH;
|
m|= S_IWOTH;
|
||||||
if(cpt[2] == 'x')
|
if(cpt[2] == 'x')
|
||||||
m|= S_IXOTH;
|
m|= S_IXOTH;
|
||||||
|
list_mode= (list_mode & ~S_IRWXO) | m;
|
||||||
if((st_mode & S_IRWXO) == (m & S_IRWXO)) {
|
if((st_mode & S_IRWXO) == (m & S_IRWXO)) {
|
||||||
overriders|= 8;
|
tag_types|= 8;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
overriders|= 1;
|
if(flag & 8) {
|
||||||
|
cpt[0]= st_mode & S_IROTH ? 'r' : '-';
|
||||||
|
cpt[1]= st_mode & S_IWOTH ? 'w' : '-';
|
||||||
|
cpt[2]= st_mode & S_IXOTH ? 'x' : '-';
|
||||||
|
}
|
||||||
|
tag_types|= 1;
|
||||||
} else if(strncmp(rpt, "other:", 6) == 0 && npt - rpt == 9) {
|
} else if(strncmp(rpt, "other:", 6) == 0 && npt - rpt == 9) {
|
||||||
cpt= rpt + 7;
|
cpt= rpt + 7;
|
||||||
goto others_st_mode;
|
goto others_st_mode;
|
||||||
|
} else if(strncmp(rpt, "mask::", 6) == 0 && npt - rpt == 9) {
|
||||||
|
/* oddly: mask overrides group in st_mode */
|
||||||
|
cpt= rpt + 6;
|
||||||
|
mask_st_mode:;
|
||||||
|
m= 0;
|
||||||
|
if(cpt[0] == 'r')
|
||||||
|
m|= S_IRGRP;
|
||||||
|
if(cpt[1] == 'w')
|
||||||
|
m|= S_IWGRP;
|
||||||
|
if(cpt[2] == 'x')
|
||||||
|
m|= S_IXGRP;
|
||||||
|
list_mode= (list_mode & ~S_IRWXG) | m;
|
||||||
|
tag_types|= 64 | 512;
|
||||||
|
if(flag & 8) {
|
||||||
|
cpt[0]= st_mode & S_IRGRP ? 'r' : '-';
|
||||||
|
cpt[1]= st_mode & S_IWGRP ? 'w' : '-';
|
||||||
|
cpt[2]= st_mode & S_IXGRP ? 'x' : '-';
|
||||||
|
}
|
||||||
|
} else if(strncmp(rpt, "mask:", 5) == 0 && npt - rpt == 8) {
|
||||||
|
cpt= rpt + 5;
|
||||||
|
goto mask_st_mode;
|
||||||
} else if(*rpt != 0) {
|
} else if(*rpt != 0) {
|
||||||
overriders|= 64;
|
tag_types|= 64;
|
||||||
}
|
}
|
||||||
if (flag & 2)
|
if (flag & 2)
|
||||||
return overriders;
|
goto ex;
|
||||||
if(wpt == rpt) {
|
if(wpt == rpt) {
|
||||||
wpt= npt + 1;
|
wpt= npt + 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(!(flag & 3))
|
if(do_cleanout)
|
||||||
memmove(wpt, rpt, 1 + npt - rpt);
|
memmove(wpt, rpt, 1 + npt - rpt);
|
||||||
wpt+= 1 + npt - rpt;
|
wpt+= 1 + npt - rpt;
|
||||||
}
|
}
|
||||||
if(!(flag & 3)) {
|
if(do_cleanout) {
|
||||||
if(wpt == acl_text)
|
if(wpt == acl_text)
|
||||||
*wpt= 0;
|
*wpt= 0;
|
||||||
else if(*(wpt - 1) != 0)
|
else if(*(wpt - 1) != 0)
|
||||||
*wpt= 0;
|
*wpt= 0;
|
||||||
}
|
}
|
||||||
return(overriders);
|
ex:;
|
||||||
|
if(flag & 4)
|
||||||
|
*in_st_mode= list_mode;
|
||||||
|
return(tag_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Important: acl_text must provide 32 bytes more than its current length !
|
/* Important: acl_text must provide 42 bytes more than its current length !
|
||||||
*/
|
*/
|
||||||
int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag)
|
int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag)
|
||||||
{
|
{
|
||||||
char *wpt;
|
char *wpt;
|
||||||
int overriders= 0;
|
int tag_types= 0;
|
||||||
|
|
||||||
overriders = aaip_cleanout_st_mode(acl_text, st_mode, 1);
|
tag_types = aaip_cleanout_st_mode(acl_text, &st_mode, 1);
|
||||||
if(!(overriders & (4 | 32))) {
|
if(!(tag_types & (4 | 32))) {
|
||||||
wpt= acl_text + strlen(acl_text);
|
wpt= acl_text + strlen(acl_text);
|
||||||
sprintf(wpt, "user::%c%c%c\n",
|
sprintf(wpt, "user::%c%c%c\n",
|
||||||
st_mode & S_IRUSR ? 'r' : '-',
|
st_mode & S_IRUSR ? 'r' : '-',
|
||||||
st_mode & S_IWUSR ? 'w' : '-',
|
st_mode & S_IWUSR ? 'w' : '-',
|
||||||
st_mode & S_IXUSR ? 'x' : '-');
|
st_mode & S_IXUSR ? 'x' : '-');
|
||||||
}
|
}
|
||||||
if(!(overriders & (2 | 16))) {
|
if(!(tag_types & (2 | 16 | 1024))) {
|
||||||
wpt= acl_text + strlen(acl_text);
|
wpt= acl_text + strlen(acl_text);
|
||||||
sprintf(wpt, "group::%c%c%c\n",
|
sprintf(wpt, "group::%c%c%c\n",
|
||||||
st_mode & S_IRGRP ? 'r' : '-',
|
st_mode & S_IRGRP ? 'r' : '-',
|
||||||
st_mode & S_IWGRP ? 'w' : '-',
|
st_mode & S_IWGRP ? 'w' : '-',
|
||||||
st_mode & S_IXGRP ? 'x' : '-');
|
st_mode & S_IXGRP ? 'x' : '-');
|
||||||
}
|
}
|
||||||
if(!(overriders & (1 | 8))) {
|
if(!(tag_types & (1 | 8))) {
|
||||||
wpt= acl_text + strlen(acl_text);
|
wpt= acl_text + strlen(acl_text);
|
||||||
sprintf(wpt, "other::%c%c%c\n",
|
sprintf(wpt, "other::%c%c%c\n",
|
||||||
st_mode & S_IROTH ? 'r' : '-',
|
st_mode & S_IROTH ? 'r' : '-',
|
||||||
st_mode & S_IWOTH ? 'w' : '-',
|
st_mode & S_IWOTH ? 'w' : '-',
|
||||||
st_mode & S_IXOTH ? 'x' : '-');
|
st_mode & S_IXOTH ? 'x' : '-');
|
||||||
}
|
}
|
||||||
|
if((tag_types & (128 | 256)) && !(tag_types & 512)) {
|
||||||
|
wpt= acl_text + strlen(acl_text);
|
||||||
|
sprintf(wpt, "mask::%c%c%c\n",
|
||||||
|
st_mode & S_IRGRP ? 'r' : '-',
|
||||||
|
st_mode & S_IWGRP ? 'w' : '-',
|
||||||
|
st_mode & S_IXGRP ? 'x' : '-');
|
||||||
|
}
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,10 +32,9 @@
|
|||||||
@return >0 is the number of SUSP fields generated,
|
@return >0 is the number of SUSP fields generated,
|
||||||
0 means error
|
0 means error
|
||||||
*/
|
*/
|
||||||
unsigned int aaip_encode(char aa_name[2],
|
size_t aaip_encode(char aa_name[2], size_t num_attrs, char **names,
|
||||||
unsigned int num_attrs, char **names,
|
size_t *value_lengths, char **values,
|
||||||
size_t *value_lengths, char **values,
|
size_t *result_len, unsigned char **result, int flag);
|
||||||
size_t *result_len, unsigned char **result, int flag);
|
|
||||||
|
|
||||||
|
|
||||||
/* ------ ACL representation ------ */
|
/* ------ ACL representation ------ */
|
||||||
@ -58,38 +57,73 @@ int aaip_encode_acl(char *acl_text,
|
|||||||
size_t *result_len, unsigned char **result, int flag);
|
size_t *result_len, unsigned char **result, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* Remove the entries of type "user::" , "group::" , "other::" , "other:"
|
/* Convert an "access" and "default" ACL from long text form into the value
|
||||||
from an ACL in long text form if they match the bits in st_mode.
|
of an Arbitrary Attribute. According to AAIP 0.2 this value is to be stored
|
||||||
@param acl_text The text to be shortened
|
together with an empty name.
|
||||||
@param st_mode The component of struct stat which shall take the
|
@param a_acl_text The "access" ACL in long text form.
|
||||||
removed information. The caller should submit the st_mode
|
Submit NULL if there is no such ACL to be encoded.
|
||||||
variable which holds permissions as indicated by ECMA-119
|
@param d_acl_text The "default" ACL in long text form.
|
||||||
and RRIP data.
|
Submit NULL if there is no such ACL to be encoded.
|
||||||
|
@param result_len Number of bytes in the resulting value
|
||||||
|
@param result *result will point to the start of the result string.
|
||||||
|
This is malloc() memory which needs to be freed when
|
||||||
|
no longer needed
|
||||||
|
@param flag Bitfield for control purposes
|
||||||
|
bit0= count only
|
||||||
|
bit1= use numeric qualifiers rather than names
|
||||||
|
@return >0 means ok
|
||||||
|
0 means error
|
||||||
|
*/
|
||||||
|
int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text,
|
||||||
|
size_t *result_len, unsigned char **result, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* Analyze occurence of ACL tag types in long text form. If not disabled by
|
||||||
|
parameter flag remove the entries of type "user::" , "group::" , "other::" ,
|
||||||
|
or "other:" from an ACL in long text form if they match the bits in st_mode
|
||||||
|
as described by man 2 stat and man 5 acl.
|
||||||
|
@param acl_text The text to be analyzed and eventually shortened.
|
||||||
|
@param st_mode The component of struct stat which tells POSIX permission
|
||||||
|
bits and eventually shall take equivalent bits as read
|
||||||
|
from the ACL. The caller should submit a pointer
|
||||||
|
to the st_mode variable which holds permissions as
|
||||||
|
indicated by stat(2) resp. ECMA-119 and RRIP data.
|
||||||
@param flag bit0= do not remove entries, only determine return value
|
@param flag bit0= do not remove entries, only determine return value
|
||||||
bit1= like bit0 but return immediately if a non-st_mode
|
bit1= like bit0 but return immediately if a non-st_mode
|
||||||
ACL entry is found
|
ACL entry is found
|
||||||
|
bit2= update *st_mode by acl_text
|
||||||
|
("user::" -> S_IRWXU, "mask::"|"group::" -> S_IRWXG,
|
||||||
|
"other::" -> S_IRWXO)
|
||||||
|
bit3= update acl_text by *st_mode (same mapping as bit 2
|
||||||
|
but with reversed transfer direction)
|
||||||
@return <0 failure
|
@return <0 failure
|
||||||
>=0 tells in its bits which tag types are present.
|
>=0 tells in its bits which tag types were found.
|
||||||
The first three tell which types deviate from the
|
The first three tell which types deviate from the
|
||||||
corresponding st_mode settings:
|
corresponding st_mode settings:
|
||||||
bit0= "other::" overrides S_IRWXO
|
bit0= "other::" overrides S_IRWXO
|
||||||
bit1= "group::" overrides S_IRWXG
|
bit1= "group::" overrides S_IRWXG (no "mask::" found)
|
||||||
bit2= "user::" overrides S_IRWXU
|
bit2= "user::" overrides S_IRWXU
|
||||||
The second three tell which types comply with st_mode:
|
The second three tell which types comply with st_mode:
|
||||||
bit3= "other::" matches S_IRWXO
|
bit3= "other::" matches S_IRWXO
|
||||||
bit4= "group::" matches S_IRWXG
|
bit4= "group::" matches S_IRWXG (no "mask::" found)
|
||||||
bit5= "user::" matches S_IRWXU
|
bit5= "user::" matches S_IRWXU
|
||||||
Given the nature of ACLs all 64 combinations are
|
Given the nature of ACLs nearly all combinations are
|
||||||
possible although some show inner contradictions.
|
possible although some would come from invalid ACLs.
|
||||||
bit6= other ACL tag types are present
|
bit6= other ACL tag types are present. Particularly:
|
||||||
|
bit7= "user:...:" is present
|
||||||
|
bit8= "group:...:" is present
|
||||||
|
bit9= "mask::" is present
|
||||||
|
bit10= "group::" found and "mask::" exists
|
||||||
|
|
||||||
*/
|
*/
|
||||||
int aaip_cleanout_st_mode(char *acl_text, mode_t st_mode, int flag);
|
int aaip_cleanout_st_mode(char *acl_text, mode_t *st_mode, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* Append entries of type "user::" , "group::" , "other::" representing the
|
/* Append entries of type "user::" , "group::" , "other::" representing the
|
||||||
permission bits in st_mode if those tag types are not present in the ACL
|
permission bits in st_mode if those tag types are not present in the ACL
|
||||||
text.
|
text. Append "mask::" if missing although "user:...:" or "group:...:"
|
||||||
@param acl_text The text to be made longer. It must offer 33 bytes more
|
is present. Eventually set it to S_IRWXG bits of st_mode.
|
||||||
|
@param acl_text The text to be made longer. It must offer 43 bytes more
|
||||||
storage space than its length when it is submitted.
|
storage space than its length when it is submitted.
|
||||||
@param st_mode The component of struct stat which shall provide the
|
@param st_mode The component of struct stat which shall provide the
|
||||||
permission information.
|
permission information.
|
||||||
|
@ -481,9 +481,8 @@ void lfs_free(IsoFileSource *src)
|
|||||||
static
|
static
|
||||||
int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
||||||
{
|
{
|
||||||
unsigned int uret;
|
|
||||||
int ret;
|
int ret;
|
||||||
size_t num_attrs = 0, *value_lengths = NULL, result_len;
|
size_t num_attrs = 0, *value_lengths = NULL, result_len, sret;
|
||||||
char *path = NULL, **names = NULL, **values = NULL;
|
char *path = NULL, **names = NULL, **values = NULL;
|
||||||
unsigned char *result = NULL;
|
unsigned char *result = NULL;
|
||||||
|
|
||||||
@ -500,9 +499,9 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
|||||||
ret = ISO_FILE_ERROR;
|
ret = ISO_FILE_ERROR;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
uret = aaip_encode("AA", (unsigned int) num_attrs, names,
|
sret = aaip_encode("AA", num_attrs, names,
|
||||||
value_lengths, values, &result_len, &result, 0);
|
value_lengths, values, &result_len, &result, 0);
|
||||||
if (uret == 0) {
|
if (sret == 0) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
@ -4126,6 +4126,7 @@ int aaip_xinfo_func(void *data, int flag);
|
|||||||
|
|
||||||
#endif /* Libisofs_with_aaiP */
|
#endif /* Libisofs_with_aaiP */
|
||||||
|
|
||||||
|
/* ts A90116 */
|
||||||
/**
|
/**
|
||||||
* Get an eventual ACL which is associated with the node.
|
* Get an eventual ACL which is associated with the node.
|
||||||
* The result will be in "long" text form as of man acl resp. acl_to_text().
|
* The result will be in "long" text form as of man acl resp. acl_to_text().
|
||||||
@ -4142,7 +4143,7 @@ int aaip_xinfo_func(void *data, int flag);
|
|||||||
* (Linux directories can have a "default" ACL which influences
|
* (Linux directories can have a "default" ACL which influences
|
||||||
* the permissions of newly created files.)
|
* the permissions of newly created files.)
|
||||||
* bit4= if no ACL is available: return *text == NULL
|
* bit4= if no ACL is available: return *text == NULL
|
||||||
else: produce ACL from POSIX permissions
|
* else: produce ACL from POSIX permissions
|
||||||
* bit15= free memory and return 1
|
* bit15= free memory and return 1
|
||||||
* @return
|
* @return
|
||||||
* 2 ACL produced from POSIX permissions
|
* 2 ACL produced from POSIX permissions
|
||||||
@ -4155,15 +4156,47 @@ int aaip_xinfo_func(void *data, int flag);
|
|||||||
int iso_node_get_acl_text(IsoNode *node, char **text, int flag);
|
int iso_node_get_acl_text(IsoNode *node, char **text, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A90119 */
|
||||||
|
/**
|
||||||
|
* Set the ACL of the given node to the list in parameter text or delete it.
|
||||||
|
*
|
||||||
|
* @param node
|
||||||
|
* The node that is to be manipulated.
|
||||||
|
* @param text
|
||||||
|
* The ACL text to be set into effect. NULL will delete an eventually
|
||||||
|
* existing ACL of the node.
|
||||||
|
* @param flag
|
||||||
|
* Bitfield for control purposes
|
||||||
|
* bit0= set "default" ACL rather than "access" ACL
|
||||||
|
* (Linux directories can have a "default" ACL which influences
|
||||||
|
* the permissions of newly created files.)
|
||||||
|
* bit1= ignore text but rather update eventual "access" ACL to the POSIX
|
||||||
|
* permissions of node. If no ACL exists, then do nothing and
|
||||||
|
* return success.
|
||||||
|
* @return
|
||||||
|
* > 0 success
|
||||||
|
* <=0 failure
|
||||||
|
*/
|
||||||
|
int iso_node_set_acl_text(IsoNode *node, char *text, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A90118 */
|
||||||
/* Set the ACL of the given file in the local filesystem to a given list
|
/* Set the ACL of the given file in the local filesystem to a given list
|
||||||
in long text form.
|
* in long text form.
|
||||||
@param disk_path Path to the file
|
*
|
||||||
@param text The input text (0 terminated, ACL long text form)
|
* @param disk_path
|
||||||
@param flag Bitfield for control purposes
|
* Path to the file
|
||||||
bit0= set default ACL rather than access ACL
|
* @param text
|
||||||
@return >0 ok
|
* The input text (0 terminated, ACL long text form)
|
||||||
0 no ACL manipulation adapter available
|
* @param flag
|
||||||
-1 failure of system ACL service (see errno)
|
* Bitfield for control purposes
|
||||||
|
* bit0= set default ACL rather than access ACL
|
||||||
|
* @return
|
||||||
|
* > 0 ok
|
||||||
|
* 0 no ACL manipulation adapter available
|
||||||
|
* -1 failure of system ACL service (see errno)
|
||||||
|
*
|
||||||
|
* @since 0.6.14
|
||||||
*/
|
*/
|
||||||
int iso_local_set_acl_text(char *disk_path, char *text, int flag);
|
int iso_local_set_acl_text(char *disk_path, char *text, int flag);
|
||||||
|
|
||||||
|
289
libisofs/node.c
289
libisofs/node.c
@ -290,26 +290,12 @@ void iso_node_set_permissions(IsoNode *node, mode_t mode)
|
|||||||
node->mode = (node->mode & S_IFMT) | (mode & ~S_IFMT);
|
node->mode = (node->mode & S_IFMT) | (mode & ~S_IFMT);
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaiP
|
#ifdef Libisofs_with_aaiP
|
||||||
|
/* ts A90119 */
|
||||||
|
|
||||||
/* Linux man 5 acl says:
|
/* If the node has ACL info : update ACL */;
|
||||||
The permissions defined by ACLs are a superset of the permissions speci-
|
iso_node_set_acl_text(node, "", 2);
|
||||||
fied by the file permission bits. The permissions defined for the file
|
|
||||||
owner correspond to the permissions of the ACL_USER_OBJ entry. The per-
|
|
||||||
missions defined for the file group correspond to the permissions of the
|
|
||||||
ACL_GROUP_OBJ entry, if the ACL has no ACL_MASK entry. If the ACL has an
|
|
||||||
ACL_MASK entry, then the permissions defined for the file group corre-
|
|
||||||
spond to the permissions of the ACL_MASK entry. The permissions defined
|
|
||||||
for the other class correspond to the permissions of the ACL_OTHER_OBJ
|
|
||||||
entry.
|
|
||||||
|
|
||||||
Modification of the file permission bits results in the modification of
|
/* >>> actually iso_node_set_permissions() would need a return value now */
|
||||||
the permissions in the associated ACL entries. Modification of the per-
|
|
||||||
missions in the ACL entries results in the modification of the file per-
|
|
||||||
mission bits.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/* >>> if the node has ACL info : */
|
|
||||||
/* >>> update ACL */;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1439,6 +1425,60 @@ int iso_node_get_attrs(IsoNode *node, size_t *num_attrs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A90121 */
|
||||||
|
int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
|
||||||
|
size_t *value_lengths, char **values, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t sret, result_len;
|
||||||
|
unsigned char *result;
|
||||||
|
|
||||||
|
sret = aaip_encode("AA", num_attrs, names, value_lengths, values,
|
||||||
|
&result_len, &result, 0);
|
||||||
|
if (sret == 0)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
|
||||||
|
ret = iso_node_remove_xinfo(node, aaip_xinfo_func);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_node_add_xinfo(node, aaip_xinfo_func, result);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (ret == 0) {
|
||||||
|
|
||||||
|
/* >>> something is messed up with xinfo */;
|
||||||
|
|
||||||
|
return ISO_ERROR;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_decode_acl(unsigned char *v_data, size_t v_len, size_t *consumed,
|
||||||
|
char **text, size_t *text_fill, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = aaip_decode_acl(v_data, v_len,
|
||||||
|
consumed, NULL, (size_t) 0, text_fill, 1);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
if (text_fill == 0)
|
||||||
|
return 0;
|
||||||
|
*text = calloc(*text_fill + 42, 1); /* 42 for aaip_update_acl_st_mode */
|
||||||
|
if (*text == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
ret = aaip_decode_acl(v_data, v_len,
|
||||||
|
consumed, *text, *text_fill, text_fill, 0);
|
||||||
|
if (ret <= 0) {
|
||||||
|
free(*text);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A90116 */
|
/* ts A90116 */
|
||||||
int iso_node_get_acl_text(IsoNode *node, char **text, int flag)
|
int iso_node_get_acl_text(IsoNode *node, char **text, int flag)
|
||||||
{
|
{
|
||||||
@ -1486,29 +1526,17 @@ int iso_node_get_acl_text(IsoNode *node, char **text, int flag)
|
|||||||
v_len -= consumed;
|
v_len -= consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = aaip_decode_acl(v_data, v_len,
|
ret = iso_decode_acl(v_data, v_len, &consumed, text, &text_fill, 0);
|
||||||
&consumed, NULL, (size_t) 0, &text_fill, 1);
|
if (ret == 0)
|
||||||
if (ret <= 0)
|
|
||||||
goto bad_decode;
|
goto bad_decode;
|
||||||
if (text_fill == 0) {
|
if (ret < 0)
|
||||||
ret = 0;
|
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
|
||||||
*text = calloc(text_fill + 32, 1); /* 32 for aaip_update_acl_st_mode */
|
|
||||||
if (*text == NULL) {
|
|
||||||
ret = ISO_OUT_OF_MEM;
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
ret = aaip_decode_acl(v_data, v_len,
|
|
||||||
&consumed, *text, text_fill, &text_fill, 0);
|
|
||||||
if (ret <= 0)
|
|
||||||
goto bad_decode;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*text == NULL && !(flag & 16)) {
|
if (*text == NULL && !(flag & 16)) {
|
||||||
from_posix = 1;
|
from_posix = 1;
|
||||||
*text = calloc(32, 1); /* 32 for aaip_update_acl_st_mode */
|
*text = calloc(42, 1); /* 42 for aaip_update_acl_st_mode */
|
||||||
}
|
}
|
||||||
if (*text != NULL) {
|
if (*text != NULL) {
|
||||||
st_mode = iso_node_get_permissions(node);
|
st_mode = iso_node_get_permissions(node);
|
||||||
@ -1543,6 +1571,199 @@ bad_decode:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A90119 */
|
||||||
|
int iso_node_set_acl_text(IsoNode *node, char *acl_text, int flag)
|
||||||
|
{
|
||||||
|
size_t num_attrs = 0, *value_lengths = NULL, i, consumed;
|
||||||
|
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;
|
||||||
|
char **tpt;
|
||||||
|
unsigned char *v_data, *acl= NULL;
|
||||||
|
int ret;
|
||||||
|
mode_t st_mode;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_aaiP
|
||||||
|
|
||||||
|
if (flag & 2) { /* want to update ACL by st_mode */
|
||||||
|
st_mode = iso_node_get_permissions(node);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* >>> validate and rectify text */;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = iso_node_get_attrs(node, &num_attrs, &names,
|
||||||
|
&value_lengths, &values, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for(i = 0; i < num_attrs; i++) {
|
||||||
|
if (names[i][0]) /* searching the empty name */
|
||||||
|
continue;
|
||||||
|
v_data = (unsigned char *) values[i];
|
||||||
|
v_len = value_lengths[i];
|
||||||
|
/* "access" ACL */;
|
||||||
|
ret = iso_decode_acl(v_data, v_len, &consumed, &a_text, &a_text_fill,
|
||||||
|
0);
|
||||||
|
if (ret == 0)
|
||||||
|
goto bad_decode;
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
if (ret == 2) {
|
||||||
|
/* "default" ACL */;
|
||||||
|
v_data += consumed;
|
||||||
|
v_len -= consumed;
|
||||||
|
ret = iso_decode_acl(v_data, v_len, &consumed, &d_text,
|
||||||
|
&d_text_fill, 0);
|
||||||
|
if (ret == 0)
|
||||||
|
goto bad_decode;
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag & 2) {
|
||||||
|
/* Update "access" ACL by st_mode */
|
||||||
|
if (a_text == NULL) {
|
||||||
|
ret = 1;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
ret = aaip_cleanout_st_mode(a_text, &st_mode, 8);
|
||||||
|
if (ret < 0)
|
||||||
|
goto bad_decode;
|
||||||
|
} else {
|
||||||
|
if (flag & 1)
|
||||||
|
tpt = &d_text;
|
||||||
|
else
|
||||||
|
tpt = &a_text;
|
||||||
|
if (*tpt != NULL) {
|
||||||
|
free(*tpt);
|
||||||
|
*tpt = NULL;
|
||||||
|
}
|
||||||
|
if (acl_text != 0) {
|
||||||
|
*tpt = calloc(strlen(acl_text) + 1, 1);
|
||||||
|
if (*tpt == NULL) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
memcpy(*tpt, acl_text, strlen(acl_text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (a_text != NULL || d_text != NULL)
|
||||||
|
ret = aaip_encode_both_acl(a_text, d_text, &acl_len, &acl, 0);
|
||||||
|
else
|
||||||
|
ret = 1;
|
||||||
|
if (ret <= 0) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* replace variable value */;
|
||||||
|
if (values[i] != NULL)
|
||||||
|
free(values[i]);
|
||||||
|
values[i] = (char *) acl;
|
||||||
|
acl = NULL;
|
||||||
|
value_lengths[i] = acl_len;
|
||||||
|
|
||||||
|
/* Encode attributes and attach to node */
|
||||||
|
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
|
||||||
|
0);
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* There is no ACL yet */
|
||||||
|
if ((flag & 2) || acl_text == NULL) {
|
||||||
|
/* thus no need to update ACL by st_mode or to delete ACL */
|
||||||
|
ret = 1;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
if (flag & 1)
|
||||||
|
ret = aaip_encode_both_acl(NULL, acl_text, &acl_len, &acl, 0);
|
||||||
|
else
|
||||||
|
ret = aaip_encode_both_acl(acl_text, NULL, &acl_len, &acl, 0);
|
||||||
|
if (ret <= 0) {
|
||||||
|
|
||||||
|
/* >>> cannot encode */;
|
||||||
|
|
||||||
|
ret = ISO_ERROR;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enlarge attribute list */
|
||||||
|
new_names = realloc(names, (num_attrs + 1) * sizeof(char *));
|
||||||
|
if (new_names == NULL) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
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("");
|
||||||
|
if (names[num_attrs] == NULL) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
values[num_attrs] = (char *) acl;
|
||||||
|
acl = NULL;
|
||||||
|
value_lengths[num_attrs] = acl_len;
|
||||||
|
num_attrs++;
|
||||||
|
|
||||||
|
/* Encode attributes and attach to node */
|
||||||
|
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
iso_node_get_attrs(node, &num_attrs, &names,
|
||||||
|
&value_lengths, &values, 1 << 15); /* free memory */
|
||||||
|
if (a_text != NULL)
|
||||||
|
free(a_text);
|
||||||
|
if (d_text != NULL)
|
||||||
|
free(d_text);
|
||||||
|
if(acl != NULL)
|
||||||
|
free(acl);
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
bad_decode:;
|
||||||
|
|
||||||
|
/* >>> something is wrong with the attribute value */;
|
||||||
|
|
||||||
|
/* >>> invent better error code */
|
||||||
|
ret = ISO_ERROR;
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
#else /* Libisofs_with_aaiP */
|
||||||
|
|
||||||
|
if (text != NULL) {
|
||||||
|
|
||||||
|
/* >>> No ACL enabled in program code */;
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
#endif /* ! Libisofs_with_aaiP */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A90118 */
|
||||||
int iso_local_set_acl_text(char *disk_path, char *text, int flag)
|
int iso_local_set_acl_text(char *disk_path, char *text, int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user