]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/af_unix.c
c24df8b7bcc2b339f85f9d675c868681cf09f633
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
27 #include <sys/socket.h>
32 int lxc_af_unix_open(const char *path
, int type
, int flags
)
35 struct sockaddr_un addr
;
40 fd
= socket(PF_UNIX
, type
, 0);
44 memset(&addr
, 0, sizeof(addr
));
49 addr
.sun_family
= AF_UNIX
;
50 /* copy entire buffer in case of abstract socket */
51 memcpy(addr
.sun_path
, path
,
52 path
[0]?strlen(path
):sizeof(addr
.sun_path
));
54 if (bind(fd
, (struct sockaddr
*)&addr
, sizeof(addr
))) {
59 if (listen(fd
, 100)) {
67 int lxc_af_unix_close(int fd
)
69 struct sockaddr_un addr
;
72 if (!getsockname(fd
, (struct sockaddr
*)&addr
, &addrlen
) &&
74 unlink(addr
.sun_path
);
81 int lxc_af_unix_connect(const char *path
)
84 struct sockaddr_un addr
;
86 fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
90 memset(&addr
, 0, sizeof(addr
));
92 addr
.sun_family
= AF_UNIX
;
93 /* copy entire buffer in case of abstract socket */
94 memcpy(addr
.sun_path
, path
,
95 path
[0]?strlen(path
):sizeof(addr
.sun_path
));
97 if (connect(fd
, (struct sockaddr
*)&addr
, sizeof(addr
))) {
105 int lxc_af_unix_send_fd(int fd
, int sendfd
, void *data
, size_t size
)
107 struct msghdr msg
= { 0 };
109 struct cmsghdr
*cmsg
;
110 char cmsgbuf
[CMSG_SPACE(sizeof(int))];
113 msg
.msg_control
= cmsgbuf
;
114 msg
.msg_controllen
= sizeof(cmsgbuf
);
116 cmsg
= CMSG_FIRSTHDR(&msg
);
117 cmsg
->cmsg_len
= CMSG_LEN(sizeof(int));
118 cmsg
->cmsg_level
= SOL_SOCKET
;
119 cmsg
->cmsg_type
= SCM_RIGHTS
;
120 *((int *) CMSG_DATA(cmsg
)) = sendfd
;
121 msg
.msg_controllen
= cmsg
->cmsg_len
;
126 iov
.iov_base
= data
? data
: buf
;
127 iov
.iov_len
= data
? size
: sizeof(buf
);
131 return sendmsg(fd
, &msg
, 0);
134 int lxc_af_unix_recv_fd(int fd
, int *recvfd
, void *data
, size_t size
)
136 struct msghdr msg
= { 0 };
138 struct cmsghdr
*cmsg
;
139 char cmsgbuf
[CMSG_SPACE(sizeof(int))];
145 msg
.msg_control
= cmsgbuf
;
146 msg
.msg_controllen
= sizeof(cmsgbuf
);
148 iov
.iov_base
= data
? data
: buf
;
149 iov
.iov_len
= data
? size
: sizeof(buf
);
153 ret
= recvmsg(fd
, &msg
, 0);
157 cmsg
= CMSG_FIRSTHDR(&msg
);
159 /* if the message is wrong the variable will not be
160 * filled and the peer will notified about a problem */
163 if (cmsg
&& cmsg
->cmsg_len
== CMSG_LEN(sizeof(int)) &&
164 cmsg
->cmsg_level
== SOL_SOCKET
&&
165 cmsg
->cmsg_type
== SCM_RIGHTS
) {
166 *recvfd
= *((int *) CMSG_DATA(cmsg
));
172 int lxc_af_unix_send_credential(int fd
, void *data
, size_t size
)
174 struct msghdr msg
= { 0 };
176 struct cmsghdr
*cmsg
;
177 struct ucred cred
= {
182 char cmsgbuf
[CMSG_SPACE(sizeof(cred
))];
185 msg
.msg_control
= cmsgbuf
;
186 msg
.msg_controllen
= sizeof(cmsgbuf
);
188 cmsg
= CMSG_FIRSTHDR(&msg
);
189 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct ucred
));
190 cmsg
->cmsg_level
= SOL_SOCKET
;
191 cmsg
->cmsg_type
= SCM_CREDENTIALS
;
192 *((struct ucred
*) CMSG_DATA(cmsg
)) = cred
;
193 msg
.msg_controllen
= cmsg
->cmsg_len
;
198 iov
.iov_base
= data
? data
: buf
;
199 iov
.iov_len
= data
? size
: sizeof(buf
);
203 return sendmsg(fd
, &msg
, 0);
206 int lxc_af_unix_rcv_credential(int fd
, void *data
, size_t size
)
208 struct msghdr msg
= { 0 };
210 struct cmsghdr
*cmsg
;
212 char cmsgbuf
[CMSG_SPACE(sizeof(cred
))];
218 msg
.msg_control
= cmsgbuf
;
219 msg
.msg_controllen
= sizeof(cmsgbuf
);
221 iov
.iov_base
= data
? data
: buf
;
222 iov
.iov_len
= data
? size
: sizeof(buf
);
226 ret
= recvmsg(fd
, &msg
, 0);
230 cmsg
= CMSG_FIRSTHDR(&msg
);
234 if (cmsg
&& cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct ucred
)) &&
235 cmsg
->cmsg_level
== SOL_SOCKET
&&
236 cmsg
->cmsg_type
== SCM_CREDENTIALS
) {
237 cred
= *((struct ucred
*) CMSG_DATA(cmsg
));
238 if (cred
.uid
== getuid() && cred
.gid
== getgid())