Fix processing of the default_password setting. It is now actually used as the plaintext password for new users. Also add /setpassword and /clearpassword server commands that can be used by admins with the PRIV_PASSWORD privilege, and update the /help message.
parent
1901158b3e
commit
2ca00fa585
|
@ -42,6 +42,8 @@ std::set<std::string> privsToSet(u64 privs)
|
||||||
s.insert("ban");
|
s.insert("ban");
|
||||||
if(privs & PRIV_GIVE)
|
if(privs & PRIV_GIVE)
|
||||||
s.insert("give");
|
s.insert("give");
|
||||||
|
if(privs & PRIV_PASSWORD)
|
||||||
|
s.insert("password");
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +66,8 @@ std::string privsToString(u64 privs)
|
||||||
os<<"ban,";
|
os<<"ban,";
|
||||||
if(privs & PRIV_GIVE)
|
if(privs & PRIV_GIVE)
|
||||||
os<<"give,";
|
os<<"give,";
|
||||||
|
if(privs & PRIV_PASSWORD)
|
||||||
|
os<<"password,";
|
||||||
if(os.tellp())
|
if(os.tellp())
|
||||||
{
|
{
|
||||||
// Drop the trailing comma. (Why on earth can't
|
// Drop the trailing comma. (Why on earth can't
|
||||||
|
@ -98,6 +102,8 @@ u64 stringToPrivs(std::string str)
|
||||||
privs |= PRIV_BAN;
|
privs |= PRIV_BAN;
|
||||||
else if(s == "give")
|
else if(s == "give")
|
||||||
privs |= PRIV_GIVE;
|
privs |= PRIV_GIVE;
|
||||||
|
else if(s == "password")
|
||||||
|
privs |= PRIV_PASSWORD;
|
||||||
else
|
else
|
||||||
return PRIV_INVALID;
|
return PRIV_INVALID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ const u64 PRIV_SHOUT = 32; // Can broadcast chat messages to all
|
||||||
// players
|
// players
|
||||||
const u64 PRIV_BAN = 64; // Can ban players
|
const u64 PRIV_BAN = 64; // Can ban players
|
||||||
const u64 PRIV_GIVE = 128; // Can give stuff
|
const u64 PRIV_GIVE = 128; // Can give stuff
|
||||||
|
const u64 PRIV_PASSWORD = 256; // Can set other players' passwords
|
||||||
|
|
||||||
// Default privileges - these can be overriden for new players using the
|
// Default privileges - these can be overriden for new players using the
|
||||||
// config option "default_privs" - however, this value still applies for
|
// config option "default_privs" - however, this value still applies for
|
||||||
|
|
|
@ -2171,20 +2171,33 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
password[PASSWORD_SIZE-1] = 0;
|
password[PASSWORD_SIZE-1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string checkpwd;
|
// Add player to auth manager
|
||||||
if(m_authmanager.exists(playername))
|
if(m_authmanager.exists(playername) == false)
|
||||||
{
|
{
|
||||||
checkpwd = m_authmanager.getPassword(playername);
|
std::wstring default_password =
|
||||||
|
narrow_to_wide(g_settings->get("default_password"));
|
||||||
|
std::string translated_default_password =
|
||||||
|
translatePassword(playername, default_password);
|
||||||
|
|
||||||
|
// If default_password is empty, allow any initial password
|
||||||
|
if (default_password.length() == 0)
|
||||||
|
translated_default_password = password;
|
||||||
|
|
||||||
|
infostream<<"Server: adding player "<<playername
|
||||||
|
<<" to auth manager"<<std::endl;
|
||||||
|
m_authmanager.add(playername);
|
||||||
|
m_authmanager.setPassword(playername, translated_default_password);
|
||||||
|
m_authmanager.setPrivs(playername,
|
||||||
|
stringToPrivs(g_settings->get("default_privs")));
|
||||||
|
m_authmanager.save();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
std::string checkpwd = m_authmanager.getPassword(playername);
|
||||||
checkpwd = g_settings->get("default_password");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*infostream<<"Server: Client gave password '"<<password
|
/*infostream<<"Server: Client gave password '"<<password
|
||||||
<<"', the correct one is '"<<checkpwd<<"'"<<std::endl;*/
|
<<"', the correct one is '"<<checkpwd<<"'"<<std::endl;*/
|
||||||
|
|
||||||
if(password != checkpwd && m_authmanager.exists(playername))
|
if(password != checkpwd)
|
||||||
{
|
{
|
||||||
infostream<<"Server: peer_id="<<peer_id
|
infostream<<"Server: peer_id="<<peer_id
|
||||||
<<": supplied invalid password for "
|
<<": supplied invalid password for "
|
||||||
|
@ -2193,23 +2206,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add player to auth manager
|
|
||||||
if(m_authmanager.exists(playername) == false)
|
|
||||||
{
|
|
||||||
infostream<<"Server: adding player "<<playername
|
|
||||||
<<" to auth manager"<<std::endl;
|
|
||||||
m_authmanager.add(playername);
|
|
||||||
m_authmanager.setPassword(playername, checkpwd);
|
|
||||||
m_authmanager.setPrivs(playername,
|
|
||||||
stringToPrivs(g_settings->get("default_privs")));
|
|
||||||
m_authmanager.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enforce user limit.
|
// Enforce user limit.
|
||||||
// Don't enforce for users that have some admin right
|
// Don't enforce for users that have some admin right
|
||||||
if(m_clients.size() >= g_settings->getU16("max_users") &&
|
if(m_clients.size() >= g_settings->getU16("max_users") &&
|
||||||
(m_authmanager.getPrivs(playername)
|
(m_authmanager.getPrivs(playername)
|
||||||
& (PRIV_SERVER|PRIV_BAN|PRIV_PRIVS)) == 0 &&
|
& (PRIV_SERVER|PRIV_BAN|PRIV_PRIVS|PRIV_PASSWORD)) == 0 &&
|
||||||
playername != g_settings->get("name"))
|
playername != g_settings->get("name"))
|
||||||
{
|
{
|
||||||
SendAccessDenied(m_con, peer_id, L"Too many users.");
|
SendAccessDenied(m_con, peer_id, L"Too many users.");
|
||||||
|
@ -2217,7 +2218,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get player
|
// Get player
|
||||||
Player *player = emergePlayer(playername, password, peer_id);
|
Player *player = emergePlayer(playername, peer_id);
|
||||||
|
|
||||||
// If failed, cancel
|
// If failed, cancel
|
||||||
if(player == NULL)
|
if(player == NULL)
|
||||||
|
@ -4678,6 +4679,22 @@ std::wstring Server::getStatusString()
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::setPlayerPassword(const std::string &name, const std::wstring &password)
|
||||||
|
{
|
||||||
|
// Add player to auth manager
|
||||||
|
if(m_authmanager.exists(name) == false)
|
||||||
|
{
|
||||||
|
infostream<<"Server: adding player "<<name
|
||||||
|
<<" to auth manager"<<std::endl;
|
||||||
|
m_authmanager.add(name);
|
||||||
|
m_authmanager.setPrivs(name,
|
||||||
|
stringToPrivs(g_settings->get("default_privs")));
|
||||||
|
}
|
||||||
|
// Change password and save
|
||||||
|
m_authmanager.setPassword(name, translatePassword(name, password));
|
||||||
|
m_authmanager.save();
|
||||||
|
}
|
||||||
|
|
||||||
// Saves g_settings to configpath given at initialization
|
// Saves g_settings to configpath given at initialization
|
||||||
void Server::saveConfig()
|
void Server::saveConfig()
|
||||||
{
|
{
|
||||||
|
@ -4813,7 +4830,7 @@ v3f findSpawnPos(ServerMap &map)
|
||||||
return intToFloat(nodepos, BS);
|
return intToFloat(nodepos, BS);
|
||||||
}
|
}
|
||||||
|
|
||||||
Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id)
|
Player *Server::emergePlayer(const char *name, u16 peer_id)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Try to get an existing player
|
Try to get an existing player
|
||||||
|
@ -4859,12 +4876,6 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
|
||||||
Create a new player
|
Create a new player
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
// Add authentication stuff
|
|
||||||
m_authmanager.add(name);
|
|
||||||
m_authmanager.setPassword(name, password);
|
|
||||||
m_authmanager.setPrivs(name,
|
|
||||||
stringToPrivs(g_settings->get("default_privs")));
|
|
||||||
|
|
||||||
/* Set player position */
|
/* Set player position */
|
||||||
|
|
||||||
infostream<<"Server: Finding spawn place for player \""
|
infostream<<"Server: Finding spawn place for player \""
|
||||||
|
|
|
@ -456,6 +456,10 @@ public:
|
||||||
dstream<<"WARNING: Auth not found for "<<name<<std::endl;
|
dstream<<"WARNING: Auth not found for "<<name<<std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Changes a player's password, password must be given as plaintext
|
||||||
|
// If the player doesn't exist, a new entry is added to the auth manager
|
||||||
|
void setPlayerPassword(const std::string &name, const std::wstring &password);
|
||||||
|
|
||||||
// Saves g_settings to configpath given at initialization
|
// Saves g_settings to configpath given at initialization
|
||||||
void saveConfig();
|
void saveConfig();
|
||||||
|
@ -591,12 +595,11 @@ private:
|
||||||
/*
|
/*
|
||||||
Get a player from memory or creates one.
|
Get a player from memory or creates one.
|
||||||
If player is already connected, return NULL
|
If player is already connected, return NULL
|
||||||
The password is not checked here - it is only used to
|
Does not verify/modify auth info and password.
|
||||||
set the password if a new player is created.
|
|
||||||
|
|
||||||
Call with env and con locked.
|
Call with env and con locked.
|
||||||
*/
|
*/
|
||||||
Player *emergePlayer(const char *name, const char *password, u16 peer_id);
|
Player *emergePlayer(const char *name, u16 peer_id);
|
||||||
|
|
||||||
// Locks environment and connection by its own
|
// Locks environment and connection by its own
|
||||||
struct PeerChange;
|
struct PeerChange;
|
||||||
|
|
|
@ -281,6 +281,54 @@ void cmd_banunban(std::wostringstream &os, ServerCommandContext *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmd_setclearpassword(std::wostringstream &os,
|
||||||
|
ServerCommandContext *ctx)
|
||||||
|
{
|
||||||
|
if((ctx->privs & PRIV_PASSWORD) == 0)
|
||||||
|
{
|
||||||
|
os<<L"-!- You don't have permission to do that";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string playername;
|
||||||
|
std::wstring password;
|
||||||
|
|
||||||
|
if(ctx->parms[0] == L"setpassword")
|
||||||
|
{
|
||||||
|
if(ctx->parms.size() != 3)
|
||||||
|
{
|
||||||
|
os<<L"-!- Missing parameter";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
playername = wide_to_narrow(ctx->parms[1]);
|
||||||
|
password = ctx->parms[2];
|
||||||
|
|
||||||
|
actionstream<<ctx->player->getName()<<" sets password of "
|
||||||
|
<<playername<<std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// clearpassword
|
||||||
|
|
||||||
|
if(ctx->parms.size() != 2)
|
||||||
|
{
|
||||||
|
os<<L"-!- Missing parameter";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
playername = wide_to_narrow(ctx->parms[1]);
|
||||||
|
password = L"";
|
||||||
|
|
||||||
|
actionstream<<ctx->player->getName()<<" clears password of"
|
||||||
|
<<playername<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->server->setPlayerPassword(playername, password);
|
||||||
|
|
||||||
|
os<<L"-!- Password change for "<<narrow_to_wide(playername)<<" successful";
|
||||||
|
}
|
||||||
|
|
||||||
void cmd_clearobjects(std::wostringstream &os,
|
void cmd_clearobjects(std::wostringstream &os,
|
||||||
ServerCommandContext *ctx)
|
ServerCommandContext *ctx)
|
||||||
{
|
{
|
||||||
|
@ -322,9 +370,9 @@ std::wstring processServerCommand(ServerCommandContext *ctx)
|
||||||
if(ctx->parms.size() == 0 || ctx->parms[0] == L"help")
|
if(ctx->parms.size() == 0 || ctx->parms[0] == L"help")
|
||||||
{
|
{
|
||||||
os<<L"-!- Available commands: ";
|
os<<L"-!- Available commands: ";
|
||||||
os<<L"status privs ";
|
os<<L"me status privs";
|
||||||
if(privs & PRIV_SERVER)
|
if(privs & PRIV_SERVER)
|
||||||
os<<L"shutdown setting ";
|
os<<L" shutdown setting clearobjects";
|
||||||
if(privs & PRIV_SETTIME)
|
if(privs & PRIV_SETTIME)
|
||||||
os<<L" time";
|
os<<L" time";
|
||||||
if(privs & PRIV_TELEPORT)
|
if(privs & PRIV_TELEPORT)
|
||||||
|
@ -333,6 +381,8 @@ std::wstring processServerCommand(ServerCommandContext *ctx)
|
||||||
os<<L" grant revoke";
|
os<<L" grant revoke";
|
||||||
if(privs & PRIV_BAN)
|
if(privs & PRIV_BAN)
|
||||||
os<<L" ban unban";
|
os<<L" ban unban";
|
||||||
|
if(privs & PRIV_PASSWORD)
|
||||||
|
os<<L" setpassword clearpassword";
|
||||||
}
|
}
|
||||||
else if(ctx->parms[0] == L"status")
|
else if(ctx->parms[0] == L"status")
|
||||||
cmd_status(os, ctx);
|
cmd_status(os, ctx);
|
||||||
|
@ -350,6 +400,8 @@ std::wstring processServerCommand(ServerCommandContext *ctx)
|
||||||
cmd_teleport(os, ctx);
|
cmd_teleport(os, ctx);
|
||||||
else if(ctx->parms[0] == L"ban" || ctx->parms[0] == L"unban")
|
else if(ctx->parms[0] == L"ban" || ctx->parms[0] == L"unban")
|
||||||
cmd_banunban(os, ctx);
|
cmd_banunban(os, ctx);
|
||||||
|
else if(ctx->parms[0] == L"setpassword" || ctx->parms[0] == L"clearpassword")
|
||||||
|
cmd_setclearpassword(os, ctx);
|
||||||
else if(ctx->parms[0] == L"me")
|
else if(ctx->parms[0] == L"me")
|
||||||
cmd_me(os, ctx);
|
cmd_me(os, ctx);
|
||||||
else if(ctx->parms[0] == L"clearobjects")
|
else if(ctx->parms[0] == L"clearobjects")
|
||||||
|
|
Loading…
Reference in New Issue