"Fossies" - the Fresh Open Source Software Archive

Member "pidentd-3.0.19/src/k_bsd42.c" (20 Jan 1999, 5709 Bytes) of package /linux/misc/old/pidentd-3.0.19.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "k_bsd42.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 ** k_bsd42.c - 4.2BSD (and compatible OS) kernel access functions.
    3 **
    4 ** Copyright (c) 1997      Peter Eriksson <pen@lysator.liu.se>
    5 **
    6 ** This program is free software; you can redistribute it and/or
    7 ** modify it as you wish - as long as you don't claim that you wrote
    8 ** it.
    9 **
   10 ** This program is distributed in the hope that it will be useful,
   11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   13 */
   14 
   15 #include "config.h"
   16 
   17 /* Needed for HP-UX */
   18 #define _INCLUDE_STRUCT_FILE
   19 
   20 
   21 #include <stdio.h>
   22 #include <errno.h>
   23 #include <ctype.h>
   24 #include <nlist.h>
   25 #include <pwd.h>
   26 #undef _POSIX_SOURCE
   27 #include <signal.h>
   28 #include <syslog.h>
   29 
   30 #include <sys/types.h>
   31 #include <sys/stat.h>
   32 #include <sys/param.h>
   33 #include <sys/ioctl.h>
   34 
   35 #include <sys/socket.h>
   36 #define SYS_SOCKET_H_INCLUDED
   37 #include <sys/socketvar.h>
   38 
   39 #define KERNEL
   40 
   41 #include <sys/file.h>
   42 #include <fcntl.h>
   43 #include <sys/dir.h>
   44 #include <sys/wait.h>
   45   
   46 #undef KERNEL
   47 
   48 #include <sys/user.h>
   49 
   50 #include <net/if.h>
   51 #include <net/route.h>
   52 
   53 #include <netinet/in.h>
   54 #include <netinet/in_pcb.h>
   55 #include <netinet/tcp.h>
   56 #include <netinet/ip_var.h>
   57 #include <netinet/tcp_timer.h>
   58 #include <netinet/tcp_var.h>
   59 
   60 #include <arpa/inet.h>
   61 
   62 #include "pidentd.h"
   63 
   64 #ifdef HAVE_KVM_H
   65 #include <kvm.h>
   66 #else
   67 #include "pkvm.h"
   68 #endif
   69 
   70 
   71 struct kainfo
   72 {
   73     kvm_t *kd;
   74     struct nlist nl[4];
   75 };
   76 
   77 
   78 #define N_FILE 0  
   79 #define N_NFILE 1
   80 #define N_TCB 2
   81 
   82 
   83 
   84 
   85 int
   86 ka_init(void)
   87 {
   88     return 0;
   89 }
   90 
   91 
   92 int
   93 ka_open(void **misc)
   94 {
   95     int rcode;
   96     struct kainfo *kp;
   97 
   98 
   99     kp = s_malloc(sizeof(*kp));
  100     
  101     /*
  102     ** Open the kernel memory device
  103     */
  104     if ((kp->kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL)
  105     {
  106     if (debug)
  107         perror("kvm_open");
  108 
  109     syslog(LOG_ERR, "kvm_open: %m");
  110     s_free(kp);
  111     return -1;
  112     }
  113 
  114     kp->nl[0].n_name = "_file";
  115     kp->nl[1].n_name = "_nfile";
  116 #ifdef HPUX7
  117     kp->nl[2].n_name = "_tcb_cb";
  118 #else
  119     kp->nl[2].n_name = "_tcb";
  120 #endif
  121     kp->nl[3].n_name = NULL;
  122     
  123     /*
  124     ** Extract offsets to the needed variables in the kernel
  125     */
  126     if ((rcode = kvm_nlist(kp->kd, kp->nl)) != 0)
  127     {
  128     kp->nl[0].n_name = "file";
  129     kp->nl[1].n_name = "nfile";
  130 #ifdef HPUX7
  131     kp->nl[2].n_name = "tcb_cb";
  132 #else
  133     kp->nl[2].n_name = "tcb";
  134 #endif
  135     
  136     if ((rcode = kvm_nlist(kp->kd, kp->nl)) != 0)
  137     {
  138         if (debug)
  139         fprintf(stderr, "kvm_nlist: returned %d\n", rcode);
  140 
  141         syslog(LOG_ERR, "kvm_nlist, rcode = %d: %m", rcode);
  142         kvm_close(kp->kd);
  143         s_free(kp);
  144         return -1;
  145     }
  146     }
  147 
  148     *misc = (void *) kp;
  149     return 0;
  150 }
  151 
  152 
  153 /*
  154 ** Get a piece of kernel memory with error handling.
  155 ** Returns 1 if call succeeded, else 0 (zero).
  156 */
  157 static int
  158 getbuf(kvm_t *kd,
  159        off_t addr,
  160        void *buf,
  161        size_t len,
  162        char *what)
  163 {
  164     if (kvm_read(kd, addr, buf, len) < 0)
  165     {
  166     syslog(LOG_INFO, "getbuf: kvm_read(%08x, %lu) - %s : %m",
  167            addr, (unsigned long) len, what);
  168     
  169     return 0;
  170     }
  171     
  172     return 1;
  173 }
  174 
  175 
  176 
  177 /*
  178 ** Traverse the inpcb list until a match is found.
  179 ** Returns NULL if no match.
  180 */
  181 static struct socket *
  182 getlist(kvm_t *kd,
  183     struct inpcb *pcbp,
  184     struct in_addr *faddr,
  185     int fport,
  186     struct in_addr *laddr,
  187     int lport)
  188 {
  189     struct inpcb *head;
  190     int limiter = 65536;
  191     
  192     if (pcbp == NULL)
  193     return NULL;
  194     
  195     head = pcbp->inp_prev;
  196     do 
  197     {
  198     if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
  199          pcbp->inp_laddr.s_addr == laddr->s_addr &&
  200          pcbp->inp_fport        == fport &&
  201          pcbp->inp_lport        == lport)
  202         return (struct socket *) (pcbp->inp_socket);
  203     
  204     if (--limiter <= 0) 
  205         break;
  206     
  207     } while (pcbp->inp_next != head &&
  208          getbuf(kd,
  209             (off_t) pcbp->inp_next,
  210             pcbp,
  211             sizeof(struct inpcb),
  212             "tcblist"));
  213     
  214     return NULL;
  215 }
  216 
  217 
  218 
  219 /*
  220 ** Return the user number for the connection owner
  221 */
  222 int
  223 ka_lookup(void *vp, struct kernel *kp)
  224 {
  225     struct in_addr *faddr;
  226     int fport;
  227     struct in_addr *laddr;
  228     int lport;
  229     
  230     struct kainfo *kip;
  231     struct inpcb tcb;
  232     struct file *xfile = NULL;
  233     off_t addr;
  234     int nfile;
  235     
  236     struct socket *sockp;
  237     int i;
  238     struct ucred ucb;
  239     
  240     kip = (struct kainfo *) vp;
  241     
  242     faddr = &kp->remote.sin_addr;
  243     laddr = &kp->local.sin_addr;
  244     fport = kp->remote.sin_port;
  245     lport = kp->local.sin_port;
  246     
  247     /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
  248     if (!getbuf(kip->kd,
  249         (off_t) kip->nl[N_NFILE].n_value,
  250         &nfile,
  251         sizeof(nfile),
  252         "nfile"))
  253     goto Fail;
  254     
  255     if (!getbuf(kip->kd,
  256         (off_t) kip->nl[N_FILE].n_value, &addr,
  257         sizeof(addr), "&file"))
  258     goto Fail;
  259     
  260     xfile = (struct file *) s_malloc(nfile*sizeof(struct file));
  261 
  262     if (!getbuf(kip->kd, addr, xfile, sizeof(struct file) * nfile, "file[]"))
  263     goto Fail;
  264     
  265     /* -------------------- TCP PCB LIST -------------------- */
  266     if (!getbuf(kip->kd, (off_t) kip->nl[N_TCB].n_value, &tcb,
  267         sizeof(tcb), "tcb"))
  268     goto Fail;
  269     
  270     tcb.inp_prev = (struct inpcb *) kip->nl[N_TCB].n_value;
  271     sockp = getlist(kip->kd, &tcb, faddr, fport, laddr, lport);
  272     if (sockp == NULL)
  273     {
  274     s_free(xfile);
  275     return 0;
  276     }
  277     
  278     /*
  279     ** Locate the file descriptor that has the socket in question
  280     ** open so that we can get the 'ucred' information
  281     */
  282     for (i = 0; i < nfile; i++)
  283     {
  284     if (xfile[i].f_count == 0)
  285         continue;
  286     
  287     if (xfile[i].f_type == DTYPE_SOCKET &&
  288         (struct socket *) xfile[i].f_data == sockp)
  289     {
  290         if (!getbuf(kip->kd,
  291             (off_t) xfile[i].f_cred, &ucb, sizeof(ucb), "ucb"))
  292         goto Fail;
  293         
  294         kp->ruid = ucb.cr_ruid;
  295         kp->euid = ucb.cr_uid;
  296         
  297         s_free(xfile);
  298         return 1;
  299     }
  300     }
  301 
  302   Fail:
  303     s_free(xfile);
  304     return -1;
  305 }
  306