home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-A.06 / NETKIT-A / NetKit-A-0.06 / pidentd-2.2 / src / kernel / irix4.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-09  |  5.7 KB  |  288 lines

  1. /*
  2. ** kernel/irix4.c             Kernel access functions to retrieve user number
  3. **
  4. ** This program is in the public domain and may be used freely by anyone
  5. ** who wants to. 
  6. **
  7. ** Last update: 17 March 1993
  8. **
  9. ** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
  10. **
  11. ** Last update: 28 June 1993
  12. **
  13. ** Modified by Christopher Kranz, Princeton University to work with suid
  14. ** root programs.  The method for which one descends through the kernel
  15. ** process structures was borrowed from lsof 2.10 written by Victor A. Abell,
  16. ** Purdue Research Foundation.
  17. */
  18.  
  19. #include <stdio.h>
  20. #include <errno.h>
  21. #include <ctype.h>
  22. #include <nlist.h>
  23. #include <pwd.h>
  24. #include <signal.h>
  25. #include <syslog.h>
  26.  
  27. #include "kvm.h"
  28.  
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <sys/param.h>
  32. #include <sys/ioctl.h>
  33. #include <sys/socket.h>
  34.  
  35. #include <sys/socketvar.h>
  36.  
  37. #include <sys/proc.h>
  38. #include <sys/syssgi.h>
  39.  
  40. #define _KERNEL
  41.  
  42. #include <sys/file.h>
  43.  
  44. #include <sys/inode.h>
  45.  
  46. #include <fcntl.h>
  47.  
  48. #include <sys/user.h>
  49. #include <sys/wait.h>
  50.   
  51. #undef _KERNEL
  52.  
  53. #include <net/if.h>
  54. #include <net/route.h>
  55. #include <netinet/in.h>
  56.  
  57. #include <netinet/in_pcb.h>
  58.  
  59. #include <netinet/tcp.h>
  60. #include <netinet/ip_var.h>
  61. #include <netinet/tcp_timer.h>
  62. #include <netinet/tcp_var.h>
  63.  
  64. #include <arpa/inet.h>
  65.  
  66. #include "identd.h"
  67. #include "error.h"
  68.  
  69.  
  70. extern void *calloc();
  71. extern void *malloc();
  72.  
  73.  
  74. struct nlist nl[] =
  75. {
  76. #define N_FILE 0  
  77. #define N_V    1
  78. #define N_TCB  2
  79. #define N_PROC 3
  80.  
  81.   { "file" },
  82.   { "v" },
  83.   { "tcb" },
  84.   { "proc" },
  85.   { "" }
  86. };
  87.  
  88. static kvm_t *kd;
  89.  
  90. static struct file *xfile;
  91. static int nfile;
  92.  
  93. static struct var v;
  94.  
  95. static struct inpcb tcb;
  96.  
  97.  
  98.  
  99. int k_open()
  100. {
  101.   /*
  102.   ** Open the kernel memory device
  103.   */
  104.   if (!(kd = kvm_open(path_unix, path_kmem, NULL, O_RDONLY, NULL)))
  105.     ERROR("main: kvm_open");
  106.   
  107.   /*
  108.   ** Extract offsets to the needed variables in the kernel
  109.   */
  110.   if (kvm_nlist(kd, nl) != 0)
  111.     ERROR("main: kvm_nlist");
  112.  
  113.   return 0;
  114. }
  115.  
  116.  
  117. /*
  118. ** Get a piece of kernel memory with error handling.
  119. ** Returns 1 if call succeeded, else 0 (zero).
  120. */
  121. static int getbuf(addr, buf, len, what)
  122.   long addr;
  123.   char *buf;
  124.   int len;
  125.   char *what;
  126. {
  127.  
  128.   if (kvm_read(kd, addr, buf, len) < 0)
  129.   {
  130.     if (syslog_flag)
  131.       syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
  132.          addr, len, what);
  133.  
  134.     return 0;
  135.   }
  136.   
  137.   return 1;
  138. }
  139.  
  140.  
  141. /*
  142. ** Traverse the inpcb list until a match is found.
  143. ** Returns NULL if no match.
  144. */
  145. static struct socket *
  146.     getlist(pcbp, faddr, fport, laddr, lport)
  147.   struct inpcb *pcbp;
  148.   struct in_addr *faddr;
  149.   int fport;
  150.   struct in_addr *laddr;
  151.   int lport;
  152. {
  153.   struct inpcb *head;
  154.  
  155.   if (!pcbp)
  156.     return NULL;
  157.  
  158.   head = pcbp->inp_prev;
  159.   do 
  160.   {
  161.     if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
  162.      pcbp->inp_laddr.s_addr == laddr->s_addr &&
  163.      pcbp->inp_fport        == fport &&
  164.      pcbp->inp_lport        == lport )
  165.       return pcbp->inp_socket;
  166.  
  167.   } while (pcbp->inp_next != head &&
  168.        getbuf((long) pcbp->inp_next,
  169.           pcbp,
  170.           sizeof(struct inpcb),
  171.           "tcblist"));
  172.  
  173.   return NULL;
  174. }
  175.  
  176.  
  177.  
  178. /*
  179. ** Return the user number for the connection owner
  180. */
  181. int k_getuid(faddr, fport, laddr, lport, uid)
  182.   struct in_addr *faddr;
  183.   int fport;
  184.   struct in_addr *laddr;
  185.   int lport;
  186.   int *uid;
  187. {
  188.   long addr;
  189.   struct socket *sockp;
  190.   int i;
  191.   struct inode inode;
  192.   long paddr;
  193.   struct proc *pp;
  194.   struct proc ps;
  195.   long pa;
  196.   int px;
  197.   int nofiles;
  198.   struct user *up;
  199.   char *uu;
  200.   size_t uul;
  201.   struct file **fp;
  202.   struct file f;
  203.  
  204.   
  205.   /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
  206.   if (!getbuf(nl[N_V].n_value, &v, sizeof(v), "v"))
  207.     return -1;
  208.   
  209.   nfile = v.v_file;
  210.   addr = nl[N_FILE].n_value;
  211.   
  212.   xfile = (struct file *) calloc(nfile, sizeof(struct file));
  213.   if (!xfile)
  214.     ERROR2("k_getuid: calloc(%d,%d)", nfile, sizeof(struct file));
  215.   
  216.   if (!getbuf(addr, xfile, sizeof(struct file)*nfile, "file[]"))
  217.     return -1;
  218.  
  219.   /* -------------------- TCP PCB LIST -------------------- */
  220.   if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
  221.     return -1;
  222.   
  223.   tcb.inp_prev = (struct inpcb *) nl[N_TCB].n_value;
  224.   sockp = getlist(&tcb, faddr, fport, laddr, lport);
  225.   
  226.   if (!sockp)
  227.     return -1;
  228.  
  229.   /* -------------------- SCAN PROCESS TABLE ------------------- */
  230.   if ( (paddr = nl[N_PROC].n_value) == NULL ) {
  231.     if (debug_flag && syslog_flag)
  232.       syslog(LOG_DEBUG, "k_getuid:  paddr == NULL");
  233.     return -1;
  234.   }
  235.  
  236.   paddr &= 0x7fffffff;
  237.  
  238.   uul = (size_t) (sizeof(struct user)
  239.       + (v.v_nofiles * sizeof(struct file *)));
  240.  
  241.   if ( (uu=(char *)malloc(uul)) == (char *)NULL ) 
  242.     return -1;
  243.  
  244.   fp = (struct file **)(uu + sizeof(struct user));
  245.   up = (struct user *)uu;
  246.  
  247.   for (pp=&ps, px=0 ; px < v.v_proc ; px++) {
  248.     pa = paddr + (long)(px * sizeof(struct proc));
  249.  
  250.     if ( !getbuf(pa, (char *)&ps, sizeof(ps), "proc") )
  251.       continue;
  252.  
  253.     if ( pp->p_stat == 0 || pp->p_stat == SZOMB )
  254.       continue;
  255.   
  256.     /* ------------------- GET U_AREA FOR PROCESS ----------------- */
  257.     if ((i=syssgi(SGI_RDUBLK, pp->p_pid, uu, uul)) < sizeof(struct user))
  258.       continue;
  259.  
  260.     /* ------------------- SCAN FILE TABLE ------------------------ */
  261.     if (i <= sizeof(struct user)
  262.     ||  ((long)up->u_ofile - UADDR) != sizeof(struct user))
  263.       nofiles = 0;
  264.     else
  265.       nofiles = (i - sizeof(struct user)) / sizeof(struct file *);
  266.  
  267.     for (i = 0 ; i < nofiles ; i++) {
  268.       if (fp[i] == NULL)
  269.         break;
  270.  
  271.       if (!getbuf(fp[i], &f, sizeof(f), "file"))
  272.         return -1;
  273.  
  274.       if ( f.f_count == 0 )
  275.         continue;
  276.  
  277.       if (!getbuf(f.f_inode, &inode, sizeof(inode), "inode"))
  278.         return -1;
  279.  
  280.       if ((inode.i_ftype & IFMT) == IFCHR && soc_fsptr(&inode) == sockp) {
  281.         *uid = up->u_ruid;
  282.         return 0;
  283.       }
  284.     } /* scan file table */
  285.   }  /* scan process table */
  286.   return -1;
  287. }
  288.