Logo Search packages:      
Sourcecode: isdnutils version File versions  Download package

radius.c

/*
 * $Id: radius.c,v 1.4 1999/06/21 13:28:52 hipp Exp $
 *
 * Copyright (C) 1996, Matjaz Godec <gody@elgo.si>
 * Copyright (C) 1996, Lars Fenneberg <in5y050@public.uni-hamburg.de>
 *
 */

#include <syslog.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <linux/if.h>
#include <linux/ip_fw.h>
#include <radiusclient.h>
#include <ctype.h>

#include "ipppd.h"
#include "fsm.h"
#include "lcp.h"
#include "upap.h"
#include "chap.h"
#include "ipcp.h"
#include "ccp.h"
#include "pathnames.h"

char *ip_ntoa __P((u_int32_t));
int   bad_ip_adrs __P((u_int32_t));
char  username_realm[255];
char    radius_user[MAXNAMELEN];
char  *make_username_realm ( char * );
static int client_port;
int called_radius_init = 0;
int auth_order = 0 ;
u_int32_t default_hisaddr = 0 ;
u_int32_t default_ouraddr = 0 ;
u_int32_t default_netmask = 0 ;
extern int idle_time_limit ;
extern int session_time_limit ;

void RestartIdleTimer __P((fsm *));
void RestartSessionTimer __P((fsm *));

00045 struct ifstats 
{
      long  rx_bytes;
      long  rx_packets;
      long  tx_bytes;
      long  tx_packets;
};

/***************************************************************************
 *
 *    Name: radius_init
 *
 *    Purpose: Initializing radiusclient 
 *
 ***************************************************************************/
int radius_init() 
{

      static char *func = "radius_init" ;
      
      syslog(LOG_DEBUG, "%s: entered", func ) ;
      
      if (rc_read_config (PATH_RADIUSCLIENT_CONF) != 0)
      {
            syslog(LOG_ERR, "can't load config file %s in %s",
                  PATH_RADIUSCLIENT_CONF, func ) ;
            return (-1) ;
      } ;
      
      if (rc_read_dictionary (rc_conf_str ("dictionary")) != 0)
      {
            syslog(LOG_ERR , "can't load dictionary file %s in %s" ,
                  rc_conf_str ("dictionary") , func ) ;
            return (-1);
      } ;

      if (rc_read_mapfile (rc_conf_str ("mapfile")) != 0)
      {
            syslog(LOG_ERR , "can't load map file %s in %s" ,
                  rc_conf_str ("mapfile") , func ) ;
            return (-1);
      } ;

      called_radius_init = 1;

      return 0;

}

/***************************************************************************
 *
 *    Name: setparams
 *
 *    Purpose: Set's up pppd parameters as received from RADIUS server
 *
 ***************************************************************************/
static int radius_setparams(unit,vp)

      int unit;
      VALUE_PAIR *vp;

{  

      fsm *f = &lcp_fsm[unit];

      ipcp_options *wo = &ipcp_wantoptions[unit];

      u_int32_t remote = 0;

      static char *func = "radius_setparams" ;
      
      syslog(LOG_DEBUG, "%s: entered", func ) ;
      /* 
       * service type (if not framed then quit), 
       * new IP address (RADIUS can define static IP for some users),
       * new netmask (RADIUS can define netmask),
       * idle time limit  ( RADIUS can define idle timeout),
       * session time limit ( RADIUS can limit session time ),
       */

      while (vp) 
      {
            switch (vp->attribute) 
            {
                  case PW_SERVICE_TYPE:
                  /* check for service type     */
                  /* if not FRAMED then exit    */
                  if (vp->lvalue != PW_FRAMED)
                  {
                        syslog (LOG_NOTICE, 
                              "RADIUS wrong service type %ld for %s",
                              vp->lvalue, radius_user );
                        return (-1);
                  }
                  break;

                  case PW_FRAMED_PROTOCOL:
                  /* check for framed protocol type   */
                  /* if not PPP then also exit        */
                  if (vp->lvalue != PW_PPP) 
                  {
                        syslog (LOG_NOTICE, 
                              "RADIUS wrong framed protocol %ld for %s)", 
                              vp->lvalue, radius_user );
                        return (-1);
                  }
                  break;

                  case PW_FRAMED_IP_ADDRESS:

                  /* seting up static IP addresses                  */
                  /* 0xfffffffe means NAS should select an ip address       */
                  /* 0xffffffff means user should be allowed to select one  */
                  /* the last case probably needs special handling ???      */

                  remote = vp->lvalue;
                  if ((remote != 0xfffffffe) && (remote != 0xffffffff)) 
                  {
                        remote = htonl(remote);
                        if (bad_ip_adrs (remote))
                        {
                              syslog (LOG_ERR, 
                                    "RADIUS bad remote IP address %s for %s in %s", 
                                    ip_ntoa (remote), 
                                    radius_user,
                                    func );
                              return (-1);
                        }
                        wo->hisaddr = remote;
                        syslog (LOG_DEBUG,
                                    "Assigned remote static IP %s in %s",
                                          ip_ntoa (remote), func ) ;
                  }
                  break;

                  case PW_FRAMED_IP_NETMASK:
                  /* changing netmask has some problems too       */
                  /* Boy have I looked when I was changed         */
                  /* server's config for USR/TC and none of my    */
                  /* linux TS didn't work any more :(       */
                        netmask = htonl (vp->lvalue);
                        syslog (LOG_DEBUG, 
                              "Assigned netmask %s in %s",
                              ip_ntoa (netmask), func ) ;
                  break;

                  case PW_FRAMED_MTU:
                  /* Don't know if this is OK but what the hack   */
                  /* anyone using this succesfully ?        */
                        lcp_allowoptions[unit].mru = vp->lvalue;
                        syslog (LOG_DEBUG, 
                              "Assigned mtu %ld in %s" ,
                              vp->lvalue , func ) ;
                  break;

                  case PW_IDLE_TIMEOUT:
                  /* This one is operational    */
                  /* have using it for some time      */
                        idle_time_limit = vp->lvalue;
                        if (idle_time_limit != 0) 
                        {
                              RestartIdleTimer ( f );
                              syslog (LOG_DEBUG,
                                    "Assigned idle timeout %ld in %s" ,
                                    vp->lvalue , func ) ;
                        }
                  break;

                  case PW_SESSION_TIMEOUT:       
                  /* This one works also for me */
                        session_time_limit = vp->lvalue;
                        if ( session_time_limit != 0 ) 
                        {
                              RestartSessionTimer ( f );
                              syslog (LOG_DEBUG, 
                              "assigned session timeout %ld in %s" ,
                              session_time_limit, func ) ;
                        }
                  break;

                  case PW_FILTER_ID:
                  /* Idea for future implementation   */
                  /* if we get the name of the filter */
                  /* we can run ipfwadm based script  */
                  /* and have one new functione as the      */
                  /* big boys have. Any volunteers ?  */
                  /* I would look at ip-up imeplementation*/
                  /* and copied it here               */
                        syslog (LOG_NOTICE, 
                              "Dynamic filtering not implemented yet in %s",
                              func );
                  break;
                  
                  case PW_FRAMED_ROUTING:
                  /* Idea for future implementation   */
                  /* Have no idea how to implement    */
                  /* for those who runs gated routing       */
                  /* would go by default if i'm not wrong */
                        syslog (LOG_NOTICE, 
                              "Dynamic routing setup not implemented yet in %s",
                              func );
                  break;
                  

            }
          
            vp = vp->next;
        
      }

      return 0;
}

#ifdef RADIUS_WTMP_LOGGING
/***************************************************************************
 * 
 * Name: radius_wtmp_logging
 *
 * Purpose: write user into wtmp database
 *
 ***************************************************************************/
static void
radius_wtmp_logging(user,unit)
      char  *user;
      int   unit ;

{
      char *tty;

      static char *func = "radius_wtmp_logging" ;

      syslog(LOG_DEBUG, "%s: entered", func ) ;

      syslog(LOG_DEBUG, "user %s logged in", user);

      tty = lns[unit].devnam;   

      if (strncmp(tty, "/dev/", 5) == 0)
      {
            tty += 5;
      }

      logwtmputmp(unit, tty, radius_user, "");

      lns[unit].logged_in = TRUE;

}
#endif

/***************************************************************************
 *
 * Name: radius_buildenv
 *
 * Purpose: 
 *
 ***************************************************************************/
int 
radius_buildenv(vp)
      VALUE_PAIR *vp ;
                      
{
                      
      char name[2048] ;
      char value[2048]; /* more than enough */
      char *p;
      int acount[256];
      int attr;
        
      script_setenv("RADIUS_USER_NAME", radius_user);

      while (vp)
      {
            strcpy(name, "RADIUS_");
            
            if (rc_avpair_tostr(vp, name+7, sizeof(name)-7, value,
                        sizeof(value)) < 0)
            {
                  return 1;
            }
            
            /* Translate "-" => "_" and uppercase*/
            for(p = name; *p; p++)
            {
                  *p = toupper(*p);
                  if (*p == '-') *p = '_';
            }
            
            /* Add to the attribute count and append the var if necessary. */
            if ((attr = vp->attribute) < 256)
            {
                  int count;
                  if ((count = acount[attr]++) > 0)
                  {
                        char buf[10];
                        sprintf(buf, "_%d", count);
                        strcat(name,buf);
                  }
            }
      
            script_setenv(name, value);   
            
            vp = vp->next;
      }
      
      return 0;

}

/****************************************************************************
 *
 * Name: radius_pap_auth 
 *
 * Purpose:  Check the user name and password against RADIUS server 
 *         and add accounting start record of the user if OK.
 *
 * Returns:  UPAP_AUTHNAK: Login failed.
 *         UPAP_AUTHACK: Login succeeded.
 *
 ****************************************************************************/
int
radius_pap_auth (unit, user, passwd, msg, msglen )

      int   unit ;
      char  *user;
      char  *passwd;
      char  **msg;
      int   *msglen;

{
      VALUE_PAIR *send ;
      VALUE_PAIR *received;
      UINT4 av_type;
      static char radius_msg[4096];
      int result;
      static char *func = "radius_pap_auth" ;
      
      syslog(LOG_DEBUG, "%s: entered", func ) ;

      send = NULL ;

      received = NULL;

      client_port = rc_map2id (lns[unit].devnam);

      av_type = PW_FRAMED;
      
      rc_avpair_add (&send, PW_SERVICE_TYPE, &av_type, 0);

      av_type = PW_PPP;

      rc_avpair_add (&send, PW_FRAMED_PROTOCOL, &av_type, 0);

      strncpy ( radius_user , make_username_realm ( user ) , 
                  sizeof (radius_user));
       
      rc_avpair_add (&send, PW_USER_NAME, radius_user , 0);
      rc_avpair_add (&send, PW_USER_PASSWORD, passwd, 0);
      
      result = rc_auth (client_port, send, &received, radius_msg);

      if (result == OK_RC)
      {
            if (radius_setparams(unit,received) < 0)
            {
                  syslog (LOG_ERR,"Error setting params in %s" , 
                        func );
                  result = ERROR_RC;
            }
            else
            {
                  /* Build the environment for ip-up and ip-down */
                  script_unsetenv_prefix("RADIUS_");

                  radius_buildenv(received);
            }
      }
      else
      {
            syslog (LOG_ERR,"Error sending auth request in %s" ,  func );
      }
      
      rc_avpair_free(received);

      rc_avpair_free (send);
      
      *msg = radius_msg;

      *msglen = strlen(radius_msg);

#ifdef RADIUS_WTMP_LOGGING
      if (result == OK_RC)
      {
            radius_wtmp_logging(user,unit);
      }
#endif

      return (result == OK_RC)?UPAP_AUTHACK:UPAP_AUTHNAK;
}

/***************************************************************************
 * 
 * Name: radius_chap_auth 
 *
 * Purpose: CHAP authentication with RADIUS server
 *
 ***************************************************************************/
int
radius_chap_auth (unit,user, remmd, cstate )

      int   unit ;
      char  *user;
      u_char      *remmd;
      chap_state  *cstate;

{

      VALUE_PAIR *send;
      VALUE_PAIR *received;
      UINT4 av_type;
      static char radius_msg[4096];
      int result;
      u_char cpassword[MD5_SIGNATURE_SIZE+1];

      static char *func = "radius_chap_auth" ;
      
      syslog(LOG_DEBUG, "%s: entered", func ) ;

      /* we handle md5 digest at the moment */
      if (cstate->chal_type != CHAP_DIGEST_MD5) 
      {
            syslog(LOG_ERR, "Challenge type not MD5 in %s", func ) ;
            return(-1);
      }

      send = received = NULL;

      client_port = rc_map2id (lns[unit].devnam);

        av_type = PW_FRAMED;

      rc_avpair_add (&send, PW_SERVICE_TYPE, &av_type, 0);

      av_type = PW_PPP;

      rc_avpair_add (&send, PW_FRAMED_PROTOCOL, &av_type, 0);

      rc_avpair_add (&send, PW_USER_NAME, radius_user , 0);

      /*
       * add the CHAP-Password and CHAP-Challenge fields 
       */
       
      cpassword[0] = cstate->chal_id;

      memcpy(&cpassword[1], remmd, MD5_SIGNATURE_SIZE);

      rc_avpair_add(&send, PW_CHAP_PASSWORD, cpassword, MD5_SIGNATURE_SIZE + 1);

      rc_avpair_add(&send, PW_CHAP_CHALLENGE, cstate->challenge, cstate->chal_len); 
            
      result = rc_auth (client_port, send, &received, radius_msg);
       
       
      if (result == OK_RC)
      {
            if (radius_setparams(unit,received) < 0)
            {
                  syslog (LOG_ERR,"Error setting params in %s" , 
                        func );
                  result = ERROR_RC;
            }
      }
      else
      {
            syslog (LOG_ERR,"Error sending auth request in %s" ,  func );
      }

      rc_avpair_free(received);

      rc_avpair_free (send);

#ifdef RADIUS_WTMP_LOGGING
      if (result == OK_RC)
      {
            radius_wtmp_logging(user,unit);
      }
#endif
      
      return (result == OK_RC)?0:(-1);

}

/***************************************************************************
 * 
 * Name: if_getipacct
 *
 * Purpose: reads ip accounting information
 *
 ***************************************************************************/

static void 
if_getipacct(ifname, ifs)

      char  *ifname ;
      struct ifstats *ifs ;

{
      FILE*       f = fopen("/proc/net/ip_acct","r");
      char        buf[256];
      char        acctif[128];
      long        dummy;
      long        direction;
      long        packets;
      long        bytes;
      int         rc;

      static char *func = "if_getipacct" ;
      
      syslog(LOG_DEBUG, "%s: entered", func ) ;

      if (!f)
      {
            syslog(LOG_ERR, "Can't open /proc/net/ip_acct in %s:" , 
                  func ) ;
            return;
      }
      
      fgets(buf, sizeof(buf), f);

      acctif[0] = '\0';

      while (1) 
      {
            rc = fscanf(f, "%ld/%ld->%ld/%ld %s %ld %ld %ld %ld %ld %ld",
                        &dummy,&dummy,&dummy,&dummy,acctif,&dummy,
                        &direction, &dummy, &dummy, &packets, &bytes);

            fgets(buf, sizeof(buf), f);

            if (rc == EOF)
            {
                  break;
            }

            if (rc != 11)
            {
                  break;
            }

            if (strcmp(ifname, acctif) == 0) 
            {

                  syslog(LOG_DEBUG, "Interface <%s> found in %s",
                        acctif, func ) ;
                        
                  if (direction == 1000) /* incoming bytes */ 
                  { 
                        syslog(LOG_DEBUG, 
                              "Incoming bytes/packets = %ld/%ld in %s",
                              bytes, packets, func ) ;
                  
                        ifs->rx_bytes = bytes;
                        ifs->rx_packets = packets;
                  } 
                  else 
                  {
                        syslog(LOG_DEBUG, 
                              "Outgoing bytes/packets = %ld/%ld in %s",
                              bytes, packets, func ) ;

                        ifs->tx_bytes = bytes;
                        ifs->tx_packets = packets;
                  }
            }
      }

      fclose(f);

}

/***************************************************************************
 *
 * Name: radius_ip_acct_on
 *
 * Purpose: set up ip accounting rules for this interface
 *
 ***************************************************************************/
static int 
radius_ip_acct_on ( unit )

      int unit ;

{
      static int sockfd = -1;
      int ret;

      struct ip_fw ip_acct ;

      static char *func = "radius_ip_acct_on" ;

      syslog ( LOG_DEBUG , "%s: entered" , func ) ;

      memset ( &ip_acct , 0x0 , sizeof ( ip_acct ) ) ;

      strncpy ( ip_acct.fw_vianame , lns[unit].ifname, IFNAMSIZ ) ;
      ip_acct.fw_flg |= IP_FW_F_ACCTIN ;
      
      if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) 
      {
            syslog ( LOG_ERR , "ipfwadm: socket creation failed in %s",
                        func );
            return (-1);
      }

      ret = setsockopt( sockfd, IPPROTO_IP, IP_ACCT_INSERT, &ip_acct , 
                              sizeof ( ip_acct) );

      close ( sockfd ) ;

      if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) 
      {
            syslog ( LOG_ERR , "ipfwadm: socket creation failed in %s",
                        func );
            return (-1);
      }

      ip_acct.fw_flg &= ~IP_FW_F_ACCTIN ;
      ip_acct.fw_flg |= IP_FW_F_ACCTOUT ;

      ret = setsockopt( sockfd, IPPROTO_IP, IP_ACCT_INSERT, &ip_acct , 
                                              sizeof ( ip_acct) );

      close ( sockfd ) ;
      
            return ret;

};

/***************************************************************************
 *
 * Name: radius_ip_acct_off
 *
 * Purpose: destroy ip accounting rules for this interface
 *
 ***************************************************************************/
static int 
radius_ip_acct_off ( unit )

      int unit ;

{
      static int sockfd = -1;
      int ret;

      struct ip_fw ip_acct ;

      static char *func = "radius_ip_acct_on" ;

      syslog ( LOG_DEBUG , "%s: entered" , func ) ;

      memset ( &ip_acct , 0x0 , sizeof ( ip_acct ) ) ;

      strncpy ( ip_acct.fw_vianame , lns[unit].ifname, IFNAMSIZ ) ;
      ip_acct.fw_flg |= IP_FW_F_ACCTIN ;

      if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) 
      {
            syslog ( LOG_ERR , "ipfwadm: socket creation failed in %s",
                        func );
            return (-1);
      }

      ret = setsockopt( sockfd, IPPROTO_IP, IP_ACCT_DELETE, &ip_acct , 
                              sizeof ( ip_acct) );

      close ( sockfd ) ;

      if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) 
      {
            syslog ( LOG_ERR , "ipfwadm: socket creation failed in %s",
                        func );
            return (-1);
      }

      ip_acct.fw_flg &= ~IP_FW_F_ACCTIN ;
      ip_acct.fw_flg |= IP_FW_F_ACCTOUT ;

      ret = setsockopt( sockfd, IPPROTO_IP, IP_ACCT_DELETE, &ip_acct , 
                                              sizeof ( ip_acct) );

      close ( sockfd ) ;
      
      return ret;

};

/***************************************************************************
 * 
 * Name: radius_acct_start
 *
 * Purpose: send acct start message to RADIUS server
 *
 ***************************************************************************/
int 
radius_acct_start(unit)

      int unit ;

{
      UINT4       av_type;
      int   result;
      VALUE_PAIR *send = NULL;
      ipcp_options *ho = &ipcp_hisoptions[unit];
      u_int32_t hisaddr ;

      static char *func = "radius_acct_start" ;
      
      syslog(LOG_DEBUG, "%s: entered", func ) ;

      client_port = rc_map2id (lns[unit].devnam);

      lns[unit].start_time = time (NULL);
      
      radius_ip_acct_on ( unit ) ;

      strncpy (lns[unit].session_id, rc_mksid (), 
                  sizeof (lns[unit].session_id) );

      rc_avpair_add (&send, PW_ACCT_SESSION_ID, lns[unit].session_id, 0);
      rc_avpair_add (&send, PW_USER_NAME, radius_user, 0);

      av_type = PW_STATUS_START;
      rc_avpair_add (&send, PW_ACCT_STATUS_TYPE, &av_type, 0);
      
      av_type = PW_FRAMED;
      rc_avpair_add (&send, PW_SERVICE_TYPE, &av_type, 0);
      
      av_type = PW_PPP;
      rc_avpair_add (&send, PW_FRAMED_PROTOCOL, &av_type, 0);

      av_type = PW_RADIUS;
      rc_avpair_add (&send, PW_ACCT_AUTHENTIC, &av_type, 0);

      rc_avpair_add (&send, PW_CALLING_STATION_ID, lns[unit].remote_number, 0);

      av_type = PW_ISDN_SYNC ;
      rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0);

      
        hisaddr = ho->hisaddr;
      av_type = htonl(hisaddr) ;
      rc_avpair_add (&send, PW_FRAMED_IP_ADDRESS , &av_type , 0 ) ;
      
      result = rc_acct (client_port, send);

      rc_avpair_free(send);
      
      if (result != OK_RC) 
      {
            /* RADIUS server could be down so make this a warning */
            syslog (LOG_WARNING, 
                  "Accounting START failed for %s in %s", 
                  radius_user,func );
      }  
      else 
      {
            lns[unit].radius_in = TRUE;

#ifdef RADIUS_WTMP_LOGGING
            if ( lns[unit].logged_in == FALSE ) 
                  radius_wtmp_logging(user,unit);
#endif
      }
      
      return ( result ) ;

}

/***************************************************************************
 * 
 * Name: radius_acct_stop
 *
 * Purpose: send acct stop message to RADIUS server
 *
 ***************************************************************************/
int 
radius_acct_stop (unit)

      int   unit ;
{
      UINT4       av_type;
      int   result;
      VALUE_PAIR  *send = NULL;
      struct      ifstats ifstats;
      ipcp_options *ho = &ipcp_hisoptions[unit];
      u_int32_t hisaddr ;

      static char *func = "radius_acct_stop" ;
      
      syslog(LOG_DEBUG, "%s: entered", func ) ;

      memset ( &ifstats , 0x0 , sizeof ( ifstats )) ;
      
      if_getipacct(lns[unit].ifname, &ifstats);

      radius_ip_acct_off ( unit ) ;
      
      rc_avpair_add (&send, PW_ACCT_SESSION_ID, lns[unit].session_id, 0);
      
      rc_avpair_add (&send, PW_USER_NAME, radius_user, 0);

      av_type = PW_STATUS_STOP;
      rc_avpair_add (&send, PW_ACCT_STATUS_TYPE, &av_type, 0);
      
      av_type = PW_FRAMED;
      rc_avpair_add (&send, PW_SERVICE_TYPE, &av_type, 0);

      av_type = PW_PPP;
      rc_avpair_add (&send, PW_FRAMED_PROTOCOL, &av_type, 0);

      av_type = PW_RADIUS;
      rc_avpair_add (&send, PW_ACCT_AUTHENTIC, &av_type, 0);

      av_type = time (NULL) - lns[unit].start_time;
      rc_avpair_add (&send, PW_ACCT_SESSION_TIME, &av_type, 0);

      av_type = ifstats.tx_bytes ;
      rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0);
               
      av_type = ifstats.rx_bytes ;
      rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0);
      
      av_type = ifstats.tx_packets ;
      rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0);
               
      av_type = ifstats.rx_packets ;
      rc_avpair_add(&send, PW_ACCT_INPUT_PACKETS, &av_type, 0);

      rc_avpair_add (&send, PW_CALLING_STATION_ID, lns[unit].remote_number, 0);

      av_type = PW_ISDN_SYNC ;
      rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0);
      
        hisaddr = ho->hisaddr;
      av_type = htonl(hisaddr) ;
      rc_avpair_add (&send, PW_FRAMED_IP_ADDRESS , &av_type , 0 ) ;     
      
      result = rc_acct (client_port, send);

      rc_avpair_free(send);

      if (result != OK_RC)
      {
            syslog(LOG_ERR, 
                  "Accounting STOP failed for %s in %s", 
                  radius_user, func);
      }
    
      lns[unit].radius_in = FALSE;
      
      return ( result ) ;

}


/***************************************************************************
 * 
 * Name: make_username_realm
 *
 * Purpose: makes username_realm from user
 *
 ***************************************************************************/
char 
*make_username_realm ( user )

      char  *user ;

{
      char  *default_realm;   
      static char *func = "radius_acct_stop" ;

      syslog(LOG_DEBUG, "%s: entered", func ) ;
      
      if ( user != NULL ) 
      {
            strncpy (username_realm, user,sizeof (username_realm));
      } 
      else
      {
            strncpy (username_realm, "\0" , sizeof (username_realm));
      }

      default_realm = rc_conf_str ("default_realm");

      if ( (strchr (username_realm, '@') == NULL) && 
            default_realm &&
            (*default_realm != '\0'))
      {
            strncat (username_realm, "@", 
                        sizeof (username_realm));
            strncat (username_realm, default_realm, 
                        sizeof (username_realm));
      }
      
      return ( username_realm ) ;

}

Generated by  Doxygen 1.6.0   Back to index