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

#!/bin/sh
# This is part 06 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/irix5.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/irix5.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/irix5.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/irix5.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/irix5.c' &&
/*
** kernel/irix5.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: 26 Jan 1995
**
** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
**
**
** Hacked to work with irix5, 27 May 1994 by
** Robert Banz (banz@umbc.edu) Univ. of Maryland, Baltimore County
**
** does some things the irix4 way, some the svr4 way, and some just the 
** silly irix5 way.
**
** Hacked to work with irix5.3, 26 Jan 1995 by
** Frank Maas (maas@wi.leidenuniv.nl) Leiden University, The Netherlands
** but all the credits go to Robert Banz (again), who found out about the
** hacks and included them in sources for pidentd-2.3.
**
*/
#define _KMEMUSER
X
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <nlist.h>
#include <pwd.h>
#include <signal.h>
#include <syslog.h>
#include "kvm.h"
X
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/cred.h>
#include <sys/socketvar.h>
#ifdef IRIX53
/** hack 1: IRIX 5.3 uses 64bit int's for file offsets in the kernel **/
/**         but a 32bit int is used in user programs. sadly though,  **/
/**         there is no way of using <sys/file.h> properly, so we    **/
/**         create our own struct.                                   **/
typedef struct file {
X   struct file 	  *f_next;
X   struct file 	  *f_prev;
X   int 		  f_flag;	/* ushort in <sys/file.h> */
X   cnt_t 	  f_count;
X   unsigned short f_lock;	/* lock_t (uint) in <sys/file.h> */
X   struct vnode   *f_vnode;
X   __uint64_t 	  f_offset;	/* off_t (long) in <sys/file.h> */
X   struct cred 	  *f_cred;
X   cnt_t 	  f_msgcount;
} file_t;
#elif defined(IRIX62)
typedef struct file {
X    struct file     *f_next;
X    struct file     *f_prev;
X    __uint64_t      f_offset; /* off_t (long) in <sys/file.h>  */
X    lock_t          f_lock;     /* lock_t (uint) in <sys/file.h> */
X    ushort          f_flag;     /* ushort in <sys/file.h>        */
X    cnt_t           f_count;
X    cnt_t           f_msgcount;
X    mutex_t         f_offlock;
X    struct vnode    *f_vnode;
X    struct  cred    *f_cred;
} file_t;
#else
#include <sys/file.h>
#endif	/* IRIX53 */
X
#if defined(IRIX6) || (defined(IRIX62) && (_MIPS_SZPTR == 64))
#define nlist nlist64
#endif
X
/** Well... here some problems begin: when upgrading IRIX to 5.3 the **/
/** `inst' program shows one of its peculiar bugs: the file vnode.h  **/
/** has changed location in between versions and now the file is up- **/
/** grade first (new package) and then deleted (old package). So if  **/
/** you have problems finding this file: reinstall eoe1.sw.unix.     **/
#include <sys/vnode.h>
X
#include <fcntl.h>
X
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
X
#ifdef IRIX62
#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>
#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_TCB  1
X 
X  { "file" },
X  { "tcb" },
X  { "" }
};
X
static kvm_t *kd;
X
static struct file *xfile;
static int nfile;
X
static struct inpcb tcb;
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
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
/*
** Traverse the inpcb list until a match is found.
** Returns NULL if no match.
** (this is basically the same as the irix4 code)
*/
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;
{
#ifdef IRIX62
X     int num = pcbp->inp_u.pcb_u2.u2_tablesz;
X     struct inpcb **u2_cache;
X 
X     u2_cache = malloc(num * sizeof(struct inpcb *));
X     if (!u2_cache) return NULL;
X 
X     getbuf((long)pcbp->inp_u.pcb_u2.u2_cache, u2_cache, num * sizeof(struct inpcb *), "tcblist");
X     
X     for (num-- ; num >= 0; num--) {
X       if (!u2_cache[num]) continue;
X       if (!getbuf((long)u2_cache[num], pcbp, sizeof(struct inpcb), "tcbcacheentry")) break;
X       if (pcbp->inp_faddr.s_addr != faddr->s_addr) continue;
X       if (pcbp->inp_laddr.s_addr != laddr->s_addr) continue;
X       if (pcbp->inp_fport        != fport)         continue;
X       if (pcbp->inp_lport        != lport)         continue;
X       free(u2_cache);
X       return pcbp->inp_socket;
X     }
X
X    free(u2_cache);
X    return NULL;
#else
X  struct inpcb *head;
/** hack 2: there is a slight problem when scanning through lists that **/
/**         change while identd scans; to prevent infinite loops a     **/
/**         counter is introduced                                      **/
X  int count = 0xffff;
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    }
X  } while ((count--) && pcbp->inp_next != head &&
X	   getbuf((long) pcbp->inp_next,
X		  pcbp,
X		  sizeof(struct inpcb),
X		  "tcblist"));
X  return NULL;
#endif
}
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  struct socket *sockp;
X  struct file *fp;
X  struct file file;
X  int count = 0xffff;	/** Yep, it's hack 2 again **/
X  
X  /* -------------------- TCP PCB LIST -------------------- */
X  if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb")) {
X    return -1;
X  }
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  /* -------------------- OPEN FILE TABLE ----------------- */
X
X  fp = (struct file *) nl[N_FILE].n_value;
X
X  if (!getbuf(fp,&file,sizeof(struct file), "file"))
X    return -1;
X
X  do {
X    struct vnode tvnode;
X    struct cred creds;
X
X    if (getbuf(file.f_vnode,&tvnode,sizeof(struct vnode),"vnode")){
X      if ((void *) sockp == (void *) tvnode.v_data) {
X	/* have a match!  return the user information! */
X	if (getbuf(file.f_cred,&creds,sizeof(struct cred),"cred")) {
X	  *uid = creds.cr_ruid;
X	  return 0;
X	}
X	break;
X      } 
X    }
X    /* if it's the end of the list _or_ we can't get the next
X       entry, then get out of here...*/
X    if ((!file.f_next) ||
X	(!getbuf(file.f_next,&file,sizeof(struct file), "file")))
X      break;
X    
X  } while (file.f_next != fp && (count--)); 
X	/* heck, if we ever get here, something is really messed up.*/
X  
X  syslog(LOG_ERR,"ident: k_getuid: lookup failure.");
X  return -1;
}
SHAR_EOF
  $shar_touch -am 0812011596 'pidentd-2.7/src/kernel/irix5.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/irix5.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/irix5.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/irix5.c:' 'MD5 check failed'
4f45a00bdc50defbcd816c8cfc904baa  pidentd-2.7/src/kernel/irix5.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/irix5.c'`"
    test 7394 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/irix5.c:' 'original size' '7394,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/aux.c ==============
if test -f 'pidentd-2.7/src/kernel/aux.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/aux.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/aux.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/aux.c' &&
/*
** kernel/aux.c		Low level kernel access functions for A/UX
**
** This program is in the public domain and may be used freely by anyone
** who wants to. 
**
** Last update: 20 April 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/config.h>
X
#include <sys/socketvar.h>
X
#define KERNEL
X
#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[3];
X
static kvm_t *kd;
X
static struct file *xfile;
X
static int nfile;
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  /* Kludge - have to do it here or A/UX 3 will barf */
#define N_FILE 0  
#define N_TCB 1
#ifdef n_name
X  strcpy(nl[N_FILE].n_name,"file");
X  strcpy(nl[N_TCB].n_name,"tcb");
X  strcpy(nl[2].n_name,"");
#else
X  nl[N_FILE].n_name = "file";
X  nl[N_TCB].n_name  = "tcb";
X  nl[2].n_name = "";
#endif
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
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 &&
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  struct socket *sockp;
X  int i;
X  struct ucred ucb;
X  
X  /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
X  nfile = NFILE;
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 0425230193 'pidentd-2.7/src/kernel/aux.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/aux.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/aux.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/aux.c:' 'MD5 check failed'
67b839b4c00419e8b9b1ae7d7591b706  pidentd-2.7/src/kernel/aux.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/aux.c'`"
    test 4240 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/aux.c:' 'original size' '4240,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/aux301.c ==============
if test -f 'pidentd-2.7/src/kernel/aux301.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/aux301.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/aux301.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/aux301.c' &&
/*
** kernel/aux301.c	Low level kernel access functions for
**                      A/UX 3.0.1 and newer
**
** This program is in the public domain and may be used freely by anyone
** who wants to. 
**
** Last update: 17 September 1995 by Herb Weiner <herbw@wiskit.com>
**
** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
*/
X
#include <stdio.h>
#include <errno.h>
#include <ctype.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/config.h>
X
#include <sys/socketvar.h>
X
#define KERNEL
X
#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/tcp_timer.h>
#include <netinet/tcp_var.h>
X
#include <arpa/inet.h>
X
#include "identd.h"
#include "error.h"
X
#include <a.out.h>
X
#include <sys/mmu.h>
#include <sys/var.h>
X
/*--------------------------------------------------------------
X * The Apple-supplied nlist(3c) function is seriously broken.
X * Here's a replacement.
X *--------------------------------------------------------------
X */
X
/*
X * Copyright (c) 1989 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X *    must display the following acknowledgement:
X *	This product includes software developed by the University of
X *	California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X *    may be used to endorse or promote products derived from this software
X *    without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
X
/*--------------------------------------------------------------------------
X * Ported to Apple A/UX by Herb Weiner <herbw@wiskit.com> September 16, 1995
X *--------------------------------------------------------------------------
X */
X
typedef struct nlist NLIST;
#define	ISVALID(p)	(p->n_nptr && p->n_nptr[0])
X
int nlist(name, list)
X	char	*name;
X	NLIST	*list;
{
X	register NLIST	*p;
X	register NLIST	*s;
X	struct filehdr	ebuf;
X	FILE			*fstr;
X	FILE			*fsym;
X	NLIST			nbuf;
X	off_t			strings_offset;
X	off_t			symbol_offset;
X	off_t			symbol_size;
X	int				entries;
X	int				len;
X	int				maxlen;
X	char			sbuf [256];
X	char			*np;
X
X	entries = -1;
X
X	if (!(fsym = fopen (name, "r")))
X		return(-1);
X
X	if (fread((char *)&ebuf, sizeof(struct filehdr), 1, fsym) != 1
X		|| BADMAG(&ebuf))
X		goto done1;
X
X	symbol_offset = ebuf.f_symptr;
X	symbol_size = ebuf.f_nsyms * sizeof (NLIST);
X	strings_offset = symbol_offset + symbol_size;
X	if (fseek(fsym, symbol_offset, SEEK_SET))
X		goto done1;
X
X	if (!(fstr = fopen(name, "r")))
X		goto done1;
X
X	/*
X	 * clean out any left-over information for all valid entries.
X	 * Type and value defined to be 0 if not found; historical
X	 * versions cleared other and desc as well.  Also figure out
X	 * the largest string length so don't read any more of the
X	 * string table than we have to.
X	 */
X	for (p = list, entries = maxlen = 0; ISVALID(p); ++p, ++entries)
X	{
X		p->n_value = 0;
X		p->n_type = 0;
X		p->n_scnum = 0;
X		p->n_sclass = 0;
X		p->n_numaux = 0;
X		if ((len = strlen(p->n_nptr)) > maxlen)
X			maxlen = len;
X	}
X	if (maxlen >= sizeof(sbuf))
X	{
X		(void)fprintf(stderr, "nlist: symbol too large.\n");
X		entries = -1;
X		goto done2;
X	}
X
X	for (s = &nbuf; symbol_size > 0; symbol_size -= sizeof(NLIST))
X	{
X		if (fread((char *)s, sizeof(NLIST), 1, fsym) != 1)
X			goto done2;
X		if (s->n_zeroes == 0)
X		{
X			if (!s->n_offset)
X				continue;
X			if (fseek(fstr, strings_offset + s->n_offset, SEEK_SET))
X				goto done2;
X			(void)fread(sbuf, sizeof(sbuf[0]), maxlen, fstr);
X			np = sbuf;
X		}
X		else
X			np = s->n_name;
X
X		for (p = list; ISVALID(p); p++)
X			if (!strcmp(p->n_nptr, np))
X			{
X				p->n_value = s->n_value;
X				p->n_type = s->n_type;
X				p->n_scnum = s->n_scnum;
X				p->n_sclass = s->n_sclass;
X				p->n_numaux = s->n_numaux;
X				if (!--entries)
X					goto done2;
X			}
X	}
done2:	(void)fclose(fstr);
done1:	(void)fclose(fsym);
X	return(entries);
}
X
/*--------------------------------------------------------------
X * End of replacement nlist(3c)
X *--------------------------------------------------------------
X */
X
extern void *calloc();
extern void *malloc();
X
#define N_FILE 0
#define N_TCB 1
#define N_V 2
#define N_LAST 3
X
struct nlist nl [N_LAST+1];
X
static kvm_t *kd;
X
static struct file *xfile;
X
static int nfile;
X
static struct inpcb tcb;
X
X
int k_open()
{
X  path_unix = "/unix";
X  path_kmem = "/dev/kmem";
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  /* Kludge - have to do it here or A/UX 3 will barf */
X
X  nl[N_FILE].n_nptr = "file_pageh";
X  nl[N_TCB].n_nptr  = "tcb";
X  nl[N_V].n_nptr  = "v";
X  nl[N_LAST].n_nptr = "";
X
X  /*
X  ** Extract offsets to the needed variables in the kernel
X  */
X
X  if (nlist(path_unix,nl) != 0)
X  	ERROR("main: 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
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 &&
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  struct socket *sockp;
X  int i;
X  struct ucred ucb;
X  int nf;
X  struct file *xf;
X  struct var my_var;
X  int FILESPPG = (PAGESIZE / sizeof (struct file)); /* Files per Page */
X  int file_page_size = FILESPPG * sizeof (struct file);
X
X  /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
X
X  if (!getbuf(nl[N_V].n_value, &my_var, sizeof(my_var), "v"))
X    return -1;
X
X  /*-----------------------------------------------------
X   * Round UP number of files to integral number of pages
X   * The number of pages ACTUALLY allocated may be fewer,
X   * if not in use.
X   *-----------------------------------------------------
X   */
X
X  if (my_var.v_file <= 3)
X    ERROR("k_getuid: System name list out of date");
X
X  if (my_var.v_file % FILESPPG)
X    nf = (my_var.v_file / FILESPPG + 1) * FILESPPG;
X  else
X    nf = my_var.v_file;
X
X  if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
X    return -1;
X
X  xfile = (struct file *) calloc (nf, sizeof(struct file));
X  if (!xfile)
X    ERROR2("k_getuid: calloc(%d,%d)", nf, sizeof(struct file));
X
X  xf = xfile;
X  nfile = 0;
X
X  while ((addr != 0) && (nfile < nf))
X  {
X    /*----------------------------------------------------
X     * Read in linked list of pages of file table entries.
X     *----------------------------------------------------
X     */
X
X    if (!getbuf(addr, xf, file_page_size, "file[]"))
X      return -1;
X
X    nfile += FILESPPG;
X	xf += FILESPPG;
X
X    if (!getbuf(addr + PAGESIZE - sizeof (addr), &addr, sizeof(addr), "&file"))
X      return -1;
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  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
X
SHAR_EOF
  $shar_touch -am 1009083995 'pidentd-2.7/src/kernel/aux301.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/aux301.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/aux301.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/aux301.c:' 'MD5 check failed'
1a3647bd87ffd111be5b9192f9688b98  pidentd-2.7/src/kernel/aux301.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/aux301.c'`"
    test 9954 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/aux301.c:' 'original size' '9954,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/bsdi.c ==============
if test -f 'pidentd-2.7/src/kernel/bsdi.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/bsdi.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/bsdi.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/bsdi.c' &&
/*
** kernel/bsdi.c		Low level kernel access functions for BSDI
**
** This program is in the public domain and may be used freely by anyone
** who wants to. 
**
** Last update: 7 April 1994
**
** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
*/
X
#include <paths.h>
#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/uio.h>
X
#define KERNEL
X
#include <sys/file.h>
X
#undef KERNEL
X
#if !defined(BSD4_4) || (defined(_BSDI_VERSION) && (_BSDI_VERSION <= 199312))
#  include <sys/kinfo.h>
#else
#  include <sys/sysctl.h>
#  define KINFO_PROC_ALL KERN_PROC_ALL
#endif
X
#include <fcntl.h>
X
#include <sys/user.h>
X
#include <sys/wait.h>
X
#include <sys/filedesc.h>
#include <sys/proc.h>
X
#if !defined(BSD4_4) || (defined(_BSDI_VERSION) && (_BSDI_VERSION <= 199312))
#  include <sys/kinfo_proc.h>
#endif
X
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
X
#include <netinet/in_systm.h>
#include <netinet/ip.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 <pwd.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      
X  { "_filehead" },
X  { "_nfiles" },
X  { "_tcb" },
X  { "" }
};
X
X
static struct file *xfile;
static int nfile;
X
static struct inpcb tcb;
static kvm_t *kd = NULL;
X
int k_open()
{
X  /*
X  ** Open the kernel memory device
X  */
X  if ((kd = (kvm_t *)kvm_openfiles(path_unix, path_kmem, NULL, O_RDONLY, NULL)) == 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 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 &&
X	   getbuf((long) pcbp->inp_next,
X		  pcbp,
X		  sizeof(struct inpcb),
X		  "tcblist"));
X
X  return NULL;
}
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  struct socket *sockp;
X  int i;
X  struct kinfo_proc	*kp;
X  int			nentries;
X
X  if ((kp = kvm_getprocs(kd, KINFO_PROC_ALL, 0, &nentries)) == NULL)
X  {
X    ERROR("k_getuid: kvm_getprocs");
X    return -1;
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  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 < nentries; i++)
X  {
X    if(kp[i].kp_proc.p_fd != NULL)
X    {
X      int				j;
X      struct filedesc	pfd;
X      struct file		**ofiles;
X      struct file		ofile;
X
X      if(!getbuf(kp[i].kp_proc.p_fd, &pfd, sizeof(pfd), "pfd"))
X        return(-1);
X
X      ofiles = (struct file **) malloc(pfd.fd_nfiles * sizeof(struct file *));
X
X      if(!getbuf(pfd.fd_ofiles, ofiles,
X                 pfd.fd_nfiles * sizeof(struct file *), "ofiles"))
X      {
X        free(ofiles);
X        return(-1);
X      }
X
X      for(j = 0; j < pfd.fd_nfiles; j ++)
X      {
X        if(!getbuf(ofiles[j], &ofile, sizeof(struct file), "ofile"))
X        {
X          free(ofiles);
X          return(-1);
X        }
X
X        if(ofile.f_count == 0)
X          continue;
X
X        if(ofile.f_type == DTYPE_SOCKET &&
X           (struct socket *) ofile.f_data == sockp)
X        {
X          struct pcred	pc;
X
X          if(!getbuf(kp[i].kp_proc.p_cred, &pc, sizeof(pc), "pcred"))
X            return(-1);
X
X          *uid = pc.p_ruid;
X          free(ofiles);
X          return 0;
X        }
X      }
X
X      free(ofiles);
X    }
X  }
X
X  return -1;
}
X
SHAR_EOF
  $shar_touch -am 0811215796 'pidentd-2.7/src/kernel/bsdi.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/bsdi.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/bsdi.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/bsdi.c:' 'MD5 check failed'
37bc045dc31b3cf4792643c6e982e929  pidentd-2.7/src/kernel/bsdi.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/bsdi.c'`"
    test 5056 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/bsdi.c:' 'original size' '5056,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/freebsd.c ==============
if test -f 'pidentd-2.7/src/kernel/freebsd.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/freebsd.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/freebsd.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/freebsd.c' &&
/*
** kernel/freebsd.c	   Low level kernel access functions for FreeBSD 2.x
**
** This program is in the public domain and may be used freely by anyone
** who wants to.
**
** Last update: 11 Aug 1996
**
** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
*/
X
#include <paths.h>
#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/sysctl.h>
#include <sys/socket.h>
X
#include <sys/queue.h>
#include <sys/uio.h>
X
#include <sys/socketvar.h>
X
#define KERNEL
X
#include <sys/file.h>
X
#undef KERNEL
X
#include <fcntl.h>
X
#include <sys/time.h>
#include <sys/user.h>
#include <sys/wait.h>
X
#include <sys/filedesc.h>
#include <sys/proc.h>
X
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
X
#include <netinet/in_systm.h>
#include <netinet/ip.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 <pwd.h>
X
#include "identd.h"
#include "error.h"
X
#ifdef INPLOOKUP_SETLOCAL
#define	_HAVE_OLD_INPCB
#endif
X
extern void *calloc();
extern void *malloc();
X
X
struct nlist nl[] =
{
#define N_TCB 0
X
X  { "_tcb" },
X  { "" }
};
X
static kvm_t *kd;
X
static int nfile;
X
#ifdef _HAVE_OLD_INPCB
static struct inpcb tcb;
#else
static struct inpcbhead tcb;
#endif
X
int k_open()
{
X  /*
X  ** Open the kernel memory device
X  */
X  if ((kd = (kvm_t *)kvm_openfiles(path_unix, path_kmem, NULL, O_RDONLY, NULL)) == 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
/*
** Traverse the inpcb list until a match is found.
** Returns NULL if no match.
*/
static struct socket *
#ifdef _HAVE_OLD_INPCB
X    getlist(pcbp, faddr, fport, laddr, lport)
X  struct inpcb *pcbp;
#else
X    getlist(pcbhead, faddr, fport, laddr, lport)
X  struct inpcbhead *pcbhead;
#endif
X  struct in_addr *faddr;
X  int fport;
X  struct in_addr *laddr;
X  int lport;
{
#ifdef _HAVE_OLD_INPCB
X  struct inpcb *head;
#else
X  struct inpcb *head, pcbp;
#endif
X
#ifdef _HAVE_OLD_INPCB
X  if (!pcbp)
X    return NULL;
#else
X  head = pcbhead->lh_first;
X  if (!head)
X    return NULL;
#endif
X
X
#ifdef _HAVE_OLD_INPCB
X  head = pcbp->inp_prev;
#endif
X  do
X  {
#ifdef _HAVE_OLD_INPCB
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 &&
X	   getbuf((long) pcbp->inp_next,
X		  pcbp,
X		  sizeof(struct inpcb),
X		  "tcblist"));
#else
X    if (!getbuf((long) head, &pcbp, sizeof(struct inpcb), "tcblist"))
X       break;
X    if (pcbp.inp_faddr.s_addr == faddr->s_addr &&
X	pcbp.inp_fport        == fport &&
X	pcbp.inp_lport        == lport )
X	return(pcbp.inp_socket);
X    head = pcbp.inp_list.le_next;
X  } while (head != NULL);
#endif
X
X  return NULL;
}
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  struct socket *sockp;
X  int i;
X  struct kinfo_proc	*kp;
X  int			nentries;
X
X  if ((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nentries)) == NULL)
X  {
X    ERROR("k_getuid: kvm_getprocs");
X    return -1;
X  }
X
X  /* -------------------- TCP PCB LIST -------------------- */
X  if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
X    return -1;
X
#ifdef _HAVE_OLD_INPCB
X  tcb.inp_prev = (struct inpcb *) nl[N_TCB].n_value;
#endif
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 < nentries; i++)
X  {
X    if(kp[i].kp_proc.p_fd != NULL)
X    {
X      int		j;
X      struct filedesc	pfd;
X      struct file	**ofiles;
X      struct file	ofile;
X
X      if(!getbuf(kp[i].kp_proc.p_fd, &pfd, sizeof(pfd), "pfd"))
X        return(-1);
X
X      ofiles = (struct file **) malloc(pfd.fd_nfiles * sizeof(struct file *));
X
X      if(!getbuf(pfd.fd_ofiles, ofiles,
X                 pfd.fd_nfiles * sizeof(struct file *), "ofiles"))
X      {
X        free(ofiles);
X        return(-1);
X      }
X
X      for(j = 0; j < pfd.fd_nfiles; j ++)
X      {
X        if(!getbuf(ofiles[j], &ofile, sizeof(struct file), "ofile"))
X	{
X          free(ofiles);
X          return(-1);
X        }
X
X        if(ofile.f_count == 0)
X	  continue;
X
X        if(ofile.f_type == DTYPE_SOCKET &&
X           (struct socket *) ofile.f_data == sockp)
X	{
X          struct pcred	pc;
X
X          if(!getbuf(kp[i].kp_proc.p_cred, &pc, sizeof(pc), "pcred"))
X            return(-1);
X
X          *uid = pc.p_ruid;
X          free(ofiles);
X	  return 0;
X	}
X      }
X
X      free(ofiles);
X    }
X  }
X
X  return -1;
}
SHAR_EOF
  $shar_touch -am 0811202696 'pidentd-2.7/src/kernel/freebsd.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/freebsd.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/freebsd.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/freebsd.c:' 'MD5 check failed'
db383a962ede77d6713c66dece39f021  pidentd-2.7/src/kernel/freebsd.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/freebsd.c'`"
    test 5444 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/freebsd.c:' 'original size' '5444,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/hpux.c ==============
if test -f 'pidentd-2.7/src/kernel/hpux.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/hpux.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/hpux.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/hpux.c' &&
/*
** kernel/hpux.c	Low level kernel access functions for HP-UX 7 & 8
**
** 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>
#include <sys/file.h>
X
#include <fcntl.h>
X
#include <sys/user.h>
#include <sys/wait.h>
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
#ifndef HPUX7
#  include <arpa/inet.h>
#endif
X
#include "identd.h"
#include "error.h"
X
X
extern void *calloc();
extern void *malloc();
X
X
struct nlist nl[] =
{
#if ((defined(hp9000s800) || defined(__hp9000s800)) && !defined(HPUX7))
X
X  /* HP9000 Series 800, HP-UX 8.0 */
X
#define N_FILE  0  
#define N_NFILE 1
#define N_TCB   2
X
X  { "file" },
X  { "nfile" },
X  { "tcb" },
X  
#else
#if ((defined(hp9000s800) || defined(__hp9000s800)) && defined(HPUX7))
X      
X  /* HP9000 Series 800, HP-UX 7.0 */
X      
#define N_FILE  0  
#define N_NFILE 1
#define N_TCB   2
X      
X  { "file" },
X  { "nfile" },
X  { "tcp_cb" },
#else
#ifdef HPUX7		/* HP-UX 7.0 */
X
#define N_FILE  0  
#define N_NFILE 1
#define N_TCB   2
X
X  { "_file" },
X  { "_nfile" },
X  { "_tcp_cb" },
X
#else         /* SUN or old BSD or other systems */      
X
#define N_FILE 0  
#define N_NFILE 1
#define N_TCB 2
X
X  { "_file" },
X  { "_nfile" },
X  { "_tcb" },
X
#endif
#endif
#endif
X  { "" }
};
X
static kvm_t *kd;
X
static struct file *xfile;
static int nfile;
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 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 &&
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  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 0516233693 'pidentd-2.7/src/kernel/hpux.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/hpux.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/hpux.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/hpux.c:' 'MD5 check failed'
94bbef10a8375d60e5f641a53c393ad5  pidentd-2.7/src/kernel/hpux.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/hpux.c'`"
    test 4769 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/hpux.c:' 'original size' '4769,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/irix4.c ==============
if test -f 'pidentd-2.7/src/kernel/irix4.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/irix4.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/irix4.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/irix4.c' &&
/*
** kernel/irix4.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>
**
** Last update: 28 June 1993
**
** Modified by Christopher Kranz, Princeton University to work with suid
** root programs.  The method for which one descends through the kernel
** process structures was borrowed from lsof 2.10 written by Victor A. Abell,
** Purdue Research Foundation.
*/
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/proc.h>
#include <sys/syssgi.h>
X
#define _KERNEL
X
#include <sys/file.h>
X
#include <sys/inode.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_V    1
#define N_TCB  2
#define N_PROC 3
X 
X  { "file" },
X  { "v" },
X  { "tcb" },
X  { "proc" },
X  { "" }
};
X
static kvm_t *kd;
X
static struct file *xfile;
static int nfile;
X
static struct var v;
X
static struct inpcb tcb;
X
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
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
/*
** 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  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
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  struct socket *sockp;
X  int i;
X  struct inode inode;
X  long paddr;
X  struct proc *pp;
X  struct proc ps;
X  long pa;
X  int px;
X  int nofiles;
X  struct user *up;
X  char *uu;
X  size_t uul;
X  struct file **fp;
X  struct file f;
X
X  
X  /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
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;
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  /* -------------------- SCAN PROCESS TABLE ------------------- */
X  if ( (paddr = nl[N_PROC].n_value) == NULL ) {
X    if (debug_flag && syslog_flag)
X      syslog(LOG_DEBUG, "k_getuid:  paddr == NULL");
X    return -1;
X  }
X
X  paddr &= 0x7fffffff;
X
X  uul = (size_t) (sizeof(struct user)
X      + (v.v_nofiles * sizeof(struct file *)));
X
X  if ( (uu=(char *)malloc(uul)) == (char *)NULL ) 
X    return -1;
X
X  fp = (struct file **)(uu + sizeof(struct user));
X  up = (struct user *)uu;
X
X  for (pp=&ps, px=0 ; px < v.v_proc ; px++) {
X    pa = paddr + (long)(px * sizeof(struct proc));
X
X    if ( !getbuf(pa, (char *)&ps, sizeof(ps), "proc") )
X      continue;
X
X    if ( pp->p_stat == 0 || pp->p_stat == SZOMB )
X      continue;
X  
X    /* ------------------- GET U_AREA FOR PROCESS ----------------- */
X    if ((i=syssgi(SGI_RDUBLK, pp->p_pid, uu, uul)) < sizeof(struct user))
X      continue;
X
X    /* ------------------- SCAN FILE TABLE ------------------------ */
X    if (i <= sizeof(struct user)
X    ||  ((long)up->u_ofile - UADDR) != sizeof(struct user))
X      nofiles = 0;
X    else
X      nofiles = (i - sizeof(struct user)) / sizeof(struct file *);
X
X    for (i = 0 ; i < nofiles ; i++) {
X      if (fp[i] == NULL)
X        break;
X
X      if (!getbuf(fp[i], &f, sizeof(f), "file"))
X        return -1;
X
X      if ( f.f_count == 0 )
X        continue;
X
X      if (!getbuf(f.f_inode, &inode, sizeof(inode), "inode"))
X        return -1;
X
X      if ((inode.i_ftype & IFMT) == IFCHR && soc_fsptr(&inode) == sockp) {
X        *uid = up->u_ruid;
X        return 0;
X      }
X    } /* scan file table */
X  }  /* scan process table */
X  return -1;
}
SHAR_EOF
  $shar_touch -am 0810030293 'pidentd-2.7/src/kernel/irix4.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/irix4.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/irix4.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/irix4.c:' 'MD5 check failed'
499c044dfc5d9c21ebceec64da645c87  pidentd-2.7/src/kernel/irix4.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/irix4.c'`"
    test 5810 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/irix4.c:' 'original size' '5810,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/kvm.h ==============
if test -f 'pidentd-2.7/src/kernel/kvm.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/kvm.h' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/kvm.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/kvm.h' &&
/*
** kvm.h                    Header file for the kernel virtual memory access
**                          routines
**
** This code is in the public domain and may be used freely by anyone
** who wants to.
**
** Last update: 19 Oct 1992
**
** Author: Peter Eriksson <pen@lysator.liu.se>
*/
X
#ifndef __KVM_H__
#define __KVM_H__
X
typedef struct
{
X  int fd;
X  char *namelist;
#ifdef BSD43
X  int swap_fd;
X  int mem_fd;
X
X  int procidx;
X  int nproc;
X  struct pte *Usrptma;
X  struct pte *usrpt;
X  struct proc *proctab;
#endif
} kvm_t;
X
X
extern kvm_t *kvm_open();
extern int kvm_close();
extern int kvm_nlist();
extern int kvm_read();
X
#ifdef BSD43
extern struct user *kvm_getu();
extern struct proc *kvm_getproc();
extern struct proc *kvm_nextproc();
extern int kvm_setproc();
#endif
X
#endif
SHAR_EOF
  $shar_touch -am 1020003092 'pidentd-2.7/src/kernel/kvm.h' &&
  chmod 0644 'pidentd-2.7/src/kernel/kvm.h' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/kvm.h' '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/kvm.h:' 'MD5 check failed'
79949caa51a68722f554b1fbeb8abda2  pidentd-2.7/src/kernel/kvm.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/kvm.h'`"
    test 786 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/kvm.h:' 'original size' '786,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/linux.c ==============
if test -f 'pidentd-2.7/src/kernel/linux.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/linux.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/linux.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/linux.c' &&
/*
** kernel/linux.c                   Linux 0.99.13q or later access functions
**
** This program is in the public domain and may be used freely by anyone
** who wants to. 
**
** Last update: 17 Nov 1993
**
** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
*/
X
#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
X
int k_open()
{
X    return 0;
}
X
X
int k_getuid(struct in_addr *faddr, int fport,
X	     struct in_addr *laddr, int lport,
X	     int *uid)
{
X    FILE *fp;
X    long dummy;
X    char buf[512];
X    struct in_addr myladdr, myraddr;
X    int mylport, myrport;
X
X    fport = ntohs(fport);
X    lport = ntohs(lport);
X    
X    /*
X     ** Open the kernel memory device
X     */
X    if ((fp = fopen("/proc/net/tcp", "r"))==NULL)
X    {
X	return -1;
X    }
X    
X    /* eat header */
X    fgets(buf,sizeof(buf)-1,fp);
X    while (fgets(buf, sizeof(buf)-1, fp))
X    {
X	if (sscanf(buf,"%d: %lX:%x %lX:%x %x %lX:%lX %x:%lX %lx %d",
X		   &dummy, &myladdr, &mylport, &myraddr, &myrport,
X		   &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
X		   uid) == 12)
X	{
X	    if (myladdr.s_addr==laddr->s_addr && mylport==lport &&
X		myraddr.s_addr==faddr->s_addr && myrport==fport)
X	    {
X		fclose(fp);
X		return 0;
X	    }
X	}
X    }
X
X    fclose(fp);
X    return -1;
}
SHAR_EOF
  $shar_touch -am 1117213593 'pidentd-2.7/src/kernel/linux.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/linux.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/linux.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/linux.c:' 'MD5 check failed'
bc6e4f7410078ae5b2803058b9f834bf  pidentd-2.7/src/kernel/linux.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/linux.c'`"
    test 1350 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/linux.c:' 'original size' '1350,' 'current size' "$shar_count!"
  fi
fi
# ============= pidentd-2.7/src/kernel/next_mach.c ==============
if test -f 'pidentd-2.7/src/kernel/next_mach.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/next_mach.c' '(file already exists)'
else
  $echo 'x -' extracting 'pidentd-2.7/src/kernel/next_mach.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/next_mach.c' &&
/*
** kernel/next_mach.c		Low level kernel access functions for 4.3BSD
**
** 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 <sys/types.h>
#include <sys/param.h>
#include <netdb.h>
#include <nlist.h>
#include <pwd.h>
#include <signal.h>
X
#include "kvm.h"
#include "paths.h"
X
#include <sys/socket.h>
#include <sys/socketvar.h>
X
#include <sys/ioctl.h>
X
#ifndef NeXT31
#  define KERNEL
#  define KERNEL_FEATURES 
#else
#  define KERNEL_FILE
#endif
X
#include <sys/file.h>
X
#ifndef NeXT31
#  undef KERNEL
#  undef KERNEL_FEATURES 
#else
#  undef KERNEL_FILE
#endif
X
#include <sys/user.h>
X
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
X
#include <netinet/in_pcb.h>
#include <netinet/ip_var.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
X   { {"_file_list"} },
X   { {"_max_file"} },
X   { {"_tcb"} },
X   { {""} }
};
X
static kvm_t *kd;
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.
*** 
**/
X
static
struct socket *getlist(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;		/* Someone gave us a duff one here */
X  
X   head = pcbp->inp_prev;
X   do {
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
X   } while (pcbp->inp_next != head &&
X	    getbuf((long) pcbp->inp_next, 
X                   pcbp, 
X                   sizeof(struct inpcb), 
X		   "tcblist"));
X
X   return NULL;			/* Not found */
}
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   static struct ucred ucb;
X   struct socket *sockp;
X   int nfile;
X   struct inpcb tcb;		/*  */
X   struct file file_entry;
X   void * addr;
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   /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
X   /* So now we hit the fun Mach kernel structures */
X   if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file_table"))
X      return -1;
X      
X   /* We only use nfile as a failsafe in case something goes wrong! */
X   if (!getbuf(nl[N_NFILE].n_value, &nfile, sizeof(nfile), "nfile"))
X      return -1;
X      
X   file_entry.links.next = addr;
X   /* ------------------- SCAN FILE TABLE ------------------------ */
X   do {
X      if (!getbuf((unsigned long) file_entry.links.next, &file_entry, 
X	          sizeof(file_entry), "struct file"))
X         return -1;
X	 
X      if (file_entry.f_count &&
X	  file_entry.f_type == DTYPE_SOCKET) {
X	 if ((void *) file_entry.f_data == (void *) sockp) {
X	    if (!getbuf((unsigned long) file_entry.f_cred, 
X	                &ucb, sizeof(ucb), "ucb"))
X	       return -1;
X	       
X	    *uid = ucb.cr_ruid;
X	    return 0;
X	 }
X      }
X   } while ((file_entry.links.next != addr) && (--nfile));
X   return -1;
}
SHAR_EOF
  $shar_touch -am 0127032195 'pidentd-2.7/src/kernel/next_mach.c' &&
  chmod 0644 'pidentd-2.7/src/kernel/next_mach.c' ||
  $echo 'restore of' 'pidentd-2.7/src/kernel/next_mach.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/next_mach.c:' 'MD5 check failed'
f409e9f5511cf561573d29472a485162  pidentd-2.7/src/kernel/next_mach.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/next_mach.c'`"
    test 4462 -eq "$shar_count" ||
    $echo 'pidentd-2.7/src/kernel/next_mach.c:' 'original size' '4462,' 'current size' "$shar_count!"
  fi
fi
: || $echo 'restore of' 'pidentd-2.7/src/kernel/other.c' 'failed'
$echo 'End of part' '6,' 'continue with part' '7'
exit 0


