/* $Id: ora_drv.c,v 1.15 2006/05/13 01:12:59 jonz Exp $ */ /* DSPAM COPYRIGHT (C) 2002-2006 JONATHAN A. ZDZIARSKI This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif #include "storage_driver.h" #include "ora_drv.h" #include "libdspam.h" #include "config.h" #include "error.h" #include "language.h" #include "util.h" #include "config_shared.h" int dspam_init_driver (DRIVER_CTX *DTX) { return 0; } int dspam_shutdown_driver (DRIVER_CTX *DTX) { return 0; } int _ds_init_storage (DSPAM_CTX * CTX, void *dbh) { struct _ora_drv_storage *s; FILE *file; char dblink[1024]; char buffer[1024]; char username[64] = ""; char password[32] = ""; char schema[32] = ""; char filename[MAX_FILENAME_LENGTH]; int i = 0; if (CTX == NULL) return EINVAL; if (dbh != NULL) { LOG(LOG_ERR, ERR_DRV_NO_ATTACH); return EINVAL; } if (CTX->flags & DSF_MERGED) { LOG(LOG_ERR, ERR_DRV_NO_MERGED); return EINVAL; } /* don't init if we're already initted */ if (CTX->storage != NULL) { LOGDEBUG ("_ds_init_storage: storage already initialized"); return EINVAL; } s = malloc (sizeof (struct _ora_drv_storage)); if (s == NULL) { LOG (LOG_CRIT, ERR_MEM_ALLOC); return EUNKNOWN; } s->control_token = 0; s->control_ih = 0; s->control_sh = 0; s->authp = NULL; s->schema = NULL; s->iter_user = NULL; s->iter_token = NULL; s->iter_sig = NULL; if (_ds_read_attribute(CTX->config->attributes, "OraServer")) { char *p; strlcpy(dblink, _ds_read_attribute(CTX->config->attributes, "OraServer"), sizeof(dblink)); if ((p = _ds_read_attribute(CTX->config->attributes, "OraUser"))) strlcpy(username, p, sizeof(username)); if ((p = _ds_read_attribute(CTX->config->attributes, "OraPass"))) strlcpy(password, p, sizeof(password)); if ((p = _ds_read_attribute(CTX->config->attributes, "OraSchema"))) strlcpy(schema, p, sizeof(schema)); } else { if (!CTX->home) { LOG(LOG_ERR, ERR_AGENT_DSPAM_HOME); return EINVAL; } snprintf (filename, MAX_FILENAME_LENGTH, "%s/oracle.data", CTX->home); file = fopen (filename, "r"); if (file == NULL) { LOG (LOG_WARNING, "unable to open %s for reading: %s", filename, strerror (errno)); return EFAILURE; } while (fgets (buffer, sizeof (buffer), file) != NULL) { chomp (buffer); if (!i) strlcpy (dblink, buffer, sizeof (dblink)); else if (i == 1) strlcpy (username, buffer, sizeof (username)); else if (i == 2) strlcpy (password, buffer, sizeof (password)); else if (i == 3) strlcpy (schema, buffer, sizeof (schema)); i++; } fclose (file); } if (schema[0] == 0) { LOG (LOG_WARNING, "file %s: incomplete Oracle connect data", filename); return EINVAL; } s->schema = strdup (schema); /* establish an Oracle session */ OCIInitialize ((ub4) OCI_DEFAULT, (dvoid *) 0, (dvoid * (*)(dvoid *, size_t)) 0, (dvoid * (*)(dvoid *, dvoid *, size_t)) 0, (void (*)(dvoid *, dvoid *)) 0); OCIEnvInit ((OCIEnv **) & s->envhp, OCI_DEFAULT, (size_t) 0, (dvoid **) 0); OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & s->errhp, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0); OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & s->srvhp, OCI_HTYPE_SERVER, (size_t) 0, (dvoid **) 0); OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & s->svchp, OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0); if (_ora_drv_checkerr (dblink, s->errhp, OCIServerAttach (s->srvhp, s->errhp, (text *) dblink, strlen (dblink), 0)) != OCI_SUCCESS) return EFAILURE; OCIAttrSet ((dvoid *) s->svchp, OCI_HTYPE_SVCCTX, (dvoid *) s->srvhp, (ub4) 0, OCI_ATTR_SERVER, (OCIError *) s->errhp); OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & s->authp, (ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0); OCIAttrSet ((dvoid *) s->authp, (ub4) OCI_HTYPE_SESSION, (dvoid *) username, (ub4) strlen ((char *) username), (ub4) OCI_ATTR_USERNAME, s->errhp); OCIAttrSet ((dvoid *) s->authp, (ub4) OCI_HTYPE_SESSION, (dvoid *) password, (ub4) strlen ((char *) password), (ub4) OCI_ATTR_PASSWORD, s->errhp); if (_ora_drv_checkerr (NULL, s->errhp, OCISessionBegin (s->svchp, s->errhp, s->authp, OCI_CRED_RDBMS, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) return EFAILURE; (void) OCIAttrSet ((dvoid *) s->svchp, (ub4) OCI_HTYPE_SVCCTX, (dvoid *) s->authp, (ub4) 0, (ub4) OCI_ATTR_SESSION, s->errhp); CTX->storage = s; /* get spam totals on successful init */ if (CTX->username != NULL) { if (_ora_drv_get_spamtotals (CTX)) { LOGDEBUG ("unable to load totals. using zero values."); memset (&CTX->totals, 0, sizeof (struct _ds_spam_totals)); memset (&s->control_totals, 0, sizeof (struct _ds_spam_totals)); } else { memcpy (&s->control_totals, &CTX->totals, sizeof (struct _ds_spam_totals)); } } else { memset (&CTX->totals, 0, sizeof (struct _ds_spam_totals)); memset (&s->control_totals, 0, sizeof (struct _ds_spam_totals)); } return 0; } int _ds_shutdown_storage (DSPAM_CTX * CTX) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; if (CTX->storage == NULL) { LOGDEBUG ("_ds_shutdown_storage: storage not initialized"); return EINVAL; } /* Store spam totals on shutdown */ if (CTX->username != NULL && CTX->operating_mode != DSM_CLASSIFY) { _ora_drv_set_spamtotals (CTX); } OCISessionEnd (s->svchp, s->errhp, s->authp, (ub4) OCI_DEFAULT); OCIServerDetach (s->srvhp, s->errhp, (ub4) OCI_DEFAULT); OCIHandleFree ((dvoid *) s->srvhp, (ub4) OCI_HTYPE_SERVER); OCIHandleFree ((dvoid *) s->svchp, (ub4) OCI_HTYPE_SVCCTX); OCIHandleFree ((dvoid *) s->errhp, (ub4) OCI_HTYPE_ERROR); OCIHandleFree ((dvoid *) s->envhp, OCI_HTYPE_ENV); free (s->schema); free (CTX->storage); CTX->storage = NULL; return 0; } void _ora_drv_query_error (const char *error, const char *query) { FILE *file; time_t tm = time (NULL); char ct[128]; char fn[MAX_FILENAME_LENGTH]; snprintf (fn, sizeof (fn), "%s/sql.errors", LOGDIR); snprintf (ct, sizeof (ct), "%s", ctime (&tm)); chomp (ct); file = fopen (fn, "a"); if (file == NULL) { LOG(LOG_ERR, ERR_IO_FILE_WRITE, fn, strerror (errno)); return; } if (query != NULL) fprintf (file, "[%s] %d: %s: %s\n", ct, getpid (), error, query); else fprintf (file, "[%s] %d: %s\n", ct, getpid (), error); fclose (file); #ifdef DEBUG if (query != NULL) fprintf (stderr, "[%s] %d: %s: %s\n", ct, getpid (), error, query); else fprintf (stderr, "[%s] %d: %s\n", ct, getpid (), error); #endif return; } sword _ora_drv_checkerr (const char *query, OCIError * errhp, sword status) { text errbuf[512]; sb4 errcode = 0; switch (status) { case OCI_SUCCESS: break; case OCI_SUCCESS_WITH_INFO: _ora_drv_query_error ("Oracle error: OCI_SUCCESS_WITH_INFO", query); break; case OCI_NEED_DATA: _ora_drv_query_error ("Oracle error: OCI_NEED_DATA", query); break; case OCI_NO_DATA: _ora_drv_query_error ("Oracle error: OCI_NO_DATA", query); break; case OCI_ERROR: (void) OCIErrorGet ((dvoid *) errhp, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof (errbuf), OCI_HTYPE_ERROR); _ora_drv_query_error ((const char *) errbuf, query); break; case OCI_INVALID_HANDLE: _ora_drv_query_error ("Oracle error: OCI_INVALID_HANDLE", query); break; case OCI_STILL_EXECUTING: _ora_drv_query_error ("Oracle error: OCI_STILL_EXECUTE", query); break; case OCI_CONTINUE: _ora_drv_query_error ("Oracle error: OCI_CONTINUE", query); break; default: break; } return status; } int _ds_create_signature_id (DSPAM_CTX * CTX, char *buf, size_t len) { char session[64]; char digit[6]; int pid, j; pid = getpid (); snprintf (session, sizeof (session), "%8lx%d", (long) time (NULL), pid); for (j = 0; j < 2; j++) { snprintf (digit, 6, "%d", rand ()); strlcat (session, digit, 64); } strlcpy (buf, session, len); return 0; } int _ds_get_signature (DSPAM_CTX * CTX, struct _ds_spam_signature *SIG, const char *signature) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; char query[1024]; struct passwd *p; OCIStmt *stmthp; OCIDefine *defn = (OCIDefine *) 0; sword status; if (CTX->storage == NULL) { LOGDEBUG ("_ds_get_signature: storage not initialized"); return EINVAL; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_get_signature: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } snprintf (query, sizeof (query), "SELECT LENGTH FROM %s.DSPAM_SIGNATURE_DATA" " WHERE SIGNATURE = '%s' AND USER_ID = %d", s->schema, signature, p->pw_uid); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn, s->errhp, 1, (dvoid *) & SIG->length, (sword) sizeof (long), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT); if (status == OCI_NO_DATA) { OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EFAILURE; } if (status != OCI_SUCCESS) goto bail; SIG->data = malloc (SIG->length); if (SIG->data == NULL) { LOG (LOG_CRIT, ERR_MEM_ALLOC); goto bail; } snprintf (query, sizeof (query), "SELECT DATA FROM %s.DSPAM_SIGNATURE_DATA" " WHERE SIGNATURE = '%s' AND USER_ID = %d", s->schema, signature, p->pw_uid); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn, s->errhp, 1, (dvoid *) SIG->data, (sword) SIG->length, SQLT_LNG, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; status = _ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)); if (status == OCI_NO_DATA) { OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EFAILURE; } if (status != OCI_SUCCESS) goto bail; OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EUNKNOWN; } int _ds_set_signature (DSPAM_CTX * CTX, struct _ds_spam_signature *SIG, const char *signature) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; char query[1024]; struct passwd *p; OCIStmt *stmthp; OCIBind *phBindSignature = NULL; if (CTX->storage == NULL) { LOGDEBUG ("_ds_set_signature: storage not initialized"); return EINVAL; } if (SIG == NULL || SIG->data == NULL || !SIG->length) return 0; p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_set_signature: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } snprintf (query, sizeof (query), "INSERT INTO %s.DSPAM_SIGNATURE_DATA(USER_ID, SIGNATURE, LENGTH, CREATED_ON" ", DATA) VALUES(%d, '%s', %ld, SYSDATE, :signature)", s->schema, p->pw_uid, signature, SIG->length); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIBindByName (stmthp, &phBindSignature, s->errhp, ":signature", -1, (dvoid *) SIG->data, SIG->length, SQLT_LNG, NULL, NULL, NULL, 0, NULL, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EUNKNOWN; } int _ds_delete_signature (DSPAM_CTX * CTX, const char *signature) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; char query[1024]; struct passwd *p; OCIStmt *stmthp; if (CTX->storage == NULL) { LOGDEBUG ("_ds_delete_signature: storage not initialized"); return EINVAL; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_set_signature: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } snprintf (query, sizeof (query), "DELETE FROM %s.DSPAM_SIGNATURE_DATA" " WHERE SIGNATURE = '%s' AND USER_ID = %d", s->schema, signature, p->pw_uid); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EUNKNOWN; } int _ds_verify_signature (DSPAM_CTX * CTX, const char *signature) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; char query[1024], sig[32]; struct passwd *p; OCIStmt *stmthp; OCIDefine *defn = (OCIDefine *) 0; sword status; if (CTX->storage == NULL) { LOGDEBUG ("_ds_verify_signature: storage not initialized"); return EINVAL; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_verify_signature: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } snprintf (query, sizeof (query), "SELECT SIGNATURE FROM %s.DSPAM_SIGNATURE_DATA" " WHERE SIGNATURE = '%s' AND USER_ID = %d", s->schema, signature, p->pw_uid); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn, s->errhp, 1, (dvoid *) & sig, (sword) sizeof (sig), SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT); if (status == OCI_NO_DATA) { OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EFAILURE; } OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EUNKNOWN; } char * _ds_get_nextuser (DSPAM_CTX * CTX) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; struct passwd *p; char query[1024]; uid_t uid; static OCIDefine *defn = (OCIDefine *) 0; static char user[MAX_FILENAME_LENGTH] = { 0 }; sword status; if (CTX->storage == NULL) { LOGDEBUG ("_ds_getall_spamrecords: storage not initialized"); return NULL; } /* Execute initial query */ if (s->iter_user == NULL) { snprintf (query, sizeof (query), "SELECT DISTINCT USER_ID FROM %s.DSPAM_STATS", s->schema); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & s-> iter_user, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return NULL; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (s->iter_user, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (s->iter_user, &defn, s->errhp, 1, (dvoid *) & uid, (sword) sizeof (uid_t), SQLT_UIN, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, s->iter_user, s->errhp, (ub4) 0, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; } status = OCIStmtFetch (s->iter_user, s->errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT, (ub4) OCI_DEFAULT); if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO) goto bail; p = _ora_drv_getpwuid (CTX, uid); if (p != NULL) { strlcpy (user, p->pw_name, sizeof (user)); return user; } bail: OCIHandleFree ((dvoid *) s->iter_user, (ub4) OCI_HTYPE_STMT); s->iter_user = NULL; return NULL; } struct _ds_storage_record * _ds_get_nexttoken (DSPAM_CTX * CTX) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; struct _ds_storage_record *st; struct passwd *p; char query[1024], token_c[32]; static OCIDefine *defn1 = NULL, *defn2 = NULL, *defn3 = NULL, *defn4 = NULL; long sh, ih, lh; sword status; if (CTX->storage == NULL) { LOGDEBUG ("_ds_getall_spamrecords: storage not initialized"); return NULL; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_get_nexttoken: unable to _ora_drv_getpwnam(%s)", CTX->username); return NULL; } if (s->iter_token == NULL) { snprintf (query, sizeof (query), "SELECT TOKEN, SPAM_HITS, INNOCENT_HITS, " "TO_NUMBER(LAST_HIT-TO_DATE('01011970','DDMMYYYY'))*60*60*24" " FROM %s.DSPAM_TOKEN_DATA WHERE USER_ID = %d", s->schema, p->pw_uid); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & s-> iter_token, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return NULL; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (s->iter_token, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (s->iter_token, &defn1, s->errhp, 1, (dvoid *) & token_c, (sword) sizeof (token_c), SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (s->iter_token, &defn2, s->errhp, 2, (dvoid *) & sh, (sword) sizeof (sh), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (s->iter_token, &defn3, s->errhp, 3, (dvoid *) & ih, (sword) sizeof (ih), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (s->iter_token, &defn4, s->errhp, 4, (dvoid *) & lh, (sword) sizeof (lh), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, s->iter_token, s->errhp, (ub4) 0, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; } status = OCIStmtFetch (s->iter_token, s->errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT, (ub4) OCI_DEFAULT); if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO) goto bail; st = malloc (sizeof (struct _ds_storage_record)); if (st == NULL) { LOG (LOG_CRIT, ERR_MEM_ALLOC); return NULL; } memset (st, 0, sizeof (struct _ds_storage_record)); st->token = strtoull (token_c, NULL, 0); st->spam_hits = sh; st->innocent_hits = ih; st->last_hit = (time_t) lh; return st; bail: OCIHandleFree ((dvoid *) s->iter_user, (ub4) OCI_HTYPE_STMT); s->iter_token = NULL; return NULL; } struct _ds_storage_signature * _ds_get_nextsignature (DSPAM_CTX * CTX) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; struct _ds_storage_signature *st; struct passwd *p; char query[1024], signature[128]; static OCIDefine *defn1 = NULL, *defn2 = NULL, *defn3 = NULL, *defn4 = NULL; long sl, lh; sword status; OCIStmt *stmthp; if (CTX->storage == NULL) { LOGDEBUG ("_ds_getall_spamrecords: storage not initialized"); return NULL; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_get_nexttoken: unable to _ora_drv_getpwnam(%s)", CTX->username); return NULL; } if (s->iter_sig == NULL) { snprintf (query, sizeof (query), "SELECT SIGNATURE, LENGTH, " " TO_NUMBER(CREATED_ON-TO_DATE('01011970','MMDDYYYY'))*60*60*24" " FROM %s.DSPAM_SIGNATURE_DATA WHERE USER_ID = %d", s->schema, p->pw_uid); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & s-> iter_sig, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return NULL; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (s->iter_sig, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (s->iter_sig, &defn1, s->errhp, 1, (dvoid *) & signature, (sword) sizeof (signature), SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (s->iter_sig, &defn2, s->errhp, 2, (dvoid *) & sl, (sword) sizeof (sl), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (s->iter_sig, &defn3, s->errhp, 3, (dvoid *) & lh, (sword) sizeof (lh), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, s->iter_sig, s->errhp, (ub4) 0, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; } status = OCIStmtFetch (s->iter_sig, s->errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT, (ub4) OCI_DEFAULT); if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO) goto bail; st = malloc (sizeof (struct _ds_storage_signature)); if (st == NULL) { LOG (LOG_CRIT, ERR_MEM_ALLOC); goto bail; } memset (st, 0, sizeof (struct _ds_storage_signature)); st->length = sl; st->created_on = (time_t) lh; strlcpy (st->signature, signature, sizeof (st->signature)); st->data = malloc (st->length); if (st->data == NULL) { LOG (LOG_CRIT, ERR_MEM_ALLOC); goto bail; } snprintf (query, sizeof (query), "SELECT DATA FROM %s.DSPAM_SIGNATURE_DATA WHERE USER_ID = %d" " AND SIGNATURE = '%s'", s->schema, p->pw_uid, st->signature); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) { OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); free (st); goto bail; } if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4, s->errhp, 1, (dvoid *) & st-> data, (sword) st->length, SQLT_LNG, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) { OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); free (st); goto bail; } if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 0, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) { OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); free (st); goto bail; } else { OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return st; } bail: OCIHandleFree ((dvoid *) s->iter_sig, (ub4) OCI_HTYPE_STMT); s->iter_sig = NULL; return NULL; } struct passwd * _ora_drv_getpwnam (DSPAM_CTX * CTX, const char *name) { #ifndef VIRTUAL_USERS static struct passwd p = { NULL, NULL, 0, 0, NULL, NULL, NULL }; struct passwd *q; if (p.pw_name != NULL) { /* cache the last name queried */ if (name != NULL && !strcmp (p.pw_name, name)) return &p; free (p.pw_name); p.pw_name = NULL; p.pw_uid = 0; } q = getpwnam (name); if (q == NULL) return NULL; p.pw_uid = q->pw_uid; p.pw_name = strdup (q->pw_name); return &p; #else struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; static struct passwd p = { NULL, NULL, 0, 0, NULL, NULL, NULL }; char query[256]; OCIStmt *stmthp; OCIDefine *defn = (OCIDefine *) 0; sword status; uid_t uid = 0; if (p.pw_name != NULL) { /* cache the last name queried */ if (name != NULL && !strcmp (p.pw_name, name)) return &p; free (p.pw_name); p.pw_name = NULL; } snprintf (query, sizeof (query), "SELECT USER_ID FROM %s." "DSPAM_VIRTUAL_USER_IDS WHERE USERNAME = '%s'", s->schema, name); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return NULL; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn, s->errhp, 1, (dvoid *) & uid, (sword) sizeof (uid_t), SQLT_UIN, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT); if (status == OCI_NO_DATA) { OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); if (CTX->source == DSS_ERROR || CTX->operating_mode != DSM_PROCESS) return NULL; return _ora_drv_setpwnam (CTX, name); } else if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO) { _ora_drv_checkerr (query, s->errhp, status); goto bail; } p.pw_uid = uid; p.pw_name = strdup (name); OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return &p; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return NULL; #endif } struct passwd * _ora_drv_getpwuid (DSPAM_CTX * CTX, uid_t uid) { #ifndef VIRTUAL_USERS static struct passwd p = { NULL, NULL, 0, 0, NULL, NULL, NULL }; struct passwd *q; if (p.pw_name != NULL) { /* cache the last uid queried */ if (p.pw_uid == uid) { return &p; } p.pw_name = NULL; } q = getpwuid (uid); memcpy (&p, q, sizeof (struct passwd)); return &p; #else struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; static struct passwd p = { NULL, NULL, 0, 0, NULL, NULL, NULL }; char query[256]; char user[128]; OCIStmt *stmthp; OCIDefine *defn = (OCIDefine *) 0; sword status; if (p.pw_name != NULL) { /* cache the last uid queried */ if (p.pw_uid == uid) return &p; free (p.pw_name); p.pw_name = NULL; } memset (user, 0, sizeof (user)); snprintf (query, sizeof (query), "SELECT USERNAME FROM %s.DSPAM_VIRTUAL_USER_IDS WHERE USER_ID = %d", s->schema, uid); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return NULL; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn, s->errhp, 1, (dvoid *) & user, (sword) sizeof (user), SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT); if (status == OCI_NO_DATA) goto bail; p.pw_uid = uid; p.pw_name = strdup (user); OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return &p; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return NULL; #endif } #ifdef VIRTUAL_USERS struct passwd * _ora_drv_setpwnam (DSPAM_CTX * CTX, const char *name) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; char query[256]; OCIStmt *stmthp; snprintf (query, sizeof (query), "INSERT INTO %s.DSPAM_VIRTUAL_USER_IDS (USER_ID, USERNAME) VALUES " "(%s.VIRTUAL_USER.NEXTVAL, '%s')", s->schema, s->schema, name); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return NULL; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return _ora_drv_getpwnam (CTX, name); bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return NULL; } #endif int _ora_drv_get_spamtotals (DSPAM_CTX * CTX) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; char query[1024]; struct passwd *p; OCIStmt *stmthp; OCIDefine *defn1 = NULL, *defn2 = NULL, *defn3 = NULL, *defn4 = NULL; long ts, ti, sm, fp, sc, ic, sf, icf; int status; ts = 0; ti = 0; sm = 0; fp = 0; sc = 0; ic = 0; sf = 0; icf = 0; if (CTX->storage == NULL) { LOGDEBUG ("_ora_drv_get_spamtotals: storage not initialized"); return EINVAL; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ora_drv_get_spamtotals: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } snprintf (query, sizeof (query), "SELECT TOTAL_SPAM, TOTAL_INNOCENT, SPAM_MISSES, FALSE_POSITIVES, " " SPAM_CORPUSFED, INNOCENT_CORPUSFED, SPAM_CLASSIFIED, " " INNOCENT_CLASSIFIED " " FROM %s.DSPAM_STATS WHERE USER_ID = %d", s->schema, p->pw_uid); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn1, s->errhp, 1, (dvoid *) & ts, (sword) sizeof (ts), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn2, s->errhp, 2, (dvoid *) & ti, (sword) sizeof (ti), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn3, s->errhp, 3, (dvoid *) & sm, (sword) sizeof (sm), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4, s->errhp, 4, (dvoid *) & fp, (sword) sizeof (fp), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4, s->errhp, 5, (dvoid *) & sc, (sword) sizeof (sc), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4, s->errhp, 6, (dvoid *) & ic, (sword) sizeof (ic), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4, s->errhp, 7, (dvoid *) & sf, (sword) sizeof (sf), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn4, s->errhp, 7, (dvoid *) & icf, (sword) sizeof (icf), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT); if (status == OCI_NO_DATA) { OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EFAILURE; } else if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO) { _ora_drv_checkerr (query, s->errhp, status); goto bail; } CTX->totals.spam_learned = ts; CTX->totals.innocent_learned = ti; CTX->totals.spam_misclassified = sm; CTX->totals.innocent_misclassified = fp; CTX->totals.spam_corpusfed = sc; CTX->totals.innocent_corpusfed = ic; CTX->totals.spam_classified = sf; CTX->totals.innocent_classified = icf; OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EUNKNOWN; } int _ora_drv_set_spamtotals (DSPAM_CTX * CTX) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; struct passwd *p; char query[1024]; OCIStmt *stmthp; int bad = 0; if (CTX->storage == NULL) { LOGDEBUG ("_ora_drv_set_spamtotals: storage not initialized"); return EINVAL; } if (CTX->operating_mode == DSM_CLASSIFY) { _ora_drv_get_spamtotals (CTX); /* undo changes to in memory totals */ return 0; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ora_drv_get_spamtotals: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } if (s->control_totals.innocent_learned == 0) { snprintf (query, sizeof (query), "INSERT INTO %s.DSPAM_STATS(USER_ID, TOTAL_SPAM, TOTAL_INNOCENT," " SPAM_MISSES, FALSE_POSITIVES, SPAM_CORPUSFED, " " INNOCENT_CORPUSFED, SPAM_CLASSIFIED, INNOCENT_CLASSIFIED) " " VALUES(%d, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld)", s->schema, p->pw_uid, CTX->totals.spam_learned, CTX->totals.innocent_learned, CTX->totals.spam_misclassified, CTX->totals.innocent_misclassified, CTX->totals.spam_corpusfed, CTX->totals.innocent_corpusfed, CTX->totals.spam_classified, CTX->totals.innocent_classified); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) bad = 1; } if (s->control_totals.innocent_learned != 0 || bad) { snprintf (query, sizeof (query), "UPDATE DSPAM_STATS SET TOTAL_SPAM = TOTAL_SPAM %s %d, " "TOTAL_INNOCENT = TOTAL_INNOCENT %s %d, " "SPAM_MISSES = SPAM_MISSES %s %d, " "FALSE_POSITIVES = FALSE_POSITIVES %s %d, " "SPAM_CORPUSFED = SPAM_CORPUSFED %s %d, " "INNOCENT_CORPUSFED = INNOCENT_CORPUSFED %s %d, " "SPAM_CLASSIFIED = SPAM_CLASSIFIED %s %d, " "INNOCENT_CLASSIFIED = INNOCENT_CLASSIFIED %s %d " "WHERE USER_ID = %d", (CTX->totals.spam_learned > s->control_totals.spam_learned) ? "+" : "-", abs (CTX->totals.spam_learned - s->control_totals.spam_learned), (CTX->totals.innocent_learned > s->control_totals.innocent_learned) ? "+" : "-", abs (CTX->totals.innocent_learned - s->control_totals.innocent_learned), (CTX->totals.spam_misclassified > s->control_totals.spam_misclassified) ? "+" : "-", abs (CTX->totals.spam_misclassified - s->control_totals.spam_misclassified), (CTX->totals.innocent_misclassified > s->control_totals.innocent_misclassified) ? "+" : "-", abs (CTX->totals.innocent_misclassified - s->control_totals.innocent_misclassified), (CTX->totals.spam_corpusfed > s->control_totals.spam_corpusfed) ? "+" : "-", abs (CTX->totals.spam_corpusfed - s->control_totals.spam_corpusfed), (CTX->totals.innocent_corpusfed > s->control_totals.innocent_corpusfed) ? "+" : "-", abs (CTX->totals.innocent_corpusfed - s->control_totals.innocent_corpusfed), (CTX->totals.spam_classified > s->control_totals.spam_classified) ? "+" : "-", abs (CTX->totals.spam_classified - s->control_totals.spam_classified), (CTX->totals.innocent_classified > s->control_totals.innocent_classified) ? "+" : "-", abs (CTX->totals.innocent_classified - s->control_totals.innocent_classified), p->pw_uid); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; } OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EUNKNOWN; } int _ds_getall_spamrecords (DSPAM_CTX * CTX, ds_diction_t diction) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; struct passwd *p; buffer *query; ds_term_t ds_term; ds_cursor_t ds_c; char scratch[1024], token_c[32] = { 0 }; struct _ds_spam_stat stat; OCIStmt *stmthp; OCIDefine *defn1 = NULL, *defn2 = NULL, *defn3 = NULL; unsigned long long token = 0; long sh = 0, ih = 0; sword status; if (CTX->storage == NULL) { LOGDEBUG ("_ds_getall_spamrecords: storage not initialized"); return EINVAL; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_getall_spamrecords: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } stat.spam_hits = 0; stat.innocent_hits = 0; query = buffer_create (NULL); if (query == NULL) { LOG (LOG_CRIT, ERR_MEM_ALLOC); return EUNKNOWN; } snprintf (scratch, sizeof (scratch), "SELECT TOKEN, SPAM_HITS, INNOCENT_HITS FROM %s.DSPAM_TOKEN_DATA WHERE " " USER_ID = %d AND TOKEN IN(", s->schema, p->pw_uid); buffer_cat (query, scratch); ds_c = ds_diction_cursor(diction); ds_term = ds_diction_next(ds_c); while(ds_term) { snprintf (scratch, sizeof (scratch), "%llu", ds_term->key); buffer_cat (query, scratch); ds_term->s.innocent_hits = 0; ds_term->s.spam_hits = 0; ds_term->s.probability = 0; ds_term->s.status &= ~TST_DISK; ds_term = ds_diction_next(ds_c); if (ds_term) buffer_cat (query, ","); } ds_diction_close(ds_c); buffer_cat (query, ")"); #ifdef VERBOSE LOGDEBUG ("oracle query length: %ld\n", query->used); #endif if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query->data, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query->data, (ub4) strlen (query->data), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query->data, s->errhp, OCIDefineByPos (stmthp, &defn1, s->errhp, 1, (dvoid *) & token_c, (sword) sizeof (token_c), SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query->data, s->errhp, OCIDefineByPos (stmthp, &defn2, s->errhp, 2, (dvoid *) & sh, (sword) sizeof (sh), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query->data, s->errhp, OCIDefineByPos (stmthp, &defn3, s->errhp, 3, (dvoid *) & ih, (sword) sizeof (ih), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 0, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT); stat.probability = 0; while ((status = OCIStmtFetch (stmthp, s->errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT, (ub4) OCI_DEFAULT)) == OCI_SUCCESS || status == OCI_SUCCESS_WITH_INFO) { token = strtoull (token_c, NULL, 0); if (token) { if (sh < 0) sh = 0; if (ih < 0) ih = 0; stat.spam_hits = sh; stat.innocent_hits = ih; stat.status |= TST_DISK; /* our control token will tell us how each token was altered */ if (stat.spam_hits && stat.innocent_hits && !s->control_token) { s->control_token = token; s->control_sh = stat.spam_hits; s->control_ih = stat.innocent_hits; } ds_diction_setstat(diction, token, &stat); } } if (!s->control_token) { s->control_token = token; s->control_sh = stat.spam_hits; s->control_ih = stat.innocent_hits; } OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); buffer_destroy (query); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EUNKNOWN; } int _ds_setall_spamrecords (DSPAM_CTX * CTX, ds_diction_t diction) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; struct _ds_spam_stat stat; ds_term_t ds_term; ds_cursor_t ds_c; buffer *query; char scratch[1024]; struct passwd *p; int update_one = 0; OCIStmt *stmthp; if (CTX->storage == NULL) { LOGDEBUG ("_ds_setall_spamrecords: storage not initialized"); return EINVAL; } if (CTX->operating_mode == DSM_CLASSIFY && (CTX->training_mode != DST_TOE || (diction->whitelist_token == 0 && (!(CTX->flags & DSF_NOISE))))) return 0; p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_setall_spamrecords: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } query = buffer_create (NULL); if (query == NULL) { LOG (LOG_CRIT, ERR_MEM_ALLOC); return EUNKNOWN; } if (s->control_token == 0) { ds_c = ds_diction_cursor(diction); ds_term = ds_diction_next(ds_c); if (!ds_term) { stat.spam_hits = 0; stat.innocent_hits = 0; } else { stat.spam_hits = ds_term->s.spam_hits; stat.innocent_hits = ds_term->s.innocent_hits; } ds_diction_close(ds_c); } else { ds_diction_setstat(diction, s->control_token, &stat); } snprintf (scratch, sizeof (scratch), "UPDATE %s.DSPAM_TOKEN_DATA SET LAST_HIT = SYSDATE, " " SPAM_HITS = GREATEST(0, SPAM_HITS %s %d), " " INNOCENT_HITS = GREATEST(0, INNOCENT_HITS %s %d) " " WHERE USER_ID = %d AND TOKEN IN(", s->schema, (stat.spam_hits > s->control_sh) ? "+" : "-", abs (stat.spam_hits - s->control_sh), (stat.innocent_hits > s->control_ih) ? "+" : "-", abs (stat.innocent_hits - s->control_ih), p->pw_uid); buffer_cat (query, scratch); ds_c = ds_diction_cursor(diction); ds_term = ds_diction_next(ds_c); while(ds_term) { int wrote_this = 0; if (CTX->training_mode == DST_TOE && CTX->classification == DSR_NONE && CTX->operating_mode == DSM_CLASSIFY && diction->whitelist_token != ds_term->key && (!ds_term->name || strncmp(ds_term->name, "bnr.", 4))) { ds_term = ds_diction_next(ds_c); continue; } if (!(ds_term->s.status & TST_DIRTY)) { ds_term = ds_diction_next(ds_c); continue; } ds_diction_getstat(diction, ds_term->key, &stat); if (!(stat.status & TST_DISK)) { char insert[1024]; snprintf (insert, sizeof (insert), "INSERT INTO %s.DSPAM_TOKEN_DATA(USER_ID, TOKEN, SPAM_HITS, " "INNOCENT_HITS, LAST_HIT) VALUES(%d, %llu, %ld, %ld, SYSDATE)", s->schema, p->pw_uid, ds_term->key, stat.spam_hits, stat.innocent_hits); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (insert, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) insert, (ub4) strlen (insert), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (insert, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) stat.status |= TST_DISK; } if ((stat.status & TST_DISK)) { snprintf (scratch, sizeof (scratch), "%llu", ds_term->key); buffer_cat (query, scratch); update_one = 1; wrote_this = 1; ds_term->s.status |= TST_DISK; } ds_term = ds_diction_next(ds_c); if (ds_term && wrote_this) buffer_cat (query, ","); } ds_diction_close(ds_c); if (query->used && query->data[strlen (query->data) - 1] == ',') { query->used--; query->data[strlen (query->data) - 1] = 0; } buffer_cat (query, ")"); if (update_one) { if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query->data, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query->data, (ub4) strlen (query-> data), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query->data, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; } OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); buffer_destroy (query); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EFAILURE; } int _ds_get_spamrecord (DSPAM_CTX * CTX, unsigned long long token, struct _ds_spam_stat *stat) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; struct passwd *p; char query[1024]; OCIStmt *stmthp; OCIDefine *defn1 = NULL, *defn2 = NULL; sword status; if (CTX->storage == NULL) { LOGDEBUG ("_ds_getall_spamrecords: storage not initialized"); return EINVAL; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_getall_spamrecords: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } snprintf (query, sizeof (query), "SELECT SPAM_HITS, INNOCENT_HITS FROM %s.DSPAM_TOKEN_DATA WHERE " " USER_ID = %d AND TOKEN = %llu", s->schema, p->pw_uid, token); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn1, s->errhp, 1, (dvoid *) & stat-> spam_hits, (sword) sizeof (long), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIDefineByPos (stmthp, &defn2, s->errhp, 2, (dvoid *) & stat-> innocent_hits, (sword) sizeof (long), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT)) != OCI_SUCCESS) goto bail; status = OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT); stat->probability = 0; if (status == OCI_NO_DATA) { OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EFAILURE; } if (_ora_drv_checkerr (query, s->errhp, status) != OCI_SUCCESS) goto bail; OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EUNKNOWN; } int _ds_set_spamrecord (DSPAM_CTX * CTX, unsigned long long token, struct _ds_spam_stat *stat) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; struct passwd *p; char query[1024]; OCIStmt *stmthp; if (CTX->operating_mode == DSM_CLASSIFY) return 0; if (CTX->storage == NULL) { LOGDEBUG ("_ds_getall_spamrecords: storage not initialized"); return EINVAL; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_getall_spamrecords: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } /* Try to insert first; will fail if exists because of unique index */ snprintf (query, sizeof (query), "INSERT INTO %s.DSPAM_TOKEN_DATA (USER_ID, TOKEN, INNOCENT_HITS," " SPAM_HITS, LAST_HIT) VALUES(%d, %llu, %ld, %ld, SYSDATE)", s->schema, p->pw_uid, token, stat->innocent_hits > 0 ? stat->innocent_hits : 0, stat->spam_hits > 0 ? stat->spam_hits : 0); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; /* If insert fails, try an update */ if (OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT) != OCI_SUCCESS) { snprintf (query, sizeof (query), "UPDATE %s.DSPAM_TOKEN_DATA SET INNOCENT_HITS = %ld, SPAM_HITS = %ld" " WHERE USER_ID = %d AND TOKEN = %llu", s->schema, stat->innocent_hits, stat->spam_hits, p->pw_uid, token); if (CTX->training_mode == DST_TUM) { if (CTX->classification == DSR_NONE) strlcat(query, " AND INNOCENT_HITS + SPAM_HITS < 50", sizeof(query)); } if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; } OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EUNKNOWN; } int _ds_delall_spamrecords (DSPAM_CTX * CTX, ds_diction_t diction) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; ds_term_t ds_term; ds_cursor_t ds_c; buffer *query; char scratch[1024]; char queryhead[1024]; struct passwd *p; OCIStmt *stmthp; if (diction == NULL || diction->items == 0) return 0; if (CTX->storage == NULL) { LOGDEBUG ("_ds_delall_spamrecords: storage not initialized"); return EINVAL; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_delall_spamrecords: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } query = buffer_create (NULL); if (query == NULL) { LOG (LOG_CRIT, ERR_MEM_ALLOC); return EUNKNOWN; } snprintf (queryhead, sizeof (queryhead), "DELETE FROM %s.DSPAM_TOKEN_DATA " " WHERE USER_ID = %d AND TOKEN IN(", s->schema, p->pw_uid); buffer_cat (query, queryhead); ds_c = ds_diction_cursor(diction); ds_term = ds_diction_next(ds_c); while (ds_term) { snprintf (scratch, sizeof (scratch), "%llu", ds_term->key); buffer_cat (query, scratch); ds_term = ds_diction_next(ds_c); if (ds_term) buffer_cat (query, ","); } ds_diction_close(ds_c); buffer_cat (query, ")"); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query->data, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query->data, (ub4) strlen (query-> data), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query->data, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); buffer_destroy (query); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EFAILURE; } int _ds_del_spamrecord (DSPAM_CTX * CTX, unsigned long long token) { struct _ora_drv_storage *s = (struct _ora_drv_storage *) CTX->storage; struct passwd *p; char query[1024]; OCIStmt *stmthp; if (CTX->storage == NULL) { LOGDEBUG ("_ds_getall_spamrecords: storage not initialized"); return EINVAL; } p = _ora_drv_getpwnam (CTX, CTX->username); if (p == NULL) { LOGDEBUG ("_ds_getall_spamrecords: unable to _ora_drv_getpwnam(%s)", CTX->username); return EINVAL; } snprintf (query, sizeof (query), "DELETE FROM %s.DSPAM_TOKEN_DATA " " WHERE USER_ID = %d AND TOKEN = %llu", s->schema, p->pw_uid, token); if (_ora_drv_checkerr (NULL, s->errhp, OCIHandleAlloc ((dvoid *) s->envhp, (dvoid **) & stmthp, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) != OCI_SUCCESS) return EUNKNOWN; if (_ora_drv_checkerr (query, s->errhp, OCIStmtPrepare (stmthp, s->errhp, (text *) query, (ub4) strlen (query), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; if (_ora_drv_checkerr (query, s->errhp, OCIStmtExecute (s->svchp, stmthp, s->errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)) != OCI_SUCCESS) goto bail; OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return 0; bail: OCIHandleFree ((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT); return EUNKNOWN; } void *_ds_connect (DSPAM_CTX *CTX) { return NULL; } /* Preference Stubs for Flat-File */ agent_pref_t _ds_pref_load(config_t config, const char *user, const char *home, void *dbh) { return _ds_ff_pref_load(config, user, home, dbh); } int _ds_pref_set(config_t config, const char *user, const char *home, const char *attrib, const char *value, void *dbh) { return _ds_ff_pref_set(config, user, home, attrib, value, dbh); } int _ds_pref_del(config_t config, const char *user, const char *home, const char *attrib, void *dbh) { return _ds_ff_pref_del(config, user, home, attrib, dbh); }