NTSTATUS delete_all_streams(connection_struct *conn, const char *fname) { struct stream_struct *stream_info; int i; unsigned int num_streams; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; status = SMB_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, ("SMB_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 = NULL; if (strequal(stream_info[i].name, "::$DATA")) { continue; } status = create_synthetic_smb_fname(talloc_tos(), fname, stream_info[i].name, NULL, &smb_fname_stream); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("talloc_aprintf failed\n")); 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, const char *basepath, const char *streamname, SMB_STRUCT_STAT *pst, char **path) { SMB_STRUCT_STAT st; char *result = NULL; NTSTATUS status; unsigned int i, num_streams; struct stream_struct *streams = NULL; result = talloc_asprintf(mem_ctx, "%s%s", basepath, streamname); if (result == NULL) { return NT_STATUS_NO_MEMORY; } if (SMB_VFS_STAT(conn, result, &st) == 0) { *pst = st; *path = result; return NT_STATUS_OK; } if (errno != ENOENT) { status = map_nt_error_from_unix(errno); DEBUG(10, ("vfs_stat failed: %s\n", nt_errstr(status))); goto fail; } status = SMB_VFS_STREAMINFO(conn, NULL, basepath, mem_ctx, &num_streams, &streams); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { SET_STAT_INVALID(*pst); *path = result; 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]: ", streamname, streams[i].name)); if (fname_equal(streamname, streams[i].name, conn->case_sensitive)) { DEBUGADD(10, ("equal\n")); break; } DEBUGADD(10, ("not equal\n")); } if (i == num_streams) { SET_STAT_INVALID(*pst); *path = result; TALLOC_FREE(streams); return NT_STATUS_OK; } TALLOC_FREE(result); result = talloc_asprintf(mem_ctx, "%s%s", basepath, streams[i].name); if (result == NULL) { status = NT_STATUS_NO_MEMORY; goto fail; } SET_STAT_INVALID(*pst); if (SMB_VFS_STAT(conn, result, pst) == 0) { stat_cache_add(orig_path, result, conn->case_sensitive); } *path = result; TALLOC_FREE(streams); return NT_STATUS_OK; fail: TALLOC_FREE(result); TALLOC_FREE(streams); return status; }