diff --git a/src/debug.h b/src/debug.h
index 5cc1e6c4d1fca599be09d1b3d7bce7090c684167..234b7c74afd4dbdd6290ea792217267f93cb0a72 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -169,7 +169,10 @@ class DebugStacker
 	bool m_overflowed;
 };
 
-#define DSTACK(...)\
+#define DSTACK(msg)\
+	DebugStacker __debug_stacker(msg);
+
+#define DSTACKF(...)\
 	char __buf[DEBUG_STACK_TEXT_SIZE];\
 	snprintf(__buf,\
 			DEBUG_STACK_TEXT_SIZE, __VA_ARGS__);\
diff --git a/src/map.cpp b/src/map.cpp
index 02614e1aed8663540e3d0a6e6e403181c02afba4..63f01ddee0de773018e2d02481467b4eb0874a97 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -3830,7 +3830,7 @@ MapChunk* ServerMap::generateChunk(v2s16 chunkpos1,
 
 ServerMapSector * ServerMap::createSector(v2s16 p2d)
 {
-	DSTACK("%s: p2d=(%d,%d)",
+	DSTACKF("%s: p2d=(%d,%d)",
 			__FUNCTION_NAME,
 			p2d.X, p2d.Y);
 	
@@ -3982,7 +3982,7 @@ MapBlock * ServerMap::generateBlock(
 		core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
 )
 {
-	DSTACK("%s: p=(%d,%d,%d)",
+	DSTACKF("%s: p=(%d,%d,%d)",
 			__FUNCTION_NAME,
 			p.X, p.Y, p.Z);
 
@@ -4618,7 +4618,7 @@ MapBlock * ServerMap::generateBlock(
 
 MapBlock * ServerMap::createBlock(v3s16 p)
 {
-	DSTACK("%s: p=(%d,%d,%d)",
+	DSTACKF("%s: p=(%d,%d,%d)",
 			__FUNCTION_NAME, p.X, p.Y, p.Z);
 	
 	/*
@@ -4682,7 +4682,7 @@ MapBlock * ServerMap::emergeBlock(
 		core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
 )
 {
-	DSTACK("%s: p=(%d,%d,%d), only_from_disk=%d",
+	DSTACKF("%s: p=(%d,%d,%d), only_from_disk=%d",
 			__FUNCTION_NAME,
 			p.X, p.Y, p.Z, only_from_disk);
 	
diff --git a/src/mapblockobject.cpp b/src/mapblockobject.cpp
index 343926f8152f733426ea8f949f927541e267e716..d05eee808891f5f112b748e3204b9d280ab239fe 100644
--- a/src/mapblockobject.cpp
+++ b/src/mapblockobject.cpp
@@ -63,7 +63,7 @@ v3f MovingObject::getAbsoluteShowPos()
 
 void MovingObject::move(float dtime, v3f acceleration)
 {
-	DSTACK("%s: typeid=%i, pos=(%f,%f,%f), speed=(%f,%f,%f)"
+	DSTACKF("%s: typeid=%i, pos=(%f,%f,%f), speed=(%f,%f,%f)"
 			", dtime=%f, acc=(%f,%f,%f)",
 			__FUNCTION_NAME,
 			getTypeId(),
@@ -755,7 +755,7 @@ void MapBlockObjectList::step(float dtime, bool server, u32 daynight_ratio)
 	core::map<s16, bool> ids_to_delete;
 
 	{
-		DSTACK("%s: stepping objects", __FUNCTION_NAME);
+		DSTACKF("%s: stepping objects", __FUNCTION_NAME);
 
 		for(core::map<s16, MapBlockObject*>::Iterator
 				i = m_objects.getIterator();
@@ -763,7 +763,7 @@ void MapBlockObjectList::step(float dtime, bool server, u32 daynight_ratio)
 		{
 			MapBlockObject *obj = i.getNode()->getValue();
 			
-			DSTACK("%s: stepping object type %i", __FUNCTION_NAME,
+			DSTACKF("%s: stepping object type %i", __FUNCTION_NAME,
 					obj->getTypeId());
 
 			if(server)
@@ -791,7 +791,7 @@ void MapBlockObjectList::step(float dtime, bool server, u32 daynight_ratio)
 	}
 
 	{
-		DSTACK("%s: deleting objects", __FUNCTION_NAME);
+		DSTACKF("%s: deleting objects", __FUNCTION_NAME);
 
 		// Delete objects in delete queue
 		for(core::map<s16, bool>::Iterator
@@ -815,7 +815,7 @@ void MapBlockObjectList::step(float dtime, bool server, u32 daynight_ratio)
 		return;
 	
 	{
-		DSTACK("%s: object wrap loop", __FUNCTION_NAME);
+		DSTACKF("%s: object wrap loop", __FUNCTION_NAME);
 
 		for(core::map<s16, MapBlockObject*>::Iterator
 				i = m_objects.getIterator();
diff --git a/src/server.cpp b/src/server.cpp
index 6c57daa5c1b660cbfe595a4dc68f9918c1d596f9..d211186eb0cdcbdc2a55a9627b6e2156d8f7a9b4 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -2870,12 +2870,18 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
 			message = message.substr(commandprefix.size());
 
+			// Local player gets all privileges regardless of
+			// what's set on their account.
+			u64 privs = player->privs;
+			if(g_settings.get("name") == player->getName())
+				privs = PRIV_ALL;
+
 			ServerCommandContext *ctx = new ServerCommandContext(
 				str_split(message, L' '),
 				this,
 				&m_env,
-				player
-				);
+				player,
+				privs);
 
 			line += processServerCommand(ctx);
 			send_to_sender = ctx->flags & 1;
diff --git a/src/servercommand.cpp b/src/servercommand.cpp
index 215dc0d275f09ff07efb0071c5620c03812bd8da..5bb4f67f823d437dff5325e5e6aacd02f1a7e80e 100644
--- a/src/servercommand.cpp
+++ b/src/servercommand.cpp
@@ -33,11 +33,13 @@ void cmd_privs(std::wostringstream &os,
 {
 	if(ctx->parms.size() == 1)
 	{
+		// Show our own real privs, without any adjustments
+		// made for admin status
 		os<<L"-!- " + privsToString(ctx->player->privs);
 		return;
 	}
 
-	if((ctx->player->privs & PRIV_PRIVS) == 0)
+	if((ctx->privs & PRIV_PRIVS) == 0)
 	{
 		os<<L"-!- You don't have permission to do that";
 		return;
@@ -62,7 +64,7 @@ void cmd_grantrevoke(std::wostringstream &os,
 		return;
 	}
 
-	if((ctx->player->privs & PRIV_PRIVS) == 0)
+	if((ctx->privs & PRIV_PRIVS) == 0)
 	{
 		os<<L"-!- You don't have permission to do that";
 		return;
@@ -100,7 +102,7 @@ void cmd_time(std::wostringstream &os,
 		return;
 	}
 
-	if((ctx->player->privs & PRIV_SETTIME) ==0)
+	if((ctx->privs & PRIV_SETTIME) ==0)
 	{
 		os<<L"-!- You don't have permission to do that";
 		return;
@@ -114,7 +116,7 @@ void cmd_time(std::wostringstream &os,
 void cmd_shutdown(std::wostringstream &os,
 	ServerCommandContext *ctx)
 {
-	if((ctx->player->privs & PRIV_SERVER) ==0)
+	if((ctx->privs & PRIV_SERVER) ==0)
 	{
 		os<<L"-!- You don't have permission to do that";
 		return;
@@ -131,7 +133,7 @@ void cmd_shutdown(std::wostringstream &os,
 void cmd_setting(std::wostringstream &os,
 	ServerCommandContext *ctx)
 {
-	if((ctx->player->privs & PRIV_SERVER) ==0)
+	if((ctx->privs & PRIV_SERVER) ==0)
 	{
 		os<<L"-!- You don't have permission to do that";
 		return;
@@ -145,7 +147,7 @@ void cmd_setting(std::wostringstream &os,
 void cmd_teleport(std::wostringstream &os,
 	ServerCommandContext *ctx)
 {
-	if((ctx->player->privs & PRIV_TELEPORT) ==0)
+	if((ctx->privs & PRIV_TELEPORT) ==0)
 	{
 		os<<L"-!- You don't have permission to do that";
 		return;
@@ -178,7 +180,7 @@ std::wstring processServerCommand(ServerCommandContext *ctx)
 	std::wostringstream os(std::ios_base::binary);
 	ctx->flags = 1;	// Default, unless we change it.
 
-	u64 privs = ctx->player->privs;
+	u64 privs = ctx->privs;
 
 	if(ctx->parms.size() == 0 || ctx->parms[0] == L"help")
 	{
diff --git a/src/servercommand.h b/src/servercommand.h
index bc7823c66ed0dc1dfa7241c02f509312f8bec9f8..058fbe65ba246c43aea3ee89a2fd467e9e4bce63 100644
--- a/src/servercommand.h
+++ b/src/servercommand.h
@@ -34,14 +34,18 @@ struct ServerCommandContext
 	Server* server;
 	ServerEnvironment *env;
 	Player* player;
+	// Effective privs for the player, which may be different to their
+	// stored ones - e.g. if they are named in the config as an admin.
+	u64 privs;
 	u32 flags;
 
 	ServerCommandContext(
 		std::vector<std::wstring> parms,
 		Server* server,
 		ServerEnvironment *env,
-		Player* player)
-		: parms(parms), server(server), env(env), player(player)
+		Player* player,
+		u64 privs)
+		: parms(parms), server(server), env(env), player(player), privs(privs)
 	{
 	}