diff options
author | Melanie Thielker | 2008-12-28 23:55:34 +0000 |
---|---|---|
committer | Melanie Thielker | 2008-12-28 23:55:34 +0000 |
commit | 817a10d0aa670c779fbd7ae74e8af0c4f21dae50 (patch) | |
tree | 98bada382d99f37d5f89407c2499e2c0dcf2d0d0 | |
parent | Thank you kindly, StrawberryFride for a patch that: (diff) | |
download | opensim-SC-817a10d0aa670c779fbd7ae74e8af0c4f21dae50.zip opensim-SC-817a10d0aa670c779fbd7ae74e8af0c4f21dae50.tar.gz opensim-SC-817a10d0aa670c779fbd7ae74e8af0c4f21dae50.tar.bz2 opensim-SC-817a10d0aa670c779fbd7ae74e8af0c4f21dae50.tar.xz |
Revamp the return logic to close a privilege escalation loophole.
Estate owner / Master avatar returns would place the item in the
returner's inventory rather than the owner's if the owner was not
in sim.
-rw-r--r-- | OpenSim/Region/Environment/Scenes/Scene.Inventory.cs | 189 |
1 files changed, 143 insertions, 46 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index 2c42502..1f671ab 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs | |||
@@ -1765,6 +1765,26 @@ namespace OpenSim.Region.Environment.Scenes | |||
1765 | } | 1765 | } |
1766 | } | 1766 | } |
1767 | 1767 | ||
1768 | private bool WaitForInventory(CachedUserInfo info) | ||
1769 | { | ||
1770 | // 200 Seconds wait. This is called in the context of the | ||
1771 | // background delete thread, so we can afford to waste time | ||
1772 | // here. | ||
1773 | // | ||
1774 | int count = 200; | ||
1775 | |||
1776 | while (count > 0) | ||
1777 | { | ||
1778 | System.Threading.Thread.Sleep(100); | ||
1779 | count--; | ||
1780 | if (info.HasReceivedInventory) | ||
1781 | return true; | ||
1782 | } | ||
1783 | m_log.DebugFormat("Timed out waiting for inventory of user {0}", | ||
1784 | info.UserProfile.ID.ToString()); | ||
1785 | return false; | ||
1786 | } | ||
1787 | |||
1768 | /// <summary> | 1788 | /// <summary> |
1769 | /// Delete a scene object from a scene and place in the given avatar's inventory. | 1789 | /// Delete a scene object from a scene and place in the given avatar's inventory. |
1770 | /// Returns the UUID of the newly created asset. | 1790 | /// Returns the UUID of the newly created asset. |
@@ -1780,63 +1800,151 @@ namespace OpenSim.Region.Environment.Scenes | |||
1780 | 1800 | ||
1781 | string sceneObjectXml = objectGroup.ToXmlString(); | 1801 | string sceneObjectXml = objectGroup.ToXmlString(); |
1782 | 1802 | ||
1803 | bool useOwner = false; | ||
1804 | |||
1805 | // Get the user info of the item destination | ||
1806 | // | ||
1783 | CachedUserInfo userInfo; | 1807 | CachedUserInfo userInfo; |
1784 | 1808 | ||
1785 | if (remoteClient == null) | 1809 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || |
1810 | action == DeRezAction.SaveToExistingUserInventoryItem) | ||
1786 | { | 1811 | { |
1787 | userInfo = CommsManager.UserProfileCacheService.GetUserDetails(objectGroup.RootPart.OwnerID); | 1812 | // Take or take copy require a taker |
1813 | // Saving changes requires a local user | ||
1814 | // | ||
1815 | if (remoteClient == null) | ||
1816 | return UUID.Zero; | ||
1817 | |||
1818 | userInfo = CommsManager.UserProfileCacheService.GetUserDetails( | ||
1819 | remoteClient.AgentId); | ||
1788 | } | 1820 | } |
1789 | else | 1821 | else |
1790 | { | 1822 | { |
1791 | userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 1823 | // All returns / deletes go to the object owner |
1824 | // | ||
1825 | userInfo = CommsManager.UserProfileCacheService.GetUserDetails( | ||
1826 | objectGroup.RootPart.OwnerID); | ||
1827 | } | ||
1828 | |||
1829 | if (userInfo == null) // Can't proceed | ||
1830 | { | ||
1831 | return UUID.Zero; | ||
1832 | } | ||
1833 | |||
1834 | if (!userInfo.HasReceivedInventory) | ||
1835 | { | ||
1836 | // Async inventory requests will queue, but they will never | ||
1837 | // execute unless inventory is actually fetched | ||
1838 | // | ||
1839 | CommsManager.UserProfileCacheService.RequestInventoryForUser( | ||
1840 | userInfo.UserProfile.ID); | ||
1792 | } | 1841 | } |
1793 | 1842 | ||
1794 | if (userInfo != null) | 1843 | if (userInfo != null) |
1795 | { | 1844 | { |
1796 | // If we're deleting someone else's item, it goes back to | ||
1797 | // their deleted items folder | ||
1798 | // If we're returning someone's item, it goes back to the | 1845 | // If we're returning someone's item, it goes back to the |
1799 | // owner's Lost And Found folder. | 1846 | // owner's Lost And Found folder. |
1847 | // Delete is treated like return in this case | ||
1848 | // Deleting your own items makes them go to trash | ||
1849 | // | ||
1800 | 1850 | ||
1801 | if (folderID == UUID.Zero | 1851 | InventoryFolderBase folder = null; |
1802 | || (action == DeRezAction.Delete && objectGroup.OwnerID != remoteClient.AgentId)) | 1852 | InventoryItemBase item = null; |
1803 | { | 1853 | |
1804 | InventoryFolderBase folder = | ||
1805 | userInfo.FindFolderForType( | ||
1806 | (int)AssetType.LostAndFoundFolder); | ||
1807 | 1854 | ||
1808 | if (folder != null) | 1855 | // No folder type needed |
1856 | // We don't go here unless we have a user logged in | ||
1857 | // so the skeleton is loaded | ||
1858 | // | ||
1859 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | ||
1860 | { | ||
1861 | item = userInfo.RootFolder.FindItem( | ||
1862 | objectGroup.RootPart.FromUserInventoryItemID); | ||
1863 | |||
1864 | if (null == item) | ||
1809 | { | 1865 | { |
1810 | folderID = folder.ID; | 1866 | m_log.DebugFormat( |
1867 | "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", | ||
1868 | objectGroup.Name, objectGroup.UUID); | ||
1869 | return UUID.Zero; | ||
1811 | } | 1870 | } |
1812 | else | 1871 | } |
1872 | else | ||
1873 | { | ||
1874 | // Folder magic | ||
1875 | // | ||
1876 | if (action == DeRezAction.Delete) | ||
1813 | { | 1877 | { |
1814 | if (userInfo.RootFolder != null) | 1878 | // Deleting someone else's item |
1879 | // | ||
1880 | if (remoteClient == null || | ||
1881 | objectGroup.OwnerID != remoteClient.AgentId) | ||
1815 | { | 1882 | { |
1816 | folderID = userInfo.RootFolder.ID; | 1883 | // Folder skeleton may not be loaded and we |
1884 | // have to wait for the inventory to find | ||
1885 | // the destination folder | ||
1886 | // | ||
1887 | if (!WaitForInventory(userInfo)) | ||
1888 | return UUID.Zero; | ||
1889 | folder = userInfo.FindFolderForType( | ||
1890 | (int)AssetType.LostAndFoundFolder); | ||
1817 | } | 1891 | } |
1818 | else | 1892 | else |
1819 | { | 1893 | { |
1820 | CommsManager.UserProfileCacheService.RequestInventoryForUser(objectGroup.RootPart.OwnerID); | 1894 | // Assume inventory skeleton was loaded during login |
1821 | m_log.WarnFormat("[SCENE] Can't find root folder for user, requesting inventory"); | 1895 | // and all folders can be found |
1822 | return assetID; | 1896 | // |
1897 | folder = userInfo.FindFolderForType( | ||
1898 | (int)AssetType.TrashFolder); | ||
1823 | } | 1899 | } |
1824 | } | 1900 | } |
1825 | } | 1901 | else if (action == DeRezAction.Return) |
1902 | { | ||
1903 | // Wait if needed | ||
1904 | // | ||
1905 | if (!userInfo.HasReceivedInventory) | ||
1906 | { | ||
1907 | if (!WaitForInventory(userInfo)) | ||
1908 | return UUID.Zero; | ||
1909 | } | ||
1826 | 1910 | ||
1827 | InventoryItemBase item = null; | 1911 | // Dump to lost + found unconditionally |
1828 | 1912 | // | |
1829 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 1913 | folder = userInfo.FindFolderForType( |
1830 | { | 1914 | (int)AssetType.LostAndFoundFolder); |
1831 | item = userInfo.RootFolder.FindItem(objectGroup.RootPart.FromUserInventoryItemID); | 1915 | } |
1832 | 1916 | ||
1833 | if (null == item) | 1917 | if (folderID == UUID.Zero && folder == null) |
1834 | { | 1918 | { |
1835 | m_log.DebugFormat( | 1919 | // Catch all. Use lost & found |
1836 | "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", | 1920 | // |
1837 | objectGroup.Name, objectGroup.UUID); | 1921 | if (!userInfo.HasReceivedInventory) |
1838 | return UUID.Zero; | 1922 | { |
1923 | if (!WaitForInventory(userInfo)) | ||
1924 | return UUID.Zero; | ||
1925 | } | ||
1926 | |||
1927 | folder = userInfo.FindFolderForType( | ||
1928 | (int)AssetType.LostAndFoundFolder); | ||
1929 | } | ||
1930 | |||
1931 | if (folder == null) // None of the above | ||
1932 | { | ||
1933 | folder = userInfo.RootFolder.FindFolder(folderID); | ||
1934 | |||
1935 | if (folder == null) // Nowhere to put it | ||
1936 | { | ||
1937 | return UUID.Zero; | ||
1938 | } | ||
1839 | } | 1939 | } |
1940 | |||
1941 | item = new InventoryItemBase(); | ||
1942 | item.Creator = objectGroup.RootPart.CreatorID; | ||
1943 | item.ID = UUID.Random(); | ||
1944 | item.InvType = (int)InventoryType.Object; | ||
1945 | item.Folder = folder.ID; | ||
1946 | item.Owner = userInfo.UserProfile.ID; | ||
1947 | |||
1840 | } | 1948 | } |
1841 | 1949 | ||
1842 | AssetBase asset = CreateAsset( | 1950 | AssetBase asset = CreateAsset( |
@@ -1854,22 +1962,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
1854 | } | 1962 | } |
1855 | else | 1963 | else |
1856 | { | 1964 | { |
1857 | item = new InventoryItemBase(); | ||
1858 | item.Creator = objectGroup.RootPart.CreatorID; | ||
1859 | |||
1860 | if (action == DeRezAction.TakeCopy || action == DeRezAction.Take) | ||
1861 | item.Owner = remoteClient.AgentId; | ||
1862 | else // Delete / Return | ||
1863 | item.Owner = objectGroup.OwnerID; | ||
1864 | |||
1865 | item.ID = UUID.Random(); | ||
1866 | item.AssetID = asset.FullID; | 1965 | item.AssetID = asset.FullID; |
1867 | item.Description = asset.Description; | 1966 | |
1868 | item.Name = asset.Name; | ||
1869 | item.AssetType = asset.Type; | ||
1870 | item.InvType = (int)InventoryType.Object; | ||
1871 | item.Folder = folderID; | ||
1872 | |||
1873 | if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && Permissions.PropagatePermissions()) | 1967 | if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && Permissions.PropagatePermissions()) |
1874 | { | 1968 | { |
1875 | uint perms=objectGroup.GetEffectivePermissions(); | 1969 | uint perms=objectGroup.GetEffectivePermissions(); |
@@ -1899,6 +1993,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
1899 | 1993 | ||
1900 | // TODO: add the new fields (Flags, Sale info, etc) | 1994 | // TODO: add the new fields (Flags, Sale info, etc) |
1901 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 1995 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
1996 | item.Description = asset.Description; | ||
1997 | item.Name = asset.Name; | ||
1998 | item.AssetType = asset.Type; | ||
1902 | 1999 | ||
1903 | userInfo.AddItem(item); | 2000 | userInfo.AddItem(item); |
1904 | 2001 | ||