1 /* $MirOS: src/libexec/identd/openbsd.c,v 1.2 2005/03/06 19:24:01 tg Exp $ */
2 /* $OpenBSD: openbsd.c,v 1.19 2004/09/16 08:25:05 deraadt Exp $ */
3
4 /*
5 * This program is in the public domain and may be used freely by anyone
6 * who wants to.
7 *
8 * Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
9 *
10 * This version elminates the kmem search in favour of a kernel sysctl to
11 * get the user id associated with a connection - Bob Beck <beck@obtuse.com>
12 */
13
14 #include <sys/param.h>
15 #include <sys/socket.h>
16 #include <sys/socketvar.h>
17 #include <sys/sysctl.h>
18
19 #include <stdio.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <syslog.h>
23
24 #include <netinet/in.h>
25 #include <netinet/in_systm.h>
26 #include <netinet/tcp.h>
27 #include <netinet/ip_var.h>
28 #include <netinet/tcp_timer.h>
29 #include <netinet/tcp_var.h>
30
31 #include <arpa/inet.h>
32
33 #include "identd.h"
34
35 __RCSID("$MirOS: src/libexec/identd/openbsd.c,v 1.2 2005/03/06 19:24:01 tg Exp $");
36
37 /*
38 * Return the user number for the connection owner
39 */
40 int
k_getuid(struct in_addr * faddr,int fport,struct in_addr * laddr,int lport,uid_t * uid)41 k_getuid(struct in_addr *faddr, int fport, struct in_addr *laddr,
42 int lport, uid_t *uid)
43 {
44 int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_IDENT };
45 struct sockaddr_in *fin, *lin;
46 struct tcp_ident_mapping tir;
47 int error = 0;
48 size_t i;
49
50 memset(&tir, 0, sizeof (tir));
51 tir.faddr.ss_len = (sizeof (struct sockaddr_storage) & 0xff);
52 tir.laddr.ss_len = (sizeof (struct sockaddr_storage) &0xff);
53 tir.faddr.ss_family = AF_INET;
54 tir.laddr.ss_family = AF_INET;
55 fin = (struct sockaddr_in *) &tir.faddr;
56 lin = (struct sockaddr_in *) &tir.laddr;
57
58 memcpy(&fin->sin_addr, faddr, sizeof (struct in_addr));
59 memcpy(&lin->sin_addr, laddr, sizeof (struct in_addr));
60 fin->sin_port = fport;
61 lin->sin_port = lport;
62 i = sizeof (tir);
63 error = sysctl(mib, sizeof (mib) / sizeof (int), &tir, &i, NULL, 0);
64 if (!error && tir.ruid != -1) {
65 *uid = tir.ruid;
66 return (0);
67 }
68 if (error == -1)
69 syslog(LOG_DEBUG, "sysctl failed (%m)");
70
71 return (-1);
72 }
73
74 /*
75 * Return the user number for the connection owner
76 * New minty IPv6 version.
77 */
78 int
k_getuid6(struct sockaddr_in6 * faddr,int fport,struct sockaddr_in6 * laddr,int lport,uid_t * uid)79 k_getuid6(struct sockaddr_in6 *faddr, int fport, struct sockaddr_in6 *laddr,
80 int lport, uid_t *uid)
81 {
82 int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_IDENT };
83 struct sockaddr_in6 *fin, *lin;
84 struct tcp_ident_mapping tir;
85 int error = 0;
86 size_t i;
87
88 memset(&tir, 0, sizeof (tir));
89 fin = (struct sockaddr_in6 *) &tir.faddr;
90 lin = (struct sockaddr_in6 *) &tir.laddr;
91
92 memcpy(fin, faddr, faddr->sin6_len);
93 memcpy(lin, laddr, laddr->sin6_len);
94 fin->sin6_port = fport;
95 lin->sin6_port = lport;
96 i = sizeof (tir);
97 error = sysctl(mib, sizeof (mib) / sizeof (int), &tir, &i, NULL, 0);
98 if (!error && tir.ruid != -1) {
99 *uid = tir.ruid;
100 return (0);
101 }
102 if (error == -1)
103 syslog(LOG_DEBUG, "sysctl failed (%m)");
104
105 return (-1);
106 }
107