1
/* $Id: ora_drv.c,v 1.15 2006/05/13 01:12:59 jonz Exp $ */
5
COPYRIGHT (C) 2002-2006 JONATHAN A. ZDZIARSKI
7
This program is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License
9
as published by the Free Software Foundation; version 2
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
#include <auto-config.h>
29
#include <sys/types.h>
40
#ifdef TIME_WITH_SYS_TIME
41
# include <sys/time.h>
44
# ifdef HAVE_SYS_TIME_H
45
# include <sys/time.h>
51
#include "storage_driver.h"
58
#include "config_shared.h"
61
dspam_init_driver (DRIVER_CTX *DTX)
67
dspam_shutdown_driver (DRIVER_CTX *DTX)
73
_ds_init_storage (DSPAM_CTX * CTX, void *dbh)
75
struct _ora_drv_storage *s;
79
char username[64] = "";
80
char password[32] = "";
82
char filename[MAX_FILENAME_LENGTH];
89
LOG(LOG_ERR, ERR_DRV_NO_ATTACH);
93
if (CTX->flags & DSF_MERGED) {
94
LOG(LOG_ERR, ERR_DRV_NO_MERGED);
98
/* don't init if we're already initted */
99
if (CTX->storage != NULL)
101
LOGDEBUG ("_ds_init_storage: storage already initialized");
105
s = malloc (sizeof (struct _ora_drv_storage));
108
LOG (LOG_CRIT, ERR_MEM_ALLOC);
112
s->control_token = 0;
118
s->iter_token = NULL;
121
if (_ds_read_attribute(CTX->config->attributes, "OraServer")) {
125
_ds_read_attribute(CTX->config->attributes, "OraServer"),
128
if ((p = _ds_read_attribute(CTX->config->attributes, "OraUser")))
129
strlcpy(username, p, sizeof(username));
131
if ((p = _ds_read_attribute(CTX->config->attributes, "OraPass")))
132
strlcpy(password, p, sizeof(password));
134
if ((p = _ds_read_attribute(CTX->config->attributes, "OraSchema")))
135
strlcpy(schema, p, sizeof(schema));
139
LOG(LOG_ERR, ERR_AGENT_DSPAM_HOME);
142
snprintf (filename, MAX_FILENAME_LENGTH, "%s/oracle.data", CTX->home);
143
file = fopen (filename, "r");
146
LOG (LOG_WARNING, "unable to open %s for reading: %s",
147
filename, strerror (errno));
151
while (fgets (buffer, sizeof (buffer), file) != NULL)
155
strlcpy (dblink, buffer, sizeof (dblink));
157
strlcpy (username, buffer, sizeof (username));
159
strlcpy (password, buffer, sizeof (password));
161
strlcpy (schema, buffer, sizeof (schema));
169
LOG (LOG_WARNING, "file %s: incomplete Oracle connect data", filename);
173
s->schema = strdup (schema);
175
/* establish an Oracle session */
177
OCIInitialize ((ub4) OCI_DEFAULT, (dvoid *) 0,
178
(dvoid * (*)(dvoid *, size_t)) 0,
179
(dvoid * (*)(dvoid *, dvoid *, size_t)) 0,
180
(void (*)(dvoid *, dvoid *)) 0);
182
OCIEnvInit ((OCIEnv **) & s->envhp, OCI_DEFAULT, (size_t) 0, (dvoid **) 0);
184
OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & s->errhp, OCI_HTYPE_ERROR,
185
(size_t) 0, (dvoid **) 0);
187
OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & s->srvhp,
188
OCI_HTYPE_SERVER, (size_t) 0, (dvoid **) 0);
190
OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & s->svchp,
191
OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0);
193
if (_ora_drv_checkerr
195
OCIServerAttach (s->srvhp, s->errhp, (text *) dblink, strlen (dblink),
199
OCIAttrSet ((dvoid *) s->svchp, OCI_HTYPE_SVCCTX, (dvoid *) s->srvhp,
200
(ub4) 0, OCI_ATTR_SERVER, (OCIError *) s->errhp);
202
OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & s->authp,
203
(ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0);
205
OCIAttrSet ((dvoid *) s->authp, (ub4) OCI_HTYPE_SESSION,
206
(dvoid *) username, (ub4) strlen ((char *) username),
207
(ub4) OCI_ATTR_USERNAME, s->errhp);
209
OCIAttrSet ((dvoid *) s->authp, (ub4) OCI_HTYPE_SESSION,
210
(dvoid *) password, (ub4) strlen ((char *) password),
211
(ub4) OCI_ATTR_PASSWORD, s->errhp);
213
if (_ora_drv_checkerr (NULL, s->errhp, OCISessionBegin (s->svchp, s->errhp,
220
(void) OCIAttrSet ((dvoid *) s->svchp, (ub4) OCI_HTYPE_SVCCTX,
221
(dvoid *) s->authp, (ub4) 0,
222
(ub4) OCI_ATTR_SESSION, s->errhp);
226
/* get spam totals on successful init */
227
if (CTX->username != NULL)
229
if (_ora_drv_get_spamtotals (CTX))
231
LOGDEBUG ("unable to load totals. using zero values.");
232
memset (&CTX->totals, 0, sizeof (struct _ds_spam_totals));
233
memset (&s->control_totals, 0, sizeof (struct _ds_spam_totals));
237
memcpy (&s->control_totals, &CTX->totals,
238
sizeof (struct _ds_spam_totals));
243
memset (&CTX->totals, 0, sizeof (struct _ds_spam_totals));
244
memset (&s->control_totals, 0, sizeof (struct _ds_spam_totals));
251
_ds_shutdown_storage (DSPAM_CTX * CTX)
253
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
255
if (CTX->storage == NULL)
257
LOGDEBUG ("_ds_shutdown_storage: storage not initialized");
261
/* Store spam totals on shutdown */
262
if (CTX->username != NULL && CTX->operating_mode != DSM_CLASSIFY)
264
_ora_drv_set_spamtotals (CTX);
266
OCISessionEnd (s->svchp, s->errhp, s->authp, (ub4) OCI_DEFAULT);
267
OCIServerDetach (s->srvhp, s->errhp, (ub4) OCI_DEFAULT);
268
OCIHandleFree ((dvoid *) s->srvhp, (ub4) OCI_HTYPE_SERVER);
269
OCIHandleFree ((dvoid *) s->svchp, (ub4) OCI_HTYPE_SVCCTX);
270
OCIHandleFree ((dvoid *) s->errhp, (ub4) OCI_HTYPE_ERROR);
271
OCIHandleFree ((dvoid *) s->envhp, OCI_HTYPE_ENV);
281
_ora_drv_query_error (const char *error, const char *query)
284
time_t tm = time (NULL);
286
char fn[MAX_FILENAME_LENGTH];
288
snprintf (fn, sizeof (fn), "%s/sql.errors", LOGDIR);
290
snprintf (ct, sizeof (ct), "%s", ctime (&tm));
293
file = fopen (fn, "a");
297
LOG(LOG_ERR, ERR_IO_FILE_WRITE, fn, strerror (errno));
301
fprintf (file, "[%s] %d: %s: %s\n", ct, getpid (), error, query);
303
fprintf (file, "[%s] %d: %s\n", ct, getpid (), error);
308
fprintf (stderr, "[%s] %d: %s: %s\n", ct, getpid (), error, query);
310
fprintf (stderr, "[%s] %d: %s\n", ct, getpid (), error);
317
_ora_drv_checkerr (const char *query, OCIError * errhp, sword status)
326
case OCI_SUCCESS_WITH_INFO:
327
_ora_drv_query_error ("Oracle error: OCI_SUCCESS_WITH_INFO", query);
330
_ora_drv_query_error ("Oracle error: OCI_NEED_DATA", query);
333
_ora_drv_query_error ("Oracle error: OCI_NO_DATA", query);
336
(void) OCIErrorGet ((dvoid *) errhp, (ub4) 1, (text *) NULL, &errcode,
337
errbuf, (ub4) sizeof (errbuf), OCI_HTYPE_ERROR);
338
_ora_drv_query_error ((const char *) errbuf, query);
340
case OCI_INVALID_HANDLE:
341
_ora_drv_query_error ("Oracle error: OCI_INVALID_HANDLE", query);
343
case OCI_STILL_EXECUTING:
344
_ora_drv_query_error ("Oracle error: OCI_STILL_EXECUTE", query);
347
_ora_drv_query_error ("Oracle error: OCI_CONTINUE", query);
357
_ds_create_signature_id (DSPAM_CTX * CTX, char *buf, size_t len)
364
snprintf (session, sizeof (session), "%8lx%d", (long) time (NULL), pid);
366
for (j = 0; j < 2; j++)
368
snprintf (digit, 6, "%d", rand ());
369
strlcat (session, digit, 64);
372
strlcpy (buf, session, len);
377
_ds_get_signature (DSPAM_CTX * CTX, struct _ds_spam_signature *SIG,
378
const char *signature)
380
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
384
OCIDefine *defn = (OCIDefine *) 0;
387
if (CTX->storage == NULL)
389
LOGDEBUG ("_ds_get_signature: storage not initialized");
393
p = _ora_drv_getpwnam (CTX, CTX->username);
396
LOGDEBUG ("_ds_get_signature: unable to _ora_drv_getpwnam(%s)",
401
snprintf (query, sizeof (query),
402
"SELECT LENGTH FROM %s.DSPAM_SIGNATURE_DATA"
403
" WHERE SIGNATURE = '%s' AND USER_ID = %d",
404
s->schema, signature, p->pw_uid);
406
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
408
(ub4) OCI_HTYPE_STMT,
414
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp,
425
if (_ora_drv_checkerr
427
OCIDefineByPos (stmthp, &defn, s->errhp, 1, (dvoid *) & SIG->length,
428
(sword) sizeof (long), SQLT_INT, (dvoid *) 0,
429
(ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
432
status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0,
433
(OCISnapshot *) NULL, (OCISnapshot *) NULL,
436
if (status == OCI_NO_DATA)
438
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
442
if (status != OCI_SUCCESS)
445
SIG->data = malloc (SIG->length);
446
if (SIG->data == NULL)
448
LOG (LOG_CRIT, ERR_MEM_ALLOC);
452
snprintf (query, sizeof (query),
453
"SELECT DATA FROM %s.DSPAM_SIGNATURE_DATA"
454
" WHERE SIGNATURE = '%s' AND USER_ID = %d",
455
s->schema, signature, p->pw_uid);
457
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
459
(ub4) OCI_HTYPE_STMT,
465
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp,
476
if (_ora_drv_checkerr
478
OCIDefineByPos (stmthp, &defn, s->errhp, 1, (dvoid *) SIG->data,
479
(sword) SIG->length, SQLT_LNG, (dvoid *) 0, (ub2 *) 0,
480
(ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
483
status = _ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp,
495
if (status == OCI_NO_DATA)
497
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
501
if (status != OCI_SUCCESS)
504
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
509
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
514
_ds_set_signature (DSPAM_CTX * CTX, struct _ds_spam_signature *SIG,
515
const char *signature)
517
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
521
OCIBind *phBindSignature = NULL;
523
if (CTX->storage == NULL)
525
LOGDEBUG ("_ds_set_signature: storage not initialized");
529
if (SIG == NULL || SIG->data == NULL || !SIG->length)
532
p = _ora_drv_getpwnam (CTX, CTX->username);
535
LOGDEBUG ("_ds_set_signature: unable to _ora_drv_getpwnam(%s)",
540
snprintf (query, sizeof (query),
541
"INSERT INTO %s.DSPAM_SIGNATURE_DATA(USER_ID, SIGNATURE, LENGTH, CREATED_ON"
542
", DATA) VALUES(%d, '%s', %ld, SYSDATE, :signature)",
543
s->schema, p->pw_uid, signature, SIG->length);
545
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
547
(ub4) OCI_HTYPE_STMT,
553
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp,
564
if (_ora_drv_checkerr (query, s->errhp, OCIBindByName (stmthp,
570
SQLT_LNG, NULL, NULL,
576
if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp,
587
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
592
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
597
_ds_delete_signature (DSPAM_CTX * CTX, const char *signature)
599
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
604
if (CTX->storage == NULL)
606
LOGDEBUG ("_ds_delete_signature: storage not initialized");
610
p = _ora_drv_getpwnam (CTX, CTX->username);
613
LOGDEBUG ("_ds_set_signature: unable to _ora_drv_getpwnam(%s)",
618
snprintf (query, sizeof (query),
619
"DELETE FROM %s.DSPAM_SIGNATURE_DATA"
620
" WHERE SIGNATURE = '%s' AND USER_ID = %d",
621
s->schema, signature, p->pw_uid);
623
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
625
(ub4) OCI_HTYPE_STMT,
631
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp,
642
if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp,
653
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
658
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
663
_ds_verify_signature (DSPAM_CTX * CTX, const char *signature)
665
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
666
char query[1024], sig[32];
669
OCIDefine *defn = (OCIDefine *) 0;
672
if (CTX->storage == NULL)
674
LOGDEBUG ("_ds_verify_signature: storage not initialized");
678
p = _ora_drv_getpwnam (CTX, CTX->username);
681
LOGDEBUG ("_ds_verify_signature: unable to _ora_drv_getpwnam(%s)",
686
snprintf (query, sizeof (query),
687
"SELECT SIGNATURE FROM %s.DSPAM_SIGNATURE_DATA"
688
" WHERE SIGNATURE = '%s' AND USER_ID = %d",
689
s->schema, signature, p->pw_uid);
691
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
693
(ub4) OCI_HTYPE_STMT,
699
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp,
710
if (_ora_drv_checkerr
712
OCIDefineByPos (stmthp, &defn, s->errhp, 1, (dvoid *) & sig,
713
(sword) sizeof (sig), SQLT_STR, (dvoid *) 0, (ub2 *) 0,
714
(ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
717
status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0,
718
(OCISnapshot *) NULL, (OCISnapshot *) NULL,
721
if (status == OCI_NO_DATA)
723
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
727
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
732
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
737
_ds_get_nextuser (DSPAM_CTX * CTX)
739
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
743
static OCIDefine *defn = (OCIDefine *) 0;
744
static char user[MAX_FILENAME_LENGTH] = { 0 };
747
if (CTX->storage == NULL)
749
LOGDEBUG ("_ds_getall_spamrecords: storage not initialized");
753
/* Execute initial query */
754
if (s->iter_user == NULL)
756
snprintf (query, sizeof (query),
757
"SELECT DISTINCT USER_ID FROM %s.DSPAM_STATS", s->schema);
759
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
769
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (s->iter_user,
781
if (_ora_drv_checkerr
783
OCIDefineByPos (s->iter_user, &defn, s->errhp, 1, (dvoid *) & uid,
784
(sword) sizeof (uid_t), SQLT_UIN, (dvoid *) 0,
785
(ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
788
if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp,
803
OCIStmtFetch (s->iter_user, s->errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT,
806
if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO)
809
p = _ora_drv_getpwuid (CTX, uid);
812
strlcpy (user, p->pw_name, sizeof (user));
818
OCIHandleFree ((dvoid *) s->iter_user, (ub4) OCI_HTYPE_STMT);
824
struct _ds_storage_record *
825
_ds_get_nexttoken (DSPAM_CTX * CTX)
827
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
828
struct _ds_storage_record *st;
830
char query[1024], token_c[32];
831
static OCIDefine *defn1 = NULL, *defn2 = NULL, *defn3 = NULL, *defn4 = NULL;
835
if (CTX->storage == NULL)
837
LOGDEBUG ("_ds_getall_spamrecords: storage not initialized");
841
p = _ora_drv_getpwnam (CTX, CTX->username);
844
LOGDEBUG ("_ds_get_nexttoken: unable to _ora_drv_getpwnam(%s)",
849
if (s->iter_token == NULL)
851
snprintf (query, sizeof (query),
852
"SELECT TOKEN, SPAM_HITS, INNOCENT_HITS, "
853
"TO_NUMBER(LAST_HIT-TO_DATE('01011970','DDMMYYYY'))*60*60*24"
854
" FROM %s.DSPAM_TOKEN_DATA WHERE USER_ID = %d", s->schema,
857
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
867
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (s->iter_token,
879
if (_ora_drv_checkerr
881
OCIDefineByPos (s->iter_token, &defn1, s->errhp, 1,
882
(dvoid *) & token_c, (sword) sizeof (token_c),
883
SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0,
884
OCI_DEFAULT)) != OCI_SUCCESS)
887
if (_ora_drv_checkerr
889
OCIDefineByPos (s->iter_token, &defn2, s->errhp, 2, (dvoid *) & sh,
890
(sword) sizeof (sh), SQLT_INT, (dvoid *) 0,
891
(ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
894
if (_ora_drv_checkerr
896
OCIDefineByPos (s->iter_token, &defn3, s->errhp, 3, (dvoid *) & ih,
897
(sword) sizeof (ih), SQLT_INT, (dvoid *) 0,
898
(ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
901
if (_ora_drv_checkerr
903
OCIDefineByPos (s->iter_token, &defn4, s->errhp, 4, (dvoid *) & lh,
904
(sword) sizeof (lh), SQLT_INT, (dvoid *) 0,
905
(ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
908
if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp,
923
OCIStmtFetch (s->iter_token, s->errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT,
926
if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO)
929
st = malloc (sizeof (struct _ds_storage_record));
932
LOG (LOG_CRIT, ERR_MEM_ALLOC);
936
memset (st, 0, sizeof (struct _ds_storage_record));
937
st->token = strtoull (token_c, NULL, 0);
939
st->innocent_hits = ih;
940
st->last_hit = (time_t) lh;
946
OCIHandleFree ((dvoid *) s->iter_user, (ub4) OCI_HTYPE_STMT);
947
s->iter_token = NULL;
952
struct _ds_storage_signature *
953
_ds_get_nextsignature (DSPAM_CTX * CTX)
955
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
956
struct _ds_storage_signature *st;
958
char query[1024], signature[128];
959
static OCIDefine *defn1 = NULL, *defn2 = NULL, *defn3 = NULL, *defn4 = NULL;
964
if (CTX->storage == NULL)
966
LOGDEBUG ("_ds_getall_spamrecords: storage not initialized");
970
p = _ora_drv_getpwnam (CTX, CTX->username);
973
LOGDEBUG ("_ds_get_nexttoken: unable to _ora_drv_getpwnam(%s)",
978
if (s->iter_sig == NULL)
980
snprintf (query, sizeof (query),
981
"SELECT SIGNATURE, LENGTH, "
982
" TO_NUMBER(CREATED_ON-TO_DATE('01011970','MMDDYYYY'))*60*60*24"
983
" FROM %s.DSPAM_SIGNATURE_DATA WHERE USER_ID = %d",
984
s->schema, p->pw_uid);
986
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
996
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (s->iter_sig,
1008
if (_ora_drv_checkerr
1010
OCIDefineByPos (s->iter_sig, &defn1, s->errhp, 1,
1011
(dvoid *) & signature, (sword) sizeof (signature),
1012
SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0,
1013
OCI_DEFAULT)) != OCI_SUCCESS)
1016
if (_ora_drv_checkerr
1018
OCIDefineByPos (s->iter_sig, &defn2, s->errhp, 2, (dvoid *) & sl,
1019
(sword) sizeof (sl), SQLT_INT, (dvoid *) 0,
1020
(ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
1023
if (_ora_drv_checkerr
1025
OCIDefineByPos (s->iter_sig, &defn3, s->errhp, 3, (dvoid *) & lh,
1026
(sword) sizeof (lh), SQLT_INT, (dvoid *) 0,
1027
(ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
1030
if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp,
1044
status = OCIStmtFetch (s->iter_sig, s->errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT,
1047
if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO)
1050
st = malloc (sizeof (struct _ds_storage_signature));
1053
LOG (LOG_CRIT, ERR_MEM_ALLOC);
1057
memset (st, 0, sizeof (struct _ds_storage_signature));
1060
st->created_on = (time_t) lh;
1061
strlcpy (st->signature, signature, sizeof (st->signature));
1062
st->data = malloc (st->length);
1064
if (st->data == NULL)
1066
LOG (LOG_CRIT, ERR_MEM_ALLOC);
1070
snprintf (query, sizeof (query),
1071
"SELECT DATA FROM %s.DSPAM_SIGNATURE_DATA WHERE USER_ID = %d"
1072
" AND SIGNATURE = '%s'", s->schema, p->pw_uid, st->signature);
1074
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
1075
(dvoid **) & stmthp,
1076
(ub4) OCI_HTYPE_STMT,
1082
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp,
1092
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1097
if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4,
1109
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1114
if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp,
1124
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1130
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1136
OCIHandleFree ((dvoid *) s->iter_sig, (ub4) OCI_HTYPE_STMT);
1142
_ora_drv_getpwnam (DSPAM_CTX * CTX, const char *name)
1145
#ifndef VIRTUAL_USERS
1146
static struct passwd p = { NULL, NULL, 0, 0, NULL, NULL, NULL };
1149
if (p.pw_name != NULL)
1151
/* cache the last name queried */
1152
if (name != NULL && !strcmp (p.pw_name, name))
1160
q = getpwnam (name);
1163
p.pw_uid = q->pw_uid;
1164
p.pw_name = strdup (q->pw_name);
1168
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
1169
static struct passwd p = { NULL, NULL, 0, 0, NULL, NULL, NULL };
1172
OCIDefine *defn = (OCIDefine *) 0;
1176
if (p.pw_name != NULL)
1178
/* cache the last name queried */
1179
if (name != NULL && !strcmp (p.pw_name, name))
1186
snprintf (query, sizeof (query), "SELECT USER_ID FROM %s."
1187
"DSPAM_VIRTUAL_USER_IDS WHERE USERNAME = '%s'", s->schema, name);
1189
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
1190
(dvoid **) & stmthp,
1191
(ub4) OCI_HTYPE_STMT,
1197
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp,
1207
if (_ora_drv_checkerr
1209
OCIDefineByPos (stmthp, &defn, s->errhp, 1, (dvoid *) & uid,
1210
(sword) sizeof (uid_t), SQLT_UIN, (dvoid *) 0,
1211
(ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
1214
status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0,
1215
(OCISnapshot *) NULL, (OCISnapshot *) NULL,
1218
if (status == OCI_NO_DATA)
1220
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1221
if (CTX->source == DSS_ERROR || CTX->operating_mode != DSM_PROCESS)
1223
return _ora_drv_setpwnam (CTX, name);
1225
else if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO)
1227
_ora_drv_checkerr (query, s->errhp, status);
1232
p.pw_name = strdup (name);
1234
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1239
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1246
_ora_drv_getpwuid (DSPAM_CTX * CTX, uid_t uid)
1248
#ifndef VIRTUAL_USERS
1249
static struct passwd p = { NULL, NULL, 0, 0, NULL, NULL, NULL };
1252
if (p.pw_name != NULL)
1254
/* cache the last uid queried */
1255
if (p.pw_uid == uid)
1263
memcpy (&p, q, sizeof (struct passwd));
1267
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
1268
static struct passwd p = { NULL, NULL, 0, 0, NULL, NULL, NULL };
1272
OCIDefine *defn = (OCIDefine *) 0;
1275
if (p.pw_name != NULL)
1277
/* cache the last uid queried */
1278
if (p.pw_uid == uid)
1284
memset (user, 0, sizeof (user));
1286
snprintf (query, sizeof (query),
1287
"SELECT USERNAME FROM %s.DSPAM_VIRTUAL_USER_IDS WHERE USER_ID = %d",
1290
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
1291
(dvoid **) & stmthp,
1292
(ub4) OCI_HTYPE_STMT,
1298
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp,
1308
if (_ora_drv_checkerr
1310
OCIDefineByPos (stmthp, &defn, s->errhp, 1, (dvoid *) & user,
1311
(sword) sizeof (user), SQLT_STR, (dvoid *) 0,
1312
(ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
1315
status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0,
1316
(OCISnapshot *) NULL, (OCISnapshot *) NULL,
1319
if (status == OCI_NO_DATA)
1323
p.pw_name = strdup (user);
1325
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1330
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1335
#ifdef VIRTUAL_USERS
1337
_ora_drv_setpwnam (DSPAM_CTX * CTX, const char *name)
1339
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
1343
snprintf (query, sizeof (query),
1344
"INSERT INTO %s.DSPAM_VIRTUAL_USER_IDS (USER_ID, USERNAME) VALUES "
1345
"(%s.VIRTUAL_USER.NEXTVAL, '%s')", s->schema, s->schema, name);
1347
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
1348
(dvoid **) & stmthp,
1349
(ub4) OCI_HTYPE_STMT,
1355
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp,
1365
if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp,
1376
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1377
return _ora_drv_getpwnam (CTX, name);
1380
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1387
_ora_drv_get_spamtotals (DSPAM_CTX * CTX)
1389
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
1393
OCIDefine *defn1 = NULL, *defn2 = NULL, *defn3 = NULL, *defn4 = NULL;
1394
long ts, ti, sm, fp, sc, ic, sf, icf;
1406
if (CTX->storage == NULL)
1408
LOGDEBUG ("_ora_drv_get_spamtotals: storage not initialized");
1412
p = _ora_drv_getpwnam (CTX, CTX->username);
1415
LOGDEBUG ("_ora_drv_get_spamtotals: unable to _ora_drv_getpwnam(%s)",
1420
snprintf (query, sizeof (query),
1421
"SELECT TOTAL_SPAM, TOTAL_INNOCENT, SPAM_MISSES, FALSE_POSITIVES, "
1422
" SPAM_CORPUSFED, INNOCENT_CORPUSFED, SPAM_CLASSIFIED, "
1423
" INNOCENT_CLASSIFIED "
1424
" FROM %s.DSPAM_STATS WHERE USER_ID = %d", s->schema, p->pw_uid);
1426
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
1427
(dvoid **) & stmthp,
1428
(ub4) OCI_HTYPE_STMT,
1434
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp,
1444
if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn1,
1447
(sword) sizeof (ts),
1456
if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn2,
1459
(sword) sizeof (ti),
1468
if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn3,
1471
(sword) sizeof (sm),
1480
if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4,
1483
(sword) sizeof (fp),
1492
if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4,
1495
(sword) sizeof (sc),
1504
if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4,
1507
(sword) sizeof (ic),
1516
if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4,
1519
(sword) sizeof (sf),
1528
if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4,
1531
(sword) sizeof (icf),
1541
status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0,
1542
(OCISnapshot *) NULL, (OCISnapshot *) NULL,
1545
if (status == OCI_NO_DATA)
1547
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1550
else if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO)
1552
_ora_drv_checkerr (query, s->errhp, status);
1556
CTX->totals.spam_learned = ts;
1557
CTX->totals.innocent_learned = ti;
1558
CTX->totals.spam_misclassified = sm;
1559
CTX->totals.innocent_misclassified = fp;
1560
CTX->totals.spam_corpusfed = sc;
1561
CTX->totals.innocent_corpusfed = ic;
1562
CTX->totals.spam_classified = sf;
1563
CTX->totals.innocent_classified = icf;
1565
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1570
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1575
_ora_drv_set_spamtotals (DSPAM_CTX * CTX)
1577
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
1583
if (CTX->storage == NULL)
1585
LOGDEBUG ("_ora_drv_set_spamtotals: storage not initialized");
1589
if (CTX->operating_mode == DSM_CLASSIFY)
1591
_ora_drv_get_spamtotals (CTX); /* undo changes to in memory totals */
1595
p = _ora_drv_getpwnam (CTX, CTX->username);
1598
LOGDEBUG ("_ora_drv_get_spamtotals: unable to _ora_drv_getpwnam(%s)",
1603
if (s->control_totals.innocent_learned == 0)
1605
snprintf (query, sizeof (query),
1606
"INSERT INTO %s.DSPAM_STATS(USER_ID, TOTAL_SPAM, TOTAL_INNOCENT,"
1607
" SPAM_MISSES, FALSE_POSITIVES, SPAM_CORPUSFED, "
1608
" INNOCENT_CORPUSFED, SPAM_CLASSIFIED, INNOCENT_CLASSIFIED) "
1609
" VALUES(%d, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld)",
1611
p->pw_uid, CTX->totals.spam_learned,
1612
CTX->totals.innocent_learned, CTX->totals.spam_misclassified,
1613
CTX->totals.innocent_misclassified,
1614
CTX->totals.spam_corpusfed, CTX->totals.innocent_corpusfed,
1615
CTX->totals.spam_classified, CTX->totals.innocent_classified);
1617
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
1627
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp,
1638
if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp,
1651
if (s->control_totals.innocent_learned != 0 || bad)
1653
snprintf (query, sizeof (query),
1654
"UPDATE DSPAM_STATS SET TOTAL_SPAM = TOTAL_SPAM %s %d, "
1655
"TOTAL_INNOCENT = TOTAL_INNOCENT %s %d, "
1656
"SPAM_MISSES = SPAM_MISSES %s %d, "
1657
"FALSE_POSITIVES = FALSE_POSITIVES %s %d, "
1658
"SPAM_CORPUSFED = SPAM_CORPUSFED %s %d, "
1659
"INNOCENT_CORPUSFED = INNOCENT_CORPUSFED %s %d, "
1660
"SPAM_CLASSIFIED = SPAM_CLASSIFIED %s %d, "
1661
"INNOCENT_CLASSIFIED = INNOCENT_CLASSIFIED %s %d "
1662
"WHERE USER_ID = %d",
1663
(CTX->totals.spam_learned >
1664
s->control_totals.spam_learned) ? "+" : "-",
1665
abs (CTX->totals.spam_learned -
1666
s->control_totals.spam_learned),
1667
(CTX->totals.innocent_learned >
1668
s->control_totals.innocent_learned) ? "+" : "-",
1669
abs (CTX->totals.innocent_learned -
1670
s->control_totals.innocent_learned),
1671
(CTX->totals.spam_misclassified >
1672
s->control_totals.spam_misclassified) ? "+" : "-",
1673
abs (CTX->totals.spam_misclassified -
1674
s->control_totals.spam_misclassified),
1675
(CTX->totals.innocent_misclassified >
1676
s->control_totals.innocent_misclassified) ? "+" : "-",
1677
abs (CTX->totals.innocent_misclassified -
1678
s->control_totals.innocent_misclassified),
1679
(CTX->totals.spam_corpusfed >
1680
s->control_totals.spam_corpusfed) ? "+" : "-",
1681
abs (CTX->totals.spam_corpusfed -
1682
s->control_totals.spam_corpusfed),
1683
(CTX->totals.innocent_corpusfed >
1684
s->control_totals.innocent_corpusfed) ? "+" : "-",
1685
abs (CTX->totals.innocent_corpusfed -
1686
s->control_totals.innocent_corpusfed),
1687
(CTX->totals.spam_classified >
1688
s->control_totals.spam_classified) ? "+" : "-",
1689
abs (CTX->totals.spam_classified -
1690
s->control_totals.spam_classified),
1691
(CTX->totals.innocent_classified >
1692
s->control_totals.innocent_classified) ? "+" : "-",
1693
abs (CTX->totals.innocent_classified -
1694
s->control_totals.innocent_classified), p->pw_uid);
1696
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
1706
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp,
1717
if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp,
1730
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1735
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1741
_ds_getall_spamrecords (DSPAM_CTX * CTX, ds_diction_t diction)
1743
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
1748
char scratch[1024], token_c[32] = { 0 };
1749
struct _ds_spam_stat stat;
1751
OCIDefine *defn1 = NULL, *defn2 = NULL, *defn3 = NULL;
1752
unsigned long long token = 0;
1753
long sh = 0, ih = 0;
1756
if (CTX->storage == NULL)
1758
LOGDEBUG ("_ds_getall_spamrecords: storage not initialized");
1762
p = _ora_drv_getpwnam (CTX, CTX->username);
1765
LOGDEBUG ("_ds_getall_spamrecords: unable to _ora_drv_getpwnam(%s)",
1771
stat.innocent_hits = 0;
1773
query = buffer_create (NULL);
1776
LOG (LOG_CRIT, ERR_MEM_ALLOC);
1780
snprintf (scratch, sizeof (scratch),
1781
"SELECT TOKEN, SPAM_HITS, INNOCENT_HITS FROM %s.DSPAM_TOKEN_DATA WHERE "
1782
" USER_ID = %d AND TOKEN IN(", s->schema, p->pw_uid);
1783
buffer_cat (query, scratch);
1784
ds_c = ds_diction_cursor(diction);
1785
ds_term = ds_diction_next(ds_c);
1788
snprintf (scratch, sizeof (scratch), "%llu", ds_term->key);
1789
buffer_cat (query, scratch);
1790
ds_term->s.innocent_hits = 0;
1791
ds_term->s.spam_hits = 0;
1792
ds_term->s.probability = 0;
1793
ds_term->s.status &= ~TST_DISK;
1794
ds_term = ds_diction_next(ds_c);
1796
buffer_cat (query, ",");
1798
ds_diction_close(ds_c);
1799
buffer_cat (query, ")");
1801
LOGDEBUG ("oracle query length: %ld\n", query->used);
1804
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
1805
(dvoid **) & stmthp,
1806
(ub4) OCI_HTYPE_STMT,
1812
if (_ora_drv_checkerr
1813
(query->data, s->errhp,
1814
OCIStmtPrepare (stmthp, s->errhp, (text *) query->data,
1815
(ub4) strlen (query->data), (ub4) OCI_NTV_SYNTAX,
1816
(ub4) OCI_DEFAULT)) != OCI_SUCCESS)
1819
if (_ora_drv_checkerr
1820
(query->data, s->errhp,
1821
OCIDefineByPos (stmthp, &defn1, s->errhp, 1, (dvoid *) & token_c,
1822
(sword) sizeof (token_c), SQLT_STR, (dvoid *) 0,
1823
(ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
1826
if (_ora_drv_checkerr
1827
(query->data, s->errhp,
1828
OCIDefineByPos (stmthp, &defn2, s->errhp, 2, (dvoid *) & sh,
1829
(sword) sizeof (sh), SQLT_INT, (dvoid *) 0, (ub2 *) 0,
1830
(ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
1833
if (_ora_drv_checkerr
1834
(query->data, s->errhp,
1835
OCIDefineByPos (stmthp, &defn3, s->errhp, 3, (dvoid *) & ih,
1836
(sword) sizeof (ih), SQLT_INT, (dvoid *) 0, (ub2 *) 0,
1837
(ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS)
1840
status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 0, (ub4) 0,
1841
(OCISnapshot *) NULL, (OCISnapshot *) NULL,
1844
stat.probability = 0;
1847
OCIStmtFetch (stmthp, s->errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT, (ub4)
1848
OCI_DEFAULT)) == OCI_SUCCESS
1849
|| status == OCI_SUCCESS_WITH_INFO)
1852
token = strtoull (token_c, NULL, 0);
1862
stat.spam_hits = sh;
1863
stat.innocent_hits = ih;
1864
stat.status |= TST_DISK;
1866
/* our control token will tell us how each token was altered */
1867
if (stat.spam_hits && stat.innocent_hits && !s->control_token)
1869
s->control_token = token;
1870
s->control_sh = stat.spam_hits;
1871
s->control_ih = stat.innocent_hits;
1873
ds_diction_setstat(diction, token, &stat);
1877
if (!s->control_token)
1879
s->control_token = token;
1880
s->control_sh = stat.spam_hits;
1881
s->control_ih = stat.innocent_hits;
1884
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1885
buffer_destroy (query);
1890
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
1896
_ds_setall_spamrecords (DSPAM_CTX * CTX, ds_diction_t diction)
1898
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
1899
struct _ds_spam_stat stat;
1908
if (CTX->storage == NULL)
1910
LOGDEBUG ("_ds_setall_spamrecords: storage not initialized");
1914
if (CTX->operating_mode == DSM_CLASSIFY &&
1915
(CTX->training_mode != DST_TOE ||
1916
(diction->whitelist_token == 0 && (!(CTX->flags & DSF_NOISE)))))
1919
p = _ora_drv_getpwnam (CTX, CTX->username);
1922
LOGDEBUG ("_ds_setall_spamrecords: unable to _ora_drv_getpwnam(%s)",
1927
query = buffer_create (NULL);
1930
LOG (LOG_CRIT, ERR_MEM_ALLOC);
1934
if (s->control_token == 0)
1936
ds_c = ds_diction_cursor(diction);
1937
ds_term = ds_diction_next(ds_c);
1941
stat.innocent_hits = 0;
1945
stat.spam_hits = ds_term->s.spam_hits;
1946
stat.innocent_hits = ds_term->s.innocent_hits;
1948
ds_diction_close(ds_c);
1952
ds_diction_setstat(diction, s->control_token, &stat);
1954
snprintf (scratch, sizeof (scratch),
1955
"UPDATE %s.DSPAM_TOKEN_DATA SET LAST_HIT = SYSDATE, "
1956
" SPAM_HITS = GREATEST(0, SPAM_HITS %s %d), "
1957
" INNOCENT_HITS = GREATEST(0, INNOCENT_HITS %s %d) "
1958
" WHERE USER_ID = %d AND TOKEN IN(",
1960
(stat.spam_hits > s->control_sh) ? "+" : "-",
1961
abs (stat.spam_hits - s->control_sh),
1962
(stat.innocent_hits > s->control_ih) ? "+" : "-",
1963
abs (stat.innocent_hits - s->control_ih), p->pw_uid);
1965
buffer_cat (query, scratch);
1967
ds_c = ds_diction_cursor(diction);
1968
ds_term = ds_diction_next(ds_c);
1972
if (CTX->training_mode == DST_TOE &&
1973
CTX->classification == DSR_NONE &&
1974
CTX->operating_mode == DSM_CLASSIFY &&
1975
diction->whitelist_token != ds_term->key &&
1976
(!ds_term->name || strncmp(ds_term->name, "bnr.", 4)))
1978
ds_term = ds_diction_next(ds_c);
1982
if (!(ds_term->s.status & TST_DIRTY)) {
1983
ds_term = ds_diction_next(ds_c);
1987
ds_diction_getstat(diction, ds_term->key, &stat);
1989
if (!(stat.status & TST_DISK))
1993
snprintf (insert, sizeof (insert),
1994
"INSERT INTO %s.DSPAM_TOKEN_DATA(USER_ID, TOKEN, SPAM_HITS, "
1995
"INNOCENT_HITS, LAST_HIT) VALUES(%d, %llu, %ld, %ld, SYSDATE)",
1996
s->schema, p->pw_uid, ds_term->key,
1997
stat.spam_hits, stat.innocent_hits);
1999
if (_ora_drv_checkerr
2001
OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp,
2002
(ub4) OCI_HTYPE_STMT, (size_t) 0,
2003
(dvoid **) 0)) != OCI_SUCCESS)
2006
if (_ora_drv_checkerr
2008
OCIStmtPrepare (stmthp, s->errhp, (text *) insert,
2009
(ub4) strlen (insert), (ub4) OCI_NTV_SYNTAX,
2010
(ub4) OCI_DEFAULT)) != OCI_SUCCESS)
2013
if (_ora_drv_checkerr
2015
OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0,
2016
(OCISnapshot *) NULL, (OCISnapshot *) NULL,
2017
(ub4) OCI_DEFAULT)) != OCI_SUCCESS)
2018
stat.status |= TST_DISK;
2021
if ((stat.status & TST_DISK))
2023
snprintf (scratch, sizeof (scratch), "%llu", ds_term->key);
2024
buffer_cat (query, scratch);
2027
ds_term->s.status |= TST_DISK;
2029
ds_term = ds_diction_next(ds_c);
2030
if (ds_term && wrote_this)
2031
buffer_cat (query, ",");
2033
ds_diction_close(ds_c);
2035
if (query->used && query->data[strlen (query->data) - 1] == ',')
2038
query->data[strlen (query->data) - 1] = 0;
2042
buffer_cat (query, ")");
2046
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
2056
if (_ora_drv_checkerr (query->data, s->errhp, OCIStmtPrepare (stmthp,
2071
if (_ora_drv_checkerr (query->data, s->errhp, OCIStmtExecute (s->svchp,
2086
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
2087
buffer_destroy (query);
2092
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
2097
_ds_get_spamrecord (DSPAM_CTX * CTX, unsigned long long token,
2098
struct _ds_spam_stat *stat)
2100
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
2104
OCIDefine *defn1 = NULL, *defn2 = NULL;
2107
if (CTX->storage == NULL)
2109
LOGDEBUG ("_ds_getall_spamrecords: storage not initialized");
2113
p = _ora_drv_getpwnam (CTX, CTX->username);
2116
LOGDEBUG ("_ds_getall_spamrecords: unable to _ora_drv_getpwnam(%s)",
2121
snprintf (query, sizeof (query),
2122
"SELECT SPAM_HITS, INNOCENT_HITS FROM %s.DSPAM_TOKEN_DATA WHERE "
2123
" USER_ID = %d AND TOKEN = %llu", s->schema, p->pw_uid, token);
2125
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
2126
(dvoid **) & stmthp,
2127
(ub4) OCI_HTYPE_STMT,
2133
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp,
2143
if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn1,
2157
if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn2,
2171
status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0,
2172
(OCISnapshot *) NULL, (OCISnapshot *) NULL,
2175
stat->probability = 0;
2177
if (status == OCI_NO_DATA)
2179
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
2183
if (_ora_drv_checkerr (query, s->errhp, status) != OCI_SUCCESS)
2186
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
2191
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
2197
_ds_set_spamrecord (DSPAM_CTX * CTX, unsigned long long token,
2198
struct _ds_spam_stat *stat)
2200
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
2205
if (CTX->operating_mode == DSM_CLASSIFY)
2208
if (CTX->storage == NULL)
2210
LOGDEBUG ("_ds_getall_spamrecords: storage not initialized");
2214
p = _ora_drv_getpwnam (CTX, CTX->username);
2217
LOGDEBUG ("_ds_getall_spamrecords: unable to _ora_drv_getpwnam(%s)",
2222
/* Try to insert first; will fail if exists because of unique index */
2224
snprintf (query, sizeof (query),
2225
"INSERT INTO %s.DSPAM_TOKEN_DATA (USER_ID, TOKEN, INNOCENT_HITS,"
2226
" SPAM_HITS, LAST_HIT) VALUES(%d, %llu, %ld, %ld, SYSDATE)",
2227
s->schema, p->pw_uid, token,
2228
stat->innocent_hits > 0 ? stat->innocent_hits : 0,
2229
stat->spam_hits > 0 ? stat->spam_hits : 0);
2231
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
2232
(dvoid **) & stmthp,
2233
(ub4) OCI_HTYPE_STMT,
2239
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp,
2250
/* If insert fails, try an update */
2252
if (OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0,
2253
(OCISnapshot *) NULL, (OCISnapshot *) NULL,
2254
(ub4) OCI_DEFAULT) != OCI_SUCCESS)
2257
snprintf (query, sizeof (query),
2258
"UPDATE %s.DSPAM_TOKEN_DATA SET INNOCENT_HITS = %ld, SPAM_HITS = %ld"
2259
" WHERE USER_ID = %d AND TOKEN = %llu", s->schema,
2260
stat->innocent_hits, stat->spam_hits, p->pw_uid, token);
2261
if (CTX->training_mode == DST_TUM) {
2262
if (CTX->classification == DSR_NONE)
2263
strlcat(query, " AND INNOCENT_HITS + SPAM_HITS < 50", sizeof(query));
2266
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
2276
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp,
2287
if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp,
2300
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
2305
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
2310
int _ds_delall_spamrecords (DSPAM_CTX * CTX, ds_diction_t diction)
2312
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
2317
char queryhead[1024];
2321
if (diction == NULL || diction->items == 0)
2324
if (CTX->storage == NULL)
2326
LOGDEBUG ("_ds_delall_spamrecords: storage not initialized");
2330
p = _ora_drv_getpwnam (CTX, CTX->username);
2333
LOGDEBUG ("_ds_delall_spamrecords: unable to _ora_drv_getpwnam(%s)",
2338
query = buffer_create (NULL);
2341
LOG (LOG_CRIT, ERR_MEM_ALLOC);
2345
snprintf (queryhead, sizeof (queryhead),
2346
"DELETE FROM %s.DSPAM_TOKEN_DATA "
2347
" WHERE USER_ID = %d AND TOKEN IN(",
2348
s->schema, p->pw_uid);
2350
buffer_cat (query, queryhead);
2352
ds_c = ds_diction_cursor(diction);
2353
ds_term = ds_diction_next(ds_c);
2356
snprintf (scratch, sizeof (scratch), "%llu", ds_term->key);
2357
buffer_cat (query, scratch);
2358
ds_term = ds_diction_next(ds_c);
2360
buffer_cat (query, ",");
2362
ds_diction_close(ds_c);
2363
buffer_cat (query, ")");
2365
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
2375
if (_ora_drv_checkerr (query->data, s->errhp, OCIStmtPrepare (stmthp,
2390
if (_ora_drv_checkerr (query->data, s->errhp, OCIStmtExecute (s->svchp,
2404
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
2405
buffer_destroy (query);
2410
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
2415
int _ds_del_spamrecord (DSPAM_CTX * CTX, unsigned long long token)
2417
struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage;
2422
if (CTX->storage == NULL)
2424
LOGDEBUG ("_ds_getall_spamrecords: storage not initialized");
2428
p = _ora_drv_getpwnam (CTX, CTX->username);
2431
LOGDEBUG ("_ds_getall_spamrecords: unable to _ora_drv_getpwnam(%s)",
2436
snprintf (query, sizeof (query),
2437
"DELETE FROM %s.DSPAM_TOKEN_DATA "
2438
" WHERE USER_ID = %d AND TOKEN = %llu",
2439
s->schema, p->pw_uid, token);
2441
if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp,
2451
if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp,
2462
if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp,
2474
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
2479
OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
2484
void *_ds_connect (DSPAM_CTX *CTX)
2489
/* Preference Stubs for Flat-File */
2491
agent_pref_t _ds_pref_load(config_t config, const char *user,
2492
const char *home, void *dbh)
2494
return _ds_ff_pref_load(config, user, home, dbh);
2497
int _ds_pref_set(config_t config, const char *user, const char *home,
2498
const char *attrib, const char *value, void *dbh)
2500
return _ds_ff_pref_set(config, user, home, attrib, value, dbh);
2503
int _ds_pref_del(config_t config, const char *user, const char *home,
2504
const char *attrib, void *dbh)
2506
return _ds_ff_pref_del(config, user, home, attrib, dbh);