Back to index

nagios-plugins  1.4.16
util.c
Go to the documentation of this file.
00001 /*
00002  *
00003  *     RADIUS
00004  *     Remote Authentication Dial In User Service
00005  *
00006  *
00007  *     Livingston Enterprises, Inc.
00008  *     6920 Koll Center Parkway
00009  *     Pleasanton, CA   94566
00010  *
00011  *     Copyright 1992 Livingston Enterprises, Inc.
00012  *     Copyright 1997 Cistron Internet Services B.V.
00013  *
00014  *     Permission to use, copy, modify, and distribute this software for any
00015  *     purpose and without fee is hereby granted, provided that this
00016  *     copyright and permission notice appear on all copies and supporting
00017  *     documentation, the name of Livingston Enterprises, Inc. not be used
00018  *     in advertising or publicity pertaining to distribution of the
00019  *     program without specific prior permission, and notice be given
00020  *     in supporting documentation that copying and distribution is by
00021  *     permission of Livingston Enterprises, Inc.   
00022  *
00023  *     Livingston Enterprises, Inc. makes no representations about
00024  *     the suitability of this software for any purpose.  It is
00025  *     provided "as is" without express or implied warranty.
00026  *
00027  */
00028 
00029 /*
00030  * util.c     Miscellanous generic functions.
00031  *
00032  */
00033 
00034 char util_sccsid[] =
00035 "@(#)util.c   1.5 Copyright 1992 Livingston Enterprises Inc\n"
00036 "             2.1 Copyright 1997 Cistron Internet Services B.V.";
00037 
00038 #include      <sys/types.h>
00039 #include      <sys/socket.h>
00040 #include      <sys/time.h>
00041 #include      <netinet/in.h>
00042 
00043 #include      <stdio.h>
00044 #include      <stdlib.h>
00045 #include      <netdb.h>
00046 #include      <pwd.h>
00047 #include      <time.h>
00048 #include      <ctype.h>
00049 #include      <signal.h>
00050 
00051 #include      "radiusd.h"
00052 
00053 /*
00054  *     Return a printable host name (or IP address in dot notation)
00055  *     for the supplied IP address.
00056  */
00057 char * ip_hostname(UINT4 ipaddr)
00058 {
00059        struct        hostent *hp;
00060        static char   hstname[128];
00061        UINT4         n_ipaddr;
00062 
00063        n_ipaddr = htonl(ipaddr);
00064        hp = gethostbyaddr((char *)&n_ipaddr, sizeof (struct in_addr), AF_INET);
00065        if (hp == 0) {
00066               ipaddr2str(hstname, ipaddr);
00067               return(hstname);
00068        }
00069        return (char *)hp->h_name;
00070 }
00071 
00072 
00073 /*
00074  *     Return an IP address in host long notation from a host
00075  *     name or address in dot notation.
00076  */
00077 UINT4 get_ipaddr(char *host)
00078 {
00079        struct hostent       *hp;
00080        UINT4         ipstr2long();
00081 
00082        if(good_ipaddr(host) == 0) {
00083               return(ipstr2long(host));
00084        }
00085        else if((hp = gethostbyname(host)) == (struct hostent *)NULL) {
00086               return((UINT4)0);
00087        }
00088        return(ntohl(*(UINT4 *)hp->h_addr));
00089 }
00090 
00091 
00092 /*
00093  *     Check for valid IP address in standard dot notation.
00094  */
00095 int good_ipaddr(char *addr)
00096 {
00097        int    dot_count;
00098        int    digit_count;
00099 
00100        dot_count = 0;
00101        digit_count = 0;
00102        while(*addr != '\0' && *addr != ' ') {
00103               if(*addr == '.') {
00104                      dot_count++;
00105                      digit_count = 0;
00106               }
00107               else if(!isdigit(*addr)) {
00108                      dot_count = 5;
00109               }
00110               else {
00111                      digit_count++;
00112                      if(digit_count > 3) {
00113                             dot_count = 5;
00114                      }
00115               }
00116               addr++;
00117        }
00118        if(dot_count != 3) {
00119               return(-1);
00120        }
00121        else {
00122               return(0);
00123        }
00124 }
00125 
00126 
00127 /*
00128  *     Return an IP address in standard dot notation for the
00129  *     provided address in host long notation.
00130  */
00131 void ipaddr2str(char *buffer, UINT4 ipaddr)
00132 {
00133        int    addr_byte[4];
00134        int    i;
00135        UINT4  xbyte;
00136 
00137        for(i = 0;i < 4;i++) {
00138               xbyte = ipaddr >> (i*8);
00139               xbyte = xbyte & (UINT4)0x000000FF;
00140               addr_byte[i] = xbyte;
00141        }
00142        sprintf(buffer, "%u.%u.%u.%u", addr_byte[3], addr_byte[2],
00143               addr_byte[1], addr_byte[0]);
00144 }
00145 
00146 
00147 /*
00148  *     Return an IP address in host long notation from
00149  *     one supplied in standard dot notation.
00150  */
00151 UINT4 ipstr2long(char *ip_str)
00152 {
00153        char   buf[6];
00154        char   *ptr;
00155        int    i;
00156        int    count;
00157        UINT4  ipaddr;
00158        int    cur_byte;
00159 
00160        ipaddr = (UINT4)0;
00161        for(i = 0;i < 4;i++) {
00162               ptr = buf;
00163               count = 0;
00164               *ptr = '\0';
00165               while(*ip_str != '.' && *ip_str != '\0' && count < 4) {
00166                      if(!isdigit(*ip_str)) {
00167                             return((UINT4)0);
00168                      }
00169                      *ptr++ = *ip_str++;
00170                      count++;
00171               }
00172               if(count >= 4 || count == 0) {
00173                      return((UINT4)0);
00174               }
00175               *ptr = '\0';
00176               cur_byte = atoi(buf);
00177               if(cur_byte < 0 || cur_byte > 255) {
00178                      return((UINT4)0);
00179               }
00180               ip_str++;
00181               ipaddr = ipaddr << 8 | (UINT4)cur_byte;
00182        }
00183        return(ipaddr);
00184 }
00185 
00186 
00187 /*
00188  *     Call getpwnam but cache the result.
00189  */
00190 struct passwd *rad_getpwnam(char *name)
00191 {
00192        static struct passwd *lastpwd;
00193        static char lastname[64];
00194        static time_t lasttime = 0;
00195        time_t now;
00196 
00197        now = time(NULL);
00198 
00199        if ((now <= lasttime + 5 ) && strncmp(name, lastname, 64) == 0)
00200               return lastpwd;
00201 
00202        strncpy(lastname, name, 63);
00203        lastname[63] = 0;
00204        lastpwd = getpwnam(name);
00205        lasttime = now;
00206 
00207        return lastpwd;
00208 }
00209 
00210 
00211 /*
00212  *     Release the memory used by a list of attribute-value
00213  *     pairs.
00214  */
00215 void pairfree(VALUE_PAIR *pair)
00216 {
00217        VALUE_PAIR    *next;
00218 
00219        while(pair != NULL) {
00220               next = pair->next;
00221               free(pair);
00222               pair = next;
00223        }
00224 }
00225 
00226 
00227 /*
00228  *     Find the pair with the mathing attribute
00229  */
00230 VALUE_PAIR * pairfind(VALUE_PAIR *first, int attr)
00231 {
00232        while(first && first->attribute != attr)
00233               first = first->next;
00234        return first;
00235 }
00236 
00237 
00238 /*
00239  *     Delete the pair(s) with the mathing attribute
00240  */
00241 void pairdelete(VALUE_PAIR **first, int attr)
00242 {
00243        VALUE_PAIR *i, *next, *last = NULL;
00244 
00245        for(i = *first; i; i = next) {
00246               next = i->next;
00247               if (i->attribute == attr) {
00248                      if (last)
00249                             last->next = next;
00250                      else
00251                             *first = next;
00252                      free(i);
00253               } else
00254                      last = i;
00255        }
00256 }
00257 
00258 /*
00259  *     Add a pair at the end of a VALUE_PAIR list.
00260  */
00261 void pairadd(VALUE_PAIR **first, VALUE_PAIR *new)
00262 {
00263        VALUE_PAIR *i;
00264 
00265        new->next = NULL;
00266        if (*first == NULL) {
00267               *first = new;
00268               return;
00269        }
00270        for(i = *first; i->next; i = i->next)
00271               ;
00272        i->next = new;
00273 }
00274 
00275 /*
00276  *     Free an AUTHREQ struct.
00277  */
00278 void authfree(AUTH_REQ *authreq)
00279 {
00280        pairfree(authreq->request);
00281        memset(authreq, 0, sizeof(AUTH_REQ));
00282        free(authreq);
00283 }
00284 
00285 #if defined (sun) && defined(__svr4__)
00286 /*
00287  *     The signal() function in Solaris 2.5.1 sets SA_NODEFER in
00288  *     sa_flags, which causes grief if signal() is called in the
00289  *     handler before the cause of the signal has been cleared.
00290  *     (Infinite recursion).
00291  */
00292 void (*sun_signal(int signo, void (*func)(int)))(int)
00293 {
00294        struct sigaction act, oact;
00295 
00296        act.sa_handler = func;
00297        sigemptyset(&act.sa_mask);
00298        act.sa_flags = 0;
00299 #ifdef  SA_INTERRUPT        /* SunOS */
00300        act.sa_flags |= SA_INTERRUPT;
00301 #endif
00302        if (sigaction(signo, &act, &oact) < 0)
00303               return SIG_ERR;
00304        return oact.sa_handler;
00305 }
00306 #endif
00307 
00308 /*
00309  *     Like strncpy, but always adds \0
00310  */
00311 char *strNcpy(char *dest, char *src, int n)
00312 {
00313        if (n > 0)
00314               strncpy(dest, src, n);
00315        else
00316               n = 1;
00317        dest[n - 1] = 0;
00318 
00319        return dest;
00320 }
00321