Fix rename trustee rights and invalidate trustee cache
All checks were successful
Source release / source-package (push) Successful in 39s
All checks were successful
Source release / source-package (push) Successful in 39s
Align rename permission checks with NetWare trustee semantics. A same-directory rename should be controlled by the Modify right instead of requiring a broader R/W/M combination. For moves to another parent directory, require Create rights on the destination parent. Also invalidate the trustee rights cache after adding or deleting trustee assignments so newly granted rights are visible immediately to subsequent operations. This fixes the MARIO trustee test where rename failed with R/W/M/F and even R/W/C/E/M/F, while the same operation succeeded only with the broader all-rights set.
This commit is contained in:
@@ -2395,12 +2395,37 @@ static int nw_rename_file_dir(int namespace,
|
||||
uint8 *unname_d =
|
||||
(uint8*)alloc_nwpath2unix_extra(&(dbe_d->nwpath), 0, last_part);
|
||||
|
||||
if (tru_eff_rights_exists(dbe_s->nwpath.volume, unname_s,
|
||||
&dbe_s->nwpath.statb, TRUSTEE_W|TRUSTEE_M|TRUSTEE_R))
|
||||
result=-0x8b;
|
||||
else if (tru_eff_rights_exists(dbe_d->nwpath.volume, unname_dp,
|
||||
&dbe_d->nwpath.statb, TRUSTEE_W))
|
||||
/* NetWare trustee semantics: M (Modify) is the right for renaming
|
||||
* files/directories. A is for trustee/IRM changes, not rename.
|
||||
*
|
||||
* The old check required R|W|M on the source and W on the destination
|
||||
* parent. That is stricter than NetWare for a same-directory rename and
|
||||
* makes REN fail for users with Modify rights.
|
||||
*/
|
||||
if (tru_eff_rights_exists(dbe_s->nwpath.volume, unname_s,
|
||||
&dbe_s->nwpath.statb, TRUSTEE_M)) {
|
||||
XDPRINTF((5, 0, "Rename denied: missing M on source `%s`", unname_s));
|
||||
result=-0x8b;
|
||||
} else {
|
||||
char src_parent[1024];
|
||||
char *slash;
|
||||
|
||||
strmaxcpy((uint8*)src_parent, unname_s, sizeof(src_parent)-1);
|
||||
slash = strrchr(src_parent, '/');
|
||||
if (slash && slash > src_parent)
|
||||
*slash = '\0';
|
||||
|
||||
/* Only require destination Create rights when this is a move to a
|
||||
* different parent directory. Same-directory rename is covered by M.
|
||||
*/
|
||||
if (slash && strcmp(src_parent, (char*)unname_dp) &&
|
||||
tru_eff_rights_exists(dbe_d->nwpath.volume, unname_dp,
|
||||
&dbe_d->nwpath.statb, TRUSTEE_C)) {
|
||||
XDPRINTF((5, 0, "Rename denied: missing C on dest parent `%s`",
|
||||
unname_dp));
|
||||
result=-0x8b;
|
||||
}
|
||||
}
|
||||
|
||||
if (result > -1) {
|
||||
if (seteuid(0)) {}
|
||||
|
||||
@@ -465,8 +465,11 @@ int tru_del_trustee(int volume, uint8 *unixname, struct stat *stb, uint32 id)
|
||||
( (tru_get_eff_rights(volume, unixname, stb) & TRUSTEE_A)
|
||||
|| (act_id_flags&1)) ) {
|
||||
result=del_trustee_from_disk(volume, stb->st_dev, stb->st_ino, id);
|
||||
if (!result)
|
||||
if (!result) {
|
||||
tru_vol_sernum(volume, 1); /* trustee sernum needs updated */
|
||||
/* Trustee data changed on disk; cached effective rights are stale. */
|
||||
tru_free_cache(volume);
|
||||
}
|
||||
}
|
||||
MDEBUG(D_TRUSTEES, {
|
||||
xdprintf(1,0, "tru_del_trustee: id=%08lx, volume=%d, file=`%s`, result=-0x%x",
|
||||
@@ -677,6 +680,9 @@ int tru_add_trustee_set(int volume, uint8 *unixname,
|
||||
}
|
||||
(void)reseteuid();
|
||||
tru_vol_sernum(volume, 1); /* trustee sernum needs updated */
|
||||
/* local_tru_add_trustee_set() built/read the cache before writing the
|
||||
* new trustee entry. Drop it so the next user sees the new rights. */
|
||||
tru_free_cache(volume);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user