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_aix432.c
Go to the documentation of this file.
1 /*
2 ** k_aix432.c - IBM AIX 4.3.2 kernel access functions.
3 **
4 ** Modified for AIX 4.3.2 system by Wendy Lin, PUCC, Jul. 1999,
5 ** based on k_aix42.c. The 4.3.2. specific getprocs() calls
6 ** are modelled after PBS and lsof.
7 **
8 ** Copyright (c) 1997 Peter Eriksson <pen@lysator.liu.se>
9 ** 1994 Harlan Stenn <harlan@pfcs.com>
10 ** 1992 Charles M. Hannum
11 **
12 ** This program is free software; you can redistribute it and/or
13 ** modify it as you wish - as long as you don't claim that you wrote
14 ** it.
15 **
16 ** This program is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 */
20 
21 #include "config.h"
22 
23 #include <sys/types.h>
24 
25 #if defined(__GNUC__)
26 
27 typedef long long aligned_off64_t __attribute__ ((aligned (8)));
28 typedef long long aligned_offset_t __attribute__ ((aligned (8)));
29 #define off64_t aligned_off64_t
30 #define offset_t aligned_offset_t
31 
32 #endif
33 
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <pwd.h>
39 #include <stdio.h>
40 #include <syslog.h>
41 
42 #include <sys/domain.h>
43 #include <sys/protosw.h>
44 #include <sys/socket.h>
45 #include <sys/socketvar.h>
46 #include <sys/statfs.h>
47 #include <sys/vfs.h>
48 #include <net/route.h>
49 #include <netinet/in.h>
50 
51 #include <netinet/ip.h>
52 
53 #include <netinet/in_pcb.h>
54 #include <arpa/inet.h>
55 
56 #define _KERNEL 1
57 #include <sys/file.h>
58 #undef _KERNEL
59 #include <procinfo.h>
60 
61 #include "pidentd.h"
62 
63 struct kainfo
64 {
65  int kd;
66 };
67 
68 
69 int
70 ka_init(void)
71 {
72  return 0;
73 }
74 
75 
76 int
77 ka_open(void **misc)
78 {
79  struct kainfo *kp;
80 
81 
82  kp = s_malloc(sizeof(*kp));
83 
84  if ((kp->kd = open("/dev/kmem", O_RDONLY)) == -1)
85  {
86  syslog(LOG_ERR, "open(\"/dev/kmem\"): %m");
87  s_free(kp);
88  return -1;
89  }
90 
91  *misc = (void *) kp;
92  return 0;
93 }
94 
95 
96 static int
97 kread (int kmem,
98  off_t addr,
99  char *buf,
100  int len)
101 {
102  int br;
103 
104  if (lseek (kmem, addr, SEEK_SET) == (off_t) -1)
105  return (-1);
106 
107  br = read(kmem, buf, len);
108 
109  return ((br == len) ? 0 : 1);
110 }
111 
112 
113 
114 int
115 ka_lookup(void *vp, struct kernel *kp)
116 {
117  int inc_procs = 256,
118  num_procs = 0, num, fd;
119  pid_t pid;
120  struct procsinfo *procsinfo = NULL, *pp;
121  struct fdsinfo *fdsinfo = NULL;
122  struct file *filep, file;
123  struct socket *socketp, socket;
124  struct protosw *protoswp, protosw;
125  struct domain *domainp, domain;
126  struct inpcb *inpcbp, inpcb;
127 
128  struct in_addr *faddr;
129  int fport;
130  struct in_addr *laddr;
131  int lport;
132 
133  struct kainfo *kip;
134 
135  kip = (struct kainfo *) vp;
136 
137  faddr = &kp->remote.sin_addr;
138  laddr = &kp->local.sin_addr;
139  fport = kp->remote.sin_port;
140  lport = kp->local.sin_port;
141 
142 
143  procsinfo = (struct procsinfo *)
144  s_malloc ((size_t) (inc_procs * sizeof (struct procsinfo)));
145  pp = procsinfo;
146  num_procs = 0;
147  pid = 0;
148  while ((num = getprocs (pp, sizeof(struct procsinfo),
149  (struct fdsinfo *) NULL, 0,
150  &pid, inc_procs)) > 0) {
151  num_procs += num;
152  if (num < inc_procs)
153  break;
154  procsinfo = (struct procsinfo *)
155  realloc(procsinfo,
156  (num_procs+inc_procs)*sizeof(struct procsinfo));
157  pp = &procsinfo[num_procs];
158  }
159 
160  /*
161  ** Allocate space for file descriptors outside the loop because
162  ** the size has to be the size of struct fdsinfo, which is
163  ** OPEN_MAX * sizeof(struct fdsinfox). Can't use individual
164  ** pi_maxofile's.
165  */
166  fdsinfo = (struct fdsinfo *)
167  s_malloc ((size_t) sizeof(struct fdsinfo));
168 
169  /*
170  ** Check all proc table entries, but return as soon as one match
171  ** is found.
172  */
173  pp = procsinfo;
174  for (; num_procs != 0; num_procs--, pp++)
175  {
176  if (pp->pi_state == 0 || pp->pi_state == SZOMB)
177  continue;
178 
179  if ((num = pp->pi_maxofile) == 0)
180  continue;
181 
182  pid = pp->pi_pid;
183  if (getprocs((struct procsinfo *) NULL, 0,
184  fdsinfo, sizeof (struct fdsinfo),
185  &pid, 1) != 1)
186  continue;
187 
188  for (fd = 0; fd < num; fd++)
189  {
190  if ((filep = fdsinfo->pi_ufd[fd].fp) == NULL)
191  continue;
192 
193  if (kread (kip->kd, (off_t) filep, (char *) &file, sizeof (file)))
194  {
195  syslog (LOG_ERR, "can not read file struct from %#x",
196  (unsigned) filep);
197  goto Fail;
198  }
199 
200  if (file.f_type != DTYPE_SOCKET)
201  continue;
202 
203  if ((socketp = (struct socket *) file.f_data) == NULL)
204  continue;
205 
206  if (kread (kip->kd,(off_t) socketp, (char *) &socket,
207  sizeof (socket)))
208  {
209  syslog (LOG_ERR, "can not read socket struct from %#x",
210  (unsigned) socketp);
211  goto Fail;
212  }
213 
214  if ((protoswp = socket.so_proto) == NULL)
215  continue;
216 
217  if (kread (kip->kd, (off_t) protoswp, (char *) &protosw,
218  sizeof (protosw)))
219  {
220  syslog (LOG_ERR, "can not read protosw struct from %#x",
221  (unsigned) protoswp);
222  goto Fail;
223  }
224 
225  if (protosw.pr_protocol != IPPROTO_TCP)
226  continue;
227 
228  if ((domainp = protosw.pr_domain) == NULL)
229  continue;
230 
231  if (kread (kip->kd, (off_t) domainp, (char *) &domain,
232  sizeof (domain)))
233  {
234  syslog (LOG_ERR, "can not read domain struct from %#x",
235  (unsigned) domainp);
236  goto Fail;
237  }
238 
239  if (domain.dom_family != AF_INET
240 #ifdef AF_INET6
241  && domain.dom_family != AF_INET6
242 #endif
243  )
244  continue;
245 
246  if ((inpcbp = (struct inpcb *) socket.so_pcb) == NULL)
247  continue;
248 
249  if (kread (kip->kd, (off_t) inpcbp, (char *) &inpcb,
250  sizeof (inpcb)))
251  {
252  syslog (LOG_ERR, "can not read inpcb struct from %#x",
253  (unsigned) inpcbp);
254  goto Fail;
255  }
256 
257  if (socketp != inpcb.inp_socket)
258  continue;
259 
260  if (inpcb.inp_faddr.s_addr != faddr->s_addr ||
261  inpcb.inp_fport != fport ||
262  inpcb.inp_laddr.s_addr != laddr->s_addr ||
263  inpcb.inp_lport != lport)
264  continue;
265 
266  kp->ruid = pp->pi_uid;
267  kp->euid = pp->pi_suid;
268  kp->pid = pp->pi_pid;
269 
270  s_free(fdsinfo);
271  s_free(procsinfo);
272 
273  return 1;
274  }
275  }
276 
277  s_free(fdsinfo);
278  s_free(procsinfo);
279  return 0;
280 
281  Fail:
282  s_free(fdsinfo);
283  s_free(procsinfo);
284  return -1;
285 }
286 
s_free
void s_free(void *p)
Definition: safeio.c:153
kainfo
Definition: k_aix42.c:73
ka_lookup
int ka_lookup(void *vp, struct kernel *kp)
Definition: k_aix432.c:115
kread
static int kread(int kmem, off_t addr, char *buf, int len)
Definition: k_aix432.c:97
pidentd.h
kernel::remote
struct sockaddr_gen remote
Definition: kernel.h:29
kainfo::kd
int kd
Definition: k_aix42.c:75
kernel::local
struct sockaddr_gen local
Definition: kernel.h:28
s_malloc
void * s_malloc(size_t size)
Definition: safeio.c:132
ka_init
int ka_init(void)
Definition: k_aix432.c:70
kernel::euid
uid_t euid
Definition: kernel.h:35
kernel::ruid
uid_t ruid
Definition: kernel.h:36
kernel::pid
pid_t pid
Definition: kernel.h:38
ka_open
int ka_open(void **misc)
Definition: k_aix432.c:77
kernel
Definition: kernel.h:25