00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdinc.h"
00026 #include "tools.h"
00027 #include "channel.h"
00028 #include "client.h"
00029 #include "common.h"
00030 #include "pcre.h"
00031 #include "irc_string.h"
00032 #include "sprintf_irc.h"
00033 #include "ircd.h"
00034 #include "hostmask.h"
00035 #include "numeric.h"
00036 #include "fdlist.h"
00037 #include "s_bsd.h"
00038 #include "s_conf.h"
00039 #include "s_log.h"
00040 #include "s_misc.h"
00041 #include "send.h"
00042 #include "hash.h"
00043 #include "handlers.h"
00044 #include "s_serv.h"
00045 #include "msg.h"
00046 #include "parse.h"
00047 #include "modules.h"
00048 #include "resv.h"
00049 #include "list.h"
00050
00051 static void mo_rxline(struct Client *, struct Client *, int, char *[]);
00052 static void ms_rxline(struct Client *, struct Client *, int, char *[]);
00053 static void mo_unrxline(struct Client *, struct Client *, int, char *[]);
00054 static void ms_unrxline(struct Client *, struct Client *, int, char *[]);
00055
00056 static int valid_xline(struct Client *, char *, char *, int);
00057 static void write_rxline(struct Client *, const char *, char *, time_t);
00058 static void remove_xline(struct Client *, char *);
00059 static int remove_txline(const char *);
00060
00061 struct Message rxline_msgtab = {
00062 "RXLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
00063 { m_unregistered, m_not_oper, ms_rxline, m_ignore, mo_rxline, m_ignore }
00064 };
00065
00066 struct Message unrxline_msgtab = {
00067 "UNRXLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
00068 { m_unregistered, m_not_oper, ms_unrxline, m_ignore, mo_unrxline, m_ignore }
00069 };
00070
00071 #ifndef STATIC_MODULES
00072 void
00073 _modinit(void)
00074 {
00075 mod_add_cmd(&rxline_msgtab);
00076 mod_add_cmd(&unrxline_msgtab);
00077 }
00078
00079 void
00080 _moddeinit(void)
00081 {
00082 mod_del_cmd(&rxline_msgtab);
00083 mod_del_cmd(&unrxline_msgtab);
00084 }
00085
00086 const char *_version = "$Revision: 33 $";
00087 #endif
00088
00089 static int
00090 already_placed_rxline(struct Client *source_p, const char *gecos)
00091 {
00092 const dlink_node *ptr = NULL;
00093
00094 DLINK_FOREACH(ptr, rxconf_items.head)
00095 {
00096 struct ConfItem *aptr = ptr->data;
00097 const struct MatchItem *match_item = map_to_conf(aptr);
00098
00099 if (!strcmp(gecos, aptr->name))
00100 {
00101 sendto_one(source_p, ":%s NOTICE %s :[%s] already RX-Lined by [%s] - %s",
00102 me.name, source_p->name, gecos,
00103 aptr->name, match_item->reason);
00104 return 1;
00105 }
00106 }
00107
00108 return 0;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 static void
00122 mo_rxline(struct Client *client_p, struct Client *source_p,
00123 int parc, char *parv[])
00124 {
00125 char *reason = NULL;
00126 char *gecos = NULL;
00127 char *target_server = NULL;
00128 time_t tkline_time = 0;
00129
00130 if (!IsOperX(source_p))
00131 {
00132 sendto_one(source_p, form_str(ERR_NOPRIVS),
00133 me.name, source_p->name, "rxline");
00134 return;
00135 }
00136
00137 if (parse_aline("RXLINE", source_p, parc, parv, AWILD, &gecos,
00138 NULL, &tkline_time, NULL, &reason) < 0)
00139 return;
00140
00141 if (target_server != NULL)
00142 {
00143 sendto_match_servs(source_p, target_server, CAP_CLUSTER,
00144 "RXLINE %s %s %d :%s",
00145 target_server, gecos, (int)tkline_time, reason);
00146
00147
00148 if (!match(target_server, me.name))
00149 return;
00150 }
00151
00152 #if 0
00153 cluster_a_line(source_p, "RXLINE", CAP_KLN, SHARED_XLINE,
00154 "%s 0 :%s", gecos, reason);
00155 #endif
00156
00157 if (!valid_xline(source_p, gecos, reason, 0))
00158 return;
00159
00160 if (!already_placed_rxline(source_p, gecos))
00161 write_rxline(source_p, gecos, reason, tkline_time);
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 static void
00173 ms_rxline(struct Client *client_p, struct Client *source_p,
00174 int parc, char *parv[])
00175 {
00176 int t_sec = 0;
00177
00178 if (parc != 5 || EmptyString(parv[4]))
00179 return;
00180
00181 if (!IsClient(source_p))
00182 return;
00183
00184 if (!valid_xline(source_p, parv[2], parv[4], 0))
00185 return;
00186
00187 t_sec = atoi(parv[3]);
00188
00189 if (t_sec < 3)
00190 t_sec = 0;
00191
00192 sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
00193 "RXLINE %s %s %s :%s",
00194 parv[1], parv[2], parv[3], parv[4]);
00195
00196 if (!match(parv[1], me.name))
00197 return;
00198
00199 if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
00200 source_p->username, source_p->host,
00201 SHARED_XLINE))
00202 if (!already_placed_rxline(source_p, parv[2]))
00203 write_rxline(source_p, parv[2], parv[4], t_sec);
00204 }
00205
00206 static void
00207 mo_unrxline(struct Client *client_p, struct Client *source_p,
00208 int parc, char *parv[])
00209 {
00210 char *gecos = NULL;
00211 char *target_server = NULL;
00212
00213 if (!IsOperX(source_p))
00214 {
00215 sendto_one(source_p, form_str(ERR_NOPRIVS),
00216 me.name, source_p->name, "unrxline");
00217 return;
00218 }
00219
00220 if (parse_aline("UNRXLINE", source_p, parc, parv, 0, &gecos,
00221 NULL, NULL, &target_server, NULL) < 0)
00222 return;
00223
00224 if (target_server != NULL)
00225 {
00226
00227 sendto_match_servs(source_p, target_server, CAP_CLUSTER,
00228 "UNRXLINE %s %s", target_server, gecos);
00229
00230
00231 if (!match(target_server, me.name))
00232 return;
00233 }
00234
00235 #if 0
00236 cluster_a_line(source_p, "UNRXLINE", CAP_CLUSTER, SHARED_UNXLINE,
00237 "%s", gecos);
00238 #endif
00239
00240 remove_xline(source_p, gecos);
00241 }
00242
00243
00244
00245
00246
00247
00248
00249 static void
00250 ms_unrxline(struct Client *client_p, struct Client *source_p,
00251 int parc, char *parv[])
00252 {
00253 if (parc != 3 || EmptyString(parv[2]))
00254 return;
00255
00256 sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
00257 "UNRXLINE %s %s",
00258 parv[1], parv[2]);
00259
00260 if (!IsClient(source_p) || !match(parv[1], me.name))
00261 return;
00262
00263 if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
00264 source_p->username, source_p->host,
00265 SHARED_UNXLINE))
00266 remove_xline(source_p, parv[2]);
00267 }
00268
00269
00270
00271
00272
00273
00274
00275 static int
00276 valid_xline(struct Client *source_p, char *gecos, char *reason, int warn)
00277 {
00278 if (EmptyString(reason))
00279 {
00280 if (warn)
00281 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
00282 me.name, source_p->name, "RXLINE");
00283 return 0;
00284 }
00285
00286 if (strchr(gecos, '"'))
00287 {
00288 sendto_one(source_p, ":%s NOTICE %s :Invalid character '\"'",
00289 me.name, source_p->name);
00290 return 0;
00291 }
00292
00293 if (!valid_wild_card_simple(gecos))
00294 {
00295 if (warn)
00296 sendto_one(source_p, ":%s NOTICE %s :Please include at least %d non-wildcard characters with the rxline",
00297 me.name, source_p->name, ConfigFileEntry.min_nonwildcard_simple);
00298
00299 return 0;
00300 }
00301
00302 return 1;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 static void
00312 write_rxline(struct Client *source_p, const char *gecos, char *reason,
00313 time_t tkline_time)
00314 {
00315 struct ConfItem *conf = NULL;
00316 struct MatchItem *match_item = NULL;
00317 const char *current_date = NULL;
00318 time_t cur_time = 0;
00319 pcre *exp_gecos = NULL;
00320 const char *errptr = NULL;
00321
00322 if (!(exp_gecos = ircd_pcre_compile(gecos, &errptr)))
00323 {
00324 sendto_realops_flags(UMODE_ALL, L_ALL,
00325 "Failed to add regular expression based X-Line: %s", errptr);
00326 return;
00327 }
00328
00329 conf = make_conf_item(RXLINE_TYPE);
00330 conf->regexpname = exp_gecos;
00331
00332 match_item = map_to_conf(conf);
00333
00334 DupString(conf->name, gecos);
00335 DupString(match_item->reason, reason);
00336 DupString(match_item->oper_reason, "");
00337
00338 cur_time = CurrentTime;
00339 current_date = smalldate(cur_time);
00340
00341 if (tkline_time)
00342 {
00343 sendto_realops_flags(UMODE_ALL, L_ALL,
00344 "%s added temporary %d min. RX-Line for [%s] [%s]",
00345 get_oper_name(source_p), (int)tkline_time/60,
00346 conf->name, match_item->reason);
00347 sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. RX-Line [%s]",
00348 MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
00349 source_p->name, (int)tkline_time/60, conf->name);
00350 ilog(L_TRACE, "%s added temporary %d min. RX-Line for [%s] [%s]",
00351 source_p->name, (int)tkline_time/60,
00352 conf->name, match_item->reason);
00353 match_item->hold = CurrentTime + tkline_time;
00354 add_temp_line(conf);
00355 }
00356 else
00357 write_conf_line(source_p, conf, current_date, cur_time);
00358 rehashed_klines = 1;
00359 }
00360
00361 static void
00362 remove_xline(struct Client *source_p, char *gecos)
00363 {
00364
00365 if (remove_txline(gecos))
00366 {
00367 sendto_one(source_p,
00368 ":%s NOTICE %s :Un-rxlined [%s] from temporary RX-Lines",
00369 me.name, source_p->name, gecos);
00370 sendto_realops_flags(UMODE_ALL, L_ALL,
00371 "%s has removed the temporary RX-Line for: [%s]",
00372 get_oper_name(source_p), gecos);
00373 ilog(L_NOTICE, "%s removed temporary RX-Line for [%s]",
00374 source_p->name, gecos);
00375 return;
00376 }
00377
00378 if (remove_conf_line(RXLINE_TYPE, source_p, gecos, NULL) > 0)
00379 {
00380 sendto_one(source_p, ":%s NOTICE %s :RX-Line for [%s] is removed",
00381 me.name, source_p->name, gecos);
00382 sendto_realops_flags(UMODE_ALL, L_ALL,
00383 "%s has removed the RX-Line for: [%s]",
00384 get_oper_name(source_p), gecos);
00385 ilog(L_NOTICE, "%s removed RX-Line for [%s]",
00386 get_oper_name(source_p), gecos);
00387 }
00388 else
00389 sendto_one(source_p, ":%s NOTICE %s :No RX-Line for %s",
00390 me.name, source_p->name, gecos);
00391 }
00392
00393
00394
00395
00396
00397
00398
00399 static int
00400 remove_txline(const char *const gecos)
00401 {
00402 dlink_node *ptr = NULL;
00403
00404 DLINK_FOREACH(ptr, temporary_rxlines.head)
00405 {
00406 struct ConfItem *conf = ptr->data;
00407
00408 if (!strcmp(gecos, conf->name))
00409 {
00410 dlinkDelete(ptr, &temporary_rxlines);
00411 free_dlink_node(ptr);
00412 delete_conf_item(conf);
00413 return 1;
00414 }
00415 }
00416
00417 return 0;
00418 }