/* ** 941026: Harlan Stenn <harlan@pfcs.com> Hacked mercilessly from: ** ** aixident -- AIX identification daemon ** version 1.0 ** ** Copyright 1992 by Charles M. Hannum. ** ** Permission is granted to copy, modify, and use this program in any way, ** so long as the above copyright notice, this permission notice, and the ** warranty disclaimer below remain on all copies, and are unaltered. ** ** aixident is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ** FITNESS FOR A PARTICULAR PURPOSE. */ #include <sys/types.h> #ifdef _AIX42 #if defined(__GNUC__) typedef long long aligned_off64_t __attribute__ ((aligned (8))); typedef long long aligned_offset_t __attribute__ ((aligned (8))); #define off64_t aligned_off64_t #define offset_t aligned_offset_t #endif #endif #include <stdlib.h> #include <errno.h> #include <pwd.h> #include <stdio.h> #include <syslog.h> #include <sys/domain.h> #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/vfs.h> #include <net/route.h> #include <netinet/in.h> #if defined(_AIX4) #include <netinet/ip.h> #endif /* defined(_AIX4) */ #include <netinet/in_pcb.h> #include <arpa/inet.h> #define _KERNEL 1 #include <sys/file.h> #undef _KERNEL #include <procinfo.h> #if defined(_AIX4) #define u_maxofile U_maxofile #define u_ufd U_ufd #endif /* defined(_AIX4) */ #include "identd.h" #include "error.h" #include "paths.h" int kmem; int kread (); int k_open() { if ((kmem = open (_PATH_KMEM, O_RDONLY)) == -1) ERROR("main: k_open"); return 0; } /* ** Return the user number for the connection owner */ int k_getuid(faddr, fport, laddr, lport, uid #ifdef ALLOW_FORMAT , pid, cmd, cmd_and_args #endif ) struct in_addr *faddr; int fport; struct in_addr *laddr; int lport; int *uid; #ifdef ALLOW_FORMAT int *pid; char **cmd,**cmd_and_args; #endif { struct sockaddr_in foreign, local; int max_procs = 64, num_procs, fd; struct procinfo *procinfo; struct user user; struct file *filep, file; struct socket *socketp, socket; struct protosw *protoswp, protosw; struct domain *domainp, domain; struct inpcb *inpcbp, inpcb; struct passwd *passwd; static char argline[4096],progname[256]; char *cp; while ((procinfo = (struct procinfo *) malloc ((size_t) (max_procs * sizeof (*procinfo)))) && (num_procs = getproc (procinfo, max_procs, sizeof (*procinfo))) == -1 && errno == ENOSPC) { max_procs <<= 1; free (procinfo); } if (! procinfo) { if (syslog_flag) (void) syslog (LOG_ERR, "out of memory allocating %ld procinfo structs\n", max_procs); return -1; } for (; num_procs; num_procs--, procinfo++) { if (procinfo->pi_stat == 0 || procinfo->pi_stat == SZOMB) continue; if (getuser (procinfo, sizeof (*procinfo), &user, sizeof (user))) continue; for (fd = 0; fd < user.u_maxofile; fd++) { if (! (filep = user.u_ufd[fd].fp)) continue; if (kread ((off_t) filep, (char *) &file, sizeof (file))) { if (syslog_flag) (void) syslog (LOG_ERR, "can't read file struct from %#x", (unsigned) filep); return -1; } if (file.f_type != DTYPE_SOCKET) continue; if (! (socketp = (struct socket *) file.f_data)) continue; if (kread ((off_t) socketp, (char *) &socket, sizeof (socket))) { if (syslog_flag) (void) syslog (LOG_ERR, "can't read socket struct from %#x", (unsigned) socketp); return -1; } if (! (protoswp = socket.so_proto)) continue; if (kread ((off_t) protoswp, (char *) &protosw, sizeof (protosw))) { if (syslog_flag) (void) syslog (LOG_ERR, "can't read protosw struct from %#x", (unsigned) protoswp); return -1; } if (protosw.pr_protocol != IPPROTO_TCP) continue; if (! (domainp = protosw.pr_domain)) continue; if (kread ((off_t) domainp, (char *) &domain, sizeof (domain))) { if (syslog_flag) (void) syslog (LOG_ERR, "can't read domain struct from %#x", (unsigned) domainp); return -1; } if (domain.dom_family != AF_INET) continue; if (! (inpcbp = (struct inpcb *) socket.so_pcb)) continue; if (kread ((off_t) inpcbp, (char *) &inpcb, sizeof (inpcb))) { if (syslog_flag) (void) syslog (LOG_ERR, "can't read inpcb struct from %#x", (unsigned) inpcbp); return -1; } if (socketp != inpcb.inp_socket) continue; if (inpcb.inp_faddr.s_addr != faddr->s_addr || inpcb.inp_fport != fport || inpcb.inp_laddr.s_addr != laddr->s_addr || inpcb.inp_lport != lport) continue; *uid = procinfo->pi_uid; #ifdef ALLOW_FORMAT *pid = procinfo->pi_pid; bzero(argline,sizeof(argline)); getargs(procinfo,sizeof(*procinfo),argline,sizeof(argline)); strcpy(progname,argline); *cmd = progname; for (cp = argline; *cp != '\0';) { cp += strlen(cp); *cp++ = ' '; } *cmd_and_args = argline; #endif return 0; } } return -1; } int kread (addr, buf, len) off_t addr; char *buf; int len; { int br; if (lseek (kmem, addr, L_SET) == (off_t) -1) return (-1); br = read(kmem, buf, len); return ((br == len) ? 0 : 1); }