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 / sco324.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-11  |  10.2 KB  |  485 lines

  1. /*
  2. ** kernel/sco324.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. ** fast COFF nlist() code written by Peter Wemm <peter@DIALix.oz.au>
  12. ** This is up to 100 times faster than 3.2v1.0 to 3.2v4.1's nlist().
  13. ** This is slightly faster than the 3.2v4.2 nlist().
  14. **
  15. ** Preliminary SCO support by Peter Wemm <peter@DIALix.oz.au>
  16. ** Known Limitations:
  17. **   1: Can only get *effective* UID of a socket.  This is a real
  18. **      serious problem, as it looks like all rlogins, and rcp'c
  19. **      come from root.  Any volunteers to emulate the fuser command
  20. **      and grope around the kernel user structs for file pointers
  21. **      to get the *real* uid?
  22. **   2: THIS WILL NOT (YET!) WORK WITH SCO TCP 1.2.1 and hence ODT 3.0
  23. */
  24.  
  25. #include <stdio.h>
  26.  
  27. #include <filehdr.h>
  28. #include <syms.h>
  29.  
  30. /* Name space collision */
  31. #undef n_name
  32.  
  33. #include <nlist.h>
  34. #include <fcntl.h>
  35. #include <stdlib.h>
  36. #include <unistd.h>
  37. #include <malloc.h>
  38. #include <string.h>
  39.  
  40. /* how much buffer space to allocate to the symbol scanning */
  41. /* Make this at least 4096, but much more than 8192 is a waste */
  42. #define CHUNKSIZE 8192
  43.  
  44. int nlist(const char *filename, struct nlist *nl)
  45. {
  46.   FILHDR fh;            /* COFF file header */
  47.   SYMENT *se;            /* pointer to a SYMENT */
  48.  
  49.   int i, n;            /* iterative variables */
  50.  
  51.   long strsect;            /* seek pos of extended string table */
  52.   long strsize;            /* byte size of extended string table*/
  53.   
  54.   int mchunk;            /* max number of syments per chunk */
  55.   int p;            /* Symbol entry cache */
  56.   int slotnum;            /* Symbol entry cache */
  57.   int chunknum;            /* Symbol entry cache */
  58.   int oldchunknum;        /* Symbol entry cache */
  59.  
  60.   char *strtab = NULL;        /* malloc'ed extended string table buffer */
  61.   char *symchunk = NULL;    /* malloc'ed SYMENT symbol entry cache */
  62.  
  63.   int fd = -1;            /* File descriptor we are dealing with */
  64.  
  65.   int nument = 0;        /* How many symbols in the array */
  66.   int numremaining;        /* Counter for symbols not found yet */
  67.   struct nlist *nptr;        /* Pointer to current struct nlist entry */
  68.  
  69.   /* a check from sanity claus */
  70.   if (filename == NULL || nl == NULL)
  71.     goto cleanup;
  72.  
  73.   /* count the entries in the request table */
  74.   nptr = nl;
  75.   while (nptr->n_name && strlen(nptr->n_name) > 0) {
  76.     /* clear out the values as per the man-page */
  77.     nptr->n_value  = 0;
  78.     nptr->n_scnum  = 0;
  79.     nptr->n_type   = 0;
  80.     nptr->n_sclass = 0;
  81.     nptr->n_numaux = 0;
  82.     nptr++;
  83.     nument++;
  84.   }
  85.  
  86.   /* early exit if nothing wanted.. return success */
  87.   if (nument == 0)
  88.     return 0;
  89.  
  90.   /* no point scanning whole list if we've found'em all */
  91.   numremaining = nument;
  92.  
  93.   /* open the COFF file */
  94.   fd = open(filename, O_RDONLY, 0);
  95.  
  96.   if (fd < 0)
  97.     goto cleanup;
  98.  
  99.   /* read the COFF file header */
  100.   if (read(fd, &fh, FILHSZ) < FILHSZ)
  101.     goto cleanup;
  102.  
  103.   /* calcualte the starting offset of the string table */
  104.   strsect = fh.f_symptr + (fh.f_nsyms * SYMESZ);
  105.  
  106.   /* read the length of the string table */
  107.   if (lseek(fd, strsect, SEEK_SET) < 0)
  108.     goto cleanup;
  109.   if (read(fd, &strsize, sizeof(strsize)) < sizeof(strsize))
  110.     goto cleanup;
  111.  
  112.   /* allocate a buffer for the string table */
  113.   strtab = malloc(strsize);
  114.   if (strtab == NULL)
  115.     goto cleanup;
  116.  
  117.   /* allocate a buffer for the string table */
  118.   mchunk = CHUNKSIZE / SYMESZ;
  119.   symchunk = malloc(mchunk * SYMESZ);
  120.   if (symchunk == NULL)
  121.     goto cleanup;
  122.  
  123.   /* read the string table */
  124.   if (lseek(fd, strsect, SEEK_SET) < 0)
  125.     goto cleanup;
  126.   if (read(fd, strtab, strsize) < strsize)
  127.     goto cleanup;
  128.  
  129.   /* step through the symbol table */
  130.   if (lseek(fd, fh.f_symptr, SEEK_SET) < 0)
  131.     goto cleanup;
  132.  
  133.   oldchunknum = -1;
  134.   p = 0;            /* symbol slot number */
  135.   for (i = 0; i < fh.f_nsyms; i++) {
  136.  
  137.     /* which "chunk" of the symbol table we want */
  138.     chunknum = p / mchunk;
  139.  
  140.     /* Where in the chunk is the SYMENT we are up to? */
  141.     slotnum  = p % mchunk;
  142.  
  143.     /* load the chunk buffer if needed */
  144.     if (chunknum != oldchunknum) {
  145.       if (read(fd, symchunk, mchunk * SYMESZ) <= 0)
  146.     goto cleanup;
  147.       oldchunknum = chunknum;
  148.     }
  149.  
  150.     /* and of course.. Get a pointer.. */
  151.     se = (SYMENT *) (symchunk + slotnum * SYMESZ);
  152.  
  153.     /* next entry */
  154.     p++;
  155.  
  156.     /* is it a long string? */
  157.     if (se->n_zeroes == 0) {
  158.  
  159.       /* check table */
  160.       for (n = 0; n < nument; n++) {
  161.     if (strcmp(strtab + se->n_offset, nl[n].n_name) == 0) {
  162.       /* load the requested table */
  163.       nl[n].n_value  = se->n_value;
  164.       nl[n].n_scnum  = se->n_scnum;
  165.       nl[n].n_type   = se->n_type;
  166.       nl[n].n_sclass = se->n_sclass;
  167.       nl[n].n_numaux = se->n_numaux;
  168.       numremaining--;
  169.       break;
  170.     }
  171.       }
  172.       if (numremaining == 0)
  173.     break;            /* drop the for loop */
  174.  
  175.     } else {
  176.  
  177.       /* check table */
  178.       for (n = 0; n < nument; n++) {
  179.     
  180.     if (strncmp(se->_n._n_name, nl[n].n_name, sizeof(se->_n._n_name)) == 0) {
  181.       /* since we stopped at the 8th char, make sure that's all we want */
  182.       if ((int)strlen(nl[n].n_name) <= 8) {
  183.         /* load the requested table */
  184.         nl[n].n_value  = se->n_value;
  185.         nl[n].n_scnum  = se->n_scnum;
  186.         nl[n].n_type   = se->n_type;
  187.         nl[n].n_sclass = se->n_sclass;
  188.         nl[n].n_numaux = se->n_numaux;
  189.         numremaining--;
  190.         break;
  191.       }
  192.     }
  193.       }
  194.       if (numremaining == 0)
  195.     break;            /* drop the for loop */
  196.  
  197.     }
  198.     
  199.     /* does it have auxillary entries? */
  200.     p += se->n_numaux;
  201.  
  202.   }
  203.   
  204.   free(strtab);
  205.   free(symchunk);
  206.   close(fd);
  207.  
  208.   return numremaining;
  209.  
  210. cleanup:
  211.   if (fd >= 0)
  212.     close(fd);
  213.   if (strtab)
  214.     free(strtab);
  215.   if (symchunk)
  216.     free(symchunk);
  217.   return -1;
  218.  
  219. }
  220.  
  221. #include <stdio.h>
  222. #include <errno.h>
  223. #include <ctype.h>
  224. #include <nlist.h>
  225. #include <pwd.h>
  226. #include <signal.h>
  227. #include <syslog.h>
  228.  
  229. #include "kvm.h"
  230.  
  231. #include <sys/types.h>
  232. #include <sys/stat.h>
  233. #include <sys/param.h>
  234. #include <sys/sysmacros.h>
  235. #include <sys/ioctl.h>
  236.  
  237. #define _KERNEL
  238.  
  239. #include <sys/file.h>
  240. #include <sys/dir.h>
  241.  
  242. #include <sys/inode.h>
  243.  
  244. #include <fcntl.h>
  245.  
  246. #include <sys/user.h>
  247. #include <sys/wait.h>
  248.  
  249. #include <sys/var.h>
  250.   
  251. #undef _KERNEL
  252.  
  253. #include <sys/socket.h>
  254. #include <sys/stream.h>
  255.  
  256. #include <net/if.h>
  257. #include <net/route.h>
  258. #include <netinet/in.h>
  259.  
  260. #include <netinet/in_systm.h>
  261. #include <netinet/in_pcb.h>
  262.  
  263. #include <netinet/ip_var.h>
  264.  
  265. #include <netinet/tcp.h>
  266. #include <netinet/tcpip.h>
  267. #include <netinet/ip_var.h>
  268. #include <netinet/tcp_timer.h>
  269. #include <netinet/tcp_var.h>
  270. #include <netinet/tcp_debug.h>
  271.  
  272. #include <arpa/inet.h>
  273.  
  274. #include <sys/net/protosw.h>
  275. #include <sys/net/socketvar.h>
  276.  
  277. #include "identd.h"
  278. #include "error.h"
  279.  
  280.  
  281. extern void *calloc();
  282. extern void *malloc();
  283.  
  284. struct nlist nl[] =
  285. {
  286. #define N_V    0
  287. #define N_TCB  1
  288.  
  289.   { "v" },
  290.   { "tcb" },
  291.   { "" }
  292. };
  293.  
  294. static kvm_t *kd;
  295.  
  296. static struct var v;
  297.  
  298. static struct inpcb tcb;
  299.  
  300.  
  301. int k_open()
  302. {
  303.   /*
  304.   ** Open the kernel memory device
  305.   */
  306.   if (!(kd = kvm_open(path_unix, path_kmem, NULL, O_RDONLY, NULL)))
  307.     ERROR("main: kvm_open");
  308.   
  309.   /*
  310.   ** Extract offsets to the needed variables in the kernel
  311.   */
  312.   if (kvm_nlist(kd, nl) != 0)
  313.     ERROR("main: kvm_nlist");
  314.  
  315.   return 0;
  316. }
  317.  
  318.  
  319. /*
  320. ** Get a piece of kernel memory with error handling.
  321. ** Returns 1 if call succeeded, else 0 (zero).
  322. */
  323. static int getbuf(addr, buf, len, what)
  324.   long addr;
  325.   char *buf;
  326.   int len;
  327.   char *what;
  328. {
  329.   if (kvm_read(kd, addr, buf, len) < 0)
  330.   {
  331.     if (syslog_flag)
  332.       syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
  333.          addr, len, what);
  334.  
  335.     return 0;
  336.   }
  337.   
  338.   return 1;
  339. }
  340.  
  341.  
  342.  
  343. /*
  344. ** Traverse the inpcb list until a match is found.
  345. ** Returns NULL if no match.
  346. */
  347. static struct inpcb *
  348.     getlist(pcbp, faddr, fport, laddr, lport)
  349.   struct inpcb *pcbp;
  350.   struct in_addr *faddr;
  351.   int fport;
  352.   struct in_addr *laddr;
  353.   int lport;
  354. {
  355.   struct inpcb *head;
  356.  
  357.   if (!pcbp)
  358.     return NULL;
  359.  
  360.   head = pcbp->inp_prev;
  361.   do 
  362.   {
  363.     if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
  364.      pcbp->inp_laddr.s_addr == laddr->s_addr &&
  365.      pcbp->inp_fport        == fport &&
  366.      pcbp->inp_lport        == lport )
  367.     {
  368.       return pcbp;
  369.     }
  370.  
  371.   } while (pcbp->inp_next != head &&
  372.        getbuf((long) pcbp->inp_next,
  373.           pcbp,
  374.           sizeof(struct inpcb),
  375.           "tcblist"));
  376.  
  377.   return NULL;
  378. }
  379.  
  380. static caddr_t
  381.     followqueue(pcbp)
  382.   struct inpcb *pcbp;
  383. {
  384.   queue_t *q;
  385.   queue_t qbuf;
  386.   int n = 1;
  387.  
  388.   if (!pcbp)
  389.     return NULL;
  390.  
  391.   q = pcbp->inp_q;
  392.  
  393.   while (getbuf((long) q, &qbuf, sizeof(qbuf), "queue_t inp_q"))
  394.   {
  395.     q = qbuf.q_next;
  396.     n++;
  397.     if (qbuf.q_next == NULL)
  398.       return qbuf.q_ptr;
  399.   }
  400.  
  401.   return NULL;
  402. }
  403.  
  404.  
  405. /*
  406. ** Return the user number for the connection owner
  407. */
  408. int k_getuid(faddr, fport, laddr, lport, uid)
  409.   struct in_addr *faddr;
  410.   int fport;
  411.   struct in_addr *laddr;
  412.   int lport;
  413.   int *uid;
  414. {
  415.   int i;
  416.   struct inode inode;
  417.   struct stat s;
  418.   struct inpcb *sockp;
  419.   caddr_t cad;
  420.   struct socket socket;
  421.   struct file file;
  422.   short sockmajor;
  423.   short sockminor;
  424.  
  425.  
  426.   /* -------------------- TCP PCB LIST -------------------- */
  427.   if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
  428.     return -1;
  429.   
  430.   tcb.inp_prev = (struct inpcb *) nl[N_TCB].n_value;
  431.  
  432.   sockp = getlist(&tcb, faddr, fport, laddr, lport);
  433.   
  434.   if (!sockp)
  435.     return -1;
  436.  
  437.   if (sockp->inp_protoopt & SO_IMASOCKET)
  438.   {
  439.  
  440.     cad = followqueue(sockp); /* socket pointer */
  441.  
  442.     if (!getbuf((long)cad, &socket, sizeof(struct socket), "socket"))
  443.       return -1;
  444.  
  445.     if (!getbuf((long)socket.so_fp, &file, sizeof(struct file), "file"))
  446.       return -1;
  447.  
  448.     if (!getbuf((long)file.f_inode, &inode, sizeof(struct inode), "inode"))
  449.       return -1;
  450.  
  451.     *uid = inode.i_uid;
  452.     return 0;
  453.   } else {
  454.  
  455.     /* we just need to determine the major number of the tcp module, which
  456.        is the minor number of the tcp clone device /dev/tcp */
  457.     if (stat("/dev/inet/tcp", &s))
  458.       ERROR("stat(\"/dev/inet/tcp\")");
  459.   
  460.     sockmajor = major(s.st_rdev);
  461.     sockminor = sockp->inp_minor;
  462.  
  463.     if (!getbuf(nl[N_V].n_value, &v, sizeof(struct var), "var"))
  464.       return -1;
  465.  
  466.     for (i = 0; i < v.v_inode; i++) {
  467.  
  468.       if (!getbuf(((long) v.ve_inode) + i * sizeof(struct inode),
  469.       &inode, sizeof(struct inode), "inode"))
  470.     return -1;
  471.     
  472.       if (((inode.i_ftype & IFMT) == IFCHR) &&
  473.       (major(inode.i_rdev) == sockmajor) &&
  474.       (minor(inode.i_rdev) == sockminor))
  475.       {
  476.     *uid = inode.i_uid;
  477.     return 0;
  478.       }
  479.     }
  480.     return -1;
  481.   }
  482. }
  483.  
  484.  
  485.