s3: Remove is_ntfs_stream_name() and split_ntfs_stream_name()
authorTim Prouty <tprouty@samba.org>
Wed, 8 Jul 2009 21:08:04 +0000 (14:08 -0700)
committerTim Prouty <tprouty@samba.org>
Thu, 9 Jul 2009 04:36:04 +0000 (21:36 -0700)
Actually I moved split_ntfs_stream_name into torture.c which is the one
consumer of it.  This could probably be changed at some point.

source3/include/proto.h
source3/lib/util.c
source3/modules/onefs_streams.c
source3/modules/vfs_streams_xattr.c
source3/smbd/nttrans.c
source3/smbd/trans2.c
source3/torture/torture.c

index 471084c264b0adb5f69b23e10564b792cb18c1f6..aaedc15726a115d364890cc9672e6386bc0bd4ca 100644 (file)
@@ -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);
index 77af939f3774ad38eb17401661479921db18bd9e..835e4c00da7178106d89ad6b503301b8df00c6cf 100644 (file)
@@ -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;
index d33d9f30a2c5f602eef6370dc742084ff18f1850..ded7dc672d44e3e5d91ec1dfe5862d8848bd8f00 100644 (file)
 
 #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;
index 74b14ff93f534ac6a7ea822f00dc5ae8e54f9321..eccc2379c9b1eacd5d64956c677b4a78a8a16f6b 100644 (file)
@@ -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;
        }
index e28e6f3a84365f392ae2be6fc385abd7c04ee498..b65af26ecaf570cf6f1efcaf70eaeab92667a2d1 100644 (file)
@@ -271,53 +271,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.
  ***************************************************************************/
@@ -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;
index 62280ddde03d558383fb258b6337d8069aaccc32..f22700deaa2f555a2854d2bad07a360b14f93409 100644 (file)
@@ -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;
                }
 
index 012f8939c5bd7fda91716fedbc195b103be93f07..aa7e83bcc83c3387b18d8b2d797e287863bfe3ba 100644 (file)
@@ -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)