Article 2809 of comp.sources.unix:
Submitted-By: peter@ifm.liu.se (Peter Eriksson)
Posting-Number: Volume 29, Issue 130
Archive-Name: pidentd-2.7/part07

#!/bin/sh
# This is part 07 of a multipart archive.
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh08724; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= pidentd-2.7/src/kernel/other.c ==============
if test ! -d 'pidentd-2.7'; then
  $echo 'x -' 'creating directory' 'pidentd-2.7'
  mkdir 'pidentd-2.7'
fi
if test ! -d 'pidentd-2.7/src'; then
  $echo 'x -' 'creating directory' 'pidentd-2.7/src'
  mkdir 'pidentd-2.7/src'
fi
if test ! -d 'pidentd-2.7/src/kernel'; then
  $echo 'x -' 'creating directory' 'pidentd-2.7/src/kernel'
  mkdir 'pidentd-2.7/src/kernel'
fi
if test -f 'pidentd-2.7/src/kernel/other.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/other.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/other.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/other.c' &&
/*
** kernel/other.c	Low level kernel access functions for a number of
**			similar Unixes (all more or less based of 4.2BSD)
**
** This program is in the public domain and may be used freely by anyone
** who wants to. 
**
** Last update: 17 March 1993
**
** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
*/
X
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <nlist.h>
#include <pwd.h>
#include <signal.h>
#include <syslog.h>
X
#ifdef HAVE_KVM
#  include <kvm.h>
#else
#  include "kvm.h"
#endif
X
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
X
#ifdef __convex__
#  define _KERN_UTIL
#endif
X
#include <sys/socketvar.h>
X
#ifdef __convex__
#  undef _KERN_UTIL
#endif
X
#define KERNEL
X
#if defined(SUNOS35) || defined(__alpha)
#  define nfile SOME_OTHER_VARIABLE_NAME
#  define _KERNEL
#endif
X
#include <sys/file.h>
X
#if defined(SUNOS35) || defined(__alpha)
#  undef nfile
#  undef _KERNEL
#endif
X
#include <fcntl.h>
X
#if defined(ultrix)
#  include <sys/dir.h>
#  undef KERNEL
#endif
X
#if defined(sequent)
#  undef KERNEL
#endif
X
#include <sys/user.h>
#include <sys/wait.h>
X
#ifdef KERNEL  
#  undef KERNEL
#endif
X
#ifdef __convex__
#  include <sys/mbuf.h>
#endif
X
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
X
#ifdef __alpha
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#endif
X 
#include <netinet/in_pcb.h>
X
#include <netinet/tcp.h>
#include <netinet/ip_var.h>
X 
#ifdef __alpha
#include <netinet/tcpip.h>
#endif
X 
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
X
#include <arpa/inet.h>
X
#ifdef MIPS
#  include <sysv/sys/var.h>
extern int errno;
#endif
X
#include "identd.h"
#include "error.h"
X
X
extern void *calloc();
extern void *malloc();
X
X
struct nlist nl[] =
{
#if (defined(ultrix) && defined(mips))
X   /* Ultrix on DEC's MIPS machines */
X
#define N_FILE  0  
#define N_NFILE 1
#define N_TCB   2
X
X  { "file" },
X  { "nfile" },
X  { "tcb" },
X  
#else
#ifdef MIPS		/* MIPS RISC/OS */
X
#define N_FILE 0  
#define N_V    1
#define N_TCB  2
X
X  { "_file" },
X  { "_v" },
X  { "_tcb" },
X
#else
X
#define N_FILE 0  
#define N_NFILE 1
#define N_TCB 2
X
X  { "_file" },
X  { "_nfile" },
X  { "_tcb" },
X
#endif
#endif
X  { "" }
};
X
static kvm_t *kd;
X
static struct file *xfile;
X
#ifndef ultrix
static int nfile;
#endif
X
#if defined(MIPS)
static struct var v;
#endif
X
static struct inpcb tcb;
X
X
int k_open()
{
X  /*
X  ** Open the kernel memory device
X  */
X  if (!(kd = kvm_open(path_unix, path_kmem, NULL, O_RDONLY, NULL)))
X    ERROR("main: kvm_open");
X  
X  /*
X  ** Extract offsets to the needed variables in the kernel
X  */
X  if (kvm_nlist(kd, nl) != 0)
X    ERROR("main: kvm_nlist");
X
X  return 0;
}
X
X
/*
** Get a piece of kernel memory with error handling.
** Returns 1 if call succeeded, else 0 (zero).
*/
static int getbuf(addr, buf, len, what)
#ifdef __alpha
X  caddr_t addr;
#else
X  long addr;
#endif
X  char *buf;
X  int len;
X  char *what;
{
X
X  if (kvm_read(kd, addr, buf, len) < 0)
X  {
X    if (syslog_flag)
X      syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
X	     addr, len, what);
X
X    return 0;
X  }
X  
X  return 1;
}
X
X
X
/*
** Traverse the inpcb list until a match is found.
** Returns NULL if no match.
*/
static struct socket *
X    getlist(pcbp, faddr, fport, laddr, lport)
X  struct inpcb *pcbp;
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
{
X  struct inpcb *head;
X
X  if (!pcbp)
X    return NULL;
X
X  
X  head = pcbp->inp_prev;
X  do 
X  {
X    if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
X	 pcbp->inp_laddr.s_addr == laddr->s_addr &&
X	 pcbp->inp_fport        == fport &&
X	 pcbp->inp_lport        == lport )
X      return pcbp->inp_socket;
X  } while (pcbp->inp_next != head &&
#ifdef __alpha
X	   getbuf((caddr_t) pcbp->inp_next,
#else
X	   getbuf((long) pcbp->inp_next,
#endif
X		  pcbp,
X		  sizeof(struct inpcb),
X		  "tcblist"));
X
X  return NULL;
}
X
X
X
/*
** Return the user number for the connection owner
*/
int k_getuid(faddr, fport, laddr, lport, uid)
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
X  int *uid;
{
#ifdef __alpha
X  caddr_t addr;
#else
X  long addr;
#endif
X  struct socket *sockp;
X  int i;
X  struct ucred ucb;
X  
X  /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
#if defined(MIPS)
X  if (!getbuf(nl[N_V].n_value, &v, sizeof(v), "v"))
X    return -1;
X  
X  nfile = v.v_file;
X  addr = nl[N_FILE].n_value;
#else /* not MIPS */
X  if (!getbuf(nl[N_NFILE].n_value, &nfile, sizeof(nfile), "nfile"))
X    return -1;
X
X  if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
X    return -1;
#endif
X  
X  xfile = (struct file *) calloc(nfile, sizeof(struct file));
X  if (!xfile)
X    ERROR2("k_getuid: calloc(%d,%d)", nfile, sizeof(struct file));
X  
X  if (!getbuf(addr, xfile, sizeof(struct file)*nfile, "file[]"))
X    return -1;
X  
X  /* -------------------- TCP PCB LIST -------------------- */
X  if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
X    return -1;
X  
X  tcb.inp_prev = (struct inpcb *) nl[N_TCB].n_value;
X  sockp = getlist(&tcb, faddr, fport, laddr, lport);
X  
X  if (!sockp)
X    return -1;
X
X  /*
X  ** Locate the file descriptor that has the socket in question
X  ** open so that we can get the 'ucred' information
X  */
X  for (i = 0; i < nfile; i++)
X  {
X    if (xfile[i].f_count == 0)
X      continue;
X    
X    if (xfile[i].f_type == DTYPE_SOCKET &&
X	(struct socket *) xfile[i].f_data == sockp)
X    {
#ifdef __convex__
X      *uid = xfile[i].f_cred.cr_uid;
#else
X      if (!getbuf(xfile[i].f_cred, &ucb, sizeof(ucb), "ucb"))
X	return -1;
X      
X      *uid = ucb.cr_ruid;
#endif
X
X      return 0;
X    }
X  }
X  
X  return -1;
}
X
SHAR_EOF
  $shar_touch -am 0605150895 'pidentd-2.7/src/kernel/other.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/other.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/other.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'pidentd-2.7/src/kernel/other.c:' 'MD5 check failed'
427a9b908ec303a46d387ad7169b3632  pidentd-2.7/src/kernel/other.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/other.c'`"
    test 5671 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/other.c:' 'original size' '5671,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/ptx2.c ==============
if test -f 'pidentd-2.7/src/kernel/ptx2.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/ptx2.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/ptx2.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/ptx2.c' &&
/*
** kernel/ptx4.c                    PTX4 specific kernel access functions
**
** This program is in the public domain and may be used freely by anyone
** who wants to. 
**
** Last update: 17 March 1993
**
** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
*/
X
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <nlist.h>
#include <pwd.h>
#include <signal.h>
#include <syslog.h>
X
#  include "kvm.h"
X
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
X
#include <sys/socketvar.h>
X
#define _INKERNEL
#include <sys/file.h>
#include <sys/var.h>
#undef _INKERNEL
X
#include <fcntl.h>
X
#include <unistd.h>
#include <sys/fcntl.h>
#include <sys/stream.h>
#include <sys/stat.h>
#include <sys/user.h>
#include <sys/vnode.h>
#include <sys/sysmacros.h>
X
#include <sys/wait.h>
X  
#undef _KMEMUSER
X
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/route.h>
X
#include <netinet/in_pcb.h>
X
#include <netinet/tcp.h>
#include <netinet/ip_var.h>
#include <netinet/tcpip.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
X
#include <arpa/inet.h>
X
#include "identd.h"
#include "error.h"
X
X
extern void *calloc();
extern void *malloc();
X
X
struct nlist nl[] =
{
#define N_TCP_NHDRS 0
#define N_TCP_HASH 1
#define N_FILE  2
#define N_V  3
X      
X  { "tcp_nhdrs" },
X  { "tcp_hash" },
X  { "file" },
X  { "v" },
X  { "" }
};
X
static kvm_t *kd;
X
static struct inpcb_hdr *k_tcp_hash;
static struct inpcb_hdr *tcp_hash;
static int tcp_nhdrs;
static struct var v;
X
int k_open()
{
X  /*
X  ** Open the kernel memory device
X  */
X  if (!(kd = kvm_open(path_unix, path_kmem, NULL, O_RDONLY, NULL)))
X    ERROR("main: kvm_open");
X  
X  /*
X  ** Extract offsets to the needed variables in the kernel
X  */
X  if (kvm_nlist(kd, nl) != 0)
X    ERROR("main: kvm_nlist");
X
X  return 0;
}
X
X
/*
** Get a piece of kernel memory with error handling.
** Returns 1 if call succeeded, else 0 (zero).
*/
static int getbuf(addr, buf, len, what)
X  long addr;
X  char *buf;
X  int len;
X  char *what;
{
X  if (kvm_read(kd, addr, buf, len) < 0)
X  {
X    if (syslog_flag)
X      syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
X	     addr, len, what);
X
X    return 0;
X  }
X  
X  return 1;
}
X
X
X
/*
** Traverse the inpcb list until a match is found.
** Returns NULL if no match.
*/
static short
X    getlist(faddr, fport, laddr, lport)
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
{
X  int i;
X  struct inpcb cur_pcb;
X  struct inpcb *inp;
X
X  for (i = 0; i < tcp_nhdrs; i++) {
X    inp = tcp_hash[i].inph_next;
X    /* Linked list on this hash chain ends when points to hash header */
X    while (inp != (struct inpcb *) &k_tcp_hash[i]) {
X      /* Can we get this PCB ? */
X      if (!getbuf((long) inp, &cur_pcb, sizeof(struct inpcb), "tcblist"))
X	break;
X      
X      if ( cur_pcb.inp_faddr == faddr->s_addr &&
X	   cur_pcb.inp_laddr == laddr->s_addr &&
X	   cur_pcb.inp_fport        == fport &&
X	   cur_pcb.inp_lport        == lport )
X	return cur_pcb.inp_minordev;
X      inp = cur_pcb.inp_next;
X    }
X  }
X
X  return -1;
}
X
X
X
/*
** Return the user number for the connection owner in the int pointed
** at in the uid argument.
*/
int k_getuid(faddr, fport, laddr, lport, uid)
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
X  int *uid;
{
X  long addr;
X  struct stat s;
X  short tcpmajor;	/* Major number of the tcp device */
X  short sockp;		/* Really a device minor number */
X  struct file *filehead, file;
X  int nfile;
X  struct ucred ucb;
X  int i;
X
X  
X  /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
X  if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
X    return -1;
X
X  /* we just need to determine the major number of the tcp module, which
X     is the minor number of the tcp clone device /dev/tcp */
X  if (stat("/dev/tcp", &s))
X    ERROR("stat(\"/dev/tcp\")");
X  
X  tcpmajor = minor(s.st_rdev);
X
X  /* -------------------- TCP PCB LIST -------------------- */
X  /* Get count of TCP hash headers */
X  if (!getbuf(nl[N_TCP_NHDRS].n_value,
X      &tcp_nhdrs, sizeof(tcp_nhdrs), "tcp_nhdrs"))
X    return(-1);
X  if ((tcp_hash = calloc(tcp_nhdrs, sizeof(struct inpcb_hdr))) == NULL)
X    return(-1);
X  k_tcp_hash = (struct inpcb_hdr *) nl[N_TCP_HASH].n_value;
X  if (!getbuf(nl[N_TCP_HASH].n_value,
X      tcp_hash, tcp_nhdrs * sizeof(struct inpcb_hdr), "tcp_hash"))
X    return -1;
X  
X  sockp = getlist(faddr, fport, laddr, lport);
X  
X  if (sockp == -1)
X    return -1;
X
X
X  /*
X  * Get the pointer to the head of the file list
X  */
X  if (!getbuf(nl[N_FILE].n_value, &filehead, sizeof(struct file *)))
X    return -1;
X
X  /* Get size of file array */
X  if (!getbuf(nl[N_V].n_value, &v, sizeof(struct var )))
X    return -1;
X
X  nfile = v.v_file;
X  
X  for (i = 0; i < nfile ; i++) {
X    struct vnode vnode;
X 
X    /*
X    ** Grab a file record
X    */
X    if (!getbuf((long) &filehead[i], &file, sizeof(struct file), "file"))
X      return -1;
X
X    /* In use ? */
X    if (file.f_count == 0)
X      continue;
X
X    /*
X    ** Grab the vnode information to check whether this file is the
X    ** correct major & minor char device
X    */
X    /* Extra check */
X    if (!file.f_vnode)
X      continue;
X    if (!getbuf((off_t)file.f_vnode, &vnode, sizeof(struct vnode), "vnode"))
X      return -1;
X    
X    if ((vnode.v_type == VCHR) && (major(vnode.v_rdev) == tcpmajor) &&
X	(minor(vnode.v_rdev) == sockp))
X    {
X      /*
X      ** We've found it!
X      */
X      if (!getbuf((off_t)file.f_cred, &ucb, sizeof(struct ucred), "cred"))
X	return -1;
X      
X      *uid = ucb.cr_ruid;
X      return 0;
X    }
X    
X  }
X  
X  return -1;
}
SHAR_EOF
  $shar_touch -am 0605150895 'pidentd-2.7/src/kernel/ptx2.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/ptx2.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/ptx2.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'pidentd-2.7/src/kernel/ptx2.c:' 'MD5 check failed'
ff9a35aec4539f1c4bafe87e29ccdd1a  pidentd-2.7/src/kernel/ptx2.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/ptx2.c'`"
    test 5635 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/ptx2.c:' 'original size' '5635,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/ptx4.c ==============
if test -f 'pidentd-2.7/src/kernel/ptx4.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/ptx4.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/ptx4.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/ptx4.c' &&
/*
** kernel/ptx4.c                    PTX4 specific kernel access functions
**
** This program is in the public domain and may be used freely by anyone
** who wants to. 
**
** Last update: 17 March 1993
**
** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
*/
X
#define _KMEMUSER
X
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <nlist.h>
#include <pwd.h>
#include <signal.h>
#include <syslog.h>
X
#  include "kvm.h"
X
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
X
#include <sys/socketvar.h>
X
#include <sys/file.h>
#include <sys/var.h>
X
#include <fcntl.h>
X
#include <unistd.h>
#include <sys/fcntl.h>
#include <sys/stream.h>
#include <sys/stat.h>
#include <sys/cred.h>
#include <sys/vnode.h>
#include <sys/sysmacros.h>
X
#include <sys/wait.h>
X  
#undef _KMEMUSER
X
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/route.h>
X
#include <netinet/in_pcb.h>
X
#include <netinet/tcp.h>
#include <netinet/ip_var.h>
#include <netinet/tcpip.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
X
#include <arpa/inet.h>
X
#include "identd.h"
#include "error.h"
X
X
extern void *calloc();
extern void *malloc();
X
X
struct nlist nl[] =
{
#define N_TCP_NHDRS 0
#define N_TCP_HASH 1
#define N_FILE  2
#define N_V  3
X      
X  { "tcp_nhdrs" },
X  { "tcp_hash" },
X  { "file" },
X  { "v" },
X  { "" }
};
X
static kvm_t *kd;
X
static struct inpcb_hdr *k_tcp_hash;
static struct inpcb_hdr *tcp_hash;
static int tcp_nhdrs;
static struct var v;
X
int k_open()
{
X  /*
X  ** Open the kernel memory device
X  */
X  if (!(kd = kvm_open(path_unix, path_kmem, NULL, O_RDONLY, NULL)))
X    ERROR("main: kvm_open");
X  
X  /*
X  ** Extract offsets to the needed variables in the kernel
X  */
X  if (kvm_nlist(kd, nl) != 0)
X    ERROR("main: kvm_nlist");
X
X  return 0;
}
X
X
/*
** Get a piece of kernel memory with error handling.
** Returns 1 if call succeeded, else 0 (zero).
*/
static int getbuf(addr, buf, len, what)
X  long addr;
X  char *buf;
X  int len;
X  char *what;
{
X  if (kvm_read(kd, addr, buf, len) < 0)
X  {
X    if (syslog_flag)
X      syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
X	     addr, len, what);
X
X    return 0;
X  }
X  
X  return 1;
}
X
X
X
/*
** Traverse the inpcb list until a match is found.
** Returns NULL if no match.
*/
static short
X    getlist(faddr, fport, laddr, lport)
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
{
X  int i;
X  struct inpcb cur_pcb;
X  struct inpcb *inp;
X
X  for (i = 0; i < tcp_nhdrs; i++) {
X    inp = tcp_hash[i].inph_next;
X    /* Linked list on this hash chain ends when points to hash header */
X    while (inp != (struct inpcb *) &k_tcp_hash[i]) {
X      /* Can we get this PCB ? */
X      if (!getbuf((long) inp, &cur_pcb, sizeof(struct inpcb), "tcblist"))
X	break;
X      
X      if ( cur_pcb.inp_faddr == faddr->s_addr &&
X	   cur_pcb.inp_laddr == laddr->s_addr &&
X	   cur_pcb.inp_fport        == fport &&
X	   cur_pcb.inp_lport        == lport )
X	return cur_pcb.inp_minordev;
X      inp = cur_pcb.inp_next;
X    }
X  }
X
X  return -1;
}
X
X
X
/*
** Return the user number for the connection owner in the int pointed
** at in the uid argument.
*/
int k_getuid(faddr, fport, laddr, lport, uid)
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
X  int *uid;
{
X  long addr;
X  struct stat s;
X  short tcpmajor;	/* Major number of the tcp device */
X  short sockp;		/* Really a device minor number */
X  struct file *filehead, file;
X  int nfile;
X  cred_t ucb;
X  int i;
X
X  
X  /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
X  if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
X    return -1;
X
X  /* we just need to determine the major number of the tcp module, which
X     is the minor number of the tcp clone device /dev/tcp */
X  if (stat("/dev/tcp", &s))
X    ERROR("stat(\"/dev/tcp\")");
X  
X  tcpmajor = minor(s.st_rdev);
X
X  /* -------------------- TCP PCB LIST -------------------- */
X  /* Get count of TCP hash headers */
X  if (!getbuf(nl[N_TCP_NHDRS].n_value,
X      &tcp_nhdrs, sizeof(tcp_nhdrs), "tcp_nhdrs"))
X    return(-1);
X  if ((tcp_hash = calloc(tcp_nhdrs, sizeof(struct inpcb_hdr))) == NULL)
X    return(-1);
X  k_tcp_hash = (struct inpcb_hdr *) nl[N_TCP_HASH].n_value;
X  if (!getbuf(nl[N_TCP_HASH].n_value,
X      tcp_hash, tcp_nhdrs * sizeof(struct inpcb_hdr), "tcp_hash"))
X    return -1;
X  
X  sockp = getlist(faddr, fport, laddr, lport);
X  
X  if (sockp == -1)
X    return -1;
X
X
X  /*
X  * Get the pointer to the head of the file list
X  */
X  if (!getbuf(nl[N_FILE].n_value, &filehead, sizeof(struct file *)))
X    return -1;
X
X  /* Get size of file array */
X  if (!getbuf(nl[N_V].n_value, &v, sizeof(struct var )))
X    return -1;
X
X  nfile = v.v_file;
X  
X  for (i = 0; i < nfile ; i++) {
X    struct vnode vnode;
X 
X    /*
X    ** Grab a file record
X    */
X    if (!getbuf((long) &filehead[i], &file, sizeof(struct file), "file"))
X      return -1;
X
X    /* In use ? */
X    if (file.f_count == 0)
X      continue;
X
X    /*
X    ** Grab the vnode information to check whether this file is the
X    ** correct major & minor char device
X    */
X    /* Extra check */
X    if (!file.f_vnode)
X      continue;
X    if (!getbuf((off_t)file.f_vnode, &vnode, sizeof(struct vnode), "vnode"))
X      return -1;
X    
X    if ((vnode.v_type == VCHR) && (major(vnode.v_rdev) == tcpmajor) &&
X	(minor(vnode.v_rdev) == sockp))
X    {
X      /*
X      ** We've found it!
X      */
X      if (!getbuf((off_t)file.f_cred, &ucb, sizeof(cred_t), "cred"))
X	return -1;
X      
X      *uid = ucb.cr_ruid;
X      return 0;
X    }
X    
X  }
X  
X  return -1;
}
SHAR_EOF
  $shar_touch -am 0605150895 'pidentd-2.7/src/kernel/ptx4.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/ptx4.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/ptx4.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'pidentd-2.7/src/kernel/ptx4.c:' 'MD5 check failed'
2e88f1770cd29713086a623626c87636  pidentd-2.7/src/kernel/ptx4.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/ptx4.c'`"
    test 5607 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/ptx4.c:' 'original size' '5607,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/sco324.c ==============
if test -f 'pidentd-2.7/src/kernel/sco324.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/sco324.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/sco324.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/sco324.c' &&
/*
** kernel/sco324.c             Kernel access functions to retrieve user number
**
** This program is in the public domain and may be used freely by anyone
** who wants to. 
**
** Last update: 17 March 1993
**
** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
**
** fast COFF nlist() code written by Peter Wemm <peter@DIALix.oz.au>
** This is up to 100 times faster than 3.2v1.0 to 3.2v4.1's nlist().
** This is slightly faster than the 3.2v4.2 nlist().
**
** Preliminary SCO support by Peter Wemm <peter@DIALix.oz.au>
** Known Limitations:
**   1: Can only get *effective* UID of a socket.  This is a real
**      serious problem, as it looks like all rlogins, and rcp'c
**      come from root.  Any volunteers to emulate the fuser command
**      and grope around the kernel user structs for file pointers
**      to get the *real* uid?
**   2: THIS WILL NOT (YET!) WORK WITH SCO TCP 1.2.1 and hence ODT 3.0
*/
X
#include <stdio.h>
X
#include <filehdr.h>
#include <syms.h>
X
/* Name space collision */
#undef n_name
X
#include <nlist.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
X
/* how much buffer space to allocate to the symbol scanning */
/* Make this at least 4096, but much more than 8192 is a waste */
#define CHUNKSIZE 8192
X
int nlist(const char *filename, struct nlist *nl)
{
X  FILHDR fh;			/* COFF file header */
X  SYMENT *se;			/* pointer to a SYMENT */
X
X  int i, n;			/* iterative variables */
X
X  long strsect;			/* seek pos of extended string table */
X  long strsize;			/* byte size of extended string table*/
X  
X  int mchunk;			/* max number of syments per chunk */
X  int p;			/* Symbol entry cache */
X  int slotnum;			/* Symbol entry cache */
X  int chunknum;			/* Symbol entry cache */
X  int oldchunknum;		/* Symbol entry cache */
X
X  char *strtab = NULL;		/* malloc'ed extended string table buffer */
X  char *symchunk = NULL;	/* malloc'ed SYMENT symbol entry cache */
X
X  int fd = -1;			/* File descriptor we are dealing with */
X
X  int nument = 0;		/* How many symbols in the array */
X  int numremaining;		/* Counter for symbols not found yet */
X  struct nlist *nptr;		/* Pointer to current struct nlist entry */
X
X  /* a check from sanity claus */
X  if (filename == NULL || nl == NULL)
X    goto cleanup;
X
X  /* count the entries in the request table */
X  nptr = nl;
X  while (nptr->n_name && strlen(nptr->n_name) > 0) {
X    /* clear out the values as per the man-page */
X    nptr->n_value  = 0;
X    nptr->n_scnum  = 0;
X    nptr->n_type   = 0;
X    nptr->n_sclass = 0;
X    nptr->n_numaux = 0;
X    nptr++;
X    nument++;
X  }
X
X  /* early exit if nothing wanted.. return success */
X  if (nument == 0)
X    return 0;
X
X  /* no point scanning whole list if we've found'em all */
X  numremaining = nument;
X
X  /* open the COFF file */
X  fd = open(filename, O_RDONLY, 0);
X
X  if (fd < 0)
X    goto cleanup;
X
X  /* read the COFF file header */
X  if (read(fd, &fh, FILHSZ) < FILHSZ)
X    goto cleanup;
X
X  /* calcualte the starting offset of the string table */
X  strsect = fh.f_symptr + (fh.f_nsyms * SYMESZ);
X
X  /* read the length of the string table */
X  if (lseek(fd, strsect, SEEK_SET) < 0)
X    goto cleanup;
X  if (read(fd, &strsize, sizeof(strsize)) < sizeof(strsize))
X    goto cleanup;
X
X  /* allocate a buffer for the string table */
X  strtab = malloc(strsize);
X  if (strtab == NULL)
X    goto cleanup;
X
X  /* allocate a buffer for the string table */
X  mchunk = CHUNKSIZE / SYMESZ;
X  symchunk = malloc(mchunk * SYMESZ);
X  if (symchunk == NULL)
X    goto cleanup;
X
X  /* read the string table */
X  if (lseek(fd, strsect, SEEK_SET) < 0)
X    goto cleanup;
X  if (read(fd, strtab, strsize) < strsize)
X    goto cleanup;
X
X  /* step through the symbol table */
X  if (lseek(fd, fh.f_symptr, SEEK_SET) < 0)
X    goto cleanup;
X
X  oldchunknum = -1;
X  p = 0;			/* symbol slot number */
X  for (i = 0; i < fh.f_nsyms; i++) {
X
X    /* which "chunk" of the symbol table we want */
X    chunknum = p / mchunk;
X
X    /* Where in the chunk is the SYMENT we are up to? */
X    slotnum  = p % mchunk;
X
X    /* load the chunk buffer if needed */
X    if (chunknum != oldchunknum) {
X      if (read(fd, symchunk, mchunk * SYMESZ) <= 0)
X	goto cleanup;
X      oldchunknum = chunknum;
X    }
X
X    /* and of course.. Get a pointer.. */
X    se = (SYMENT *) (symchunk + slotnum * SYMESZ);
X
X    /* next entry */
X    p++;
X
X    /* is it a long string? */
X    if (se->n_zeroes == 0) {
X
X      /* check table */
X      for (n = 0; n < nument; n++) {
X	if (strcmp(strtab + se->n_offset, nl[n].n_name) == 0) {
X	  /* load the requested table */
X	  nl[n].n_value  = se->n_value;
X	  nl[n].n_scnum  = se->n_scnum;
X	  nl[n].n_type   = se->n_type;
X	  nl[n].n_sclass = se->n_sclass;
X	  nl[n].n_numaux = se->n_numaux;
X	  numremaining--;
X	  break;
X	}
X      }
X      if (numremaining == 0)
X	break;			/* drop the for loop */
X
X    } else {
X
X      /* check table */
X      for (n = 0; n < nument; n++) {
X	
X	if (strncmp(se->_n._n_name, nl[n].n_name, sizeof(se->_n._n_name)) == 0) {
X	  /* since we stopped at the 8th char, make sure that's all we want */
X	  if ((int)strlen(nl[n].n_name) <= 8) {
X	    /* load the requested table */
X	    nl[n].n_value  = se->n_value;
X	    nl[n].n_scnum  = se->n_scnum;
X	    nl[n].n_type   = se->n_type;
X	    nl[n].n_sclass = se->n_sclass;
X	    nl[n].n_numaux = se->n_numaux;
X	    numremaining--;
X	    break;
X	  }
X	}
X      }
X      if (numremaining == 0)
X	break;			/* drop the for loop */
X
X    }
X    
X    /* does it have auxillary entries? */
X    p += se->n_numaux;
X
X  }
X  
X  free(strtab);
X  free(symchunk);
X  close(fd);
X
X  return numremaining;
X
cleanup:
X  if (fd >= 0)
X    close(fd);
X  if (strtab)
X    free(strtab);
X  if (symchunk)
X    free(symchunk);
X  return -1;
X
}
X
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <nlist.h>
#include <pwd.h>
#include <signal.h>
#include <syslog.h>
X
#include "kvm.h"
X
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/sysmacros.h>
#include <sys/ioctl.h>
X
#define _KERNEL
X
#include <sys/file.h>
#include <sys/dir.h>
X
#include <sys/inode.h>
X
#include <fcntl.h>
X
#include <sys/user.h>
#include <sys/wait.h>
X
#include <sys/var.h>
X  
#undef _KERNEL
X
#include <sys/socket.h>
#include <sys/stream.h>
X
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
X
#include <netinet/in_systm.h>
#include <netinet/in_pcb.h>
X
#include <netinet/ip_var.h>
X
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <netinet/ip_var.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
#include <netinet/tcp_debug.h>
X
#include <arpa/inet.h>
X
#include <sys/net/protosw.h>
#include <sys/net/socketvar.h>
X
#include "identd.h"
#include "error.h"
X
X
extern void *calloc();
extern void *malloc();
X
struct nlist nl[] =
{
#define N_V    0
#define N_TCB  1
X 
X  { "v" },
X  { "tcb" },
X  { "" }
};
X
static kvm_t *kd;
X
static struct var v;
X
static struct inpcb tcb;
X
X
int k_open()
{
X  /*
X  ** Open the kernel memory device
X  */
X  if (!(kd = kvm_open(path_unix, path_kmem, NULL, O_RDONLY, NULL)))
X    ERROR("main: kvm_open");
X  
X  /*
X  ** Extract offsets to the needed variables in the kernel
X  */
X  if (kvm_nlist(kd, nl) != 0)
X    ERROR("main: kvm_nlist");
X
X  return 0;
}
X
X
/*
** Get a piece of kernel memory with error handling.
** Returns 1 if call succeeded, else 0 (zero).
*/
static int getbuf(addr, buf, len, what)
X  long addr;
X  char *buf;
X  int len;
X  char *what;
{
X  if (kvm_read(kd, addr, buf, len) < 0)
X  {
X    if (syslog_flag)
X      syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
X	     addr, len, what);
X
X    return 0;
X  }
X  
X  return 1;
}
X
X
X
/*
** Traverse the inpcb list until a match is found.
** Returns NULL if no match.
*/
static struct inpcb *
X    getlist(pcbp, faddr, fport, laddr, lport)
X  struct inpcb *pcbp;
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
{
X  struct inpcb *head;
X
X  if (!pcbp)
X    return NULL;
X
X  head = pcbp->inp_prev;
X  do 
X  {
X    if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
X	 pcbp->inp_laddr.s_addr == laddr->s_addr &&
X	 pcbp->inp_fport        == fport &&
X	 pcbp->inp_lport        == lport )
X    {
X      return pcbp;
X    }
X
X  } while (pcbp->inp_next != head &&
X	   getbuf((long) pcbp->inp_next,
X		  pcbp,
X		  sizeof(struct inpcb),
X		  "tcblist"));
X
X  return NULL;
}
X
static caddr_t
X    followqueue(pcbp)
X  struct inpcb *pcbp;
{
X  queue_t *q;
X  queue_t qbuf;
X  int n = 1;
X
X  if (!pcbp)
X    return NULL;
X
X  q = pcbp->inp_q;
X
X  while (getbuf((long) q, &qbuf, sizeof(qbuf), "queue_t inp_q"))
X  {
X    q = qbuf.q_next;
X    n++;
X    if (qbuf.q_next == NULL)
X      return qbuf.q_ptr;
X  }
X
X  return NULL;
}
X
X
/*
** Return the user number for the connection owner
*/
int k_getuid(faddr, fport, laddr, lport, uid)
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
X  int *uid;
{
X  int i;
X  struct inode inode;
X  struct stat s;
X  struct inpcb *sockp;
X  caddr_t cad;
X  struct socket socket;
X  struct file file;
X  short sockmajor;
X  short sockminor;
X
X
X  /* -------------------- TCP PCB LIST -------------------- */
X  if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
X    return -1;
X  
X  tcb.inp_prev = (struct inpcb *) nl[N_TCB].n_value;
X
X  sockp = getlist(&tcb, faddr, fport, laddr, lport);
X  
X  if (!sockp)
X    return -1;
X
X  if (sockp->inp_protoopt & SO_IMASOCKET)
X  {
X
X    cad = followqueue(sockp); /* socket pointer */
X
X    if (!getbuf((long)cad, &socket, sizeof(struct socket), "socket"))
X      return -1;
X
X    if (!getbuf((long)socket.so_fp, &file, sizeof(struct file), "file"))
X      return -1;
X
X    if (!getbuf((long)file.f_inode, &inode, sizeof(struct inode), "inode"))
X      return -1;
X
X    *uid = inode.i_uid;
X    return 0;
X  } else {
X
X    /* we just need to determine the major number of the tcp module, which
X       is the minor number of the tcp clone device /dev/tcp */
X    if (stat("/dev/inet/tcp", &s))
X      ERROR("stat(\"/dev/inet/tcp\")");
X  
X    sockmajor = major(s.st_rdev);
X    sockminor = sockp->inp_minor;
X
X    if (!getbuf(nl[N_V].n_value, &v, sizeof(struct var), "var"))
X      return -1;
X
X    for (i = 0; i < v.v_inode; i++) {
X
X      if (!getbuf(((long) v.ve_inode) + i * sizeof(struct inode),
X	  &inode, sizeof(struct inode), "inode"))
X	return -1;
X    
X      if (((inode.i_ftype & IFMT) == IFCHR) &&
X	  (major(inode.i_rdev) == sockmajor) &&
X	  (minor(inode.i_rdev) == sockminor))
X      {
X	*uid = inode.i_uid;
X	return 0;
X      }
X    }
X    return -1;
X  }
}
X
X
SHAR_EOF
  $shar_touch -am 0812010593 'pidentd-2.7/src/kernel/sco324.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/sco324.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/sco324.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'pidentd-2.7/src/kernel/sco324.c:' 'MD5 check failed'
c61593cf3cdcdff689b4bfbec7a678cc  pidentd-2.7/src/kernel/sco324.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/sco324.c'`"
    test 10406 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/sco324.c:' 'original size' '10406,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/sco32_42+5.c ==============
if test -f 'pidentd-2.7/src/kernel/sco32_42+5.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/sco32_42+5.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/sco32_42+5.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/sco32_42+5.c' &&
/*
X * kernel/sco3242_325.c - kernel access functions for SCO 3.2v4.2
X *			  and 3.2v5.0.0
X */
X
X
/*
X * Copyright 1995 Purdue Research Foundation, West Lafayette, Indiana
X * 47907.  All rights reserved.
X *
X * Written by Victor A. Abell <abe@cc.purdue.edu>
X *
X * This software is not subject to any license of the American Telephone
X * and Telegraph Company or the Regents of the University of California.
X *
X * Permission is granted to anyone to use this software for any purpose on
X * any computer system, and to alter it and redistribute it freely, subject
X * to the following restrictions:
X *
X * 1. Neither the authors nor Purdue University are responsible for any
X *    consequences of the use of this software.
X *
X * 2. The origin of this software must not be misrepresented, either by
X *    explicit claim or by omission.  Credit to the authors and Purdue
X *    University must appear in documentation and sources.
X *
X * 3. Altered versions must be plainly marked as such, and must not be
X *    misrepresented as being the original software.
X *
X * 4. This notice may not be removed or altered.
X */
X
/*
X * MODIFICATION HISTORY
X *
X * 95/06/05 created by Victor A. Abell <abe@cc.purdue.edu>
X *
X *
X * 95/07/30 modified by Bela Lubkin <belal@sco.com>
X *     -- Added code to find the real socket head, which may be hidden
X *        behind an in-kernel rlogind/telnetd stream head.
X *
X * 95/07/31 modified by Victor A. Abell <abe@cc.purdue.edu>
X *     -- Moved reading of TCP control block into k_getuid() so it will
X *	  be initialized at each call of k_getuid(), thus enabling the
X *	  -b abd -w modes to function properly.
X */
X
#include <stdio.h>
#include <fcntl.h>
#include <nlist.h>
#include <malloc.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
X
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stream.h>
#include <sys/file.h>
#include <sys/immu.h>
#include <sys/inode.h>
#include <sys/region.h>
#include <sys/proc.h>
#include <sys/socket.h>
X
#if	sco<500
#include <sys/net/protosw.h>
#include <sys/net/socketvar.h>
#else	/* sco>=500 */
#include <sys/protosw.h>
#include <sys/socketvar.h>
#endif	/* sco<500 */
X
#include <sys/sysi86.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <sys/var.h>
X
#include <sys/netinet/in.h>
#include <sys/net/route.h>
#include <sys/netinet/in_pcb.h>
X
#if   sco>=500
#define       _INKERNEL
#include <sys/net/iknt.h>
#undef        _INKERNEL
#endif	/* sco>=500 */
X
/*
X * This confusing sequence of redefinitions of xdevmap allows the sizing
X * of the copy of the kernel's xdevmap[] table to be dynamic, based on the
X * kernel's nxdevmaps value.
X *
X * The net result is that there is a dummy struct XDEVMAP[1] that is never
X * used.  The copy of the kernel's xdevmap[] table is stored in the space
X * malloc()'d in k_open() and addressed by Xdevmap.  The last redefinition
X * of xdevmap to Xdevmap causes the macroes of <sys/sysmacros.h> to use
X * Xdevmap.
X *
X * All this is done: 1) to avoid having to allocate a large amount of fixed
X * space in advance to a copy of the kernel's xdevmap; and 2) to keep CC from
X * complaining about the absence of a "struct xdevmap xdevmap[]," matching
X * the "extern struct xdevmap xdevmap[]" declaration in <sys/sysmacros.h>,
X * while still allowing the use of the equivalent of a "struct xdevmap *"
X * construct instead, particularly with the kernel forms of the major() and
X * minor() macroes.
X */
X
#define	xdevmap XDEVMAP
#define	_INKERNEL
#include <sys/sysmacros.h>
#undef	_INKERNEL
static struct XDEVMAP XDEVMAP[1], *Xdevmap;
#undef	xdevmap
#define	xdevmap Xdevmap
X
#include "identd.h"
#include "error.h"
X
X
/*
X * Local definitions
X */
X
#define	KMEM		"/dev/kmem"	/* kernel memory device */
#define	N_UNIX		"/unix"		/* kernel image */
#define	PROCBFRD	32		/* proc structure buffer size */
X
X
/*
X * Local variables
X */
X
static int Kmem = -1;			/* kernel memory file descriptor */
static off_t Kp = (off_t)NULL;		/* proc table address */
static int nxdevmaps = -1;		/* maximum kernel xdevmap[] index */
X
struct nlist Nl[] = {			/* kernel image name list */
X
X	{ "nxdevmaps",	0, 0, 0, 0, 0 },
#define	X_NXD					0
X
X	{ "proc",	0, 0, 0, 0, 0 },
#define	X_PROC					1
X
X	{ "sockdev",	0, 0, 0, 0, 0 },
#define	X_SDEV					2
X
X	{ "socktab",	0, 0, 0, 0, 0 },
#define	X_STAB					3
X
X	{ "tcb",	0, 0, 0, 0, 0 },
#define	X_TCB					4
X
X	{ "v",		0, 0, 0, 0, 0 },
#define	X_VAR					5
X
X	{ "xdevmap",	0, 0, 0, 0, 0 },
#define	X_XDEV					6
X
#if   sco>=500
X	{ "ikntrinit",  0, 0, 0, 0, 0 },
#define X_IKNTR					7
#endif /* sco>=500 */
X
X	{ NULL,         0, 0, 0, 0, 0 }
};
X
static char *Psb;			/* proc structure buffer */
static int Sdev;			/* kernel's socket device */
static off_t Stab;			/* kernel's socket table address */
static char *Uab;			/* user area buffer */
static struct var Var;			/* kernel var struct */
X
X
/*
X * k_open() - open access to kernel memory
X */
X
int
k_open()
{
X	int err, i;
X	size_t len;
X
X	if ((Kmem = open(KMEM, O_RDONLY, 0)) < 0)
X		ERROR1("main: open(%s)", KMEM);
/*
X * Get the kernel name list and check it.
X */
X	if (nlist(N_UNIX, Nl) < 0)
X		ERROR1("main: nlist(%s)", N_UNIX);
X	for (err = i = 0; Nl[i].n_name; i++) {
X		if (Nl[i].n_value == (long)NULL) {
X
#if   sco>=500
X			if (i == X_IKNTR)
X			
X			/*
X			 * The ikntrinit kernel entry point is optional, so
X			 * it's OK if nlist() fails to find its address.
X			 */
X				continue;
#endif	/* sco>=500 */
X
X			if (syslog_flag)
X				syslog(LOG_ERR, "no kernel address for %s",
X					Nl[i].n_name);
X			(void) fprintf(stderr, "no kernel address for %s\n",
X				Nl[i].n_value);
X			err++;
X		}
X	}
X	if (err)
X
k_open_err_exit:
X
X		ERROR("main: k_open");
/*
X * Read or set kernel values:
X *
X *	Kp = process table address;
X *	Sdev = socket device major number;
X *	Stab = socket table address;
X *	Var = kernel environment structure.
X */
X	Kp = (off_t)Nl[X_PROC].n_value;
X	if (kread((off_t)Nl[X_SDEV].n_value, (char *)&Sdev, sizeof(Sdev))) {
X		if (syslog_flag)
X			syslog(LOG_ERR, "sockdev read (%#x)",
X				Nl[X_SDEV].n_name);
X		(void) fprintf(stderr, "sockdev read (%#x)\n",
X			Nl[X_SDEV].n_name);
X		err++;
X	}
X	Stab = (off_t)Nl[X_STAB].n_value;
X	if (kread((off_t)Nl[X_VAR].n_value, (char *)&Var, sizeof(Var))) {
X		if (syslog_flag)
X			syslog(LOG_ERR, "var struct read (%#x)",
X				Nl[X_VAR].n_name);
X		(void) fprintf(stderr, "var struct read (%#x)\n",
X			Nl[X_VAR].n_name);
X		err++;
X	}
X	if (err)
X		goto k_open_err_exit;
/*
X * Get extended device table parameters.  These are needed by the kernel
X * versions of the major() and minor() device numbers; they identify socket
X * devices and assist in the conversion of socket device numbers to socket
X * table addresses.
X */
X	if (kread((off_t)Nl[X_NXD].n_value, (char *)&nxdevmaps,
X		sizeof(nxdevmaps))
X	)
X		ERROR1("main: k_open nxdevmaps read (%#x)", Nl[X_NXD].n_name);
X	if (nxdevmaps < 0)
X		ERROR1("main: k_open nxdevmaps size (%d)", nxdevmaps);
X	len = (size_t)((nxdevmaps + 1) * sizeof(struct XDEVMAP));
X	if ((Xdevmap = (struct XDEVMAP *)malloc(len)) == (struct XDEVMAP *)NULL)
X		ERROR1("main: xdevmap malloc (%d)", len);
X	if (kread((off_t)Nl[X_XDEV].n_value, (char *)Xdevmap, len))
X		ERROR1("main: xdevmap read (%#x)", Nl[X_XDEV].n_value);
/*
X * Allocate user area and proc structure buffers.
X */
X	if ((Uab = (char *)malloc(MAXUSIZE * NBPC)) == (char *)NULL)
X		ERROR1("main: k_open user struct size (%d)", MAXUSIZE * NBPC);
X	if ((Psb = (char *)malloc(sizeof(struct proc) * PROCBFRD)) == NULL)
X		ERROR1("main: k_open proc stuct size (%d)",
X			sizeof(struct proc) * PROCBFRD);
X	return(0);
}
X
X
/*
X * k_getuid() - get User ID for local and foreign TCP address combination
X *
X * returns: -1 if address combination not found
X *	     0 if address combination found and:
X *			*uid = User ID of process with open socket file
X *			       having the address combination
X */
X
int
k_getuid(faddr, fport, laddr, lport, uid)
X	struct in_addr *faddr;		/* foreign network address */
X	int fport;			/* foreign port */
X	struct in_addr *laddr;		/* local network address */
X	int lport;			/* local port */
X	int *uid;			/* returned UID pointer */
{
X	struct file f;
X	int i, j, nf, pbc, px;
X	struct inode in;
X	struct proc *p;
X	struct inpcb pcb, tcb;
X	struct queue *q, qb;
X	off_t sa, spa;
X	struct user *u;
X
#if   sco>=500
X	iknt_t ikb;
#endif /* sco>=500 */
X
/*
X * Search the kernel's TCP control block chain for one whose local and foreign
X * addresses match.
X */
X	if (kread((off_t)Nl[X_TCB].n_value, (char *)&tcb, sizeof(tcb))) {
X		if (syslog_flag)
X			syslog(LOG_ERR, "TCP struct read (%#x)",
X				Nl[X_TCB].n_name);
X		(void) fprintf(stderr, "TCB struct read (%#x)\n",
X			Nl[X_TCB].n_name);
X		ERROR("k_getuid: no TCP control block head");
X	}
X	i = 0;
X	pcb = tcb;
X	do {
X		if (pcb.inp_faddr.s_addr == faddr->s_addr
X		&&  pcb.inp_laddr.s_addr == laddr->s_addr
X		&&  pcb.inp_fport == fport && pcb.inp_lport == lport) {
X			i = 1;
X			break;
X		}
X	} while (pcb.inp_next != (struct inpcb *)NULL
X	     &&  pcb.inp_next != tcb.inp_prev
X	     &&  kread((off_t)pcb.inp_next, (char *)&pcb, sizeof(pcb)) == 0);
X	if ( ! i)
X		return(-1);
/*
X * Follow the stream input queue for the TCP control block to its end
X * to get the socket address.
X */
X	for (q = pcb.inp_q, qb.q_ptr = (caddr_t)NULL; q; q = qb.q_next) {
X		if (kread((off_t)q, (char *)&qb, sizeof(qb)))
X			return(-1);
X	}
X
#if   sco>=500
/*
X * If this is an in-kernel rlogind/telnetd stream head, follow its private
X * pointer back to the original stream head where the socket address may
X * be found.
X */
X	if (Nl[X_IKNTR].n_value && qb.q_qinfo
X	&&  qb.q_qinfo == (struct qinit *)Nl[X_IKNTR].n_value) {
X		if (kread((off_t)qb.q_ptr, (char *)&ikb, sizeof(ikb)))
X			return(-1);
X		qb.q_ptr = ikb.ik_oqptr;
X	}
#endif /* sco>=500 */
X
X	if (qb.q_ptr == (caddr_t)NULL)
X		return(-1);
/*
X * Search the process table, the user structures associated with its proc
X * structures, and the open file structures associated with the user structs
X * to find an inode whose major device is Sdev and whose socket structure's
X * address matches the address identified from the TCB control block scan.
X */
X	for (pbc = px = 0, u = (struct user *)Uab; px < Var.v_proc; px++) {
X		if (px >= pbc) {
X
X		/*
X		 * Refill the proc struct buffer.
X		 */
X			i = Var.v_proc - px;
X			if (i > PROCBFRD)
X				i = PROCBFRD;
X			j = kread((off_t)(Kp + (px * sizeof(struct proc))),
X				Psb, sizeof(struct proc) * i);
X			pbc = px + i;
X			if (j) {
X				px += i;
X				continue;
X			}
X			p = (struct proc *)Psb;
X		} else
X			p++;
X		if (p->p_stat == 0 || p->p_stat == SZOMB)
X			continue;
X	/*
X	 * Get the user area for the process and follow its file structure
X	 * pointers to their inodes.  Compare the addresses of socket
X	 * structures to the address located in the TCP control block scan
X	 * and return the User ID of the first process that has a match.
X	 */
X		if (sysi86(RDUBLK, (int)p->p_pid, Uab, MAXUSIZE * NBPC) == -1)
X			continue;
X		nf = u->u_nofiles ? u->u_nofiles : Var.v_nofiles;
X		for (i = 0; i < nf; i++) {
X			if (u->u_ofile[i] == (struct file *)NULL
X			||  kread((off_t)u->u_ofile[i], (char *)&f, sizeof(f))
X			||  f.f_count == 0
X			||  f.f_inode == (struct inode *)NULL
X			||  kread((off_t)f.f_inode, (char *)&in, sizeof(in)))
X				continue;
X			if ((in.i_ftype & IFMT) != IFCHR
X			||  major(in.i_rdev) != Sdev)
X				continue;
X			spa = Stab + (minor(in.i_rdev)*sizeof(struct socket *));
X			if (kread(spa, (char *)&sa, sizeof(sa)))
X				continue;
X			if ((caddr_t)sa == qb.q_ptr) {
X				*uid = (int)p->p_uid;
X				return(0);
X			}
X		}
X	}
X	return(-1);
}
X
X
/*
X * kread() - read from kernel memory
X */
X
int
kread(addr, buf, len)
X	off_t addr;			/* kernel memory address */
X	char *buf;			/* buffer to receive data */
X	unsigned len;			/* length to read */
{
X	int br;
X
X	if (lseek(Kmem, (off_t)addr, SEEK_SET) == (off_t)-1L)
X		return(1);
X	if ((br = read(Kmem, buf, len)) < 0)
X		return(1);
X	return(((unsigned)br == len) ? 0 : 1);
}
X
SHAR_EOF
  $shar_touch -am 0803172795 'pidentd-2.7/src/kernel/sco32_42+5.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/sco32_42+5.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/sco32_42+5.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'pidentd-2.7/src/kernel/sco32_42+5.c:' 'MD5 check failed'
90fe831c853b8a1375398832ecb68276  pidentd-2.7/src/kernel/sco32_42+5.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/sco32_42+5.c'`"
    test 11768 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/sco32_42+5.c:' 'original size' '11768,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/sunos4.c ==============
if test -f 'pidentd-2.7/src/kernel/sunos4.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/sunos4.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/sunos4.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/sunos4.c' &&
/*
** kernel/sunos4.c                 SunOS 4 kernel access fnctions
**
** This program is in the public domain and may be used freely by anyone
** who wants to. 
**
** Last update: 8 Mar 1993
**
** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
*/
X
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <nlist.h>
#include <pwd.h>
#include <signal.h>
#include <syslog.h>
X
#include <kvm.h>
X
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
X
#include <sys/socketvar.h>
X
#define KERNEL
#include <sys/file.h>
X
#include <fcntl.h>
X
#include <sys/user.h>
#include <sys/wait.h>
X  
#undef KERNEL
X
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
X
#include <netinet/in_pcb.h>
X
#include <netinet/tcp.h>
#include <netinet/ip_var.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
X
#include <arpa/inet.h>
X
#include "identd.h"
#include "error.h"
X
X
extern void *calloc();
extern void *malloc();
X
X
struct nlist nl[] =
{
#define N_FILE 0  
#define N_NFILE 1
#define N_TCB 2
X
#ifdef i386
X  { "file" },
X  { "nfile" },
X  { "tcb" },
#else
X  { "_file" },
X  { "_nfile" },
X  { "_tcb" },
#endif
X  { "" }
};
X
static kvm_t *kd;
X
static struct file *xfile;
X
static struct inpcb tcb;
X
X
int k_open()
{
X  int rcode;
X  
X  /*
X  ** Open the kernel memory device
X  */
X  if (!(kd = kvm_open(path_unix, path_kmem, NULL, O_RDONLY, NULL)))
X    ERROR("main: kvm_open");
X  
X  /*
X  ** Extract offsets to the needed variables in the kernel
X  */
X  if ((rcode = kvm_nlist(kd, nl)) != 0)
X      if (rcode != 3)
X	  ERROR1("main: kvm_nlist, rcode = %d", rcode);
X
X  return 0;
}
X
X
/*
** Get a piece of kernel memory with error handling.
** Returns 1 if call succeeded, else 0 (zero).
*/
static int getbuf(addr, buf, len, what)
X  long addr;
X  char *buf;
X  int len;
X  char *what;
{
X
X  if (kvm_read(kd, addr, buf, len) < 0)
X  {
X    if (syslog_flag)
X      syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
X	     addr, len, what);
X
X    return 0;
X  }
X  
X  return 1;
}
X
X
X
/*
** Traverse the inpcb list until a match is found.
** Returns NULL if no match.
*/
static struct socket *
X    getlist(pcbp, faddr, fport, laddr, lport)
struct inpcb *pcbp;
struct in_addr *faddr;
int fport;
struct in_addr *laddr;
int lport;
{
X  struct inpcb *head;
X  int limiter = 65536;	/* avoid infinite loop <umura@nn.solan.chubu.ac.jp> */
X  
X  if (!pcbp)
X    return NULL;
X
X  head = pcbp->inp_prev;
X  do 
X  {
X    if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
X	 pcbp->inp_laddr.s_addr == laddr->s_addr &&
X	 pcbp->inp_fport        == fport &&
X	 pcbp->inp_lport        == lport )
X      return pcbp->inp_socket;
X    if (--limiter <= 0)	/* avoid infinite loop <umura@nn.solan.chubu.ac.jp> */
X        break;
X
X  } while (pcbp->inp_next != head &&
X	   getbuf((long) pcbp->inp_next,
X		  pcbp,
X		  sizeof(struct inpcb),
X		  "tcblist"));
X
X  return NULL;
}
X
X
X
/*
** Return the user number for the connection owner
*/
int k_getuid(faddr, fport, laddr, lport, uid)
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
X  int *uid;
{
X  long addr;
X  
X  struct socket *sockp;
X  int i;
X  struct ucred ucb;
X  
X  /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
X  if (!getbuf(nl[N_NFILE].n_value, &nfile, sizeof(nfile), "nfile"))
X    return -1;
X  
X  if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
X    return -1;
X
X  xfile = (struct file *) calloc(nfile, sizeof(struct file));
X  if (!xfile)
X    ERROR2("k_getuid: calloc(%d,%d)", nfile, sizeof(struct file));
X  
X  if (!getbuf(addr, xfile, sizeof(struct file)*nfile, "file[]"))
X    return -1;
X
X  /* -------------------- TCP PCB LIST -------------------- */
X  if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
X    return -1;
X  
X  tcb.inp_prev = (struct inpcb *) nl[N_TCB].n_value;
X  sockp = getlist(&tcb, faddr, fport, laddr, lport);
X  
X  if (!sockp)
X    return -1;
X
X  /*
X  ** Locate the file descriptor that has the socket in question
X  ** open so that we can get the 'ucred' information
X  */
X  for (i = 0; i < nfile; i++)
X  {
X    if (xfile[i].f_count == 0)
X      continue;
X    
X    if (xfile[i].f_type == DTYPE_SOCKET &&
X	(struct socket *) xfile[i].f_data == sockp)
X    {
X      if (!getbuf(xfile[i].f_cred, &ucb, sizeof(ucb), "ucb"))
X	return -1;
X      
X      *uid = ucb.cr_ruid;
X      return 0;
X    }
X  }
X  
X  return -1;
}
X
SHAR_EOF
  $shar_touch -am 0811220196 'pidentd-2.7/src/kernel/sunos4.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/sunos4.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/sunos4.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'pidentd-2.7/src/kernel/sunos4.c:' 'MD5 check failed'
deb34dffa469fe9166586b4ecd09ed0e  pidentd-2.7/src/kernel/sunos4.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/sunos4.c'`"
    test 4380 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/sunos4.c:' 'original size' '4380,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/sunos5.c ==============
if test -f 'pidentd-2.7/src/kernel/sunos5.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/sunos5.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/sunos5.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/sunos5.c' &&
/*
** kernel/sunos5.c                 SunOS 5 kernel access functions
**
** This program is in the public domain and may be used freely by anyone
** who wants to. 
**
** Author: Casper Dik <casper@fwi.uva.nl>
**
** Last update: 13 Oct 1994
**
** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
*/
X
#if 0
#define DEBUGHASH
#endif
X
#define _KMEMUSER
#define _KERNEL
X
/* some definition conflicts. but we must define _KERNEL */
X
#define exit 		kernel_exit
#define strsignal	kernel_strsignal
X
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <sys/param.h>
#include <netinet/in.h>
X
#include <stdio.h>
#include <kvm.h>
#include <nlist.h>
#include <math.h>
#include <sys/fcntl.h>
#include <sys/cred.h>
#include <sys/file.h>
#include <sys/stream.h>
#include <inet/common.h>
#include <inet/ip.h>
X
#ifdef ipc_tcp_laddr
#define SOLARIS24 1
#define BROKEN_HASH
/*
X * In Solaris 2.4 there have been a number of changes:
X * - the ipc_s structure had its field names changed
X * - the file global no longer exists in the kernel.
X * (this sort of makes sense for MP machines: having to go through
X * one global lock for all file opens/closes doesn't scale
X * very well)
X */
#endif
X
#undef exit
#undef strsignal
X
#include <unistd.h>
#include <string.h>
#include <stddef.h>
X
#include "identd.h"
#include "error.h"
X
#define N_FANOUT 0
#ifndef SOLARIS24
#define N_FILE	 1
#endif
X
struct nlist nl[] = {
X	{ "ipc_tcp_fanout" },
#ifndef SOLARIS24
X	{ "file" },
#endif
X	{ 0 },
};
X
X
static kvm_t *kd;
X
X
int k_open()
#ifdef SOLARIS24_WORKAROUND
{
X    return 0;
}
X
static int local_k_open()
#endif
{
X  /*
X  ** Open the kernel memory device
X  */
X  if (!(kd = kvm_open(path_unix, path_kmem, NULL, O_RDONLY, NULL)))
X    ERROR("main: kvm_open");
X  
X  /*
X  ** Extract offsets to the needed variables in the kernel
X  */
X  if (kvm_nlist(kd, nl) != 0)
X    ERROR("main: kvm_nlist");
X  
X  return 0;
}
X
#ifdef SOLARIS24_WORKAROUND
static void local_k_close()
{
X    kvm_close(kd);
}
#endif
X
/*
** Get a piece of kernel memory with error handling.
** Returns 1 if call succeeded, else 0 (zero).
*/
static int getbuf(addr, buf, len, what)
X  long addr;
X  char *buf;
X  int len;
X  char *what;
{
X    int i, status;
X
X
X    i = 0;
X    while (i < 10 && (status = kvm_read(kd, addr, buf, len)) < 0)
X	++i;
X
X    if (status < 0)
X	return 0;
X  
X    return 1;
}
X
X
/*
** Return the user number for the connection owner
*/
int k_getuid(faddr, fport, laddr, lport, uid)
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
X  int *uid;
#ifdef SOLARIS24_WORKAROUND
{
X    extern int local_k_getuid();
X    int result;
X
X    
X    local_k_open();
X    result = local_k_getuid(faddr, fport, laddr, lport, uid);
X    local_k_close();
X
X    return result;
}
X
X
static int local_k_getuid(faddr, fport, laddr, lport, uid)
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
X  int *uid;
#endif
{
X    queue_t sqr
#ifndef SOLARIS24
X	,*qp, *pq
#endif
X	    ;
X    ipc_t ic, *icp;
X    unsigned short uslp, usfp;
X    unsigned int offset;
#ifndef SOLARIS24
X    unsigned long fp;
#endif
X    file_t tf;
X    unsigned long zero = 0;
X    u16 *ports;
X    u32 *locaddr, *raddr;
#ifdef DEBUGHASH
X    int i;
#endif
#ifdef SOLARIS24
X    struct proc *procp;
#endif
#ifdef BROKEN_HASH
X    ipc_t *alticp = 0;
X    unsigned int altoffset;
#endif
X    
X    usfp = fport;
X    uslp = lport;
X
#ifdef BROKEN_HASH
X    /* code used (ports > 8) instead of (ports >> 8)
X    /* low byte of local port number not used, low byte of 
X       local addres is used
X	ip_bind  in the kernel (+ approx 0x4c0)
X                srl     %i3, 0x18, %o0
X                xor     %i2, %o0, %o0
X                srl     %i3, 0x10, %o1
X                xor     %o0, %o1, %o0
X                xor     %o0, %l0, %o0
X                xor     %o0, %i3, %o0
X                and     %o0, 0xff, %o0
X                sethi   %hi(0xfc1d9c00), %o2
X                or      %o2, 0x1c0, %o2          ! ipc_tcp_fanout
X
X     */
#if (defined(BIG_ENDIAN) || defined(_BIG_ENDIAN))
X    altoffset = usfp >> 8;
#else
X    altoffset = uslp >> 8;
#endif
X    altoffset ^= usfp ^ uslp;
X    altoffset ^= faddr->S_un.S_un_b.s_b4;
X    if (uslp > 8 || usfp != 0)
X	altoffset ^= 1;
X    altoffset &= 0xff;
X    if (!getbuf(nl[N_FANOUT].n_value + sizeof(ipc_t *) * altoffset,
X		(char *) &alticp,
X		sizeof(ipc_t *),
X		"ipc_tcp_fanout[altoffset]"))
X	alticp = 0;
#endif
X    offset = usfp ^ uslp;
X    offset ^= (unsigned) faddr->S_un.S_un_b.s_b4 ^ (offset >> 8);
X    offset &= 0xff;
X
X    if (!getbuf(nl[N_FANOUT].n_value + sizeof(ipc_t *) * offset,
X		(char *) &icp,
X		sizeof(ipc_t *),
X		"ipc_tcp_fanout[offset]"))
X	return -1;
X    
#ifdef BROKEN_HASH
X    if (icp == 0 && alticp != 0) {
X	icp = alticp;
X	alticp = 0;
X    }
#endif
#ifndef DEBUGHASH
X    if (icp == 0) {
X	syslog(LOG_INFO, "k_getuid: Hash miss");
X	return -1;
X    }
#endif
X
#ifdef SOLARIS24
X    locaddr = &ic.ipc_tcp_laddr;
X    raddr = &ic.ipc_tcp_faddr;
X    ports = (u16*) &ic.ipc_tcp_ports;
#else
X    locaddr = (u32*) &ic.ipc_tcp_addr[0];
X    raddr = (u32*) &ic.ipc_tcp_addr[2];
X    ports = &ic.ipc_tcp_addr[4];
#endif
X
#ifdef DEBUGHASH
X  for (i = 0; i < 256; i++) {
X    if (!getbuf(nl[N_FANOUT].n_value + sizeof(ipc_t *) * i,
X		(char *) &icp,
X		sizeof(ipc_t *),
X		"ipc_tcp_fanout[offset]"))
X	return -1;
X    if (icp == 0)
X	continue;
#endif
X
X    while (icp) {
X	if (!getbuf((unsigned long) icp,
X		    (char *) &ic,
X		    sizeof(ic),
X		    "hash entry"))
X	    return -1;
X
#if 0
X	printf("E: %s:%d -> ", inet_ntoa(*laddr), ntohs(ports[1]));
X	printf("%s:%d\n", inet_ntoa(*faddr), ntohs(ports[0]));
#endif
X	if (usfp == ports[0] && /* remote port */
X	    uslp == ports[1] && /* local port */
#if 0
X	    memcmp(&laddr->s_addr, locaddr, 4) == 0 && /* local */
#else
X 	    (memcmp(&laddr->s_addr, locaddr, 4) == 0 ||
X 	    /* In SunOS 5.3, the local part can be all zeros */
X 	     memcmp(&zero, locaddr, 4) == 0) /* local */ &&
#endif
X	    memcmp(&faddr->s_addr, raddr, 4) == 0)
X		break;
X	icp = ic.ipc_hash_next;
#ifdef BROKEN_HASH
X	if (icp == 0 && alticp != 0) {
X	    icp = alticp;
X	    alticp = 0;
X	}
#endif
X    }
#ifdef DEBUGHASH
X    if (icp)
X	break;
X  } /* for i */
X    if (icp)
X	printf("found, offset = %x, i = %x, i ^ offset = %x\n", offset,i,
X		offset ^ i);
#endif
X
X    if (!icp) {
X	syslog(LOG_INFO, "k_getuid: Port not found");
X	return -1;
X    }
X    
X    if (!getbuf((unsigned long) ic.ipc_rq+offsetof(queue_t, q_stream),
X		(char *) &sqr.q_stream,
X		sizeof(sqr.q_stream),
X		"queue.q_stream"))
X	return -1;
X
X    /* at this point sqr.q_stream holds the pointer to the stream we're
X       interested in. Now we're going to find the file pointer
X       that refers to the vnode that refers to this stream stream */
X
#ifdef SOLARIS24
X    /* Solaris 2.4 no longer links all file pointers together with
X     * f_next, the only way seems to be scrounging them from
X     * the proc/user structure, ugh.
X     */
X
X    if (kvm_setproc(kd) != 0)
X	return -1;
X
X    while ((procp = kvm_nextproc(kd)) != NULL) {
X	struct uf_entry files[NFPCHUNK];
X	int nfiles = procp->p_user.u_nofiles;
X	unsigned long addr = (unsigned long) procp->p_user.u_flist;
X
X	while  (nfiles > 0) {
X	    int nread = nfiles > NFPCHUNK ? NFPCHUNK : nfiles;
X	    int size = nread * sizeof(struct uf_entry);
X	    int i;
X	    struct file *last = 0;
X	    vnode_t vp;
X
X	    if (!getbuf(addr, (char*) &files[0], size, "ufentries")) {
X		return -1;
X	    }
X	    for (i = 0; i < nread; i++) {
X		if (files[i].uf_ofile == 0 || files[i].uf_ofile == last)
X		    continue;
X		if (!getbuf((unsigned long) (last = files[i].uf_ofile),
X			(char*) &tf, sizeof(tf), "file pointer")) {
X			    return -1;
X		}
X
X		if (!tf.f_vnode)
X		    continue;
X
X		if (!getbuf((unsigned long) tf.f_vnode +
X				offsetof(vnode_t,v_stream),
X				(char *) &vp.v_stream,
X				sizeof(vp.v_stream),"vnode.v_stream"))
X		    return -1;
X
X		if (vp.v_stream == sqr.q_stream) {
X		    cred_t cr;
X		    if (!getbuf((unsigned long) tf.f_cred +
X				    offsetof(cred_t, cr_ruid),
X				(char *) &cr.cr_ruid,
X				sizeof(cr.cr_ruid),
X				"cred.cr_ruid"))
X			return -1;
X		    *uid = cr.cr_ruid;
X		    return 0;
X		}
X	    }
X	    nfiles -= nread;
X	    addr += size;
X	}
X    }
#else
X    fp = nl[N_FILE].n_value;
X    for (;fp;fp = (unsigned long) tf.f_next) {
X	vnode_t vp;
X
X	if (!getbuf(fp, (char *) &tf, sizeof(file_t),"file pointer"))
X	    return -1;
X
X	if (!tf.f_vnode)
X	    continue;
X
X	if (!getbuf((unsigned long) tf.f_vnode + offsetof(vnode_t,v_stream),
X			(char *) &vp.v_stream,
X			sizeof(vp.v_stream),"vnode.v_stream"))
X	    return -1;
X
X	if (vp.v_stream == sqr.q_stream) {
X	    cred_t cr;
X	    if (!getbuf((unsigned long) tf.f_cred + offsetof(cred_t, cr_ruid),
X			(char *) &cr.cr_ruid,
X			sizeof(cr.cr_ruid),
X			"cred.cr_ruid"))
X		return -1;
X	    *uid = cr.cr_ruid;
X	    return 0;
X	}
X    }
#endif
X    return -1;
}
SHAR_EOF
  $shar_touch -am 0811235996 'pidentd-2.7/src/kernel/sunos5.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/sunos5.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/sunos5.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'pidentd-2.7/src/kernel/sunos5.c:' 'MD5 check failed'
c8d846f2cf55a956dd629bb28cc9b347  pidentd-2.7/src/kernel/sunos5.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/sunos5.c'`"
    test 8786 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/sunos5.c:' 'original size' '8786,' 'current size' "$shar_count!"
  fi
fi
: || $echo 'restore of' 'pidentd-2.7/src/kernel/svr4.c' 'failed'
$echo 'End of part' '7,' 'continue with part' '8'
exit 0


