[v7,4/6] server: add *BSD credentials support

Submitted by Leonid Bobrov on Feb. 25, 2019, 6:21 p.m.

Details

Message ID 20190225182123.65203-4-mazocomp@disroot.org
State Not Applicable
Headers show
Series "Series without cover letter" ( rev: 1 ) in Wayland

Not browsing as part of any series.

Commit Message

Leonid Bobrov Feb. 25, 2019, 6:21 p.m.
From: Vadim Zhukov <persgray@gmail.com>

Co-authored-by: Koop Mast <kwm@rainbow-runner.nl>
Signed-off-by: Vadim Zhukov <persgray@gmail.com>
Signed-off-by: Koop Mast <kwm@rainbow-runner.nl>
Signed-off-by: Leonid Bobrov <mazocomp@disroot.org>
---
 configure.ac         |  3 +++
 src/wayland-server.c | 35 +++++++++++++++++++++++++++++++++++
 src/wayland-shm.c    | 10 ++++++++++
 3 files changed, 48 insertions(+)

Patch hide | download patch | download mbox

diff --git a/configure.ac b/configure.ac
index dcefc78..c5ead62 100644
--- a/configure.ac
+++ b/configure.ac
@@ -73,6 +73,9 @@  AC_CHECK_HEADERS([sys/mman.h])
 AC_CHECK_FUNCS([waitid])
 AC_CHECK_HEADERS([signal.h])
 
+# Credential support on *BSD
+AC_CHECK_HEADERS([sys/ucred.h])
+
 AC_ARG_ENABLE([libraries],
 	      [AC_HELP_STRING([--disable-libraries],
 			      [Disable compilation of wayland libraries])],
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 19f6a76..64d021f 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -23,8 +23,15 @@ 
  * SOFTWARE.
  */
 
+#include "config.h"
+
 #define _GNU_SOURCE
 
+#ifdef HAVE_SYS_UCRED_H
+#include <sys/types.h>
+#include <sys/ucred.h>
+#endif
+
 #include <stdlib.h>
 #include <stdint.h>
 #include <stddef.h>
@@ -77,7 +84,11 @@  struct wl_client {
 	struct wl_list link;
 	struct wl_map objects;
 	struct wl_priv_signal destroy_signal;
+#ifdef HAVE_SYS_UCRED_H
+	struct xucred xucred;
+#else
 	struct ucred ucred;
+#endif
 	int error;
 	struct wl_priv_signal resource_created_signal;
 };
@@ -312,7 +323,11 @@  wl_resource_post_error(struct wl_resource *resource,
 static void
 destroy_client_with_error(struct wl_client *client, const char *reason)
 {
+#ifdef HAVE_SYS_UCRED_H
+	wl_log("%s (uid %u)\n", reason, client->xucred.cr_uid);
+#else
 	wl_log("%s (pid %u)\n", reason, client->ucred.pid);
+#endif
 	wl_client_destroy(client);
 }
 
@@ -526,10 +541,22 @@  wl_client_create(struct wl_display *display, int fd)
 	if (!client->source)
 		goto err_client;
 
+#ifdef HAVE_SYS_UCRED_H
+	len = sizeof client->xucred;
+	if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED,
+		       &client->xucred, &len) < 0
+# ifdef XUCRED_VERSION
+	               /* FreeBSD */
+		       || client->xucred.cr_version != XUCRED_VERSION
+# endif
+	              )
+		goto err_source;
+#else
 	len = sizeof client->ucred;
 	if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED,
 		       &client->ucred, &len) < 0)
 		goto err_source;
+#endif
 
 	client->connection = wl_connection_create(fd);
 	if (client->connection == NULL)
@@ -583,12 +610,20 @@  WL_EXPORT void
 wl_client_get_credentials(struct wl_client *client,
 			  pid_t *pid, uid_t *uid, gid_t *gid)
 {
+#ifdef HAVE_SYS_UCRED_H
+	*pid = 0; /* FIXME: pid is not defined on BSD */
+	if (uid)
+		*uid = client->xucred.cr_uid;
+	if (gid)
+		*gid = client->xucred.cr_gid;
+#else
 	if (pid)
 		*pid = client->ucred.pid;
 	if (uid)
 		*uid = client->ucred.uid;
 	if (gid)
 		*gid = client->ucred.gid;
+#endif
 }
 
 /** Get the file descriptor for the client
diff --git a/src/wayland-shm.c b/src/wayland-shm.c
index 5bfdece..567dedf 100644
--- a/src/wayland-shm.c
+++ b/src/wayland-shm.c
@@ -28,6 +28,8 @@ 
  *
  */
 
+#include "config.h"
+
 #define _GNU_SOURCE
 
 #include <stdbool.h>
@@ -62,6 +64,7 @@  struct wl_shm_pool {
 	char *data;
 	int32_t size;
 	int32_t new_size;
+	int fd;
 };
 
 struct wl_shm_buffer {
@@ -130,6 +133,9 @@  shm_pool_unref(struct wl_shm_pool *pool, bool external)
 	if (pool->internal_refcount + pool->external_refcount)
 		return;
 
+#ifdef HAVE_SYS_UCRED_H
+	close(pool->fd);
+#endif
 	munmap(pool->data, pool->size);
 	free(pool);
 }
@@ -304,7 +310,11 @@  shm_create_pool(struct wl_client *client, struct wl_resource *resource,
 				       "failed mmap fd %d: %m", fd);
 		goto err_free;
 	}
+#ifdef HAVE_SYS_UCRED_H
+	pool->fd = fd;
+#else
 	close(fd);
+#endif
 
 	pool->resource =
 		wl_resource_create(client, &wl_shm_pool_interface, 1, id);