diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/ChangeLog a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/ChangeLog
new file mode 100644
index 0000000..fa9f650
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/ChangeLog
@@ -0,0 +1,3 @@
+
+
+* Mar 6, 2011: Released version 0.1 of the rlm_sql_ocioracle driver.
diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/Makefile.in a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/Makefile.in
new file mode 100644
index 0000000..5ea8656
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/Makefile.in
@@ -0,0 +1,8 @@
+include ../../../../../Make.inc
+
+TARGET         = @targetname@
+SRCS           = sql_ocioracle.c list.c row.c field.c
+RLM_SQL_CFLAGS = @sql_ocioracle_cflags@ $(INCLTDL)
+RLM_SQL_LIBS   = @sql_ocioracle_ldflags@
+
+include ../rules.mak
diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/README a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/README
new file mode 100644
index 0000000..3502e32
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/README
@@ -0,0 +1,2 @@
+For add sql_ocioracle driver as stable drivers it is needed
+add string "rlm_sql_ocioracle" on file src/modules/rlm_sql/stable.
diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/configure.in a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/configure.in
new file mode 100644
index 0000000..7a5f478
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/configure.in
@@ -0,0 +1,226 @@
+AC_INIT(sql_ocioracle.c)
+AC_REVISION($Revision: 1.10 $)
+AC_DEFUN(modname,[rlm_sql_ocioracle])
+
+AC_ARG_WITH(ocilib, [AC_HELP_STRING([--with-ocilib],
+                                    [path of the Oracle OCI libraries])],
+            [ ocilib="$withval" ], [ ocilib="" ])
+AC_ARG_WITH(ociinc, [AC_HELP_STRING([--with-ociinc],
+                                    [path of the Oracle OCI includes])],
+            [ ociinc="$withval" ], [ ociinc="" ])
+AC_ARG_WITH(ociliblib, [AC_HELP_STRING([--with-ociliblib],
+                                      [path of the opensource ocilib library])],
+            [ ociliblib="$withval" ], [ ocilibliblib="" ])
+AC_ARG_WITH(ocilibinc, [AC_HELP_STRING([--with-ocilibinc],
+                                      [path of the opensource ocilib library includes])],
+            [ ocilibinc="$withval" ], [ ocilibinc="" ])
+
+fail=
+sql_ocioracle_ldflags=
+sql_ocioracle_cflags=
+
+# Checks for programs.
+AC_PROG_CC
+
+
+AC_DEFUN([AC_CC_TRY_FLAG], [
+  AC_MSG_CHECKING([whether gcc understands $1])
+
+  # clean cflags
+  CFLAGS=""
+  ac_save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $1"
+  AC_COMPILE_IFELSE([ ], [ac_cc_flag=yes], [ac_cc_flag=no])
+  CFLAGS="$CFLAGS $ac_save_CFLAGS"
+
+  if test "x$ac_cc_flag" = "xyes"; then
+    ifelse([$2], , :, [$2])
+  else
+    ifelse([$3], , :, [$3])
+  fi
+  AC_MSG_RESULT([$ac_cc_flag])
+])
+
+if test "x$GCC" = "xyes"; then
+  AC_CC_TRY_FLAG([-Wfloat-equal],
+                 [ac_flag_float_equal=yes],
+                 [ac_flag_float_equal=no])
+
+  changequote(,)dnl
+  case " $CFLAGS " in
+  *[\ \	]-Wall[\ \	]*) ;;
+  *) CFLAGS="$CFLAGS -Wall" ;;
+  esac
+
+  case " $CFLAGS " in
+  *[\ \	]-Wchar-subscripts[\ \	]*) ;;
+  *) CFLAGS="$CFLAGS -Wchar-subscripts" ;;
+  esac
+
+  case " $CFLAGS " in
+  *[\ \	]-Wmissing-declarations[\ \	]*) ;;
+  *) CFLAGS="$CFLAGS -Wmissing-declarations" ;;
+  esac
+
+  case " $CFLAGS " in
+  *[\ \	]-Wmissing-prototypes[\ \	]*) ;;
+  *) CFLAGS="$CFLAGS -Wmissing-prototypes" ;;
+  esac
+
+  case " $CFLAGS " in
+  *[\ \	]-Wnested-externs[\ \	]*) ;;
+  *) CFLAGS="$CFLAGS -Wnested-externs" ;;
+  esac
+
+  case " $CFLAGS " in
+  *[\ \	]-Wpointer-arith[\ \ ]*) ;;
+  *) CFLAGS="$CFLAGS -Wpointer-arith" ;;
+  esac
+
+  case " $CFLAGS " in
+  *[\ \	]-Wcast-align[\ \	]*) ;;
+  *) CFLAGS="$CFLAGS -Wcast-align" ;;
+  esac
+
+  if test "x$ac_flag_float_equal" = "xyes"; then
+    case " $CFLAGS " in
+    *[\ \	]-Wfloat-equal[\ \ ]*) ;;
+    *) CFLAGS="$CFLAGS -Wfloat-equal" ;;
+    esac
+  fi
+
+  case " $CFLAGS " in
+  *[\ \	]-Wsign-compare[\ \	]*) ;;
+  *) CFLAGS="$CFLAGS -Wsign-compare" ;;
+  esac
+
+  if test "x$enable_ansi" = "xyes"; then
+    case " $CFLAGS " in
+    *[\ \	]-ansi[\ \ ]*) ;;
+    *) CFLAGS="$CFLAGS -ansi" ;;
+    esac
+
+    case " $CFLAGS " in
+    *[\ \	]-D_POSIX_C_SOURCE*) ;;
+    *) CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=199309L" ;;
+    esac
+
+    case " $CFLAGS " in
+    *[\ \	]-D_BSD_SOURCE[\ \ ]*) ;;
+    *) CFLAGS="$CFLAGS -D_BSD_SOURCE" ;;
+    esac
+
+    case " $CFLAGS " in
+    *[\ \	]-pedantic[\ \ ]*) ;;
+    *) CFLAGS="$CFLAGS -pedantic" ;;
+    esac
+  fi
+  if test x$enable_gcov = xyes; then
+    case " $CFLAGS " in
+    *[\ \	]-fprofile-arcs[\ \	]*) ;;
+    *) CFLAGS="$CFLAGS -fprofile-arcs" ;;
+    esac
+    case " $CFLAGS " in
+    *[\ \	]-ftest-coverage[\ \ ]*) ;;
+    *) CFLAGS="$CFLAGS -ftest-coverage" ;;
+    esac
+
+  fi
+
+#    dnl enable share -fPIC flag
+#    CFLAGS="$CFLAGS -fPIC"
+  changequote([,])dnl
+fi
+
+# compress spaces in flags
+CFLAGS=`echo "$CFLAGS" | sed -e 's/ +/ /g'`
+
+CFLAGS="$CFLAGS -Wcomment -Wformat -Wnonnull -Wimplicit-int -Wimplicit \
+        -Wmain -Wmissing-braces -Wparentheses -Wsequence-point \
+        -Wreturn-type -Wswitch -Wtrigraphs -Wunused-function \
+        -Wunused-label -Wunused-value \
+        -Wchar-subscripts -Wmissing-declarations -Wmissing-prototypes \
+        -Wnested-externs -Wpointer-arith  \
+        -Wcast-align -Wall"
+
+
+# Check for ORACLE Library
+LDFLAGS_PRE="$LDFLAGS"
+if test x$ocilib != x ; then
+    OCILIB="-L$ocilib"
+    LDFLAGS="$LDFLAGS -L$ocilib -lclntsh -L$ocilib -lnnz10 -L$ocilib -locci"
+fi
+
+AC_CHECK_LIB(clntsh, [ OCIInitialize ], ocilib_present=1,
+             ocilib_present=0)
+ocilib_present=1
+
+if test $ocilib_present -eq 1 ; then
+    OCILIB="$OCILIB -lnnz10 -L$ocilib -locci -L$ocilib -lclntsh"
+    LDFLAGS="$LDFLAGS_PRE"
+else
+    AC_MSG_ERROR("No Oracle libraries founded!!!!")
+fi
+AC_SUBST(OCILIB)
+
+# Check for Opensource Ocilib library
+LDFLAGS_PRE="$LDFLAGS"
+if test x$ociliblib != x ; then
+    OOCILIB="-L$ociliblib"
+    LDFLAGS="$LDFLAGS -L$ociliblib $OCILIB"
+else
+    LDFLAGS="$LDFLAGS $OCILIB"
+fi
+
+AC_CHECK_LIB(ocilib, [ OCI_ConnectionCreate ], oocilib_present=1,
+             oocilib_present=0)
+
+if test $oocilib_present -eq 1 ; then
+    OOCILIB="$OOCILIB -locilib"
+    LDFLAGS="$LDFLAGS_PRE"
+else
+    AC_MSG_ERROR("No Opensource OCI Library founded!!!!")
+fi
+AC_SUBST(OOCILIB)
+
+
+# Check for Oracle includes
+CFLAGS_PRE="$CFLAGS"
+if test x$ociinc != x ; then
+  OCI_INCLUDES="-I$ociinc"
+  CFLAGS="$CFLAGS $OCI_INCLUDES"
+fi
+AC_CHECK_HEADERS([oci.h])
+CFLAGS="$CFLAGS_PRE"
+AC_SUBST(OCI_INCLUDES)
+
+# Check for Opensource OCIlib includes
+CFLAGS_PRE="$CFLAGS"
+if test x$ocilibinc != x ; then
+    OOCILIB_INCLUDES="-I$ocilibinc"
+    CFLAGS="$CFLAGS $OOCILIB_INCLUDES"
+fi
+AC_CHECK_HEADERS([ocilib.h])
+CFLAGS="$CFLAGS_PRE"
+AC_SUBST(OOCILIB_INCLUDES)
+
+sql_ocioracle_cflags="$OOCILIB_INCLUDES $OCI_INCLUDES"
+sql_ocioracle_ldflags="$OOCILIB $OCILIB"
+targetname=modname
+
+dnl Don't change this section.
+if test "x$fail" != x; then
+	if test "x${enable_strict_dependencies}" = xyes; then
+		AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
+	else
+		AC_MSG_WARN([silently not building ]modname[.])
+		AC_MSG_WARN([FAILURE: ]modname[ requires:$fail.]);
+		targetname=
+	fi
+fi
+
+
+AC_SUBST(sql_ocioracle_ldflags)
+AC_SUBST(sql_ocioracle_cflags)
+AC_SUBST(targetname)
+AC_OUTPUT(Makefile)
diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/field.c a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/field.c
new file mode 100644
index 0000000..05812a7
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/field.c
@@ -0,0 +1,312 @@
+/*
+ Copyright (C) 2011  Ge@@ru, geaaru@gmail.com 
+
+ 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; either version 2
+ of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ License:  GPL 2.0
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include "sql_ocioracle.h"
+#include "sql_ocioracle_field.h"
+
+#include <freeradius-devel/radiusd.h>
+
+/**
+ * @return NULL on error
+ */
+rlm_sql_ocioracle_field *
+rlm_sql_ocioracle_field_create (void *closure)
+{
+    rlm_sql_ocioracle_field *ans = NULL;
+
+    ans = rad_malloc(sizeof(rlm_sql_ocioracle_field));
+    if (ans) {
+        ans->closure = closure;
+        ans->colname = NULL;
+        ans->data = NULL;
+        ans->data_len = 0;
+        ans->type = 0;
+    }
+
+    return ans;
+}
+
+/**
+ * @return 1 on error
+ * @return 0 on success
+ */
+int
+rlm_sql_ocioracle_field_destroy (rlm_sql_ocioracle_field *f)
+{
+    if (!f) return 1;
+
+    if (f->colname) {
+        free(f->colname);
+        f->colname = NULL;
+    }
+
+    if (f->data) {
+        free(f->data);
+        f->data = NULL;
+    }
+
+    f->closure = NULL;
+
+    free(f);
+
+    return 0;
+}
+
+/**
+ * @return 1 on error
+ * @return 0 on success
+ */
+int
+rlm_sql_ocioracle_field_set_data (rlm_sql_ocioracle_field *f,
+                                  void *data, size_t size,
+                                  char usevalue)
+{
+    if (!f || !data || f->data || size <= 0) return 1;
+
+    if (usevalue)
+        f->data = data;
+    else {
+        f->data = rad_malloc(size);
+        if (!f->data) return 1;
+        memset(f->data, 0, size);
+        memcpy(f->data, data, size);
+    }
+
+    f->data_len = size;
+
+    return 0;
+}
+
+/**
+ * @return 1 on error
+ * @return 0 on success
+ */
+int
+rlm_sql_ocioracle_field_set_colname (rlm_sql_ocioracle_field *f,
+                                     char *colname, char usevalue)
+{
+    int len = 0;
+
+    if (!f || !colname) return 1;
+
+    if (usevalue)
+        f->colname = colname;
+    else {
+        len = strlen(colname) + 1;
+        f->colname = (char *) rad_malloc(sizeof(char) * len);
+        if (!f->colname) return 1;
+
+        memset(f->colname, 0, len);
+        memcpy(f->colname, colname, len);
+    }
+
+    return 0;
+}
+
+/**
+ * @return NULL on error or if data isn't initialized
+ */
+inline void *
+rlm_sql_ocioracle_field_get_data (rlm_sql_ocioracle_field *f)
+{
+    return (f ? f->data : NULL);
+}
+
+/**
+ * @return NULL on error or if colname isn't initialized
+ */
+inline const char *
+rlm_sql_ocioracle_field_get_colname (rlm_sql_ocioracle_field *f)
+{
+    return (f ? f->colname : NULL);
+}
+
+/**
+ * @return closure of the field
+ */
+inline void *
+rlm_sql_ocioracle_field_get_closure (rlm_sql_ocioracle_field *f)
+{
+    return (f ? f->closure : NULL);
+}
+
+/**
+ * @return 0 on error or if data isn't initialized
+ */
+inline size_t
+rlm_sql_ocioracle_field_get_data_len (rlm_sql_ocioracle_field *f)
+{
+    return (f ? f->data_len : 0);
+}
+
+/**
+ * Set type of the field.
+ * Possible values are:
+ * OCI_CDT_NUMERIC : short, int, long long, double
+ * OCI_CDT_DATETIME : OCI_Date *
+ * OCI_CDT_TEXT : dtext *
+ * OCI_CDT_LONG : OCI_Long *
+ * OCI_CDT_CURSOR : OCI_Statement *
+ * OCI_CDT_LOB : OCI_Lob *
+ * OCI_CDT_FILE : OCI_File *
+ * OCI_CDT_TIMESTAMP : OCI_Timestamp *
+ * OCI_CDT_INTERVAL : OCI_Interval *
+ * OCI_CDT_RAW : void *
+ * OCI_CDT_OBJECT : OCI_Object *
+ * OCI_CDT_COLLECTION : OCI_Coll *
+ * OCI_CDT_REF : OCI_Ref *
+ * @return 1 on error
+ * @return 0 on success
+ */
+int
+rlm_sql_ocioracle_field_set_type (rlm_sql_ocioracle_field *f,
+                                  unsigned int type)
+{
+    if (!f) return 1;
+
+    f->type = type;
+
+    return 0;
+}
+
+/**
+ * @return type of the field or 0 if it isn't initialized or on error
+ */
+inline unsigned int
+rlm_sql_ocioracle_field_get_type (rlm_sql_ocioracle_field *f)
+{
+    return (f ? f->type : 0);
+}
+
+/**
+ * @return 1 on error
+ * @return 0 on success
+ */
+int
+rlm_sql_ocioracle_field_store_data (rlm_sql_ocioracle_field *f,
+                                    OCI_Column *col,
+                                    OCI_Resultset *rs)
+{
+    int number = 0;
+    unsigned int type = 0;
+    unsigned int index = 0;
+    const char *string = NULL;
+    char buffer[256];
+
+    if (!f || !col || !rs) return 1;
+
+    type = OCI_ColumnGetType(col);
+    rlm_sql_ocioracle_field_set_colname(f, (char *) OCI_ColumnGetName(col), 0);
+    rlm_sql_ocioracle_field_set_type(f, type);
+
+    index = OCI_GetColumnIndex(rs, OCI_ColumnGetName(col));
+    if (OCI_IsNull(rs, index))
+        // No data to store
+        return 0;
+
+    switch (type) {
+        case OCI_CDT_TEXT: // dtext *
+            string = OCI_GetString(rs, index);
+            if (rlm_sql_ocioracle_field_set_data(f, (void *) string,
+                                                 strlen(string) + 1, 0))
+                goto error;
+            break;
+        case OCI_CDT_NUMERIC: // short, int, long long, double
+            // Temporary handle all number as int
+            number = OCI_GetInt(rs, index);
+            memset(buffer, 0, 256);
+            snprintf(buffer, 256, "%d", number);
+            if (rlm_sql_ocioracle_field_set_data(f, (void *) buffer,
+                                                 strlen(buffer) + 1, 0))
+                goto error;
+            break;
+        case OCI_CDT_DATETIME: // OCI_Date
+            // For now convert date to string
+        case OCI_CDT_TIMESTAMP: // OCI_Timestamp *
+        case OCI_CDT_LONG: // OCI_Long *
+        case OCI_CDT_LOB: // OCI_Lob
+        case OCI_CDT_FILE: // OCI_File *
+        case OCI_CDT_CURSOR: // OCI_Statement *
+        case OCI_CDT_INTERVAL: // OCI_Interval *
+        case OCI_CDT_RAW: // void *
+        case OCI_CDT_OBJECT: // OCI_Object *
+        case OCI_CDT_COLLECTION: // OCI_Coll *
+        case OCI_CDT_REF: // OCI_Ref *
+        default:
+            radlog(L_ERR, "rlm_sql_ocioracle: type of column %s (%d) not permitted",
+                   (f->colname ? f->colname : ""), type);
+            break;
+    } // end switch
+
+    return 0;
+
+error:
+
+    return 1;
+}
+
+/**
+ * @return NULL on error or if there aren't data for field
+ */
+char *
+rlm_sql_ocioracle_field_dump (rlm_sql_ocioracle_field *f)
+{
+    char *ans = NULL;
+
+    if (!f) return ans;
+
+    switch (f->type) {
+        case OCI_CDT_TEXT: // dtext *
+        case OCI_CDT_NUMERIC: // short, int, long long, double
+            if (f->data) {
+                ans = (char *) rad_malloc(f->data_len);
+                if (!ans) goto error;
+
+                memset(ans, 0, f->data_len);
+                memcpy(ans, f->data, f->data_len);
+            }
+            break;
+        case OCI_CDT_DATETIME: // OCI_Date
+            // For now convert date to string
+        case OCI_CDT_TIMESTAMP: // OCI_Timestamp *
+        case OCI_CDT_LONG: // OCI_Long *
+        case OCI_CDT_LOB: // OCI_Lob
+        case OCI_CDT_FILE: // OCI_File *
+        case OCI_CDT_CURSOR: // OCI_Statement *
+        case OCI_CDT_INTERVAL: // OCI_Interval *
+        case OCI_CDT_RAW: // void *
+        case OCI_CDT_OBJECT: // OCI_Object *
+        case OCI_CDT_COLLECTION: // OCI_Coll *
+        case OCI_CDT_REF: // OCI_Ref *
+        default:
+            break;
+
+    } // end switch
+
+    return ans;
+
+error:
+
+    return NULL;
+}
+
+// vim: ts=4 shiftwidth=4 expandtab
diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/list.c a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/list.c
new file mode 100644
index 0000000..5b43c2f
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/list.c
@@ -0,0 +1,530 @@
+/*
+ Copyright (C) 2011  Ge@@ru, geaaru@gmail.com 
+
+ 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; either version 2
+ of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ License:  GPL 2.0
+*/
+
+#include <stdlib.h>
+#include "sql_ocioracle.h"
+#include "sql_ocioracle_row.h"
+#include "list.h"
+
+#include <freeradius-devel/radiusd.h>
+
+
+/**
+ * @return NULL on error
+ */
+rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_node_create (void *data)
+{
+    rlm_sql_ocioracle_node *ans = NULL;
+
+    ans = (rlm_sql_ocioracle_node *)
+          rad_malloc(sizeof(rlm_sql_ocioracle_node));
+
+    if (ans) {
+        ans->data = data;
+        ans->next = NULL;
+        ans->prev = NULL;
+    }
+
+    return ans;
+}
+
+/**
+ */
+int
+rlm_sql_ocioracle_node_destroy (rlm_sql_ocioracle_node *n)
+{
+    if (!n) return 1;
+
+    n->data = NULL;
+    n->next = NULL;
+    n->prev = NULL;
+
+    free(n);
+
+    return 0;
+}
+
+/**
+ * @return NULL on error
+ */
+rlm_sql_ocioracle_list *
+rlm_sql_ocioracle_list_create (void *closure)
+{
+    rlm_sql_ocioracle_list *ans = NULL;
+
+    ans = (rlm_sql_ocioracle_list *)
+          rad_malloc(sizeof(rlm_sql_ocioracle_list));
+
+    if (ans) {
+        ans->first = ans->last = NULL;
+        ans->size = 0;
+        ans->closure = closure;
+    }
+
+    return ans;
+}
+
+/**
+ * @return 1 on error
+ * @return 0 on success
+ */
+int
+rlm_sql_ocioracle_list_set_closure (rlm_sql_ocioracle_list *l, void *data)
+{
+    if (!l) return 1;
+
+    l->closure = data;
+
+    return 0;
+}
+
+/**
+ * @return 1 on error
+ * @return 0 on success
+ */
+int
+rlm_sql_ocioracle_list_destroy (rlm_sql_ocioracle_list *l)
+{
+    rlm_sql_ocioracle_node *n = NULL;
+
+    if (!l) return 1;
+
+    while (l->first) {
+        n = l->first;
+        l->first = n->next;
+
+        rlm_sql_ocioracle_node_destroy(n);
+    }
+
+    l->last = NULL;
+    l->size = 0;
+    l->closure = NULL;
+
+    free(l);
+
+    return 0;
+}
+
+/**
+ * Append a new node to list.
+ * @return 0 on success
+ * @return 1 on error
+ */
+int
+rlm_sql_ocioracle_list_add_node (rlm_sql_ocioracle_list *l,
+                                 rlm_sql_ocioracle_node *n)
+{
+    if (!l || !n)
+        return 1;
+
+    if (l->last) {
+        n->prev = l->last;
+        l->last = n->prev->next = n;
+    } else
+        l->first = l->last = n;
+
+    l->size++;
+
+    return 0;
+}
+
+/**
+ * Create a new node to list and set data as value of the node.
+ * @return 0 on success
+ * @return 1 on error
+ */
+int
+rlm_sql_ocioracle_list_add_node_data (rlm_sql_ocioracle_list *l, void *data)
+{
+    rlm_sql_ocioracle_node *node = NULL;
+
+    if (!l || !data)
+        return 1;
+
+    node = rlm_sql_ocioracle_node_create(data);
+    if (!node) goto error;
+
+    if (rlm_sql_ocioracle_list_add_node(l, node))
+        goto error;
+
+    return 0;
+
+error:
+
+    if (node)
+        rlm_sql_ocioracle_node_destroy(node);
+
+    return 1;
+}
+
+/**
+ * @return closure of the rlm_sql_ocioracle_list object
+ */
+inline void *
+rlm_sql_ocioracle_list_get_closure (rlm_sql_ocioracle_list *l)
+{
+    return (l ? l->closure : NULL);
+}
+
+/**
+ * @return -1 on error
+ * @return number of node in list
+ */
+inline int
+rlm_sql_ocioracle_list_get_size (rlm_sql_ocioracle_list *l)
+{
+    return (l ? l->size : -1);
+}
+
+/**
+ */
+inline rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_list_get_first (rlm_sql_ocioracle_list *l)
+{
+    return (l ? l->first : NULL);
+}
+
+/**
+ */
+inline rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_list_get_last (rlm_sql_ocioracle_list *l)
+{
+    return (l ? l->last : NULL);
+}
+
+/**
+ */
+inline rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_node_get_next (rlm_sql_ocioracle_node *n)
+{
+    return (n ? n->next : (rlm_sql_ocioracle_node *) NULL);
+}
+
+/**
+ */
+inline rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_node_get_prev (rlm_sql_ocioracle_node *n)
+{
+    return (n ? n->prev : NULL);
+}
+
+/**
+ */
+inline void *
+rlm_sql_ocioracle_node_get_data (rlm_sql_ocioracle_node *n)
+{
+    return (n ? n->data : NULL);
+}
+
+/**
+ * @return 1 on error
+ * @return 0 on success
+ */
+inline int
+rlm_sql_ocioracle_node_set_data (rlm_sql_ocioracle_node *n, void *data)
+{
+    if (!n) return 1;
+
+    n->data = data;
+
+    return 0;
+}
+
+/**
+ * @return 1 if node is on list
+ * @return 0 if node isn't on list
+ * @return -1 on error
+ */
+int
+rlm_sql_ocioracle_list_node_is_onlist (rlm_sql_ocioracle_list *l,
+                                       rlm_sql_ocioracle_node *n)
+{
+    int i;
+    rlm_sql_ocioracle_node *un = NULL;
+
+    if (!l || !n) return -1;
+
+    if (l->size) {
+        for (i = 0, un = l->first; i < l->size;
+             i++, un = (un ? un->next : NULL)) {
+            if (n == un) return 1;
+        } // end for
+    }
+
+    return 0;
+}
+
+/**
+ * \note
+ *  This method works only if data of rlm_sql_ocioracle_node are string.
+ * @return 0 if doesn't exits
+ * @return 1 if exists
+ * @return -1 on error
+ */
+int
+rlm_sql_ocioracle_list_exist_node_string (rlm_sql_ocioracle_list *l, char *str)
+{
+    rlm_sql_ocioracle_node *n = NULL;
+
+    if (!l || !str) return -1;
+
+    n = l->first;
+    while (n) {
+        if (n->data &&
+            !strncmp(str, (char *) n->data,
+                     strlen(str) > strlen((char *) n->data) ?
+                     strlen(str) : strlen((char *)n->data)))
+            return 1;
+        n = n->next;
+    }
+
+    return 0;
+}
+
+/**
+ * Insert on common list commons string found between l1 and l2
+ * (there aren't check for repeated string).
+ * \pre
+ *      input list MUST contains only node with string
+ * @param copy 1 --> copy string
+ *        copy 0 --> use same pointer
+ * @param l1  list input 1
+ * @param l2  list input 2
+ * @param common  target common list where are added common string
+ * @return 0 on success
+ * @return 1 on error
+ */
+int
+rlm_sql_ocioracle_list_string_get_common (rlm_sql_ocioracle_list *l1,
+                                          rlm_sql_ocioracle_list *l2,
+                                          rlm_sql_ocioracle_list *common,
+                                          short copy)
+{
+    int i, ret;
+    rlm_sql_ocioracle_node *n = NULL;
+    char *value = NULL, *copy_value = NULL;
+
+    if (!l1 || !l2 || !common) return 1;
+
+    for (i = 0, n = rlm_sql_ocioracle_list_get_first(l1);
+         i < rlm_sql_ocioracle_list_get_size(l1) && n;
+         i++, n = rlm_sql_ocioracle_node_get_next(n), copy_value = NULL) {
+
+        value = (char *) rlm_sql_ocioracle_node_get_data(n);
+        if (!value) goto error;
+
+        ret = rlm_sql_ocioracle_list_exist_node_string(l2, value);
+        if (ret < 0) goto error;
+
+        if (ret) {
+            if (copy) {
+                copy_value = (char *) rad_malloc(strlen(value) + 1);
+                if (!copy_value) goto error;
+            } else
+                copy_value = value;
+
+            if (rlm_sql_ocioracle_list_add_node_data(common, copy_value))
+                goto error;
+        }
+
+    } // end for i
+
+    return 0;
+
+error:
+
+    if (copy && copy_value)
+        free(copy_value);
+
+    return 1;
+}
+
+/**
+ * @return 0 if doesn't exits
+ * @return 1 if exists
+ * @return -1 on error
+ */
+int
+rlm_sql_ocioracle_list_exist_node_ptr (rlm_sql_ocioracle_list *l, void *ptr)
+{
+    rlm_sql_ocioracle_node *n = NULL;
+
+    if (!l || !ptr) return -1;
+
+    for (n = l->first; n; n = (n ? n->next : NULL))
+        if (ptr == n->data) return 1;
+
+    return 0;
+}
+
+/**
+ * @return NULL on error or now node available
+ * @return deleted node
+ */
+rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_list_del_last_node (rlm_sql_ocioracle_list *l)
+{
+    rlm_sql_ocioracle_node *ans = NULL;
+
+    if (!l) return ans;
+
+    if (l->last) {
+        ans = l->last;
+
+        if (l->last == l->first) {
+            l->last = l->first = NULL;
+        } else {
+            ans->prev->next = NULL;
+            l->last = ans->prev;
+        }
+
+        l->size--;
+    }
+
+    return ans;
+}
+
+/**
+ * @return 1 on error
+ * @return 0 on success (node founded and removed)
+ */
+int
+rlm_sql_ocioracle_list_del_node (rlm_sql_ocioracle_list *l,
+                                 rlm_sql_ocioracle_node *n)
+{
+    rlm_sql_ocioracle_node *node = NULL, *prev = NULL;
+    int notfounded = 1;
+
+    if (!l || !n || !l->size) return 1;
+
+    for (node = l->first; node && l->size;
+         prev = node, node = (node ? node->next : NULL)) {
+        if (node == n) {
+            if (prev) {
+                prev->next = node->next;
+                if (!node->next)
+                    l->last = prev;
+                else
+                    node->next->prev = prev;
+
+            } else {
+                l->first = node->next;
+                if (!node->next)
+                    l->last = NULL;
+                else
+                    node->next->prev = NULL;
+            }
+
+            rlm_sql_ocioracle_node_destroy(node);
+
+            notfounded = 0;
+            l->size--;
+
+            break;
+        }
+    }
+
+    return notfounded;
+}
+
+/**
+ * @return 1 on error
+ * @return 0 on success (node founded and removed)
+ */
+int
+rlm_sql_ocioracle_list_del_node_by_ptr (rlm_sql_ocioracle_list *l, void *ptr)
+{
+    rlm_sql_ocioracle_node *node = NULL, *prev = NULL;
+    void *data = NULL;
+    int notfounded = 1;
+
+    if (!l || !ptr || !l->size) return 1;
+
+    for (node = l->first; node && l->size;
+         prev = node,
+         node = rlm_sql_ocioracle_node_get_next(node)) {
+
+        data = rlm_sql_ocioracle_node_get_data(node);
+        if (!data) return 1;
+
+        if (ptr == data) {
+            if (prev) {
+                prev->next = node->next;
+                if (!node->next)
+                    l->last = prev;
+                else
+                    node->next->prev = prev;
+
+            } else {
+                l->first = node->next;
+                if (!node->next)
+                    l->last = NULL;
+                else
+                    node->next->prev = NULL;
+            }
+
+            rlm_sql_ocioracle_node_destroy(node);
+            notfounded = 0;
+            l->size--;
+
+            break;
+        }
+    }
+
+    return notfounded;
+}
+
+/**
+ * Destroy a list with string and free internal strings.
+ * @return 1 on error
+ * @return 0 on success
+ */
+int
+rlm_sql_ocioracle_list_string_destroy (rlm_sql_ocioracle_list *l)
+{
+    int i;
+    char *value = NULL;
+    rlm_sql_ocioracle_node *n = NULL;
+
+    if (!l) return 1;
+
+    for (i = 0, n = rlm_sql_ocioracle_list_get_first(l);
+         i < rlm_sql_ocioracle_list_get_size(l) && n;
+         i++, n = rlm_sql_ocioracle_node_get_next(n)) {
+
+        value = (char *) rlm_sql_ocioracle_node_get_data(n);
+        if (value)
+            free(value);
+
+        rlm_sql_ocioracle_node_set_data(n, NULL);
+
+    }  // end for i
+
+    if (rlm_sql_ocioracle_list_destroy(l)) goto error;
+
+    return 0;
+
+error:
+
+    return 1;
+}
+
+// vim: ts=4 shiftwidth=4 expandtab
diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/list.h a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/list.h
new file mode 100644
index 0000000..e9ab1b3
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/list.h
@@ -0,0 +1,121 @@
+/*
+ Copyright (C) 2011  Ge@@ru, geaaru@gmail.com 
+
+ 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; either version 2
+ of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ License:  GPL 2.0
+*/
+
+#ifndef  RLM_SQL_OCIORACLE_LIST_H_H
+#define  RLM_SQL_OCIORACLE_LIST_H_H
+
+/**
+ * Node element.
+ */
+struct rlm_sql_ocioracle_node {
+    void *data;
+    rlm_sql_ocioracle_node *next;
+    rlm_sql_ocioracle_node *prev;
+};
+
+/**
+ * List container.
+ */
+struct rlm_sql_ocioracle_list {
+    rlm_sql_ocioracle_node *first;
+    rlm_sql_ocioracle_node *last;
+    int size;
+    void *closure;
+};
+
+// Prototypes
+rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_node_create (void *);
+
+int
+rlm_sql_ocioracle_node_destroy (rlm_sql_ocioracle_node *);
+
+inline rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_node_get_next (rlm_sql_ocioracle_node *);
+
+inline rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_node_get_prev (rlm_sql_ocioracle_node *);
+
+inline void *
+rlm_sql_ocioracle_node_get_data (rlm_sql_ocioracle_node *);
+
+inline int
+rlm_sql_ocioracle_node_set_data (rlm_sql_ocioracle_node *, void *);
+
+rlm_sql_ocioracle_list *
+rlm_sql_ocioracle_list_create(void *);
+
+inline void *
+rlm_sql_ocioracle_list_get_closure (rlm_sql_ocioracle_list *);
+
+int
+rlm_sql_ocioracle_list_set_closure (rlm_sql_ocioracle_list *, void *);
+
+inline int
+rlm_sql_ocioracle_list_get_size (rlm_sql_ocioracle_list *);
+
+inline rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_list_get_first (rlm_sql_ocioracle_list *);
+
+inline rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_list_get_last (rlm_sql_ocioracle_list *);
+
+int
+rlm_sql_ocioracle_list_destroy (rlm_sql_ocioracle_list *);
+
+int
+rlm_sql_ocioracle_list_add_node (rlm_sql_ocioracle_list *,
+                                 rlm_sql_ocioracle_node *);
+
+int
+rlm_sql_ocioracle_list_node_is_onlist(rlm_sql_ocioracle_list *,
+                                      rlm_sql_ocioracle_node *);
+
+int
+rlm_sql_ocioracle_list_exist_node_string(rlm_sql_ocioracle_list *, char *);
+
+int
+rlm_sql_ocioracle_list_exist_node_ptr(rlm_sql_ocioracle_list *, void *);
+
+int
+rlm_sql_ocioracle_list_del_node (rlm_sql_ocioracle_list *,
+                                 rlm_sql_ocioracle_node *);
+
+int
+rlm_sql_ocioracle_list_del_node_by_ptr (rlm_sql_ocioracle_list *, void *);
+
+rlm_sql_ocioracle_node *
+rlm_sql_ocioracle_list_del_last_node (rlm_sql_ocioracle_list *);
+
+int
+rlm_sql_ocioracle_list_add_node_data (rlm_sql_ocioracle_list *, void *);
+
+int
+rlm_sql_ocioracle_list_string_get_common (rlm_sql_ocioracle_list *,
+                                          rlm_sql_ocioracle_list *,
+                                          rlm_sql_ocioracle_list *,
+                                          short);
+
+int
+rlm_sql_ocioracle_list_string_destroy (rlm_sql_ocioracle_list *l);
+
+#endif   /* ----- #ifndef RLM_SQL_OCIORACLE_LIST_H_H  ----- */
+
+// vim: ts=4 shiftwidth=4 expandtab
diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/row.c a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/row.c
new file mode 100644
index 0000000..32d35cd
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/row.c
@@ -0,0 +1,182 @@
+/*
+ Copyright (C) 2011  Ge@@ru, geaaru@gmail.com 
+
+ 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; either version 2
+ of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ License:  GPL 2.0
+*/
+
+#include <stdlib.h>
+#include "sql_ocioracle.h"
+#include "sql_ocioracle_row.h"
+#include "sql_ocioracle_field.h"
+
+#include <freeradius-devel/radiusd.h>
+
+/**
+ * @return NULL on error
+ */
+rlm_sql_ocioracle_row *
+rlm_sql_ocioracle_row_create (int ncolumn, int rowcount,
+                              void *closure)
+{
+    rlm_sql_ocioracle_row *ans = NULL;
+
+    if (ncolumn <= 0 || rowcount < 0) goto error;
+
+    ans = (rlm_sql_ocioracle_row *)
+          rad_malloc(sizeof(rlm_sql_ocioracle_row));
+
+    if (ans) {
+        ans->colnum = ncolumn;
+        ans->closure = closure;
+        ans->rowcount = rowcount;
+
+        ans->data = (rlm_sql_ocioracle_field **)
+                    rad_malloc(sizeof(rlm_sql_ocioracle_field *) *
+                               ncolumn);
+        if (!ans->data) goto error;
+        memset(ans->data, 0, sizeof(rlm_sql_ocioracle_field *) * ncolumn);
+    }
+
+    return ans;
+
+error:
+
+    if (ans) rlm_sql_ocioracle_row_destroy(ans);
+
+    return NULL;
+}
+
+/**
+ * @return 1 on error
+ * @return 0 on success
+ */
+int
+rlm_sql_ocioracle_row_destroy (rlm_sql_ocioracle_row *r)
+{
+    int i;
+
+    if (!r) return 1;
+
+    if (r->data) {
+
+        for (i = 0; i < r->colnum; i++) {
+
+            if (r->data[i]) {
+                rlm_sql_ocioracle_field_destroy(r->data[i]);
+                r->data[i] = NULL;
+            }
+
+        } // end for i
+
+        free(r->data);
+        r->data = NULL;
+    }
+
+    r->colnum = 0;
+    r->rowcount = 0;
+    r->closure = NULL;
+
+    free(r);
+
+    return 0;
+}
+
+/**
+ * @return 1 on error
+ * @return 0 on success
+ * @pre
+ *      Target field position must be not initialized
+ */
+int
+rlm_sql_ocioracle_row_set_field (rlm_sql_ocioracle_row *r,
+                                 rlm_sql_ocioracle_field *f,
+                                 int pos)
+{
+    if (!r || !f || pos < 0 || pos > r->colnum)
+        return 1;
+
+    if (!r->data || r->data[pos]) return 1;
+
+    r->data[pos] = f;
+
+    return 0;
+}
+
+/**
+ * @return NULL on error or if field is not initialized or present.
+ */
+inline rlm_sql_ocioracle_field *
+rlm_sql_ocioracle_row_get_field (rlm_sql_ocioracle_row *r, int pos)
+{
+    return (r && pos >= 0 && pos <= r->colnum ? r->data[pos] : NULL); 
+}
+
+/**
+ * @return closure
+ */
+inline void *
+rlm_sql_ocioracle_row_get_closure (rlm_sql_ocioracle_row *r)
+{
+    return (r ? r->closure : NULL);
+}
+
+/**
+ * @return 0 on error
+ */
+inline int
+rlm_sql_ocioracle_row_get_colnum (rlm_sql_ocioracle_row *r)
+{
+    return (r ? r->colnum : 0);
+}
+
+/**
+ * @return 0 on error
+ */
+inline int
+rlm_sql_ocioracle_row_get_rowcount (rlm_sql_ocioracle_row *r)
+{
+    return (r ? r->rowcount : 0);
+}
+
+/**
+ *  Create results array with strings
+ *  @return 1 on error
+ *  @return 0 on success
+ */
+int
+rlm_sql_ocioracle_row_dump (rlm_sql_ocioracle_row *r, char ***res)
+{
+    int i;
+    char **rr = NULL;
+
+    if (!r || !res) return 1;
+
+    rr = (char **) rad_malloc(sizeof(char *) * r->colnum);
+    if (!rr) return 1;
+
+    memset(rr, 0, sizeof(char *) * r->colnum);
+
+    for (i = 0; i < r->colnum; i++) {
+        rr[i] = rlm_sql_ocioracle_field_dump(r->data[i]);
+    } // end for i
+
+    *res = rr;
+
+    return 0;
+}
+
+// vim: ts=4 shiftwidth=4 expandtab
diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle.c a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle.c
new file mode 100644
index 0000000..fa3885a
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle.c
@@ -0,0 +1,816 @@
+/*
+ *   sql_ocioracle.c Oracle (OCIlib) routines for rlm_sql
+ *
+ *   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; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ *   Copyright 2011  Ge@@ru <geaaru@gmail.com>
+ */
+
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
+
+#include <freeradius-devel/radiusd.h>
+#include <sys/stat.h>
+
+#include "rlm_sql.h"
+#include "sql_ocioracle.h"
+#include "sql_ocioracle_row.h"
+#include "sql_ocioracle_field.h"
+#include "list.h"
+
+static short ocilib_not_initialized = 1;
+
+// Local prototypes
+static int
+sql_release_statement(SQLSOCK *, SQL_CONFIG *);
+
+static int
+sql_reconnect (SQLSOCK *, rlm_sql_ocioracle_sock *, SQL_CONFIG *);
+
+
+/**
+ * Callback used by OCIOracle library
+ */
+static void sql_error_handler_cb(OCI_Error *error) {
+}
+
+/*************************************************************************
+ *
+ *      Function: sql_error
+ *
+ *      Purpose: database specific error. Returns error associated with
+ *               connection
+ *
+ *************************************************************************/
+static const char *sql_error(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+   static char msgbuf[SQLERROR_MSG_BUFFER];
+   rlm_sql_ocioracle_sock *o_sock = NULL;
+
+   o_sock = (rlm_sql_ocioracle_sock *) sqlsocket->conn;
+   if (!o_sock) return "rlm_sql_ocioracle: no connection to db";
+
+   memset((void *) msgbuf, (int)'\0', sizeof(msgbuf));
+
+    if (o_sock->errHandle) {
+        snprintf(msgbuf, SQLERROR_MSG_BUFFER,
+                 "OCICODE = %d\n%s",
+                 (OCI_ErrorGetOCICode(o_sock->errHandle) ?
+                  OCI_ErrorGetOCICode(o_sock->errHandle) :
+                  (OCI_ErrorGetInternalCode(o_sock->errHandle) ?
+                   OCI_ErrorGetInternalCode(o_sock->errHandle) : 0)),
+                 OCI_ErrorGetString(o_sock->errHandle));
+        return msgbuf;
+    }
+
+    return NULL;
+}
+
+/*************************************************************************
+ *
+ *  Function: sql_check_error
+ *
+ *  Purpose: check the error to see if the server is down
+ *
+ *************************************************************************/
+static int sql_check_error(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+    const char *err = NULL;
+
+    err = sql_error(sqlsocket, config);
+
+    if (err) {
+       if ((strstr(err, "ORA-03113") || strstr(err, "ORA-03114"))) {
+          radlog(L_ERR,"rlm_sql_ocioracle: OCI_SERVER_NOT_CONNECTED: %s", err);
+          return SQL_DOWN;
+       }
+    }
+    radlog(L_ERR,"rlm_sql_ocioracle: OCI_SERVER_NORMAL");
+    return -1;
+}
+
+/*************************************************************************
+ *
+ * Function: sql_close
+ *
+ * Purpose: database specific close. Closes an open database
+ *          connection and cleans up any open handles.
+ *
+ *************************************************************************/
+static int sql_close(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+   rlm_sql_ocioracle_sock *o_sock = (rlm_sql_ocioracle_sock *) sqlsocket->conn;
+
+   sql_release_statement(sqlsocket, config);
+
+   if (o_sock->conn) {
+      OCI_ConnectionFree(o_sock->conn);
+      o_sock->conn = NULL;
+   }
+
+   free(o_sock);
+   sqlsocket->conn = NULL;
+
+   return 0;
+}
+
+
+/*************************************************************************
+ *
+ *	Function: sql_init_socket
+ *
+ *	Purpose: Establish connection to the db
+ *
+ *************************************************************************/
+static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+    const char *err = NULL;
+    OCI_Error *errHandle = NULL;
+    rlm_sql_ocioracle_sock *o_sock = NULL;
+
+    // Initialize library
+    if (ocilib_not_initialized) {
+
+        // Temporary handle error without callback
+        // if (!OCI_Initialize(sql_error_handler_cb,
+        //                    OCI_ENV_THREADED | OCI_ENV_CONTEXT)) {
+
+        if (!OCI_Initialize(NULL, NULL,
+                            OCI_ENV_THREADED | OCI_ENV_CONTEXT)) {
+           radlog(L_ERR,
+                  "rlm_sql_ocioracle: Couldn't init Oracle OCI Lib environment (OCI_Initialize())");
+            return -1;
+        }
+        ocilib_not_initialized = 0;
+    }
+
+    // Allocate object
+    if (!sqlsocket->conn) {
+       sqlsocket->conn = (rlm_sql_ocioracle_sock *)
+          rad_malloc(sizeof(rlm_sql_ocioracle_sock));
+       if (!sqlsocket->conn)
+          return -1;
+    }
+    memset(sqlsocket->conn,0,sizeof(rlm_sql_ocioracle_sock));
+    o_sock = sqlsocket->conn;
+
+    o_sock->rows = NULL;
+    o_sock->curr_row = NULL;
+    o_sock->pos = -1;
+    o_sock->rs = NULL;
+    o_sock->cursorHandle = NULL;
+    o_sock->queryHandle = NULL;
+    o_sock->errHandle = NULL;
+    o_sock->results = NULL;
+
+    radlog(L_INFO, "rlm_sql_ocioracle: try to connect to service name %s",
+           config->sql_db);
+
+    // Connect to database
+    o_sock->conn = OCI_ConnectionCreate(config->sql_db,
+                                        config->sql_login,
+                                        config->sql_password,
+                                        OCI_SESSION_DEFAULT);
+    if (!o_sock->conn) {
+       err = sql_error(sqlsocket,config);
+        if (!err) {
+            errHandle = OCI_GetLastError();
+            err = OCI_ErrorGetString(errHandle);
+        }
+        radlog(L_ERR, "rlm_sql_ocioracle: Oracle connection failed: '%s'",
+              (err ? err : "Error description not available"));
+        return -1;
+    }
+
+    // Disable autocommit
+    if (!OCI_SetAutoCommit(o_sock->conn, 0)) {
+       err = sql_error(sqlsocket,config);
+       if (!err) {
+          errHandle = OCI_GetLastError();
+          err = OCI_ErrorGetString(errHandle);
+       }
+       radlog(L_ERR, "rlm_sql_ocioracle: Error on disable autommit '%s'",
+             (err ? err : "Error description not available"));
+       return -1;
+    }
+
+
+    return 0;
+}
+
+/*************************************************************************
+ *
+ * Function: sql_release_statement
+ *
+ * Purpose: Free statement and Resultset data
+ *
+ *************************************************************************/
+static int sql_release_statement(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+    int i;
+    rlm_sql_ocioracle_sock *o_sock = NULL;
+    rlm_sql_ocioracle_node *n = NULL;
+    rlm_sql_ocioracle_row *r = NULL;
+
+    o_sock = (rlm_sql_ocioracle_sock *) (sqlsocket ? sqlsocket->conn : NULL);
+
+    if (o_sock) {
+
+        if (o_sock->cursorHandle) {
+            OCI_StatementFree(o_sock->cursorHandle);
+            o_sock->cursorHandle = NULL;
+        }
+
+        // OCI_Resultset is destroy by OCI_StatementFree
+        o_sock->rs = NULL;
+        // OCI_Error is destroy by OCI_StatementFree
+        o_sock->errHandle = NULL;
+
+
+        if (o_sock->queryHandle) {
+            OCI_StatementFree(o_sock->queryHandle);
+            o_sock->queryHandle = NULL;
+        }
+
+        if (o_sock->results) {
+            r = (rlm_sql_ocioracle_row *)
+                rlm_sql_ocioracle_node_get_data(o_sock->curr_row);
+            for (i = 0; r && i < rlm_sql_ocioracle_row_get_colnum(r); i++) {
+
+                if (o_sock->results[i]) {
+                    free(o_sock->results[i]);
+                    o_sock->results[i] = NULL;
+                }
+
+            } // end for i
+
+            free(o_sock->results);
+            o_sock->results = NULL;
+        }
+
+        o_sock->curr_row = NULL;
+        o_sock->pos = -1;
+
+        if (o_sock->rows) {
+            for (i = 0, n = rlm_sql_ocioracle_list_get_first(o_sock->rows);
+                 i < rlm_sql_ocioracle_list_get_size(o_sock->rows) && n;
+                 i++, n = rlm_sql_ocioracle_node_get_next(n), r = NULL) {
+
+                r = (rlm_sql_ocioracle_row *)
+                    rlm_sql_ocioracle_node_get_data(n);
+
+                if (r) {
+                    rlm_sql_ocioracle_row_destroy(r);
+                    rlm_sql_ocioracle_node_set_data(n, NULL);
+                }
+
+            } // end for i
+
+            rlm_sql_ocioracle_list_destroy(o_sock->rows);
+            o_sock->rows = NULL;
+        }
+    }
+
+    return 0;
+}
+
+/*************************************************************************
+ *
+ *	Function: sql_destroy_socket
+ *
+ *	Purpose: Free socket and private connection data
+ *
+ *************************************************************************/
+static int sql_destroy_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+    if (sqlsocket && sqlsocket->conn) {
+        sql_close(sqlsocket, config);
+        sqlsocket->conn = NULL;
+    }
+
+    return 0;
+}
+
+/*************************************************************************
+ *
+ *	Function: sql_num_fields
+ *
+ *	Purpose: database specific num_fields function. Returns number
+ *               of columns from query
+ *  In some case column number value is 0 if there are problem on PL/SQL procedure
+ *  or other.
+ *
+ *************************************************************************/
+static int sql_num_fields(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+   int count = -1;
+   rlm_sql_ocioracle_sock *o_sock = (sqlsocket ? sqlsocket->conn : NULL);
+   rlm_sql_ocioracle_row *r = NULL;
+
+   if (!o_sock) return -1;
+
+   /* get the number of columns in the select list */
+    if (o_sock->curr_row) {
+        r = (rlm_sql_ocioracle_row *) rlm_sql_ocioracle_node_get_data(o_sock->curr_row);
+        count = rlm_sql_ocioracle_row_get_colnum(r);
+    } else if (o_sock->rs) {
+        count = OCI_GetColumnCount(o_sock->rs);
+        if (!count) {
+            radlog(L_ERR,"rlm_sql_ocioracle: Error retrieving column count in sql_num_fields: %s",
+                sql_error(sqlsocket, config));
+            count = -1;
+        }
+    }
+
+    return count;
+}
+
+/*************************************************************************
+ *
+ * Function: sql_query
+ *
+ * Purpose: Issue a non-SELECT query (ie: update/delete/insert) to
+ *               the database.
+ *  Pre: This query is done with autocommit enable
+ *
+ *************************************************************************/
+static int sql_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) {
+
+    const char *err_str = NULL;
+    char plsqlCursorQuery = 0;
+    int res = 0;
+    rlm_sql_ocioracle_sock *o_sock = NULL;
+
+    o_sock = (rlm_sql_ocioracle_sock *) (sqlsocket ? sqlsocket->conn : NULL);
+    if (!o_sock) {
+       radlog(L_ERR, "rlm_sql_ocioracle: unexpected invalid socket object");
+       return SQL_DOWN;
+    }
+
+    /*if (config->sqltrace) DEBUG(querystr);*/
+    sql_release_statement(sqlsocket, config);
+
+    if (!o_sock->conn || !OCI_IsConnected(o_sock->conn)) {
+
+       // Try to reconnecto to database
+       if (sql_reconnect(sqlsocket, o_sock, config))
+          return SQL_DOWN;
+    }
+
+    // Check if it is a procedure with a returned cursor
+    plsqlCursorQuery = (strstr(querystr, RLM_SQL_OCIORACLE_CURSOR_PROCEDURE_STR) ? 1 : 0);
+
+    o_sock->queryHandle = OCI_StatementCreate(o_sock->conn);
+    if (plsqlCursorQuery)
+        o_sock->cursorHandle = OCI_StatementCreate(o_sock->conn);
+
+    if (!o_sock->queryHandle || (plsqlCursorQuery && !o_sock->cursorHandle)) {
+       radlog(L_ERR,"rlm_sql_ocioracle: create OCI_Statement in sql_query: %s",
+              sql_error(sqlsocket, config));
+       goto error;
+    }
+
+    // Prepare Statement
+    if (!OCI_Prepare(o_sock->queryHandle, querystr)) {
+       radlog(L_ERR,"rlm_sql_ocioracle: prepare failed in sql_query: %s",
+              sql_error(sqlsocket, config));
+       goto error;
+    }
+
+    // Bind Cursor returned statement
+    if (plsqlCursorQuery && !OCI_BindStatement(o_sock->queryHandle,
+                                               MT(RLM_SQL_OCIORACLE_CURSOR_PROCEDURE_STR),
+                                               o_sock->cursorHandle)) {
+       radlog(L_ERR,"rlm_sql_ocioracle: bind return cursor statetement.");
+       goto error;
+    }
+
+    res = OCI_Execute(o_sock->queryHandle);
+
+    o_sock->rs = (plsqlCursorQuery ?
+                  OCI_GetResultset(o_sock->cursorHandle) :
+                  OCI_GetResultset(o_sock->queryHandle));
+
+    if (!res || (plsqlCursorQuery && !o_sock->rs)) {
+       o_sock->errHandle = OCI_GetLastError();
+       err_str = sql_error(sqlsocket, config);
+       radlog(L_ERR,"rlm_sql_ocioracle: execute query failed in sql_query: %s", err_str);
+
+       return sql_check_error(sqlsocket, config);
+    }
+
+    // Commit
+    OCI_Commit(o_sock->conn);
+
+    return 0;
+
+error:
+
+    return sql_check_error(sqlsocket, config);
+}
+
+
+/*************************************************************************
+ *
+ *	Function: sql_select_query
+ *
+ *	Purpose: Issue a select query to the database
+ *
+ *************************************************************************/
+static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) {
+
+   OCI_Column *col = NULL;
+   rlm_sql_ocioracle_sock *o_sock = NULL;
+   rlm_sql_ocioracle_row *r = NULL;
+   rlm_sql_ocioracle_field *f = NULL;
+   const char *err_str = NULL;
+   char plsqlCursorQuery = 0;
+   int res = 0, colnum = 0, i, y;
+
+   o_sock = (rlm_sql_ocioracle_sock *) (sqlsocket ? sqlsocket->conn : NULL);
+   if (!o_sock) {
+      radlog(L_ERR, "rlm_sql_ocioracle: unexpected invalid socket object");
+      return SQL_DOWN;
+   }
+
+   /*if (config->sqltrace) DEBUG(querystr);*/
+   sql_release_statement(sqlsocket, config);
+
+   if (!o_sock->conn || !OCI_IsConnected(o_sock->conn)) {
+       // Try to reconnecto to database
+       if (sql_reconnect(sqlsocket, o_sock, config))
+          return SQL_DOWN;
+   }
+
+   // Check if it is a procedure with a returned cursor
+   plsqlCursorQuery = (strstr(querystr, RLM_SQL_OCIORACLE_CURSOR_PROCEDURE_STR) ? 1 : 0);
+
+   o_sock->queryHandle = OCI_StatementCreate(o_sock->conn);
+   if (plsqlCursorQuery)
+      o_sock->cursorHandle = OCI_StatementCreate(o_sock->conn);
+
+   if (!o_sock->queryHandle || (plsqlCursorQuery && !o_sock->cursorHandle)) {
+      radlog(L_ERR,"rlm_sql_ocioracle: create OCI_Statement in sql_query: %s",
+            sql_error(sqlsocket, config));
+      goto error;
+   }
+
+   // Prepare Statement
+   if (!OCI_Prepare(o_sock->queryHandle, querystr)) {
+      radlog(L_ERR,"rlm_sql_ocioracle: prepare failed in sql_query: %s",
+            sql_error(sqlsocket, config));
+      goto error;
+   }
+
+   // Bind Cursor returned statement
+   if (plsqlCursorQuery && !OCI_BindStatement(o_sock->queryHandle,
+                                              MT(RLM_SQL_OCIORACLE_CURSOR_PROCEDURE_STR),
+                                              o_sock->cursorHandle)) {
+      radlog(L_ERR,"rlm_sql_ocioracle: bind return cursor statetement.");
+      goto error;
+   }
+
+   res = OCI_Execute(o_sock->queryHandle);
+
+   o_sock->rs = (plsqlCursorQuery ?
+         OCI_GetResultset(o_sock->cursorHandle) :
+         OCI_GetResultset(o_sock->queryHandle));
+
+   if (!res || (plsqlCursorQuery && !o_sock->rs)) {
+      o_sock->errHandle = OCI_GetLastError();
+      err_str = sql_error(sqlsocket, config);
+      radlog(L_ERR,"rlm_sql_ocioracle: execute query failed in sql_query: %s", err_str);
+
+      return sql_check_error(sqlsocket, config);
+   }
+
+   /*
+    * Define where the output from fetch calls will go
+    *
+    * This is a gross hack, but it works - we convert
+    * all data to strings for ease of use.  Fortunately, most
+    * of the data we deal with is already in string format.
+    */
+   colnum = sql_num_fields(sqlsocket, config);
+   if (!colnum) {
+      err_str = sql_error(sqlsocket, config); 
+      radlog(L_ERR,"rlm_sql_ocioracle: query failed in sql_select_query: %s", err_str);
+      goto error;
+   }
+
+   // Create rows list
+   o_sock->rows = rlm_sql_ocioracle_list_create(o_sock);
+   if (!o_sock->rows) {
+      radlog(L_ERR,"rlm_sql_ocioracle: error on create list");
+      goto error;
+   }
+
+   for (i = 0; OCI_FetchNext(o_sock->rs); i++, r = NULL) {
+
+      // Create row object
+      r = rlm_sql_ocioracle_row_create(colnum, i, o_sock->rows);
+      if (!r) {
+         radlog(L_ERR, "rlm_sql_ocioracle: error on create row object");
+         goto error;
+      }
+
+      for (y = 1; y <= colnum; y++, col = NULL, f = NULL) {
+
+         col = OCI_GetColumn(o_sock->rs, y);
+         if (!col) {
+            radlog(L_ERR, "rlm_sql_ocioracle: error on column at pos %d (row %d)",
+                  y, i);
+            goto error;
+         }
+
+         f = rlm_sql_ocioracle_field_create(r);
+         if (!f) {
+            radlog(L_ERR, "rlm_sql_ocioracle: error on create field at pos %d (row %d)",
+                  y, i);
+            goto error;
+         }
+
+         if (rlm_sql_ocioracle_field_store_data(f, col, o_sock->rs)) {
+            radlog(L_ERR, "rlm_sql_ocioracle: error on store data field at pos %d (row %d)",
+                  y, i);
+            goto error;
+         }
+
+         if (rlm_sql_ocioracle_row_set_field(r, f, y - 1)) {
+            radlog(L_ERR, "rlm_sql_ocioracle: error on set field on row at pos %d (row %d)",
+                  y, i);
+            goto error;
+         }
+
+      } // end for y
+
+      // Add row to list
+      if (rlm_sql_ocioracle_list_add_node_data(o_sock->rows, r)) {
+         radlog(L_ERR, "rlm_sql_ocioracle: error on add row to list at pos %d", i);
+         goto error;
+      }
+
+   } // end for i
+
+   o_sock->pos = 0;
+   o_sock->curr_row = rlm_sql_ocioracle_list_get_first(o_sock->rows);
+
+   return 0;
+
+error:
+
+   return sql_check_error(sqlsocket, config);
+}
+
+
+/*************************************************************************
+ *
+ * Function: sql_store_result
+ *
+ * Purpose: database specific store_result function. Returns a result
+ *               set for the query.
+ *
+ *************************************************************************/
+static int sql_store_result(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+   /* Not needed for Oracle */
+   return 0;
+}
+
+
+/*************************************************************************
+ *
+ * Function: sql_num_rows
+ *
+ * Purpose: database specific num_rows. Returns number of rows in
+ *          query
+ *
+ *************************************************************************/
+static int sql_num_rows(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+   rlm_sql_ocioracle_sock *o_sock = NULL;
+
+   o_sock = (rlm_sql_ocioracle_sock *) (sqlsocket ?  sqlsocket->conn : NULL);
+
+   return (o_sock && o_sock->rows ? rlm_sql_ocioracle_list_get_size(o_sock->rows) : 0);
+}
+
+
+/*************************************************************************
+ *
+ * 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.
+ *
+ *************************************************************************/
+static int sql_fetch_row (SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+   int ans = 0, i;
+   rlm_sql_ocioracle_row *r = NULL;
+   rlm_sql_ocioracle_sock *o_sock = NULL;
+
+   o_sock = (rlm_sql_ocioracle_sock *) (sqlsocket ?  sqlsocket->conn : NULL);
+   if (!o_sock) {
+      radlog(L_ERR, "rlm_sql_ocioracle: unexpected invalid socket object");
+      return SQL_DOWN;
+   }
+
+   if (!o_sock->conn || !OCI_IsConnected(o_sock->conn)) {
+      radlog(L_ERR, "rlm_sql_ocioracle: Socket not connected");
+      return SQL_DOWN;
+   }
+
+   if (!o_sock->rs) return -1;
+
+   sqlsocket->row = NULL;
+
+   r = (rlm_sql_ocioracle_row *) rlm_sql_ocioracle_node_get_data(o_sock->curr_row);
+
+   if (o_sock->results) { // Fetch local next rows
+
+      // Free results
+      if (o_sock->results) {
+         for (i = 0; r && i < rlm_sql_ocioracle_row_get_colnum(r); i++) {
+
+            if (o_sock->results[i]) {
+               free(o_sock->results[i]);
+               o_sock->results[i] = NULL;
+            }
+
+         } // end for i
+
+         free(o_sock->results);
+         o_sock->results = NULL;
+      }
+
+      o_sock->curr_row = rlm_sql_ocioracle_node_get_next(o_sock->curr_row);
+      r = (rlm_sql_ocioracle_row *) rlm_sql_ocioracle_node_get_data(o_sock->curr_row);
+
+   } // else Fetch currect row: first call of this functio
+
+
+   if (r) {
+      rlm_sql_ocioracle_row_dump(r, &o_sock->results);
+      sqlsocket->row = o_sock->results;
+   } else
+      // No other fetch data
+      ans = -1;
+
+   return ans;
+}
+
+
+
+/*************************************************************************
+ *
+ *	Function: sql_free_result
+ *
+ *	Purpose: database specific free_result. Frees memory allocated
+ *               for a result set
+ *
+ *************************************************************************/
+static int sql_free_result(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+   sql_release_statement(sqlsocket, config);
+
+   return 0;
+}
+
+
+
+/*************************************************************************
+ *
+ *	Function: sql_finish_query
+ *
+ *	Purpose: End the query, such as freeing memory
+ *
+ *************************************************************************/
+static int sql_finish_query(SQLSOCK *sqlsocket, SQL_CONFIG *config)
+{
+   return 0;
+}
+
+
+
+/*************************************************************************
+ *
+ *	Function: sql_finish_select_query
+ *
+ *	Purpose: End the select query, such as freeing memory or result
+ *
+ *************************************************************************/
+static int sql_finish_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+   sql_release_statement(sqlsocket, config);
+
+   return 0;
+}
+
+
+/*************************************************************************
+ *
+ * Function: sql_affected_rows
+ *
+ * Purpose: Return the number of rows affected by the query (update,
+ *          or insert)
+ *
+ *************************************************************************/
+static int sql_affected_rows(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
+
+   return sql_num_rows(sqlsocket, config);
+}
+
+/*************************************************************************
+ *
+ * Function: sql_reconnect
+ *
+ * Purpose: This method must be called when there is an error on connection
+ *          and system try to reconnect without return SQL_DOWN.
+ *
+ * @return 1 on error
+ * @return 0 on success
+ *
+ *************************************************************************/
+static int sql_reconnect (SQLSOCK *sqlsocket,
+                          rlm_sql_ocioracle_sock *o_sock,
+                          SQL_CONFIG *config) {
+
+   const char *err = NULL;
+   OCI_Error *errHandle = NULL;
+
+   // Try to reconnect to database
+   radlog(L_INFO, "rlm_sql_ocioracle: Found an expired connection."
+                  " I try to reconnect to database");
+
+   if (!o_sock || !config)
+      return 1;
+
+   if (o_sock->conn) {
+      OCI_ConnectionFree(o_sock->conn);
+      o_sock->conn = NULL;
+   }
+
+   // Connect to database
+   o_sock->conn = OCI_ConnectionCreate(config->sql_db,
+                                       config->sql_login,
+                                       config->sql_password,
+                                       OCI_SESSION_DEFAULT);
+
+   if (!o_sock->conn) {
+      err = sql_error(sqlsocket,config);
+      if (!err) {
+         errHandle = OCI_GetLastError();
+         err = OCI_ErrorGetString(errHandle);
+      }
+      radlog(L_ERR, "rlm_sql_ocioracle: Oracle connection failed: '%s'",
+            (err ? err : "Error description not available"));
+      return 1;
+   }
+
+   // Disable autocommit
+   if (!OCI_SetAutoCommit(o_sock->conn, 0)) {
+      err = sql_error(sqlsocket,config);
+      if (!err) {
+         errHandle = OCI_GetLastError();
+         err = OCI_ErrorGetString(errHandle);
+      }
+      radlog(L_ERR, "rlm_sql_ocioracle: Error on disable autommit '%s'",
+            (err ? err : "Error description not available"));
+      return 1;
+   }
+
+   return 0;
+}
+
+
+/* Exported to rlm_sql */
+rlm_sql_module_t rlm_sql_ocioracle = {
+   "rlm_sql_ocioracle",
+   sql_init_socket,
+   sql_destroy_socket,
+   sql_query,
+   sql_select_query,
+   sql_store_result,
+   sql_num_fields,
+   sql_num_rows,
+   sql_fetch_row,
+   sql_free_result,
+   sql_error,
+   sql_close,
+   sql_finish_query,
+   sql_finish_select_query,
+   sql_affected_rows
+};
diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle.h a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle.h
new file mode 100644
index 0000000..e3f0f89
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle.h
@@ -0,0 +1,61 @@
+/*
+ Copyright (C) 2011  Ge@@ru, geaaru@gmail.com 
+
+ 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; either version 2
+ of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ License:  GPL 2.0
+*/
+
+
+#ifndef  SQL_OCIORACLE_H
+#define  SQL_OCIORACLE_H
+
+// Opensource OCILib library
+#include <ocilib.h>
+
+#define MAX_DATASTR_LEN 64
+#define RLM_SQL_OCIORACLE_CURSOR_PROCEDURE_STR  ":Ret_Cursor"
+#define SQLERROR_MSG_BUFFER 512
+
+typedef struct rlm_sql_ocioracle_sock rlm_sql_ocioracle_sock;
+typedef struct rlm_sql_ocioracle_row rlm_sql_ocioracle_row;
+typedef struct rlm_sql_ocioracle_field rlm_sql_ocioracle_field;
+typedef struct rlm_sql_ocioracle_list rlm_sql_ocioracle_list;
+typedef struct rlm_sql_ocioracle_node rlm_sql_ocioracle_node;
+
+struct rlm_sql_ocioracle_sock {
+    OCI_Connection  *conn;
+    OCI_Statement   *queryHandle;
+    OCI_Error       *errHandle;
+
+    OCI_Resultset   *rs;
+    // This pointer is used only
+    // for procedure that return cursor
+    OCI_Statement   *cursorHandle;
+
+    char            **results;
+    int             id;
+    int             in_use;
+    struct timeval  tv;
+
+    int              pos;
+    rlm_sql_ocioracle_list *rows;
+    rlm_sql_ocioracle_node *curr_row;
+};
+
+
+#endif   /* ----- #ifndef SQL_OCIORACLE_H  ----- */
+
+// vim: ts=4 shiftwidth=4 expandtab
diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle_field.h a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle_field.h
new file mode 100644
index 0000000..1954b26
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle_field.h
@@ -0,0 +1,79 @@
+/*
+ Copyright (C) 2011  Ge@@ru, geaaru@gmail.com 
+
+ 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; either version 2
+ of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ License:  GPL 2.0
+*/
+
+
+#ifndef  SQL_OCIORACLE_FIELD_H
+#define  SQL_OCIORACLE_FIELD_H
+
+struct rlm_sql_ocioracle_field {
+    void *closure;
+    char *colname;
+    // As slq_oracle module convert all data to string
+    void *data;
+    size_t data_len;
+    unsigned int type;
+};
+
+
+// Prototypes
+rlm_sql_ocioracle_field *
+rlm_sql_ocioracle_field_create (void *);
+
+int
+rlm_sql_ocioracle_field_destroy (rlm_sql_ocioracle_field *);
+
+int
+rlm_sql_ocioracle_field_set_data (rlm_sql_ocioracle_field *,
+                                  void *, size_t, char);
+
+int
+rlm_sql_ocioracle_field_set_colname (rlm_sql_ocioracle_field *,
+                                     char *, char);
+
+inline void *
+rlm_sql_ocioracle_field_get_data (rlm_sql_ocioracle_field *);
+
+inline const char *
+rlm_sql_ocioracle_field_get_colname (rlm_sql_ocioracle_field *);
+
+inline void *
+rlm_sql_ocioracle_field_get_closure (rlm_sql_ocioracle_field *);
+
+inline size_t
+rlm_sql_ocioracle_field_get_data_len (rlm_sql_ocioracle_field *);
+
+int
+rlm_sql_ocioracle_field_set_type (rlm_sql_ocioracle_field *,
+                                  unsigned int);
+
+inline unsigned int
+rlm_sql_ocioracle_field_get_type (rlm_sql_ocioracle_field *);
+
+int
+rlm_sql_ocioracle_field_store_data (rlm_sql_ocioracle_field *,
+                                    OCI_Column *, 
+                                    OCI_Resultset *);
+
+char *
+rlm_sql_ocioracle_field_dump (rlm_sql_ocioracle_field *);
+
+#endif   /* ----- #ifndef SQL_OCIORACLE_FIELD_H  ----- */
+
+// vim: ts=4 shiftwidth=4 expandtab
diff --git b/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle_row.h a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle_row.h
new file mode 100644
index 0000000..a017090
--- /dev/null
+++ a/src/modules/rlm_sql/drivers/rlm_sql_ocioracle/sql_ocioracle_row.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2011  Ge@@ru, geaaru@gmail.com 
+
+ 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; either version 2
+ of the License, or (at your option) any later version.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ License:  GPL 2.0
+*/
+
+
+#ifndef  SQL_OCIORACLE_ROW_H
+#define  SQL_OCIORACLE_ROW_H
+
+struct rlm_sql_ocioracle_row {
+    /// Contains
+    int colnum;
+    /// Contains position of the row
+    int rowcount;
+    rlm_sql_ocioracle_field **data;
+    void *closure;
+};
+
+// Prototypes
+rlm_sql_ocioracle_row *
+rlm_sql_ocioracle_row_create (int, int, void *);
+
+int
+rlm_sql_ocioracle_row_destroy (rlm_sql_ocioracle_row *);
+
+int
+rlm_sql_ocioracle_row_set_field (rlm_sql_ocioracle_row *,
+                                 rlm_sql_ocioracle_field *,
+                                 int);
+
+inline rlm_sql_ocioracle_field *
+rlm_sql_ocioracle_row_get_field (rlm_sql_ocioracle_row *, int);
+
+inline void *
+rlm_sql_ocioracle_row_get_closure (rlm_sql_ocioracle_row *);
+
+inline int
+rlm_sql_ocioracle_row_get_colnum (rlm_sql_ocioracle_row *);
+
+inline int
+rlm_sql_ocioracle_row_get_rowcount (rlm_sql_ocioracle_row *);
+
+int
+rlm_sql_ocioracle_row_dump (rlm_sql_ocioracle_row *, char ***);
+
+#endif   /* ----- #ifndef SQL_OCIORACLE_ROW_H  ----- */
+
+// vim: ts=4 shiftwidth=4 expandtab
