pidentd  3.0.19
About: implementation of the RFC1413 identification server (more or less complete rewrite compared to version 2)
  Fossies Dox: pidentd-3.0.19.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

k_bsd42.c
Go to the documentation of this file.
1 /*
2 ** k_bsd42.c - 4.2BSD (and compatible OS) kernel access functions.
3 **
4 ** Copyright (c) 1997 Peter Eriksson <pen@lysator.liu.se>
5 **
6 ** This program is free software; you can redistribute it and/or
7 ** modify it as you wish - as long as you don't claim that you wrote
8 ** it.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 */
14 
15 #include "config.h"
16 
17 /* Needed for HP-UX */
18 #define _INCLUDE_STRUCT_FILE
19 
20 
21 #include <stdio.h>
22 #include <errno.h>
23 #include <ctype.h>
24 #include <nlist.h>
25 #include <pwd.h>
26 #undef _POSIX_SOURCE
27 #include <signal.h>
28 #include <syslog.h>
29 
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <sys/param.h>
33 #include <sys/ioctl.h>
34 
35 #include <sys/socket.h>
36 #define SYS_SOCKET_H_INCLUDED
37 #include <sys/socketvar.h>
38 
39 #define KERNEL
40 
41 #include <sys/file.h>
42 #include <fcntl.h>
43 #include <sys/dir.h>
44 #include <sys/wait.h>
45 
46 #undef KERNEL
47 
48 #include <sys/user.h>
49 
50 #include <net/if.h>
51 #include <net/route.h>
52 
53 #include <netinet/in.h>
54 #include <netinet/in_pcb.h>
55 #include <netinet/tcp.h>
56 #include <netinet/ip_var.h>
57 #include <netinet/tcp_timer.h>
58 #include <netinet/tcp_var.h>
59 
60 #include <arpa/inet.h>
61 
62 #include "pidentd.h"
63 
64 #ifdef HAVE_KVM_H
65 #include <kvm.h>
66 #else
67 #include "pkvm.h"
68 #endif
69 
70 
71 struct kainfo
72 {
74  struct nlist nl[4];
75 };
76 
77 
78 #define N_FILE 0
79 #define N_NFILE 1
80 #define N_TCB 2
81 
82 
83 
84 
85 int
86 ka_init(void)
87 {
88  return 0;
89 }
90 
91 
92 int
93 ka_open(void **misc)
94 {
95  int rcode;
96  struct kainfo *kp;
97 
98 
99  kp = s_malloc(sizeof(*kp));
100 
101  /*
102  ** Open the kernel memory device
103  */
104  if ((kp->kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL)
105  {
106  if (debug)
107  perror("kvm_open");
108 
109  syslog(LOG_ERR, "kvm_open: %m");
110  s_free(kp);
111  return -1;
112  }
113 
114  kp->nl[0].n_name = "_file";
115  kp->nl[1].n_name = "_nfile";
116 #ifdef HPUX7
117  kp->nl[2].n_name = "_tcb_cb";
118 #else
119  kp->nl[2].n_name = "_tcb";
120 #endif
121  kp->nl[3].n_name = NULL;
122 
123  /*
124  ** Extract offsets to the needed variables in the kernel
125  */
126  if ((rcode = kvm_nlist(kp->kd, kp->nl)) != 0)
127  {
128  kp->nl[0].n_name = "file";
129  kp->nl[1].n_name = "nfile";
130 #ifdef HPUX7
131  kp->nl[2].n_name = "tcb_cb";
132 #else
133  kp->nl[2].n_name = "tcb";
134 #endif
135 
136  if ((rcode = kvm_nlist(kp->kd, kp->nl)) != 0)
137  {
138  if (debug)
139  fprintf(stderr, "kvm_nlist: returned %d\n", rcode);
140 
141  syslog(LOG_ERR, "kvm_nlist, rcode = %d: %m", rcode);
142  kvm_close(kp->kd);
143  s_free(kp);
144  return -1;
145  }
146  }
147 
148  *misc = (void *) kp;
149  return 0;
150 }
151 
152 
153 /*
154 ** Get a piece of kernel memory with error handling.
155 ** Returns 1 if call succeeded, else 0 (zero).
156 */
157 static int
159  off_t addr,
160  void *buf,
161  size_t len,
162  char *what)
163 {
164  if (kvm_read(kd, addr, buf, len) < 0)
165  {
166  syslog(LOG_INFO, "getbuf: kvm_read(%08x, %lu) - %s : %m",
167  addr, (unsigned long) len, what);
168 
169  return 0;
170  }
171 
172  return 1;
173 }
174 
175 
176 
177 /*
178 ** Traverse the inpcb list until a match is found.
179 ** Returns NULL if no match.
180 */
181 static struct socket *
183  struct inpcb *pcbp,
184  struct in_addr *faddr,
185  int fport,
186  struct in_addr *laddr,
187  int lport)
188 {
189  struct inpcb *head;
190  int limiter = 65536;
191 
192  if (pcbp == NULL)
193  return NULL;
194 
195  head = pcbp->inp_prev;
196  do
197  {
198  if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
199  pcbp->inp_laddr.s_addr == laddr->s_addr &&
200  pcbp->inp_fport == fport &&
201  pcbp->inp_lport == lport)
202  return (struct socket *) (pcbp->inp_socket);
203 
204  if (--limiter <= 0)
205  break;
206 
207  } while (pcbp->inp_next != head &&
208  getbuf(kd,
209  (off_t) pcbp->inp_next,
210  pcbp,
211  sizeof(struct inpcb),
212  "tcblist"));
213 
214  return NULL;
215 }
216 
217 
218 
219 /*
220 ** Return the user number for the connection owner
221 */
222 int
223 ka_lookup(void *vp, struct kernel *kp)
224 {
225  struct in_addr *faddr;
226  int fport;
227  struct in_addr *laddr;
228  int lport;
229 
230  struct kainfo *kip;
231  struct inpcb tcb;
232  struct file *xfile = NULL;
233  off_t addr;
234  int nfile;
235 
236  struct socket *sockp;
237  int i;
238  struct ucred ucb;
239 
240  kip = (struct kainfo *) vp;
241 
242  faddr = &kp->remote.sin_addr;
243  laddr = &kp->local.sin_addr;
244  fport = kp->remote.sin_port;
245  lport = kp->local.sin_port;
246 
247  /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
248  if (!getbuf(kip->kd,
249  (off_t) kip->nl[N_NFILE].n_value,
250  &nfile,
251  sizeof(nfile),
252  "nfile"))
253  goto Fail;
254 
255  if (!getbuf(kip->kd,
256  (off_t) kip->nl[N_FILE].n_value, &addr,
257  sizeof(addr), "&file"))
258  goto Fail;
259 
260  xfile = (struct file *) s_malloc(nfile*sizeof(struct file));
261 
262  if (!getbuf(kip->kd, addr, xfile, sizeof(struct file) * nfile, "file[]"))
263  goto Fail;
264 
265  /* -------------------- TCP PCB LIST -------------------- */
266  if (!getbuf(kip->kd, (off_t) kip->nl[N_TCB].n_value, &tcb,
267  sizeof(tcb), "tcb"))
268  goto Fail;
269 
270  tcb.inp_prev = (struct inpcb *) kip->nl[N_TCB].n_value;
271  sockp = getlist(kip->kd, &tcb, faddr, fport, laddr, lport);
272  if (sockp == NULL)
273  {
274  s_free(xfile);
275  return 0;
276  }
277 
278  /*
279  ** Locate the file descriptor that has the socket in question
280  ** open so that we can get the 'ucred' information
281  */
282  for (i = 0; i < nfile; i++)
283  {
284  if (xfile[i].f_count == 0)
285  continue;
286 
287  if (xfile[i].f_type == DTYPE_SOCKET &&
288  (struct socket *) xfile[i].f_data == sockp)
289  {
290  if (!getbuf(kip->kd,
291  (off_t) xfile[i].f_cred, &ucb, sizeof(ucb), "ucb"))
292  goto Fail;
293 
294  kp->ruid = ucb.cr_ruid;
295  kp->euid = ucb.cr_uid;
296 
297  s_free(xfile);
298  return 1;
299  }
300  }
301 
302  Fail:
303  s_free(xfile);
304  return -1;
305 }
306 
s_free
void s_free(void *p)
Definition: safeio.c:153
ka_init
int ka_init(void)
Definition: k_bsd42.c:86
kainfo
Definition: k_aix42.c:73
kvm_nlist
int kvm_nlist(kvm_t *kd, struct nlist *nl)
pidentd.h
ka_lookup
int ka_lookup(void *vp, struct kernel *kp)
Definition: k_bsd42.c:223
kernel::remote
struct sockaddr_gen remote
Definition: kernel.h:29
kvm_t
Definition: pkvm.h:18
kainfo::kd
int kd
Definition: k_aix42.c:75
kernel::local
struct sockaddr_gen local
Definition: kernel.h:28
N_TCB
#define N_TCB
Definition: k_bsd42.c:80
s_malloc
void * s_malloc(size_t size)
Definition: safeio.c:132
kernel::euid
uid_t euid
Definition: kernel.h:35
kvm_close
int kvm_close(kvm_t *kd)
kvm_open
kvm_t * kvm_open(const char *namelist, const char *corefile, const char *swapfile, int flag, const char *errstr)
debug
int debug
Definition: gen_osinfo.c:23
kernel::ruid
uid_t ruid
Definition: kernel.h:36
N_FILE
#define N_FILE
Definition: k_bsd42.c:78
N_NFILE
#define N_NFILE
Definition: k_bsd42.c:79
kainfo::kd
kvm_t * kd
Definition: k_bsd42.c:73
getlist
static struct socket * getlist(kvm_t *kd, struct inpcb *pcbp, struct in_addr *faddr, int fport, struct in_addr *laddr, int lport)
Definition: k_bsd42.c:182
getbuf
static int getbuf(kvm_t *kd, off_t addr, void *buf, size_t len, char *what)
Definition: k_bsd42.c:158
pkvm.h
kernel
Definition: kernel.h:25
ka_open
int ka_open(void **misc)
Definition: k_bsd42.c:93
kvm_read
ssize_t kvm_read(kvm_t *kd, off_t addr, void *buf, size_t len)
kainfo::nl
struct nlist nl[4]
Definition: k_bsd42.c:74