2 Verify that this user/password is valid per a database.
3 Return 1 if verified, 0 otherwise.
5 Format of connection string (look like internet URL):
7 db://user:password@hostname/table?name&passwd
9 Example connect to Oracle RDBMS at user 'roger' with password
10 'tiger', to 'host.domain.com' database server, fields name in
11 table is 'name' and 'passwd' in 'oshadow' table:
13 oracle://roger:tiger@host.domain.com/oshadow?name&passwd
17 Add DB support to 'login = db <string>'
18 14-nov-1998 Change Tacacs+ version from 0.95 to 3.0.9
19 18-nov-1998 Added code for Oracle [version 8.0.5]
20 27-nov-1998 Tested with 30'000 usernames Oracle database
21 Added DB support to global configuration
22 'default authentication = db <string>'
23 28-nov-1998 Added code for NULL database %)
24 14-dec-1999 Add code for MySQL and also more check
27 Make *_db_verify() the functions is reenterable
28 More security for connection to database
30 Separate debug logging
31 Perfomance testing on 10000 records in Oracle database
32 (in guide sayd about 3 auth/sec on Ultra 2 - hmm)
34 -------------------------------------------------------
35 fil@artelecom.ru http://twister.pp.ru
37 ****************************************************************************
40 I am added some extra extension. Like MySQL and PostgreSQL database support
41 And change most of lines for use dynamic memory allocation. db_accounting
44 devrim(devrim@gazi.edu.tr)
60 #include "do_author.h" /* for "struct identity" */
75 static int check_db_type TAC_ARGS((char *db_type));
78 /* The databases recognized by this function */
79 #define DEFINED_DB {"null","mysql","pgsql"}
81 int db_verify TAC_ARGS((const char *user, const char *users_passwd, const char *str_conn));
84 db_verify(user, users_passwd, str_conn)
85 const char *user; /* username ... */
86 const char *users_passwd; /* ... and given password */
87 const char *str_conn; /* string connection to database */
90 char *db_pref, *db_user, *db_password;
91 char *db_hostname, *db_table,*db_name,*dbfield_name, *dbfield_passwd;
94 if (debug & DEBUG_PASSWD_FLAG)
95 report(LOG_DEBUG, "verify %s by database at %s", user, str_conn);
97 buffer = db_pref = (char *) tac_malloc( strlen(str_conn) + 1 );
99 strcpy( buffer, str_conn );
101 db_user = (char *)strstr( db_pref, "://" );
102 if( db_user == NULL ){
103 if (debug & DEBUG_PASSWD_FLAG)
104 report(LOG_DEBUG, "Error parse db_user");
110 /* For recognize db authentication database */
112 if (check_db_type(db_pref)) {
113 report(LOG_DEBUG, "%s DB authentication scheme didn't recognize by tac_plus",db_pref);
120 db_password = (char *)strstr( db_user, ":" );
121 if( db_password == NULL ){
122 if (debug & DEBUG_PASSWD_FLAG)
123 report(LOG_DEBUG, "Error parse db_password");
130 db_hostname = (char *)strstr( db_password, "@" );
131 if( db_hostname == NULL ){
132 if (debug & DEBUG_PASSWD_FLAG)
133 report(LOG_DEBUG, "Error parse db_hostname");
140 db_name = (char *)strstr( db_hostname, "/" );
141 if( db_name == NULL ){
142 if (debug & DEBUG_PASSWD_FLAG)
143 report(LOG_DEBUG, "Error parse db_name");
150 db_table = (char *)strstr( db_name, "/" );
151 if( db_table == NULL ){
152 if (debug & DEBUG_PASSWD_FLAG)
153 report(LOG_DEBUG, "Error parse db_table");
160 dbfield_name = (char *)strstr( db_table, "?" );
161 if( dbfield_name == NULL){
162 if (debug & DEBUG_PASSWD_FLAG)
163 report(LOG_DEBUG, "Error parse dbfield_name");
167 *dbfield_name = '\0';
171 dbfield_passwd = (char *)strstr( dbfield_name, "&" );
172 if( dbfield_passwd == NULL){
173 if (debug & DEBUG_PASSWD_FLAG)
174 report(LOG_DEBUG, "Error parse dbfield_passwd");
178 *dbfield_passwd = '\0';
182 /* Parse database connection string */
183 if (debug & DEBUG_PASSWD_FLAG)
184 report(LOG_DEBUG, "db_verify: db_pref=%s, db_user=%s, db_password=%s db_hostname=%s, db_name=%s ,db_table=%s, dbfield_name=%s, dbfield_passwd=%s", db_pref, db_user, db_password, db_hostname, db_name,db_table, dbfield_name, dbfield_passwd);
186 /* Check for empty passwords */
187 if (users_passwd == NULL || *users_passwd == '\0' ||
188 db_password == NULL || *db_password == '\0' ) {
189 if (debug & DEBUG_PASSWD_FLAG)
190 report(LOG_DEBUG, "One from passwords is empty");
197 /* Run database depend function */
198 #if defined(DB_ORACLE)
199 if (!strcmp(db_pref, "oracle")) {
200 ret = oracle_db_verify(
202 db_user, db_password, db_hostname, db_table,
203 dbfield_name, dbfield_passwd);
207 #if defined(DB_MYSQL)
208 if (!strcmp(db_pref, "mysql")) {
209 ret = mysql_db_verify(
211 db_user, db_password, db_hostname, db_name, db_table,
212 dbfield_name, dbfield_passwd);
216 #if defined(DB_PGSQL)
217 if (!strcmp(db_pref, "pgsql")) {
218 ret = pgsql_db_verify(
220 db_user, db_password, db_hostname,db_name, db_table,
221 dbfield_name, dbfield_passwd);
226 if (!strcmp(db_pref, "null")) {
227 ret = null_db_verify(
229 db_user, db_password, db_hostname ,db_table,
230 dbfield_name, dbfield_passwd);
235 if (!strcmp(db_pref, "gdbm")) {
239 free(buffer); /* Free unused memory */
240 return (ret); /* error */
244 int db_acct TAC_ARGS((struct acct_rec *rec));
246 /* Db accounting routine */
249 struct acct_rec *rec;
252 char *db_pref, *db_user, *db_password;
253 char *db_hostname, *db_name,*db_table;
254 char *a_username,*s_name,*c_name,*elapsed_time,*bytes_in,*bytes_out;
257 buffer = db_pref = (char *) tac_malloc( strlen(session.db_acct) + 1 );
259 strcpy( buffer, session.db_acct);
261 db_user = (char *)strstr( db_pref, "://" );
262 if( db_user == NULL ){
263 if (debug & DEBUG_PASSWD_FLAG)
264 report(LOG_DEBUG, "Error parse db_user");
270 /* For recognize db accouting database */
272 if( check_db_type(db_pref) ) {
273 report(LOG_DEBUG, "%s DB accounting scheme didn't recognize by tac_plus",db_pref);
280 db_password = (char *)strstr( db_user, ":" );
281 if( db_password == NULL ){
282 if (debug & DEBUG_PASSWD_FLAG)
283 report(LOG_DEBUG, "Error parse db_password");
290 db_hostname = (char *)strstr( db_password, "@" );
291 if( db_hostname == NULL ){
292 if (debug & DEBUG_PASSWD_FLAG)
293 report(LOG_DEBUG, "Error parse db_hostname");
300 db_name = (char *)strstr( db_hostname, "/" );
301 if( db_name == NULL ){
302 if (debug & DEBUG_PASSWD_FLAG)
303 report(LOG_DEBUG, "Error parse db_name");
310 db_table = (char *)strstr( db_name, "/" );
311 if( db_table == NULL ){
312 if (debug & DEBUG_PASSWD_FLAG)
313 report(LOG_DEBUG, "Error parse db_table");
320 /* Find some attributes for accounting */
321 a_username=rec->identity->username;
322 if (a_username==NULL ) {
323 if (debug & DEBUG_PASSWD_FLAG)
324 report(LOG_DEBUG,"db_acct: Can't find username!");
328 s_name=rec->identity->NAS_name;
330 if (debug & DEBUG_PASSWD_FLAG)
331 report(LOG_DEBUG,"db_acct: Can't find NAS name!");
335 c_name=find_attr_value("addr", rec->args, rec->num_args);
337 if (debug & DEBUG_PASSWD_FLAG)
338 report(LOG_DEBUG,"db_acct: Can't find client adress!");
339 /* Can't find client adress so give NAC_address attribute value */
340 c_name=rec->identity->NAC_address;
342 elapsed_time=find_attr_value("elapsed_time", rec->args, rec->num_args);
343 if (elapsed_time==NULL) {
344 if (debug & DEBUG_PASSWD_FLAG)
345 report(LOG_DEBUG,"db_acct: Can't get elapsed time!");
349 bytes_in=find_attr_value("bytes_in", rec->args, rec->num_args);
350 if (bytes_in==NULL) bytes_in="0";
351 bytes_out=find_attr_value("bytes_out", rec->args, rec->num_args);
352 if (bytes_out==NULL) bytes_out="0";
355 /* Parse database connection string */
356 if (debug & DEBUG_PASSWD_FLAG)
357 report(LOG_DEBUG, "db_verify: db_pref=%s, db_user=%s,db_password=%s , db_hostname=%s, db_name=%s ,db_table=%s ",
358 db_pref, db_user, db_password,
359 db_hostname, db_name,db_table );
361 /* Check for empty passwords */
362 if (db_user == NULL || db_password == '\0' ) {
363 if (debug & DEBUG_PASSWD_FLAG)
364 report(LOG_DEBUG, "One from passwords is empty");
370 /* Run database depend function */
371 #if defined(DB_ORACLE)
372 if (!strcmp(db_pref, "oracle")) {
373 ret = oracle_db_acct(
374 db_user, db_password, db_hostname, db_name, db_table);
378 #if defined(DB_MYSQL)
379 if (!strcmp(db_pref, "mysql")) {
381 db_user, db_password, db_hostname, db_name, db_table,s_name,c_name,a_username,elapsed_time,bytes_in,bytes_out);
385 #if defined(DB_PGSQL)
386 if (!strcmp(db_pref, "pgsql")) {
388 db_user, db_password, db_hostname, db_name, db_table,s_name,c_name,a_username,elapsed_time,bytes_in,bytes_out);
393 if (!strcmp(db_pref, "null")) {
395 db_user, db_password, db_hostname, db_name, db_table,s_name,c_name,a_username,elapsed_time,bytes_in,bytes_out);
399 if (!strcmp(db_pref, "gdbm")) {
404 free(buffer); /* Free unused memory */
405 return (ret); /* error */
409 static int check_db_type TAC_ARGS((char *db_type));
411 /* For checking DB type */
413 check_db_type(db_type)
416 char *dbp[]=DEFINED_DB;
419 for (i=0; dbp[i] ; i++ ) {
420 if(!strcmp(db_type,dbp[i])) {