]> git.pld-linux.org Git - packages/ConsoleKit.git/blame - ConsoleKit-git.patch
- rel 11
[packages/ConsoleKit.git] / ConsoleKit-git.patch
CommitLineData
61cccc46
JR
1diff --git a/NEWS b/NEWS
2index 81c3225..cf06a31 100644
3--- a/NEWS
4+++ b/NEWS
5@@ -1,4 +1,11 @@
6 ==============
7+Version 0.4.5
8+==============
9+
10+ * Loop around opening /dev/console to deal with BKL-less kernels (Colin Watson)
11+ * systemd fixes (Lennart Poettering)
12+
13+==============
14 Version 0.4.4
15 ==============
16
17diff --git a/configure.ac b/configure.ac
18index 0efc489..7a3b33f 100644
19--- a/configure.ac
20+++ b/configure.ac
21@@ -1,7 +1,7 @@
22
23-AC_PREREQ(2.59c)
24+AC_PREREQ([2.68])
25 AC_INIT([ConsoleKit],
26- [0.4.5],
27+ [0.4.6],
28 [https://bugs.freedesktop.org/enter_bug.cgi?product=ConsoleKit],
29 [ConsoleKit])
30
31@@ -12,13 +12,14 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
32 AM_MAINTAINER_MODE
33
34 # for O_NOFOLLOW support
35-AC_GNU_SOURCE
36+AC_USE_SYSTEM_EXTENSIONS
37
38-AC_ISC_POSIX
39+AC_SEARCH_LIBS([strerror],[cposix])
40 AC_PROG_CC
41-AC_STDC_HEADERS
42+AM_PROG_CC_C_O
43+AC_HEADER_STDC
44 AC_DISABLE_STATIC
45-AC_PROG_LIBTOOL
46+LT_INIT
47
48 AC_HEADER_STDC
49
50@@ -88,50 +89,15 @@ case "$host" in
51 ;;
52 esac
53
54-# Find out the version of DBUS we're using
55-
56-dbus_version=`pkg-config --modversion dbus-1`
57-DBUS_VERSION_MAJOR=`echo $dbus_version | awk -F. '{print $1}'`
58-DBUS_VERSION_MINOR=`echo $dbus_version | awk -F. '{print $2}'`
59-DBUS_VERSION_MICRO=`echo $dbus_version | awk -F. '{print $3}'`
60-if test "z$DBUS_VERSION_MAJOR" = "z"; then
61- DBUS_VERSION_MAJOR="0"
62-fi
63-if test "z$DBUS_VERSION_MINOR" = "z"; then
64- DBUS_VERSION_MINOR="0"
65-fi
66-if test "z$DBUS_VERSION_MICRO" = "z"; then
67- DBUS_VERSION_MICRO="0"
68-fi
69-
70-if test "z$DBUS_VERSION_MAJOR" = "z0" -a "z$DBUS_VERSION_MINOR" = "z0" -a "z$DBUS_VERSION_MICRO" = "z0"; then echo "Error: Couldn't determine the version of your DBUS package."
71- echo " This is probably an error in this script, please report it"
72- echo " along with the following information:"
73- echo " Base DBUS version ='$dbus_version'"
74- echo " DBUS_VERSION_MAJOR='$DBUS_VERSION_MAJOR'"
75- echo " DBUS_VERSION_MINOR='$DBUS_VERSION_MINOR'"
76- echo " DBUS_VERSION_MICRO='$DBUS_VERSION_MICRO'"
77- exit 1
78-else
79-
80- echo "Your dbus version is $DBUS_VERSION_MAJOR,$DBUS_VERSION_MINOR,$DBUS_VERSION_MICRO."
81- DBUS_CFLAGS="$DBUS_CFLAGS -DDBUS_VERSION_MAJOR=$DBUS_VERSION_MAJOR"
82- DBUS_CFLAGS="$DBUS_CFLAGS -DDBUS_VERSION_MINOR=$DBUS_VERSION_MINOR"
83- DBUS_CFLAGS="$DBUS_CFLAGS -DDBUS_VERSION_MICRO=$DBUS_VERSION_MICRO"
84-
85- AC_SUBST(DBUS_CFLAGS)
86-fi
87
88 dnl ---------------------------------------------------------------------------
89 dnl - Are we specifying a different dbus root ?
90 dnl ---------------------------------------------------------------------------
91
92 AC_ARG_WITH(dbus-sys,
93- [AC_HELP_STRING([--with-dbus-sys=<dir>],
94- [where D-BUS system.d directory is])])
95+ [AS_HELP_STRING([--with-dbus-sys=<dir>],[where D-BUS system.d directory is])])
96 AC_ARG_WITH(dbus-services,
97- [AC_HELP_STRING([--with-dbus-services=<dir>],
98- [where D-BUS services directory is])])
99+ [AS_HELP_STRING([--with-dbus-services=<dir>],[where D-BUS services directory is])])
100 if ! test -z "$with_dbus_sys" ; then
101 DBUS_SYS_DIR="$with_dbus_sys"
102 else
103@@ -158,8 +124,7 @@ dnl - PID file
104 dnl ---------------------------------------------------------------------------
105
106 AC_ARG_WITH(pid-file,
107- [AC_HELP_STRING([--with-pid-file=<file>],
108- [pid file location])])
109+ [AS_HELP_STRING([--with-pid-file=<file>],[pid file location])])
110
111 if ! test -z "$with_pid_file"; then
112 CONSOLE_KIT_PID_FILE=$with_pid_file
113@@ -190,6 +155,9 @@ case "$host" in
114 *-*-solaris*)
115 CK_BACKEND="solaris"
116 ;;
117+ *-*-gnu*)
118+ CK_BACKEND="gnu"
119+ ;;
120 *)
121 AC_MSG_ERROR([No sysdeps back-end implemented for host $host])
122 ;;
123@@ -200,6 +168,7 @@ AC_SUBST(KVM_LIBS)
124 AM_CONDITIONAL(CK_COMPILE_LINUX, test x$CK_BACKEND = xlinux, [Compiling for Linux])
125 AM_CONDITIONAL(CK_COMPILE_FREEBSD, test x$CK_BACKEND = xfreebsd, [Compiling for FreeBSD])
126 AM_CONDITIONAL(CK_COMPILE_SOLARIS, test x$CK_BACKEND = xsolaris, [Compiling for Solaris])
127+AM_CONDITIONAL(CK_COMPILE_GNU, test x$CK_BACKEND = xgnu, [Compiling for GNU])
128 AC_SUBST(CK_BACKEND)
129
130 dnl ---------------------------------------------------------------------------
131@@ -221,8 +190,7 @@ AC_CHECK_LIB(pam, pam_syslog, [AC_DEFINE(HAVE_PAM_SYSLOG, [], [Define to 1 if yo
132 # Check if we should build the PAM module
133 msg_pam_module=no
134 AC_ARG_ENABLE(pam-module,
135- [AC_HELP_STRING([--enable-pam-module],
136- [build PAM module])],
137+ [AS_HELP_STRING([--enable-pam-module],[build PAM module])],
138 , enable_pam_module=no)
139 if test "x$enable_pam_module" = "xyes"; then
140 if test "x$have_pam" = "xno"; then
141@@ -233,13 +201,32 @@ if test "x$enable_pam_module" = "xyes"; then
142 fi
143 AM_CONDITIONAL(ENABLE_PAM_MODULE, test "x$enable_pam_module" = "xyes")
144
145+dnl ------------------------------------------------------------------------------
146+dnl udev-acl - apply ACLs for users with local forground sessions
147+dnl ------------------------------------------------------------------------------
148+AC_ARG_ENABLE([udev-acl],
149+ AS_HELP_STRING([--enable-udev-acl], [enable local user acl permissions support @<:@default=disabled@:>@]),
150+ [], [enable_udev_acl=no])
151+AS_IF([test "x$enable_udev_acl" = "xyes"], [
152+
153+ PKG_CHECK_MODULES([UDEV_ACL], [glib-2.0 >= 2.22.0 gobject-2.0 >= 2.22.0 libudev])
154+ AC_CHECK_LIB([acl], [acl_init], [UDEV_ACL_LIBS="$UDEV_ACL_LIBS -lacl"], AC_MSG_ERROR([libacl not found]))
155+ AC_CHECK_HEADER([acl/libacl.h], [:], AC_MSG_ERROR([libacl header not found]))
156+ UDEVDIR=`$PKG_CONFIG --variable udevdir udev`
157+ if test -z "$UDEVDIR" ; then
158+ UDEVDIR="/lib/udev"
159+ fi
160+ AC_SUBST(UDEVDIR)
161+])
162+AM_CONDITIONAL([ENABLE_UDEV_ACL], [test "x$enable_udev_acl" = "xyes"])
163+
164+
165 dnl ---------------------------------------------------------------------------
166 dnl - Install directory for PAM security module
167 dnl ---------------------------------------------------------------------------
168
169 AC_ARG_WITH(pam-module-dir,
170- [AC_HELP_STRING([--with-pam-module-dir=<dir>],
171- [directory to install PAM security module])])
172+ [AS_HELP_STRING([--with-pam-module-dir=<dir>],[directory to install PAM security module])])
173 if ! test -z "$with_pam_module_dir"; then
174 PAM_MODULE_DIR="$with_pam_module_dir"
175 else
176@@ -252,8 +239,7 @@ dnl - DocBook Documentation
177 dnl ---------------------------------------------------------------------------
178
179 AC_ARG_ENABLE(docbook-docs,
180- [AC_HELP_STRING([--enable-docbook-docs],
181- [build documentation (requires xmlto)])],
182+ [AS_HELP_STRING([--enable-docbook-docs],[build documentation (requires xmlto)])],
183 enable_docbook_docs=$enableval,enable_docbook_docs=no)
184 AC_PATH_PROG(XMLTO, xmlto, no)
185 AC_MSG_CHECKING([whether to build DocBook documentation])
186@@ -308,8 +294,7 @@ dnl ---------------------------------------------------------------------------
187
188 msg_rbac_shutdown=no
189 AC_ARG_ENABLE(rbac-shutdown,
190- [AC_HELP_STRING([--enable-rbac-shutdown=<key>],
191- [Build with RBAC support specifying shutdown/reboot RBAC authentication key])],
192+ [AS_HELP_STRING([--enable-rbac-shutdown=<key>],[Build with RBAC support specifying shutdown/reboot RBAC authentication key])],
193 enable_rbac_shutdown=$enableval,enable_rbac_shutdown=no)
194 if test "x$enable_rbac_shutdown" != "xno"; then
195 RBAC_LIBS="-lsecdb -lsocket -lnsl"
196@@ -326,8 +311,7 @@ dnl ---------------------------------------------------------------------------
197 # Turn on the additional warnings last, so -Werror doesn't affect other tests.
198
199 AC_ARG_ENABLE(more-warnings,
200- [AC_HELP_STRING([--enable-more-warnings],
201- [Maximum compiler warnings])],
202+ [AS_HELP_STRING([--enable-more-warnings],[Maximum compiler warnings])],
203 set_more_warnings="$enableval",[
204 if test -d $srcdir/.git; then
205 set_more_warnings=yes
206@@ -349,9 +333,7 @@ if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then
207 SAVE_CFLAGS="$CFLAGS"
208 CFLAGS="$CFLAGS $option"
209 AC_MSG_CHECKING([whether gcc understands $option])
210- AC_TRY_COMPILE([], [],
211- has_option=yes,
212- has_option=no,)
213+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[has_option=yes],[has_option=no])
214 if test $has_option = no; then
215 CFLAGS="$SAVE_CFLAGS"
216 fi
217@@ -368,8 +350,7 @@ fi
218 # Enable Debug
219 #
220 AC_ARG_ENABLE(debug,
221- [AC_HELP_STRING([--enable-debug],
222- [turn on debugging])],
223+ [AS_HELP_STRING([--enable-debug],[turn on debugging])],
224 , enable_debug=yes)
225 if test "$enable_debug" = "yes"; then
226 DEBUG_CFLAGS="-DG_ENABLE_DEBUG"
227@@ -395,10 +376,9 @@ AC_SUBST(LDFLAGS)
228
229 AC_ARG_WITH([systemdsystemunitdir],
230 AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
231- [],
232- [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
233-AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
234-AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir"])
235+ [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
236+AS_IF([test "x$with_systemdsystemunitdir" != "xno"], [ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])])
237+AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != "xno"])
238
239 # Files
240
241@@ -445,6 +425,7 @@ echo "
242 Build backend: ${CK_BACKEND}
243 PAM module dir: ${PAM_MODULE_DIR}
244 Build PAM module: ${msg_pam_module}
245+ Build udev-acl: ${enable_udev_acl}
246 Build docs: ${enable_docbook_docs}
247
248 PolicyKit support ${have_polkit}
249diff --git a/pam-ck-connector/pam-ck-connector.c b/pam-ck-connector/pam-ck-connector.c
250index 9bdef51..949a9b0 100644
251--- a/pam-ck-connector/pam-ck-connector.c
252+++ b/pam-ck-connector/pam-ck-connector.c
253@@ -244,12 +244,12 @@ pam_sm_open_session (pam_handle_t *pamh,
254 const char *s;
255 uid_t uid;
256 char buf[256];
257- char ttybuf[PATH_MAX];
258+ char *ttybuf;
259 DBusError error;
260 dbus_bool_t is_local;
261
262 ret = PAM_IGNORE;
263-
264+ ttybuf = NULL;
265 is_local = TRUE;
266
267 _parse_pam_args (pamh, flags, argc, argv);
268@@ -295,7 +295,13 @@ pam_sm_open_session (pam_handle_t *pamh,
269 x11_display = display_device;
270 display_device = "";
271 } else if (strncmp (_PATH_DEV, display_device, 5) != 0) {
272- snprintf (ttybuf, sizeof (ttybuf), _PATH_DEV "%s", display_device);
273+ int len = strlen (_PATH_DEV) + strlen (display_device) + 1;
274+ ttybuf = malloc (len);
275+ if (ttybuf == NULL) {
276+ ck_pam_syslog (pamh, LOG_ERR, "oom allocating ttybuf");
277+ goto out;
278+ }
279+ snprintf (ttybuf, len, _PATH_DEV "%s", display_device);
280 display_device = ttybuf;
281 }
282
283@@ -411,6 +417,8 @@ pam_sm_open_session (pam_handle_t *pamh,
284 ret = PAM_SUCCESS;
285
286 out:
287+ free (ttybuf);
288+
289 return ret;
290 }
291
292diff --git a/src/Makefile.am b/src/Makefile.am
293index 869decd..217e531 100644
294--- a/src/Makefile.am
295+++ b/src/Makefile.am
296@@ -57,11 +57,18 @@ libck_la_SOURCES += \
297 $(NULL)
298 libck_la_LIBADD = $(KVM_LIBS)
299 endif
300+if CK_COMPILE_GNU
301+libck_la_SOURCES += \
302+ ck-sysdeps-gnu.c \
303+ $(NULL)
304+libck_la_LIBADD = -lps
305+endif
306
307 EXTRA_libck_la_SOURCES = \
308 ck-sysdeps-linux.c \
309 ck-sysdeps-solaris.c \
310 ck-sysdeps-freebsd.c \
311+ ck-sysdeps-gnu.c \
312 $(NULL)
313
314 sbin_PROGRAMS = \
315diff --git a/src/ck-sysdeps-gnu.c b/src/ck-sysdeps-gnu.c
316new file mode 100644
317index 0000000..254f7ef
318--- /dev/null
319+++ b/src/ck-sysdeps-gnu.c
320@@ -0,0 +1,402 @@
321+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
322+ *
323+ * Copyright (C) 2009 Pino Toscano <pino@kde.org>
324+ *
325+ * This program is free software; you can redistribute it and/or modify
326+ * it under the terms of the GNU General Public License as published by
327+ * the Free Software Foundation; either version 2 of the License, or
328+ * (at your option) any later version.
329+ *
330+ * This program is distributed in the hope that it will be useful,
331+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
332+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
333+ * GNU General Public License for more details.
334+ *
335+ * You should have received a copy of the GNU General Public License
336+ * along with this program; if not, write to the Free Software
337+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
338+ *
339+ */
340+
341+#include "config.h"
342+
343+#include <stdlib.h>
344+#include <stdio.h>
345+#include <unistd.h>
346+#include <string.h>
347+#include <errno.h>
348+
349+#include <hurd.h>
350+#include <dirent.h>
351+#include <ps.h>
352+#include <ttyent.h>
353+
354+#ifdef HAVE_PATHS_H
355+#include <paths.h>
356+#endif /* HAVE_PATHS_H */
357+
358+#include "ck-sysdeps.h"
359+
360+struct _CkProcessStat
361+{
362+ struct proc_stat *ps; /* the statistics of a process */
363+};
364+
365+static struct ps_context *pc = NULL;
366+
367+static gboolean
368+get_proc_stat_from_pid (pid_t pid,
369+ ps_flags_t flags,
370+ struct proc_stat **res_ps)
371+{
372+ error_t err;
373+ struct proc_stat *ps;
374+
375+ g_assert (pid >= 0);
376+ g_assert (res_ps != NULL);
377+
378+ if (pc == NULL) {
379+ err = ps_context_create (getproc (), &pc);
380+ if (err) {
381+ return FALSE;
382+ }
383+ }
384+
385+ err = _proc_stat_create (pid, pc, &ps);
386+ if (err) {
387+ return FALSE;
388+ }
389+
390+ err = proc_stat_set_flags (ps, PSTAT_PID | flags);
391+ if (err) {
392+ return FALSE;
393+ }
394+
395+ *res_ps = ps;
396+ return TRUE;
397+}
398+
399+
400+pid_t
401+ck_process_stat_get_ppid (CkProcessStat *stat)
402+{
403+ g_return_val_if_fail (stat != NULL, -1);
404+
405+ return proc_stat_pid (stat->ps);
406+}
407+
408+char *
409+ck_process_stat_get_cmd (CkProcessStat *stat)
410+{
411+ g_return_val_if_fail (stat != NULL, NULL);
412+
413+ return g_strdup (proc_stat_args (stat->ps));
414+}
415+
416+char *
417+ck_process_stat_get_tty (CkProcessStat *stat)
418+{
419+ struct ps_tty *tty;
420+
421+ g_return_val_if_fail (stat != NULL, NULL);
422+
423+ tty = proc_stat_tty (stat->ps);
424+
425+ return tty ? g_strdup (ps_tty_name (tty)) : NULL;
426+}
427+
428+gboolean
429+ck_process_stat_new_for_unix_pid (pid_t pid,
430+ CkProcessStat **stat,
431+ GError **error)
432+{
433+ gboolean res;
434+ struct proc_stat *ps;
435+ CkProcessStat *proc;
436+
437+ g_return_val_if_fail (pid > 1, FALSE);
438+
439+ if (stat == NULL) {
440+ return FALSE;
441+ }
442+
443+ *stat = NULL;
444+
445+ res = get_proc_stat_from_pid (pid, PSTAT_ARGS | PSTAT_TTY, &ps);
446+ if (!res) {
447+ return FALSE;
448+ }
449+
450+ proc = g_new0 (CkProcessStat, 1);
451+ proc->ps = ps;
452+ *stat = proc;
453+
454+ return TRUE;
455+}
456+
457+void
458+ck_process_stat_free (CkProcessStat *stat)
459+{
460+ _proc_stat_free (stat->ps);
461+
462+ g_free (stat);
463+}
464+
465+GHashTable *
466+ck_unix_pid_get_env_hash (pid_t pid)
467+{
468+ struct proc_stat *ps;
469+ char *env_p;
470+ size_t env_index;
471+ size_t env_l;
472+ gboolean res;
473+ GHashTable *hash;
474+
475+ g_return_val_if_fail (pid > 1, NULL);
476+
477+ res = get_proc_stat_from_pid (pid, PSTAT_ENV, &ps);
478+ if (!res) {
479+ return NULL;
480+ }
481+
482+ hash = g_hash_table_new_full (g_str_hash,
483+ g_str_equal,
484+ g_free,
485+ g_free);
486+
487+ env_index = 0;
488+ env_l = 0;
489+ env_p = proc_stat_env (ps);
490+ while (env_index < proc_stat_env_len (ps)) {
491+ env_l = strlen (env_p);
492+ env_index += env_l + 1;
493+ if (env_l) {
494+ char **vals;
495+ vals = g_strsplit (env_p, "=", 2);
496+ if (vals != NULL) {
497+ g_hash_table_insert (hash,
498+ g_strdup (vals[0]),
499+ g_strdup (vals[1]));
500+ g_strfreev (vals);
501+ }
502+ }
503+ env_p = env_p + env_l + 1;
504+ }
505+
506+ _proc_stat_free (ps);
507+
508+ return hash;
509+}
510+
511+char *
512+ck_unix_pid_get_env (pid_t pid,
513+ const char *var)
514+{
515+ struct proc_stat *ps;
516+ char *env_p;
517+ size_t env_index;
518+ size_t env_l;
519+ char *prefix;
520+ int prefix_len;
521+ char *val;
522+ gboolean res;
523+
524+ g_return_val_if_fail (pid > 1, NULL);
525+
526+ val = NULL;
527+
528+ res = get_proc_stat_from_pid (pid, PSTAT_ENV, &ps);
529+ if (!res) {
530+ return NULL;
531+ }
532+
533+ prefix = g_strdup_printf ("%s=", var);
534+ prefix_len = strlen (prefix);
535+
536+ env_index = 0;
537+ env_l = 0;
538+ env_p = proc_stat_env (ps);
539+ while (env_index < proc_stat_env_len (ps)) {
540+ env_l = strlen (env_p);
541+ env_index += env_l + 1;
542+ if (env_l && g_str_has_prefix (env_p, prefix)) {
543+ val = g_strdup (env_p + prefix_len);
544+ break;
545+ }
546+ env_p = env_p + env_l + 1;
547+ }
548+
549+ g_free (prefix);
550+
551+ _proc_stat_free (ps);
552+
553+ return val;
554+}
555+
556+uid_t
557+ck_unix_pid_get_uid (pid_t pid)
558+{
559+ struct proc_stat *ps;
560+ gboolean res;
561+ uid_t uid;
562+
563+ g_return_val_if_fail (pid > 1, 0);
564+
565+ res = get_proc_stat_from_pid (pid, PSTAT_OWNER_UID, &ps);
566+ if (!res) {
567+ return 0;
568+ }
569+
570+ uid = proc_stat_owner_uid (ps);
571+
572+ _proc_stat_free (ps);
573+
574+ return uid;
575+}
576+
577+pid_t
578+ck_unix_pid_get_ppid (pid_t pid)
579+{
580+ struct proc_stat *ps;
581+ gboolean res;
582+ pid_t ppid;
583+
584+ g_return_val_if_fail (pid > 1, 0);
585+
586+ res = get_proc_stat_from_pid (pid, PSTAT_PROC_INFO, &ps);
587+ if (!res) {
588+ return 0;
589+ }
590+
591+ ppid = proc_stat_proc_info (ps)->ppid;
592+
593+ _proc_stat_free (ps);
594+
595+ return ppid;
596+}
597+
598+gboolean
599+ck_unix_pid_get_login_session_id (pid_t pid,
600+ char **idp)
601+{
602+ g_return_val_if_fail (pid > 1, FALSE);
603+
604+ return FALSE;
605+}
606+
607+gboolean
608+ck_get_max_num_consoles (guint *num)
609+{
610+ int max_consoles;
611+ int res;
612+ gboolean ret;
613+ struct ttyent *t;
614+
615+ ret = FALSE;
616+ max_consoles = 0;
617+
618+ res = setttyent ();
619+ if (res == 0) {
620+ goto done;
621+ }
622+
623+ while ((t = getttyent ()) != NULL) {
624+ if (t->ty_status & TTY_ON && strncmp (t->ty_name, "tty", 3) == 0)
625+ max_consoles++;
626+ }
627+
628+ /* Increment one more so that all consoles are properly counted
629+ * this is arguable a bug in vt_add_watches().
630+ */
631+ max_consoles++;
632+
633+ ret = TRUE;
634+
635+ endttyent ();
636+
637+done:
638+ if (num != NULL) {
639+ *num = max_consoles;
640+ }
641+
642+ return ret;
643+}
644+
645+gboolean
646+ck_supports_activatable_consoles (void)
647+{
648+ return TRUE;
649+}
650+
651+char *
652+ck_get_console_device_for_num (guint num)
653+{
654+ char *device;
655+
656+ device = g_strdup_printf (_PATH_TTY "%u", num);
657+
658+ return device;
659+}
660+
661+gboolean
662+ck_get_console_num_from_device (const char *device,
663+ guint *num)
664+{
665+ guint n;
666+ gboolean ret;
667+
668+ n = 0;
669+ ret = FALSE;
670+
671+ if (device == NULL) {
672+ return FALSE;
673+ }
674+
675+ if (sscanf (device, _PATH_TTY "%u", &n) == 1) {
676+ ret = TRUE;
677+ }
678+
679+ if (num != NULL) {
680+ *num = n;
681+ }
682+
683+ return ret;
684+}
685+
686+gboolean
687+ck_get_active_console_num (int console_fd,
688+ guint *num)
689+{
690+ gboolean ret;
691+ int res;
692+ long cur_active;
693+ char buf[30];
694+ guint active;
695+
696+ g_assert (console_fd != -1);
697+
698+ active = 0;
699+ ret = FALSE;
700+
701+ res = readlink ("/dev/cons/vcs", buf, sizeof (buf));
702+ if (res > 0) {
703+ /* the resolved path is like "/dev/vcs/$number", so skip
704+ the non-number part at the start */
705+ const char *p = buf;
706+ while ((*p) && ((*p < '0') || (*p > '9'))) {
707+ ++p;
708+ }
709+ if (*p) {
710+ cur_active = strtol (p, NULL, 10);
711+ g_debug ("Current VT: tty%ld", cur_active);
712+ active = cur_active;
713+ ret = TRUE;
714+ }
715+ }
716+
717+ if (num != NULL) {
718+ *num = active;
719+ }
720+
721+ return ret;
722+}
723diff --git a/tools/70-udev-acl.rules b/tools/70-udev-acl.rules
724new file mode 100644
725index 0000000..2dac283
726--- /dev/null
727+++ b/tools/70-udev-acl.rules
728@@ -0,0 +1,76 @@
729+# do not edit this file, it will be overwritten on update
730+
731+# Do not use TAG+="udev-acl" outside of this file. This variable is private to
732+# udev-acl of this udev release and may be replaced at any time.
733+
734+ENV{MAJOR}=="", GOTO="acl_end"
735+ACTION=="remove", GOTO="acl_apply"
736+
737+# systemd replaces udev-acl entirely, skip if active
738+TEST=="/sys/fs/cgroup/systemd", TAG=="uaccess", GOTO="acl_end"
739+
740+# PTP/MTP protocol devices, cameras, portable media players
741+SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:060101:*", TAG+="udev-acl"
742+
743+# digicams with proprietary protocol
744+ENV{ID_GPHOTO2}=="*?", TAG+="udev-acl"
745+
746+# SCSI and USB scanners
747+ENV{libsane_matched}=="yes", TAG+="udev-acl"
748+
749+# HPLIP devices (necessary for ink level check and HP tool maintenance)
750+ENV{ID_HPLIP}=="1", TAG+="udev-acl"
751+
752+# optical drives
753+SUBSYSTEM=="block", ENV{ID_CDROM}=="1", TAG+="udev-acl"
754+SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", TAG+="udev-acl"
755+
756+# sound devices
757+SUBSYSTEM=="sound", TAG+="udev-acl"
758+
759+# ffado is an userspace driver for firewire sound cards
760+SUBSYSTEM=="firewire", ENV{ID_FFADO}=="1", TAG+="udev-acl"
761+
762+# webcams, frame grabber, TV cards
763+SUBSYSTEM=="video4linux", TAG+="udev-acl"
764+SUBSYSTEM=="dvb", TAG+="udev-acl"
765+
766+# IIDC devices: industrial cameras and some webcams
767+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x00010*", TAG+="udev-acl"
768+SUBSYSTEM=="firewire", ATTR{units}=="*0x00b09d:0x00010*", TAG+="udev-acl"
769+# AV/C devices: camcorders, set-top boxes, TV sets, audio devices, and more
770+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", TAG+="udev-acl"
771+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", TAG+="udev-acl"
772+
773+# DRI video devices
774+SUBSYSTEM=="drm", KERNEL=="card*", TAG+="udev-acl"
775+
776+# KVM
777+SUBSYSTEM=="misc", KERNEL=="kvm", TAG+="udev-acl"
778+
779+# smart-card readers
780+ENV{ID_SMARTCARD_READER}=="*?", TAG+="udev-acl"
781+
782+# PDA devices
783+ENV{ID_PDA}=="*?", TAG+="udev-acl"
784+
785+# Programmable remote control
786+ENV{ID_REMOTE_CONTROL}=="1", TAG+="udev-acl"
787+
788+# joysticks
789+SUBSYSTEM=="input", ENV{ID_INPUT_JOYSTICK}=="?*", TAG+="udev-acl"
790+
791+# color measurement devices
792+ENV{COLOR_MEASUREMENT_DEVICE}=="*?", TAG+="udev-acl"
793+
794+# DDC/CI device, usually high-end monitors such as the DreamColor
795+ENV{DDC_DEVICE}=="*?", TAG+="udev-acl"
796+
797+# media player raw devices (for user-mode drivers, Android SDK, etc.)
798+SUBSYSTEM=="usb", ENV{ID_MEDIA_PLAYER}=="?*", TAG+="udev-acl"
799+
800+# apply ACL for all locally logged in users
801+LABEL="acl_apply", TAG=="udev-acl", TEST=="/var/run/ConsoleKit/database", \
802+ RUN+="udev-acl --action=$env{ACTION} --device=$env{DEVNAME}"
803+
804+LABEL="acl_end"
805diff --git a/tools/Makefile.am b/tools/Makefile.am
806index 13c191f..88f3c91 100644
807--- a/tools/Makefile.am
808+++ b/tools/Makefile.am
809@@ -143,6 +143,21 @@ ck_get_x11_display_device_LDADD = \
810 $(top_builddir)/src/libck.la \
811 $(NULL)
812
813+if ENABLE_UDEV_ACL
814+udevdir = $(UDEVDIR)
815+udevrulesdir = $(UDEVDIR)/rules.d
816+
817+dist_udevrules_DATA = 70-udev-acl.rules
818+udev_PROGRAMS = udev-acl
819+
820+udev_acl_SOURCES = udev-acl.c
821+udev_acl_LDADD = $(UDEV_ACL_LIBS)
822+udev_acl_CFLAGS = $(UDEV_ACL_CFLAGS)
823+
824+install-exec-hook:
825+ mkdir -p $(DESTDIR)$(prefix)/lib/ConsoleKit/run-seat.d
826+ ln -sf $(UDEVDIR)/udev-acl $(DESTDIR)$(prefix)/lib/ConsoleKit/run-seat.d/udev-acl.ck
827+endif
828
829 EXTRA_DIST = \
830 $(NULL)
831diff --git a/tools/ck-history.c b/tools/ck-history.c
832index d02caaa..85d9e6f 100644
833--- a/tools/ck-history.c
834+++ b/tools/ck-history.c
835@@ -804,7 +804,7 @@ generate_report_frequent (int uid,
836 data = user_counts->data;
837
838 username = get_user_name_for_uid (data->uid);
839- g_print ("%-8.8s %u\n", username, data->count);
840+ g_print ("%-8s %u\n", username, data->count);
841 g_free (data);
842 user_counts = g_list_delete_link (user_counts, user_counts);
843 g_free (username);
844diff --git a/tools/udev-acl.c b/tools/udev-acl.c
845new file mode 100644
846index 0000000..628cfbe
847--- /dev/null
848+++ b/tools/udev-acl.c
849@@ -0,0 +1,430 @@
850+/*
851+ * Copyright (C) 2009 Kay Sievers <kay.sievers@vrfy.org>
852+ *
853+ * This program is free software; you can redistribute it and/or
854+ * modify it under the terms of the GNU General Public License as
855+ * published by the Free Software Foundation; either version 2 of the
856+ * License, or (at your option) any later version.
857+ *
858+ * This program is distributed in the hope that it will be useful, but
859+ * WITHOUT ANY WARRANTY; without even the implied warranty of
860+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
861+ * General Public License for more details:
862+ */
863+
864+#include <acl/libacl.h>
865+#include <sys/stat.h>
866+#include <errno.h>
867+#include <getopt.h>
868+#include <glib.h>
869+#include <inttypes.h>
870+#include <libudev.h>
871+#include <stdbool.h>
872+#include <stdio.h>
873+#include <stdlib.h>
874+#include <string.h>
875+#include <unistd.h>
876+
877+static int debug;
878+
879+enum{
880+ ACTION_NONE = 0,
881+ ACTION_REMOVE,
882+ ACTION_ADD,
883+ ACTION_CHANGE
884+};
885+
886+static int set_facl(const char* filename, uid_t uid, int add)
887+{
888+ int get;
889+ acl_t acl;
890+ acl_entry_t entry = NULL;
891+ acl_entry_t e;
892+ acl_permset_t permset;
893+ int ret;
894+
895+ /* don't touch ACLs for root */
896+ if (uid == 0)
897+ return 0;
898+
899+ /* read current record */
900+ acl = acl_get_file(filename, ACL_TYPE_ACCESS);
901+ if (!acl)
902+ return -1;
903+
904+ /* locate ACL_USER entry for uid */
905+ get = acl_get_entry(acl, ACL_FIRST_ENTRY, &e);
906+ while (get == 1) {
907+ acl_tag_t t;
908+
909+ acl_get_tag_type(e, &t);
910+ if (t == ACL_USER) {
911+ uid_t *u;
912+
913+ u = (uid_t*)acl_get_qualifier(e);
914+ if (u == NULL) {
915+ ret = -1;
916+ goto out;
917+ }
918+ if (*u == uid) {
919+ entry = e;
920+ acl_free(u);
921+ break;
922+ }
923+ acl_free(u);
924+ }
925+
926+ get = acl_get_entry(acl, ACL_NEXT_ENTRY, &e);
927+ }
928+
929+ /* remove ACL_USER entry for uid */
930+ if (!add) {
931+ if (entry == NULL) {
932+ ret = 0;
933+ goto out;
934+ }
935+ acl_delete_entry(acl, entry);
936+ goto update;
937+ }
938+
939+ /* create ACL_USER entry for uid */
940+ if (entry == NULL) {
941+ ret = acl_create_entry(&acl, &entry);
942+ if (ret != 0)
943+ goto out;
944+ acl_set_tag_type(entry, ACL_USER);
945+ acl_set_qualifier(entry, &uid);
946+ }
947+
948+ /* add permissions for uid */
949+ acl_get_permset(entry, &permset);
950+ acl_add_perm(permset, ACL_READ|ACL_WRITE);
951+update:
952+ /* update record */
953+ if (debug)
954+ printf("%c%u %s\n", add ? '+' : '-', uid, filename);
955+ acl_calc_mask(&acl);
956+ ret = acl_set_file(filename, ACL_TYPE_ACCESS, acl);
957+ if (ret != 0)
958+ goto out;
959+out:
960+ acl_free(acl);
961+ return ret;
962+}
963+
964+/* check if a given uid is listed */
965+static int uid_in_list(GSList *list, uid_t uid)
966+{
967+ GSList *l;
968+
969+ for (l = list; l != NULL; l = g_slist_next(l))
970+ if (uid == GPOINTER_TO_UINT(l->data))
971+ return 1;
972+ return 0;
973+}
974+
975+/* return list of current uids of local active sessions */
976+static GSList *uids_with_local_active_session(const char *own_id)
977+{
978+ GSList *list = NULL;
979+ GKeyFile *keyfile;
980+
981+ keyfile = g_key_file_new();
982+ if (g_key_file_load_from_file(keyfile, "/var/run/ConsoleKit/database", 0, NULL)) {
983+ gchar **groups;
984+
985+ groups = g_key_file_get_groups(keyfile, NULL);
986+ if (groups != NULL) {
987+ int i;
988+
989+ for (i = 0; groups[i] != NULL; i++) {
990+ uid_t u;
991+
992+ if (!g_str_has_prefix(groups[i], "Session "))
993+ continue;
994+ if (own_id != NULL &&g_str_has_suffix(groups[i], own_id))
995+ continue;
996+ if (!g_key_file_get_boolean(keyfile, groups[i], "is_local", NULL))
997+ continue;
998+ if (!g_key_file_get_boolean(keyfile, groups[i], "is_active", NULL))
999+ continue;
1000+ u = g_key_file_get_integer(keyfile, groups[i], "uid", NULL);
1001+ if (u > 0 && !uid_in_list(list, u))
1002+ list = g_slist_prepend(list, GUINT_TO_POINTER(u));
1003+ }
1004+ g_strfreev(groups);
1005+ }
1006+ }
1007+ g_key_file_free(keyfile);
1008+
1009+ return list;
1010+}
1011+
1012+/* ConsoleKit calls us with special variables */
1013+static int consolekit_called(const char *ck_action, uid_t *uid, uid_t *uid2, const char **remove_session_id, int *action)
1014+{
1015+ int a = ACTION_NONE;
1016+ uid_t u = 0;
1017+ uid_t u2 = 0;
1018+ const char *s;
1019+ const char *s2;
1020+ const char *old_session = NULL;
1021+
1022+ if (ck_action == NULL || strcmp(ck_action, "seat_active_session_changed") != 0)
1023+ return -1;
1024+
1025+ /* We can have one of: remove, add, change, no-change */
1026+ s = getenv("CK_SEAT_OLD_SESSION_ID");
1027+ s2 = getenv("CK_SEAT_SESSION_ID");
1028+ if (s == NULL && s2 == NULL) {
1029+ return -1;
1030+ } else if (s2 == NULL) {
1031+ a = ACTION_REMOVE;
1032+ } else if (s == NULL) {
1033+ a = ACTION_ADD;
1034+ } else {
1035+ a = ACTION_CHANGE;
1036+ }
1037+
1038+ switch (a) {
1039+ case ACTION_ADD:
1040+ s = getenv("CK_SEAT_SESSION_USER_UID");
1041+ if (s == NULL)
1042+ return -1;
1043+ u = strtoul(s, NULL, 10);
1044+
1045+ s = getenv("CK_SEAT_SESSION_IS_LOCAL");
1046+ if (s == NULL)
1047+ return -1;
1048+ if (strcmp(s, "true") != 0)
1049+ return 0;
1050+
1051+ break;
1052+ case ACTION_REMOVE:
1053+ s = getenv("CK_SEAT_OLD_SESSION_USER_UID");
1054+ if (s == NULL)
1055+ return -1;
1056+ u = strtoul(s, NULL, 10);
1057+
1058+ s = getenv("CK_SEAT_OLD_SESSION_IS_LOCAL");
1059+ if (s == NULL)
1060+ return -1;
1061+ if (strcmp(s, "true") != 0)
1062+ return 0;
1063+
1064+ old_session = getenv("CK_SEAT_OLD_SESSION_ID");
1065+ if (old_session == NULL)
1066+ return -1;
1067+
1068+ break;
1069+ case ACTION_CHANGE:
1070+ s = getenv("CK_SEAT_OLD_SESSION_USER_UID");
1071+ if (s == NULL)
1072+ return -1;
1073+ u = strtoul(s, NULL, 10);
1074+ s = getenv("CK_SEAT_SESSION_USER_UID");
1075+ if (s == NULL)
1076+ return -1;
1077+ u2 = strtoul(s, NULL, 10);
1078+
1079+ s = getenv("CK_SEAT_OLD_SESSION_IS_LOCAL");
1080+ s2 = getenv("CK_SEAT_SESSION_IS_LOCAL");
1081+ if (s == NULL || s2 == NULL)
1082+ return -1;
1083+ /* don't process non-local session changes */
1084+ if (strcmp(s, "true") != 0 && strcmp(s2, "true") != 0)
1085+ return 0;
1086+
1087+ if (strcmp(s, "true") == 0 && strcmp(s, "true") == 0) {
1088+ /* process the change */
1089+ if (u == u2) {
1090+ /* special case: we noop if we are
1091+ * changing between local sessions for
1092+ * the same uid */
1093+ a = ACTION_NONE;
1094+ }
1095+ old_session = getenv("CK_SEAT_OLD_SESSION_ID");
1096+ if (old_session == NULL)
1097+ return -1;
1098+ } else if (strcmp(s, "true") == 0) {
1099+ /* only process the removal */
1100+ a = ACTION_REMOVE;
1101+ old_session = getenv("CK_SEAT_OLD_SESSION_ID");
1102+ if (old_session == NULL)
1103+ return -1;
1104+ } else if (strcmp(s2, "true") == 0) {
1105+ /* only process the addition */
1106+ a = ACTION_ADD;
1107+ u = u2;
1108+ }
1109+ break;
1110+ }
1111+
1112+ *remove_session_id = old_session;
1113+ *uid = u;
1114+ *uid2 = u2;
1115+ *action = a;
1116+ return 0;
1117+}
1118+
1119+/* add or remove a ACL for a given uid from all matching devices */
1120+static void apply_acl_to_devices(uid_t uid, int add)
1121+{
1122+ struct udev *udev;
1123+ struct udev_enumerate *enumerate;
1124+ struct udev_list_entry *list_entry;
1125+
1126+ /* iterate over all devices tagged with ACL_SET */
1127+ udev = udev_new();
1128+ enumerate = udev_enumerate_new(udev);
1129+ udev_enumerate_add_match_tag(enumerate, "udev-acl");
1130+ udev_enumerate_scan_devices(enumerate);
1131+ udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
1132+ struct udev_device *device;
1133+ const char *node;
1134+
1135+ device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
1136+ udev_list_entry_get_name(list_entry));
1137+ if (device == NULL)
1138+ continue;
1139+ node = udev_device_get_devnode(device);
1140+ if (node == NULL) {
1141+ udev_device_unref(device);
1142+ continue;
1143+ }
1144+ set_facl(node, uid, add);
1145+ udev_device_unref(device);
1146+ }
1147+ udev_enumerate_unref(enumerate);
1148+ udev_unref(udev);
1149+}
1150+
1151+static void
1152+remove_uid (uid_t uid, const char *remove_session_id)
1153+{
1154+ /*
1155+ * Remove ACL for given uid from all matching devices
1156+ * when there is currently no local active session.
1157+ */
1158+ GSList *list;
1159+
1160+ list = uids_with_local_active_session(remove_session_id);
1161+ if (!uid_in_list(list, uid))
1162+ apply_acl_to_devices(uid, 0);
1163+ g_slist_free(list);
1164+}
1165+
1166+int main (int argc, char* argv[])
1167+{
1168+ static const struct option options[] = {
1169+ { "action", required_argument, NULL, 'a' },
1170+ { "device", required_argument, NULL, 'D' },
1171+ { "user", required_argument, NULL, 'u' },
1172+ { "debug", no_argument, NULL, 'd' },
1173+ { "help", no_argument, NULL, 'h' },
1174+ {}
1175+ };
1176+ int action = -1;
1177+ const char *device = NULL;
1178+ bool uid_given = false;
1179+ uid_t uid = 0;
1180+ uid_t uid2 = 0;
1181+ const char* remove_session_id = NULL;
1182+ int rc = 0;
1183+
1184+ /* valgrind is more important to us than a slice allocator */
1185+ g_slice_set_config (G_SLICE_CONFIG_ALWAYS_MALLOC, 1);
1186+
1187+ while (1) {
1188+ int option;
1189+
1190+ option = getopt_long(argc, argv, "+a:D:u:dh", options, NULL);
1191+ if (option == -1)
1192+ break;
1193+
1194+ switch (option) {
1195+ case 'a':
1196+ if (strcmp(optarg, "remove") == 0)
1197+ action = ACTION_REMOVE;
1198+ else
1199+ action = ACTION_ADD;
1200+ break;
1201+ case 'D':
1202+ device = optarg;
1203+ break;
1204+ case 'u':
1205+ uid_given = true;
1206+ uid = strtoul(optarg, NULL, 10);
1207+ break;
1208+ case 'd':
1209+ debug = 1;
1210+ break;
1211+ case 'h':
1212+ printf("Usage: udev-acl --action=ACTION [--device=DEVICEFILE] [--user=UID]\n\n");
1213+ goto out;
1214+ }
1215+ }
1216+
1217+ if (action < 0 && device == NULL && !uid_given)
1218+ if (!consolekit_called(argv[optind], &uid, &uid2, &remove_session_id, &action))
1219+ uid_given = true;
1220+
1221+ if (action < 0) {
1222+ fprintf(stderr, "missing action\n\n");
1223+ rc = 2;
1224+ goto out;
1225+ }
1226+
1227+ if (device != NULL && uid_given) {
1228+ fprintf(stderr, "only one option, --device=DEVICEFILE or --user=UID expected\n\n");
1229+ rc = 3;
1230+ goto out;
1231+ }
1232+
1233+ if (uid_given) {
1234+ switch (action) {
1235+ case ACTION_ADD:
1236+ /* Add ACL for given uid to all matching devices. */
1237+ apply_acl_to_devices(uid, 1);
1238+ break;
1239+ case ACTION_REMOVE:
1240+ remove_uid(uid, remove_session_id);
1241+ break;
1242+ case ACTION_CHANGE:
1243+ remove_uid(uid, remove_session_id);
1244+ apply_acl_to_devices(uid2, 1);
1245+ break;
1246+ case ACTION_NONE:
1247+ goto out;
1248+ break;
1249+ default:
1250+ g_assert_not_reached();
1251+ break;
1252+ }
1253+ } else if (device != NULL) {
1254+ /*
1255+ * Add ACLs for all current session uids to a given device.
1256+ *
1257+ * Or remove ACLs for uids which do not have any current local
1258+ * active session. Remove is not really interesting, because in
1259+ * most cases the device node is removed anyway.
1260+ */
1261+ GSList *list;
1262+ GSList *l;
1263+
1264+ list = uids_with_local_active_session(NULL);
1265+ for (l = list; l != NULL; l = g_slist_next(l)) {
1266+ uid_t u;
1267+
1268+ u = GPOINTER_TO_UINT(l->data);
1269+ if (action == ACTION_ADD || !uid_in_list(list, u))
1270+ set_facl(device, u, action == ACTION_ADD);
1271+ }
1272+ g_slist_free(list);
1273+ } else {
1274+ fprintf(stderr, "--device=DEVICEFILE or --user=UID expected\n\n");
1275+ rc = 3;
1276+ }
1277+out:
1278+ return rc;
1279+}
This page took 0.186695 seconds and 4 git commands to generate.