NTSTATUS delete_all_streams(connection_struct *conn, const char *fname) { struct stream_struct *stream_info = NULL; int i; unsigned int num_streams = 0; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; status = vfs_streaminfo(conn, NULL, fname, talloc_tos(), &num_streams, &stream_info); if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { DEBUG(10, ("no streams around\n")); TALLOC_FREE(frame); return NT_STATUS_OK; } if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("vfs_streaminfo failed: %s\n", nt_errstr(status))); goto fail; } DEBUG(10, ("delete_all_streams found %d streams\n", num_streams)); if (num_streams == 0) { TALLOC_FREE(frame); return NT_STATUS_OK; } for (i=0; i<num_streams; i++) { int res; struct smb_filename *smb_fname_stream; if (strequal(stream_info[i].name, "::$DATA")) { continue; } smb_fname_stream = synthetic_smb_fname( talloc_tos(), fname, stream_info[i].name, NULL); if (smb_fname_stream == NULL) { DEBUG(0, ("talloc_aprintf failed\n")); status = NT_STATUS_NO_MEMORY; goto fail; } res = SMB_VFS_UNLINK(conn, smb_fname_stream); if (res == -1) { status = map_nt_error_from_unix(errno); DEBUG(10, ("Could not delete stream %s: %s\n", smb_fname_str_dbg(smb_fname_stream), strerror(errno))); TALLOC_FREE(smb_fname_stream); break; } TALLOC_FREE(smb_fname_stream); } fail: TALLOC_FREE(frame); return status; }
static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, connection_struct *conn, const char *orig_path, struct smb_filename *smb_fname) { NTSTATUS status; unsigned int i, num_streams = 0; struct stream_struct *streams = NULL; if (SMB_VFS_STAT(conn, smb_fname) == 0) { DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname))); return NT_STATUS_OK; } if (errno != ENOENT) { DEBUG(10, ("vfs_stat failed: %s\n", strerror(errno))); status = map_nt_error_from_unix(errno); goto fail; } /* Fall back to a case-insensitive scan of all streams on the file. */ status = vfs_streaminfo(conn, NULL, smb_fname->base_name, mem_ctx, &num_streams, &streams); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { SET_STAT_INVALID(smb_fname->st); return NT_STATUS_OK; } if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("vfs_streaminfo failed: %s\n", nt_errstr(status))); goto fail; } for (i=0; i<num_streams; i++) { DEBUG(10, ("comparing [%s] and [%s]: ", smb_fname->stream_name, streams[i].name)); if (fname_equal(smb_fname->stream_name, streams[i].name, conn->case_sensitive)) { DEBUGADD(10, ("equal\n")); break; } DEBUGADD(10, ("not equal\n")); } /* Couldn't find the stream. */ if (i == num_streams) { SET_STAT_INVALID(smb_fname->st); TALLOC_FREE(streams); return NT_STATUS_OK; } DEBUG(10, ("case insensitive stream. requested: %s, actual: %s\n", smb_fname->stream_name, streams[i].name)); TALLOC_FREE(smb_fname->stream_name); smb_fname->stream_name = talloc_strdup(smb_fname, streams[i].name); if (smb_fname->stream_name == NULL) { status = NT_STATUS_NO_MEMORY; goto fail; } SET_STAT_INVALID(smb_fname->st); if (SMB_VFS_STAT(conn, smb_fname) == 0) { DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname))); } status = NT_STATUS_OK; fail: TALLOC_FREE(streams); return status; }