Handling ACL entries which match the POSIX permissions
This commit is contained in:
parent
ece6eca9a5
commit
723d23321a
@ -330,4 +330,9 @@ SUSP 1.12 ftp://ftp.ymi.com/pub/rockridge/susp112.ps
|
||||
RRIP 1.12 ftp://ftp.ymi.com/pub/rockridge/rrip112.ps
|
||||
(especially field SL)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Pending considerations:
|
||||
|
||||
- shall "AA" be fixely defined as signature ?
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <sys/acl.h>
|
||||
|
||||
@ -27,6 +28,9 @@
|
||||
with bit15 of flag.
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= obtain default ACL rather than access ACL
|
||||
bit4= do not return entries which match the st_mode
|
||||
permissions. If no other ACL entries exist:
|
||||
set *text = NULL and return 2
|
||||
bit15= free text and return 1
|
||||
@return > 0 ok
|
||||
-1 failure of system ACL service (see errno)
|
||||
@ -34,6 +38,8 @@
|
||||
int aaip_get_acl_text(char *path, char **text, int flag)
|
||||
{
|
||||
acl_t acl= NULL;
|
||||
struct stat stbuf;
|
||||
int ret;
|
||||
|
||||
if(flag & (1 << 15)) {
|
||||
if(*text != NULL)
|
||||
@ -55,6 +61,16 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
||||
acl_free(acl);
|
||||
if(*text == NULL)
|
||||
return(-1);
|
||||
if(flag & 16) {
|
||||
ret= stat(path, &stbuf);
|
||||
if(ret != -1)
|
||||
aaip_cleanout_st_mode(*text, stbuf.st_mode, 0);
|
||||
if((*text)[0] == 0 || strcmp(*text, "\n") == 0) {
|
||||
acl_free(text);
|
||||
*text= NULL;
|
||||
return(2);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -74,6 +90,8 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
||||
bit0= obtain ACL (access and eventually default)
|
||||
bit1= use numeric ACL qualifiers rather than names
|
||||
bit2= do not encode attributes other than ACL
|
||||
bit3= -reserved-
|
||||
bit4= do not return st_mode permissions in ACL.
|
||||
bit15= free memory of names, value_lengths, values
|
||||
@return >0 ok
|
||||
<=0 error
|
||||
@ -118,9 +136,11 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
|
||||
if(flag & 1) { /* Obtain ACL */
|
||||
/* access-ACL */
|
||||
ret= aaip_get_acl_text(path, &acl_text, 0);
|
||||
ret= aaip_get_acl_text(path, &acl_text, flag & 16);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
if(ret == 2)
|
||||
{ret= 1; goto ex;} /* empty ACL / only st_mode info was found in ACL */
|
||||
ret= aaip_encode_acl(acl_text, &a_acl_len, &a_acl, flag & 2);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <sys/acl.h>
|
||||
#include <attr/xattr.h>
|
||||
@ -30,6 +31,9 @@
|
||||
with bit15 of flag.
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= obtain default ACL rather than access ACL
|
||||
bit4= do not return entries which match the st_mode
|
||||
permissions. If no other ACL entries exist:
|
||||
set *text = NULL and return 2
|
||||
bit15= free text and return 1
|
||||
@return > 0 ok
|
||||
-1 failure of system ACL service (see errno)
|
||||
@ -37,6 +41,8 @@
|
||||
int aaip_get_acl_text(char *path, char **text, int flag)
|
||||
{
|
||||
acl_t acl= NULL;
|
||||
struct stat stbuf;
|
||||
int ret;
|
||||
|
||||
if(flag & (1 << 15)) {
|
||||
if(*text != NULL)
|
||||
@ -52,6 +58,16 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
||||
acl_free(acl);
|
||||
if(*text == NULL)
|
||||
return(-1);
|
||||
if(flag & 16) {
|
||||
ret= stat(path, &stbuf);
|
||||
if(ret != -1)
|
||||
aaip_cleanout_st_mode(*text, stbuf.st_mode, 0);
|
||||
if((*text)[0] == 0 || strcmp(*text, "\n") == 0) {
|
||||
acl_free(text);
|
||||
*text= NULL;
|
||||
return(2);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -69,6 +85,7 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
||||
bit2= do not obtain attributes other than ACL
|
||||
bit3= do not ignore eventual local ACL attribute
|
||||
(e.g. system.posix_acl_access)
|
||||
bit4= do not return st_mode permissions in ACL.
|
||||
bit15= free memory of names, value_lengths, values
|
||||
@return >0 ok
|
||||
<=0 error
|
||||
@ -158,9 +175,11 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
|
||||
if(flag & 1) { /* Obtain ACL */
|
||||
/* access-ACL */
|
||||
ret= aaip_get_acl_text(path, &acl_text, 0);
|
||||
ret= aaip_get_acl_text(path, &acl_text, flag & 16);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
if(ret == 2)
|
||||
{ret= 1; goto ex;} /* empty ACL / only st_mode info was found in ACL */
|
||||
ret= aaip_encode_acl(acl_text, &a_acl_len, &a_acl, flag & 2);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* <<<
|
||||
*/
|
||||
@ -425,6 +426,121 @@ group_by_name:;
|
||||
}
|
||||
|
||||
|
||||
/* Remove the entries user::??? , group::??? , other::??? , other:???
|
||||
from an ACL in long text form if they match the bits in st_mode.
|
||||
@param flag bit0= do not remove entries, only determine return value
|
||||
*/
|
||||
int aaip_cleanout_st_mode(char *acl_text, mode_t st_mode, int flag)
|
||||
{
|
||||
char *rpt, *wpt, *npt, *cpt;
|
||||
mode_t m;
|
||||
int overriders= 0;
|
||||
|
||||
for(npt= wpt= rpt= acl_text; *npt != 0; rpt= npt + 1) {
|
||||
npt= strchr(rpt, '\n');
|
||||
if(npt == NULL)
|
||||
npt= rpt + strlen(rpt);
|
||||
if(strncmp(rpt, "user::", 6) == 0 && npt - rpt == 9) {
|
||||
cpt= rpt + 6;
|
||||
m= 0;
|
||||
if(cpt[0] == 'r')
|
||||
m|= S_IRUSR;
|
||||
if(cpt[1] == 'w')
|
||||
m|= S_IWUSR;
|
||||
if(cpt[2] == 'x')
|
||||
m|= S_IXUSR;
|
||||
if((st_mode & S_IRWXU) == (m & S_IRWXU)) {
|
||||
overriders|= 32;
|
||||
continue;
|
||||
}
|
||||
overriders|= 4;
|
||||
}
|
||||
if(strncmp(rpt, "group::", 7) == 0 && npt - rpt == 10) {
|
||||
cpt= rpt + 7;
|
||||
m= 0;
|
||||
if(cpt[0] == 'r')
|
||||
m|= S_IRGRP;
|
||||
if(cpt[1] == 'w')
|
||||
m|= S_IWGRP;
|
||||
if(cpt[2] == 'x')
|
||||
m|= S_IXGRP;
|
||||
if((st_mode & S_IRWXG) == (m & S_IRWXG)) {
|
||||
overriders|= 16;
|
||||
continue;
|
||||
}
|
||||
overriders|= 2;
|
||||
}
|
||||
if(strncmp(rpt, "other::", 7) == 0 && npt - rpt == 10) {
|
||||
cpt= rpt + 7;
|
||||
others_st_mode:;
|
||||
m= 0;
|
||||
if(cpt[0] == 'r')
|
||||
m|= S_IROTH;
|
||||
if(cpt[1] == 'w')
|
||||
m|= S_IWOTH;
|
||||
if(cpt[2] == 'x')
|
||||
m|= S_IXOTH;
|
||||
if((st_mode & S_IRWXO) == (m & S_IRWXO)) {
|
||||
overriders|= 8;
|
||||
continue;
|
||||
}
|
||||
overriders|= 1;
|
||||
}
|
||||
if(strncmp(rpt, "other:", 6) == 0 && npt - rpt == 9) {
|
||||
cpt= rpt + 7;
|
||||
goto others_st_mode;
|
||||
}
|
||||
if(wpt == rpt) {
|
||||
wpt= npt + 1;
|
||||
continue;
|
||||
}
|
||||
if(!(flag & 1))
|
||||
memmove(wpt, rpt, 1 + npt - rpt);
|
||||
wpt+= 1 + npt - rpt;
|
||||
}
|
||||
if(!(flag & 1)) {
|
||||
if(wpt == acl_text)
|
||||
*wpt= 0;
|
||||
else if(*(wpt - 1) != 0)
|
||||
*wpt= 0;
|
||||
}
|
||||
return(overriders);
|
||||
}
|
||||
|
||||
|
||||
/* Important: acl_text must provide 32 bytes more than its current length !
|
||||
*/
|
||||
int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag)
|
||||
{
|
||||
char *wpt;
|
||||
int overriders= 0;
|
||||
|
||||
overriders = aaip_cleanout_st_mode(acl_text, st_mode, 1);
|
||||
if(!(overriders & (4 | 32))) {
|
||||
wpt= acl_text + strlen(acl_text);
|
||||
sprintf(wpt, "user::%c%c%c\n",
|
||||
st_mode & S_IRUSR ? 'r' : '-',
|
||||
st_mode & S_IWUSR ? 'w' : '-',
|
||||
st_mode & S_IXUSR ? 'x' : '-');
|
||||
}
|
||||
if(!(overriders & (2 | 16))) {
|
||||
wpt= acl_text + strlen(acl_text);
|
||||
sprintf(wpt, "group::%c%c%c\n",
|
||||
st_mode & S_IRGRP ? 'r' : '-',
|
||||
st_mode & S_IWGRP ? 'w' : '-',
|
||||
st_mode & S_IXGRP ? 'x' : '-');
|
||||
}
|
||||
if(!(overriders & (1 | 8))) {
|
||||
wpt= acl_text + strlen(acl_text);
|
||||
sprintf(wpt, "other::%c%c%c\n",
|
||||
st_mode & S_IROTH ? 'r' : '-',
|
||||
st_mode & S_IWOTH ? 'w' : '-',
|
||||
st_mode & S_IXOTH ? 'x' : '-');
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------- Decoder ---------------------------- */
|
||||
|
||||
/* --- private --- */
|
||||
|
@ -58,6 +58,44 @@ int aaip_encode_acl(char *acl_text,
|
||||
size_t *result_len, unsigned char **result, int flag);
|
||||
|
||||
|
||||
/* Remove the entries of type "user::" , "group::" , "other::" , "other:"
|
||||
from an ACL in long text form if they match the bits in st_mode.
|
||||
@param acl_text The text to be shortened
|
||||
@param st_mode The component of struct stat which shall take the
|
||||
removed information. The caller should submit the st_mode
|
||||
variable which holds permissions as indicated by ECMA-119
|
||||
and RRIP data.
|
||||
@param flag bit0= do not remove entries, only determine return value
|
||||
@return <0 failure
|
||||
>=0 tells in six bits which tag types are present.
|
||||
The first three tell which types deviate from the
|
||||
corresponding st_mode settings:
|
||||
bit0= "other::" overrides S_IRWXO
|
||||
bit1= "group::" overrides S_IRWXG
|
||||
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
|
||||
bit5= "user::" matches S_IRWXU
|
||||
Given the nature of ACLs all 64 combinations are
|
||||
possible although some show inner contradictions.
|
||||
*/
|
||||
int aaip_cleanout_st_mode(char *acl_text, mode_t st_mode, int flag);
|
||||
|
||||
|
||||
/* Append entries of type "user::" , "group::" , "other::" representing the
|
||||
permission bits in st_mode if those tag types are not present in the ACL
|
||||
text.
|
||||
@param acl_text The text to be made longer. It must offer 33 bytes more
|
||||
storage space than its length when it is submitted.
|
||||
@param st_mode The component of struct stat which shall provide the
|
||||
permission information.
|
||||
@param flag Unused yet. Submit 0.
|
||||
@return <0 failure
|
||||
*/
|
||||
int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag);
|
||||
|
||||
|
||||
/* ------ OS interface ------ */
|
||||
|
||||
/* Obtain the ACL of the given file in long text form.
|
||||
@ -67,9 +105,13 @@ int aaip_encode_acl(char *acl_text,
|
||||
with bit15 of flag.
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= obtain default ACL rather than access ACL
|
||||
bit4= do not return entries which match the st_mode
|
||||
permissions. If no other ACL entries exist:
|
||||
set *text = NULL and return 2
|
||||
bit15= free text and return 1
|
||||
@return > 0 ok
|
||||
-1 failure of system ACL service (see errno)
|
||||
@return 1 ok
|
||||
2 only st_mode permissions exist and bit 4 is set
|
||||
-1 failure of system ACL service (see errno)
|
||||
*/
|
||||
int aaip_get_acl_text(char *path, char **text, int flag);
|
||||
|
||||
@ -89,6 +131,7 @@ int aaip_get_acl_text(char *path, char **text, int flag);
|
||||
bit2= do not obtain attributes other than ACLs
|
||||
bit3= do not ignore eventual ACL attribute
|
||||
(e.g. system.posix_acl_access)
|
||||
bit4= do not return st_mode permissions in ACL.
|
||||
bit15= free memory of names, value_lengths, values
|
||||
@return >0 ok
|
||||
<=0 error
|
||||
|
@ -489,11 +489,13 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
||||
|
||||
*aa_string = NULL;
|
||||
/* Obtain EAs and ACLs ("access" and "default"). ACLs encoded according
|
||||
to AAIP ACL representation.
|
||||
to AAIP ACL representation. Clean out st_mode ACL entries.
|
||||
*/
|
||||
path = iso_file_source_get_path(src);
|
||||
|
||||
/* >>> make adjustable: bit4 = ignoring of st_mode ACL entries */
|
||||
ret = aaip_get_attr_list(path, &num_attrs, &names,
|
||||
&value_lengths, &values, 1 | 2);
|
||||
&value_lengths, &values, 1 | 2 | 16);
|
||||
if (ret <= 0) {
|
||||
ret = ISO_FILE_ERROR;
|
||||
goto ex;
|
||||
|
@ -4141,9 +4141,12 @@ int aaip_xinfo_func(void *data, int flag);
|
||||
* bit0= obtain "default" ACL rather than "access" ACL
|
||||
* (Linux directories can have a "default" ACL which influences
|
||||
* the permissions of newly created files.)
|
||||
* bit4= if no ACL available: return *text == NULL
|
||||
else: produce ACL from PROSIX permissions
|
||||
* bit15= free memory and return 1
|
||||
* @return
|
||||
* 1 on success,
|
||||
* 2 ACL produced from POSIX permissions
|
||||
* 1 ACL was read from node
|
||||
* 0 if the desire ACL type is not available
|
||||
* < 0 on error
|
||||
*
|
||||
|
@ -1421,7 +1421,8 @@ int iso_node_get_acl_text(IsoNode *node, char **text, int flag)
|
||||
size_t v_len;
|
||||
char **names = NULL, **values = NULL;
|
||||
unsigned char *v_data;
|
||||
int ret;
|
||||
int ret, from_posix= 0;
|
||||
mode_t st_mode;
|
||||
|
||||
if (flag & (1 << 15)) {
|
||||
if (*text != NULL)
|
||||
@ -1468,7 +1469,7 @@ int iso_node_get_acl_text(IsoNode *node, char **text, int flag)
|
||||
ret = 0;
|
||||
goto ex;
|
||||
}
|
||||
*text = calloc(text_fill, 1);
|
||||
*text = calloc(text_fill + 32, 1); /* 32 for aaip_update_acl_st_mode */
|
||||
if (*text == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto ex;
|
||||
@ -1479,8 +1480,21 @@ int iso_node_get_acl_text(IsoNode *node, char **text, int flag)
|
||||
goto bad_decode;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*text == NULL && !(flag & 16)) {
|
||||
from_posix = 1;
|
||||
*text = calloc(32, 1); /* 32 for aaip_update_acl_st_mode */
|
||||
}
|
||||
if (*text != NULL) {
|
||||
st_mode = iso_node_get_permissions(node);
|
||||
aaip_add_acl_st_mode(*text, st_mode, 0);
|
||||
text_fill = strlen(*text);
|
||||
}
|
||||
|
||||
ret = (*text != NULL);
|
||||
if (text == NULL)
|
||||
ret = 0;
|
||||
else
|
||||
ret = 1 + from_posix;
|
||||
ex:;
|
||||
iso_node_get_attrs(node, &num_attrs, &names,
|
||||
&value_lengths, &values, 1 << 15); /* free memory */
|
||||
|
Loading…
Reference in New Issue
Block a user