aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment
diff options
context:
space:
mode:
authorMelanie Thielker2008-12-28 23:55:34 +0000
committerMelanie Thielker2008-12-28 23:55:34 +0000
commit817a10d0aa670c779fbd7ae74e8af0c4f21dae50 (patch)
tree98bada382d99f37d5f89407c2499e2c0dcf2d0d0 /OpenSim/Region/Environment
parentThank you kindly, StrawberryFride for a patch that: (diff)
downloadopensim-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.
Diffstat (limited to 'OpenSim/Region/Environment')
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.Inventory.cs189
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