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