nwconn: derive AFP access privileges from trustees
All checks were successful
Source release / source-package (push) Successful in 47s
All checks were successful
Source release / source-package (push) Successful in 47s
This commit is contained in:
55
src/nwconn.c
55
src/nwconn.c
@@ -1150,11 +1150,56 @@ static uint16 afp_basic_attributes(int volume, const char *unixname, const struc
|
||||
return(attributes);
|
||||
}
|
||||
|
||||
static uint16 afp_basic_access_privileges(const struct stat *stb)
|
||||
#define AFP_PRIV_READ 0x0100
|
||||
#define AFP_PRIV_WRITE 0x0200
|
||||
#define AFP_PRIV_OPEN 0x0400
|
||||
#define AFP_PRIV_CREATE 0x0800
|
||||
#define AFP_PRIV_DELETE 0x1000
|
||||
#define AFP_PRIV_PARENTAL 0x2000
|
||||
#define AFP_PRIV_SEARCH 0x4000
|
||||
#define AFP_PRIV_MODIFY_ATTRS 0x8000
|
||||
|
||||
static uint16 afp_access_privileges(int volume, const char *unixname,
|
||||
const struct stat *stb)
|
||||
{
|
||||
if (S_ISDIR(stb->st_mode))
|
||||
return(0x4000 | 0x2000 | 0x8000); /* search, parental, modify attrs */
|
||||
return(0x0100 | 0x0200 | 0x0400 | 0x1000 | 0x8000); /* rw open delete modify */
|
||||
int rights;
|
||||
uint16 privileges = 0;
|
||||
|
||||
rights = tru_get_eff_rights(volume, (uint8 *)unixname, (struct stat *)stb);
|
||||
if (rights < 0)
|
||||
return(0);
|
||||
|
||||
if (rights & TRUSTEE_S)
|
||||
rights |= TRUSTEE_R | TRUSTEE_W | TRUSTEE_O | TRUSTEE_C |
|
||||
TRUSTEE_E | TRUSTEE_A | TRUSTEE_F | TRUSTEE_M;
|
||||
|
||||
if (S_ISDIR(stb->st_mode)) {
|
||||
if (rights & (TRUSTEE_C | TRUSTEE_E | TRUSTEE_M))
|
||||
privileges |= AFP_PRIV_PARENTAL;
|
||||
if (rights & TRUSTEE_F)
|
||||
privileges |= AFP_PRIV_SEARCH;
|
||||
if (rights & TRUSTEE_M)
|
||||
privileges |= AFP_PRIV_MODIFY_ATTRS;
|
||||
return(privileges);
|
||||
}
|
||||
|
||||
if (rights & TRUSTEE_R)
|
||||
privileges |= AFP_PRIV_READ;
|
||||
if (rights & TRUSTEE_W)
|
||||
privileges |= AFP_PRIV_WRITE;
|
||||
if (rights & TRUSTEE_O)
|
||||
privileges |= AFP_PRIV_OPEN;
|
||||
if (rights & TRUSTEE_C)
|
||||
privileges |= AFP_PRIV_CREATE;
|
||||
if (rights & TRUSTEE_E)
|
||||
privileges |= AFP_PRIV_DELETE;
|
||||
if (rights & TRUSTEE_M)
|
||||
privileges |= AFP_PRIV_MODIFY_ATTRS;
|
||||
|
||||
if (get_nw_attrib_dword(volume, (char *)unixname, (struct stat *)stb) & FILE_ATTR_R)
|
||||
privileges &= ~(AFP_PRIV_WRITE | AFP_PRIV_DELETE);
|
||||
|
||||
return(privileges);
|
||||
}
|
||||
|
||||
static uint16 afp_count_offspring(const char *unixname, const struct stat *stb)
|
||||
@@ -1246,7 +1291,7 @@ static int afp_fill_file_info_response(const char *unixname,
|
||||
afp_leaf_name_from_path(response + 64, 32, display_path, display_path_len);
|
||||
U32_TO_BE32(get_file_owner(&stbuff), response + 96);
|
||||
afp_leaf_name_from_path(response + 100, 12, display_path, display_path_len);
|
||||
U16_TO_BE16(afp_basic_access_privileges(&stbuff), response + 112);
|
||||
U16_TO_BE16(afp_access_privileges(volume, unixname, &stbuff), response + 112);
|
||||
/* ProDOS info at offset 114 stays zero until a real Mac namespace maps it. */
|
||||
|
||||
if (entry_id_out) *entry_id_out = entry_id;
|
||||
|
||||
@@ -30,7 +30,7 @@ static void usage(const char *prog)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s [--afp20] [--allow-invalid-namespace] [--allow-invalid-path] "
|
||||
"[--volume N] [--entry-id ID] [--request-mask MASK] [ncpfs options] PATH\n"
|
||||
"[--volume N] [--entry-id ID] [--request-mask MASK] [--expect-rights-set MASK] [--expect-rights-clear MASK] [ncpfs options] PATH\n"
|
||||
"\n"
|
||||
"ncpfs options are parsed by ncp_initialize(), for example:\n"
|
||||
" -S SERVER -U USER -P PASSWORD -n\n"
|
||||
@@ -106,6 +106,8 @@ int main(int argc, char **argv)
|
||||
uint32_t volume_number = 0;
|
||||
uint32_t entry_id = 0;
|
||||
uint32_t request_mask = AFP_GET_ALL;
|
||||
uint32_t expect_rights_set = 0;
|
||||
uint32_t expect_rights_clear = 0;
|
||||
uint32_t afp_subfunction = AFP_GET_FILE_INFORMATION;
|
||||
int i;
|
||||
size_t path_len;
|
||||
@@ -152,6 +154,18 @@ int main(int argc, char **argv)
|
||||
ncp_close(conn);
|
||||
return 2;
|
||||
}
|
||||
} else if (!strcmp(argv[i], "--expect-rights-set")) {
|
||||
if (++i >= argc || parse_u32(argv[i], &expect_rights_set) || expect_rights_set > 0xffff) {
|
||||
fprintf(stderr, "invalid --expect-rights-set value\n");
|
||||
ncp_close(conn);
|
||||
return 2;
|
||||
}
|
||||
} else if (!strcmp(argv[i], "--expect-rights-clear")) {
|
||||
if (++i >= argc || parse_u32(argv[i], &expect_rights_clear) || expect_rights_clear > 0xffff) {
|
||||
fprintf(stderr, "invalid --expect-rights-clear value\n");
|
||||
ncp_close(conn);
|
||||
return 2;
|
||||
}
|
||||
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
|
||||
usage(argv[0]);
|
||||
ncp_close(conn);
|
||||
@@ -226,6 +240,21 @@ int main(int argc, char **argv)
|
||||
copy_fixed_string(long_name, sizeof(long_name), reply_buf + 64, 32);
|
||||
copy_fixed_string(short_name, sizeof(short_name), reply_buf + 100, 12);
|
||||
|
||||
if (expect_rights_set &&
|
||||
(be16_to_cpu(reply_buf + 112) & expect_rights_set) != expect_rights_set) {
|
||||
fprintf(stderr, "AFP File Info rights missing expected bits: rights=0x%04x expected_set=0x%04x path=%s\n",
|
||||
be16_to_cpu(reply_buf + 112), (unsigned int)expect_rights_set, path);
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
if (expect_rights_clear &&
|
||||
(be16_to_cpu(reply_buf + 112) & expect_rights_clear) != 0) {
|
||||
fprintf(stderr, "AFP File Info rights has unexpected bits: rights=0x%04x expected_clear=0x%04x path=%s\n",
|
||||
be16_to_cpu(reply_buf + 112), (unsigned int)expect_rights_clear, path);
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("AFP File Info subfunction=0x%02x path=%s entry_id=0x%08x parent_id=0x%08x attrs=0x%04x "
|
||||
"data_len=%u resource_len=%u offspring=%u long_name=%s short_name=%s rights=0x%04x\n",
|
||||
(unsigned int)afp_subfunction,
|
||||
|
||||
@@ -418,6 +418,12 @@ if [ -n "$READONLY_USER" ]; then
|
||||
READONLY_AUTH_ARGS=(-P "$READONLY_PASSWORD")
|
||||
fi
|
||||
|
||||
run_cmd \
|
||||
"AFP Get File Information readonly rights" \
|
||||
"./afp_file_info_smoke --expect-rights-set 0x0100 --expect-rights-clear 0x9200 $READONLY_PRINT '$NETWARE_PATH'" \
|
||||
"$SCRIPT_DIR/afp_file_info_smoke" --expect-rights-set 0x0100 --expect-rights-clear 0x9200 \
|
||||
-S "$SERVER" -U "$READONLY_USER" "${READONLY_AUTH_ARGS[@]}" "$NETWARE_PATH"
|
||||
|
||||
run_cmd \
|
||||
"AFP metadata Modify rights rejected: FinderInfo" \
|
||||
"./afp_set_file_info_smoke --expect-completion 0x8c $READONLY_PRINT --finder-info-only --type '$FINDER_TYPE' --creator '$FINDER_CREATOR' '$NETWARE_PATH'" \
|
||||
|
||||
Reference in New Issue
Block a user