diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 138360cc0118ebaf76879afe1a505aae7b536577..21420acf11d943fe7f1f3c3e41e2ce9a846631db 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -627,6 +627,14 @@ void LLAvatarActions::csr(const LLUUID& id, std::string name)
 //static 
 void LLAvatarActions::share(const LLUUID& id)
 {
+// [RLVa:KB] - @share
+	if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(id)) )
+	{
+		RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", id));
+		return;
+	}
+// [/RLVa:KB]
+
 	LLSD key;
 	LLFloaterSidePanelContainer::showPanel("inventory", key);
 	LLFloaterReg::showInstance("im_container");
@@ -845,10 +853,34 @@ namespace action_give_inventory
 	 * @param avatar_names - avatar names request to be sent.
 	 * @param avatar_uuids - avatar names request to be sent.
 	 */
-	static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names, LLInventoryPanel* panel = NULL)
+//	static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names, LLInventoryPanel* panel = NULL)
+// [RLVa:KB] - @share
+	static void give_inventory(uuid_vec_t avatar_uuids, std::vector<LLAvatarName> avatar_names, LLInventoryPanel* panel = NULL)
+// [/RLVa:KB]
 	{
 		llassert(avatar_names.size() == avatar_uuids.size());
 
+// [RLVa:KB] - @share
+		if ( (RlvActions::isRlvEnabled()) && (RlvActions::hasBehaviour(RLV_BHVR_SHARE)) )
+		{
+			for (int idxAvatar = avatar_uuids.size() - 1; idxAvatar >= 0; idxAvatar--)
+			{
+				if (!RlvActions::canGiveInventory(avatar_uuids[idxAvatar]))
+				{
+					RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", avatar_uuids[idxAvatar], "completename").getSLURLString()));
+
+					avatar_uuids.erase(avatar_uuids.begin() + idxAvatar);
+					avatar_names.erase(avatar_names.begin() + idxAvatar);
+				}
+			}
+		}
+
+		if (avatar_uuids.empty())
+		{
+			return;
+		}
+// [/RLVa:KB]
+
 		const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(panel);
 		if (inventory_selected_uuids.empty())
 		{
@@ -971,6 +1003,14 @@ std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs(LLInventoryPanel* ac
 //static
 void LLAvatarActions::shareWithAvatars(LLView * panel)
 {
+// [RLVa:KB] - @share
+	if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory()) )
+	{
+		RlvUtil::notifyBlocked(RlvStringKeys::Blocked::ShareGeneric);
+		return;
+	}
+// [/RLVa:KB]
+
 	using namespace action_give_inventory;
 
 	LLFloater* root_floater = gFloaterView->getParentFloater(panel);
diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index 9ca8114f08c957f366ddca6f17c8fa7288a56fe4..1af706f2541f5b59ed5a1ddf7a719d178cdd468d 100644
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -49,6 +49,7 @@
 #include "llvoavatarself.h"
 // [RLVa:KB] - Checked: RLVa-1.2.2
 #include "llavatarnamecache.h"
+#include "llslurl.h"
 #include "rlvactions.h"
 #include "rlvcommon.h"
 #include "rlvui.h"
@@ -200,7 +201,10 @@ bool LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent,
 	if (item->getPermissions().allowCopyBy(gAgentID))
 	{
 		// just give it away.
-		LLGiveInventory::commitGiveInventoryItem(to_agent, item, im_session_id);
+// [RLVa:KB] - @share
+		res = LLGiveInventory::commitGiveInventoryItem(to_agent, item, im_session_id);
+// [/RLVa:KB]
+//		LLGiveInventory::commitGiveInventoryItem(to_agent, item, im_session_id);
 	}
 	else
 	{
@@ -361,6 +365,14 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL
 	switch(option)
 	{
 	case 0:  // "Yes"
+// [RLVa:KB] - @share
+		if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(notification["payload"]["agent_id"].asUUID())) )
+		{
+			RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", notification["payload"]["agent_id"], "completename").getSLURLString()));
+			return false;
+		}
+// [/RLVa:KB]
+
 		for (LLSD::array_iterator it = itmes.beginArray(); it != itmes.endArray(); it++)
 		{
 			item = gInventory.getItem((*it).asUUID());
@@ -394,11 +406,24 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL
 }
 
 // static
-void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
+//void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
+//												const LLInventoryItem* item,
+//												const LLUUID& im_session_id)
+// [RLVa:KB] - @share
+bool LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
 												const LLInventoryItem* item,
 												const LLUUID& im_session_id)
+// [/RLVa:KB]
 {
-	if (!item) return;
+//	if (!item) return;
+// [RLVa:KB] - @share
+	if (!item) return false;
+	if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(to_agent)) )
+	{
+		return false;
+	}
+// [/RLVa:KB]
+
 	std::string name;
 	std::string item_name = item->getName();
 	LLAgentUI::buildFullname(name);
@@ -448,6 +473,7 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
 	{
 		LLRecentPeople::instance().add(to_agent);
 	}
+	return true;
 // [/RLVa:KB]
 }
 
@@ -463,6 +489,14 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons
 		cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID());
 		if (cat)
 		{
+// [RLVa:KB] - @share
+			if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(notification["payload"]["agent_id"].asUUID())) )
+			{
+				RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", notification["payload"]["agent_id"], "completename").getSLURLString()));
+				return false;
+			}
+// [/RLVa:KB]
+
 			give_successful = LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
 				cat);
 			LLViewerInventoryCategory::cat_array_t cats;
@@ -510,6 +544,13 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
 	{
 		return false;
 	}
+// [RLVa:KB] - @share
+	if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(to_agent)) )
+	{
+		return false;
+	}
+// [/RLVa:KB]
+
 	LL_INFOS() << "LLGiveInventory::commitGiveInventoryCategory() - "
 		<< cat->getUUID() << LL_ENDL;
 
diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h
index 20e6df76e5c7add2d46fade4f917b319e522e43a..86919f90104fe674e03143f01f914412c31edc03 100644
--- a/indra/newview/llgiveinventory.h
+++ b/indra/newview/llgiveinventory.h
@@ -82,9 +82,14 @@ class LLGiveInventory
 									const std::string& item_name = std::string(),
 									bool is_folder = false);
 
-	static void commitGiveInventoryItem(const LLUUID& to_agent,
+// [RLVa:KB] - @share
+	static bool commitGiveInventoryItem(const LLUUID& to_agent,
 									const LLInventoryItem* item,
 									const LLUUID &im_session_id = LLUUID::null);
+// [/RLVa:KB]
+//	static void commitGiveInventoryItem(const LLUUID& to_agent,
+//									const LLInventoryItem* item,
+//									const LLUUID &im_session_id = LLUUID::null);
 
 	// give inventory category functionality
 	static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 5abd52fbf8840df1529e91706125234b078fcb04..ae9a67bd9b64b7aa70ffe388d225880fad208da2 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -6046,6 +6046,19 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
 	BOOL rv = FALSE;
 	if(item)
 	{
+// [RLVa:KB] - @share
+		if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(item->getCreatorUUID())) )
+		{
+			if (drop)
+			{
+				RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", item->getCreatorUUID(), "completename").getSLURLString()));
+			}
+			// We should return false but our caller uses the return value as both 'will accept' *and* 'was handled' so
+			// returning false will result in the dropped item being moved when it is blocked.
+			return true;
+		}
+// [/RLVa:KB]
+
 		// check the type
 		switch(cargo_type)
 		{
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 7044a1827e9033aed245261b2c70747b1d7f2e96..0502ca3d30b2013497e961f072f8304900c31523 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -61,6 +61,7 @@
 #include "llworld.h"
 #include "llpanelface.h"
 // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1)
+#include "rlvactions.h"
 #include "rlvhandler.h"
 #include "rlvlocks.h"
 // [/RLVa:KB]
@@ -1641,6 +1642,14 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
 											  EAcceptance* accept,
 											  const LLSD& dest)
 {
+// [RLVa:KB] - @share
+	if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(dest_agent)) )
+	{
+		*accept = ACCEPT_NO_LOCKED;
+		return true;
+	}
+// [/RLVa:KB]
+
 	// check the type
 	switch(cargo_type)
 	{
@@ -2463,6 +2472,12 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryObject(
 	}
 	if( obj && avatar )
 	{
+// [RLVa:KB] - @share
+		if ( (obj) && (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(obj->getID())) )
+		{
+			return ACCEPT_NO_LOCKED;
+		}
+// [/RLVa:KB]
 		if(drop)
 		{
 			LLGiveInventory::doGiveInventoryItem(obj->getID(), item );
@@ -2489,6 +2504,12 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventory(
 	{
 		return ACCEPT_NO;
 	}
+// [RLVa:KB] - @share
+	if ( (obj) && (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(obj->getID())) )
+	{
+		return ACCEPT_NO_LOCKED;
+	}
+// [/RLVa:KB]
 	if (drop && obj)
 	{
 		LLGiveInventory::doGiveInventoryItem(obj->getID(), item);
@@ -2502,6 +2523,12 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryCategory(
 	LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
 {
 	LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventoryCategory()" << LL_ENDL;
+// [RLVa:KB] - @share
+	if ( (obj) && (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(obj->getID())) )
+	{
+		return ACCEPT_NO_LOCKED;
+	}
+// [/RLVa:KB]
 	if(drop && obj)
 	{
 		LLViewerInventoryItem* item;
diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp
index ee8ca58e8216f3d0ab687450a0643b8c85062d24..83f04fbb5b044d955d5c48afa640e221f34bbead 100644
--- a/indra/newview/rlvactions.cpp
+++ b/indra/newview/rlvactions.cpp
@@ -133,6 +133,20 @@ bool RlvActions::canChangeActiveGroup(const LLUUID& idRlvObject)
 	return (idRlvObject.isNull()) ? !gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP) : !gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, idRlvObject);
 }
 
+bool RlvActions::canGiveInventory()
+{
+	// User can give at least one (unspecified) avatar inventory if:
+	//   - not specifically restricted from giving inventory (or at least one exception exists)
+	return (!gRlvHandler.hasBehaviour(RLV_BHVR_SHARE)) || (gRlvHandler.hasException(RLV_BHVR_SHARE));
+}
+
+bool RlvActions::canGiveInventory(const LLUUID& idAgent)
+{
+	// User can give another avatar inventory if:
+	//   - not specifically restricted from giving inventory (or the target is an exception)
+	return (!gRlvHandler.hasBehaviour(RLV_BHVR_SHARE)) || (gRlvHandler.isException(RLV_BHVR_SHARE, idAgent));
+}
+
 // Little helper function to check the IM exclusion range for @recvim, @sendim and @startim (returns: min_dist <= (pos user - pos target) <= max_dist)
 static bool rlvCheckAvatarIMDistance(const LLUUID& idAvatar, ERlvBehaviourModifier eModDistMin, ERlvBehaviourModifier eModDistMax)
 {
diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h
index 69d499280c0d0e83f5edf78028d88a9ffc2de345..d14354994925d471e9c82c7b91ecae7b373ff86f 100644
--- a/indra/newview/rlvactions.h
+++ b/indra/newview/rlvactions.h
@@ -89,6 +89,16 @@ class RlvActions
 	 */
 	static bool canChangeActiveGroup(const LLUUID& idRlvObject = LLUUID::null);
 
+	/*
+	 * Returns true if the user is allowed to give inventory to at least one (unspecified) avatar (used to blanket ban use of 'Share' if the user cannot give items to *anyone*)
+	 */
+	static bool canGiveInventory();
+
+	/*
+	 * Returns true if the user is allowed to give the specified avatar inventory
+	 */
+	static bool canGiveInventory(const LLUUID& idAgent);
+
 	/*
 	 * Returns true if the user is allowed to receive IMs from the specified sender (can be an avatar or a group)
 	 */
diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h
index b0b869b640fcdb4f38c151e1608c941602bd9840..4d40fc14ba64fd985037a42ef1d411b408b43bb2 100644
--- a/indra/newview/rlvdefines.h
+++ b/indra/newview/rlvdefines.h
@@ -129,6 +129,7 @@ enum ERlvBehaviour {
 	RLV_BHVR_SENDGESTURE,
 	RLV_BHVR_PERMISSIVE,			// "permissive"
 	RLV_BHVR_NOTIFY,				// "notify"
+	RLV_BHVR_SHARE,
 	RLV_BHVR_SHOWINV,				// "showinv"
 	RLV_BHVR_SHOWMINIMAP,			// "showminimap"
 	RLV_BHVR_SHOWWORLDMAP,			// "showworldmap"
@@ -460,6 +461,8 @@ namespace RlvStringKeys
 		/*inline*/ constexpr boost::string_view RecvIm = make_string_view("blocked_recvim");
 		/*inline*/ constexpr boost::string_view RecvImRemote = make_string_view("blocked_recvim_remote");
 		/*inline*/ constexpr boost::string_view SendIm = make_string_view("blocked_sendim");
+		/*inline*/ constexpr boost::string_view Share = make_string_view("blocked_share");
+		/*inline*/ constexpr boost::string_view ShareGeneric = make_string_view("blocked_share_generic");
 		/*inline*/ constexpr boost::string_view StartConference = make_string_view("blocked_startconf");
 		/*inline*/ constexpr boost::string_view StartIm = make_string_view("blocked_startim");
 		/*inline*/ constexpr boost::string_view Teleport = make_string_view("blocked_teleport");
@@ -477,6 +480,8 @@ namespace RlvStringKeys
 		constexpr const char RecvIm[] = "blocked_recvim";
 		constexpr const char RecvImRemote[] = "blocked_recvim_remote";
 		constexpr const char SendIm[] = "blocked_sendim";
+		constexpr const char Share[] = "blocked_share";
+		constexpr const char ShareGeneric[] = "blocked_share_generic";
 		constexpr const char StartConference[] = "blocked_startconf";
 		constexpr const char StartIm[] = "blocked_startim";
 		constexpr const char Teleport[] = "blocked_teleport";
diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp
index e7c3d7f0ef02db8e47b1910906f5d8b81b37ad9e..2eeee306d3456da494242527da33399bf13c2ad7 100644
--- a/indra/newview/rlvhelper.cpp
+++ b/indra/newview/rlvhelper.cpp
@@ -138,6 +138,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
 	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETDEBUG, RLV_OPTION_NONE>("setdebug"));
 	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETENV, RLV_OPTION_NONE>("setenv"));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("setgroup", RLV_BHVR_SETGROUP));
+	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("share", RLV_BHVR_SHARE, RlvBehaviourInfo::BHVR_STRICT));
 	addEntry(new RlvBehaviourInfo("sharedunwear",			RLV_BHVR_SHAREDUNWEAR,			RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED));
 	addEntry(new RlvBehaviourInfo("sharedwear",				RLV_BHVR_SHAREDWEAR,			RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED));
 	addEntry(new RlvBehaviourProcessor<RLV_BHVR_SHOWHOVERTEXT>("showhovertext"));
diff --git a/indra/newview/skins/default/xui/en/rlva_strings.xml b/indra/newview/skins/default/xui/en/rlva_strings.xml
index de0e99d6d0949a6a1dec9013a380b5477fca062d..3ffb3d90094faa6b79b16e959a6ecb84b45d39a9 100644
--- a/indra/newview/skins/default/xui/en/rlva_strings.xml
+++ b/indra/newview/skins/default/xui/en/rlva_strings.xml
@@ -141,6 +141,16 @@
 			<key>value</key>
 			<string>Unable to show script dialog or textbox due to RLV restrictions</string>
 		</map>
+		<key>blocked_share</key>
+		<map>
+			<key>value</key>
+			<string>Unable to share inventory with [RECIPIENT] due to RLV restrictions.</string>
+		</map>
+		<key>blocked_share_generic</key>
+		<map>
+			<key>value</key>
+			<string>Unable to share inventory due to RLV restrictions.</string>
+		</map>
 		<key>blocked_startim</key>
 		<map>
 			<key>value</key>