znc-0.052-add_denysetvhost2.diff
2007-12-17 Veit Wahlich <cru@ircnet.de>

This patch adds "Deny SetVHost" capabilities to znc and webadmin to disallow
certain users to change their VHost.

==============================================================================
diff -N -r --unified=5 znc-0.052.orig/AUTHORS znc-0.052/AUTHORS
--- znc-0.052.orig/AUTHORS	2007-05-16 00:19:13.000000000 +0200
+++ znc-0.052/AUTHORS	2007-12-19 14:37:07.000000000 +0100
@@ -36,5 +36,8 @@
 Zack3000 - BetaTester, ShellProvider
 	Provided shell for testing
 
 d4n13L <daniel@danielschmitz.de> - WebDesigner
 	Contributed graphiX webadmin skin
+
+Veit "Cru" Wahlich <cru@ircnet.de> - Patches
+	Implementation of "Deny SetVHost" capabilities in znc and webadmin
diff -N -r --unified=5 znc-0.052.orig/Client.cpp znc-0.052/Client.cpp
--- znc-0.052.orig/Client.cpp	2007-11-17 23:41:26.000000000 +0100
+++ znc-0.052/Client.cpp	2007-12-19 15:47:28.000000000 +0100
@@ -1287,11 +1287,11 @@
 		PutStatus(sModRet);
 #else
 		PutStatus("Unable to unload [" + sMod + "] Modules are not enabled.");
 #endif
 		return;
-	} else if (sCommand.CaseCmp("SETVHOST") == 0) {
+	} else if (sCommand.CaseCmp("SETVHOST") == 0 && (m_pUser->IsAdmin() || !m_pUser->DenySetVHost())) {
 		CString sVHost = sLine.Token(1);
 
 		if (sVHost.empty()) {
 			PutStatus("Usage: SetVHost <VHost>");
 		}
@@ -1460,11 +1460,13 @@
 	Table.AddRow(); Table.SetCell("Command", "RemServer");	Table.SetCell("Arguments", "<host>");				Table.SetCell("Description", "Remove a server from the list");
 	Table.AddRow(); Table.SetCell("Command", "Topics");		Table.SetCell("Arguments", "");						Table.SetCell("Description", "Show topics in all channels");
 	Table.AddRow(); Table.SetCell("Command", "PlayBuffer");	Table.SetCell("Arguments", "<#chan>");				Table.SetCell("Description", "Play back the buffer for a given channel");
 	Table.AddRow(); Table.SetCell("Command", "ClearBuffer");Table.SetCell("Arguments", "<#chan>");				Table.SetCell("Description", "Clear the buffer for a given channel");
 	Table.AddRow(); Table.SetCell("Command", "SetBuffer");	Table.SetCell("Arguments", "<#chan> [linecount]");	Table.SetCell("Description", "Set the buffer count for a channel");
-	Table.AddRow(); Table.SetCell("Command", "SetVHost");	Table.SetCell("Arguments", "<vhost (ip preferred)>");Table.SetCell("Description", "Set the VHost for this connection");
+	if (m_pUser->IsAdmin() || !m_pUser->DenySetVHost()) {
+		Table.AddRow(); Table.SetCell("Command", "SetVHost");	Table.SetCell("Arguments", "<vhost (ip preferred)>");Table.SetCell("Description", "Set the VHost for this connection");
+	}
 	Table.AddRow(); Table.SetCell("Command", "Jump");		Table.SetCell("Arguments", "");						Table.SetCell("Description", "Jump to the next server in the list");
 	Table.AddRow(); Table.SetCell("Command", "Disconnect");		Table.SetCell("Arguments", "");						Table.SetCell("Description", "Disconnect from IRC");
 	Table.AddRow(); Table.SetCell("Command", "Connect");		Table.SetCell("Arguments", "");						Table.SetCell("Description", "Reconnect to IRC");
 	Table.AddRow(); Table.SetCell("Command", "Send");		Table.SetCell("Arguments", "<nick> <file>");		Table.SetCell("Description", "Send a shell file to a nick on IRC");
 	Table.AddRow(); Table.SetCell("Command", "Get");		Table.SetCell("Arguments", "<file>");				Table.SetCell("Description", "Send a shell file to yourself");
diff -N -r --unified=5 znc-0.052.orig/modules/webadmin.cpp znc-0.052/modules/webadmin.cpp
--- znc-0.052.orig/modules/webadmin.cpp	2007-10-28 18:57:07.000000000 +0100
+++ znc-0.052/modules/webadmin.cpp	2007-12-19 16:13:19.000000000 +0100
@@ -865,18 +865,20 @@
 			m_Template["Title"] = "Add User";
 			m_Template["StatusPrefix"] = "*";
 		}
 
 		const VCString& vsVHosts = CZNC::Get().GetVHosts();
-		for (unsigned int b = 0; b < vsVHosts.size(); b++) {
-			const CString& sVHost = vsVHosts[b];
-			CTemplate& l = m_Template.AddRow("VHostLoop");
+		if (IsAdmin() || !(pUser && pUser->DenySetVHost() && !pUser->IsAdmin())) {
+			for (unsigned int b = 0; b < vsVHosts.size(); b++) {
+				const CString& sVHost = vsVHosts[b];
+				CTemplate& l = m_Template.AddRow("VHostLoop");
 
-			l["VHost"] = sVHost;
+				l["VHost"] = sVHost;
 
-			if (pUser && pUser->GetVHost() == sVHost) {
-				l["Checked"] = "true";
+				if (pUser && pUser->GetVHost() == sVHost) {
+					l["Checked"] = "true";
+				}
 			}
 		}
 
 		set<CModInfo> ssUserMods;
 		CZNC::Get().GetModules().GetAvailableMods(ssUserMods);
@@ -947,10 +949,15 @@
 			CTemplate& o10 = m_Template.AddRow("OptionLoop");
 			o10["Name"] = "isadmin";
 			o10["DisplayName"] = "Admin";
 			if (pUser && pUser->IsAdmin()) { o10["Checked"] = "true"; }
 			if (pUser && pUser == CZNC::Get().FindUser(GetUser())) { o10["Disabled"] = "true"; }
+
+			CTemplate& o11 = m_Template.AddRow("OptionLoop");
+			o11["Name"] = "denysetvhost";
+			o11["DisplayName"] = "Deny SetVHost";
+			if (pUser && pUser->DenySetVHost()) { o11["Checked"] = "true"; }
 		}
 
 		PrintPage(sPageRet, "UserPage.tmpl");
 		return true;
 	}
@@ -1096,15 +1103,22 @@
 	sArg = GetParam("nick"); if (!sArg.empty()) { pNewUser->SetNick(sArg); }
 	sArg = GetParam("altnick"); if (!sArg.empty()) { pNewUser->SetAltNick(sArg); }
 	sArg = GetParam("statusprefix"); if (!sArg.empty()) { pNewUser->SetStatusPrefix(sArg); }
 	sArg = GetParam("ident"); if (!sArg.empty()) { pNewUser->SetIdent(sArg); }
 	sArg = GetParam("realname"); if (!sArg.empty()) { pNewUser->SetRealName(sArg); }
-	sArg = GetParam("vhost"); if (!sArg.empty()) { pNewUser->SetVHost(sArg); }
 	sArg = GetParam("quitmsg"); if (!sArg.empty()) { pNewUser->SetQuitMsg(sArg); }
 	sArg = GetParam("chanmodes"); if (!sArg.empty()) { pNewUser->SetDefaultChanModes(sArg); }
 	sArg = GetParam("timestampformat"); if (!sArg.empty()) { pNewUser->SetTimestampFormat(sArg); }
 
+	sArg = GetParam("vhost");
+	if (IsAdmin() || !pUser || (pUser && !pUser->DenySetVHost())) {
+		if(!sArg.empty()) pNewUser->SetVHost(sArg);
+	}
+	else if(pUser){
+		pNewUser->SetVHost(pUser->GetVHost());
+	}
+
 	pNewUser->SetBufferCount(GetParam("bufsize").ToUInt());
 	pNewUser->SetKeepBuffer(GetParam("keepbuffer").ToBool());
 	pNewUser->SetMultiClients(GetParam("multiclients").ToBool());
 	pNewUser->SetBounceDCCs(GetParam("bouncedccs").ToBool());
 	pNewUser->SetAutoCycle(GetParam("autocycle").ToBool());
@@ -1113,12 +1127,14 @@
 	pNewUser->SetTimestampAppend(GetParam("appendtimestamp").ToBool());
 	pNewUser->SetTimestampPrepend(GetParam("prependtimestamp").ToBool());
 
 	if (IsAdmin()) {
 		pNewUser->SetDenyLoadMod(GetParam("denyloadmod").ToBool());
+		pNewUser->SetDenySetVHost(GetParam("denysetvhost").ToBool());
 	} else if (pUser) {
 		pNewUser->SetDenyLoadMod(pUser->DenyLoadMod());
+		pNewUser->SetDenySetVHost(pUser->DenySetVHost());
 	}
 
 	if (pUser && pUser != CZNC::Get().FindUser(GetUser())) {
 		pNewUser->SetAdmin(GetParam("isadmin").ToBool());
 	} else if (pUser) {
diff -N -r --unified=5 znc-0.052.orig/User.cpp znc-0.052/User.cpp
--- znc-0.052.orig/User.cpp	2007-11-16 23:37:27.000000000 +0100
+++ znc-0.052/User.cpp	2007-12-19 15:43:16.000000000 +0100
@@ -38,10 +38,11 @@
 	m_bPassHashed = false;
 	m_bUseClientIP = false;
 	m_bKeepNick = false;
 	m_bDenyLoadMod = false;
 	m_bAdmin= false;
+	m_bDenySetVHost= false;
 	m_sStatusPrefix = "*";
 	m_sChanPrefixes = "#&";
 	m_uBufferCount = 50;
 	m_uMaxJoinTries = 0;
 	m_bKeepBuffer = false;
@@ -408,10 +409,11 @@
 	SetMultiClients(User.MultiClients());
 	SetBounceDCCs(User.BounceDCCs());
 	SetUseClientIP(User.UseClientIP());
 	SetDenyLoadMod(User.DenyLoadMod());
 	SetAdmin(User.IsAdmin());
+	SetDenySetVHost(User.DenySetVHost());
 	SetTimestampAppend(User.GetTimestampAppend());
 	SetTimestampPrepend(User.GetTimestampPrepend());
 	SetTimestampFormat(User.GetTimestampFormat());
 	// !Flags
 
@@ -553,10 +555,11 @@
 	PrintLine(File, "MultiClients", CString((MultiClients()) ? "true" : "false"));
 	PrintLine(File, "BounceDCCs", CString((BounceDCCs()) ? "true" : "false"));
 	PrintLine(File, "AutoCycle", CString((AutoCycle()) ? "true" : "false"));
 	PrintLine(File, "DenyLoadMod", CString((DenyLoadMod()) ? "true" : "false"));
 	PrintLine(File, "Admin", CString((IsAdmin()) ? "true" : "false"));
+	PrintLine(File, "DenySetVHost", CString((DenySetVHost()) ? "true" : "false"));
 	PrintLine(File, "DCCLookupMethod", CString((UseClientIP()) ? "client" : "default"));
 	PrintLine(File, "TimestampFormat", GetTimestampFormat());
 	PrintLine(File, "AppendTimestamp", CString((GetTimestampAppend()) ? "true" : "false"));
 	PrintLine(File, "PrependTimestamp", CString((GetTimestampPrepend()) ? "true" : "false"));
 	PrintLine(File, "TimezoneOffset", CString(m_fTimezoneOffset));
@@ -992,10 +995,11 @@
 void CUser::SetBounceDCCs(bool b) { m_bBounceDCCs = b; }
 void CUser::SetUseClientIP(bool b) { m_bUseClientIP = b; }
 void CUser::SetKeepNick(bool b) { m_bKeepNick = b; }
 void CUser::SetDenyLoadMod(bool b) { m_bDenyLoadMod = b; }
 void CUser::SetAdmin(bool b) { m_bAdmin = b; }
+void CUser::SetDenySetVHost(bool b) { m_bDenySetVHost = b; }
 void CUser::SetDefaultChanModes(const CString& s) { m_sDefaultChanModes = s; }
 void CUser::SetIRCServer(const CString& s) { m_sIRCServer = s; m_bIRCConnected = true; }
 void CUser::SetQuitMsg(const CString& s) { m_sQuitMsg = s; }
 void CUser::SetBufferCount(unsigned int u) { m_uBufferCount = u; }
 void CUser::SetKeepBuffer(bool b) { m_bKeepBuffer = b; }
@@ -1062,10 +1066,11 @@
 
 bool CUser::UseClientIP() const { return m_bUseClientIP; }
 bool CUser::GetKeepNick() const { return m_bKeepNick; }
 bool CUser::DenyLoadMod() const { return m_bDenyLoadMod; }
 bool CUser::IsAdmin() const { return m_bAdmin; }
+bool CUser::DenySetVHost() const { return m_bDenySetVHost; }
 bool CUser::MultiClients() const { return m_bMultiClients; }
 bool CUser::BounceDCCs() const { return m_bBounceDCCs; }
 const CString& CUser::GetStatusPrefix() const { return m_sStatusPrefix; }
 const CString& CUser::GetDefaultChanModes() const { return m_sDefaultChanModes; }
 const vector<CChan*>& CUser::GetChans() const { return m_vChans; }
diff -N -r --unified=5 znc-0.052.orig/User.h znc-0.052/User.h
--- znc-0.052.orig/User.h	2007-11-16 23:37:27.000000000 +0100
+++ znc-0.052/User.h	2007-12-19 14:37:07.000000000 +0100
@@ -128,10 +128,11 @@
 	void SetMultiClients(bool b);
 	void SetUseClientIP(bool b);
 	void SetKeepNick(bool b);
 	void SetDenyLoadMod(bool b);
 	void SetAdmin(bool b);
+	void SetDenySetVHost(bool b);
 	bool SetStatusPrefix(const CString& s);
 	void SetDefaultChanModes(const CString& s);
 	void SetIRCNick(const CNick& n);
 	void SetIRCServer(const CString& s);
 	void SetQuitMsg(const CString& s);
@@ -176,10 +177,11 @@
 
 	bool UseClientIP() const;
 	bool GetKeepNick() const;
 	bool DenyLoadMod() const;
 	bool IsAdmin() const;
+	bool DenySetVHost() const;
 	bool BounceDCCs() const;
 	bool MultiClients() const;
 	const CString& GetStatusPrefix() const;
 	const CString& GetDefaultChanModes() const;
 	const vector<CChan*>& GetChans() const;
@@ -233,10 +235,11 @@
 	bool				m_bPassHashed;
 	bool				m_bUseClientIP;
 	bool				m_bKeepNick;
 	bool				m_bDenyLoadMod;
 	bool				m_bAdmin;
+	bool				m_bDenySetVHost;
 	bool				m_bKeepBuffer;
 	bool				m_bAutoCycle;
 	bool				m_bBeingDeleted;
 	bool				m_bAppendTimestamp;
 	bool				m_bPrependTimestamp;
diff -N -r --unified=5 znc-0.052.orig/znc.cpp znc-0.052/znc.cpp
--- znc-0.052.orig/znc.cpp	2007-11-16 23:37:27.000000000 +0100
+++ znc-0.052/znc.cpp	2007-12-19 14:37:07.000000000 +0100
@@ -967,10 +967,13 @@
 						pUser->SetDenyLoadMod((sValue.CaseCmp("TRUE") == 0));
 						continue;
 					} else if (sName.CaseCmp("Admin") == 0) {
 						pUser->SetAdmin((sValue.CaseCmp("TRUE") == 0));
 						continue;
+					} else if (sName.CaseCmp("DenySetVHost") == 0) {
+						pUser->SetDenySetVHost((sValue.CaseCmp("TRUE") == 0));
+						continue;
 					} else if (sName.CaseCmp("StatusPrefix") == 0) {
 						if (!pUser->SetStatusPrefix(sValue)) {
 							CUtils::PrintError("Invalid StatusPrefix [" + sValue + "] Must be 1-5 chars, no spaces.");
 							return false;
 						}
