Took into respect that ACL operations always happen on link targets

while xattr can happen on the link itself.
This commit is contained in:
Thomas Schmitt 2009-02-04 19:53:00 +01:00
parent 1add3e32c5
commit e8267b71d1
4 changed files with 142 additions and 67 deletions

View File

@ -37,10 +37,13 @@
bit0= obtain default ACL rather than access ACL bit0= obtain default ACL rather than access ACL
bit4= set *text = NULL and return 2 bit4= set *text = NULL and return 2
if the ACL matches st_mode permissions. if the ACL matches st_mode permissions.
bit5= in case of symbolic link: inquire link target
bit15= free text and return 1 bit15= free text and return 1
@return > 0 ok @return > 0 ok
0 ACL support not enabled at compile time
-1 failure of system ACL service (see errno) -1 failure of system ACL service (see errno)
-2 ACL support not enabled at compile time -2 attempt to inquire ACL of a symbolic
link without bit4 or bit5
*/ */
int aaip_get_acl_text(char *path, char **text, int flag) int aaip_get_acl_text(char *path, char **text, int flag)
{ {
@ -60,7 +63,19 @@ int aaip_get_acl_text(char *path, char **text, int flag)
*text= NULL; *text= NULL;
return(1); return(1);
} }
*text= NULL; *text= NULL;
if(flag & 32)
ret= stat(path, &stbuf);
else
ret= lstat(path, &stbuf);
if(ret == -1)
return(-1);
if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
if(flag & 16)
return(2);
return(-2);
}
/* Note: no ACL_TYPE_DEFAULT in FreeBSD */ /* Note: no ACL_TYPE_DEFAULT in FreeBSD */
if(flag & 1) if(flag & 1)
@ -79,19 +94,16 @@ int aaip_get_acl_text(char *path, char **text, int flag)
/* ??? >>> Fake ACL */; /* ??? >>> Fake ACL */;
return(-2); return(0);
#endif /* ! Libisofs_with_aaip_acL */ #endif /* ! Libisofs_with_aaip_acL */
if(*text == NULL) if(*text == NULL)
return(-1); return(-1);
if(flag & 16) { if(flag & 16) {
ret= stat(path, &stbuf);
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;
}
if((*text)[0] == 0 || strcmp(*text, "\n") == 0) { if((*text)[0] == 0 || strcmp(*text, "\n") == 0) {
#ifdef Libisofs_with_aaip_acL #ifdef Libisofs_with_aaip_acL
acl_free(text); acl_free(text);
@ -166,7 +178,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
if(flag & 1) { /* Obtain ACL */ if(flag & 1) { /* Obtain 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 | 32));
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
if(ret == 2) if(ret == 2)
@ -241,6 +253,16 @@ int aaip_set_acl_text(char *path, char *text, int flag)
int ret; int ret;
acl_t acl= NULL; acl_t acl= NULL;
struct stat stbuf;
if(flag & 32)
ret= stat(path, &stbuf);
else
ret= lstat(path, &stbuf);
if(ret == -1)
return(-1);
if((stbuf.st_mode & S_IFMT) == S_IFLNK)
return(-2);
acl= acl_from_text(text); acl= acl_from_text(text);
if(acl == NULL) { if(acl == NULL) {
@ -313,7 +335,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
has_default_acl= (ret == 2); has_default_acl= (ret == 2);
#ifdef Libisofs_with_aaip_acL #ifdef Libisofs_with_aaip_acL
ret= aaip_set_acl_text(path, acl_text, 0); ret= aaip_set_acl_text(path, acl_text, flag & 32);
if(ret <= 0) if(ret <= 0)
{ret= -3; goto ex;} {ret= -3; goto ex;}
#else #else
@ -336,7 +358,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
acl_text, acl_text_fill, &acl_text_fill, 0); acl_text, acl_text_fill, &acl_text_fill, 0);
if(ret <= 0) if(ret <= 0)
{ret= -2; goto ex;} {ret= -2; goto ex;}
ret= aaip_set_acl_text(path, acl_text, 1); ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32));
if(ret <= 0) if(ret <= 0)
{ret= -3; goto ex;} {ret= -3; goto ex;}
} }

View File

@ -24,9 +24,6 @@
#include <attr/xattr.h> #include <attr/xattr.h>
#endif #endif
#define Aaip_a_acl_attrnamE "system.posix_acl_access"
#define Aaip_d_acl_attrnamE "system.posix_acl_default"
/* ------------------------------ Getters --------------------------------- */ /* ------------------------------ Getters --------------------------------- */
@ -40,12 +37,15 @@
behave like bit4 if ACL is empty behave like bit4 if ACL is empty
bit4= set *text = NULL and return 2 bit4= set *text = NULL and return 2
if the ACL matches st_mode permissions. if the ACL matches st_mode permissions.
bit5= in case of symbolic link: inquire link target
bit15= free text and return 1 bit15= free text and return 1
@return 1 ok @return 1 ok
2 only st_mode permissions exist and bit 4 is set 2 only st_mode permissions exist and bit 4 is set
or empty ACL and bit0 is set or empty ACL and bit0 is set
0 ACL support not enabled at compile time 0 ACL support not enabled at compile time
-1 failure of system ACL service (see errno) -1 failure of system ACL service (see errno)
-2 attempt to inquire ACL of a symbolic link without
bit4 or bit5 resp. with no suitable link target
*/ */
int aaip_get_acl_text(char *path, char **text, int flag) int aaip_get_acl_text(char *path, char **text, int flag)
{ {
@ -63,6 +63,18 @@ int aaip_get_acl_text(char *path, char **text, int flag)
} }
*text= NULL; *text= NULL;
if(flag & 32)
ret= stat(path, &stbuf);
else
ret= lstat(path, &stbuf);
if(ret == -1)
return(-1);
if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
if(flag & 16)
return(2);
return(-2);
}
acl= acl_get_file(path, (flag & 1) ? ACL_TYPE_DEFAULT : ACL_TYPE_ACCESS); acl= acl_get_file(path, (flag & 1) ? ACL_TYPE_DEFAULT : ACL_TYPE_ACCESS);
if(acl == NULL) if(acl == NULL)
return(-1); return(-1);
@ -72,13 +84,10 @@ int aaip_get_acl_text(char *path, char **text, int flag)
if(*text == NULL) if(*text == NULL)
return(-1); return(-1);
if(flag & 16) { if(flag & 16) {
ret= stat(path, &stbuf);
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;
} }
}
if(flag & (1 | 16)) { if(flag & (1 | 16)) {
if((*text)[0] == 0 || strcmp(*text, "\n") == 0) { if((*text)[0] == 0 || strcmp(*text, "\n") == 0) {
acl_free(text); acl_free(text);
@ -107,9 +116,11 @@ int aaip_get_acl_text(char *path, char **text, int flag)
bit0= obtain ACL (access and eventually default) bit0= obtain ACL (access and eventually default)
bit1= use numeric ACL qualifiers rather than names bit1= use numeric ACL qualifiers rather than names
bit2= do not obtain attributes other than ACL bit2= do not obtain attributes other than ACL
bit3= do not ignore eventual local ACL attribute bit3= do not ignore eventual non-user attributes
(e.g. system.posix_acl_access) I.e. those with a name which does not begin
by "user."
bit4= do not return trivial ACL that matches st_mode bit4= do not return trivial ACL that matches st_mode
bit5= in case of symbolic link: inquire link target
bit15= free memory of names, value_lengths, values bit15= free memory of names, value_lengths, values
@return >0 ok @return >0 ok
<=0 error <=0 error
@ -138,13 +149,19 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
#ifdef Libisofs_with_aaip_xattR #ifdef Libisofs_with_aaip_xattR
if(flag & 32)
list_size= listxattr(path, list, 0); list_size= listxattr(path, list, 0);
else
list_size= llistxattr(path, list, 0);
if(list_size == -1) if(list_size == -1)
{ret= -1; goto ex;} {ret= -1; goto ex;}
list= calloc(list_size, 1); list= calloc(list_size, 1);
if(list == NULL) if(list == NULL)
{ret= -1; goto ex;} {ret= -1; goto ex;}
if(flag & 32)
list_size= listxattr(path, list, list_size); list_size= listxattr(path, list, list_size);
else
list_size= llistxattr(path, list, list_size);
if(list_size == -1) if(list_size == -1)
{ret= -1; goto ex;} {ret= -1; goto ex;}
@ -180,8 +197,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
for(i= 0; i < list_size && num_names > *num_attrs; for(i= 0; i < list_size && num_names > *num_attrs;
i+= strlen(list + i) + 1) { i+= strlen(list + i) + 1) {
if(!(flag & 8)) if(!(flag & 8))
if(strcmp(list + i, Aaip_a_acl_attrnamE) == 0 || if(strncmp(list + i, "user.", 5))
strcmp(list + i, Aaip_d_acl_attrnamE) == 0)
continue; continue;
(*names)[(*num_attrs)++]= strdup(list + i); (*names)[(*num_attrs)++]= strdup(list + i);
if((*names)[(*num_attrs) - 1] == NULL) if((*names)[(*num_attrs) - 1] == NULL)
@ -194,16 +210,21 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
if(!(flag & 4)) { /* Get xattr values */ if(!(flag & 4)) { /* Get xattr values */
for(i= 0; i < *num_attrs; i++) { for(i= 0; i < *num_attrs; i++) {
if(!(flag & 8)) if(!(flag & 8))
if(strcmp((*names)[i], Aaip_a_acl_attrnamE) == 0 || if(strncmp((*names)[i], "user.", 5))
strcmp((*names)[i], Aaip_d_acl_attrnamE) == 0)
continue; continue;
if(flag & 32)
value_ret= getxattr(path, (*names)[i], NULL, 0); value_ret= getxattr(path, (*names)[i], NULL, 0);
else
value_ret= lgetxattr(path, (*names)[i], NULL, 0);
if(value_ret == -1) if(value_ret == -1)
continue; continue;
(*values)[i]= calloc(value_ret + 1, 1); (*values)[i]= calloc(value_ret + 1, 1);
if((*values)[i] == NULL) if((*values)[i] == NULL)
{ret= -1; goto ex;} {ret= -1; goto ex;}
if(flag & 32)
value_ret= getxattr(path, (*names)[i], (*values)[i], value_ret); value_ret= getxattr(path, (*names)[i], (*values)[i], value_ret);
else
value_ret= lgetxattr(path, (*names)[i], (*values)[i], value_ret);
if(value_ret == -1) { /* there could be a race condition */ if(value_ret == -1) { /* there could be a race condition */
if(retry++ > 5) if(retry++ > 5)
{ret= -1; goto ex;} {ret= -1; goto ex;}
@ -221,8 +242,8 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
if(flag & 1) { /* Obtain ACL */ if(flag & 1) { /* Obtain ACL */
aaip_get_acl_text(path, &a_acl_text, flag & 16); aaip_get_acl_text(path, &a_acl_text, flag & (16 | 32));
aaip_get_acl_text(path, &d_acl_text, 1); aaip_get_acl_text(path, &d_acl_text, 1 | (flag & 32));
if(a_acl_text == NULL && d_acl_text == NULL) if(a_acl_text == NULL && d_acl_text == NULL)
{ret= 1; goto ex;} {ret= 1; goto ex;}
ret= aaip_encode_both_acl(a_acl_text, d_acl_text, (mode_t) 0, ret= aaip_encode_both_acl(a_acl_text, d_acl_text, (mode_t) 0,
@ -282,9 +303,12 @@ ex:;
@param text The input text (0 terminated, ACL long text form) @param text The input text (0 terminated, ACL long text form)
@param flag Bitfield for control purposes @param flag Bitfield for control purposes
bit0= set default ACL rather than access ACL bit0= set default ACL rather than access ACL
bit5= in case of symbolic link: manipulate link target
@return >0 ok @return >0 ok
0 ACL support not enabled at compile time 0 ACL support not enabled at compile time
-1 failure of system ACL service (see errno) -1 failure of system ACL service (see errno)
-2 attempt to manipulate ACL of a symbolic link
without bit5 resp. with no suitable link target
*/ */
int aaip_set_acl_text(char *path, char *text, int flag) int aaip_set_acl_text(char *path, char *text, int flag)
{ {
@ -293,6 +317,16 @@ int aaip_set_acl_text(char *path, char *text, int flag)
int ret; int ret;
acl_t acl= NULL; acl_t acl= NULL;
struct stat stbuf;
if(flag & 32)
ret= stat(path, &stbuf);
else
ret= lstat(path, &stbuf);
if(ret == -1)
return(-1);
if((stbuf.st_mode & S_IFMT) == S_IFLNK)
return(-2);
acl= acl_from_text(text); acl= acl_from_text(text);
if(acl == NULL) { if(acl == NULL) {
@ -321,8 +355,10 @@ ex:
bit0= decode and set ACLs bit0= decode and set ACLs
bit1= first clear all existing attributes of the file bit1= first clear all existing attributes of the file
bit2= do not set attributes other than ACLs bit2= do not set attributes other than ACLs
bit3= do not ignore eventual ACL attribute bit3= do not ignore eventual non-user attributes.
(e.g. system.posix_acl_access) I.e. those with a name which does not begin
by "user."
bit5= in case of symbolic link: manipulate link target
@return 1 success @return 1 success
-1 error memory allocation -1 error memory allocation
-2 error with decoding of ACL -2 error with decoding of ACL
@ -341,21 +377,30 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
#ifdef Libisofs_with_aaip_xattR #ifdef Libisofs_with_aaip_xattR
if(flag & 2) /* Delete all file attributes */ if(flag & 2) { /* Delete all file attributes */
if(flag & 32)
list_size= listxattr(path, list, 0); list_size= listxattr(path, list, 0);
else
list_size= llistxattr(path, list, 0);
}
if(list_size > 0) { /* Delete all file attributes */ if(list_size > 0) { /* Delete all file attributes */
list= calloc(list_size, 1); list= calloc(list_size, 1);
if(list == NULL) if(list == NULL)
{ret= -5; goto ex;} {ret= -5; goto ex;}
if(flag & 32)
list_size= listxattr(path, list, list_size); list_size= listxattr(path, list, list_size);
else
list_size= llistxattr(path, list, list_size);
if(list_size == -1) if(list_size == -1)
{ret= -5; goto ex;} {ret= -5; goto ex;}
for(i= 0; i < list_size; i+= strlen(list + i) + 1) { for(i= 0; i < list_size; i+= strlen(list + i) + 1) {
if(!(flag & 8)) if(!(flag & 8))
if(strcmp(list + i, Aaip_a_acl_attrnamE) == 0 || if(strncmp(list + i, "user.", 5))
strcmp(list + i, Aaip_d_acl_attrnamE) == 0)
continue; continue;
if(flag & 32)
ret= removexattr(path, list + i); ret= removexattr(path, list + i);
else
ret= lremovexattr(path, list + i);
if(ret == -1) if(ret == -1)
{ret= -5; goto ex;} {ret= -5; goto ex;}
} }
@ -374,13 +419,15 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
} }
/* Extended Attribute */ /* Extended Attribute */
if((flag & 1) && !(flag & 8)) if((flag & 1) && !(flag & 8))
if(strcmp(names[i], Aaip_a_acl_attrnamE) == 0 || if(strncmp(names[i], "user.", 5))
strcmp(names[i], Aaip_d_acl_attrnamE) == 0)
continue; continue;
#ifdef Libisofs_with_aaip_xattR #ifdef Libisofs_with_aaip_xattR
if(flag & 32)
ret= setxattr(path, names[i], values[i], value_lengths[i], 0); ret= setxattr(path, names[i], values[i], value_lengths[i], 0);
else
ret= lsetxattr(path, names[i], values[i], value_lengths[i], 0);
if(ret == -1) if(ret == -1)
{ret= -4; goto ex;} {ret= -4; goto ex;}
@ -411,7 +458,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
has_default_acl= (ret == 2); has_default_acl= (ret == 2);
#ifdef Libisofs_with_aaip_acL #ifdef Libisofs_with_aaip_acL
ret= aaip_set_acl_text(path, acl_text, 0); ret= aaip_set_acl_text(path, acl_text, flag & 32);
if(ret <= 0) if(ret <= 0)
{ret= -3; goto ex;} {ret= -3; goto ex;}
#else #else
@ -434,7 +481,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
acl_text, acl_text_fill, &acl_text_fill, 0); acl_text, acl_text_fill, &acl_text_fill, 0);
if(ret <= 0) if(ret <= 0)
{ret= -2; goto ex;} {ret= -2; goto ex;}
ret= aaip_set_acl_text(path, acl_text, 1); ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32));
if(ret <= 0) if(ret <= 0)
{ret= -3; goto ex;} {ret= -3; goto ex;}
} }

View File

@ -4439,12 +4439,15 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
* bit0= get default ACL rather than access ACL * bit0= get default ACL rather than access ACL
* bit4= set *text = NULL and return 2 * bit4= set *text = NULL and return 2
* if the ACL matches st_mode permissions. * if the ACL matches st_mode permissions.
* bit5= in case of symbolic link: inquire link target
* bit15= free text and return 1 * bit15= free text and return 1
* @return * @return
* 1 ok * 1 ok
* 2 ok, trivial ACL found while bit4 is set, *text is NULL * 2 ok, trivial ACL found while bit4 is set, *text is NULL
* 0 no ACL manipulation adapter available * 0 no ACL manipulation adapter available
* -1 failure of system ACL service (see errno) * -1 failure of system ACL service (see errno)
* -2 attempt to inquire ACL of a symbolic link without bit4 or bit5
* resp. with no suitable link target
* *
* @since 0.6.14 * @since 0.6.14
*/ */
@ -4463,10 +4466,13 @@ int iso_local_get_acl_text(char *disk_path, char **text, int flag);
* @param flag * @param flag
* Bitfield for control purposes * Bitfield for control purposes
* bit0= set default ACL rather than access ACL * bit0= set default ACL rather than access ACL
* bit5= in case of symbolic link: manipulate link target
* @return * @return
* > 0 ok * > 0 ok
* 0 no ACL manipulation adapter available * 0 no ACL manipulation adapter available
* -1 failure of system ACL service (see errno) * -1 failure of system ACL service (see errno)
* -2 attempt to manipulate ACL of a symbolic link without bit5
* resp. with no suitable link target
* *
* @since 0.6.14 * @since 0.6.14
*/ */
@ -4497,8 +4503,9 @@ int iso_local_set_acl_text(char *disk_path, char *text, int flag);
* Bitfield for control purposes * Bitfield for control purposes
* bit0= obtain eventual ACLs as attribute with empty name * bit0= obtain eventual ACLs as attribute with empty name
* bit2= do not obtain attributes other than ACLs * bit2= do not obtain attributes other than ACLs
* bit3= do not ignore eventual xattr representing ACL in local format * bit3= do not ignore eventual non-user attributes.
* (e.g. name "system.posix_acl_access") * I.e. those with a name which does not begin by "user."
* bit5= in case of symbolic link: inquire link target
* bit15= free memory * bit15= free memory
* @return * @return
* 1 ok * 1 ok
@ -4529,8 +4536,9 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
* @param flag * @param flag
* Bitfield for control purposes * Bitfield for control purposes
* bit0= do not attach ACLs from an eventual attribute with empty name * bit0= do not attach ACLs from an eventual attribute with empty name
* bit3= do not ignore eventual xattr representing ACL in local format * bit3= do not ignore eventual non-user attributes.
* (e.g. name "system.posix_acl_access") * I.e. those with a name which does not begin by "user."
* bit5= in case of symbolic link: manipulate link target
* @return * @return
* 1 = ok * 1 = ok
* < 0 = error * < 0 = error

View File

@ -1838,9 +1838,7 @@ int iso_local_get_acl_text(char *disk_path, char **text, int flag)
int ret; int ret;
ret = aaip_get_acl_text(disk_path, text, flag & (1 | 16 | (1 << 15))); ret = aaip_get_acl_text(disk_path, text, flag & (1 | 16 | 32 | (1 << 15)));
if (ret < 0)
return ISO_AAIP_NO_GET_LOCAL;
return ret; return ret;
#else /* Libisofs_with_aaiP */ #else /* Libisofs_with_aaiP */
@ -1860,7 +1858,7 @@ int iso_local_set_acl_text(char *disk_path, char *text, int flag)
int ret; int ret;
ret = aaip_set_acl_text(disk_path, text, flag & 1); ret = aaip_set_acl_text(disk_path, text, flag & (1 | 32));
if (ret < 0) if (ret < 0)
return ISO_AAIP_NO_SET_LOCAL; return ISO_AAIP_NO_SET_LOCAL;
return ret; return ret;
@ -1885,7 +1883,7 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
ret = aaip_get_attr_list(disk_path, ret = aaip_get_attr_list(disk_path,
num_attrs, names, value_lengths, values, num_attrs, names, value_lengths, values,
(flag & (1 | 4 | 8 | (1 << 15))) | 2 | 16); (flag & (1 | 4 | 8 | 32 | (1 << 15))) | 2 | 16);
if (ret <= 0) if (ret <= 0)
return ISO_AAIP_NO_GET_LOCAL; return ISO_AAIP_NO_GET_LOCAL;
return 1; return 1;
@ -1912,7 +1910,7 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
int ret; int ret;
ret = aaip_set_attr_list(disk_path, num_attrs, names, value_lengths, ret = aaip_set_attr_list(disk_path, num_attrs, names, value_lengths,
values, (flag & 8) | !(flag & 1)); values, (flag & (8 | 32)) | !(flag & 1));
if (ret <= 0) if (ret <= 0)
return ISO_AAIP_NO_SET_LOCAL; return ISO_AAIP_NO_SET_LOCAL;
return 1; return 1;