password[PASSWORD_SIZE-1] = 0;
}
- std::string checkpwd;
- if(m_authmanager.exists(playername))
- {
- checkpwd = m_authmanager.getPassword(playername);
- }
- else
+ // Add player to auth manager
+ if(m_authmanager.exists(playername) == false)
{
- checkpwd = g_settings->get("default_password");
+ 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();
}
-
+
+ std::string checkpwd = m_authmanager.getPassword(playername);
+
/*infostream<<"Server: Client gave password '"<<password
<<"', the correct one is '"<<checkpwd<<"'"<<std::endl;*/
-
- if(password != checkpwd && m_authmanager.exists(playername))
+
+ if(password != checkpwd)
{
infostream<<"Server: peer_id="<<peer_id
<<": supplied invalid password for "
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.
// Don't enforce for users that have some admin right
if(m_clients.size() >= g_settings->getU16("max_users") &&
(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"))
{
SendAccessDenied(m_con, peer_id, L"Too many users.");
}
// Get player
- Player *player = emergePlayer(playername, password, peer_id);
+ Player *player = emergePlayer(playername, peer_id);
// If failed, cancel
if(player == NULL)
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
void Server::saveConfig()
{
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
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 */
infostream<<"Server: Finding spawn place for player \""
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
void saveConfig();
/*
Get a player from memory or creates one.
If player is already connected, return NULL
- The password is not checked here - it is only used to
- set the password if a new player is created.
+ Does not verify/modify auth info and password.
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
struct PeerChange;
}
}
+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,
ServerCommandContext *ctx)
{
if(ctx->parms.size() == 0 || ctx->parms[0] == L"help")
{
os<<L"-!- Available commands: ";
- os<<L"status privs ";
+ os<<L"me status privs";
if(privs & PRIV_SERVER)
- os<<L"shutdown setting ";
+ os<<L" shutdown setting clearobjects";
if(privs & PRIV_SETTIME)
os<<L" time";
if(privs & PRIV_TELEPORT)
os<<L" grant revoke";
if(privs & PRIV_BAN)
os<<L" ban unban";
+ if(privs & PRIV_PASSWORD)
+ os<<L" setpassword clearpassword";
}
else if(ctx->parms[0] == L"status")
cmd_status(os, ctx);
cmd_teleport(os, ctx);
else if(ctx->parms[0] == L"ban" || ctx->parms[0] == L"unban")
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")
cmd_me(os, ctx);
else if(ctx->parms[0] == L"clearobjects")