Browse Source

ckdb - add ok, unok and expire to cmd_events

master
kanoi 9 years ago
parent
commit
61cb60c00a
  1. 2
      src/ckdb.h
  2. 141
      src/ckdb_cmd.c

2
src/ckdb.h

@ -51,7 +51,7 @@
#define DB_VLOCK "1"
#define DB_VERSION "1.0.4"
#define CKDB_VERSION DB_VERSION"-1.955"
#define CKDB_VERSION DB_VERSION"-1.957"
#define WHERE_FFL " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__

141
src/ckdb_cmd.c

@ -7533,12 +7533,12 @@ static void event_tree(K_TREE *event_tree, char *list, char *reply, size_t siz,
// Events status/settings
static char *cmd_events(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by,
tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *cd, K_TREE *trf_root)
{
K_ITEM *i_action, *i_cmd, *i_list, *i_ip, *i_eventname, *i_lifetime;
K_ITEM *i_des, *i_item;
K_ITEM *i_des, *i_item, *next_item;
K_TREE_CTX ctx[1];
IPS *ips;
char *action, *alert_cmd, *list, *ip, *eventname, *des;
@ -7798,7 +7798,6 @@ static char *cmd_events(__maybe_unused PGconn *conn, char *cmd, char *id,
* You need to BOTH use this AND remove the optioncontrol
* record from the database to permanently remove a ban
* (since there's no cmd_expopts ... yet) */
bool found = false;
i_ip = require_name(trf_root, "ip", 1, NULL, reply, siz);
if (!i_ip)
@ -7825,8 +7824,142 @@ static char *cmd_events(__maybe_unused PGconn *conn, char *cmd, char *id,
APPEND_REALLOC(buf, off, len, " unbanned");
} else {
APPEND_REALLOC(buf, off, len,
"ERR.unknown ip+eventname");
"ERR.unknown BAN ip+eventname");
}
} else if (strcasecmp(action, "ok") == 0) {
/* OK the ip+eventname with optional lifetime
* N.B. this doesn't survive a CKDB restart
* use just cmd_setopts for permanent OKs */
bool found = false;
oldlife = 0;
i_ip = require_name(trf_root, "ip", 1, NULL, reply, siz);
if (!i_ip)
return strdup(reply);
ip = transfer_data(i_ip);
i_eventname = require_name(trf_root, "eventname", 1, NULL, reply, siz);
if (!i_eventname)
return strdup(reply);
eventname = transfer_data(i_eventname);
i_lifetime = optional_name(trf_root, "lifetime", 1,
(char *)intpatt, reply, siz);
if (i_lifetime)
lifetime = atoi(transfer_data(i_lifetime));
else {
if (*reply)
return strdup(reply);
// Forever
lifetime = 0;
}
i_des = optional_name(trf_root, "des", 1, NULL, reply, siz);
if (i_des)
des = transfer_data(i_des);
else {
if (*reply)
return strdup(reply);
des = NULL;
}
K_WLOCK(ips_free);
i_item = find_ips(IPS_GROUP_OK, ip, eventname, NULL);
if (i_item) {
DATA_IPS(ips, i_item);
found = true;
oldlife = ips->lifetime;
ips->lifetime = lifetime;
// Don't change it if it's not supplied
if (des) {
LIST_MEM_SUB(ips_free, ips->description);
FREENULL(ips->description);
ips->description = strdup(des);
LIST_MEM_ADD(ips_free, ips->description);
}
} else {
ips_add(IPS_GROUP_OK, ip, eventname,
is_elimitname(eventname, true), des, true,
false, lifetime, true);
}
K_WUNLOCK(ips_free);
APPEND_REALLOC_INIT(buf, off, len);
APPEND_REALLOC(buf, off, len, "ok.");
if (found) {
snprintf(tmp, sizeof(tmp), "already %s/%s %d->%d",
ip, eventname, oldlife, lifetime);
} else {
snprintf(tmp, sizeof(tmp), "ok %s/%s %d",
ip, eventname, lifetime);
}
APPEND_REALLOC(buf, off, len, tmp);
} else if (strcasecmp(action, "unok") == 0) {
/* UnOK the ip+eventname - sets lifetime to 1 meaning
* it expires 1 second after it was created
* so next access will remove the OK and succeed
* N.B. if it was a permanent 'cmd_setopts' OK, the unOK
* won't survive a CKDB restart.
* You need to BOTH use this AND remove the optioncontrol
* record from the database to permanently remove an OK
* (since there's no cmd_expopts ... yet) */
bool found = false;
i_ip = require_name(trf_root, "ip", 1, NULL, reply, siz);
if (!i_ip)
return strdup(reply);
ip = transfer_data(i_ip);
i_eventname = require_name(trf_root, "eventname", 1, NULL, reply, siz);
if (!i_eventname)
return strdup(reply);
eventname = transfer_data(i_eventname);
K_WLOCK(ips_free);
i_item = find_ips(IPS_GROUP_OK, ip, eventname, NULL);
if (i_item) {
found = true;
DATA_IPS(ips, i_item);
ips->lifetime = 1;
}
K_WUNLOCK(ips_free);
APPEND_REALLOC_INIT(buf, off, len);
if (found) {
APPEND_REALLOC(buf, off, len, "ok.");
APPEND_REALLOC(buf, off, len, ip);
APPEND_REALLOC(buf, off, len, "/");
APPEND_REALLOC(buf, off, len, eventname);
APPEND_REALLOC(buf, off, len, " unOKed");
} else {
APPEND_REALLOC(buf, off, len,
"ERR.unknown OK ip+eventname");
}
} else if (strcasecmp(action, "expire") == 0) {
/* Expire all ips that are too old
* and remove all non-current */
bool expire;
rows = 0;
K_WLOCK(ips_free);
i_item = first_in_ktree(ips_root, ctx);
while (i_item) {
DATA_IPS(ips, i_item);
expire = false;
if (!CURRENT(&(ips->expirydate)))
expire = true;
else if (ips->lifetime != 0 &&
(int)tvdiff(now, &(ips->createdate)) > ips->lifetime) {
expire = true;
}
if (expire) {
rows++;
next_item = next_in_ktree(ctx);
remove_from_ktree(ips_root, i_item);
k_unlink_item(ips_store, i_item);
if (ips->description) {
LIST_MEM_SUB(ips_free, ips->description);
FREENULL(ips->description);
}
k_add_head(ips_free, i_item);
i_item = next_item;
continue;
}
i_item = next_in_ktree(ctx);
}
K_WUNLOCK(ips_free);
APPEND_REALLOC_INIT(buf, off, len);
snprintf(tmp, sizeof(tmp), "ok.expired %d", rows);
APPEND_REALLOC(buf, off, len, tmp);
} else {
snprintf(reply, siz, "unknown action '%s'", action);
LOGERR("%s() %s.%s", __func__, id, reply);

Loading…
Cancel
Save