} rlm_sql_postgres_sock;
/* Prototypes */
+
+/*
static int sql_num_fields(SQLSOCK * sqlsocket, SQL_CONFIG *config);
+*/
/* Internal function. Return true if the postgresql status value
* indicates successful completion of the query. Return false otherwise
- */
static int
status_is_ok(ExecStatusType status)
{
return status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK;
}
+*/
/* Internal function. Return the number of affected rows of the result
}
-/***********************************************************************
-* Check to see if we could try to reconnect after a query-server error
-* we are checking only first 2 characters according to the error code
-* class..time consuming...
-************************************************************************/
-static int sql_check_error(char *errcode)
+/*************************************************************************
+* Function: check_fatal_error
+*
+* Purpose: Check error type and behave accordingly
+*
+*************************************************************************/
+
+static int check_fatal_error (char *errorcode)
{
int x = 0;
+ /*
+ Check the error code to see if we should reconnect or not
+ Error Code table taken from
+ http://www.postgresql.org/docs/8.1/interactive/errcodes-appendix.html
+ */
+
while(errorcodes[x].errorcode != NULL){
- if (strcmp(errorcodes[x].errorcode, errcode) == 0){
- radlog(L_DBG, "rlm_sql_postgresql: Postgresql Fatal Error: [%s] Occurred!!", errorcodes[x].meaning);
+ if (strcmp(errorcodes[x].errorcode, errorcode) == 0){
+ radlog(L_DBG, "rlm_sql_postgresql: Postgresql Fatal Error: [%s: %s] Occurred!!", errorcode, errorcodes[x].meaning);
if (errorcodes[x].shouldreconnect == 1)
return SQL_DOWN;
else
}
x++;
}
-
- return SQL_DOWN;
-}
-/*************************************************************************
-* Function: check_fatal_error
-*
-* Purpose: check and behave according to the error type we get
-* from query.
-*
-* Note: This will not cause reconnects because of errors other than
-* connection errors
-* Tuyan Ozipek <tuyan@suntel.com.tr>
-*************************************************************************/
-
-static int check_fatal_error (char *errorcode)
-{
- /* We have the error code in chars..
- please have a look at table at the web page
- http://www.postgresql.org/docs/8.1/interactive/errcodes-appendix.html
- */
radlog(L_DBG, "rlm_sql_postgresql: Postgresql Fatal Error: [%s] Occurred!!", errorcode);
- return sql_check_error(errorcode);
+ /* We don't seem to have a matching error class/code */
+ return -1;
}
}
pg_sock->result = PQexec(pg_sock->conn, querystr);
- /* Returns a result pointer or possibly a NULL pointer.
- * A non-NULL pointer will generally be returned except in
+ /*
+ * Returns a PGresult pointer or possibly a null pointer.
+ * A non-null pointer will generally be returned except in
* out-of-memory conditions or serious errors such as inability
- * to send the command to the backend. If a NULL is returned,
- * it should be treated like a PGRES_FATAL_ERROR result.
- * Use PQerrorMessage to get more information about the error.
+ * to send the command to the server. If a null pointer is
+ * returned, it should be treated like a PGRES_FATAL_ERROR
+ * result.
*/
if (!pg_sock->result)
{
radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL Query failed Error: %s",
PQerrorMessage(pg_sock->conn));
+ /* As this error COULD be a connection error OR an out-of-memory
+ * condition return value WILL be wrong SOME of the time regardless!
+ * Pick your poison....
+ */
return SQL_DOWN;
} else {
ExecStatusType status = PQresultStatus(pg_sock->result);
break;
+ default:
+ /* FIXME: An unhandled error occurred.*/
+
+ /* PGRES_EMPTY_QUERY PGRES_COPY_OUT PGRES_COPY_IN */
+
+ return -1;
+
+ break;
+
+
}
/*
* Function: sql_fetch_row
*
* Purpose: database specific fetch_row. Returns a SQL_ROW struct
- * with all the data for the query in 'sqlsocket->row'. Returns
- * 0 on success, -1 on failure, SQL_DOWN if 'database is down'.
+ * with all the data for the query in 'sqlsocket->row'. Returns
+ * 0 on success, -1 on failure, SQL_DOWN if 'database is down'.
*
*************************************************************************/
static int sql_fetch_row(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
PQclear(pg_sock->result);
pg_sock->result = NULL;
}
-#if 0
- /*
- * Commented out because it appears to free memory too early.
- */
+
free_result_row(pg_sock);
-#endif
return 0;
}
char expansion[MAX_STRING_LEN * 4];
char query[MAX_STRING_LEN * 4];
SQL_ROW row;
- int r;
+ int rlen, retval = 0;
sqlippool_expand(expansion, sizeof(expansion), fmt, instance, param, param_len);
return 0;
}
- r = rlm_sql_fetch_row(sqlsocket, data->sql_inst);
- (data->sql_inst->module->sql_finish_select_query)(sqlsocket, data->sql_inst->config);
-
- if (r) {
- DEBUG("sqlippool_query1: SQL query did not succeed");
- out[0] = '\0';
- return 0;
- }
+ out[0] = '\0';
- row = sqlsocket->row;
- if (row == NULL) {
- DEBUG("sqlippool_query1: SQL query did not return any results");
- out[0] = '\0';
- return 0;
- }
+ if (!rlm_sql_fetch_row(sqlsocket, data->sql_inst)) {
+ if (sqlsocket->row) {
+ if (sqlsocket->row[0]) {
+ if ((rlen = strlen(sqlsocket->row[0])) < outlen) {
+ strcpy(out, sqlsocket->row[0]);
+ retval = rlen;
+ } else DEBUG("sqlippool_query1: insufficient string space");
+ } else DEBUG("sqlippool_query1: row[0] returned NULL");
+ } else DEBUG("sqlippool_query1: SQL query did not return any results");
+ } else DEBUG("sqlippool_query1: SQL query did not succeed");
- if (row[0] == NULL){
- DEBUG("sqlippool_query1: row[0] returned NULL");
- out[0] = '\0';
- return 0;
- }
-
- r = strlen(row[0]);
- if (r >= outlen){
- DEBUG("sqlippool_query1: insufficient string space");
- out[0] = '\0';
- return 0;
- }
-
- strncpy(out, row[0], r);
- out[r] = '\0';
-
- return r;
+ (data->sql_inst->module->sql_finish_select_query)(sqlsocket, data->sql_inst->config);
+ return retval;
}
static int sqlippool_initialize_sql(void * instance)
}
- /* Reminder to self </tuyan>
- * please make it work with the ipv6 address'
- * before the freeradius v2 release
+ /*
+ * FIXME: Make it work with the ipv6 addresses
*/
if ((ip_hton(allocation, AF_INET, &ipaddr) < 0) ||
((ip_allocation = ipaddr.ipaddr.ip4addr.s_addr) == INADDR_NONE))