]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/af_unix.c
2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <daniel.lezcano at free.fr>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include <sys/socket.h>
35 lxc_log_define(lxc_af_unix
, lxc
);
37 int lxc_abstract_unix_open(const char *path
, int type
, int flags
)
41 struct sockaddr_un addr
;
46 fd
= socket(PF_UNIX
, type
, 0);
50 /* Clear address structure */
51 memset(&addr
, 0, sizeof(addr
));
56 addr
.sun_family
= AF_UNIX
;
58 len
= strlen(&path
[1]) + 1;
59 if (len
>= sizeof(addr
.sun_path
) - 1) {
64 /* addr.sun_path[0] has already been set to 0 by memset() */
65 strncpy(&addr
.sun_path
[1], &path
[1], strlen(&path
[1]));
67 if (bind(fd
, (struct sockaddr
*)&addr
, offsetof(struct sockaddr_un
, sun_path
) + len
)) {
74 if (type
== SOCK_STREAM
&& listen(fd
, 100)) {
84 int lxc_abstract_unix_close(int fd
)
86 struct sockaddr_un addr
;
87 socklen_t addrlen
= sizeof(addr
);
89 if (!getsockname(fd
, (struct sockaddr
*)&addr
, &addrlen
) &&
91 unlink(addr
.sun_path
);
98 int lxc_abstract_unix_connect(const char *path
)
102 struct sockaddr_un addr
;
104 fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
108 memset(&addr
, 0, sizeof(addr
));
110 addr
.sun_family
= AF_UNIX
;
112 len
= strlen(&path
[1]) + 1;
113 if (len
>= sizeof(addr
.sun_path
) - 1) {
115 errno
= ENAMETOOLONG
;
118 /* addr.sun_path[0] has already been set to 0 by memset() */
119 strncpy(&addr
.sun_path
[1], &path
[1], strlen(&path
[1]));
121 if (connect(fd
, (struct sockaddr
*)&addr
, offsetof(struct sockaddr_un
, sun_path
) + len
)) {
123 /* special case to connect to older containers */
124 if (connect(fd
, (struct sockaddr
*)&addr
, sizeof(addr
)) == 0)
134 int lxc_abstract_unix_send_fd(int fd
, int sendfd
, void *data
, size_t size
)
136 struct msghdr msg
= { 0 };
138 struct cmsghdr
*cmsg
;
139 char cmsgbuf
[CMSG_SPACE(sizeof(int))];
143 msg
.msg_control
= cmsgbuf
;
144 msg
.msg_controllen
= sizeof(cmsgbuf
);
146 cmsg
= CMSG_FIRSTHDR(&msg
);
147 cmsg
->cmsg_len
= CMSG_LEN(sizeof(int));
148 cmsg
->cmsg_level
= SOL_SOCKET
;
149 cmsg
->cmsg_type
= SCM_RIGHTS
;
150 val
= (int *)(CMSG_DATA(cmsg
));
156 iov
.iov_base
= data
? data
: buf
;
157 iov
.iov_len
= data
? size
: sizeof(buf
);
161 return sendmsg(fd
, &msg
, MSG_NOSIGNAL
);
164 int lxc_abstract_unix_recv_fd(int fd
, int *recvfd
, void *data
, size_t size
)
166 struct msghdr msg
= { 0 };
168 struct cmsghdr
*cmsg
;
169 char cmsgbuf
[CMSG_SPACE(sizeof(int))];
175 msg
.msg_control
= cmsgbuf
;
176 msg
.msg_controllen
= sizeof(cmsgbuf
);
178 iov
.iov_base
= data
? data
: buf
;
179 iov
.iov_len
= data
? size
: sizeof(buf
);
183 ret
= recvmsg(fd
, &msg
, 0);
187 cmsg
= CMSG_FIRSTHDR(&msg
);
189 /* if the message is wrong the variable will not be
190 * filled and the peer will notified about a problem */
193 if (cmsg
&& cmsg
->cmsg_len
== CMSG_LEN(sizeof(int)) &&
194 cmsg
->cmsg_level
== SOL_SOCKET
&&
195 cmsg
->cmsg_type
== SCM_RIGHTS
) {
196 val
= (int *) CMSG_DATA(cmsg
);
203 int lxc_abstract_unix_send_credential(int fd
, void *data
, size_t size
)
205 struct msghdr msg
= { 0 };
207 struct cmsghdr
*cmsg
;
208 struct ucred cred
= {
213 char cmsgbuf
[CMSG_SPACE(sizeof(cred
))];
216 msg
.msg_control
= cmsgbuf
;
217 msg
.msg_controllen
= sizeof(cmsgbuf
);
219 cmsg
= CMSG_FIRSTHDR(&msg
);
220 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct ucred
));
221 cmsg
->cmsg_level
= SOL_SOCKET
;
222 cmsg
->cmsg_type
= SCM_CREDENTIALS
;
223 memcpy(CMSG_DATA(cmsg
), &cred
, sizeof(cred
));
228 iov
.iov_base
= data
? data
: buf
;
229 iov
.iov_len
= data
? size
: sizeof(buf
);
233 return sendmsg(fd
, &msg
, MSG_NOSIGNAL
);
236 int lxc_abstract_unix_rcv_credential(int fd
, void *data
, size_t size
)
238 struct msghdr msg
= { 0 };
240 struct cmsghdr
*cmsg
;
242 char cmsgbuf
[CMSG_SPACE(sizeof(cred
))];
248 msg
.msg_control
= cmsgbuf
;
249 msg
.msg_controllen
= sizeof(cmsgbuf
);
251 iov
.iov_base
= data
? data
: buf
;
252 iov
.iov_len
= data
? size
: sizeof(buf
);
256 ret
= recvmsg(fd
, &msg
, 0);
260 cmsg
= CMSG_FIRSTHDR(&msg
);
262 if (cmsg
&& cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct ucred
)) &&
263 cmsg
->cmsg_level
== SOL_SOCKET
&&
264 cmsg
->cmsg_type
== SCM_CREDENTIALS
) {
265 memcpy(&cred
, CMSG_DATA(cmsg
), sizeof(cred
));
266 if (cred
.uid
&& (cred
.uid
!= getuid() || cred
.gid
!= getgid())) {
267 INFO("message denied for '%d/%d'", cred
.uid
, cred
.gid
);