diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua
index f54b2f1ad3b65b60c575f218c9a82b4c9cccabe2..5500d6419a0923145ef7062b5de772347666f970 100644
--- a/mods/tnt/init.lua
+++ b/mods/tnt/init.lua
@@ -86,8 +86,8 @@ end
 local basic_flame_on_construct -- cached value
 local function destroy(drops, npos, cid, c_air, c_fire,
 		on_blast_queue, on_construct_queue,
-		ignore_protection, ignore_on_blast)
-	if not ignore_protection and minetest.is_protected(npos, "") then
+		ignore_protection, ignore_on_blast, owner)
+	if not ignore_protection and minetest.is_protected(npos, owner) then
 		return cid
 	end
 
@@ -266,13 +266,13 @@ function tnt.burn(pos, nodename)
 	elseif def.on_ignite then
 		def.on_ignite(pos)
 	elseif minetest.get_item_group(name, "tnt") > 0 then
+		minetest.swap_node(pos, {name = name .. "_burning"})
 		minetest.sound_play("tnt_ignite", {pos = pos})
-		minetest.set_node(pos, {name = name .. "_burning"})
 		minetest.get_node_timer(pos):start(1)
 	end
 end
 
-local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
+local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast, owner)
 	pos = vector.round(pos)
 	-- scan for adjacent TNT nodes first, and enlarge the explosion
 	local vm1 = VoxelManip()
@@ -333,7 +333,7 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
 			if cid ~= c_air then
 				data[vi] = destroy(drops, p, cid, c_air, c_fire,
 					on_blast_queue, on_construct_queue,
-					ignore_protection, ignore_on_blast)
+					ignore_protection, ignore_on_blast, owner)
 			end
 		end
 		vi = vi + 1
@@ -375,14 +375,19 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
 		queued_data.fn(queued_data.pos)
 	end
 
+	minetest.log("action", "TNT owned by " .. owner .. " detonated at " ..
+		minetest.pos_to_string(pos) .. " with radius " .. radius)
+
 	return drops, radius
 end
 
 function tnt.boom(pos, def)
+	local meta = minetest.get_meta(pos)
+	local owner = meta:get_string("owner")
 	minetest.sound_play("tnt_explode", {pos = pos, gain = 1.5, max_hear_distance = 2*64})
 	minetest.set_node(pos, {name = "tnt:boom"})
 	local drops, radius = tnt_explode(pos, def.radius, def.ignore_protection,
-			def.ignore_on_blast)
+			def.ignore_on_blast, owner)
 	-- append entity drops
 	local damage_radius = (radius / def.radius) * def.damage_radius
 	entity_physics(pos, damage_radius, drops)
@@ -579,9 +584,16 @@ function tnt.register_tnt(def)
 			is_ground_content = false,
 			groups = {dig_immediate = 2, mesecon = 2, tnt = 1, flammable = 5},
 			sounds = default.node_sound_wood_defaults(),
+			after_place_node = function(pos, placer)
+				if placer:is_player() then
+					local meta = minetest.get_meta(pos)
+					meta:set_string("owner", placer:get_player_name())
+				end
+			end,
 			on_punch = function(pos, node, puncher)
 				if puncher:get_wielded_item():get_name() == "default:torch" then
-					minetest.set_node(pos, {name = name .. "_burning"})
+					minetest.swap_node(pos, {name = name .. "_burning"})
+					minetest.registered_nodes[name .. "_burning"].on_construct(pos)
 					minetest.log("action", puncher:get_player_name() ..
 						" ignites " .. node.name .. " at " ..
 						minetest.pos_to_string(pos))
@@ -600,10 +612,12 @@ function tnt.register_tnt(def)
 				}
 			},
 			on_burn = function(pos)
-				minetest.set_node(pos, {name = name .. "_burning"})
+				minetest.swap_node(pos, {name = name .. "_burning"})
+				minetest.registered_nodes[name .. "_burning"].on_construct(pos)
 			end,
 			on_ignite = function(pos, igniter)
-				minetest.set_node(pos, {name = name .. "_burning"})
+				minetest.swap_node(pos, {name = name .. "_burning"})
+				minetest.registered_nodes[name .. "_burning"].on_construct(pos)
 			end,
 		})
 	end