summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Koegel <eric.koegel@gmail.com>2017-06-22 17:08:27 +0300
committerEric Koegel <eric.koegel@gmail.com>2017-06-22 19:19:34 +0300
commit2095226293fc8d13e3fad30ca83d50d8692abc37 (patch)
treefbdc643db75043d5850f0555295c0d4d43a30027
parentc8ca45ab96888d35ccb37d33a0c213d16f94fba4 (diff)
downloadConsoleKit2-2095226293fc8d13e3fad30ca83d50d8692abc37.tar.gz
fix: FreeBSD session activation
This is based heavily on the work of Jesper Schmitz Mouridsen in: https://bugs.freebsd.org/bugzilla/attachment.cgi?id=179399&action=diff from: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=202269 Fixes: https://github.com/ConsoleKit2/ConsoleKit2/issues/85
-rw-r--r--configure.ac7
-rw-r--r--src/ck-sysdeps-freebsd.c2
-rw-r--r--src/ck-sysdeps-unix.c38
-rw-r--r--tools/ck-get-x11-display-device.c76
4 files changed, 112 insertions, 11 deletions
diff --git a/configure.ac b/configure.ac
index 525cf62..35e2c4d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,7 +71,7 @@ AC_CHECK_HEADERS([unistd.h paths.h sys/vt.h sys/consio.h fcntl.h limits.h \
sys/wait.h sys/resource.h sys/mount.h sys/param.h ftw.h \
sys/sysmacros.h sys/types.h libudev.h linux/input.h \
sys/mkdev.h devattr.h sys/kd.h sys/kbio.h libprop/proplib.h \
- linux/kd.h])
+ linux/kd.h sys/queue.h sys/stat.h sys/fcntl.h])
AC_CHECK_FUNCS([getpeerucred getpeereid memset setenv strchr strdup \
strerror strrchr strspn strstr strtol strtoul uname \
@@ -203,6 +203,11 @@ case "$host" in
if test "x$have_kvm" = "xyes"; then
KVM_LIBS="-lkvm"
fi
+ AC_CHECK_LIB(procstat, procstat_open_sysctl, have_procstat=yes,
+ AC_MSG_WARN([Unable to find libprocstat which is used on FreeBSD]))
+ if test "x$have_procstat" = "xyes"; then
+ KVM_LIBS="${KVM_LIBS} -lprocstat"
+ fi
;;
*-*-netbsd*)
CK_BACKEND="netbsd"
diff --git a/src/ck-sysdeps-freebsd.c b/src/ck-sysdeps-freebsd.c
index 6396cda..66babdd 100644
--- a/src/ck-sysdeps-freebsd.c
+++ b/src/ck-sysdeps-freebsd.c
@@ -128,7 +128,7 @@ ck_process_stat_get_tty (CkProcessStat *stat)
{
g_return_val_if_fail (stat != NULL, NULL);
- return g_strdup (stat->tty_text);
+ return g_strdup_printf ("/dev/%s", stat->tty_text);
}
static gboolean
diff --git a/src/ck-sysdeps-unix.c b/src/ck-sysdeps-unix.c
index 6d39dff..dcf6be0 100644
--- a/src/ck-sysdeps-unix.c
+++ b/src/ck-sysdeps-unix.c
@@ -57,6 +57,14 @@
#include <ucred.h>
#endif
+#ifdef __FreeBSD__
+#include <kvm.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+#include <paths.h>
+#endif
+
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -134,6 +142,10 @@ ck_get_socket_peer_credentials (int socket_fd,
}
#elif defined(HAVE_GETPEEREID)
gid_t dummy;
+ char errbuf[_POSIX2_LINE_MAX];
+ int cnt = 0;
+ kvm_t* kd;
+ struct kinfo_proc * prc;
if (getpeereid (socket_fd, &uid_read, &dummy) == 0) {
ret = TRUE;
@@ -141,6 +153,23 @@ ck_get_socket_peer_credentials (int socket_fd,
g_warning ("Failed to getpeereid() credentials: %s\n",
g_strerror (errno));
}
+#ifdef __FreeBSD__
+ kd = kvm_openfiles (NULL, _PATH_DEVNULL, NULL, O_RDONLY, errbuf);
+ if (kd == NULL) {
+ g_warning ("kvm_openfiles failed: %s", errbuf);
+ return FALSE;
+ }
+
+ prc = kvm_getprocs (kd, KERN_PROC_UID, uid_read, &cnt);
+ for (int i = 0; i < cnt; i++) {
+ if(strncmp (prc[i].ki_comm, "Xorg", 4) == 0) {
+ pid_read = prc[i].ki_pid;
+ break;
+ }
+ }
+
+ kvm_close(kd);
+#endif /* __FreeBSD__ */
#else /* !SO_PEERCRED && !HAVE_GETPEERUCRED */
g_warning ("Socket credentials not supported on this OS\n");
#endif
@@ -238,15 +267,6 @@ ck_get_a_console_fd (void)
fd = -1;
-#ifdef __FreeBSD__
- /* On FreeBSD, try /dev/consolectl first as this will survive
- * /etc/ttys initialization. */
- fd = ck_open_a_console ("/dev/consolectl");
- if (fd >= 0) {
- goto done;
- }
-#endif
-
#ifdef __sun
/* On Solaris, first try Sun VT device. */
fd = ck_open_a_console ("/dev/vt/active");
diff --git a/tools/ck-get-x11-display-device.c b/tools/ck-get-x11-display-device.c
index 348115c..7925e76 100644
--- a/tools/ck-get-x11-display-device.c
+++ b/tools/ck-get-x11-display-device.c
@@ -28,6 +28,33 @@
#include <libintl.h>
#include <locale.h>
+#ifdef HAVE_KVM_H
+#include <kvm.h>
+#endif
+
+#ifdef HAVE_SYS_QUEUE_H
+#include <sys/queue.h>
+#endif
+
+#ifdef HAVE_SYS_FCNTL_H
+#include <sys/fcntl.h>
+#endif
+#ifdef HAVE_SYS_USER_H
+#include <sys/user.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <glib.h>
@@ -35,6 +62,54 @@
#include "ck-sysdeps.h"
+#ifdef __FreeBSD__
+#include <libprocstat.h>
+
+
+static char *
+get_tty_for_pid (int pid)
+{
+ gchar *device = NULL;
+ gboolean res;
+ char errstr[_POSIX2_LINE_MAX];
+ int cnt = 0;
+ struct vnstat vn;
+ struct filestat_list *head;
+ struct filestat *fst;
+ kvm_t* kd;
+ struct kinfo_proc * prc;
+ struct procstat *procstat;
+
+ kd = kvm_openfiles (NULL, "/dev/null", NULL, O_RDONLY, errstr);
+ prc = kvm_getprocs (kd, KERN_PROC_PID, pid, &cnt);
+ procstat = procstat_open_sysctl ();
+
+ for (int i = 0; i < cnt; i++) {
+ head = procstat_getfiles (procstat,&prc[i], 0);
+
+ STAILQ_FOREACH (fst, head, next) {
+ if (fst->fs_type == PS_FST_TYPE_VNODE) {
+ procstat_get_vnode_info (procstat, fst, &vn, NULL);
+
+ if (vn.vn_type == PS_FST_VTYPE_VCHR) {
+ char *ctty = devname( prc[i].ki_tdev,S_IFCHR);
+ const char * pre = "ttyv";
+
+ if(strncmp (pre, vn.vn_devname, strlen (pre)) == 0 && strncmp (vn.vn_devname, ctty, strlen(ctty)) != 0) {
+ device = g_strdup_printf ("/dev/%s", vn.vn_devname);
+ procstat_freefiles (procstat, head);
+ res = TRUE;
+ return device;
+ }
+ }
+ }
+ }
+ }
+
+ procstat_freefiles(procstat, head);
+ return device;
+}
+#else /* __FreeBSD__ */
static char *
get_tty_for_pid (int pid)
{
@@ -58,6 +133,7 @@ get_tty_for_pid (int pid)
ck_process_stat_free (xorg_stat);
return device;
}
+#endif /* __FreeBSD__ */
static Display *
display_init (const char *display_name)