]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanservprivs.c
CHANSERV: don't allow non-opers to see last realhosts in AUTHHISTORY / WHOIS
[irc/quakenet/newserv.git] / chanserv / chanservprivs.c
1 /* chanservprivs.c */
2
3 #include "chanserv.h"
4 #include "../nick/nick.h"
5 #include "../lib/irc_string.h"
6 #include <string.h>
7 #include <ctype.h>
8
9 int cs_privcheck(int privnum, nick *np) {
10 reguser *rup=NULL;
11
12 if (np)
13 rup=getreguserfromnick(np);
14
15 switch(privnum) {
16 case QPRIV_SUSPENDBYPASS:
17 case QPRIV_VIEWCHANFLAGS:
18 case QPRIV_VIEWFULLCHANLEV:
19 case QPRIV_VIEWFULLWHOIS:
20 case QPRIV_VIEWCHANMODES:
21 case QPRIV_VIEWAUTOLIMIT:
22 case QPRIV_VIEWBANTIMER:
23 case QPRIV_VIEWUSERFLAGS:
24 case QPRIV_VIEWCHANSUSPENSION:
25 return (rup && UHasHelperPriv(rup));
26
27 case QPRIV_VIEWCOMMENTS:
28 case QPRIV_VIEWEMAIL:
29 case QPRIV_CHANGECHANLEV:
30 case QPRIV_CHANGECHANFLAGS:
31 case QPRIV_CHANGECHANMODES:
32 case QPRIV_CHANGEAUTOLIMIT:
33 case QPRIV_CHANGEBANTIMER:
34 case QPRIV_CHANGEUSERFLAGS:
35 case QPRIV_VIEWSUSPENDEDBY:
36 case QPRIV_VIEWWALLMESSAGE: /* if you change VIEWWALLMESSAGE alter chanservwallmessage too */
37 case QPRIV_VIEWREALHOST:
38 return (np && rup && IsOper(np) && UHasOperPriv(rup));
39
40 default: /* By default opers can override anything */
41 return (np && rup && IsOper(np) && UHasOperPriv(rup));
42 }
43 }
44
45 /* Generic access check function.
46 * Note that the chanindex is returned for success, this
47 * can be used to avoid duplicate hash lookups */
48
49 chanindex *cs_checkaccess(nick *np, const char *chan, unsigned int flags,
50 chanindex *cip, const char *cmdname, int priv, int quiet) {
51 reguser *rup=getreguserfromnick(np);
52 regchan *rcp;
53 regchanuser *rcup=NULL;
54 unsigned long *lp;
55
56 if ((flags & CA_AUTHED) && !rup)
57 return NULL;
58
59 if (!cip && !(cip=findchanindex(chan))) {
60 if (!quiet) chanservstdmessage(np, QM_UNKNOWNCHAN, chan);
61 return NULL;
62 }
63
64 if (!(rcp=cip->exts[chanservext])) {
65 if (!quiet) chanservstdmessage(np, QM_UNKNOWNCHAN, cip->name->content);
66 return NULL;
67 }
68
69
70 if (CIsSuspended(rcp)) {
71 if (cs_privcheck(QPRIV_SUSPENDBYPASS, np)) {
72 if (!quiet) chanservstdmessage(np, QM_BYPASSINGSUSPEND, cip->name->content);
73 } else {
74 if (!quiet) chanservstdmessage(np, QM_UNKNOWNCHAN, cip->name->content);
75 return NULL;
76 }
77 }
78
79 if (rcp && rup)
80 rcup=findreguseronchannel(rcp, rup);
81
82 if (!cs_privcheck(priv,np)) {
83 if ((flags & CA_VOICEPRIV) &&
84 !(rcp && CIsVoiceAll(rcp) && !(rcup && CUIsQuiet(rcup)) &&
85 !(cip->channel && (nickbanned(np, cip->channel, 1) || IsInviteOnly(cip->channel)))) &&
86 !(rcup && CUHasVoicePriv(rcup))) {
87 if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname);
88 return NULL;
89 }
90
91 if ((flags & CA_NEEDKNOWN) && !rup) {
92 if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname);
93 return NULL;
94 }
95
96 if ((flags & CA_NEEDKNOWN) && (!rcup || !CUKnown(rcup))) {
97 if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname);
98 return NULL;
99 }
100
101 if (((flags & CA_OPPRIV ) && !CUHasOpPriv(rcup)) ||
102 ((flags & CA_MASTERPRIV) && !CUHasMasterPriv(rcup)) ||
103 ((flags & CA_OWNERPRIV) && !CUIsOwner(rcup)) ||
104 ((flags & CA_TOPICPRIV ) && !CUHasTopicPriv(rcup))) {
105 if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname);
106 return NULL;
107 }
108 }
109
110 if ((flags & CA_ONCHANREQ) && !(cip->channel)) {
111 if (!quiet) chanservstdmessage(np, QM_NOTONCHAN, cip->name->content);
112 return NULL;
113 }
114
115 if (cip->channel) {
116 lp=getnumerichandlefromchanhash(cip->channel->users, np->numeric);
117
118 if ((flags & CA_ONCHANREQ) && !lp) {
119 if (!quiet) chanservstdmessage(np, QM_NOTONCHAN, cip->name->content);
120 return NULL;
121 }
122
123 if ((flags & CA_OPPED) && !(*lp & CUMODE_OP)) {
124 if (!quiet) chanservstdmessage(np, QM_NOTOPPED, cip->name->content);
125 return NULL;
126 }
127
128 if ((flags & CA_DEOPPED) && (*lp & CUMODE_OP)) {
129 if (!quiet) chanservstdmessage(np, QM_ALREADYOPPED, cip->name->content);
130 return NULL;
131 }
132
133 if ((flags & CA_VOICED) && !(*lp & CUMODE_VOICE)) {
134 if (!quiet) chanservstdmessage(np, QM_NOTVOICED, cip->name->content);
135 return NULL;
136 }
137
138 if ((flags & CA_DEVOICED) && (*lp & CUMODE_VOICE)) {
139 if (!quiet) chanservstdmessage(np, QM_ALREADYVOICED, cip->name->content);
140 return NULL;
141 }
142
143 if ((flags & CA_OFFCHAN) && lp) {
144 if (!quiet) chanservstdmessage(np, QM_ALREADYONCHAN, cip->name->content);
145 return NULL;
146 }
147 }
148
149 return cip;
150 }
151