1 kumpf 1.2 /*
|
2 martin 1.6 //%LICENSE////////////////////////////////////////////////////////////////
|
3 kumpf 1.2 //
|
4 martin 1.6 // Licensed to The Open Group (TOG) under one or more contributor license
5 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
6 // this work for additional information regarding copyright ownership.
7 // Each contributor licenses this file to you under the OpenPegasus Open
8 // Source License; you may not use this file except in compliance with the
9 // License.
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a
12 // copy of this software and associated documentation files (the "Software"),
13 // to deal in the Software without restriction, including without limitation
14 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 // and/or sell copies of the Software, and to permit persons to whom the
16 // Software is furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included
19 // in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
25 martin 1.6 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 //////////////////////////////////////////////////////////////////////////
|
30 kumpf 1.2 */
31
32 #ifndef _Executor_Socket_h
33 #define _Executor_Socket_h
34
35 #include <stdlib.h>
36 #include <sys/socket.h>
37 #include <string.h>
|
38 kumpf 1.4 #include <errno.h>
39 #include <unistd.h>
40 #include <Executor/Defines.h>
41
42 #ifdef PEGASUS_ENABLE_PRIVILEGE_SEPARATION
|
43 kumpf 1.2
44 EXECUTOR_LINKAGE
45 int SetNonBlocking(int sock);
46
47 EXECUTOR_LINKAGE
48 int SetBlocking(int sock);
49
50 EXECUTOR_LINKAGE
|
51 kumpf 1.5 int WaitForReadEnable(int sock, long timeoutMsec);
52
53 EXECUTOR_LINKAGE
|
54 kumpf 1.2 ssize_t RecvNonBlock(int sock, void* buffer, size_t size);
55
56 EXECUTOR_LINKAGE
57 ssize_t SendNonBlock(int sock, const void* buffer, size_t size);
58
59 EXECUTOR_LINKAGE
60 int CloseOnExec(int fd);
61
62 EXECUTOR_LINKAGE
63 ssize_t SendDescriptorArray(int sock, int descriptors[], size_t count);
64
65 EXECUTOR_LINKAGE
66 int CreateSocketPair(int pair[2]);
67
68 static int RecvDescriptorArray(int sock, int descriptors[], size_t count)
69 {
70 struct iovec iov[1];
71 char dummy;
72 struct msghdr mh;
73 ssize_t n;
74 #if defined(HAVE_MSG_CONTROL)
75 kumpf 1.2 size_t size;
76 char* data;
|
77 kumpf 1.3 struct cmsghdr* cmh;
|
78 kumpf 1.2
79 /*
80 * This control data begins with a cmsghdr struct followed by the data
81 * (a descriptor in this case). The union ensures that the data is
82 * aligned suitably for the leading cmsghdr struct. The descriptor
83 * itself is properly aligned since the cmsghdr ends on a boundary
84 * that is suitably aligned for any type (including int).
85 *
86 * ControlData = [ cmsghdr | int ]
87 */
88
89 size = CMSG_SPACE(sizeof(int) * count);
90 data = (char*)malloc(size);
91
92 /* Define a msghdr that refers to the control data, which is filled in
93 * by calling recvmsg() below.
94 */
95
96 memset(&mh, 0, sizeof(mh));
97 mh.msg_control = data;
98 mh.msg_controllen = size;
99 kumpf 1.2
100 #else /* !defined(HAVE_MSG_CONTROL) */
101
102 memset(&mh, 0, sizeof(mh));
103 mh.msg_accrights = (caddr_t)descriptors;
104 mh.msg_accrightslen = sizeof(int) * count;
105
106 #endif /* defined(HAVE_MSG_CONTROL) */
107
108 /*
109 * The other process sends a single-byte message. This byte is not
110 * used since we only need the control data (the descriptor) but we
111 * must request at least one byte from recvmsg().
112 */
113
114 memset(iov, 0, sizeof(iov));
115 iov[0].iov_base = &dummy;
116 iov[0].iov_len = 1;
117 mh.msg_iov = iov;
118 mh.msg_iovlen = 1;
119
120 kumpf 1.2 /* Receive the message from the other process. */
121
122 n = recvmsg(sock, &mh, 0);
123
124 if (n <= 0)
|
125 kumpf 1.3 {
126 #if defined(HAVE_MSG_CONTROL)
127 free(data);
128 #endif
|
129 kumpf 1.2 return -1;
|
130 kumpf 1.3 }
|
131 kumpf 1.2
132 /* Get a pointer to control message. Return if the header is null or
133 * does not contain what we expect.
134 */
135
136 #if defined(HAVE_MSG_CONTROL)
137
138 cmh = CMSG_FIRSTHDR(&mh);
139
140 if (!cmh ||
141 cmh->cmsg_len != CMSG_LEN(sizeof(int) * count) ||
142 cmh->cmsg_level != SOL_SOCKET ||
143 cmh->cmsg_type != SCM_RIGHTS)
144 {
|
145 kumpf 1.3 free(data);
|
146 kumpf 1.2 return -1;
147 }
148
149 /* Copy the data: */
150
151 memcpy(descriptors, CMSG_DATA(cmh), sizeof(int) * count);
152
|
153 kumpf 1.3 free(data);
154
|
155 kumpf 1.2 #else /* !defined(HAVE_MSG_CONTROL) */
156
157 if (mh.msg_accrightslen != sizeof(int) * count)
158 return -1;
159
160 memcpy(descriptors, mh.msg_accrights, sizeof(int) * count);
161
162 #endif /* defined(HAVE_MSG_CONTROL) */
163
164 return 0;
165 }
166
|
167 kumpf 1.4 #endif
168
169 /*
170 These functions are used by the PAM cimservera implementation regardless
171 of whether privilege separation is enabled.
172 */
173
174 static ssize_t RecvBlock(int sock, void* buffer, size_t size)
175 {
176 size_t r = size;
177 char* p = (char*)buffer;
178
179 if (size == 0)
180 return -1;
181
182 while (r)
183 {
184 ssize_t n;
185
186 EXECUTOR_RESTART(read(sock, p, r), n);
187
188 kumpf 1.4 if (n == -1)
189 return -1;
190 else if (n == 0)
191 return size - r;
192
193 r -= n;
194 p += n;
195 }
196
197 return size - r;
198 }
199
200 static ssize_t SendBlock(int sock, void* buffer, size_t size)
201 {
202 size_t r = size;
203 char* p = (char*)buffer;
204
205 while (r)
206 {
207 ssize_t n;
208 EXECUTOR_RESTART(write(sock, p, r), n);
209 kumpf 1.4
210 if (n == -1)
211 return -1;
212 else if (n == 0)
213 return size - r;
214
215 r -= n;
216 p += n;
217 }
218
219 return size - r;
220 }
221
|
222 kumpf 1.2 #endif /* _Executor_Socket_h */
|