]>
Commit | Line | Data |
---|---|---|
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 | case QPRIV_RESETCHANSTAT: | |
39 | return (np && rup && IsOper(np) && UHasOperPriv(rup)); | |
40 | ||
41 | default: /* By default opers can override anything */ | |
42 | return (np && rup && IsOper(np) && UHasOperPriv(rup)); | |
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 | ||
65 | if (!(rcp=cip->exts[chanservext])) { | |
66 | if (!quiet) chanservstdmessage(np, QM_UNKNOWNCHAN, cip->name->content); | |
67 | return NULL; | |
68 | } | |
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 | } | |
79 | ||
80 | if (rcp && rup) | |
81 | rcup=findreguseronchannel(rcp, rup); | |
82 | ||
83 | if (!cs_privcheck(priv,np)) { | |
84 | if ((flags & CA_VOICEPRIV) && | |
85 | !(rcp && CIsVoiceAll(rcp) && !(rcup && CUIsQuiet(rcup)) && | |
86 | !(cip->channel && (nickbanned(np, cip->channel, 1) || IsInviteOnly(cip->channel)))) && | |
87 | !(rcup && CUHasVoicePriv(rcup))) { | |
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 | ||
97 | if ((flags & CA_NEEDKNOWN) && (!rcup || !CUKnown(rcup))) { | |
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 |