summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-04-16 18:39:07 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2014-04-16 22:24:28 -0400
commit9754d56e9b21bfe89fc18f47987d6bef491b8521 (patch)
tree52e39e7fff1072ac25a23e8628a80c4d20d8c84d /src/core
parent5d2abc04fc95f5c5f6d0eaf2f9b06c70d504019f (diff)
Handle Unix domain socket connections from outside our namespace
NixOS uses Unix domain sockets for certain host <-> container interaction; i.e. the host connects to a socket visible in the container's directory tree, where the container uses a .socket unit to spawn the handler program on demand. This worked in systemd 203, but in 212 fails with "foo.socket failed to queue service startup job (Maybe the service file is missing or not a template unit?): No data available". The reason is that getpeercred() now returns ENODATA if it can't get the PID of the client, which happens in this case because the client is not in the same PID namespace. Since getpeercred() is only used to generate the instance name, this patch simply handles ENODATA by creating an instance name "<nr>-unknown". [zj: reorder clauses and remove (unsigned long) casts.]
Diffstat (limited to 'src/core')
-rw-r--r--src/core/socket.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/core/socket.c b/src/core/socket.c
index 7c18a2b75c..d57e7701ca 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -663,17 +663,21 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
int k;
k = getpeercred(fd, &ucred);
- if (k < 0)
+ if (k >= 0) {
+ if (asprintf(&r,
+ "%u-"PID_FMT"-"UID_FMT,
+ nr, ucred.pid, ucred.uid) < 0)
+ return -ENOMEM;
+ } else if (k == -ENODATA) {
+ /* This handles the case where somebody is
+ * connecting from another pid/uid namespace
+ * (e.g. from outside of our container). */
+ if (asprintf(&r,
+ "%u-unknown",
+ nr) < 0)
+ return -ENOMEM;
+ } else
return k;
-
- if (asprintf(&r,
- "%u-%lu-%lu",
- nr,
- (unsigned long) ucred.pid,
- (unsigned long) ucred.uid) < 0)
- return -ENOMEM;
-
- break;
}
default: