/[radius]/radius/radiusd/sql.c
ViewVC logotype

Diff of /radius/radiusd/sql.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.54 by gray, Fri Aug 2 11:18:43 2002 UTC revision 1.55 by gray, Fri Apr 18 05:27:10 2003 UTC
# Line 1  Line 1 
1  /* This file is part of GNU RADIUS.  /* This file is part of GNU Radius.
2     Copyright (C) 2000,2001, Sergey Poznyakoff     Copyright (C) 2000,2001,2002,2003 Sergey Poznyakoff
3        
4     This program is free software; you can redistribute it and/or modify     GNU Radius is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.     (at your option) any later version.
8        
9     This program is distributed in the hope that it will be useful,     GNU Radius is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.     GNU General Public License for more details.
13        
14     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software Foundation,     along with GNU Radius; if not, write to the Free Software Foundation,
16     Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */     Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17    
18  #define RADIUS_MODULE_SQL_C  #define RADIUS_MODULE_SQL_C
 #ifndef lint  
 static char rcsid[] =  
 "@(#) $Id$";  
 #endif  
19    
20  #if defined(HAVE_CONFIG_H)  #if defined(HAVE_CONFIG_H)
21  # include <config.h>  # include <config.h>
# Line 43  static void detach_sql_connection(int ty Line 39  static void detach_sql_connection(int ty
39    
40  static char *getline();  static char *getline();
41  static int get_boolean(char *str, int *retval);  static int get_boolean(char *str, int *retval);
 static int get_unsigned(char *str, unsigned *retval);  
42  static char * sql_digest(SQL_cfg *cfg);  static char * sql_digest(SQL_cfg *cfg);
43  static int sql_digest_comp(char *d1, char *d2);  static int sql_digest_comp(char *d1, char *d2);
44  static int sql_cfg_comp(SQL_cfg *a, SQL_cfg *b);  static int sql_cfg_comp(SQL_cfg *a, SQL_cfg *b);
# Line 51  static int chop(char *str); Line 46  static int chop(char *str);
46  static void sql_flush();  static void sql_flush();
47    
48  SQL_cfg sql_cfg;  SQL_cfg sql_cfg;
49    static struct sql_connection *sql_conn[SQL_NSERVICE];
50    
51  #define STMT_SERVER                 1  #define STMT_SERVER                 1
52  #define STMT_PORT                   2  #define STMT_PORT                   2
# Line 82  static char *cur_line, *cur_ptr; Line 78  static char *cur_line, *cur_ptr;
78  static struct obstack parse_stack;  static struct obstack parse_stack;
79  static int stmt_type;  static int stmt_type;
80    
 static pthread_key_t sql_conn_key[SQL_NSERVICE];  
 static pthread_once_t sql_conn_key_once = PTHREAD_ONCE_INIT;  
   
81  struct keyword sql_keyword[] = {  struct keyword sql_keyword[] = {
82          "server",             STMT_SERVER,          "server",             STMT_SERVER,
83          "port",               STMT_PORT,          "port",               STMT_PORT,
# Line 117  struct keyword sql_keyword[] = { Line 110  struct keyword sql_keyword[] = {
110   * Chop off trailing whitespace. Return length of the resulting string   * Chop off trailing whitespace. Return length of the resulting string
111   */   */
112  int  int
113  chop(str)  chop(char *str)
         char *str;  
114  {  {
115          int len;          int len;
116    
# Line 183  getline() Line 175  getline()
175  }  }
176    
177  int  int
178  get_boolean(str, retval)  get_boolean(char *str, int *retval)
         char *str;  
         int *retval;  
179  {  {
180          if (strcmp(str, "yes") == 0)          if (strcmp(str, "yes") == 0)
181                  *retval = 1;                  *retval = 1;
# Line 197  get_boolean(str, retval) Line 187  get_boolean(str, retval)
187  }  }
188    
189  char *  char *
190  sql_digest(cfg)  sql_digest(SQL_cfg *cfg)
         SQL_cfg *cfg;  
191  {  {
192          int length;          int length;
193          char *digest, *p;          char *digest, *p;
# Line 246  sql_digest(cfg) Line 235  sql_digest(cfg)
235  }  }
236    
237  int  int
238  sql_digest_comp(d1, d2)  sql_digest_comp(char *d1, char *d2)
         char *d1, *d2;  
239  {  {
240          int len;          int len;
241    
# Line 258  sql_digest_comp(d1, d2) Line 246  sql_digest_comp(d1, d2)
246  }  }
247    
248  int  int
249  sql_cfg_comp(a, b)  sql_cfg_comp(SQL_cfg *a, SQL_cfg *b)
         SQL_cfg *a, *b;  
250  {  {
251          char *dig1, *dig2;          char *dig1, *dig2;
252          int rc;          int rc;
# Line 272  sql_cfg_comp(a, b) Line 259  sql_cfg_comp(a, b)
259          return rc;          return rc;
260  }  }
261    
 static void  
 sql_conn_destroy(void *data)  
 {  
         struct sql_connection *conn = data;  
         disp_sql_disconnect(sql_cfg.interface, conn);  
         mem_free(conn);  
 }  
   
 static void  
 sql_conn_key_alloc()  
 {  
         pthread_key_create(&sql_conn_key[SQL_AUTH], sql_conn_destroy);  
         pthread_key_create(&sql_conn_key[SQL_ACCT], sql_conn_destroy);  
 }  
   
 void  
 rad_sql_thread_cleanup(arg)  
         void *arg;  
 {  
         struct obstack *stk = arg;  
           
         obstack_free(stk, NULL);  
   
         disp_sql_drop(sql_cfg.interface,  
                       pthread_getspecific(sql_conn_key[SQL_AUTH]));  
         disp_sql_drop(sql_cfg.interface,  
                       pthread_getspecific(sql_conn_key[SQL_ACCT]));  
 }  
   
262  int  int
263  rad_sql_init()  rad_sql_init()
264  {  {
# Line 310  rad_sql_init() Line 268  rad_sql_init()
268          time_t timeout;          time_t timeout;
269          SQL_cfg new_cfg;          SQL_cfg new_cfg;
270    
         pthread_once(&sql_conn_key_once, sql_conn_key_alloc);  
           
271  #define FREE(a) if (a) efree(a); a = NULL  #define FREE(a) if (a) efree(a); a = NULL
272    
273          bzero(&new_cfg, sizeof(new_cfg));          bzero(&new_cfg, sizeof(new_cfg));
# Line 526  rad_sql_init() Line 482  rad_sql_init()
482  }  }
483    
484  static void  static void
485  radiusd_sql_shutdown_thread(unused)  sql_conn_destroy(struct sql_connection **conn)
         void *unused;  
486  {  {
487          struct sql_connection *conn;          if (*conn) {
488                    disp_sql_disconnect(sql_cfg.interface, *conn);
489          debug(10, ("shutting down sql connections"));                  mem_free(*conn);
490          conn = pthread_getspecific(sql_conn_key[SQL_AUTH]);                  *conn = NULL;
491          if (conn)          }
                 disp_sql_disconnect(SQL_AUTH, conn);  
         conn = pthread_getspecific(sql_conn_key[SQL_ACCT]);  
         if (conn)  
                 disp_sql_disconnect(SQL_ACCT, conn);  
492  }  }
493    
494  void  void
495  radiusd_sql_shutdown()  radiusd_sql_shutdown()
496  {  {
497          request_thread_command(radiusd_sql_shutdown_thread, NULL);          sql_conn_destroy(&sql_conn[SQL_AUTH]);
498            sql_conn_destroy(&sql_conn[SQL_ACCT]);
499  }  }
500    
501  void  void
502  sql_check_config(cfg)  sql_check_config(SQL_cfg *cfg)
         SQL_cfg *cfg;  
503  {  {
504  #define FREE_IF_EMPTY(s) if (s && strcmp(s, "none") == 0) {\  #define FREE_IF_EMPTY(s) if (s && strcmp(s, "none") == 0) {\
505                                  efree(s);\                                  efree(s);\
# Line 618  sql_flush() Line 569  sql_flush()
569  {  {
570          radlog(L_NOTICE,          radlog(L_NOTICE,
571                 _("SQL configuration changed: closing existing connections"));                 _("SQL configuration changed: closing existing connections"));
572          radiusd_flush_queues();          radiusd_flush_queue();
573          radiusd_sql_shutdown();          radiusd_sql_shutdown();
574  }  }
575    
576  struct sql_connection *  struct sql_connection *
577  attach_sql_connection(type)  attach_sql_connection(int type)
         int type;  
578  {  {
579          struct sql_connection *conn;          struct sql_connection *conn;
580          time_t now;          time_t now;
581                    
582          time(&now);          time(&now);
583          conn = pthread_getspecific(sql_conn_key[type]);          conn = sql_conn[type];
584          if (!conn) {          if (!conn) {
585                  debug(1, ("allocating new %d sql connection", type));                  debug(1, ("allocating new %d sql connection", type));
586    
# Line 640  attach_sql_connection(type) Line 590  attach_sql_connection(type)
590                  conn->last_used = now;                  conn->last_used = now;
591                  conn->type = type;                  conn->type = type;
592    
593                  pthread_setspecific(sql_conn_key[type], conn);                  sql_conn[type] = conn;
594          }          }
595    
596          if (!conn->connected || now - conn->last_used > sql_cfg.idle_timeout) {          if (!conn->connected || now - conn->last_used > sql_cfg.idle_timeout) {
# Line 654  attach_sql_connection(type) Line 604  attach_sql_connection(type)
604  }  }
605    
606  void  void
607  detach_sql_connection(type)  detach_sql_connection(int type)
         int type;  
608  {  {
609          struct sql_connection *conn;          struct sql_connection *conn;
610    
611          conn = pthread_getspecific(sql_conn_key[type]);          conn = sql_conn[type];
612          if (!conn)          if (!conn)
613                  return;                  return;
614          debug(1, ("detaching %p [%d]", conn, type));          debug(1, ("detaching %p [%d]", conn, type));
# Line 669  detach_sql_connection(type) Line 618  detach_sql_connection(type)
618                  if (conn->connected)                  if (conn->connected)
619                          disp_sql_disconnect(sql_cfg.interface, conn);                          disp_sql_disconnect(sql_cfg.interface, conn);
620                  mem_free(conn);                  mem_free(conn);
621                  pthread_setspecific(sql_conn_key[type], NULL);                  sql_conn[type] = NULL;
622          }          }
623  }  }
624    
625  /*ARGSUSED*/  /*ARGSUSED*/
626  void  void
627  rad_sql_cleanup(type, req)  rad_sql_cleanup(int type, void *req ARG_UNUSED)
         int type;  
         RADIUS_REQ *req; /* Unused */  
628  {  {
629          if (sql_cfg.active[type])          if (sql_cfg.active[type])
630                  detach_sql_connection(type);                  detach_sql_connection(type);
# Line 687  rad_sql_cleanup(type, req) Line 634  rad_sql_cleanup(type, req)
634   * Perform normal accounting   * Perform normal accounting
635   */   */
636  void  void
637  rad_sql_acct(radreq)  rad_sql_acct(RADIUS_REQ *radreq)
         RADIUS_REQ *radreq;  
638  {  {
639          int rc, count;          int rc, count;
640          int status;          int status;
# Line 712  rad_sql_acct(radreq) Line 658  rad_sql_acct(radreq)
658    
659          conn = attach_sql_connection(SQL_ACCT);          conn = attach_sql_connection(SQL_ACCT);
660          obstack_init(&stack);          obstack_init(&stack);
         pthread_cleanup_push(rad_sql_thread_cleanup, &stack);  
661    
662          switch (status) {          switch (status) {
663          case DV_ACCT_STATUS_TYPE_START:          case DV_ACCT_STATUS_TYPE_START:
# Line 798  rad_sql_acct(radreq) Line 743  rad_sql_acct(radreq)
743                             count);                             count);
744          }          }
745    
         pthread_cleanup_pop(0);  
746          obstack_free(&stack, NULL);          obstack_free(&stack, NULL);
747  }  }
748    
749    
750  char *  char *
751  rad_sql_pass(req, authdata)  rad_sql_pass(RADIUS_REQ *req, char *authdata)
         RADIUS_REQ *req;  
         char *authdata;  
752  {  {
753          char *mysql_passwd;          char *mysql_passwd;
754          struct sql_connection *conn;          struct sql_connection *conn;
# Line 831  rad_sql_pass(req, authdata) Line 773  rad_sql_pass(req, authdata)
773          avl_delete(&req->request, DA_AUTH_DATA);          avl_delete(&req->request, DA_AUTH_DATA);
774                    
775          conn = attach_sql_connection(SQL_AUTH);          conn = attach_sql_connection(SQL_AUTH);
         pthread_cleanup_push(rad_sql_thread_cleanup, &stack);  
776          mysql_passwd = disp_sql_getpwd(sql_cfg.interface, conn, query);          mysql_passwd = disp_sql_getpwd(sql_cfg.interface, conn, query);
         pthread_cleanup_pop(0);  
777                    
778          if (mysql_passwd)          if (mysql_passwd)
779                  chop(mysql_passwd);                  chop(mysql_passwd);
# Line 843  rad_sql_pass(req, authdata) Line 783  rad_sql_pass(req, authdata)
783          return mysql_passwd;          return mysql_passwd;
784  }  }
785    
 struct cleanup_data {  
         struct sql_connection *conn;  
         void *data;  
 };  
   
 void  
 rad_sql_data_cleanup(arg)  
         void *arg;  
 {  
         struct cleanup_data *p = arg;  
         disp_sql_free(sql_cfg.interface, p->conn, p->data);  
 }  
           
786  int  int
787  rad_sql_checkgroup(req, groupname)  rad_sql_checkgroup(req, groupname)
788          RADIUS_REQ *req;          RADIUS_REQ *req;
# Line 867  rad_sql_checkgroup(req, groupname) Line 794  rad_sql_checkgroup(req, groupname)
794          char *p;          char *p;
795          char *query;          char *query;
796          struct obstack stack;          struct obstack stack;
         struct cleanup_data cleanup_data;  
797                    
798          if (sql_cfg.doauth == 0 || sql_cfg.group_query == NULL)          if (sql_cfg.doauth == 0 || sql_cfg.group_query == NULL)
799                  return -1;                  return -1;
# Line 877  rad_sql_checkgroup(req, groupname) Line 803  rad_sql_checkgroup(req, groupname)
803                  return -1;                  return -1;
804    
805          obstack_init(&stack);          obstack_init(&stack);
         pthread_cleanup_push(rad_sql_thread_cleanup, &stack);  
806                    
807          query = radius_xlate(&stack, sql_cfg.group_query, req, NULL);          query = radius_xlate(&stack, sql_cfg.group_query, req, NULL);
808    
809          data = disp_sql_exec(sql_cfg.interface, conn, query);          data = disp_sql_exec(sql_cfg.interface, conn, query);
810    
         cleanup_data.conn = conn;  
         cleanup_data.data = data;  
         pthread_cleanup_push(rad_sql_data_cleanup, &cleanup_data);  
           
811          while (rc != 0          while (rc != 0
812                 && disp_sql_next_tuple(sql_cfg.interface, conn, data) == 0) {                 && disp_sql_next_tuple(sql_cfg.interface, conn, data) == 0) {
813                  if ((p = disp_sql_column(sql_cfg.interface, data, 0)) == NULL)                  if ((p = disp_sql_column(sql_cfg.interface, data, 0)) == NULL)
# Line 897  rad_sql_checkgroup(req, groupname) Line 818  rad_sql_checkgroup(req, groupname)
818          }          }
819          disp_sql_free(sql_cfg.interface, conn, data);          disp_sql_free(sql_cfg.interface, conn, data);
820                    
         pthread_cleanup_pop(0);  
         pthread_cleanup_pop(0);  
           
821          obstack_free(&stack, NULL);          obstack_free(&stack, NULL);
822          return rc;          return rc;
823  }  }
824    
825  static int rad_sql_retrieve_pairs(struct sql_connection *conn,  static int
826                                    char *query,  rad_sql_retrieve_pairs(struct sql_connection *conn,
827                                    VALUE_PAIR **return_pairs,                         char *query,
828                                    int op_too);                         VALUE_PAIR **return_pairs,
829                           int op_too)
 int  
 rad_sql_retrieve_pairs(conn, query, return_pairs, op_too)  
         struct sql_connection *conn;  
         char *query;  
         VALUE_PAIR **return_pairs;  
         int op_too;  
830  {  {
831          void *data;          void *data;
832          int i;          int i;
# Line 964  rad_sql_retrieve_pairs(conn, query, retu Line 876  rad_sql_retrieve_pairs(conn, query, retu
876  }  }
877    
878  int  int
879  rad_sql_reply_attr_query(req, reply_pairs)  rad_sql_reply_attr_query(RADIUS_REQ *req, VALUE_PAIR **reply_pairs)
         RADIUS_REQ *req;  
         VALUE_PAIR **reply_pairs;  
880  {  {
881          struct sql_connection *conn;          struct sql_connection *conn;
882          char *query;          char *query;
# Line 978  rad_sql_reply_attr_query(req, reply_pair Line 888  rad_sql_reply_attr_query(req, reply_pair
888                    
889          conn = attach_sql_connection(SQL_AUTH);          conn = attach_sql_connection(SQL_AUTH);
890          obstack_init(&stack);          obstack_init(&stack);
         pthread_cleanup_push(rad_sql_thread_cleanup, &stack);  
891    
892          query = radius_xlate(&stack, sql_cfg.reply_attr_query, req, NULL);          query = radius_xlate(&stack, sql_cfg.reply_attr_query, req, NULL);
893          rc = rad_sql_retrieve_pairs(conn, query, reply_pairs, 0);          rc = rad_sql_retrieve_pairs(conn, query, reply_pairs, 0);
894    
         pthread_cleanup_pop(0);  
895          obstack_free(&stack, NULL);          obstack_free(&stack, NULL);
896          return rc == 0;          return rc == 0;
897  }  }
898    
899  int  int
900  rad_sql_check_attr_query(req, return_pairs)  rad_sql_check_attr_query(RADIUS_REQ *req, VALUE_PAIR **return_pairs)
         RADIUS_REQ *req;  
         VALUE_PAIR **return_pairs;  
901  {  {
902          struct sql_connection *conn;          struct sql_connection *conn;
903          char *query;          char *query;
# Line 1003  rad_sql_check_attr_query(req, return_pai Line 909  rad_sql_check_attr_query(req, return_pai
909                    
910          conn = attach_sql_connection(SQL_AUTH);          conn = attach_sql_connection(SQL_AUTH);
911          obstack_init(&stack);          obstack_init(&stack);
         pthread_cleanup_push(rad_sql_thread_cleanup, &stack);  
912                    
913          query = radius_xlate(&stack, sql_cfg.check_attr_query, req, NULL);          query = radius_xlate(&stack, sql_cfg.check_attr_query, req, NULL);
914          rc = rad_sql_retrieve_pairs(conn, query, return_pairs, 1);          rc = rad_sql_retrieve_pairs(conn, query, return_pairs, 1);
915                    
         pthread_cleanup_pop(0);  
916          obstack_free(&stack, NULL);          obstack_free(&stack, NULL);
917          return rc == 0;          return rc == 0;
918  }  }

Legend:
Removed from v.1.54  
changed lines
  Added in v.1.55

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26