]>
Commit | Line | Data |
---|---|---|
c86edd1d Q |
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: | |
e086f1b5 | 24 | case QPRIV_VIEWCHANSUSPENSION: |
c86edd1d Q |
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: | |
e086f1b5 | 35 | case QPRIV_VIEWSUSPENDEDBY: |
9de8d198 | 36 | case QPRIV_VIEWWALLMESSAGE: /* if you change VIEWWALLMESSAGE alter chanservwallmessage too */ |
ffc0f3ab | 37 | case QPRIV_VIEWREALHOST: |
917b9b2e | 38 | case QPRIV_RESETCHANSTAT: |
c86edd1d Q |
39 | return (np && rup && IsOper(np) && UHasOperPriv(rup)); |
40 | ||
103521a1 | 41 | default: /* By default opers can override anything */ |
42 | return (np && rup && IsOper(np) && UHasOperPriv(rup)); | |
c86edd1d Q |
43 | } |
44 | } | |
45 | ||
46 | /* Generic access check function. | |
47 | * Note that the chanindex is returned for success, this | |
48 | * can be used to avoid duplicate hash lookups */ | |
49 | ||
50 | chanindex *cs_checkaccess(nick *np, const char *chan, unsigned int flags, | |
51 | chanindex *cip, const char *cmdname, int priv, int quiet) { | |
52 | reguser *rup=getreguserfromnick(np); | |
53 | regchan *rcp; | |
54 | regchanuser *rcup=NULL; | |
55 | unsigned long *lp; | |
56 | ||
57 | if ((flags & CA_AUTHED) && !rup) | |
58 | return NULL; | |
59 | ||
60 | if (!cip && !(cip=findchanindex(chan))) { | |
61 | if (!quiet) chanservstdmessage(np, QM_UNKNOWNCHAN, chan); | |
62 | return NULL; | |
63 | } | |
64 | ||
64c666e3 | 65 | if (!(rcp=cip->exts[chanservext])) { |
c86edd1d Q |
66 | if (!quiet) chanservstdmessage(np, QM_UNKNOWNCHAN, cip->name->content); |
67 | return NULL; | |
68 | } | |
64c666e3 | 69 | |
70 | ||
71 | if (CIsSuspended(rcp)) { | |
72 | if (cs_privcheck(QPRIV_SUSPENDBYPASS, np)) { | |
73 | if (!quiet) chanservstdmessage(np, QM_BYPASSINGSUSPEND, cip->name->content); | |
74 | } else { | |
75 | if (!quiet) chanservstdmessage(np, QM_UNKNOWNCHAN, cip->name->content); | |
76 | return NULL; | |
77 | } | |
78 | } | |
e70833ab | 79 | |
80 | if (rcp && rup) | |
81 | rcup=findreguseronchannel(rcp, rup); | |
c86edd1d | 82 | |
e4946b42 | 83 | if (!cs_privcheck(priv,np)) { |
c86edd1d | 84 | if ((flags & CA_VOICEPRIV) && |
21af7a34 | 85 | !(rcp && CIsVoiceAll(rcp) && !(rcup && CUIsQuiet(rcup)) && |
873f4217 | 86 | !(cip->channel && (nickbanned(np, cip->channel, 1) || IsInviteOnly(cip->channel)))) && |
21af7a34 | 87 | !(rcup && CUHasVoicePriv(rcup))) { |
c86edd1d Q |
88 | if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname); |
89 | return NULL; | |
90 | } | |
91 | ||
92 | if ((flags & CA_NEEDKNOWN) && !rup) { | |
93 | if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname); | |
94 | return NULL; | |
95 | } | |
96 | ||
e70833ab | 97 | if ((flags & CA_NEEDKNOWN) && (!rcup || !CUKnown(rcup))) { |
c86edd1d Q |
98 | if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname); |
99 | return NULL; | |
100 | } | |
101 | ||
102 | if (((flags & CA_OPPRIV ) && !CUHasOpPriv(rcup)) || | |
103 | ((flags & CA_MASTERPRIV) && !CUHasMasterPriv(rcup)) || | |
104 | ((flags & CA_OWNERPRIV) && !CUIsOwner(rcup)) || | |
105 | ((flags & CA_TOPICPRIV ) && !CUHasTopicPriv(rcup))) { | |
106 | if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname); | |
107 | return NULL; | |
108 | } | |
109 | } | |
110 | ||
111 | if ((flags & CA_ONCHANREQ) && !(cip->channel)) { | |
112 | if (!quiet) chanservstdmessage(np, QM_NOTONCHAN, cip->name->content); | |
113 | return NULL; | |
114 | } | |
115 | ||
116 | if (cip->channel) { | |
117 | lp=getnumerichandlefromchanhash(cip->channel->users, np->numeric); | |
118 | ||
119 | if ((flags & CA_ONCHANREQ) && !lp) { | |
120 | if (!quiet) chanservstdmessage(np, QM_NOTONCHAN, cip->name->content); | |
121 | return NULL; | |
122 | } | |
123 | ||
124 | if ((flags & CA_OPPED) && !(*lp & CUMODE_OP)) { | |
125 | if (!quiet) chanservstdmessage(np, QM_NOTOPPED, cip->name->content); | |
126 | return NULL; | |
127 | } | |
128 | ||
129 | if ((flags & CA_DEOPPED) && (*lp & CUMODE_OP)) { | |
130 | if (!quiet) chanservstdmessage(np, QM_ALREADYOPPED, cip->name->content); | |
131 | return NULL; | |
132 | } | |
133 | ||
134 | if ((flags & CA_VOICED) && !(*lp & CUMODE_VOICE)) { | |
135 | if (!quiet) chanservstdmessage(np, QM_NOTVOICED, cip->name->content); | |
136 | return NULL; | |
137 | } | |
138 | ||
139 | if ((flags & CA_DEVOICED) && (*lp & CUMODE_VOICE)) { | |
140 | if (!quiet) chanservstdmessage(np, QM_ALREADYVOICED, cip->name->content); | |
141 | return NULL; | |
142 | } | |
143 | ||
144 | if ((flags & CA_OFFCHAN) && lp) { | |
145 | if (!quiet) chanservstdmessage(np, QM_ALREADYONCHAN, cip->name->content); | |
146 | return NULL; | |
147 | } | |
148 | } | |
149 | ||
150 | return cip; | |
151 | } | |
152 |