diff --git a/include/znc/User.h b/include/znc/User.h
index 19c6e026..20f7cf97 100644
--- a/include/znc/User.h
+++ b/include/znc/User.h
@@ -137,6 +137,11 @@ class CUser : private CCoreTranslationMixin {
void SetDenyLoadMod(bool b);
void SetAdmin(bool b);
void SetDenySetBindHost(bool b);
+ void SetDenySetIdent(bool b);
+ void SetDenySetNetwork(bool b);
+ void SetDenySetRealName(bool b);
+ void SetDenySetQuitMsg(bool b);
+ void SetDenySetCTCPReplies(bool b);
bool SetStatusPrefix(const CString& s);
void SetDefaultChanModes(const CString& s);
void SetClientEncoding(const CString& s);
@@ -192,6 +197,11 @@ class CUser : private CCoreTranslationMixin {
bool DenyLoadMod() const;
bool IsAdmin() const;
bool DenySetBindHost() const;
+ bool DenySetIdent() const;
+ bool DenySetNetwork() const;
+ bool DenySetRealName() const;
+ bool DenySetQuitMsg() const;
+ bool DenySetCTCPReplies() const;
bool MultiClients() const;
bool AuthOnlyViaModule() const;
const CString& GetStatusPrefix() const;
@@ -254,6 +264,11 @@ class CUser : private CCoreTranslationMixin {
bool m_bDenyLoadMod;
bool m_bAdmin;
bool m_bDenySetBindHost;
+ bool m_bDenySetIdent;
+ bool m_bDenySetNetwork;
+ bool m_bDenySetRealName;
+ bool m_bDenySetQuitMsg;
+ bool m_bDenySetCTCPReplies;
bool m_bAutoClearChanBuffer;
bool m_bAutoClearQueryBuffer;
bool m_bBeingDeleted;
diff --git a/modules/controlpanel.cpp b/modules/controlpanel.cpp
index 85d676bd..801591b9 100644
--- a/modules/controlpanel.cpp
+++ b/modules/controlpanel.cpp
@@ -94,6 +94,11 @@ class CAdminMod : public CModule {
{"MultiClients", boolean},
{"DenyLoadMod", boolean},
{"DenySetBindHost", boolean},
+ {"DenySetIdent", boolean},
+ {"DenySetNetwork", boolean},
+ {"DenySetRealName", boolean},
+ {"DenySetQuitMsg", boolean},
+ {"DenySetCTCPReplies", boolean},
{"DefaultChanModes", str},
{"QuitMsg", str},
{"ChanBufferSize", integer},
@@ -241,6 +246,16 @@ class CAdminMod : public CModule {
PutModule("DenyLoadMod = " + CString(pUser->DenyLoadMod()));
else if (sVar == "denysetbindhost")
PutModule("DenySetBindHost = " + CString(pUser->DenySetBindHost()));
+ else if (sVar == "denysetident")
+ PutModule("DenySetIdent = " + CString(pUser->DenySetIdent()));
+ else if (sVar == "denysetnetwork")
+ PutModule("DenySetNetwork = " + CString(pUser->DenySetNetwork()));
+ else if (sVar == "denysetrealname")
+ PutModule("DenySetRealName = " + CString(pUser->DenySetRealName()));
+ else if (sVar == "denysetquitmsg")
+ PutModule("DenySetQuitMsg = " + CString(pUser->DenySetQuitMsg()));
+ else if (sVar == "denysetctcpreplies")
+ PutModule("DenySetCTCPReplies = " + CString(pUser->DenySetCTCPReplies()));
else if (sVar == "defaultchanmodes")
PutModule("DefaultChanModes = " + pUser->GetDefaultChanModes());
else if (sVar == "quitmsg")
@@ -326,11 +341,19 @@ class CAdminMod : public CModule {
pUser->SetAltNick(sValue);
PutModule("AltNick = " + sValue);
} else if (sVar == "ident") {
- pUser->SetIdent(sValue);
- PutModule("Ident = " + sValue);
+ if (!pUser->DenySetIdent() || GetUser()->IsAdmin()) {
+ pUser->SetIdent(sValue);
+ PutModule("Ident = " + sValue);
+ } else {
+ PutModule(t_s("Access denied!"));
+ }
} else if (sVar == "realname") {
- pUser->SetRealName(sValue);
- PutModule("RealName = " + sValue);
+ if (!pUser->DenySetRealName() || GetUser()->IsAdmin()) {
+ pUser->SetRealName(sValue);
+ PutModule("RealName = " + sValue);
+ } else {
+ PutModule(t_s("Access denied!"));
+ }
} else if (sVar == "bindhost") {
if (!pUser->DenySetBindHost() || GetUser()->IsAdmin()) {
if (sValue.Equals(pUser->GetBindHost())) {
@@ -363,12 +386,56 @@ class CAdminMod : public CModule {
} else {
PutModule(t_s("Access denied!"));
}
+ } else if (sVar == "denysetident") {
+ if (GetUser()->IsAdmin()) {
+ bool b = sValue.ToBool();
+ pUser->SetDenySetIdent(b);
+ PutModule("DenySetIdent = " + CString(b));
+ } else {
+ PutModule(t_s("Access denied!"));
+ }
+ } else if (sVar == "denysetnetwork") {
+ if (GetUser()->IsAdmin()) {
+ bool b = sValue.ToBool();
+ pUser->SetDenySetNetwork(b);
+ PutModule("DenySetNetwork = " + CString(b));
+ } else {
+ PutModule(t_s("Access denied!"));
+ }
+ } else if (sVar == "denysetrealname") {
+ if (GetUser()->IsAdmin()) {
+ bool b = sValue.ToBool();
+ pUser->SetDenySetRealName(b);
+ PutModule("DenySetRealName = " + CString(b));
+ } else {
+ PutModule(t_s("Access denied!"));
+ }
+ } else if (sVar == "denysetquitmsg") {
+ if (GetUser()->IsAdmin()) {
+ bool b = sValue.ToBool();
+ pUser->SetDenySetQuitMsg(b);
+ PutModule("DenySetQuitMsg = " + CString(b));
+ } else {
+ PutModule(t_s("Access denied!"));
+ }
+ } else if (sVar == "denysetctcpreplies") {
+ if (GetUser()->IsAdmin()) {
+ bool b = sValue.ToBool();
+ pUser->SetDenySetCTCPReplies(b);
+ PutModule("DenySetCTCPReplies = " + CString(b));
+ } else {
+ PutModule(t_s("Access denied!"));
+ }
} else if (sVar == "defaultchanmodes") {
pUser->SetDefaultChanModes(sValue);
PutModule("DefaultChanModes = " + sValue);
} else if (sVar == "quitmsg") {
- pUser->SetQuitMsg(sValue);
- PutModule("QuitMsg = " + sValue);
+ if (!pUser->DenySetQuitMsg() || GetUser()->IsAdmin()) {
+ pUser->SetQuitMsg(sValue);
+ PutModule("QuitMsg = " + sValue);
+ } else {
+ PutModule(t_s("Access denied!"));
+ }
} else if (sVar == "chanbuffersize" || sVar == "buffercount") {
unsigned int i = sValue.ToUInt();
// Admins don't have to honour the buffer limit
@@ -614,11 +681,19 @@ class CAdminMod : public CModule {
pNetwork->SetAltNick(sValue);
PutModule("AltNick = " + pNetwork->GetAltNick());
} else if (sVar.Equals("ident")) {
- pNetwork->SetIdent(sValue);
- PutModule("Ident = " + pNetwork->GetIdent());
+ if (!pUser->DenySetIdent() || GetUser()->IsAdmin()) {
+ pNetwork->SetIdent(sValue);
+ PutModule("Ident = " + pNetwork->GetIdent());
+ } else {
+ PutModule(t_s("Access denied!"));
+ }
} else if (sVar.Equals("realname")) {
- pNetwork->SetRealName(sValue);
- PutModule("RealName = " + pNetwork->GetRealName());
+ if (!pUser->DenySetRealName() || GetUser()->IsAdmin()) {
+ pNetwork->SetRealName(sValue);
+ PutModule("RealName = " + pNetwork->GetRealName());
+ } else {
+ PutModule(t_s("Access denied!"));
+ }
} else if (sVar.Equals("bindhost")) {
if (!pUser->DenySetBindHost() || GetUser()->IsAdmin()) {
if (sValue.Equals(pNetwork->GetBindHost())) {
@@ -646,8 +721,12 @@ class CAdminMod : public CModule {
PutModule("Encoding = " + pNetwork->GetEncoding());
#endif
} else if (sVar.Equals("quitmsg")) {
- pNetwork->SetQuitMsg(sValue);
- PutModule("QuitMsg = " + pNetwork->GetQuitMsg());
+ if (!pUser->DenySetQuitMsg() || GetUser()->IsAdmin()) {
+ pNetwork->SetQuitMsg(sValue);
+ PutModule("QuitMsg = " + pNetwork->GetQuitMsg());
+ } else {
+ PutModule(t_s("Access denied!"));
+ }
} else if (sVar.Equals("trustallcerts")) {
bool b = sValue.ToBool();
pNetwork->SetTrustAllCerts(b);
@@ -1043,6 +1122,11 @@ class CAdminMod : public CModule {
return;
}
+ if (!GetUser()->IsAdmin() && pUser->DenySetNetwork()) {
+ PutModule(t_s("Access denied!"));
+ return;
+ }
+
if (!GetUser()->IsAdmin() && !pUser->HasSpaceForNewNetwork()) {
PutStatus(
t_s("Network number limit reached. Ask an admin to increase "
@@ -1088,6 +1172,11 @@ class CAdminMod : public CModule {
return;
}
+ if (!GetUser()->IsAdmin() && pUser->DenySetNetwork()) {
+ PutModule(t_s("Access denied!"));
+ return;
+ }
+
CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork);
if (!pNetwork) {
return;
@@ -1166,6 +1255,11 @@ class CAdminMod : public CModule {
CUser* pUser = FindUser(sUsername);
if (!pUser) return;
+ if (!GetUser()->IsAdmin() && pUser->DenySetNetwork()) {
+ PutModule(t_s("Access denied!"));
+ return;
+ }
+
CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork);
if (!pNetwork) {
return;
@@ -1197,6 +1291,11 @@ class CAdminMod : public CModule {
CUser* pUser = FindUser(sUsername);
if (!pUser) return;
+ if (!GetUser()->IsAdmin() && pUser->DenySetNetwork()) {
+ PutModule(t_s("Access denied!"));
+ return;
+ }
+
CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork);
if (!pNetwork) {
return;
@@ -1325,6 +1424,11 @@ class CAdminMod : public CModule {
CUser* pUser = FindUser(sUsername);
if (!pUser) return;
+ if (!GetUser()->IsAdmin() && pUser->DenySetCTCPReplies()) {
+ PutModule(t_s("Access denied!"));
+ return;
+ }
+
pUser->AddCTCPReply(sCTCPRequest, sCTCPReply);
if (sCTCPReply.empty()) {
PutModule(t_f("CTCP requests {1} to user {2} will now be blocked.")(
@@ -1347,6 +1451,11 @@ class CAdminMod : public CModule {
CUser* pUser = FindUser(sUsername);
if (!pUser) return;
+ if (!GetUser()->IsAdmin() && pUser->DenySetCTCPReplies()) {
+ PutModule(t_s("Access denied!"));
+ return;
+ }
+
if (sCTCPRequest.empty()) {
PutModule(t_s("Usage: DelCTCP [user] [request]"));
return;
diff --git a/modules/data/webadmin/files/webadmin.css b/modules/data/webadmin/files/webadmin.css
index 3fa3fa84..8a2b02e6 100644
--- a/modules/data/webadmin/files/webadmin.css
+++ b/modules/data/webadmin/files/webadmin.css
@@ -21,3 +21,4 @@ table .reverse-sorted::after {
width: 400px;
}
+table.networks[data-network-edit="0"] .network_delete { display: none; }
\ No newline at end of file
diff --git a/modules/data/webadmin/files/webadmin.js b/modules/data/webadmin/files/webadmin.js
index f9774d5d..0fb776be 100644
--- a/modules/data/webadmin/files/webadmin.js
+++ b/modules/data/webadmin/files/webadmin.js
@@ -121,18 +121,31 @@ function serverlist_init($) {
row.remove();
serialize();
}
- row.append(
- $("
| ").append($("").attr({"type":"text"})
- .addClass("servers_row_host").val(host)),
- $(" | ").append($("").attr({"type":"number"})
- .addClass("servers_row_port").val(port)),
- $(" | ").append($("").attr({"type":"checkbox"})
- .addClass("servers_row_ssl").prop("checked", ssl)),
- $(" | ").append($("").attr({"type":"text"})
- .addClass("servers_row_pass").val(pass)),
- $(" | ").append($("").attr({"type":"button"})
- .val("X").click(delete_row))
- );
+ if (NetworkEdit) {
+ row.append(
+ $(" | ").append($("").attr({"type":"text"})
+ .addClass("servers_row_host").val(host)),
+ $(" | ").append($("").attr({"type":"number"})
+ .addClass("servers_row_port").val(port)),
+ $(" | ").append($("").attr({"type":"checkbox"})
+ .addClass("servers_row_ssl").prop("checked", ssl)),
+ $(" | ").append($("").attr({"type":"text"})
+ .addClass("servers_row_pass").val(pass)),
+ $(" | ").append($("").attr({"type":"button"})
+ .val("X").click(delete_row))
+ );
+ } else {
+ row.append(
+ $(" | ").append($("").attr({"type":"text","disabled":true})
+ .addClass("servers_row_host").val(host)),
+ $(" | ").append($("").attr({"type":"number","disabled":true})
+ .addClass("servers_row_port").val(port)),
+ $(" | ").append($("").attr({"type":"checkbox","disabled":true})
+ .addClass("servers_row_ssl").prop("checked", ssl)),
+ $(" | ").append($("").attr({"type":"text","disabled":true})
+ .addClass("servers_row_pass").val(pass))
+ );
+ }
$("input", row).change(serialize);
$("#servers_tbody").append(row);
}
@@ -210,16 +223,27 @@ function ctcpreplies_init($) {
row.remove();
serialize();
}
- row.append(
- $(" | ").append($("").val(request)
- .addClass("ctcpreplies_row_request")
- .attr({"type":"text","list":"ctcpreplies_list"})),
- $(" | ").append($("").val(response)
- .addClass("ctcpreplies_row_response")
- .attr({"type":"text","placeholder":$("#ctcpreplies_js").data("placeholder")})),
- $(" | ").append($("").val("X")
- .attr({"type":"button"}).click(delete_row))
- );
+ if (CTCPEdit) {
+ row.append(
+ $(" | ").append($("").val(request)
+ .addClass("ctcpreplies_row_request")
+ .attr({"type":"text","list":"ctcpreplies_list"})),
+ $(" | ").append($("").val(response)
+ .addClass("ctcpreplies_row_response")
+ .attr({"type":"text","placeholder":$("#ctcpreplies_js").data("placeholder")})),
+ $(" | ").append($("").val("X")
+ .attr({"type":"button"}).click(delete_row))
+ );
+ } else {
+ row.append(
+ $(" | ").append($("").val(request)
+ .addClass("ctcpreplies_row_request")
+ .attr({"type":"text","list":"ctcpreplies_list","disabled":true})),
+ $(" | ").append($("").val(response)
+ .addClass("ctcpreplies_row_response")
+ .attr({"type":"text","placeholder":$("#ctcpreplies_js").data("placeholder"),"disabled":true})),
+ );
+ }
$("input", row).change(serialize);
$("#ctcpreplies_tbody").append(row);
}
diff --git a/modules/data/webadmin/tmpl/add_edit_network.tmpl b/modules/data/webadmin/tmpl/add_edit_network.tmpl
index d0ea2cf0..6d414073 100644
--- a/modules/data/webadmin/tmpl/add_edit_network.tmpl
+++ b/modules/data/webadmin/tmpl/add_edit_network.tmpl
@@ -3,6 +3,10 @@
AddRow CSSLoop HREF=/modfiles/global/webadmin/webadmin.css ?>
INC Header.tmpl ?>
+
+
IF Edit ?>
SETBLOCK ClientConnectHint_Password ?> VAR Username ?>/ VAR Name ?>: FORMAT "<password>" ?> ENDSETBLOCK ?>
@@ -28,7 +32,7 @@
@@ -45,12 +49,12 @@
IF BindHostEdit ?>
@@ -64,7 +68,8 @@
@@ -87,7 +92,7 @@
-
diff --git a/modules/data/webadmin/tmpl/add_edit_user.tmpl b/modules/data/webadmin/tmpl/add_edit_user.tmpl
index 5e695795..51e65c27 100644
--- a/modules/data/webadmin/tmpl/add_edit_user.tmpl
+++ b/modules/data/webadmin/tmpl/add_edit_user.tmpl
@@ -3,6 +3,10 @@
AddRow CSSLoop HREF=/modfiles/global/webadmin/webadmin.css ?>
INC Header.tmpl ?>
+
+