nwconn: route AFP access timestamps through atime
All checks were successful
Source release / source-package (push) Successful in 48s
All checks were successful
Source release / source-package (push) Successful in 48s
This commit is contained in:
67
src/nwconn.c
67
src/nwconn.c
@@ -35,6 +35,7 @@
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
#include <utime.h>
|
||||
#if !CALL_NWCONN_OVER_SOCKET
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
@@ -1114,6 +1115,7 @@ static void afp_leaf_name_from_path(uint8 *dst, int dst_len,
|
||||
}
|
||||
|
||||
#define AFP_FILE_BITMAP_ATTRIBUTES 0x0100
|
||||
#define AFP_FILE_BITMAP_ACCESS_DATE 0x0400
|
||||
#define AFP_FILE_BITMAP_CREATE_DATE 0x0800
|
||||
#define AFP_FILE_BITMAP_MODIFY_DATE 0x1000
|
||||
#define AFP_FILE_BITMAP_BACKUP_DATE 0x2000
|
||||
@@ -1358,6 +1360,28 @@ static int afp_check_metadata_modify_rights(int volume, char *unixname,
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static int afp_set_access_time(int volume, char *unixname, struct stat *stb,
|
||||
time_t new_atime)
|
||||
{
|
||||
struct utimbuf ut;
|
||||
|
||||
if (tru_eff_rights_exists(volume, (uint8 *)unixname, stb, TRUSTEE_M))
|
||||
return(-0x8c);
|
||||
|
||||
ut.actime = new_atime;
|
||||
ut.modtime = stb->st_mtime;
|
||||
if (!utime(unixname, &ut))
|
||||
return(0);
|
||||
if (seteuid(0)) {}
|
||||
if (!utime(unixname, &ut)) {
|
||||
(void)reseteuid();
|
||||
return(0);
|
||||
}
|
||||
(void)reseteuid();
|
||||
return(-0x8c);
|
||||
}
|
||||
|
||||
static int afp_set_file_information(uint8 *afp_req, int afp_len,
|
||||
const char *call_name)
|
||||
/*
|
||||
@@ -1366,12 +1390,13 @@ static int afp_set_file_information(uint8 *afp_req, int afp_len,
|
||||
* Netatalk's FPSetFileParams tests use the FinderInfo bitmap as a small,
|
||||
* metadata-only write probes. Mirror the safest slices for the NCP AFP
|
||||
* extension: accept the same path-backed VOL:-style smoke requests as Get File
|
||||
* Information, persist only the file attribute word, the file creation timestamp,
|
||||
* the file modification timestamp, and/or 32-byte FinderInfo block. Attributes are routed through the NetWare attribute path and FinderInfo data lives in
|
||||
* Information, persist only the file attribute word, the file access timestamp,
|
||||
* the file creation timestamp, the file modification timestamp, and/or
|
||||
* 32-byte FinderInfo block. Attributes are routed through the NetWare attribute path and FinderInfo data lives in
|
||||
* mars_nwe's private AFP xattr namespace; Create Date/Time reuses the existing
|
||||
* nwarchive fileinfo helper, while the modification timestamp is routed
|
||||
* through the existing NetWare timestamp helper so trustee Modify rights and
|
||||
* utime handling stay shared with the classic NCP paths. Reject all other
|
||||
* nwarchive fileinfo helper, while access and modification timestamps are
|
||||
* routed through the existing POSIX atime/mtime path with trustee Modify
|
||||
* rights enforced before utime(). Reject all other
|
||||
* bitmap bits until DOS attribute, resource-fork, and entry-id lookup
|
||||
* semantics are deliberately wired in.
|
||||
*/
|
||||
@@ -1386,6 +1411,7 @@ static int afp_set_file_information(uint8 *afp_req, int afp_len,
|
||||
struct stat stbuff;
|
||||
int result;
|
||||
uint16 log_attrs = 0;
|
||||
time_t log_atime = (time_t)-1;
|
||||
time_t log_mtime = (time_t)-1;
|
||||
int needs_afp_metadata_modify = 0;
|
||||
|
||||
@@ -1416,8 +1442,9 @@ static int afp_set_file_information(uint8 *afp_req, int afp_len,
|
||||
return(-0x9c); /* Invalid Path until persistent entry-id lookup exists */
|
||||
}
|
||||
|
||||
if (request_mask & ~(AFP_FILE_BITMAP_ATTRIBUTES | AFP_FILE_BITMAP_CREATE_DATE |
|
||||
AFP_FILE_BITMAP_MODIFY_DATE | AFP_FILE_BITMAP_BACKUP_DATE |
|
||||
if (request_mask & ~(AFP_FILE_BITMAP_ATTRIBUTES | AFP_FILE_BITMAP_ACCESS_DATE |
|
||||
AFP_FILE_BITMAP_CREATE_DATE | AFP_FILE_BITMAP_MODIFY_DATE |
|
||||
AFP_FILE_BITMAP_BACKUP_DATE |
|
||||
AFP_FILE_BITMAP_FINDER_INFO)) {
|
||||
XDPRINTF((2,0, "%s rejected: unsupported bitmap vol=%d entry=0x%08x mask=0x%04x path='%s'",
|
||||
call_name, (int)volume_number, request_entry_id, request_mask,
|
||||
@@ -1450,6 +1477,13 @@ static int afp_set_file_information(uint8 *afp_req, int afp_len,
|
||||
* the NetWare Modify-rights check. FinderInfo remains AFP metadata. */
|
||||
data_off += 2;
|
||||
}
|
||||
if ((request_mask & AFP_FILE_BITMAP_ACCESS_DATE) && afp_len < data_off + 4) {
|
||||
XDPRINTF((2,0, "%s rejected: short access timestamp data len=%d data_off=%d",
|
||||
call_name, afp_len, data_off));
|
||||
return(-0x7e);
|
||||
}
|
||||
if (request_mask & AFP_FILE_BITMAP_ACCESS_DATE)
|
||||
data_off += 4;
|
||||
if ((request_mask & AFP_FILE_BITMAP_CREATE_DATE) && afp_len < data_off + 4) {
|
||||
XDPRINTF((2,0, "%s rejected: short create timestamp data len=%d data_off=%d",
|
||||
call_name, afp_len, data_off));
|
||||
@@ -1529,6 +1563,20 @@ static int afp_set_file_information(uint8 *afp_req, int afp_len,
|
||||
}
|
||||
data_off += 2;
|
||||
}
|
||||
if (request_mask & AFP_FILE_BITMAP_ACCESS_DATE) {
|
||||
time_t new_atime = nw_2_un_time(afp_req + data_off, afp_req + data_off + 2);
|
||||
if (new_atime == (time_t)-1) {
|
||||
XDPRINTF((2,0, "%s rejected: invalid access timestamp path='%s'",
|
||||
call_name, visable_data(afp_req + 9, path_len)));
|
||||
return(-0x8c);
|
||||
}
|
||||
result = afp_set_access_time(path_volume, unixname, &stbuff, new_atime);
|
||||
if (result < 0)
|
||||
return(result);
|
||||
log_atime = new_atime;
|
||||
if (!stat(unixname, &stbuff)) {}
|
||||
data_off += 4;
|
||||
}
|
||||
if (request_mask & AFP_FILE_BITMAP_CREATE_DATE) {
|
||||
uint16 create_date = GET_BE16(afp_req + data_off);
|
||||
uint16 create_time = GET_BE16(afp_req + data_off + 2);
|
||||
@@ -1575,15 +1623,16 @@ static int afp_set_file_information(uint8 *afp_req, int afp_len,
|
||||
return(result);
|
||||
}
|
||||
|
||||
XDPRINTF((3,0, "%s: vol=%d request_vol=%d entry=0x%08x mask=0x%04x path='%s'%s%s%s attrs=0x%04x mtime=%ld",
|
||||
XDPRINTF((3,0, "%s: vol=%d request_vol=%d entry=0x%08x mask=0x%04x path='%s'%s%s%s%s%s attrs=0x%04x atime=%ld mtime=%ld",
|
||||
call_name, path_volume, (int)volume_number, request_entry_id,
|
||||
request_mask, visable_data(afp_req + 9, path_len),
|
||||
(request_mask & AFP_FILE_BITMAP_ATTRIBUTES) ? " attributes" : "",
|
||||
(request_mask & AFP_FILE_BITMAP_ACCESS_DATE) ? " access_time" : "",
|
||||
(request_mask & AFP_FILE_BITMAP_CREATE_DATE) ? " create_time" : "",
|
||||
(request_mask & AFP_FILE_BITMAP_MODIFY_DATE) ? " modify_time" : "",
|
||||
(request_mask & AFP_FILE_BITMAP_BACKUP_DATE) ? " backup_time" : "",
|
||||
(request_mask & AFP_FILE_BITMAP_FINDER_INFO) ? " finder_info" : "",
|
||||
log_attrs, (long)log_mtime));
|
||||
log_attrs, (long)log_atime, (long)log_mtime));
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user