Annotation of embedaddon/strongswan/src/libstrongswan/networking/streams/stream_service_unix.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2013 Martin Willi
                      3:  * Copyright (C) 2013 revosec AG
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include <library.h>
                     17: #include <networking/streams/stream_unix.h>
                     18: 
                     19: #include <errno.h>
                     20: #include <unistd.h>
                     21: #include <sys/socket.h>
                     22: #include <sys/un.h>
                     23: #include <sys/stat.h>
                     24: 
                     25: /**
                     26:  * See header
                     27:  */
                     28: stream_service_t *stream_service_create_unix(char *uri, int backlog)
                     29: {
                     30:        struct sockaddr_un addr;
                     31:        mode_t old;
                     32:        int fd, len;
                     33: 
                     34:        len = stream_parse_uri_unix(uri, &addr);
                     35:        if (len == -1)
                     36:        {
                     37:                DBG1(DBG_NET, "invalid stream URI: '%s'", uri);
                     38:                return NULL;
                     39:        }
                     40:        if (!lib->caps->check(lib->caps, CAP_CHOWN))
                     41:        {       /* required to chown(2) service socket */
                     42:                DBG1(DBG_NET, "cannot change ownership of socket '%s' without "
                     43:                         "CAP_CHOWN capability. socket directory should be accessible to "
                     44:                         "UID/GID under which the daemon will run", uri);
                     45:        }
                     46:        fd = socket(AF_UNIX, SOCK_STREAM, 0);
                     47:        if (fd == -1)
                     48:        {
                     49:                DBG1(DBG_NET, "opening socket '%s' failed: %s", uri, strerror(errno));
                     50:                return NULL;
                     51:        }
                     52:        unlink(addr.sun_path);
                     53: 
                     54:        old = umask(S_IRWXO);
                     55:        if (bind(fd, (struct sockaddr*)&addr, len) < 0)
                     56:        {
                     57:                DBG1(DBG_NET, "binding socket '%s' failed: %s", uri, strerror(errno));
                     58:                close(fd);
                     59:                return NULL;
                     60:        }
                     61:        umask(old);
                     62:        /* Only attempt to change owner of socket if we have CAP_CHOWN. Otherwise,
                     63:         * attempt to change group of socket to group under which charon runs after
                     64:         * dropping caps. This requires the user that charon starts as to:
                     65:         * a) Have write access to the socket dir.
                     66:         * b) Belong to the group that charon will run under after dropping caps. */
                     67:        if (lib->caps->check(lib->caps, CAP_CHOWN))
                     68:        {
                     69:                if (chown(addr.sun_path, lib->caps->get_uid(lib->caps),
                     70:                                  lib->caps->get_gid(lib->caps)) != 0)
                     71:                {
                     72:                        DBG1(DBG_NET, "changing socket owner/group for '%s' failed: %s",
                     73:                                 uri, strerror(errno));
                     74:                }
                     75:        }
                     76:        else
                     77:        {
                     78:                if (chown(addr.sun_path, -1, lib->caps->get_gid(lib->caps)) != 0)
                     79:                {
                     80:                        DBG1(DBG_NET, "changing socket group for '%s' failed: %s",
                     81:                                 uri, strerror(errno));
                     82:                }
                     83:        }
                     84:        if (listen(fd, backlog) < 0)
                     85:        {
                     86:                DBG1(DBG_NET, "listen on socket '%s' failed: %s", uri, strerror(errno));
                     87:                unlink(addr.sun_path);
                     88:                close(fd);
                     89:                return NULL;
                     90:        }
                     91:        return stream_service_create_from_fd(fd);
                     92: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>