1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
/* $OpenBSD: openbsd.c,v 1.21 2006/11/10 20:44:07 mk 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 eliminates 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 <syslog.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"
/*
* Return the user number for the connection owner
*/
int
k_getuid(struct in_addr *faddr, int fport, struct in_addr *laddr,
int lport, uid_t *uid)
{
int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_IDENT };
struct sockaddr_in *fin, *lin;
struct tcp_ident_mapping tir;
int err = 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);
err = sysctl(mib, sizeof (mib) / sizeof (int), &tir, &i, NULL, 0);
if (!err && tir.ruid != -1) {
*uid = tir.ruid;
return (0);
}
if (err == -1)
syslog(LOG_DEBUG, "sysctl failed (%m)");
return (-1);
}
/*
* Return the user number for the connection owner
* New minty IPv6 version.
*/
int
k_getuid6(struct sockaddr_in6 *faddr, int fport, struct sockaddr_in6 *laddr,
int lport, uid_t *uid)
{
int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_IDENT };
struct sockaddr_in6 *fin, *lin;
struct tcp_ident_mapping tir;
int err = 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);
err = sysctl(mib, sizeof (mib) / sizeof (int), &tir, &i, NULL, 0);
if (!err && tir.ruid != -1) {
*uid = tir.ruid;
return (0);
}
if (err == -1)
syslog(LOG_DEBUG, "sysctl failed (%m)");
return (-1);
}
|