chiark / gitweb /
sd-daemon: verify socket family, too
authorLennart Poettering <lennart@poettering.net>
Fri, 21 May 2010 15:06:40 +0000 (17:06 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 21 May 2010 15:06:40 +0000 (17:06 +0200)
fixme
src/logger.c
src/sd-daemon.c
src/sd-daemon.h

diff --git a/fixme b/fixme
index 22c5cc3a3528b83193a94aa34c48920c3d612528..b8d0fca354027e641c4d65ac28335ae30095c5ba 100644 (file)
--- a/fixme
+++ b/fixme
@@ -47,9 +47,9 @@
    - uuidd    DONE
    - nscd     DONE
    - dbus     DONE
+   - rsyslog  DONE
    - rpcbind (/var/run/rpcbind.sock!)
    - avahi-daemon (/var/run/avahi-daemon/socket)
-   - rsyslog
    - cups
    - ssh      CLASSIC
    - postfix, saslauthd
index c486a8acd1d854a83e0915b44f6de15f1f91d23a..2e036dd77bc14153d9c3e90a5d6cbcd2b28d569e 100644 (file)
@@ -428,7 +428,7 @@ static int server_init(Server *s, unsigned n_sockets) {
 
                 fd = SD_LISTEN_FDS_START+i;
 
-                if ((r = sd_is_socket(fd, SOCK_STREAM, 1)) < 0) {
+                if ((r = sd_is_socket(fd, AF_UNSPEC, SOCK_STREAM, 1)) < 0) {
                         log_error("Failed to determine file descriptor type: %s", strerror(-r));
                         goto fail;
                 }
index ad2bfa82e72f4e76e9d46edb069a35c14459b9ec..eec4722709cb15f89eaca9ad8e2a8aa64ad75cec 100644 (file)
@@ -133,7 +133,7 @@ int sd_is_fifo(int fd, const char *path) {
         return 1;
 }
 
-int sd_is_socket(int fd, int type, int listening) {
+static int sd_is_socket_internal(int fd, int type, int listening) {
         struct stat st_fd;
 
         if (fd < 0 || type < 0)
@@ -176,18 +176,51 @@ int sd_is_socket(int fd, int type, int listening) {
         return 1;
 }
 
-int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) {
-        union {
-                struct sockaddr sa;
-                struct sockaddr_in in4;
-                struct sockaddr_in6 in6;
-                struct sockaddr_un un;
-                struct sockaddr_storage storage;
-        } sockaddr;
+union sockaddr_union {
+        struct sockaddr sa;
+        struct sockaddr_in in4;
+        struct sockaddr_in6 in6;
+        struct sockaddr_un un;
+        struct sockaddr_storage storage;
+};
+
+int sd_is_socket(int fd, int family, int type, int listening) {
+        int r;
+
+        if (family < 0)
+                return -EINVAL;
+
+        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
+                return r;
+
+        if (family > 0) {
+                union sockaddr_union sockaddr;
+                socklen_t l;
+
+                memset(&sockaddr, 0, sizeof(sockaddr));
+                l = sizeof(sockaddr);
+
+                if (getsockname(fd, &sockaddr.sa, &l) < 0)
+                        return -errno;
+
+                if (l < sizeof(sa_family_t))
+                        return -EINVAL;
+
+                return sockaddr.sa.sa_family == family;
+        }
+
+        return 1;
+}
+
+int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) {
+        union sockaddr_union sockaddr;
         socklen_t l;
         int r;
 
-        if ((r = sd_is_socket(fd, type, listening)) <= 0)
+        if (family != 0 && family != AF_INET && family != AF_INET6)
+                return -EINVAL;
+
+        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
                 return r;
 
         memset(&sockaddr, 0, sizeof(sockaddr));
@@ -196,13 +229,17 @@ int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) {
         if (getsockname(fd, &sockaddr.sa, &l) < 0)
                 return -errno;
 
-        if (l < sizeof(struct sockaddr))
+        if (l < sizeof(sa_family_t))
                 return -EINVAL;
 
         if (sockaddr.sa.sa_family != AF_INET &&
             sockaddr.sa.sa_family != AF_INET6)
                 return 0;
 
+        if (family > 0)
+                if (sockaddr.sa.sa_family != family)
+                        return 0;
+
         if (port > 0) {
                 if (sockaddr.sa.sa_family == AF_INET) {
                         if (l < sizeof(struct sockaddr_in))
@@ -221,17 +258,11 @@ int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) {
 }
 
 int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
-        union {
-                struct sockaddr sa;
-                struct sockaddr_in in4;
-                struct sockaddr_in6 in6;
-                struct sockaddr_un un;
-                struct sockaddr_storage storage;
-        } sockaddr;
+        union sockaddr_union sockaddr;
         socklen_t l;
         int r;
 
-        if ((r = sd_is_socket(fd, type, listening)) <= 0)
+        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
                 return r;
 
         memset(&sockaddr, 0, sizeof(sockaddr));
index ab69364c2645d3df703da451eb0124aaac7419ae..e209af64896d12d6c027db6480502b5e579915e5 100644 (file)
@@ -73,24 +73,26 @@ int sd_listen_fds(int unset_environment);
 int sd_is_fifo(int fd, const char *path);
 
 /* Helper call for identifying a passed file descriptor. Returns 1 if
- * the file descriptor is a socket of the specified type (SOCK_DGRAM,
- * SOCK_STREAM, ...), 0 otherwise. If type is 0 a socket type check
- * will not be done and the call only verifies if the file descriptor
- * refers to a socket. If listening is > 0 it is verified that the
- * socket is in listening mode. (i.e. listen() has been called) If
- * listening is == 0 it is verified that the socket is not in
- * listening mode. If listening is < 0 no listening mode check is
- * done. Returns a negative errno style error code on failure. */
-int sd_is_socket(int fd, int type, int listening);
+ * the file descriptor is a socket of the specified family (AF_INET,
+ * ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If
+ * family is 0 a socket family check will not be done. If type is 0 a
+ * socket type check will not be done and the call only verifies if
+ * the file descriptor refers to a socket. If listening is > 0 it is
+ * verified that the socket is in listening mode. (i.e. listen() has
+ * been called) If listening is == 0 it is verified that the socket is
+ * not in listening mode. If listening is < 0 no listening mode check
+ * is done. Returns a negative errno style error code on failure. */
+int sd_is_socket(int fd, int family, int type, int listening);
 
 /* Helper call for identifying a passed file descriptor. Returns 1 if
- * the file descriptor is an Internet socket (either AF_INET or
- * AF_INET6) of the specified type (SOCK_DGRAM, SOCK_STREAM, ...), 0
- * otherwise. If type is 0 a socket type check will not be done. If
- * port is 0 a socket port check will not be done. The listening flag
- * is used the same way as in sd_is_socket(). Returns a negative errno
- * style error code on failure. */
-int sd_is_socket_inet(int fd, int type, int listening, uint16_t port);
+ * the file descriptor is an Internet socket, of the specified family
+ * (either AF_INET or AF_INET6) of the specified type (SOCK_DGRAM,
+ * SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version
+ * check is not done. If type is 0 a socket type check will not be
+ * done. If port is 0 a socket port check will not be done. The
+ * listening flag is used the same way as in sd_is_socket(). Returns a
+ * negative errno style error code on failure. */
+int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port);
 
 /* Helper call for identifying a passed file descriptor. Returns 1 if
  * the file descriptor is an AF_UNIX socket of the specified type