2 * oper-override for charybdis.
4 * adds usermode +p and has a timer event that is iterated over to disable
5 * usermode +p after a while...
7 * you need to have oper:override permission on the opers you want to be
8 * able to use this extension.
22 #include "privilege.h"
23 #include "s_newconf.h"
25 static void check_umode_change(void *data
);
26 static void hack_channel_access(void *data
);
27 static void hack_can_join(void *data
);
28 static void hack_can_send(void *data
);
29 static void handle_client_exit(void *data
);
31 mapi_hfn_list_av1 override_hfnlist
[] = {
32 { "umode_changed", (hookfn
) check_umode_change
},
33 { "get_channel_access", (hookfn
) hack_channel_access
},
34 { "can_join", (hookfn
) hack_can_join
},
35 { "can_send", (hookfn
) hack_can_send
},
36 { "client_exit", (hookfn
) handle_client_exit
},
40 #define IsOperOverride(x) (HasPrivilege((x), "oper:override"))
42 struct OverrideSession
{
45 struct Client
*client
;
49 rb_dlink_list overriding_opers
= { NULL
, NULL
, 0 };
52 update_session_deadline(struct Client
*source_p
, struct OverrideSession
*session_p
)
54 if (session_p
== NULL
)
58 RB_DLINK_FOREACH(n
, overriding_opers
.head
)
60 struct OverrideSession
*s
= n
->data
;
62 if (s
->client
== source_p
)
70 if (session_p
== NULL
)
72 session_p
= rb_malloc(sizeof(struct OverrideSession
));
73 session_p
->client
= source_p
;
76 session_p
->deadline
= rb_current_time() + 1800;
78 rb_dlinkDelete(&session_p
->node
, &overriding_opers
);
79 rb_dlinkAdd(session_p
, &session_p
->node
, &overriding_opers
);
83 expire_override_deadlines(void *unused
)
85 rb_dlink_node
*n
, *tn
;
87 RB_DLINK_FOREACH_SAFE(n
, tn
, overriding_opers
.head
)
89 struct OverrideSession
*session_p
= n
->data
;
91 if (session_p
->deadline
> rb_current_time())
93 else if (session_p
->deadline
< rb_current_time())
95 const char *parv
[4] = {session_p
->client
->name
, session_p
->client
->name
, "-p", NULL
};
96 user_mode(session_p
->client
, session_p
->client
, 3, parv
);
102 check_umode_change(void *vdata
)
104 hook_data_umode_changed
*data
= (hook_data_umode_changed
*)vdata
;
105 struct Client
*source_p
= data
->client
;
107 if (!MyClient(source_p
))
110 /* didn't change +p umode, we don't need to do anything */
111 if (!((data
->oldumodes
^ source_p
->umodes
) & user_modes
['p']))
114 if (!IsOperOverride(source_p
))
116 sendto_one_notice(source_p
, ":*** You need oper:override privilege for +p");
117 source_p
->umodes
&= ~user_modes
['p'];
121 if (source_p
->umodes
& user_modes
['p'])
123 update_session_deadline(source_p
, NULL
);
125 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
, "%s has enabled oper-override (+p)",
126 get_oper_name(source_p
));
128 else if (!(source_p
->umodes
& user_modes
['p']))
130 rb_dlink_node
*n
, *tn
;
132 RB_DLINK_FOREACH_SAFE(n
, tn
, overriding_opers
.head
)
134 struct OverrideSession
*session_p
= n
->data
;
136 if (session_p
->client
!= source_p
)
139 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
, "%s has disabled oper-override (+p)",
140 get_oper_name(session_p
->client
));
142 rb_dlinkDelete(n
, &overriding_opers
);
149 hack_channel_access(void *vdata
)
151 hook_data_channel_approval
*data
= (hook_data_channel_approval
*) vdata
;
153 if (data
->approved
== CHFL_CHANOP
)
156 if (data
->client
->umodes
& user_modes
['p'])
158 update_session_deadline(data
->client
, NULL
);
159 data
->approved
= CHFL_CHANOP
;
161 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
, "%s is using oper-override on %s (modehacking)",
162 get_oper_name(data
->client
), data
->chptr
->chname
);
167 hack_can_join(void *vdata
)
169 hook_data_channel
*data
= (hook_data_channel
*) vdata
;
171 if (data
->approved
== 0)
174 if (data
->client
->umodes
& user_modes
['p'])
176 update_session_deadline(data
->client
, NULL
);
179 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
, "%s is using oper-override on %s (banwalking)",
180 get_oper_name(data
->client
), data
->chptr
->chname
);
185 hack_can_send(void *vdata
)
187 hook_data_channel_approval
*data
= (hook_data_channel_approval
*) vdata
;
189 if (data
->approved
== CAN_SEND_NONOP
|| data
->approved
== CAN_SEND_OPV
)
192 if (data
->client
->umodes
& user_modes
['p'])
194 data
->approved
= CAN_SEND_NONOP
;
196 if (MyClient(data
->client
))
198 update_session_deadline(data
->client
, NULL
);
199 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
, "%s is using oper-override on %s (forcing message)",
200 get_oper_name(data
->client
), data
->chptr
->chname
);
206 handle_client_exit(void *vdata
)
208 hook_data_client_exit
*data
= (hook_data_client_exit
*) vdata
;
209 rb_dlink_node
*n
, *tn
;
210 struct Client
*source_p
= data
->target
;
212 RB_DLINK_FOREACH_SAFE(n
, tn
, overriding_opers
.head
)
214 struct OverrideSession
*session_p
= n
->data
;
216 if (session_p
->client
!= source_p
)
219 rb_dlinkDelete(n
, &overriding_opers
);
224 struct ev_entry
*expire_override_deadlines_ev
= NULL
;
229 /* add the usermode to the available slot */
230 user_modes
['p'] = find_umode_slot();
231 construct_umodebuf();
233 expire_override_deadlines_ev
= rb_event_add("expire_override_deadlines", expire_override_deadlines
, NULL
, 60);
241 /* disable the umode and remove it from the available list */
243 construct_umodebuf();
245 rb_event_delete(expire_override_deadlines_ev
);
248 DECLARE_MODULE_AV1(override
, _modinit
, _moddeinit
, NULL
, NULL
,
249 override_hfnlist
, "$Revision: 3526 $");