nwnss: enable OtherFS XATTR smoke roundtrip
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/xattr.h>
|
||||
|
||||
#include <lsa/lsaPrivate.h>
|
||||
|
||||
@@ -119,25 +120,62 @@ NssLsaXattrUserspaceInodePrivate(struct inode *inode)
|
||||
return inode ? (LsaInode_s *)inode->i_private : NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
NssLsaXattrUserspaceOtherfsPath(const NssLsaXattrUserspace_s *xattr)
|
||||
{
|
||||
const char *path;
|
||||
|
||||
path = NssUserspaceProviderPath(xattr ? &xattr->provider : NULL);
|
||||
return path && path[0] != '\0' ? path : NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
NssLsaXattrUserspaceOtherfsHostName(const char *name,
|
||||
char *buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
return NssLsaXattrUserspaceOtherfsName(name, buffer, bufferSize);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
NssLsaXattrUserspaceGet(NssLsaXattrUserspace_s *xattr,
|
||||
const char *name,
|
||||
void *value,
|
||||
size_t size)
|
||||
{
|
||||
char hostName[256];
|
||||
const char *path;
|
||||
ssize_t result;
|
||||
|
||||
if (!xattr || !name)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
if (NssLsaXattrUserspaceGetProvider(xattr) !=
|
||||
NSS_USERSPACE_PROVIDER_NSS_VOLUME)
|
||||
switch (NssLsaXattrUserspaceGetProvider(xattr))
|
||||
{
|
||||
return -ENOTSUP;
|
||||
case NSS_USERSPACE_PROVIDER_NSS_VOLUME:
|
||||
return netware_getxattr(NssLsaXattrUserspaceDentry(xattr),
|
||||
NssLsaXattrUserspaceNssName(name),
|
||||
value,
|
||||
size);
|
||||
case NSS_USERSPACE_PROVIDER_OTHERFS_XATTR:
|
||||
path = NssLsaXattrUserspaceOtherfsPath(xattr);
|
||||
if (!path)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
result = NssLsaXattrUserspaceOtherfsHostName(name,
|
||||
hostName,
|
||||
sizeof(hostName));
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = getxattr(path, hostName, value, size);
|
||||
return result < 0 ? -errno : result;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return netware_getxattr(NssLsaXattrUserspaceDentry(xattr),
|
||||
NssLsaXattrUserspaceNssName(name),
|
||||
value,
|
||||
size);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
@@ -146,36 +184,76 @@ NssLsaXattrUserspaceSet(NssLsaXattrUserspace_s *xattr,
|
||||
const void *value,
|
||||
size_t size)
|
||||
{
|
||||
char hostName[256];
|
||||
const char *path;
|
||||
int result;
|
||||
|
||||
if (!xattr || !name)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
if (NssLsaXattrUserspaceGetProvider(xattr) !=
|
||||
NSS_USERSPACE_PROVIDER_NSS_VOLUME)
|
||||
switch (NssLsaXattrUserspaceGetProvider(xattr))
|
||||
{
|
||||
return -ENOTSUP;
|
||||
case NSS_USERSPACE_PROVIDER_NSS_VOLUME:
|
||||
return netware_setxattr(NssLsaXattrUserspaceDentry(xattr),
|
||||
NssLsaXattrUserspaceNssName(name),
|
||||
value,
|
||||
size);
|
||||
case NSS_USERSPACE_PROVIDER_OTHERFS_XATTR:
|
||||
path = NssLsaXattrUserspaceOtherfsPath(xattr);
|
||||
if (!path)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
result = NssLsaXattrUserspaceOtherfsHostName(name,
|
||||
hostName,
|
||||
sizeof(hostName));
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = setxattr(path, hostName, value, size, 0);
|
||||
return result < 0 ? -errno : result;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return netware_setxattr(NssLsaXattrUserspaceDentry(xattr),
|
||||
NssLsaXattrUserspaceNssName(name),
|
||||
value,
|
||||
size);
|
||||
}
|
||||
|
||||
int
|
||||
NssLsaXattrUserspaceRemove(NssLsaXattrUserspace_s *xattr,
|
||||
const char *name)
|
||||
{
|
||||
char hostName[256];
|
||||
const char *path;
|
||||
int result;
|
||||
|
||||
if (!xattr || !name)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
if (NssLsaXattrUserspaceGetProvider(xattr) !=
|
||||
NSS_USERSPACE_PROVIDER_NSS_VOLUME)
|
||||
switch (NssLsaXattrUserspaceGetProvider(xattr))
|
||||
{
|
||||
return -ENOTSUP;
|
||||
case NSS_USERSPACE_PROVIDER_NSS_VOLUME:
|
||||
return netware_removexattr(NssLsaXattrUserspaceDentry(xattr),
|
||||
NssLsaXattrUserspaceNssName(name));
|
||||
case NSS_USERSPACE_PROVIDER_OTHERFS_XATTR:
|
||||
path = NssLsaXattrUserspaceOtherfsPath(xattr);
|
||||
if (!path)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
result = NssLsaXattrUserspaceOtherfsHostName(name,
|
||||
hostName,
|
||||
sizeof(hostName));
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = removexattr(path, hostName);
|
||||
return result < 0 ? -errno : result;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return netware_removexattr(NssLsaXattrUserspaceDentry(xattr),
|
||||
NssLsaXattrUserspaceNssName(name));
|
||||
}
|
||||
|
||||
#endif /* NSS_USERSPACE */
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
add_executable(test_nwnss_xattr test_nwnss_xattr.c)
|
||||
target_link_libraries(test_nwnss_xattr PRIVATE mars_nwe::nwnss)
|
||||
add_test(NAME nwnss.xattr COMMAND test_nwnss_xattr)
|
||||
set_tests_properties(nwnss.xattr PROPERTIES SKIP_RETURN_CODE 77)
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define CHECK(expr) \
|
||||
do { \
|
||||
@@ -13,12 +16,103 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SKIP_CODE 77
|
||||
|
||||
static int is_xattr_unsupported(int err)
|
||||
{
|
||||
return err == -ENOTSUP || err == -EOPNOTSUPP || err == -ENOSYS ||
|
||||
err == -EPERM || err == -EACCES;
|
||||
}
|
||||
|
||||
static int make_temp_file(char *path, size_t pathSize)
|
||||
{
|
||||
const char *tmpdir;
|
||||
int fd;
|
||||
|
||||
tmpdir = getenv("TMPDIR");
|
||||
if (!tmpdir || tmpdir[0] == '\0')
|
||||
{
|
||||
tmpdir = ".";
|
||||
}
|
||||
if (snprintf(path, pathSize, "%s/nwnss-xattr-XXXXXX", tmpdir) < 0 ||
|
||||
strlen(path) >= pathSize)
|
||||
{
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
fd = mkstemp(path);
|
||||
if (fd < 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_otherfs_roundtrip(NssLsaXattrUserspace_s *xattr,
|
||||
const char *nssName,
|
||||
const char *expectedHostName,
|
||||
const char *payload)
|
||||
{
|
||||
char hostName[128];
|
||||
char hostValue[128];
|
||||
char nssValue[128];
|
||||
ssize_t got;
|
||||
ssize_t result;
|
||||
|
||||
CHECK(NssLsaXattrUserspaceOtherfsName(nssName,
|
||||
hostName,
|
||||
sizeof(hostName)) == 0);
|
||||
CHECK(strcmp(hostName, expectedHostName) == 0);
|
||||
|
||||
result = NssLsaXattrUserspaceSet(xattr,
|
||||
nssName,
|
||||
payload,
|
||||
strlen(payload));
|
||||
if (is_xattr_unsupported((int)result))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"SKIP/WARN: host filesystem does not allow user xattrs on test file\n");
|
||||
return SKIP_CODE;
|
||||
}
|
||||
CHECK(result == 0);
|
||||
|
||||
memset(hostValue, 0, sizeof(hostValue));
|
||||
got = getxattr(NssUserspaceProviderPath(NssLsaXattrUserspaceProvider(xattr)),
|
||||
expectedHostName,
|
||||
hostValue,
|
||||
sizeof(hostValue));
|
||||
CHECK(got == (ssize_t)strlen(payload));
|
||||
CHECK(memcmp(hostValue, payload, strlen(payload)) == 0);
|
||||
|
||||
memset(nssValue, 0, sizeof(nssValue));
|
||||
got = NssLsaXattrUserspaceGet(xattr,
|
||||
nssName,
|
||||
nssValue,
|
||||
sizeof(nssValue));
|
||||
CHECK(got == (ssize_t)strlen(payload));
|
||||
CHECK(memcmp(nssValue, payload, strlen(payload)) == 0);
|
||||
|
||||
got = NssLsaXattrUserspaceGet(xattr, nssName, NULL, 0);
|
||||
CHECK(got == (ssize_t)strlen(payload));
|
||||
|
||||
CHECK(NssLsaXattrUserspaceRemove(xattr, nssName) == 0);
|
||||
got = getxattr(NssUserspaceProviderPath(NssLsaXattrUserspaceProvider(xattr)),
|
||||
expectedHostName,
|
||||
hostValue,
|
||||
sizeof(hostValue));
|
||||
CHECK(got < 0 && errno == ENODATA);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
NssUserspaceProvider_s provider;
|
||||
NssLsaXattrUserspace_s xattr;
|
||||
VolumeID_t volumeId;
|
||||
char hostName[128];
|
||||
char tempPath[4096];
|
||||
int result;
|
||||
|
||||
NssUserspaceProviderInit(&provider);
|
||||
CHECK(NssUserspaceProviderGetKind(&provider) == NSS_USERSPACE_PROVIDER_UNSET);
|
||||
@@ -65,17 +159,49 @@ int main(void)
|
||||
CHECK(strcmp(NssLsaXattrUserspaceNssName("netware.metadata"),
|
||||
"metadata") == 0);
|
||||
|
||||
CHECK(NssLsaXattrUserspaceInitOtherfsPath(&xattr, ".") == 0);
|
||||
CHECK(make_temp_file(tempPath, sizeof(tempPath)) == 0);
|
||||
result = NssLsaXattrUserspaceInitOtherfsPath(&xattr, tempPath);
|
||||
if (result != 0)
|
||||
{
|
||||
unlink(tempPath);
|
||||
CHECK(result == 0);
|
||||
}
|
||||
CHECK(NssLsaXattrUserspaceGetProvider(&xattr) ==
|
||||
NSS_USERSPACE_PROVIDER_OTHERFS_XATTR);
|
||||
CHECK(NssLsaXattrUserspaceOtherfsName("netware.trustees",
|
||||
hostName,
|
||||
sizeof(hostName)) == 0);
|
||||
hostName,
|
||||
sizeof(hostName)) == 0);
|
||||
CHECK(strcmp(hostName, "user.netware.trustees") == 0);
|
||||
CHECK(NssLsaXattrUserspaceGet(&xattr,
|
||||
"netware.metadata",
|
||||
NULL,
|
||||
0) == -ENOTSUP);
|
||||
|
||||
result = check_otherfs_roundtrip(&xattr,
|
||||
"netware.metadata",
|
||||
"user.netware.metadata",
|
||||
"metadata:v1;rights=rwcemf");
|
||||
if (result == SKIP_CODE)
|
||||
{
|
||||
unlink(tempPath);
|
||||
return SKIP_CODE;
|
||||
}
|
||||
CHECK(result == 0);
|
||||
|
||||
result = check_otherfs_roundtrip(&xattr,
|
||||
"metadata",
|
||||
"user.netware.metadata",
|
||||
"metadata:v2;name=short");
|
||||
CHECK(result == 0);
|
||||
|
||||
result = check_otherfs_roundtrip(&xattr,
|
||||
"user.netware.metadata",
|
||||
"user.netware.metadata",
|
||||
"metadata:v3;direct-host-name");
|
||||
CHECK(result == 0);
|
||||
|
||||
result = check_otherfs_roundtrip(&xattr,
|
||||
"netware.trustees",
|
||||
"user.netware.trustees",
|
||||
"trustee:1001:RWCEMF");
|
||||
CHECK(result == 0);
|
||||
|
||||
unlink(tempPath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user