Wednesday, March 12, 2008

Idea using FreeRadius with Timesten

FreeRADIUS(http://www.freeradius.org/) is the premiere open source RADIUS server.

I need to use freeradius connect Timeten DB. I don't know any idea.

I found "rlm_sql" on freeradius and unixodbc example.

So I have a good idea to create driver to support Timesten on freeradius.(Wish somebody develope it)

Note:
freeradius-server-2.0.2
timesten-7.0.3
SOURCE_DIR = freeradius source
TIMESTEN_DIR=/oracle/product/TimesTen/ttmb/

1. I copied SOURCE_DIR/src/modules/rlm_sql/drivers/rlm_sql_unixodbc to SOURCE_DIR/src/modules/rlm_sql/drivers/rlm_sql_timesten

2. modified rlm_sql_timesten DIR (replaced sql_unixodbc to sql_timesten)
$cd SOURCE_DIR/src/modules/rlm_sql/drivers/rlm_sql_timesten/
$ ls
configure configure.in Makefile Makefile.in sql_timesten.c

- Modified Makefile.in
include ../../../../../Make.inc
INSTDIR = --with-timesten-dir
COMMDIR = $(INSTDIR)/demo/common
CC = gcc
PLATCFLAGS = -Os -finline-functions
LDFLAGS =
INCS = -I$(INSTDIR)/include -I$(COMMDIR)
CSDEFS = -DTTCLIENTSERVER
CFLAGS = $(PLATCFLAGS) $(INCS)
TTLINK = -L$(INSTDIR)/lib -Wl,-rpath,$(INSTDIR)/lib
DCLIBS = $(TTLINK) -ltten $(EXTRALIBS)
CSLIBS = $(TTLINK) -lttclient $(EXTRALIBS)
TARGET = @targetname@
SRCS = sql_timesten.c
RLM_SQL_CFLAGS = @sql_timesten_cflags@ $(INCLTDL) $(INCS)
RLM_SQL_LIBS = @sql_timesten_ldflags@ $(DCLIBS)
#RLM_SQL_LIBS = @sql_timesten_ldflags@ $(CSLIBS)
include ../rules.mak

- Modified sql_timesten.c file (changed code to support ODBC programming http://www.oracle.com/timesten).

#include "rlm_sql.h"

typedef struct rlm_sql_timesten_sock {
SQLHENV env_handle;
SQLHDBC dbc_handle;
SQLHSTMT stmt_handle;
SQL_ROW row;
void *conn;
} rlm_sql_timesten_sock;
.
.
.
static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
rlm_sql_timesten_sock *timesten_sock;
long err_handle;

if (!sqlsocket->conn) {

sqlsocket->conn = (rlm_sql_timesten_sock *)rad_malloc(sizeof rlm_sql_timesten_sock));
if (!sqlsocket->conn) {
return -1;

}
}

timesten_sock = sqlsocket->conn;
memset(timesten_sock, 0, sizeof(*timesten_sock));

/* Allocate Environment */
err_handle = SQLAllocEnv(&timesten_sock->env_handle);

if (sql_state(err_handle, sqlsocket, config)) {

radlog(L_ERR, "rlm_sql_timesten: Unable to allocate an environment handle\n");
SQLFreeEnv(timesten_sock->env_handle);
return -1;

}

/* Allocate Connection */

err_handle = SQLAllocConnect(timesten_sock->env_handle, &timesten_sock->dbc_handle);

if (sql_state(err_handle, sqlsocket, config)) {

radlog(L_ERR, "rlm_sql_timesten: Can't allocate connection handle\n");
SQLFreeEnv(timesten_sock->env_handle);
return -1;

}

/* Set Connect Options */

SQLSetConnectOption(timesten_sock->dbc_handle, SQL_LOGIN_TIMEOUT, 5);

/* Connect to db */

err_handle = SQLConnect(timesten_sock->dbc_handle, (SQLCHAR*) config->sql_db, strlen(config->sql_db), (SQLCHAR*) config->sql_login, strlen(config->sql_login), (SQLCHAR*) config->sql_password,strlen(config->sql_password));

if (sql_state(err_handle, sqlsocket, config)) {

radlog(L_ERR, "rlm_sql_timesten: Connection failed\n");
SQLFreeConnect(timesten_sock->dbc_handle);
SQLFreeEnv(timesten_sock->env_handle);
return -1;

}

timesten_sock->stmt_handle = SQL_NULL_HSTMT;

/* Allocate Statement */
err_handle = SQLAllocStmt(timesten_sock->dbc_handle, &timesten_sock->stmt_handle);

if (sql_state(err_handle, sqlsocket, config)) {
radlog(L_ERR, "rlm_sql_timesten: Can't allocate the statement\n");
SQLDisconnect(timesten_sock->dbc_handle);
SQLFreeConnect(timesten_sock->dbc_handle);
SQLFreeEnv(timesten_sock->env_handle);
return -1;

}

return 0;
}
.
.
.

3. Mofidied SOURCE_SIR/src/modules/rlm_sql/stable file.

rlm_sql_iodbc
rlm_sql_mysql
rlm_sql_postgresql
rlm_sql_oracle
rlm_sql_unixodbc
rlm_sql_timesten

4. Modified SOURCE_DIR/src/main/Makefile.in file.

SUB_MODULES += rlm_sql_db2 rlm_sql_iodbc rlm_sql_mysql
SUB_MODULES += rlm_sql_oracle rlm_sql_postgresql rlm_sql_sybase rlm_sql_unixodbc rlm_sql_timesten

5. installed freeradius

$ cd SOURCE_DIR
$ ./configure --with-timesten-dir=/oracle/product/TimesTen/ttmb
$ make
$ ls src/modules/rlm_sql/drivers/rlm_sql_timesten/
config.log configure Makefile rlm_sql_timesten.la sql_timesten.lo
config.status configure.in Makefile.in sql_timesten.c sql_timesten.o
$ su root
$ make install
$ vi /etc/ld.so.conf
.
.
.
/usr/local/lib
/oracle/product/TimesTen/ttmb/lib/


$ ldconfig

$ ls /usr/local/lib/rlm_sql_timesten.so
/usr/local/lib/rlm_sql_timesten.so

6. example Timesten data source (sys.odbc.ini)

[ttmb_demo3]
Driver=/oracle/product/TimesTen/ttmb/lib/libtten.so
DataStore=/oradata/TimesTen/ttmb_demo3
DatabaseCharacterSet=TH8TISASCII
PermSize=1000
TempSize=1000
UID=timesten_tmp
Authenticate=1
TempWarnThreshold=85
PermWarnThreshold=85

$ ttisql ttmb_demo3
Copyright (c) 1996-2007, Oracle. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
All commands must end with a semicolon character.

connect "DSN=ttmb_demo3";
Enter password for 'timesten_tmp':
Connection successful: DSN=ttmb_demo3;UID=timesten_tmp;DataStore=/oradata/TimesTen/ttmb_demo3;DatabaseCharacterSet=TH8TISASCII;ConnectionCharacterSet=US7ASCII;DRIVER=/oracle/product/TimesTen/ttmb/lib/libtten.so;PermSize=1000;TempSize=1000;PermWarnThreshold=85;TempWarnThreshold=85;TypeMode=0;(Default setting AutoCommit=1)

7. configured FreeRadius

$ cd /usr/local/etc/raddb/
$ cp sql.conf timesten.conf

- Modified timesten.conf file.
.
.
.
database = "timesten"
driver = "rlm_sql_${database}"
server = "localhost"
login = "timesten_tmp"
password = "password"
radius_db = "ttmb_demo3"

8. Edited radiusd.conf file.

$INCLUDE ${confdir}/sql.conf

Replace this line with:

$INCLUDE ${confdir}/timesten.conf

and =>

#
# Look in an SQL database. The schema of the database
# is meant to mirror the "users" file.
#
# See "Authorization Queries" in sql.conf
# sql

Uncomment out the sql entry:

#
# Look in an SQL database. The schema of the database
# is meant to mirror the "users" file.
#
# See "Authorization Queries" in sql.conf
sql
-
$ cd /usr/local/etc/raddb/sql
$ cp -rp oracle/ timesten/

9. Created tables on Timesten DB (Mofified from oracle schema)

CREATE TABLE radacct ( radacctid INT PRIMARY KEY,
acctsessionid VARCHAR(32) NOT NULL,
acctuniqueid VARCHAR(32),
username VARCHAR(64) NOT NULL,
groupname VARCHAR(32) NOT NULL,
realm VARCHAR(30),
nasipaddress VARCHAR(15) NOT NULL,
nasportid VARCHAR(15),
nasporttype VARCHAR(32),
acctstarttime DATE, acctstoptime DATE,
acctsessiontime NUMERIC(19),
acctauthentic VARCHAR(32),
connectinfo_start VARCHAR(50),
connectinfo_stop VARCHAR(50),
acctinputoctets NUMERIC(19),
acctoutputoctets NUMERIC(19),
calledstationid VARCHAR(50),
callingstationid VARCHAR(50),
acctterminatecause VARCHAR(32),
servicetype VARCHAR(32),
framedprotocol VARCHAR(32),
framedipaddress VARCHAR(15),
acctstartdelay NUMERIC(12),
acctstopdelay NUMERIC(12),
XAscendSessionSvrKey VARCHAR(10)
);


CREATE UNIQUE INDEX radacct_idx1
ON radacct(acctsessionid,username,acctstarttime, acctstoptime,nasipaddress,framedipaddress);

CREATE TABLE radcheck (
id INT PRIMARY KEY,
username VARCHAR(30) NOT NULL,
attribute VARCHAR(30),
op VARCHAR(2) NOT NULL,
value VARCHAR(40)
);

CREATE SEQUENCE radcheck_seq START WITH 1 INCREMENT BY 1;

CREATE TABLE radgroupcheck (
id INT PRIMARY KEY,
groupname VARCHAR(20) UNIQUE NOT NULL,
attribute VARCHAR(40),
op CHAR(2) NOT NULL,
value VARCHAR(40)
);

CREATE SEQUENCE radgroupcheck_seq START WITH 1 INCREMENT BY 1;

CREATE TABLE radgroupreply (
id INT PRIMARY KEY,
GroupName VARCHAR(20) UNIQUE NOT NULL,
Attribute VARCHAR(40),
op CHAR(2) NOT NULL,
Value VARCHAR(40)
);

CREATE SEQUENCE radgroupreply_seq START WITH 1 INCREMENT BY 1;

CREATE TABLE radreply (
id INT PRIMARY KEY,
UserName VARCHAR(30) NOT NULL,
Attribute VARCHAR(30),
op CHAR(2) NOT NULL,
Value VARCHAR(40)
);

CREATE INDEX radreply_idx1 ON radreply(UserName);

CREATE SEQUENCE radreply_seq START WITH 1 INCREMENT BY 1;

CREATE TABLE radusergroup (
id INT PRIMARY KEY,
UserName VARCHAR(30) UNIQUE NOT NULL,
GroupName VARCHAR(30)
);

CREATE SEQUENCE radusergroup_seq START WITH 1 INCREMENT BY 1;

CREATE TABLE realmgroup
( id INT PRIMARY KEY,
RealmName VARCHAR(30) UNIQUE NOT NULL,
GroupName VARCHAR(30));

CREATE SEQUENCE realmgroup_seq START WITH 1 INCREMENT BY 1;

CREATE TABLE realms (
id INT PRIMARY KEY,
realmname VARCHAR(64),
nas VARCHAR(128),
authport INT,
options VARCHAR(128));

CREATE SEQUENCE realms_seq START WITH 1 INCREMENT BY 1;

Remark: Timesten does not support Trigger.

10. Inserted Data for Testing

INSERT INTO
radgroupcheck ( ID, GroupName, Attribute, Value, op )
VALUES ( 1, 'easy', 'Auth-Type', 'Local', ':=' )

INSERT INTO
radcheck(ID, UserName, Attribute, Value, op )
VALUES(1, 'easyuser', 'password', 'easypass', '==' )

INSERT INTO
radusergroup(ID, UserName, GroupName )
VALUES(1, 'easyuser', 'easy' )

11. Test

- Start free radius
$ radiusd -X

Listening on authentication address * port 1812
Listening on accounting address * port 1813
Listening on proxy address * port 1814
Ready to process reques

and :

$ radtest easyuser easypass localhost 1 testing123

Sending Access-Request of id 17 to 127.0.0.1 port 1812
User-Name = "easyuser"
User-Password = "easypass"
NAS-IP-Address = 192.168.1.10
NAS-Port = 1

rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=17, length=20


Note: This is only idea to develope for someone use FreeRadius with Timesten



No comments: