Giving lfa flag "a" the same treatment as "i"

This commit is contained in:
Thomas Schmitt 2024-09-09 15:42:46 +02:00
parent 1ed76b7bdc
commit aa0d5d1309
5 changed files with 77 additions and 54 deletions

View File

@ -940,15 +940,17 @@ int Linkitem_get_link_count(struct LinkiteM *item, int flag)
struct PermiteM { struct PermiteM {
char *disk_path; char *disk_path;
struct stat stbuf; struct stat stbuf;
int immutable; /* bit0= set chattr immutable bit int chattr_flags; /* bit0= set chattr immutable bit
bit1= only set immutable bit bit1= only set chattr bits
bit2= set chattr append-only bit
*/ */
struct PermiteM *next; struct PermiteM *next;
}; };
/* @param flag bit0= Linux chattr immutable bit is set /* @param flag bit0= Linux chattr immutable bit is set
bit1= when popping only set immutable bit bit1= when popping only set chattr bits
bit2= Linux chattr append-only bit is set
*/ */
int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf, int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf,
int flag) int flag)
@ -960,7 +962,7 @@ int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf,
return(-1); return(-1);
m->disk_path= NULL; m->disk_path= NULL;
memcpy(&(m->stbuf), stbuf, sizeof(struct stat)); memcpy(&(m->stbuf), stbuf, sizeof(struct stat));
m->immutable= flag & 3; m->chattr_flags= flag & 7;
m->next= *o; m->next= *o;
m->disk_path= strdup(disk_path); m->disk_path= strdup(disk_path);
@ -979,7 +981,7 @@ failed:;
/* @param flag bit0= minimal transfer: access permissions only /* @param flag bit0= minimal transfer: access permissions only
bit1= do not set timestamps bit1= do not set timestamps
bit2= do not set chattr flag i "immutable" bit2= do not set chattr flags
*/ */
int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
struct XorrisO *xorriso, int flag) struct XorrisO *xorriso, int flag)
@ -1001,7 +1003,7 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
} }
for(m= *o; m!=stopper; m= m_next) { for(m= *o; m!=stopper; m= m_next) {
if(!(m->immutable & 2)) { if(!(m->chattr_flags & 2)) {
ret= chmod(m->disk_path, m->stbuf.st_mode); ret= chmod(m->disk_path, m->stbuf.st_mode);
if(ret==-1) { if(ret==-1) {
if(xorriso!=NULL) { if(xorriso!=NULL) {
@ -1015,7 +1017,7 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
} }
} }
if(!((flag & 1) || (m->immutable & 2))) { if(!((flag & 1) || (m->chattr_flags & 2))) {
ret= chown(m->disk_path, m->stbuf.st_uid, m->stbuf.st_gid); ret= chown(m->disk_path, m->stbuf.st_uid, m->stbuf.st_gid);
/* don't complain if it fails */ /* don't complain if it fails */
if(!(flag&2)) { if(!(flag&2)) {
@ -1032,9 +1034,10 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
} }
} }
if((m->immutable & 1) && !(flag & 4)) { if((m->chattr_flags & (1 | 4)) && !(flag & 4)) {
/* It seems tradition here to just complain but to go on to return 1 */ /* It seems tradition here to just complain but to go on to return 1 */
Xorriso_set_local_chattr_i(xorriso, m->disk_path, 0); Xorriso_set_local_chattr_ia(xorriso, m->disk_path,
(m->chattr_flags & 1) | ((m->chattr_flags & 4) >> 1));
} }
m_next= m->next; m_next= m->next;
@ -1047,11 +1050,11 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
/* Look for stack item with disk_path /* Look for stack item with disk_path
@return 0= nothing found, 1= *stbuf and *immutable are valid @return 0= nothing found, 1= *stbuf and *chattr_flags are valid
*/ */
int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper, int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper,
struct XorrisO *xorriso, struct XorrisO *xorriso,
char *disk_path, struct stat **stbuf, int *immutable, char *disk_path, struct stat **stbuf, int *chattr_flags,
int flag) int flag)
{ {
struct PermiteM *m; struct PermiteM *m;
@ -1061,7 +1064,7 @@ int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper,
for(m= *o; m != NULL; m= m->next) { for(m= *o; m != NULL; m= m->next) {
if(strcmp(m->disk_path, disk_path) == 0) { if(strcmp(m->disk_path, disk_path) == 0) {
*stbuf= &(m->stbuf); *stbuf= &(m->stbuf);
*immutable= m->immutable; *chattr_flags= m->chattr_flags;
return(1); return(1);
} }
if(m->next == stopper) if(m->next == stopper)

View File

@ -181,13 +181,14 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
struct XorrisO *xorriso, int flag); struct XorrisO *xorriso, int flag);
/* Look for stack item with disk_path /* Look for stack item with disk_path
@param immutable bit0= when popping: set chattr immutable bit @param chattr_flag bit0= when popping: set chattr bit 'i'
bit1= when popping: only set immutable bit bit1= when popping: only set chattr bits
@return 0= nothing found, 1= *stbuf and *immutable are valid bit2= when popping: set chattr bit 'a'
@return 0= nothing found, 1= *stbuf and *chattr_flags are valid
*/ */
int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper, int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper,
struct XorrisO *xorriso, struct XorrisO *xorriso,
char *disk_path, struct stat **stbuf, int *immutable, char *disk_path, struct stat **stbuf, int *chattr_flags,
int flag); int flag);
#endif /* ! Xorriso_pvt_auxobj_includeD */ #endif /* ! Xorriso_pvt_auxobj_includeD */

View File

@ -436,45 +436,61 @@ uint64_t Xorriso__lfa_bits(char *lfa_text)
} }
int Xorriso_set_local_chattr_i(struct XorrisO *xorriso, char *disk_path, /* @param flag bit0= set i
bit1= set a
*/
int Xorriso_set_local_chattr_ia(struct XorrisO *xorriso, char *disk_path,
int flag) int flag)
{ {
int ret, max_bit= 31, os_errno; int ret, max_bit= 31, os_errno;
static uint64_t lfa_i= 0xffffffff; uint64_t lfa_flags= 0;
static uint64_t lfa_i= 0xffffffff, lfa_a= 0;
if(lfa_i == 0xffffffff) if(lfa_i == 0xffffffff) {
lfa_i= Xorriso__lfa_bits("i"); lfa_i= Xorriso__lfa_bits("i");
lfa_a= Xorriso__lfa_bits("a");
ret= iso_local_set_lfa_flags(disk_path, lfa_i, max_bit, lfa_i, &os_errno, 4); }
ret= Xorriso_report_chattr_outcome(xorriso, disk_path, lfa_i, lfa_i, if(flag & 1)
ret, os_errno, 0); lfa_flags|= lfa_i;
if(flag & 2)
lfa_flags|= lfa_a;
if(lfa_flags == 0)
return(1);
ret= Xorriso_local_set_lfa_flags(xorriso, disk_path, lfa_flags, max_bit,
lfa_flags, &os_errno, 0);
if(ret <= 0) if(ret <= 0)
return(ret); return(ret);
return(1); return(1);
} }
/* If present and enabled: restore chattr i */ /* If present and enabled: restore chattr i and/or a */
int Xorriso_restore_chattr_i(struct XorrisO *xorriso, IsoNode *node, int Xorriso_restore_chattr_ia(struct XorrisO *xorriso, IsoNode *node,
char *disk_path, int flag) char *disk_path, int flag)
{ {
int ret, max_bit; int ret, max_bit;
uint64_t lfa_flags, mask; uint64_t lfa_flags, mask, chattr_flag= 0;
static uint64_t lfa_i= 0xffffffff; static uint64_t lfa_i= 0xffffffff, lfa_a= 0;
if(lfa_i == 0xffffffff) if(lfa_i == 0xffffffff) {
lfa_i= Xorriso__lfa_bits("i"); lfa_i= Xorriso__lfa_bits("i");
lfa_a= Xorriso__lfa_bits("a");
}
if((xorriso->do_aaip & (1 << 12))) { if((xorriso->do_aaip & (1 << 12))) {
mask= iso_util_get_effective_lfa_mask(xorriso->lfa_restore_mask, mask= iso_util_get_effective_lfa_mask(xorriso->lfa_restore_mask,
(!!(xorriso->do_aaip & (1 << 13))) | (!!(xorriso->do_aaip & (1 << 13))) |
((!!(xorriso->do_aaip & (1 << 14))) << 1)); ((!!(xorriso->do_aaip & (1 << 14))) << 1));
if(!(mask & lfa_i)) if(!(mask & (lfa_i | lfa_a)))
return(2); return(2);
ret= iso_node_get_lfa_flags(node, &lfa_flags, &max_bit, 0); ret= iso_node_get_lfa_flags(node, &lfa_flags, &max_bit, 0);
if(ret > 0) { if(ret > 0) {
if(lfa_flags & lfa_i) { if(lfa_flags & lfa_i)
ret= Xorriso_set_local_chattr_i(xorriso, disk_path, 0); chattr_flag|= 1;
if(lfa_flags & lfa_a)
chattr_flag|= 2;
if(chattr_flag) {
ret= Xorriso_set_local_chattr_ia(xorriso, disk_path, chattr_flag);
if(ret <= 0) if(ret <= 0)
return(ret); return(ret);
return(1); return(1);
@ -552,13 +568,13 @@ int Xorriso_restore_timestamps(struct XorrisO *xorriso, char *disk_path,
/* @param flag bit0= minimal transfer: access permissions only /* @param flag bit0= minimal transfer: access permissions only
bit1= keep directory open: keep owner, allow rwx for owner bit1= keep directory open: keep owner, allow rwx for owner
and push directory onto xorriso->perm_stack and push directory onto xorriso->perm_stack
@return 1=ok , 2=ok, lfa "i" pushed to permstack, <=0 error @return 1=ok , 2=ok, lfa "i" and/or "a" pushed to permstack, <=0 error
*/ */
int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path,
IsoNode *node, int flag) IsoNode *node, int flag)
{ {
int ret, is_dir= 0, errno_copy= 0, local_attrs_set= 0, i, err_count; int ret, is_dir= 0, errno_copy= 0, local_attrs_set= 0, i, err_count;
int lfa_i_pushed= 0; int lfa_ia_pushed= 0;
mode_t mode; mode_t mode;
uid_t uid, disk_uid; uid_t uid, disk_uid;
gid_t gid, disk_gid; gid_t gid, disk_gid;
@ -568,12 +584,13 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path,
int *errnos= NULL; int *errnos= NULL;
uint64_t lfa_flags= 0, mask= 0, push_mask= 0; uint64_t lfa_flags= 0, mask= 0, push_mask= 0;
int max_bit, os_errno; int max_bit, os_errno;
static uint64_t lfa_C= 0xffffffff, lfa_i= 0, lfa_F= 0; static uint64_t lfa_C= 0xffffffff, lfa_i= 0, lfa_a= 0, lfa_F= 0;
if(lfa_C == 0xffffffff) { if(lfa_C == 0xffffffff) {
lfa_C= Xorriso__lfa_bits("C"); lfa_C= Xorriso__lfa_bits("C");
lfa_F= Xorriso__lfa_bits("F"); lfa_F= Xorriso__lfa_bits("F");
lfa_i= Xorriso__lfa_bits("i"); lfa_i= Xorriso__lfa_bits("i");
lfa_a= Xorriso__lfa_bits("a");
} }
ret= lstat(disk_path, &stbuf); ret= lstat(disk_path, &stbuf);
@ -670,9 +687,10 @@ cannot_set_xattr:;
if(is_dir) if(is_dir)
mask&= ~lfa_F; mask&= ~lfa_F;
push_mask= mask; push_mask= mask;
/* Do not set lfa_flag 'i' of a directory here. It would be too early. */ /* Do not set lfa_flags 'i' or 'a' of a directory here.
It would be too early. */
if(is_dir) if(is_dir)
mask&= ~lfa_i; mask&= ~(lfa_i | lfa_a);
} }
} }
@ -682,7 +700,8 @@ cannot_set_xattr:;
if(ret<=0) if(ret<=0)
{ret= 0; goto ex;} {ret= 0; goto ex;}
ret= Permstack_push(&(xorriso->perm_stack), disk_path, &stbuf, ret= Permstack_push(&(xorriso->perm_stack), disk_path, &stbuf,
!!(lfa_flags & push_mask & lfa_i)); (!!(lfa_flags & push_mask & lfa_i)) |
((!!(lfa_flags & push_mask & lfa_a)) << 2));
if(ret<=0) { if(ret<=0) {
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
strcpy(xorriso->info_text, strcpy(xorriso->info_text,
@ -690,7 +709,7 @@ cannot_set_xattr:;
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
{ret= -1; goto ex;} {ret= -1; goto ex;}
} }
lfa_i_pushed= !!(lfa_flags & push_mask & lfa_i); lfa_ia_pushed= !!(lfa_flags & push_mask & (lfa_i | lfa_a));
mode|= S_IRUSR|S_IWUSR|S_IXUSR; mode|= S_IRUSR|S_IWUSR|S_IXUSR;
} }
ret= chmod(disk_path, mode); ret= chmod(disk_path, mode);
@ -751,7 +770,7 @@ cannot_set_perm:;
} }
} }
ret= 1 + !!lfa_i_pushed; ret= 1 + !!lfa_ia_pushed;
ex:; ex:;
iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,1 << 15); iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,1 << 15);
if(errnos != NULL) if(errnos != NULL)
@ -1954,7 +1973,7 @@ int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir,
int dir_create= 0, node_register= 0, do_node_count= 0, normal_mode= 0; int dir_create= 0, node_register= 0, do_node_count= 0, normal_mode= 0;
int target_was_no_dir, dir_is_new; int target_was_no_dir, dir_is_new;
struct stat *stack_stbufpt; struct stat *stack_stbufpt;
int lfa_i_pushed= 0, stack_immutable; int lfa_ia_pushed= 0, stack_chattr;
perm_stack_mem= xorriso->perm_stack; perm_stack_mem= xorriso->perm_stack;
switch((flag >> 7) & 3) { switch((flag >> 7) & 3) {
@ -2182,15 +2201,15 @@ much_too_long:;
if(source_is_dir) { if(source_is_dir) {
/* Restore exact access permissions of directory */ /* Restore exact access permissions of directory */
hret= Permstack_peek(&(xorriso->perm_stack), perm_stack_mem, xorriso, hret= Permstack_peek(&(xorriso->perm_stack), perm_stack_mem, xorriso,
disk_path, &stack_stbufpt, &stack_immutable, 0); disk_path, &stack_stbufpt, &stack_chattr, 0);
if(hret == 1 && (stack_immutable & 1)) if(hret == 1 && (stack_chattr & (1 | 4)))
lfa_i_pushed= 1; lfa_ia_pushed= 1;
hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
!!(flag&64)); !!(flag&64));
if(hret<=0 && hret<ret) if(hret<=0 && hret<ret)
ret= hret; ret= hret;
if(dir_is_new && !(dir_create || lfa_i_pushed)) { if(dir_is_new && !(dir_create || lfa_ia_pushed)) {
hret= Xorriso_restore_chattr_i(xorriso, node, disk_path, 0); hret= Xorriso_restore_chattr_ia(xorriso, node, disk_path, 0);
if(hret <= 0 && hret < ret) if(hret <= 0 && hret < ret)
ret= hret; ret= hret;
} }
@ -2272,7 +2291,7 @@ int Xorriso_restore(struct XorrisO *xorriso,
struct stat stbuf; struct stat stbuf;
struct PermiteM *perm_stack_mem; struct PermiteM *perm_stack_mem;
struct stat *stack_stbufpt; struct stat *stack_stbufpt;
int lfa_i_pushed= 0, stack_immutable; int lfa_ia_pushed= 0, stack_chattr;
perm_stack_mem= xorriso->perm_stack; perm_stack_mem= xorriso->perm_stack;
@ -2479,15 +2498,15 @@ attach_source:;
So pop earlier than normal. So pop earlier than normal.
*/ */
hret= Permstack_peek(&(xorriso->perm_stack), perm_stack_mem, xorriso, hret= Permstack_peek(&(xorriso->perm_stack), perm_stack_mem, xorriso,
disk_path, &stack_stbufpt, &stack_immutable, 0); disk_path, &stack_stbufpt, &stack_chattr, 0);
if(hret == 1 && (stack_immutable & 1)) if(hret == 1 && (stack_chattr & (1 | 4)))
lfa_i_pushed= 1; lfa_ia_pushed= 1;
hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
2 | !!(flag&64)); 2 | !!(flag&64));
if(hret <= 0 && hret < ret) if(hret <= 0 && hret < ret)
ret= hret; ret= hret;
if(!lfa_i_pushed) { if(!lfa_ia_pushed) {
hret= Xorriso_restore_chattr_i(xorriso, node, disk_path, 0); hret= Xorriso_restore_chattr_ia(xorriso, node, disk_path, 0);
if(hret <= 0 && hret < ret) if(hret <= 0 && hret < ret)
ret= hret; ret= hret;
if(ret <= 0) if(ret <= 0)

View File

@ -1 +1 @@
#define Xorriso_timestamP "2024.09.08.192526" #define Xorriso_timestamP "2024.09.09.134057"

View File

@ -714,7 +714,7 @@ int Xorriso_set_lfa_flags(struct XorrisO *xorriso, void *in_node, char *path,
int Xorriso_remove_all_lfa_flags(struct XorrisO *xorriso, int flag); int Xorriso_remove_all_lfa_flags(struct XorrisO *xorriso, int flag);
int Xorriso_set_local_chattr_i(struct XorrisO *xorriso, char *disk_path, int Xorriso_set_local_chattr_ia(struct XorrisO *xorriso, char *disk_path,
int flag); int flag);
#endif /* Xorrisoburn_includeD */ #endif /* Xorrisoburn_includeD */