restore: fix restore of NFS4 ACLs

Changing the mode bits on a file with an NFS4 ACL results in the
NFS4 ACL being replaced by one matching the new mode bits being set,
so when restoring a file with an NFS4 ACL, set the owner/group/mode first
and then set the NFS4 ACL, so that setting the mode does not throw away
the ACL that we just set.

Reviewed by:	mckusick
Differential Revision:  https://reviews.freebsd.org/D37618
This commit is contained in:
Chuck Silvers 2022-12-12 08:14:17 -08:00
parent 86edb11e74
commit 9dda00df7e
2 changed files with 13 additions and 13 deletions

View File

@ -646,6 +646,11 @@ setdirmodes(int flags)
} }
cp = myname(ep); cp = myname(ep);
if (!Nflag) { if (!Nflag) {
if (myuid != 0)
(void) chown(cp, myuid, node.gid);
else
(void) chown(cp, node.uid, node.gid);
(void) chmod(cp, node.mode);
if (node.extsize > 0) { if (node.extsize > 0) {
if (bufsize >= node.extsize) { if (bufsize >= node.extsize) {
set_extattr(-1, cp, buf, node.extsize, SXA_FILE); set_extattr(-1, cp, buf, node.extsize, SXA_FILE);
@ -654,11 +659,6 @@ setdirmodes(int flags)
"extended attributes for ", cp); "extended attributes for ", cp);
} }
} }
if (myuid != 0)
(void) chown(cp, myuid, node.gid);
else
(void) chown(cp, node.uid, node.gid);
(void) chmod(cp, node.mode);
utimensat(AT_FDCWD, cp, node.ctimep, 0); utimensat(AT_FDCWD, cp, node.ctimep, 0);
utimensat(AT_FDCWD, cp, node.mtimep, 0); utimensat(AT_FDCWD, cp, node.mtimep, 0);
(void) chflags(cp, node.flags); (void) chflags(cp, node.flags);

View File

@ -628,10 +628,10 @@ extractfile(char *name)
return (GOOD); return (GOOD);
} }
if (linkit(lnkbuf, name, SYMLINK) == GOOD) { if (linkit(lnkbuf, name, SYMLINK) == GOOD) {
if (extsize > 0)
set_extattr(-1, name, buf, extsize, SXA_LINK);
(void) lchown(name, uid, gid); (void) lchown(name, uid, gid);
(void) lchmod(name, mode); (void) lchmod(name, mode);
if (extsize > 0)
set_extattr(-1, name, buf, extsize, SXA_LINK);
(void) utimensat(AT_FDCWD, name, ctimep, (void) utimensat(AT_FDCWD, name, ctimep,
AT_SYMLINK_NOFOLLOW); AT_SYMLINK_NOFOLLOW);
(void) utimensat(AT_FDCWD, name, mtimep, (void) utimensat(AT_FDCWD, name, mtimep,
@ -655,6 +655,8 @@ extractfile(char *name)
skipfile(); skipfile();
return (FAIL); return (FAIL);
} }
(void) chown(name, uid, gid);
(void) chmod(name, mode);
if (extsize == 0) { if (extsize == 0) {
skipfile(); skipfile();
} else { } else {
@ -662,8 +664,6 @@ extractfile(char *name)
getfile(xtrnull, xtrattr, xtrnull); getfile(xtrnull, xtrattr, xtrnull);
set_extattr(-1, name, buf, extsize, SXA_FILE); set_extattr(-1, name, buf, extsize, SXA_FILE);
} }
(void) chown(name, uid, gid);
(void) chmod(name, mode);
(void) utimensat(AT_FDCWD, name, ctimep, 0); (void) utimensat(AT_FDCWD, name, ctimep, 0);
(void) utimensat(AT_FDCWD, name, mtimep, 0); (void) utimensat(AT_FDCWD, name, mtimep, 0);
(void) chflags(name, flags); (void) chflags(name, flags);
@ -685,6 +685,8 @@ extractfile(char *name)
skipfile(); skipfile();
return (FAIL); return (FAIL);
} }
(void) chown(name, uid, gid);
(void) chmod(name, mode);
if (extsize == 0) { if (extsize == 0) {
skipfile(); skipfile();
} else { } else {
@ -692,8 +694,6 @@ extractfile(char *name)
getfile(xtrnull, xtrattr, xtrnull); getfile(xtrnull, xtrattr, xtrnull);
set_extattr(-1, name, buf, extsize, SXA_FILE); set_extattr(-1, name, buf, extsize, SXA_FILE);
} }
(void) chown(name, uid, gid);
(void) chmod(name, mode);
(void) utimensat(AT_FDCWD, name, ctimep, 0); (void) utimensat(AT_FDCWD, name, ctimep, 0);
(void) utimensat(AT_FDCWD, name, mtimep, 0); (void) utimensat(AT_FDCWD, name, mtimep, 0);
(void) chflags(name, flags); (void) chflags(name, flags);
@ -714,12 +714,12 @@ extractfile(char *name)
skipfile(); skipfile();
return (FAIL); return (FAIL);
} }
(void) fchown(ofile, uid, gid);
(void) fchmod(ofile, mode);
buf = setupextattr(extsize); buf = setupextattr(extsize);
getfile(xtrfile, xtrattr, xtrskip); getfile(xtrfile, xtrattr, xtrskip);
if (extsize > 0) if (extsize > 0)
set_extattr(ofile, name, buf, extsize, SXA_FD); set_extattr(ofile, name, buf, extsize, SXA_FD);
(void) fchown(ofile, uid, gid);
(void) fchmod(ofile, mode);
(void) futimens(ofile, ctimep); (void) futimens(ofile, ctimep);
(void) futimens(ofile, mtimep); (void) futimens(ofile, mtimep);
(void) fchflags(ofile, flags); (void) fchflags(ofile, flags);