]>
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 <dlezcano at fr.ibm.com>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <sys/socket.h>
34 lxc_log_define(lxc_af_unix
, lxc
);
36 int lxc_af_unix_open(const char *path
, int type
, int flags
)
39 struct sockaddr_un addr
;
44 fd
= socket(PF_UNIX
, type
, 0);
48 memset(&addr
, 0, sizeof(addr
));
53 addr
.sun_family
= AF_UNIX
;
54 /* copy entire buffer in case of abstract socket */
55 memcpy(addr
.sun_path
, path
,
56 path
[0]?strlen(path
):sizeof(addr
.sun_path
));
58 if (bind(fd
, (struct sockaddr
*)&addr
, sizeof(addr
))) {
63 if (type
== SOCK_STREAM
&& listen(fd
, 100)) {
71 int lxc_af_unix_close(int fd
)
73 struct sockaddr_un addr
;
76 if (!getsockname(fd
, (struct sockaddr
*)&addr
, &addrlen
) &&
78 unlink(addr
.sun_path
);
85 int lxc_af_unix_connect(const char *path
)
88 struct sockaddr_un addr
;
90 fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
94 memset(&addr
, 0, sizeof(addr
));
96 addr
.sun_family
= AF_UNIX
;
97 /* copy entire buffer in case of abstract socket */
98 memcpy(addr
.sun_path
, path
,
99 path
[0]?strlen(path
):sizeof(addr
.sun_path
));
101 if (connect(fd
, (struct sockaddr
*)&addr
, sizeof(addr
))) {
109 int lxc_af_unix_send_fd(int fd
, int sendfd
, void *data
, size_t size
)
111 struct msghdr msg
= { 0 };
113 struct cmsghdr
*cmsg
;
114 char cmsgbuf
[CMSG_SPACE(sizeof(int))];
117 msg
.msg_control
= cmsgbuf
;
118 msg
.msg_controllen
= sizeof(cmsgbuf
);
120 cmsg
= CMSG_FIRSTHDR(&msg
);
121 cmsg
->cmsg_len
= CMSG_LEN(sizeof(int));
122 cmsg
->cmsg_level
= SOL_SOCKET
;
123 cmsg
->cmsg_type
= SCM_RIGHTS
;
124 *((int *) CMSG_DATA(cmsg
)) = sendfd
;
125 msg
.msg_controllen
= cmsg
->cmsg_len
;
130 iov
.iov_base
= data
? data
: buf
;
131 iov
.iov_len
= data
? size
: sizeof(buf
);
135 return sendmsg(fd
, &msg
, 0);
138 int lxc_af_unix_recv_fd(int fd
, int *recvfd
, void *data
, size_t size
)
140 struct msghdr msg
= { 0 };
142 struct cmsghdr
*cmsg
;
143 char cmsgbuf
[CMSG_SPACE(sizeof(int))];
149 msg
.msg_control
= cmsgbuf
;
150 msg
.msg_controllen
= sizeof(cmsgbuf
);
152 iov
.iov_base
= data
? data
: buf
;
153 iov
.iov_len
= data
? size
: sizeof(buf
);
157 ret
= recvmsg(fd
, &msg
, 0);
161 cmsg
= CMSG_FIRSTHDR(&msg
);
163 /* if the message is wrong the variable will not be
164 * filled and the peer will notified about a problem */
167 if (cmsg
&& cmsg
->cmsg_len
== CMSG_LEN(sizeof(int)) &&
168 cmsg
->cmsg_level
== SOL_SOCKET
&&
169 cmsg
->cmsg_type
== SCM_RIGHTS
) {
170 *recvfd
= *((int *) CMSG_DATA(cmsg
));
176 int lxc_af_unix_send_credential(int fd
, void *data
, size_t size
)
178 struct msghdr msg
= { 0 };
180 struct cmsghdr
*cmsg
;
181 struct ucred cred
= {
186 char cmsgbuf
[CMSG_SPACE(sizeof(cred
))];
189 msg
.msg_control
= cmsgbuf
;
190 msg
.msg_controllen
= sizeof(cmsgbuf
);
192 cmsg
= CMSG_FIRSTHDR(&msg
);
193 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct ucred
));
194 cmsg
->cmsg_level
= SOL_SOCKET
;
195 cmsg
->cmsg_type
= SCM_CREDENTIALS
;
196 *((struct ucred
*) CMSG_DATA(cmsg
)) = cred
;
197 msg
.msg_controllen
= cmsg
->cmsg_len
;
202 iov
.iov_base
= data
? data
: buf
;
203 iov
.iov_len
= data
? size
: sizeof(buf
);
207 return sendmsg(fd
, &msg
, 0);
210 int lxc_af_unix_rcv_credential(int fd
, void *data
, size_t size
)
212 struct msghdr msg
= { 0 };
214 struct cmsghdr
*cmsg
;
216 char cmsgbuf
[CMSG_SPACE(sizeof(cred
))];
222 msg
.msg_control
= cmsgbuf
;
223 msg
.msg_controllen
= sizeof(cmsgbuf
);
225 iov
.iov_base
= data
? data
: buf
;
226 iov
.iov_len
= data
? size
: sizeof(buf
);
230 ret
= recvmsg(fd
, &msg
, 0);
234 cmsg
= CMSG_FIRSTHDR(&msg
);
236 if (cmsg
&& cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct ucred
)) &&
237 cmsg
->cmsg_level
== SOL_SOCKET
&&
238 cmsg
->cmsg_type
== SCM_CREDENTIALS
) {
239 cred
= *((struct ucred
*) CMSG_DATA(cmsg
));
240 if (cred
.uid
&& (cred
.uid
!= getuid() || cred
.gid
!= getgid())) {
241 INFO("message denied for '%d/%d'", cred
.uid
, cred
.gid
);