diff --git a/src/auth.cpp b/src/auth.cpp index 684391654..9920e0e40 100644 --- a/src/auth.cpp +++ b/src/auth.cpp @@ -42,6 +42,8 @@ std::set privsToSet(u64 privs) s.insert("ban"); if(privs & PRIV_GIVE) s.insert("give"); + if(privs & PRIV_PASSWORD) + s.insert("password"); return s; } @@ -64,6 +66,8 @@ std::string privsToString(u64 privs) os<<"ban,"; if(privs & PRIV_GIVE) os<<"give,"; + if(privs & PRIV_PASSWORD) + os<<"password,"; if(os.tellp()) { // Drop the trailing comma. (Why on earth can't @@ -98,6 +102,8 @@ u64 stringToPrivs(std::string str) privs |= PRIV_BAN; else if(s == "give") privs |= PRIV_GIVE; + else if(s == "password") + privs |= PRIV_PASSWORD; else return PRIV_INVALID; } diff --git a/src/auth.h b/src/auth.h index 9939632a9..0ef94735f 100644 --- a/src/auth.h +++ b/src/auth.h @@ -41,6 +41,7 @@ const u64 PRIV_SHOUT = 32; // Can broadcast chat messages to all // players const u64 PRIV_BAN = 64; // Can ban players 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 // config option "default_privs" - however, this value still applies for diff --git a/src/server.cpp b/src/server.cpp index 5646c0ac9..660fdfea9 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2171,20 +2171,33 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) password[PASSWORD_SIZE-1] = 0; } - std::string checkpwd; - if(m_authmanager.exists(playername)) + // Add player to auth manager + 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 "<get("default_privs"))); + m_authmanager.save(); } - else - { - checkpwd = g_settings->get("default_password"); - } - + + std::string checkpwd = m_authmanager.getPassword(playername); + /*infostream<<"Server: Client gave password '"<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."); @@ -2217,7 +2218,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) } // Get player - Player *player = emergePlayer(playername, password, peer_id); + Player *player = emergePlayer(playername, peer_id); // If failed, cancel if(player == NULL) @@ -4678,6 +4679,22 @@ std::wstring Server::getStatusString() 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 "<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() { @@ -4813,7 +4830,7 @@ v3f findSpawnPos(ServerMap &map) 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 @@ -4859,12 +4876,6 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id 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 \"" diff --git a/src/server.h b/src/server.h index 98c4f65d6..618b05d99 100644 --- a/src/server.h +++ b/src/server.h @@ -456,6 +456,10 @@ public: dstream<<"WARNING: Auth not found for "<privs & PRIV_PASSWORD) == 0) + { + os<parms[0] == L"setpassword") + { + if(ctx->parms.size() != 3) + { + os<parms[1]); + password = ctx->parms[2]; + + actionstream<player->getName()<<" sets password of " + <parms.size() != 2) + { + os<parms[1]); + password = L""; + + actionstream<player->getName()<<" clears password of" + <server->setPlayerPassword(playername, password); + + os<parms.size() == 0 || ctx->parms[0] == L"help") { os<parms[0] == L"status") cmd_status(os, ctx); @@ -350,6 +400,8 @@ std::wstring processServerCommand(ServerCommandContext *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")