Make CUser::m_sUserName constant

Changing the user name for a CUser instance is a really, really bad idea. There
are lots of paths that depend on the user name and only few of them are fixed up
when the user name changes.

This fixes a problem where admin's "CloneUser from to" caused problems with
modules, because all modules where loaded under the old user name and thus they
read/write NV data from the wrong directory in ~/.znc/users.

Thanks to un1matr1x for reporting this.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter
2011-02-24 19:09:46 +01:00
parent 0b8f9eec42
commit d44e590336
3 changed files with 14 additions and 22 deletions

View File

@@ -48,10 +48,15 @@ protected:
CUser* m_pUser;
};
CUser::CUser(const CString& sUserName) {
CUser::CUser(const CString& sUserName)
: m_sUserName(sUserName), m_sCleanUserName(MakeCleanUserName(sUserName))
{
// set paths that depend on the user name:
m_sUserPath = CZNC::Get().GetUserPath() + "/" + m_sUserName;
m_sDLPath = m_sUserPath + "/downloads";
m_pIRCSock = NULL;
m_fTimezoneOffset = 0;
SetUserName(sUserName);
m_sNick = m_sCleanUserName;
m_sIdent = m_sCleanUserName;
m_sRealName = sUserName;
@@ -343,13 +348,11 @@ bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneChans) {
return false;
}
// user names can only specified for the constructor, changing it later
// on breaks too much stuff (e.g. lots of paths depend on the user name)
if (GetUserName() != User.GetUserName()) {
if (CZNC::Get().FindUser(User.GetUserName())) {
sErrorRet = "New username already exists";
return false;
}
SetUserName(User.GetUserName());
DEBUG("Ignoring username in CUser::Clone(), old username [" << GetUserName()
<< "]; New username [" << User.GetUserName() << "]");
}
if (!User.GetPass().empty()) {
@@ -1205,15 +1208,6 @@ CString CUser::MakeCleanUserName(const CString& sUserName) {
}
// Setters
void CUser::SetUserName(const CString& s) {
m_sCleanUserName = CUser::MakeCleanUserName(s);
m_sUserName = s;
// set paths that depend on the user name:
m_sUserPath = CZNC::Get().GetUserPath() + "/" + m_sUserName;
m_sDLPath = GetUserPath() + "/downloads";
}
bool CUser::IsChan(const CString& sChan) const {
if (sChan.empty())
return false; // There is no way this is a chan

5
User.h
View File

@@ -136,7 +136,6 @@ public:
void AddBytesWritten(unsigned long long u) { m_uBytesWritten += u; }
// Setters
void SetUserName(const CString& s);
void SetNick(const CString& s);
void SetAltNick(const CString& s);
void SetIdent(const CString& s);
@@ -230,8 +229,8 @@ private:
void JoinChans(set<CChan*>& sChans);
protected:
CString m_sUserName;
CString m_sCleanUserName;
const CString m_sUserName;
const CString m_sCleanUserName;
CString m_sNick;
CString m_sAltNick;
CString m_sIdent;

View File

@@ -563,14 +563,13 @@ class CAdminMod : public CModule {
return;
}
CUser* pNewUser = new CUser(sOldUsername);
CUser* pNewUser = new CUser(sNewUsername);
CString sError;
if (!pNewUser->Clone(*pOldUser, sError)) {
delete pNewUser;
PutModule("Error: Cloning failed! [" + sError + "]");
return;
}
pNewUser->SetUserName(sNewUsername);
pNewUser->SetIRCConnectEnabled(false);
if (!CZNC::Get().AddUser(pNewUser, sError)) {