-
Notifications
You must be signed in to change notification settings - Fork 0
/
minoplevel.patch
72 lines (63 loc) · 3.41 KB
/
minoplevel.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
Fix for enforcing the min oplevel we added to snircd.
Previously, only oplevels between 0 and MINOPLEVEL (value 100) were accepted from
services server (+s flag) or from a service client (umode +k) on them.
1. Servers bouncing modes with such an oplevel would be set back to MINOPLEVEL,
instead of the original level, leading to desynch. Locally the server that bounces the mode
would keep the original oplevel, and bounce it back upstream, were the servers would correct
it with MINOPLEVEL.
2. If we would ever dicide to change this hardcoded value for MINOPLEVEL, there would be
desynchs for the oplevels chanops would have between old and new servers.
3. The original oplevel received (either by client or over a server link)
was propagated (further) and not the oplevel the ircd set locally
(and which may have been changed for the MINOPLEVEL value).
All of these issues are fixed in this patch.
1. MINOPLEVEL is only enforced on local clients, that is, local clients
using /MODE (for more detail, see comment in code).
2. if we ever change the value, there would be no desynch, just different local
enforcement of the value between old and new servers.
3. in case the oplevel is corrected for MINOPLEVEL, the correct oplevel goes upstream.
NOTE: previously MINOPLEVEL was also enforced on /OPMODE - it is no longer in this patch (should it?)
diff -r 041543097dfa ircd/channel.c
--- a/ircd/channel.c Sun Feb 15 16:28:56 2009 +0100
+++ b/ircd/channel.c Sun Feb 15 16:36:34 2009 +0100
@@ -3355,18 +3355,34 @@
* Otherwise, get state->member's oplevel+1.
*/
if (state->cli_change[i].oplevel <= MAXOPLEVEL) {
- if ((IsChannelService(state->sptr) && IsService(cli_user(state->sptr)->server)) || (IsService(state->sptr))) {
- SetOpLevel(member, state->cli_change[i].oplevel);
- } else {
- SetOpLevel(member, state->cli_change[i].oplevel > MINOPLEVEL ? state->cli_change[i].oplevel : MINOPLEVEL);
- }
+ /* MINOPLEVEL - snircd
+ * accept oplevels as given when forced - modes are forced when:
+ * MODE &chan by oper with MODE_LCHAN PRIV
+ * OPMODE, MODE with server as source, MODE from remote user
+ *
+ * we need to change state->cli_change[i].oplevel so that
+ * the oplevel we set goes upstream (including any change we make to it),
+ * and not the oplevel specified by the client
+ * we do not want to set one thing locally, and send upstream another
+ */
+ if (!(state->flags & MODE_PARSE_FORCE) && state->cli_change[i].oplevel < MINOPLEVEL)
+ state->cli_change[i].oplevel = MINOPLEVEL;
+ SetOpLevel(member, state->cli_change[i].oplevel);
}
else if (!state->member)
SetOpLevel(member, MAXOPLEVEL);
else if (OpLevel(state->member) >= MAXOPLEVEL)
SetOpLevel(member, OpLevel(state->member));
- else
- SetOpLevel(member, OpLevel(state->member) >= MINOPLEVEL ? OpLevel(state->member) + 1 : MINOPLEVEL);
+ else {
+ /* MINOPLEVEL - snircd
+ * change state->cli_change[i].oplevel - see above.
+ */
+ if (!(state->flags & MODE_PARSE_FORCE) && OpLevel(state->member) < MINOPLEVEL)
+ state->cli_change[i].oplevel = MINOPLEVEL;
+ else
+ state->cli_change[i].oplevel = OpLevel(state->member) + 1;
+ SetOpLevel(member, state->cli_change[i].oplevel);
+ }
}
/* actually effect the change */