Merge branch 'master' of ssh://git.samba.org/data/git/samba
authorJelmer Vernooij <jelmer@samba.org>
Mon, 5 Jan 2009 13:02:30 +0000 (14:02 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Mon, 5 Jan 2009 13:02:30 +0000 (14:02 +0100)
13 files changed:
lib/tevent/tevent.h
source3/include/vfs_macros.h
source3/modules/vfs_full_audit.c
source3/modules/vfs_streams_depot.c
source3/modules/vfs_streams_xattr.c
source3/smbd/nttrans.c
source3/smbd/reply.c
source3/smbd/service.c
source4/lib/ldb/pyldb.c
source4/scripting/python/samba/provision.py
source4/setup/schema-map-openldap-2.3
source4/setup/schema_samba4.ldif
source4/torture/raw/streams.c

index b57d96f5fb99eb42b9b7414cd73ac28fcc0c6913..98d31aa7c4c4dad95157415a6993b448e7f415a7 100644 (file)
@@ -82,7 +82,7 @@ struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
                                       const char *location);
 #define tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) \
        _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \
-                         #handler, __location__);
+                         #handler, __location__)
 
 struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
                                         TALLOC_CTX *mem_ctx,
@@ -106,7 +106,7 @@ struct tevent_aio *_tevent_add_aio(struct tevent_context *ev,
                                   const char *location);
 #define tevent_add_aio(ev, mem_ctx, iocb, handler, private_data) \
        _tevent_add_aio(ev, mem_ctx, iocb, handler, private_data, \
-                       #handler, __location__);
+                       #handler, __location__)
 
 int tevent_loop_once(struct tevent_context *ev);
 int tevent_loop_wait(struct tevent_context *ev);
index b008d86b3ca624f716356babc1b1ac0f2fbfa566..c6ccd4912a1ec576af0f13515ceec35a26661780 100644 (file)
 #define SMB_VFS_NEXT_CHFLAGS(handle, path, flags) ((handle)->vfs_next.ops.chflags((handle)->vfs_next.handles.chflags, (path), (flags)))
 #define SMB_VFS_NEXT_FILE_ID_CREATE(handle, dev, inode) ((handle)->vfs_next.ops.file_id_create((handle)->vfs_next.handles.file_id_create, (dev), (inode)))
 #define SMB_VFS_NEXT_STREAMINFO(handle, fsp, fname, mem_ctx, num_streams, streams) ((handle)->vfs_next.ops.streaminfo((handle)->vfs_next.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams)))
-#define SMB_VFS_NEXT_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name) ((conn)->vfs_next.ops.get_real_filename((conn)->vfs_next.handles.get_real_filename, (path), (name), (mem_ctx), (found_name)))
+#define SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx, found_name) ((handle)->vfs_next.ops.get_real_filename((handle)->vfs_next.handles.get_real_filename, (path), (name), (mem_ctx), (found_name)))
 
 /* NT ACL operations. */
 #define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc) ((handle)->vfs_next.ops.fget_nt_acl((handle)->vfs_next.handles.fget_nt_acl, (fsp), (security_info), (ppdesc)))
index 7970bf264460852b677f67a6772b7529bec52ce9..1d9983a753b4c1132446267e10290d5d91ef741b 100644 (file)
@@ -211,6 +211,11 @@ static NTSTATUS smb_full_audit_streaminfo(vfs_handle_struct *handle,
                                          TALLOC_CTX *mem_ctx,
                                          unsigned int *pnum_streams,
                                          struct stream_struct **pstreams);
+static int smb_full_audit_get_real_filename(struct vfs_handle_struct *handle,
+                                           const char *path,
+                                           const char *name,
+                                           TALLOC_CTX *mem_ctx,
+                                           char **found_name);
 static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                                uint32 security_info,
                                SEC_DESC **ppdesc);
@@ -444,6 +449,8 @@ static vfs_op_tuple audit_op_tuples[] = {
         SMB_VFS_LAYER_LOGGER},
        {SMB_VFS_OP(smb_full_audit_streaminfo), SMB_VFS_OP_STREAMINFO,
         SMB_VFS_LAYER_LOGGER},
+       {SMB_VFS_OP(smb_full_audit_get_real_filename), SMB_VFS_OP_GET_REAL_FILENAME,
+        SMB_VFS_LAYER_LOGGER},
 
        /* NT ACL operations. */
 
@@ -576,6 +583,7 @@ static struct {
        { SMB_VFS_OP_RMDIR,     "rmdir" },
        { SMB_VFS_OP_CLOSEDIR,  "closedir" },
        { SMB_VFS_OP_OPEN,      "open" },
+       { SMB_VFS_OP_CREATE_FILE, "create_file" },
        { SMB_VFS_OP_CLOSE,     "close" },
        { SMB_VFS_OP_READ,      "read" },
        { SMB_VFS_OP_PREAD,     "pread" },
@@ -612,6 +620,7 @@ static struct {
        { SMB_VFS_OP_CHFLAGS,   "chflags" },
        { SMB_VFS_OP_FILE_ID_CREATE,    "file_id_create" },
        { SMB_VFS_OP_STREAMINFO,        "streaminfo" },
+       { SMB_VFS_OP_GET_REAL_FILENAME, "get_real_filename" },
        { SMB_VFS_OP_FGET_NT_ACL,       "fget_nt_acl" },
        { SMB_VFS_OP_GET_NT_ACL,        "get_nt_acl" },
        { SMB_VFS_OP_FSET_NT_ACL,       "fset_nt_acl" },
@@ -712,6 +721,7 @@ static int audit_syslog_priority(vfs_handle_struct *handle)
 static char *audit_prefix(TALLOC_CTX *ctx, connection_struct *conn)
 {
        char *prefix = NULL;
+       char *result;
 
        prefix = talloc_strdup(ctx,
                        lp_parm_const_string(SNUM(conn), "full_audit",
@@ -719,7 +729,7 @@ static char *audit_prefix(TALLOC_CTX *ctx, connection_struct *conn)
        if (!prefix) {
                return NULL;
        }
-       return talloc_sub_advanced(ctx,
+       result = talloc_sub_advanced(ctx,
                        lp_servicename(SNUM(conn)),
                        conn->server_info->unix_name,
                        conn->connectpath,
@@ -727,6 +737,8 @@ static char *audit_prefix(TALLOC_CTX *ctx, connection_struct *conn)
                        conn->server_info->sanitized_username,
                        pdb_get_domain(conn->server_info->sam_account),
                        prefix);
+       TALLOC_FREE(prefix);
+       return result;
 }
 
 static bool log_success(vfs_handle_struct *handle, vfs_op_type op)
@@ -840,14 +852,14 @@ static void do_log(vfs_op_type op, bool success, vfs_handle_struct *handle,
                fstr_sprintf(err_msg, "fail (%s)", strerror(errno));
 
        va_start(ap, format);
-       op_msg = talloc_vasprintf(NULL, format, ap);
+       op_msg = talloc_vasprintf(talloc_tos(), format, ap);
        va_end(ap);
 
        if (!op_msg) {
                return;
        }
 
-       audit_pre = audit_prefix(NULL, handle->conn);
+       audit_pre = audit_prefix(talloc_tos(), handle->conn);
        syslog(audit_syslog_priority(handle), "%s|%s|%s|%s\n",
                audit_pre ? audit_pre : "",
                audit_opname(op), err_msg, op_msg);
@@ -1615,6 +1627,23 @@ static NTSTATUS smb_full_audit_streaminfo(vfs_handle_struct *handle,
        return result;
 }
 
+static int smb_full_audit_get_real_filename(struct vfs_handle_struct *handle,
+                                           const char *path,
+                                           const char *name,
+                                           TALLOC_CTX *mem_ctx,
+                                           char **found_name)
+{
+       int result;
+
+       result = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx,
+                                               found_name);
+
+       do_log(SMB_VFS_OP_GET_REAL_FILENAME, (result == 0), handle,
+              "%s/%s->%s", path, name, (result == 0) ? "" : *found_name);
+
+       return result;
+}
+
 static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                                uint32 security_info,
                                SEC_DESC **ppdesc)
index 69d34940fd3a76c12992c60d6b63c69a02385938..54c17db1ce22847e89011d5ff337f8a7f9ba8b96 100644 (file)
@@ -525,6 +525,7 @@ static int streams_depot_rename(vfs_handle_struct *handle,
        char *nsname = NULL;
        char *ostream_fname = NULL;
        char *nstream_fname = NULL;
+       char *newname_full = NULL;
 
        DEBUG(10, ("streams_depot_rename called for %s => %s\n",
                   oldname, newname));
@@ -536,11 +537,6 @@ static int streams_depot_rename(vfs_handle_struct *handle,
                return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
        }
 
-       if (!(old_is_stream && new_is_stream)) {
-               errno = ENOSYS;
-               return -1;
-       }
-
        frame = talloc_stackframe();
 
        if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), oldname,
@@ -549,7 +545,7 @@ static int streams_depot_rename(vfs_handle_struct *handle,
                goto done;
        }
 
-       if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), oldname,
+       if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), newname,
                                                    &nbase, &nsname))) {
                errno = ENOMEM;
                goto done;
@@ -561,17 +557,27 @@ static int streams_depot_rename(vfs_handle_struct *handle,
                goto done;
        }
 
-       if (StrCaseCmp(obase, nbase) != 0) {
-               errno = ENOSYS;
-               goto done;
-       }
-
        ostream_fname = stream_name(handle, oldname, false);
        if (ostream_fname == NULL) {
                return -1;
        }
 
-       nstream_fname = stream_name(handle, newname, false);
+       /*
+        * Handle passing in a stream name without the base file.  This is
+        * exercised by the NTRENAME streams rename path.
+        */
+       if (StrCaseCmp(nbase, "./") == 0) {
+               newname_full = talloc_asprintf(talloc_tos(), "%s:%s", obase,
+                                              nsname);
+               if (newname_full == NULL) {
+                       errno = ENOMEM;
+                       goto done;
+               }
+       }
+
+       nstream_fname = stream_name(handle,
+                                   newname_full ? newname_full : newname,
+                                   false);
        if (nstream_fname == NULL) {
                return -1;
        }
index ecfc31970dae7a960437779833047b49995f0cd4..7124c575203a184fb5936d88274dc2657904b86a 100644 (file)
@@ -511,11 +511,6 @@ static int streams_xattr_rename(vfs_handle_struct *handle,
                return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
        }
 
-       if (!(o_is_stream && n_is_stream)) {
-               errno = ENOSYS;
-               goto fail;
-       }
-
        frame = talloc_stackframe();
        if (!frame) {
                goto fail;
@@ -544,12 +539,6 @@ static int streams_xattr_rename(vfs_handle_struct *handle,
                goto fail;
        }
 
-       /* the new base should be empty */
-       if (StrCaseCmp(obase, nbase) != 0) {
-               errno = ENOSYS;
-               goto fail;
-       }
-
        if (StrCaseCmp(ostream, nstream) == 0) {
                goto done;
        }
index b17aec80fa23d2714784bc57cb4824cda102a7c8..3f33237f18979f429609134c572426766ad83c93 100644 (file)
@@ -1310,13 +1310,6 @@ void reply_ntrename(struct smb_request *req)
                return;
        }
 
-       if( is_ntfs_stream_name(oldname)) {
-               /* Can't rename a stream. */
-               reply_nterror(req, NT_STATUS_ACCESS_DENIED);
-               END_PROFILE(SMBntrename);
-               return;
-       }
-
        if (ms_has_wild(oldname)) {
                reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
                END_PROFILE(SMBntrename);
@@ -1364,6 +1357,13 @@ void reply_ntrename(struct smb_request *req)
                return;
        }
 
+       /* The new name must begin with a ':' if the old name is a stream. */
+       if (is_ntfs_stream_name(oldname) && (newname[0] != ':')) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBntrename);
+               return;
+       }
+
        DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
 
        switch(rename_type) {
index 2133a30dc651c7cf5cc1d653488aabaa6614a1bb..593558e3992aea0a4f87d679dc56cd646669d435 100644 (file)
@@ -5439,7 +5439,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
        SMB_STRUCT_STAT sbuf, sbuf1;
        NTSTATUS status = NT_STATUS_OK;
        struct share_mode_lock *lck = NULL;
-       bool dst_exists;
+       bool dst_exists, old_is_stream, new_is_stream;
 
        ZERO_STRUCT(sbuf);
 
@@ -5508,6 +5508,18 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
                return NT_STATUS_OK;
        }
 
+       old_is_stream = is_ntfs_stream_name(fsp->fsp_name);
+       new_is_stream = is_ntfs_stream_name(newname);
+
+       /* Return the correct error code if both names aren't streams. */
+       if (!old_is_stream && new_is_stream) {
+               return NT_STATUS_OBJECT_NAME_INVALID;
+       }
+
+       if (old_is_stream && !new_is_stream) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
        /*
         * Have vfs_object_exist also fill sbuf1
         */
@@ -5519,18 +5531,11 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
                return NT_STATUS_OBJECT_NAME_COLLISION;
        }
 
-       if(replace_if_exists && dst_exists) {
-               /* Ensure both or neither are stream names. */
-               if (is_ntfs_stream_name(fsp->fsp_name) !=
-                               is_ntfs_stream_name(newname)) {
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-       }
-
        if (dst_exists) {
                struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf1);
                files_struct *dst_fsp = file_find_di_first(fileid);
-               if (dst_fsp) {
+               /* The file can be open when renaming a stream */
+               if (dst_fsp && !new_is_stream) {
                        DEBUG(3, ("rename_internals_fsp: Target file open\n"));
                        return NT_STATUS_ACCESS_DENIED;
                }
index 0dea615fb58026f60a1e1e267939b7cfe1dc3f8c..e90098fed066b5f7ecdfa3a3428c7d5b7a9e6ea7 100644 (file)
@@ -235,6 +235,10 @@ static int load_registry_service(const char *servicename)
                return -1;
        }
 
+       if ((servicename == NULL) || (*servicename == '\0')) {
+               return -1;
+       }
+
        if (strequal(servicename, GLOBAL_NAME)) {
                return -2;
        }
index 10b9691ae079ca93519bf6c95e2713a0fee3d3fa..0dda9aa05bb45e4b023394ad331c821393e3bf41 100644 (file)
@@ -538,7 +538,7 @@ static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs
 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
 {
        char *url;
-       int flags;
+       int flags = 0;
        PyObject *py_options = Py_None;
        int ret;
        const char **options;
index 150e5c00df8f7c2c322747aa8e0c4b2f764f5965..763140b486df12413390a0905039ef6de87b006d 100644 (file)
@@ -1255,12 +1255,12 @@ def provision_backend(setup_dir=None, message=None,
 
     elif ldap_backend_type == "openldap":
         attrs = ["linkID", "lDAPDisplayName"]
-        res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs)
+        res = schemadb.search(expression="(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1))(objectclass=attributeSchema)(omSyntax=127))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs)
 
         memberof_config = "# Generated from schema in %s\n" % schemadb_path
         refint_attributes = ""
         for i in range (0, len(res)):
-            expression = "(&(objectclass=attributeSchema)(linkID=%d))" % (int(res[i]["linkID"][0])+1)
+            expression = "(&(objectclass=attributeSchema)(linkID=%d)(omSyntax=127))" % (int(res[i]["linkID"][0])+1)
             target = schemadb.searchone(basedn=names.schemadn, 
                                         expression=expression, 
                                         attribute="lDAPDisplayName", 
index 233f9a961373ba53543fb1df00a570d169c99ff9..0d38652dae662f0d7d14165b740512f8742bfb1b 100644 (file)
@@ -11,7 +11,6 @@ distinguishedName
 description
 cn
 top
-entryTTL
 uidNumber
 gidNumber
 #The memberOf plugin provides this attribute
@@ -30,6 +29,10 @@ name:samba4RDN
 #Remap these so that we don't put operational attributes in a schema MAY
 modifyTimeStamp:samba4ModifyTimestamp
 2.5.18.2:1.3.6.1.4.1.7165.4.255.3
+dynamicObject:samba4DynaimcObject
+1.3.6.1.4.1.1466.101.119.2:1.3.6.1.4.1.7165.4.255.8
+entryTTL:samba4EntryTTL
+1.3.6.1.4.1.1466.101.119.3:1.3.6.1.4.1.7165.4.255.9
 #MiddleName has a conflicting OID
 2.16.840.1.113730.3.1.34:1.3.6.1.4.1.7165.4.255.1
 #defaultGroup has a conflicting OID
index d42795b94dca9129311dee573fe222348888eeac..47010da6373168fdf047f4ee309095fba7ac959c 100644 (file)
@@ -189,6 +189,8 @@ oMSyntax: 20
 #Allocated: (objectClasses) samba4ObjectClasses: 1.3.6.1.4.1.7165.4.255.5
 #Allocated: (ditContentRules) samba4DitContentRules: 1.3.6.1.4.1.7165.4.255.6
 #Allocated: (attributeTypes) samba4AttributeTypes: 1.3.6.1.4.1.7165.4.255.7
+#Allocated: (dynamicObject) samba4DynamicObject: 1.3.6.1.4.1.7165.4.255.8
+#Allocated: (entryTTL) samba4EntryTTL: 1.3.6.1.4.1.7165.4.255.9
 
 #
 # Fedora DS uses this attribute, and we need to set it via our module stack
index ba74530c6f97a01c6594a41c4cf03b3f343a18df..1898fe9d33b91eb68753a520123345bdbaa78b06 100644 (file)
@@ -640,6 +640,7 @@ static bool test_stream_delete(struct torture_context *tctx,
        CHECK_STATUS(status, NT_STATUS_OK);
 done:
        smbcli_close(cli->tree, fnum);
+       smbcli_unlink(cli->tree, fname);
        return ret;
 }
 
@@ -1112,6 +1113,198 @@ done:
        return ret;
 }
 
+static bool test_stream_rename2(struct torture_context *tctx,
+                              struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+{
+       NTSTATUS status;
+       union smb_open io;
+       const char *fname1 = BASEDIR "\\stream.txt";
+       const char *fname2 = BASEDIR "\\stream2.txt";
+       const char *stream_name1 = ":Stream One:$DATA";
+       const char *stream_name2 = ":Stream Two:$DATA";
+       const char *stream_name_default = "::$DATA";
+       const char *sname1;
+       const char *sname2;
+       bool ret = true;
+       int fnum = -1;
+       union smb_setfileinfo sinfo;
+       union smb_rename rio;
+
+       sname1 = talloc_asprintf(mem_ctx, "%s:%s", fname1, "Stream One");
+       sname2 = talloc_asprintf(mem_ctx, "%s:%s", fname1, "Stream Two");
+
+       io.generic.level = RAW_OPEN_NTCREATEX;
+       io.ntcreatex.in.root_fid = 0;
+       io.ntcreatex.in.flags = 0;
+       io.ntcreatex.in.access_mask = (SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|
+           SEC_STD_DELETE|SEC_FILE_APPEND_DATA|SEC_STD_READ_CONTROL);
+       io.ntcreatex.in.create_options = 0;
+       io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+       io.ntcreatex.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
+                                       NTCREATEX_SHARE_ACCESS_WRITE |
+                                       NTCREATEX_SHARE_ACCESS_DELETE);
+       io.ntcreatex.in.alloc_size = 0;
+       io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+       io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+       io.ntcreatex.in.security_flags = 0;
+       io.ntcreatex.in.fname = sname1;
+
+       /* Open/create new stream. */
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+
+       /*
+        * Check raw rename with <base>:<stream>.
+        */
+       printf("(%s) Checking NTRENAME of a stream using <base>:<stream>\n",
+              __location__);
+       rio.generic.level = RAW_RENAME_NTRENAME;
+       rio.ntrename.in.old_name = sname1;
+       rio.ntrename.in.new_name = sname2;
+       rio.ntrename.in.attrib = 0;
+       rio.ntrename.in.cluster_size = 0;
+       rio.ntrename.in.flags = RENAME_FLAG_RENAME;
+       status = smb_raw_rename(cli->tree, &rio);
+       CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+
+       /*
+        * Check raw rename to the default stream using :<stream>.
+        */
+       printf("(%s) Checking NTRENAME to default stream using :<stream>\n",
+              __location__);
+       rio.ntrename.in.new_name = stream_name_default;
+       status = smb_raw_rename(cli->tree, &rio);
+       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
+
+       /*
+        * Check raw rename using :<stream>.
+        */
+       printf("(%s) Checking NTRENAME of a stream using :<stream>\n",
+              __location__);
+       rio.ntrename.in.new_name = stream_name2;
+       status = smb_raw_rename(cli->tree, &rio);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       /*
+        * Check raw rename of a stream to a file.
+        */
+       printf("(%s) Checking NTRENAME of a stream to a file\n",
+              __location__);
+       rio.ntrename.in.old_name = sname2;
+       rio.ntrename.in.new_name = fname2;
+       status = smb_raw_rename(cli->tree, &rio);
+       CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+
+       /*
+        * Check raw rename of a file to a stream.
+        */
+       printf("(%s) Checking NTRENAME of a file to a stream\n",
+              __location__);
+
+       /* Create the file. */
+       io.ntcreatex.in.fname = fname2;
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+
+       /* Try the rename. */
+       rio.ntrename.in.old_name = fname2;
+       rio.ntrename.in.new_name = sname1;
+       status = smb_raw_rename(cli->tree, &rio);
+       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
+
+       /*
+        * Reopen the stream for trans2 renames.
+        */
+       io.ntcreatex.in.fname = sname2;
+       io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       fnum = io.ntcreatex.out.file.fnum;
+
+       /*
+        * Check trans2 rename of a stream using :<stream>.
+        */
+       printf("(%s) Checking trans2 rename of a stream using :<stream>\n",
+              __location__);
+       ZERO_STRUCT(sinfo);
+       sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
+       sinfo.rename_information.in.file.fnum = fnum;
+       sinfo.rename_information.in.overwrite = 1;
+       sinfo.rename_information.in.root_fid = 0;
+       sinfo.rename_information.in.new_name = stream_name1;
+       status = smb_raw_setfileinfo(cli->tree, &sinfo);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       /*
+        * Check trans2 rename of an overwriting stream using :<stream>.
+        */
+       printf("(%s) Checking trans2 rename of an overwriting stream using "
+              ":<stream>\n", __location__);
+
+       /* Create second stream. */
+       io.ntcreatex.in.fname = sname2;
+       io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+
+       /* Rename the first stream onto the second. */
+       sinfo.rename_information.in.file.fnum = fnum;
+       sinfo.rename_information.in.new_name = stream_name2;
+       status = smb_raw_setfileinfo(cli->tree, &sinfo);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       smbcli_close(cli->tree, fnum);
+
+       /*
+        * Reopen the stream with the new name.
+        */
+       io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+       io.ntcreatex.in.fname = sname2;
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       fnum = io.ntcreatex.out.file.fnum;
+
+       /*
+        * Check trans2 rename of a stream using <base>:<stream>.
+        */
+       printf("(%s) Checking trans2 rename of a stream using "
+              "<base>:<stream>\n", __location__);
+       sinfo.rename_information.in.file.fnum = fnum;
+       sinfo.rename_information.in.new_name = sname1;
+       status = smb_raw_setfileinfo(cli->tree, &sinfo);
+       CHECK_STATUS(status, NT_STATUS_NOT_SUPPORTED);
+
+       /*
+        * Samba3 doesn't currently support renaming a stream to the default
+        * stream.  This test does pass on windows.
+        */
+       if (torture_setting_bool(tctx, "samba3", false)) {
+               goto done;
+       }
+
+       /*
+        * Check trans2 rename to the default stream using :<stream>.
+        */
+       printf("(%s) Checking trans2 rename to defaualt stream using "
+              ":<stream>\n", __location__);
+       sinfo.rename_information.in.file.fnum = fnum;
+       sinfo.rename_information.in.new_name = stream_name_default;
+       status = smb_raw_setfileinfo(cli->tree, &sinfo);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       smbcli_close(cli->tree, fnum);
+
+ done:
+       smbcli_close(cli->tree, fnum);
+       status = smbcli_unlink(cli->tree, fname1);
+       status = smbcli_unlink(cli->tree, fname2);
+       return ret;
+}
+
 
 /* 
    basic testing of streams calls
@@ -1131,15 +1324,17 @@ bool torture_raw_streams(struct torture_context *torture,
        smb_raw_exit(cli->session);
        ret &= test_stream_sharemodes(torture, cli, torture);
        smb_raw_exit(cli->session);
+       if (!torture_setting_bool(torture, "samba4", false)) {
+               ret &= test_stream_delete(torture, cli, torture);
+       }
        ret &= test_stream_names(torture, cli, torture);
        smb_raw_exit(cli->session);
        ret &= test_stream_names2(torture, cli, torture);
        smb_raw_exit(cli->session);
        ret &= test_stream_rename(torture, cli, torture);
        smb_raw_exit(cli->session);
-       if (!torture_setting_bool(torture, "samba4", false)) {
-               ret &= test_stream_delete(torture, cli, torture);
-       }
+       ret &= test_stream_rename2(torture, cli, torture);
+       smb_raw_exit(cli->session);
 
        smb_raw_exit(cli->session);
        smbcli_deltree(cli->tree, BASEDIR);