Commit | Line | Data |
---|---|---|
e1b631e8 | 1 | /* |
d3faac99 KB |
2 | * Copyright (c) 1992, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
e1b631e8 JSP |
4 | * All rights reserved. |
5 | * | |
6 | * This code is derived from software donated to Berkeley by | |
7 | * Jan-Simon Pendry. | |
8 | * | |
9 | * %sccs.include.redist.c% | |
10 | * | |
7736a2e4 | 11 | * @(#)pt_tcp.c 8.2 (Berkeley) %G% |
e1b631e8 JSP |
12 | * |
13 | * $Id: pt_tcp.c,v 1.1 1992/05/25 21:43:09 jsp Exp jsp $ | |
14 | */ | |
15 | ||
16 | #include <stdio.h> | |
17 | #include <unistd.h> | |
18 | #include <stdlib.h> | |
19 | #include <errno.h> | |
225429d9 | 20 | #include <strings.h> |
e1b631e8 | 21 | #include <sys/types.h> |
225429d9 | 22 | #include <sys/param.h> |
e1b631e8 | 23 | #include <sys/syslog.h> |
0be6ec50 JSP |
24 | #include <sys/socket.h> |
25 | #include <netinet/in.h> | |
26 | #include <netdb.h> | |
e1b631e8 JSP |
27 | |
28 | #include "portald.h" | |
29 | ||
225429d9 JSP |
30 | /* |
31 | * Key will be tcp/host/port[/"priv"] | |
32 | * Create a TCP socket connected to the | |
33 | * requested host and port. | |
34 | * Some trailing suffix values have special meanings. | |
35 | * An unrecognised suffix is an error. | |
36 | */ | |
0be6ec50 | 37 | int portal_tcp(pcr, key, v, kso, fdp) |
e1b631e8 JSP |
38 | struct portal_cred *pcr; |
39 | char *key; | |
40 | char **v; | |
0be6ec50 | 41 | int kso; |
e1b631e8 JSP |
42 | int *fdp; |
43 | { | |
225429d9 JSP |
44 | char host[MAXHOSTNAMELEN]; |
45 | char port[MAXHOSTNAMELEN]; | |
46 | char *p = key + (v[1] ? strlen(v[1]) : 0); | |
47 | char *q; | |
0be6ec50 JSP |
48 | struct hostent *hp; |
49 | struct servent *sp; | |
50 | struct in_addr **ipp; | |
51 | struct in_addr *ip[2]; | |
52 | struct in_addr ina; | |
53 | int s_port; | |
7736a2e4 | 54 | int priv = 0; |
0be6ec50 | 55 | struct sockaddr_in sain; |
225429d9 JSP |
56 | |
57 | q = strchr(p, '/'); | |
58 | if (q == 0 || q - p >= sizeof(host)) | |
59 | return (EINVAL); | |
60 | *q = '\0'; | |
61 | strcpy(host, p); | |
7736a2e4 | 62 | p = q + 1; |
225429d9 JSP |
63 | |
64 | q = strchr(p, '/'); | |
7736a2e4 JSP |
65 | if (q) |
66 | *q = '\0'; | |
67 | if (strlen(p) >= sizeof(port)) | |
225429d9 | 68 | return (EINVAL); |
225429d9 | 69 | strcpy(port, p); |
7736a2e4 JSP |
70 | if (q) { |
71 | p = q + 1; | |
72 | if (strcmp(p, "priv") == 0) { | |
73 | if (pcr->pcr_uid == 0) | |
74 | priv = 1; | |
75 | else | |
76 | return (EPERM); | |
77 | } else { | |
78 | return (EINVAL); | |
79 | } | |
80 | } | |
225429d9 | 81 | |
0be6ec50 JSP |
82 | hp = gethostbyname(host); |
83 | if (hp != 0) { | |
84 | ipp = (struct in_addr **) hp->h_addr_list; | |
85 | } else { | |
86 | ina.s_addr = inet_addr(host); | |
87 | if (ina.s_addr == INADDR_NONE) | |
88 | return (EINVAL); | |
89 | ip[0] = &ina; | |
90 | ip[1] = 0; | |
91 | ipp = ip; | |
92 | } | |
93 | ||
94 | sp = getservbyname(port, "tcp"); | |
95 | if (sp != 0) | |
96 | s_port = sp->s_port; | |
97 | else { | |
98 | s_port = atoi(port); | |
99 | if (s_port == 0) | |
100 | return (EINVAL); | |
101 | } | |
102 | ||
103 | bzero(&sain, sizeof(sain)); | |
104 | sain.sin_len = sizeof(sain); | |
105 | sain.sin_family = AF_INET; | |
106 | sain.sin_port = s_port; | |
107 | ||
108 | while (ipp[0]) { | |
109 | int so; | |
110 | ||
7736a2e4 JSP |
111 | if (priv) |
112 | so = rresvport((int *) 0); | |
113 | else | |
114 | so = socket(AF_INET, SOCK_STREAM, 0); | |
0be6ec50 JSP |
115 | if (so < 0) { |
116 | syslog(LOG_ERR, "socket: %m"); | |
117 | return (errno); | |
118 | } | |
119 | ||
120 | sain.sin_addr = *ipp[0]; | |
121 | if (connect(so, (struct sockaddr *) &sain, sizeof(sain)) == 0) { | |
122 | *fdp = so; | |
123 | return (0); | |
124 | } | |
125 | (void) close(so); | |
126 | ||
127 | ipp++; | |
128 | } | |
129 | ||
130 | return (errno); | |
e1b631e8 | 131 | } |