[Snort-users] output rule types

Andrew R. Baker andrewb at ...1150...
Sat Mar 17 16:07:53 EST 2001


OK, I have created a patch and sent it to Marty for inclusion in snort
1.7.1.  This patch should also apply
cleanly to the snort 1.7 code base, but I have not tried that.  The
patch has had limited testing under OpenBSD.

-Andrew

"Andrew R. Baker" wrote:
> 
> Are you using the also using the database output plugin with another
> rule type?  It looks like there is
> a bug with associating the database plugin with multiple rule types.  In
> this case, many of the alerts
> are not properly entered into the database.  I am working on a fix for
> this, which will hopefully correct
> your problem.
> 
> -Andrew
> 
> John Kiehnle wrote:
> >
> > Any clues why snort will not log to a mysql db file when the output plugin is
> > associated with a ruletype such as the redalert example in snort.conf.
> >
> > Using snort 1.7
> >
> > If I uncomment the example rule type redalert which includes;
> >
> > ruletype redalert
> > {
> > output alert_syslog: LOG_AUTH LOG_ALERT
> > output database: log, mysql, user=piggy password=xyz dbname=snort_log
> > host=localhost
> > }
> >
> > Snort displays the db config data and starts with no errors but never logs to
> > the database... syslog works Ok. If I uncomment the individual lines for each
> > output plugin without the associating rule type, It works fine. Both mysql and
> > syslog begin to generate logfiles.
> >
> > I noticed this happens on both my outside sensor on the DMZ and the sensor
> > inside my firewall. Associate the db plugin with a ruletype and I have
> > problems, uncomment it by itself and it works fine. MySQL does not complain at
> > all either way.
> >
> > Am i just not getting the ruletype configured properly? It really does not look
> > too complicated here... what gives?
> >
> > The more I learn, the more I realize how little I really know. :(
> >
> > John Kiehnle
> >
> > --- CHAOS -Where Great Dreams Begin ---
> >
> > Befor a great vision can become reality there may be difficulty. Befor a person
> > begins a great endeavor, they may encounter chaos.
> >
> > As a new plant breaks the ground with great difficulty, foreshadowing the huge
> > tree, so must we sometimes push against difficulty in bringing forth our
> > dreams.
> >
> > "Out of Chaos, Brilliant Stars are Born."
> >
> > I-Ching Hexagram #3
> >
> > _______________________________________________
> > Snort-users mailing list
> > Snort-users at lists.sourceforge.net
> > Go to this URL to change user options or unsubscribe:
> > http://lists.sourceforge.net/lists/listinfo/snort-users
> 
> _______________________________________________
> Snort-users mailing list
> Snort-users at lists.sourceforge.net
> Go to this URL to change user options or unsubscribe:
> http://lists.sourceforge.net/lists/listinfo/snort-users
> Snort-users list archive:
> http://www.geocrawler.com/redir-sf.php3?list=snort-users
-------------- next part --------------
diff -durN snort-1.7.1-beta-CVS/spo_database.c snort-1.7.1-beta-dev/spo_database.c
--- snort-1.7.1-beta-CVS/spo_database.c	Wed Feb 28 23:26:12 2001
+++ snort-1.7.1-beta-dev/spo_database.c	Sat Mar 17 12:54:43 2001
@@ -1,5 +1,6 @@
 /*
 ** Copyright (C) 2000,2001 Carnegie Mellon University
+** Portions Copyright (C) 2001 Andrew R. Baker <andrewb at ...1150...>
 **
 ** 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
@@ -30,6 +31,20 @@
 #include "spo_database.h"
 extern PV pv;
 
+/* list for lookup of shared data information */
+typedef struct _SharedDatabaseDataNode
+{
+    SharedDatabaseData *data;
+    struct _SharedDatabaseDataNode *next;
+} SharedDatabaseDataNode;
+
+static SharedDatabaseDataNode *sharedDataList = NULL;
+static int instances = 0;
+
+/* Locally defined functions */
+void FreeSharedDataList();
+
+
 /* If you want extra debugging information for solving database 
    configuration problems, uncomment the following line. */
 /* #define DEBUG */
@@ -74,6 +89,8 @@
     char * select0;
     char * select1;
     char * insert0;
+	int foundEntry = 0;
+	SharedDatabaseDataNode *current;
 
     /* parse the argument list from the rules file */
     data = ParseDatabaseArgs(args);
@@ -122,25 +139,75 @@
 
     Connect(data);
 
-    data->sid = Select(select0,data);
-    if(data->sid == 0)
+    data->shared->sid = Select(select0,data);
+    if(data->shared->sid == 0)
     {
         Insert(insert0,data);
-        data->sid = Select(select0,data);
-        if(data->sid == 0)
+        data->shared->sid = Select(select0,data);
+        if(data->shared->sid == 0)
         {
-            ErrorMessage("database: Problem obtaining SENSOR ID (sid) from %s->%s->sensor\n", data->dbtype,data->dbname);
+            ErrorMessage("database: Problem obtaining SENSOR ID (sid) from %s->%s->sensor\n", data->shared->dbtype,data->shared->dbname);
             FatalError("\n When this plugin starts, a SELECT query is run to find the sensor id for the\n currently running sensor. If the sensor id is not found, the plugin will run\n an INSERT query to insert the proper data and generate a new sensor id. Then a\n SELECT query is run to get the newly allocated sensor id. If that fails then\n this error message is generated.\n\n Some possible causes for this error are:\n   * the user does not have proper INSERT or SELECT privileges\n   * the sensor table does not exist\n\n If you are _absolutly_ certain that you have the proper privileges set and\n that your database structure is built properly please let me know if you\n continue to get this error. You can contact me at (jed at ...153...).\n\n");
         }
     }
 
-    printf("database:     sensor id = %u\n", data->sid);
+    printf("database:     sensor id = %u\n", data->shared->sid);
 
-    snprintf(select1, MAX_QUERY_LENGTH,
-             "SELECT max(cid) FROM event WHERE sid = '%u'", data->sid);
+	/* the cid may be shared across multiple instances of the database
+	   plugin, first we check the shared data list to see if we already
+	   have a value to use, if so, we replace the SharedDatabaseData struct
+	   in the DatabaseData struct with the one out of the sharedDataList.
+	   Sound confusing enough?  
+	   -Andrew	
+     */
+	/* XXX: Creating a set of list handling functions would make this cleaner */
+	current = sharedDataList;
+	while(current != NULL)
+	{
+		/* We have 4 key fields to check */
+		/* XXX: This code would be cleaner if dbtype was an int */
+		if((current->data->sid == data->shared->sid) &&
+				(strcasecmp(current->data->dbtype, data->shared->dbtype) == 0) &&
+				/* XXX: should this be a case insensitive compare? */
+				(strcasecmp(current->data->dbname, data->shared->dbname) == 0) &&
+				(strcasecmp(current->data->host, data->shared->host) == 0))
+		{
+			foundEntry = 1;
+			break;
+		}
+		current = current->next;
+	}
+	
+	if(foundEntry == 0)
+	{
+		/* Add it the the shared data list */
+		SharedDatabaseDataNode *newNode = (SharedDatabaseDataNode *)malloc(sizeof(SharedDatabaseDataNode));
+		newNode->data = data->shared;
+		newNode->next = NULL;
+		if(sharedDataList == NULL)
+		{
+			sharedDataList = newNode;
+		}
+		else
+		{
+			current = sharedDataList;
+			while(current->next != NULL)
+				current = current->next;
+			current->next = newNode;
+		}
+		/* Set the cid value */
+    	snprintf(select1, MAX_QUERY_LENGTH,
+        	     "SELECT max(cid) FROM event WHERE sid = '%u'", data->shared->sid);
 
-    data->cid = Select(select1,data);
-    data->cid++;
+  	  	data->shared->cid = Select(select1,data);
+    	++(data->shared->cid);
+	}
+	else
+	{
+		/* Free memory associated with data->shared */
+		free(data->shared);
+		data->shared = current->data;
+	}
 
     /* free memory */
     free(select0);
@@ -163,6 +230,7 @@
 
     AddFuncToCleanExitList(SpoDatabaseCleanExitFunction, data);
     AddFuncToRestartList(SpoDatabaseRestartFunction, data); 
+	++instances;
 }
 
 /*
@@ -185,7 +253,9 @@
     char *facility;
 
     data = (DatabaseData *)calloc(1, sizeof(DatabaseData));
+	data->shared = (SharedDatabaseData *)malloc(sizeof(SharedDatabaseData));
 
+			
     if(args == NULL)
     {
         ErrorMessage("database: you must supply arguments for database plugin\n");
@@ -193,7 +263,7 @@
         FatalError("");
     }
 
-    data->dbtype = NULL;
+    data->shared->dbtype = NULL;
     data->sensor_name = NULL;
     data->facility = NULL;
     data->encoding = ENCODING_HEX;
@@ -237,28 +307,28 @@
     printf("%s ",MYSQL);
     if(!strncasecmp(type,MYSQL,5))
     {
-        data->dbtype = type; 
+        data->shared->dbtype = type; 
     }
 #endif
 #ifdef ENABLE_POSTGRESQL
     printf("%s ",POSTGRESQL);
     if(!strncasecmp(type,POSTGRESQL,10))
     {
-        data->dbtype = type; 
+        data->shared->dbtype = type; 
     }
 #endif
 #ifdef ENABLE_UNIXODBC
     printf("%s ",UNIXODBC);
     if(!strncasecmp(type,UNIXODBC,8))
     {
-        data->dbtype = type; 
+        data->shared->dbtype = type; 
     }
 #endif
 #ifdef ENABLE_ORACLE
     printf("%s ",ORACLE);
     if(!strncasecmp(type,ORACLE,5))
     {
-      data->dbtype = type; 
+      data->shared->dbtype = type; 
     }
 #endif
 
@@ -266,7 +336,7 @@
 
     printf("database: configured to use %s\n", type);
 
-    if(data->dbtype == NULL)
+    if(data->shared->dbtype == NULL)
     {
         ErrorMessage("database: %s support is not compiled in this copy\n\n", type);
         FatalError(" Check your configuration file to be sure you did not mis-spell \"%s\".\n If you did not, you will need to reconfigure and recompile ensuring that\n you have set the correct options to the configure script. Type \n \"./configure --help\" to see options for the configure script.\n\n", type);
@@ -279,8 +349,8 @@
         a1 = strtok(NULL, ", ");
         if(!strncasecmp(dbarg,"host",4))
         {
-            data->host = a1;
-            printf("database:          host = %s\n", data->host);
+            data->shared->host = a1;
+            printf("database:          host = %s\n", data->shared->host);
         }
         if(!strncasecmp(dbarg,"port",4))
         {
@@ -290,7 +360,7 @@
         if(!strncasecmp(dbarg,"user",4))
         {
             data->user = a1;
-            printf("database:          user = %s\n", data->user);
+            printf("database:          user = %s\n", data->user); fflush(stdout);
         }
         if(!strncasecmp(dbarg,"password",8))
         {
@@ -299,8 +369,8 @@
         }
         if(!strncasecmp(dbarg,"dbname",6))
         {
-            data->dbname = a1;
-            printf("database: database name = %s\n", data->dbname);
+            data->shared->dbname = a1;
+            printf("database: database name = %s\n", data->shared->dbname);
         }
         if(!strncasecmp(dbarg,"sensor_name",11))
         {
@@ -355,7 +425,7 @@
         dbarg = strtok(NULL, "=");
     } 
 
-    if(data->dbname == NULL)
+    if(data->shared->dbname == NULL)
     {
         ErrorMessage("database: must enter database name in configuration file\n\n");
         DatabasePrintUsage();
@@ -428,7 +498,6 @@
     char dip[16];
     char *s0,*s1,*s2,*s3,*d0,*d1,*d2,*d3;
 
-
     query = NewQueryNode(NULL, 0);
     root = query;
 
@@ -449,7 +518,7 @@
     snprintf(query->val, MAX_QUERY_LENGTH, 
              "INSERT INTO event (sid,cid,signature,timestamp) VALUES "
              "('%u', '%u', '%s', '%s')",
-             data->sid, data->cid, msg, tmp);
+             data->shared->sid, data->shared->cid, msg, tmp);
     free(tmp); 
 
 /* We do not log fragments! They are assumed to be handled 
@@ -488,7 +557,7 @@
                                  "INSERT INTO icmphdr (sid, cid, icmp_type, icmp_code, "
                                  "icmp_csum, icmp_id, icmp_seq) "
                                  "VALUES ('%u','%u','%u','%u','%u','%u','%u')",
-                                 data->sid, data->cid, p->icmph->type, p->icmph->code,
+                                 data->shared->sid, data->shared->cid, p->icmph->type, p->icmph->code,
                                  ntohs(p->icmph->csum), ntohs(p->ext->id), ntohs(p->ext->seqno));
                     }
                     else
@@ -497,7 +566,7 @@
                                  "INSERT INTO icmphdr (sid, cid, icmp_type, icmp_code, "
                                  "icmp_csum) "
                                  "VALUES ('%u','%u','%u','%u','%u')",
-                                 data->sid, data->cid, p->icmph->type, p->icmph->code,
+                                 data->shared->sid, data->shared->cid, p->icmph->type, p->icmph->code,
                                  ntohs(p->icmph->csum));
                     }
                 }
@@ -506,7 +575,7 @@
                     snprintf(query->val, MAX_QUERY_LENGTH, 
                              "INSERT INTO icmphdr (sid, cid, icmp_type, icmp_code) "
                              "VALUES ('%u','%u','%u','%u')",
-                             data->sid, data->cid, p->icmph->type, p->icmph->code);
+                             data->shared->sid, data->shared->cid, p->icmph->type, p->icmph->code);
                 }
             }
             else if(p->iph->ip_proto == IPPROTO_TCP)
@@ -524,7 +593,7 @@
                              "VALUES ('%u','%u','%u','%u','%lu','%lu','%u',"
                              "'%u','%u','%u','%u','%u')",
 
-                             data->sid, data->cid, ntohs(p->tcph->th_sport), 
+                             data->shared->sid, data->shared->cid, ntohs(p->tcph->th_sport), 
                              ntohs(p->tcph->th_dport), (u_long)ntohl(p->tcph->th_seq),
                              (u_long)ntohl(p->tcph->th_ack), p->tcph->th_off, 
                              p->tcph->th_x2, p->tcph->th_flags, 
@@ -537,7 +606,7 @@
                              "INSERT INTO tcphdr "
                              "(sid,cid,tcp_sport,tcp_dport,tcp_flags) "
                              "VALUES ('%u','%u','%u','%u','%u')",
-                             data->sid, data->cid, ntohs(p->tcph->th_sport), 
+                             data->shared->sid, data->shared->cid, ntohs(p->tcph->th_sport), 
                              ntohs(p->tcph->th_dport), p->tcph->th_flags);
                 }
 
@@ -560,7 +629,7 @@
                                  "INSERT INTO opt "
                                  "(sid,cid,optid,opt_proto,opt_code,opt_len,opt_data) "
                                  "VALUES ('%u','%u','%u','%u','%u','%u','%s')",
-                                 data->sid, data->cid, i, 6, p->tcp_options[i].code,
+                                 data->shared->sid, data->shared->cid, i, 6, p->tcp_options[i].code,
                                  p->tcp_options[i].len, tmp); 
                         free(tmp);
                     }
@@ -575,7 +644,7 @@
                              "INSERT INTO udphdr "
                              "(sid, cid, udp_sport, udp_dport, udp_len, udp_csum) "
                              "VALUES ('%u', '%u', '%u', '%u', '%u', '%u')",
-                             data->sid, data->cid, ntohs(p->udph->uh_sport), 
+                             data->shared->sid, data->shared->cid, ntohs(p->udph->uh_sport), 
                              ntohs(p->udph->uh_dport), ntohs(p->udph->uh_len),
                              ntohs(p->udph->uh_chk));
                 }
@@ -585,7 +654,7 @@
                              "INSERT INTO udphdr "
                              "(sid, cid, udp_sport, udp_dport) "
                              "VALUES ('%u', '%u', '%u', '%u')",
-                             data->sid, data->cid, ntohs(p->udph->uh_sport), 
+                             data->shared->sid, data->shared->cid, ntohs(p->udph->uh_sport), 
                              ntohs(p->udph->uh_dport));
                 }
             }
@@ -609,7 +678,7 @@
                      "'%u','%u','%u','%u','%u','%u',"
                      "'%u','%u','%u')",
 
-                     data->sid, data->cid, (u_long)ntohl(p->iph->ip_src.s_addr), 
+                     data->shared->sid, data->shared->cid, (u_long)ntohl(p->iph->ip_src.s_addr), 
                      s0, s1, s2, s3, (u_long)ntohl(p->iph->ip_dst.s_addr), 
                      d0, d1, d2, d3, p->iph->ip_ver, p->iph->ip_hlen, 
                      p->iph->ip_tos, ntohs(p->iph->ip_len), ntohs(p->iph->ip_id), 
@@ -625,7 +694,7 @@
 
                      "VALUES ('%u','%u','%lu','%lu','%u')",
 
-                     data->sid, data->cid, (u_long)ntohl(p->iph->ip_src.s_addr),
+                     data->shared->sid, data->shared->cid, (u_long)ntohl(p->iph->ip_src.s_addr),
                      (u_long)ntohl(p->iph->ip_dst.s_addr), p->iph->ip_proto);
         }
 
@@ -649,7 +718,7 @@
                              "INSERT INTO opt "
                              "(sid,cid,optid,opt_proto,opt_code,opt_len,opt_data) "
                              "VALUES ('%u','%u','%u','%u','%u','%u','%s')",
-                             data->sid, data->cid, i, 0, p->ip_options[i].code,
+                             data->shared->sid, data->shared->cid, i, 0, p->ip_options[i].code,
                              p->ip_options[i].len, tmp); 
                     free(tmp);
                 }
@@ -684,7 +753,7 @@
                          "INSERT INTO data "
                          "(sid,cid,data_payload) "
                          "VALUES ('%u','%u','%s",
-                         data->sid, data->cid, tmp);
+                         data->shared->sid, data->shared->cid, tmp);
                 strcat(query->val, "')");
                 free (tmp);
                 free (tmp_not_escaped);
@@ -702,13 +771,13 @@
 
     FreeQueryNode(root); 
 
-    data->cid++;
+    data->shared->cid++;
 
     /* A Unixodbc bugfix */
 #ifdef ENABLE_UNIXODBC
-    if(data->cid == 600)
+    if(data->shared->cid == 600)
     {
-        data->cid = 601;
+        data->shared->cid = 601;
     }
 #endif
 }
@@ -735,7 +804,7 @@
     to = (char *)malloc(strlen(from) * 2 + 1);
     to_start = to;
 #ifdef ENABLE_ORACLE
-    if (!strcasecmp(data->dbtype,ORACLE))
+    if (!strcasecmp(data->shared->dbtype,ORACLE))
     {
       for (end=from+from_length; from != end; from++)
       {
@@ -823,7 +892,7 @@
 #endif
 
 #ifdef ENABLE_POSTGRESQL
-    if(!strcasecmp(data->dbtype,POSTGRESQL))
+    if(!strcasecmp(data->shared->dbtype,POSTGRESQL))
     {
         data->p_result = PQexec(data->p_connection,query);
         if(!(PQresultStatus(data->p_result) != PGRES_COMMAND_OK))
@@ -841,7 +910,7 @@
 #endif
 
 #ifdef ENABLE_MYSQL
-    if(!strcasecmp(data->dbtype,MYSQL))
+    if(!strcasecmp(data->shared->dbtype,MYSQL))
     {
         if(!strncasecmp(query, STANDARD_INSERT, strlen(STANDARD_INSERT)))
         {
@@ -868,7 +937,7 @@
 #endif
 
 #ifdef ENABLE_UNIXODBC
-    if(!strcasecmp(data->dbtype,UNIXODBC))
+    if(!strcasecmp(data->shared->dbtype,UNIXODBC))
     {
         if(SQLAllocStmt(data->u_connection, &data->u_statement) == SQL_SUCCESS)
             if(SQLPrepare(data->u_statement, query, SQL_NTS) == SQL_SUCCESS)
@@ -878,7 +947,7 @@
 #endif
 
 #ifdef ENABLE_ORACLE
-    if(!strcasecmp(data->dbtype,ORACLE))
+    if(!strcasecmp(data->shared->dbtype,ORACLE))
     {
         if (OCIStmtPrepare(data->o_statement, data->o_error, query, strlen(query), OCI_NTV_SYNTAX, OCI_DEFAULT) || 
 	    OCIStmtExecute(data->o_servicecontext, data->o_statement, data->o_error, 1,  0, NULL, NULL, OCI_COMMIT_ON_SUCCESS))
@@ -921,7 +990,7 @@
     int result = 0;
 
 #ifdef ENABLE_POSTGRESQL
-    if(!strcasecmp(data->dbtype,POSTGRESQL))
+    if(!strcasecmp(data->shared->dbtype,POSTGRESQL))
     {
         data->p_result = PQexec(data->p_connection,query);
         if((PQresultStatus(data->p_result) == PGRES_TUPLES_OK))
@@ -950,7 +1019,7 @@
 #endif
 
 #ifdef ENABLE_MYSQL
-    if(!strcasecmp(data->dbtype,MYSQL))
+    if(!strcasecmp(data->shared->dbtype,MYSQL))
     {
         if(mysql_query(data->m_sock,query))
         {
@@ -985,7 +1054,7 @@
 #endif
 
 #ifdef ENABLE_UNIXODBC
-    if(!strcasecmp(data->dbtype,UNIXODBC))
+    if(!strcasecmp(data->shared->dbtype,UNIXODBC))
     {
         if(SQLAllocStmt(data->u_connection, &data->u_statement) == SQL_SUCCESS)
             if(SQLPrepare(data->u_statement, query, SQL_NTS) == SQL_SUCCESS)
@@ -1010,7 +1079,7 @@
 #endif
 
 #ifdef ENABLE_ORACLE
-    if(!strcasecmp(data->dbtype,ORACLE))
+    if(!strcasecmp(data->shared->dbtype,ORACLE))
     {
         if (OCIStmtPrepare(data->o_statement, data->o_error, query, strlen(query), OCI_NTV_SYNTAX, OCI_DEFAULT) ||
 	    OCIStmtExecute(data->o_servicecontext, data->o_statement, data->o_error, 0, 0, NULL, NULL, OCI_DEFAULT) ||
@@ -1051,24 +1120,24 @@
 #endif
 
 #ifdef ENABLE_POSTGRESQL
-    if(!strcasecmp(data->dbtype,POSTGRESQL))
+    if(!strcasecmp(data->shared->dbtype,POSTGRESQL))
     {
-        data->p_connection = PQsetdbLogin(data->host,data->port,NULL,NULL,data->dbname,data->user,data->password);
+        data->p_connection = PQsetdbLogin(data->shared->host,data->port,NULL,NULL,data->shared->dbname,data->user,data->password);
         if(PQstatus(data->p_connection) == CONNECTION_BAD)
         {
             PQfinish(data->p_connection);
-            FatalError("database: Connection to database '%s' failed\n", data->dbname);
+            FatalError("database: Connection to database '%s' failed\n", data->shared->dbname);
         }
     }
 #endif
 
 #ifdef ENABLE_MYSQL
-    if(!strcasecmp(data->dbtype,MYSQL))
+    if(!strcasecmp(data->shared->dbtype,MYSQL))
     {
         data->m_sock = mysql_init(NULL);
         if(data->m_sock == NULL)
         {
-            FatalError("database: Connection to database '%s' failed\n", data->dbname);
+            FatalError("database: Connection to database '%s' failed\n", data->shared->dbname);
         }
         if(data->port != NULL)
         {
@@ -1078,19 +1147,19 @@
         {
             x = 0;
         }
-        if(mysql_real_connect(data->m_sock, data->host, data->user, data->password, data->dbname, x, NULL, 0) == 0)
+        if(mysql_real_connect(data->m_sock, data->shared->host, data->user, data->password, data->shared->dbname, x, NULL, 0) == 0)
         {
             if(mysql_errno(data->m_sock))
             {
                 FatalError("database: mysql_error: %s\n", mysql_error(data->m_sock));
             }
-            FatalError("database: Failed to logon to database '%s'\n", data->dbname);
+            FatalError("database: Failed to logon to database '%s'\n", data->shared->dbname);
         }
     }
 #endif
 
 #ifdef ENABLE_UNIXODBC
-    if(!strcasecmp(data->dbtype,UNIXODBC))
+    if(!strcasecmp(data->shared->dbtype,UNIXODBC))
     {
         if(!(SQLAllocEnv(&data->u_handle) == SQL_SUCCESS))
         {
@@ -1101,7 +1170,7 @@
         {
             exit(-6);
         }
-        if(!(SQLConnect(data->u_connection, data->dbname, SQL_NTS, data->user, SQL_NTS, data->password, SQL_NTS) == SQL_SUCCESS))
+        if(!(SQLConnect(data->u_connection, data->shared->dbname, SQL_NTS, data->user, SQL_NTS, data->password, SQL_NTS) == SQL_SUCCESS))
         {
             exit(-7);
         }
@@ -1109,17 +1178,17 @@
 #endif
 
 #ifdef ENABLE_ORACLE
-    if(!strcasecmp(data->dbtype,ORACLE))
+    if(!strcasecmp(data->shared->dbtype,ORACLE))
     {
       if (OCIInitialize(OCI_DEFAULT, NULL, NULL, NULL, NULL) ||
          OCIEnvInit(&data->o_environment, OCI_DEFAULT, 0, NULL) ||
          OCIEnvInit(&data->o_environment, OCI_DEFAULT, 0, NULL) ||
          OCIHandleAlloc(data->o_environment, (dvoid **)&data->o_error, OCI_HTYPE_ERROR, (size_t) 0, NULL) ||
          OCILogon(data->o_environment, data->o_error, &data->o_servicecontext,
-data->user, strlen(data->user), data->password, strlen(data->password), data->dbname, strlen(data->dbname)) ||
+data->user, strlen(data->user), data->password, strlen(data->password), data->shared->dbname, strlen(data->shared->dbname)) ||
          OCIHandleAlloc(data->o_environment, (dvoid **)&data->o_statement, OCI_HTYPE_STMT, 0, NULL))
       {
-         FatalError("database: Connection to database '%s' failed\n", data->dbname);
+         FatalError("database: Connection to database '%s' failed\n", data->shared->dbname);
       }
     }
 #endif
@@ -1132,26 +1201,26 @@
 
 void Disconnect(DatabaseData * data)
 {
-    printf("database: Closing %s connection to database \"%s\"\n", data->dbtype, data->dbname);
+    printf("database: Closing %s connection to database \"%s\"\n", data->shared->dbtype, data->shared->dbname);
 
     if(data)
     {
 #ifdef ENABLE_POSTGRESQL
-        if(!strcasecmp(data->dbtype,POSTGRESQL))
+        if(!strcasecmp(data->shared->dbtype,POSTGRESQL))
         {
             if(data->p_connection) PQfinish(data->p_connection);
         }
 #endif
 
 #ifdef ENABLE_MYSQL
-        if(!strcasecmp(data->dbtype,MYSQL))
+        if(!strcasecmp(data->shared->dbtype,MYSQL))
         {
             if(data->m_sock) mysql_close(data->m_sock);
         }
 #endif
 
 #ifdef ENABLE_UNIXODBC
-        if(!strcasecmp(data->dbtype,UNIXODBC))
+        if(!strcasecmp(data->shared->dbtype,UNIXODBC))
         {
             if(data->u_handle)
             {
@@ -1214,7 +1283,10 @@
     printf("database(debug): entered SpoDatabaseCleanExitFunction\n");
 #endif
     Disconnect(data); 
-    if(data) free(data);
+    if(data) 
+		free(data);
+	if(--instances == 0)
+		FreeSharedDataList();
 }
 
 void SpoDatabaseRestartFunction(int signal, void *arg)
@@ -1224,5 +1296,21 @@
     printf("database(debug): entered SpoDatabaseRestartFunction\n");
 #endif
     Disconnect(data);
-    if(data) free(data);
+    if(data) 
+		free(data);
+	if(--instances == 0)
+		FreeSharedDataList();
 }
+
+void FreeSharedDataList()
+{
+	SharedDatabaseDataNode *current;
+	while(sharedDataList != NULL)
+	{ 
+		current = sharedDataList;
+		free(current->data);
+		sharedDataList = current->next;
+		free(current);
+	}
+}
+
diff -durN snort-1.7.1-beta-CVS/spo_database.h snort-1.7.1-beta-dev/spo_database.h
--- snort-1.7.1-beta-CVS/spo_database.h	Fri Feb 16 13:46:25 2001
+++ snort-1.7.1-beta-dev/spo_database.h	Sat Mar 17 12:16:49 2001
@@ -49,21 +49,36 @@
     struct _SQLQuery * next;
 } SQLQuery;
 
+
+/* the cid is unique across the dbtype, dbname, host, and sid */
+/* therefore, we use these as a lookup key for the cid */
+typedef struct _SharedDatabaseData
+{
+	char *dbtype;
+	char *dbname;
+	char *host;
+	int sid;
+	int cid;
+	int reference;
+} SharedDatabaseData;
+
 typedef struct _DatabaseData
 {
+	SharedDatabaseData *shared;
+/*  char * dbtype;
+ *  char * dbname;
+ *  char * host;
+ *  int  sid;
+ *  int  cid;
+ */
     char * facility;
-    char * dbtype;
-    char * dbname;
     char * password;
-    char * host;
     char * user;
     char * port;
     char * sensor_name;
     int  encoding;
     int  detail;
     int  tz;
-    int  sid;
-    int  cid;
 #ifdef ENABLE_POSTGRESQL
     PGconn * p_connection;
     PGresult * p_result;


More information about the Snort-users mailing list