19 #include <sys/types.h>
30 #include <sys/ioctl.h>
31 #include <net/gen/in.h>
32 #include <net/gen/inet.h>
34 #include <net/gen/socket.h>
35 #include <net/gen/tcp.h>
36 #include <net/gen/tcp_io.h>
38 #include <net/netlib.h>
43 #define where() fprintf(stderr, "%s, %d: ", __FILE__, __LINE__)
46 char cmdbuf
[_POSIX_ARG_MAX
+1], locuser
[16], remuser
[16];
47 extern char **environ
;
48 char username
[20]="USER=";
49 char homedir
[64]="HOME=";
50 char shell
[64]="SHELL=";
52 char *envinit
[]= {homedir
, shell
, username
, tz
, "PATH=:/bin:/usr/bin", 0};
54 char buffer
[PIPE_BUF
];
57 #define PROTO(func, args) func args
59 #define PROTO(func, args) func ()
62 PROTO (int main
, (int argc
, char *argv
[]));
63 PROTO (void getstr
, (char*buf
, int cnt
, char *err
));
64 PROTO (void close_on_exec
, (int fd
));
71 nwio_tcpconf_t tcpconf
, err_tcpconf
;
72 nwio_tcpcl_t tcpconnopt
;
73 nwio_tcpatt_t tcpattachopt
;
77 pid_t pid
, pid1
, new_pg
;
82 char *cp
, *buff_ptr
, *TZ
;
88 fprintf(stderr
, "%s: wrong number of arguments (%d)\n",
93 signal(SIGINT
, SIG_DFL
);
94 signal(SIGQUIT
, SIG_DFL
);
95 signal(SIGTERM
, SIG_DFL
);
98 { where(); fprintf(stderr
, "\n"); }
100 result
= ioctl (0, NWIOGTCPCONF
, &tcpconf
);
103 fprintf(stderr
, "%s: ioctl(NWIOGTCPCONF)= %d : %s\n",
104 prog_name
, errno
, strerror(errno
));
108 { where(); fprintf(stderr
, "\n"); }
111 tcpport
= ntohs(tcpconf
.nwtc_remport
);
112 if (tcpport
>= TCPPORT_RESERVED
|| tcpport
< TCPPORT_RESERVED
/2)
114 printf("\1%s: unprotected port (%d)\n", prog_name
, tcpport
);
122 result
= read(0, &c
, 1);
125 fprintf(stderr
, "%s: read= %d : %s\n", prog_name
,
126 errno
, strerror(errno
));
132 err_port
= err_port
*10 + c
- '0';
142 lport
= (lport
<< 1) | (pid
& 1);
144 } while (lport
< TCPPORT_RESERVED
/2);
146 n
= TCPPORT_RESERVED
/2;
149 if (--lport
< TCPPORT_RESERVED
/2)
150 lport
= TCPPORT_RESERVED
-1;
151 err_fd
= open ("/dev/tcp", O_RDWR
);
154 fprintf(stderr
, "%s: open= %d : %s\n",
155 prog_name
, errno
, strerror(errno
));
158 close_on_exec(err_fd
);
159 err_tcpconf
.nwtc_flags
= NWTC_LP_SET
| NWTC_SET_RA
|
160 NWTC_SET_RP
| NWTC_EXCL
;
161 err_tcpconf
.nwtc_locport
= htons(lport
);
162 err_tcpconf
.nwtc_remport
= htons(err_port
);
163 err_tcpconf
.nwtc_remaddr
= tcpconf
.nwtc_remaddr
;
166 { where(); fprintf(stderr
, "\n"); }
168 result
= ioctl (err_fd
, NWIOSTCPCONF
, &err_tcpconf
);
169 if (result
== 0) break;
170 if (errno
!= EADDRINUSE
)
173 "%s: ioctl(NWIOSTCPCONF)= %d : %s\n",
174 prog_name
, errno
, strerror(errno
));
181 printf("\1can't get stderr port\n");
185 err_tcpconf
.nwtc_flags
= NWTC_SHARED
;
187 { where(); fprintf(stderr
, "\n"); }
189 result
= ioctl (err_fd
, NWIOSTCPCONF
, &err_tcpconf
);
193 "%s: ioctl(NWIOSTCPCONF)= %d : %s\n",
194 prog_name
, errno
, strerror(errno
));
198 { where(); fprintf(stderr
, "\n"); }
200 tcpconnopt
.nwtcl_flags
= 0;
206 { where(); fprintf(stderr
, "\n"); }
208 result
= ioctl (err_fd
, NWIOTCPCONN
, &tcpconnopt
);
209 if (result
== 0) break;
210 if (errno
!= EAGAIN
&& errno
!= ECONNREFUSED
)
213 "%s: ioctl(NWIOTCPCONN)= %d : %s\n",
214 prog_name
, errno
, strerror(errno
));
220 { where(); fprintf(stderr
, "\n"); }
224 err2_fd
= open ("/dev/tcp", O_RDWR
);
225 close_on_exec(err2_fd
);
228 fprintf(stderr
, "%s: open= %d : %s\n", errno
,
229 prog_name
, strerror(errno
));
233 { where(); fprintf(stderr
, "\n"); }
235 result
= ioctl (err2_fd
, NWIOSTCPCONF
, &err_tcpconf
);
238 fprintf(stderr
, "%s: ioctl(NWIOSTCPCONF)= %d : %s\n",
239 prog_name
, errno
, strerror(errno
));
243 { where(); fprintf(stderr
, "\n"); }
245 tcpattachopt
.nwta_flags
= 0;
247 { where(); fprintf(stderr
, "\n"); }
249 result
= ioctl (err2_fd
, NWIOTCPATTACH
, &tcpattachopt
);
252 fprintf(stderr
, "%s: ioctl(NWIOTCPATTACH)= %d : %s\n",
253 prog_name
, errno
, strerror(errno
));
257 { where(); fprintf(stderr
, "\n"); }
261 getstr(remuser
, sizeof(remuser
), "remuser");
262 getstr(locuser
, sizeof(locuser
), "locuser");
263 getstr(cmdbuf
, sizeof(cmdbuf
), "cmdbuf");
265 pwent
= getpwnam(locuser
);
268 printf("\1Login incorrect.\n");
272 if (chdir(pwent
->pw_dir
) < 0)
277 { where(); fprintf(stderr
, "calling iruserok(%s, %d, %s, %s)\n",
278 inet_ntoa(tcpconf
.nwtc_remaddr
), 0, remuser
, locuser
); }
280 if (iruserok(tcpconf
.nwtc_remaddr
, 0, remuser
, locuser
) < 0)
282 printf("\1Permission denied.\n");
287 /* Let's go to a different process group. */
294 fprintf(stderr
, "%s: fork()= %d : %s\n",
295 prog_name
, errno
, strerror(errno
));
297 printf("\1Try again.\n");
302 close(0); /* stdin */
303 close(1); /* stdout */
305 close(err_fd
); /* stderr for shell */
312 if (read(err_fd
, &sig
, 1) <= 0)
314 if (read(err2_fd
, &sig
, 1) <= 0)
318 printf("read failed: %d\n", errno
);
324 printf("killing %d with %d\n", -new_pg
, sig
);
330 close(err2_fd
); /* signal channel for parent */
335 printf("\1Can't make pipe\n");
336 kill(getppid(), SIGTERM
);
344 fprintf(stderr
, "%s: fork()= %d : %s\n",
345 prog_name
, errno
, strerror(errno
));
347 printf("\1Try again.\n");
348 kill(-new_pg
, SIGTERM
);
353 close(pds
[1]); /* write side of pipe */
356 result
= read(pds
[0], buffer
, sizeof(buffer
));
365 result1
= write (err_fd
, buff_ptr
,
370 "%s: write()= %d : %s\n",
373 kill(-new_pg
, SIGTERM
);
380 close(err_fd
); /* file descriptor for error channel */
381 close (pds
[0]); /* read side of pipe */
383 close (pds
[1]); /* write side of pipe */
385 if (*pwent
->pw_shell
== '\0')
386 pwent
->pw_shell
= "/bin/sh";
388 initgroups(pwent
->pw_name
, pwent
->pw_gid
);
390 setgid(pwent
->pw_gid
);
391 setuid(pwent
->pw_uid
);
394 strncat(homedir
, pwent
->pw_dir
, sizeof(homedir
)-6);
395 strncat(shell
, pwent
->pw_shell
, sizeof(shell
)-7);
396 strncat(username
, pwent
->pw_name
, sizeof(username
)-6);
398 strncat(tz
, TZ
, sizeof(tz
)-4);
402 cp
= strrchr(pwent
->pw_shell
, '/');
412 execl(pwent
->pw_shell
, cp
, "-c", cmdbuf
, 0);
414 open("/dev/tty", O_RDWR
);
415 fprintf(stderr
, "%s: execl(%s, %s, .., %s)= %d : %s\n", prog_name
,
416 pwent
->pw_shell
, cp
, cmdbuf
, errno
, strerror(errno
));
417 kill(getppid(), SIGTERM
);
421 void getstr(buf
, cnt
, err
)
430 if (read(0, &c
, 1) != 1)
435 printf("\1%s too long", err
);
441 void close_on_exec(fd
)
444 (void) fcntl(fd
, F_SETFD
, fcntl(fd
, F_GETFD
) | FD_CLOEXEC
);