/* $OpenBSD: openbsd.c,v 1.15 2001/01/28 19:34:29 niklas Exp $ */ /* * This program is in the public domain and may be used freely by anyone * who wants to. * * Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se> * * This version elminates the kmem search in favour of a kernel sysctl to * get the user id associated with a connection - Bob Beck <beck@obtuse.com> */ #include <sys/param.h> #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/sysctl.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/tcp.h> #include <netinet/ip_var.h> #include <netinet/tcp_timer.h> #include <netinet/tcp_var.h> #include <arpa/inet.h> #include "identd.h" #include "error.h" /* * Return the user number for the connection owner */ int k_getuid(faddr, fport, laddr, lport, uid) struct in_addr *faddr; int fport; struct in_addr *laddr; int lport; uid_t *uid; { struct tcp_ident_mapping tir; struct sockaddr_in *fin, *lin; int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_IDENT }; int error = 0; size_t i; memset(&tir, 0, sizeof (tir)); tir.faddr.ss_len = (sizeof (struct sockaddr_storage) & 0xff); tir.laddr.ss_len = (sizeof (struct sockaddr_storage) &0xff); tir.faddr.ss_family = AF_INET; tir.laddr.ss_family = AF_INET; fin = (struct sockaddr_in *) &tir.faddr; lin = (struct sockaddr_in *) &tir.laddr; memcpy(&fin->sin_addr, faddr, sizeof (struct in_addr)); memcpy(&lin->sin_addr, laddr, sizeof (struct in_addr)); fin->sin_port = fport; lin->sin_port = lport; i = sizeof (tir); error = sysctl(mib, sizeof (mib) / sizeof (int), &tir, &i, NULL, 0); if (!error && tir.ruid != -1) { *uid = tir.ruid; return (0); } if (error == -1) syslog(LOG_DEBUG, "sysctl failed (%m)"); return (-1); } /* * Return the user number for the connection owner * New minty IPv6 version. */ int k_getuid6(faddr, fport, laddr, lport, uid) struct sockaddr_in6 *faddr; int fport; struct sockaddr_in6 *laddr; int lport; uid_t *uid; { struct tcp_ident_mapping tir; struct sockaddr_in6 *fin, *lin; int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_IDENT }; int error = 0; size_t i; memset(&tir, 0, sizeof (tir)); fin = (struct sockaddr_in6 *) &tir.faddr; lin = (struct sockaddr_in6 *) &tir.laddr; if (faddr->sin6_len > sizeof(tir.faddr)) return -1; memcpy(fin, faddr, faddr->sin6_len); if (laddr->sin6_len > sizeof(tir.laddr)) return -1; memcpy(lin, laddr, laddr->sin6_len); fin->sin6_port = fport; lin->sin6_port = lport; i = sizeof (tir); error = sysctl(mib, sizeof (mib) / sizeof (int), &tir, &i, NULL, 0); if (!error && tir.ruid != -1) { *uid = tir.ruid; return (0); } if (error == -1) syslog(LOG_DEBUG, "sysctl failed (%m)"); return (-1); }