mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
Add "split_ntfs_stream_name()" together with a torture test
(This used to be commit d813bd9e02d9baf916eb96c478be89f0c435e07c)
This commit is contained in:
parent
14e7c292bc
commit
2411c6cb90
@ -3273,3 +3273,93 @@ void *talloc_zeronull(const void *context, size_t size, const char *name)
|
||||
return talloc_named_const(context, size, name);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Split a path name into filename and stream name components. Canonicalise
|
||||
* such that an implicit $DATA token is always explicit.
|
||||
*
|
||||
* The "specification" of this function can be found in the
|
||||
* run_local_stream_name() function in torture.c, I've tried those
|
||||
* combinations against a W2k3 server.
|
||||
*/
|
||||
|
||||
NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
|
||||
char **pbase, char **pstream)
|
||||
{
|
||||
char *base = NULL;
|
||||
char *stream = NULL;
|
||||
char *sname; /* stream name */
|
||||
const char *stype; /* stream type */
|
||||
|
||||
DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
|
||||
|
||||
sname = strchr_m(fname, ':');
|
||||
|
||||
if (lp_posix_pathnames() || (sname == NULL)) {
|
||||
if (pbase != NULL) {
|
||||
base = talloc_strdup(mem_ctx, fname);
|
||||
NT_STATUS_HAVE_NO_MEMORY(base);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (pbase != NULL) {
|
||||
base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
|
||||
NT_STATUS_HAVE_NO_MEMORY(base);
|
||||
}
|
||||
|
||||
sname += 1;
|
||||
|
||||
stype = strchr_m(sname, ':');
|
||||
|
||||
if (stype == NULL) {
|
||||
sname = talloc_strdup(mem_ctx, sname);
|
||||
stype = "$DATA";
|
||||
}
|
||||
else {
|
||||
if (StrCaseCmp(stype, ":$DATA") != 0) {
|
||||
/*
|
||||
* If there is an explicit stream type, so far we only
|
||||
* allow $DATA. Is there anything else allowed? -- vl
|
||||
*/
|
||||
DEBUG(10, ("[%s] is an invalid stream type\n", stype));
|
||||
TALLOC_FREE(base);
|
||||
return NT_STATUS_OBJECT_NAME_INVALID;
|
||||
}
|
||||
sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
|
||||
stype += 1;
|
||||
}
|
||||
|
||||
if (sname == NULL) {
|
||||
TALLOC_FREE(base);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (sname[0] == '\0') {
|
||||
/*
|
||||
* no stream name, so no stream
|
||||
*/
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (pstream != NULL) {
|
||||
stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
|
||||
if (stream == NULL) {
|
||||
TALLOC_FREE(sname);
|
||||
TALLOC_FREE(base);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
/*
|
||||
* upper-case the type field
|
||||
*/
|
||||
strupper_m(strchr_m(stream, ':')+1);
|
||||
}
|
||||
|
||||
done:
|
||||
if (pbase != NULL) {
|
||||
*pbase = base;
|
||||
}
|
||||
if (pstream != NULL) {
|
||||
*pstream = stream;
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
@ -271,6 +271,9 @@ void send_nt_replies(connection_struct *conn,
|
||||
|
||||
/****************************************************************************
|
||||
Is it an NTFS stream name ?
|
||||
An NTFS file name is <path>.<extention>:<stream name>:<stream type>
|
||||
$DATA can be used as both a stream name and a stream type. A missing stream
|
||||
name or type implies $DATA.
|
||||
****************************************************************************/
|
||||
|
||||
bool is_ntfs_stream_name(const char *fname)
|
||||
|
@ -5098,6 +5098,74 @@ static bool run_local_rbtree(int dummy)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool test_stream_name(const char *fname, const char *expected_base,
|
||||
const char *expected_stream,
|
||||
NTSTATUS expected_status)
|
||||
{
|
||||
NTSTATUS status;
|
||||
char *base = NULL;
|
||||
char *stream = NULL;
|
||||
|
||||
status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
|
||||
if (!NT_STATUS_EQUAL(status, expected_status)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (base == NULL) goto error;
|
||||
|
||||
if (strcmp(expected_base, base) != 0) goto error;
|
||||
|
||||
if ((expected_stream != NULL) && (stream == NULL)) goto error;
|
||||
if ((expected_stream == NULL) && (stream != NULL)) goto error;
|
||||
|
||||
if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
|
||||
goto error;
|
||||
|
||||
TALLOC_FREE(base);
|
||||
TALLOC_FREE(stream);
|
||||
return true;
|
||||
|
||||
error:
|
||||
d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
|
||||
fname, expected_base ? expected_base : "<NULL>",
|
||||
expected_stream ? expected_stream : "<NULL>",
|
||||
nt_errstr(expected_status));
|
||||
d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
|
||||
base ? base : "<NULL>", stream ? stream : "<NULL>",
|
||||
nt_errstr(status));
|
||||
TALLOC_FREE(base);
|
||||
TALLOC_FREE(stream);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool run_local_stream_name(int dummy)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
ret &= test_stream_name(
|
||||
"bla", "bla", NULL, NT_STATUS_OK);
|
||||
ret &= test_stream_name(
|
||||
"bla::$DATA", "bla", NULL, NT_STATUS_OK);
|
||||
ret &= test_stream_name(
|
||||
"bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
|
||||
ret &= test_stream_name(
|
||||
"bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
|
||||
ret &= test_stream_name(
|
||||
"bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
|
||||
ret &= test_stream_name(
|
||||
"bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
|
||||
ret &= test_stream_name(
|
||||
"bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
|
||||
ret &= test_stream_name(
|
||||
"bla:x", "bla", "x:$DATA", NT_STATUS_OK);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
|
||||
{
|
||||
if (a.length != b.length) {
|
||||
@ -5328,6 +5396,7 @@ static struct {
|
||||
{ "LOCAL-GENCACHE", run_local_gencache, 0},
|
||||
{ "LOCAL-RBTREE", run_local_rbtree, 0},
|
||||
{ "LOCAL-MEMCACHE", run_local_memcache, 0},
|
||||
{ "LOCAL-STREAM-NAME", run_local_stream_name, 0},
|
||||
{NULL, NULL, 0}};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user