[PATCH v2 8/9] server: add *BSD credentials support
Leonid Bobrov
mazocomp at disroot.org
Sat Feb 9 05:49:45 UTC 2019
Signed-off-by: Leonid Bobrov <mazocomp at disroot.org>
---
configure.ac | 3 +++
src/wayland-server.c | 35 +++++++++++++++++++++++++++++++++++
src/wayland-shm.c | 10 ++++++++++
3 files changed, 48 insertions(+)
diff --git a/configure.ac b/configure.ac
index 3c227a2..15535ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,6 +70,9 @@ if test "x$ac_cv_header_sys_epoll_h" != "xyes" && test "x$ac_cv_header_sys_event
AC_MSG_ERROR([Can't find sys/epoll.h or sys/event.h. Please ensure either epoll or kqueue is available.])
fi
+# Credential support on BSD
+AC_CHECK_HEADERS([sys/ucred.h])
+
# Replacement for /proc on BSD
AC_CHECK_HEADERS([kvm.h])
SAVE_LIBS="$LIBS"
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 4191231..6f2b1d8 100644
--- a/src/wayland-shm.c
+++ b/src/wayland-shm.c
@@ -28,6 +28,8 @@
*
*/
+#include "config.h"
+
#define _GNU_SOURCE
#include <stdbool.h>
@@ -59,6 +61,7 @@ struct wl_shm_pool {
char *data;
int32_t size;
int32_t new_size;
+ int fd;
};
struct wl_shm_buffer {
@@ -110,6 +113,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);
}
@@ -284,7 +290,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);
--
2.20.1
More information about the wayland-devel
mailing list