summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/include/proto.h3
-rw-r--r--source3/lib/util.c90
-rw-r--r--source3/modules/onefs_streams.c48
-rw-r--r--source3/modules/vfs_streams_xattr.c21
-rw-r--r--source3/smbd/nttrans.c49
-rw-r--r--source3/smbd/trans2.c3
-rw-r--r--source3/torture/torture.c90
7 files changed, 105 insertions, 199 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 471084c264..aaedc15726 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1202,8 +1202,6 @@ void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const c
void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name);
void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name);
void *talloc_zeronull(const void *context, size_t size, const char *name);
-NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
- char **pbase, char **pstream);
bool is_valid_policy_hnd(const struct policy_handle *hnd);
bool policy_hnd_equal(const struct policy_handle *hnd1,
const struct policy_handle *hnd2);
@@ -6548,7 +6546,6 @@ void send_nt_replies(connection_struct *conn,
struct smb_request *req, NTSTATUS nt_error,
char *params, int paramsize,
char *pdata, int datasize);
-bool is_ntfs_stream_name(const char *fname);
bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname);
bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname);
void reply_ntcreate_and_X(struct smb_request *req);
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 77af939f37..835e4c00da 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -3001,96 +3001,6 @@ void *talloc_zeronull(const void *context, size_t size, const char *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;
-}
-
bool is_valid_policy_hnd(const struct policy_handle *hnd)
{
struct policy_handle tmp;
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index d33d9f30a2..ded7dc672d 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -25,35 +25,6 @@
#include <sys/isi_enc.h>
-/*
- * OneFS stores streams without the explicit :$DATA at the end, so this strips
- * it off. All onefs_stream functions must call through this instead of
- * split_ntfs_stream_name directly.
- */
-NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
- char **pbase, char **pstream)
-{
- NTSTATUS status;
- char *stream;
-
- status = split_ntfs_stream_name(mem_ctx, fname, pbase, pstream);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- /* Default $DATA stream. */
- if (pstream == NULL || *pstream == NULL) {
- return NT_STATUS_OK;
- }
-
- /* Strip off the $DATA. */
- stream = strrchr_m(*pstream, ':');
- SMB_ASSERT(stream);
- stream[0] = '\0';
-
- return NT_STATUS_OK;
-}
-
NTSTATUS onefs_stream_prep_smb_fname(TALLOC_CTX *ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **smb_fname_out)
@@ -100,25 +71,6 @@ NTSTATUS onefs_stream_prep_smb_fname(TALLOC_CTX *ctx,
return status;
}
-int onefs_is_stream(const char *path, char **pbase, char **pstream,
- bool *is_stream)
-{
- (*is_stream) = is_ntfs_stream_name(path);
-
- if (!(*is_stream)) {
- return 0;
- }
-
- if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path,
- pbase, pstream))) {
- DEBUG(10, ("onefs_split_ntfs_stream_name failed\n"));
- errno = ENOMEM;
- return -1;
- }
-
- return 0;
-}
-
int onefs_close(vfs_handle_struct *handle, struct files_struct *fsp)
{
int ret2, ret = 0;
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index 74b14ff93f..eccc2379c9 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -128,29 +128,29 @@ static NTSTATUS streams_xattr_get_name(TALLOC_CTX *ctx,
static bool streams_xattr_recheck(struct stream_io *sio)
{
NTSTATUS status;
- char *base = NULL;
- char *sname = NULL;
+ struct smb_filename *smb_fname = NULL;
char *xattr_name = NULL;
if (sio->fsp->fsp_name == sio->fsp_name_ptr) {
return true;
}
- status = split_ntfs_stream_name(talloc_tos(), sio->fsp->fsp_name,
- &base, &sname);
+ status = create_synthetic_smb_fname_split(talloc_tos(),
+ sio->fsp->fsp_name, NULL,
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
return false;
}
- if (sname == NULL) {
+ if (smb_fname->stream_name == NULL) {
/* how can this happen */
errno = EINVAL;
return false;
}
- xattr_name = talloc_asprintf(talloc_tos(), "%s%s",
- SAMBA_XATTR_DOSSTREAM_PREFIX, sname);
- if (xattr_name == NULL) {
+ status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name,
+ &xattr_name);
+ if (!NT_STATUS_IS_OK(status)) {
return false;
}
@@ -159,9 +159,12 @@ static bool streams_xattr_recheck(struct stream_io *sio)
sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp),
xattr_name);
sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp),
- base);
+ smb_fname->base_name);
sio->fsp_name_ptr = sio->fsp->fsp_name;
+ TALLOC_FREE(smb_fname);
+ TALLOC_FREE(xattr_name);
+
if ((sio->xattr_name == NULL) || (sio->base == NULL)) {
return false;
}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index e28e6f3a84..b65af26eca 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -272,53 +272,6 @@ 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.
-
- Both Windows stream names and POSIX files can contain the ':' character.
- This function first checks for the existence of a colon in the last component
- of the given name. If the name contains a colon we differentiate between a
- stream and POSIX file by checking if the latter exists through a POSIX stat.
-
- Function assumes we've already chdir() to the "root" directory of fname.
-****************************************************************************/
-
-bool is_ntfs_stream_name(const char *fname)
-{
- const char *lastcomp;
- SMB_STRUCT_STAT sbuf;
-
- /* If all pathnames are treated as POSIX we ignore streams. */
- if (lp_posix_pathnames()) {
- return false;
- }
-
- /* Find the last component of the name. */
- if ((lastcomp = strrchr_m(fname, '/')) != NULL)
- ++lastcomp;
- else
- lastcomp = fname;
-
- /* If there is no colon in the last component, it's not a stream. */
- if (strchr_m(lastcomp, ':') == NULL)
- return false;
-
- /*
- * If file already exists on disk, it's not a stream. The stat must
- * bypass the vfs layer so streams modules don't intefere.
- */
- if (sys_stat(fname, &sbuf) == 0) {
- DEBUG(5, ("is_ntfs_stream_name: file %s contains a ':' but is "
- "not a stream\n", fname));
- return false;
- }
-
- return true;
-}
-
-/****************************************************************************
Simple check to determine if the filename is a stream.
***************************************************************************/
bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname)
@@ -1454,7 +1407,7 @@ void reply_ntrename(struct smb_request *req)
}
/* The new name must begin with a ':' if the old name is a stream. */
- if (is_ntfs_stream_name(oldname) && (newname[0] != ':')) {
+ if (is_ntfs_stream_smb_fname(smb_fname_old) && (newname[0] != ':')) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBntrename);
return;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 62280ddde0..f22700deaa 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1421,6 +1421,7 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(fname);
+ return false;
}
if (INFO_LEVEL_IS_UNIX(info_level)) {
@@ -5554,7 +5555,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
}
} else {
/* newname must *not* be a stream name. */
- if (is_ntfs_stream_name(newname)) {
+ if (newname[0] == ':') {
return NT_STATUS_NOT_SUPPORTED;
}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 012f8939c5..aa7e83bcc8 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -5939,6 +5939,96 @@ static bool run_local_rbtree(int dummy)
return ret;
}
+/* 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.
+ */
+
+static 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;
+}
+
static bool test_stream_name(const char *fname, const char *expected_base,
const char *expected_stream,
NTSTATUS expected_status)