diff options
author | Samuli Suominen <ssuominen@gentoo.org> | 2012-03-20 07:39:06 +0000 |
---|---|---|
committer | Samuli Suominen <ssuominen@gentoo.org> | 2012-03-20 07:39:06 +0000 |
commit | 3bcdb3f2582818f9a92f92620795c62cc7c6483f (patch) | |
tree | 300e37ddeeed4287c20119781a06c61e31954809 /sys-auth | |
parent | Unmask =sys-fs/udev-182 because udev-acl is now moved to =sys-auth/consolekit... (diff) | |
download | gentoo-2-3bcdb3f2582818f9a92f92620795c62cc7c6483f.tar.gz gentoo-2-3bcdb3f2582818f9a92f92620795c62cc7c6483f.tar.bz2 gentoo-2-3bcdb3f2582818f9a92f92620795c62cc7c6483f.zip |
Move udev-acl from sys-fs/udev to here wrt #408713 by Rafał Mużyło
(Portage version: 2.2.0_alpha92/cvs/Linux x86_64)
Diffstat (limited to 'sys-auth')
5 files changed, 739 insertions, 2 deletions
diff --git a/sys-auth/consolekit/ChangeLog b/sys-auth/consolekit/ChangeLog index 368b3ec4dc58..d2bb12bb1722 100644 --- a/sys-auth/consolekit/ChangeLog +++ b/sys-auth/consolekit/ChangeLog @@ -1,6 +1,14 @@ # ChangeLog for sys-auth/consolekit -# Copyright 1999-2011 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/sys-auth/consolekit/ChangeLog,v 1.114 2011/10/20 19:14:47 axs Exp $ +# Copyright 1999-2012 Gentoo Foundation; Distributed under the GPL v2 +# $Header: /var/cvsroot/gentoo-x86/sys-auth/consolekit/ChangeLog,v 1.115 2012/03/20 07:39:06 ssuominen Exp $ + +*consolekit-0.4.5-r3 (20 Mar 2012) + + 20 Mar 2012; Samuli Suominen <ssuominen@gentoo.org> + +consolekit-0.4.5-r3.ebuild, +files/consolekit-0.4.5-udev-acl.patch, + +files/consolekit-0.4.5-udev-acl-install_to_usr_and_missing_seat_d_symlink.pa + tch, +files/consolekit-0.4.5-udev-acl-missing-AC_SUBST.patch: + Move udev-acl from sys-fs/udev to here wrt #408713 by Rafał Mużyło *consolekit-0.4.5-r2 (20 Oct 2011) diff --git a/sys-auth/consolekit/consolekit-0.4.5-r3.ebuild b/sys-auth/consolekit/consolekit-0.4.5-r3.ebuild new file mode 100644 index 000000000000..62ec510b7d72 --- /dev/null +++ b/sys-auth/consolekit/consolekit-0.4.5-r3.ebuild @@ -0,0 +1,95 @@ +# Copyright 1999-2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/sys-auth/consolekit/consolekit-0.4.5-r3.ebuild,v 1.1 2012/03/20 07:39:06 ssuominen Exp $ + +EAPI=4 +inherit autotools eutils linux-info pam systemd + +MY_PN=ConsoleKit +MY_P=${MY_PN}-${PV} + +DESCRIPTION="Framework for defining and tracking users, login sessions and seats." +HOMEPAGE="http://www.freedesktop.org/wiki/Software/ConsoleKit" +SRC_URI="http://www.freedesktop.org/software/${MY_PN}/dist/${MY_P}.tar.bz2" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64 ~arm ~hppa ~mips ~ppc ~ppc64 ~sh ~x86 ~x86-fbsd ~x86-freebsd ~amd64-linux ~ia64-linux ~x86-linux" +IUSE="acl debug doc kernel_linux pam policykit test" + +RDEPEND=">=dev-libs/dbus-glib-0.98 + >=dev-libs/glib-2.22 + sys-libs/zlib + x11-libs/libX11 + kernel_linux? ( acl? ( sys-apps/acl >=sys-fs/udev-182 ) ) + pam? ( virtual/pam ) + policykit? ( >=sys-auth/polkit-0.101-r1 ) + !<sys-fs/udev-182" +DEPEND="${RDEPEND} + dev-util/pkgconfig + dev-libs/libxslt + doc? ( app-text/xmlto ) + test? ( app-text/docbook-xml-dtd:4.1.2 )" + +S=${WORKDIR}/${MY_P} + +pkg_setup() { + # This is required to get login-session-id string with pam_ck_connector.so + if use pam && use kernel_linux; then + CONFIG_CHECK="~AUDITSYSCALL" + linux-info_pkg_setup + fi +} + +src_prepare() { + epatch \ + "${FILESDIR}"/${PN}-0.2.10-cleanup_console_tags.patch \ + "${FILESDIR}"/${PN}-0.4.0-polkit-automagic.patch \ + "${FILESDIR}"/${PN}-0.4.1-shutdown-reboot-without-policies.patch \ + "${FILESDIR}"/${PN}-0.4.5-udev-acl.patch \ + "${FILESDIR}"/${PN}-0.4.5-udev-acl-missing-AC_SUBST.patch \ + "${FILESDIR}"/${PN}-0.4.5-udev-acl-install_to_usr_and_missing_seat_d_symlink.patch + + eautoreconf +} + +src_configure() { + local myconf + use kernel_linux && myconf="$(use_enable acl udev-acl)" + + econf \ + XMLTO_FLAGS="--skip-validation" \ + --localstatedir="${EPREFIX}"/var \ + $(use_enable pam pam-module) \ + $(use_enable doc docbook-docs) \ + $(use_enable debug) \ + $(use_enable policykit polkit) \ + --with-dbus-services="${EPREFIX}"/usr/share/dbus-1/services \ + --with-pam-module-dir=$(getpam_mod_dir) \ + "$(systemd_with_unitdir)" \ + ${myconf} +} + +src_install() { + emake \ + DESTDIR="${D}" \ + htmldocdir="${EPREFIX}"/usr/share/doc/${PF}/html \ + install + + dodoc AUTHORS ChangeLog HACKING NEWS README TODO + + newinitd "${FILESDIR}"/${PN}-0.2.rc consolekit + + keepdir /usr/lib/ConsoleKit/run-seat.d + keepdir /usr/lib/ConsoleKit/run-session.d + keepdir /etc/ConsoleKit/run-session.d + keepdir /var/log/ConsoleKit + + exeinto /etc/X11/xinit/xinitrc.d + newexe "${FILESDIR}"/90-consolekit-3 90-consolekit + + exeinto /usr/lib/ConsoleKit/run-session.d + doexe "${FILESDIR}"/pam-foreground-compat.ck + + find "${ED}" -name '*.la' -exec rm -f {} + +} diff --git a/sys-auth/consolekit/files/consolekit-0.4.5-udev-acl-install_to_usr_and_missing_seat_d_symlink.patch b/sys-auth/consolekit/files/consolekit-0.4.5-udev-acl-install_to_usr_and_missing_seat_d_symlink.patch new file mode 100644 index 000000000000..785e4e688b89 --- /dev/null +++ b/sys-auth/consolekit/files/consolekit-0.4.5-udev-acl-install_to_usr_and_missing_seat_d_symlink.patch @@ -0,0 +1,26 @@ +This was mailed to mbiebl@debian.org and is pending review. + +--- tools/Makefile.am ++++ tools/Makefile.am +@@ -144,15 +144,19 @@ + $(NULL) + + if ENABLE_UDEV_ACL +-udevdir = $(UDEVDIR) + udevrulesdir = $(UDEVDIR)/rules.d + + dist_udevrules_DATA = 70-udev-acl.rules +-udev_PROGRAMS = udev-acl ++libexec_PROGRAMS = udev-acl + + udev_acl_SOURCES = udev-acl.c + udev_acl_LDADD = $(UDEV_ACL_LIBS) + udev_acl_CFLAGS = $(UDEV_ACL_CFLAGS) ++ ++install-exec-hook: ++ mkdir -p $(DESTDIR)$(prefix)/lib/ConsoleKit/run-seat.d ++ ln -sf $(libexecdir)/udev-acl $(DESTDIR)$(prefix)/lib/ConsoleKit/run-seat.d/udev-acl.ck ++ ln -sf $(libexecdir)/udev-acl $(DESTDIR)$(UDEVDIR)/udev-acl + endif + + EXTRA_DIST = \ diff --git a/sys-auth/consolekit/files/consolekit-0.4.5-udev-acl-missing-AC_SUBST.patch b/sys-auth/consolekit/files/consolekit-0.4.5-udev-acl-missing-AC_SUBST.patch new file mode 100644 index 000000000000..0e1135132064 --- /dev/null +++ b/sys-auth/consolekit/files/consolekit-0.4.5-udev-acl-missing-AC_SUBST.patch @@ -0,0 +1,12 @@ +This was accepted and committed to ~mbiebl/ConsoleKit/ repository. + +--- configure.ac ++++ configure.ac +@@ -249,6 +249,7 @@ + if test -z "$UDEVDIR" ; then + UDEVDIR="/lib/udev" + fi ++ AC_SUBST(UDEVDIR) + ]) + AM_CONDITIONAL([ENABLE_UDEV_ACL], [test "x$enable_udev_acl" = "xyes"]) + diff --git a/sys-auth/consolekit/files/consolekit-0.4.5-udev-acl.patch b/sys-auth/consolekit/files/consolekit-0.4.5-udev-acl.patch new file mode 100644 index 000000000000..8e6ed3fe40bb --- /dev/null +++ b/sys-auth/consolekit/files/consolekit-0.4.5-udev-acl.patch @@ -0,0 +1,596 @@ +From d491e4017d3a098b6a2a4fe5a73989c172dfa035 Mon Sep 17 00:00:00 2001 +From: Michael Biebl <biebl@debian.org> +Date: Mon, 19 Mar 2012 00:25:57 +0000 +Subject: Import udev-acl tool from udev + +The udev-acl tool has been removed from udev in version 182. +Add this tool to ConsoleKit for systems which don't use systemd-logind. +--- +diff --git a/configure.ac b/configure.ac +index 7394ed4..886c1ba 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -16,6 +16,7 @@ AC_GNU_SOURCE + + AC_ISC_POSIX + AC_PROG_CC ++AM_PROG_CC_C_O + AC_STDC_HEADERS + AC_DISABLE_STATIC + AC_PROG_LIBTOOL +@@ -233,6 +234,25 @@ if test "x$enable_pam_module" = "xyes"; then + fi + AM_CONDITIONAL(ENABLE_PAM_MODULE, test "x$enable_pam_module" = "xyes") + ++dnl ------------------------------------------------------------------------------ ++dnl udev-acl - apply ACLs for users with local forground sessions ++dnl ------------------------------------------------------------------------------ ++AC_ARG_ENABLE([udev-acl], ++ AS_HELP_STRING([--enable-udev-acl], [enable local user acl permissions support @<:@default=disabled@:>@]), ++ [], [enable_udev_acl=no]) ++AS_IF([test "x$enable_udev_acl" = "xyes"], [ ++ ++ PKG_CHECK_MODULES([UDEV_ACL], [glib-2.0 >= 2.22.0 gobject-2.0 >= 2.22.0 libudev]) ++ AC_CHECK_LIB([acl], [acl_init], [UDEV_ACL_LIBS="$UDEV_ACL_LIBS -lacl"], AC_MSG_ERROR([libacl not found])) ++ AC_CHECK_HEADER([acl/libacl.h], [:], AC_MSG_ERROR([libacl header not found])) ++ UDEVDIR=`$PKG_CONFIG --variable udevdir udev` ++ if test -z "$UDEVDIR" ; then ++ UDEVDIR="/lib/udev" ++ fi ++]) ++AM_CONDITIONAL([ENABLE_UDEV_ACL], [test "x$enable_udev_acl" = "xyes"]) ++ ++ + dnl --------------------------------------------------------------------------- + dnl - Install directory for PAM security module + dnl --------------------------------------------------------------------------- +@@ -445,6 +465,7 @@ echo " + Build backend: ${CK_BACKEND} + PAM module dir: ${PAM_MODULE_DIR} + Build PAM module: ${msg_pam_module} ++ Build udev-acl: ${enable_udev_acl} + Build docs: ${enable_docbook_docs} + + PolicyKit support ${have_polkit} +diff --git a/tools/70-udev-acl.rules b/tools/70-udev-acl.rules +new file mode 100644 +index 0000000..2dac283 +--- a/dev/null ++++ b/tools/70-udev-acl.rules +@@ -0,0 +1,76 @@ ++# do not edit this file, it will be overwritten on update ++ ++# Do not use TAG+="udev-acl" outside of this file. This variable is private to ++# udev-acl of this udev release and may be replaced at any time. ++ ++ENV{MAJOR}=="", GOTO="acl_end" ++ACTION=="remove", GOTO="acl_apply" ++ ++# systemd replaces udev-acl entirely, skip if active ++TEST=="/sys/fs/cgroup/systemd", TAG=="uaccess", GOTO="acl_end" ++ ++# PTP/MTP protocol devices, cameras, portable media players ++SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:060101:*", TAG+="udev-acl" ++ ++# digicams with proprietary protocol ++ENV{ID_GPHOTO2}=="*?", TAG+="udev-acl" ++ ++# SCSI and USB scanners ++ENV{libsane_matched}=="yes", TAG+="udev-acl" ++ ++# HPLIP devices (necessary for ink level check and HP tool maintenance) ++ENV{ID_HPLIP}=="1", TAG+="udev-acl" ++ ++# optical drives ++SUBSYSTEM=="block", ENV{ID_CDROM}=="1", TAG+="udev-acl" ++SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", TAG+="udev-acl" ++ ++# sound devices ++SUBSYSTEM=="sound", TAG+="udev-acl" ++ ++# ffado is an userspace driver for firewire sound cards ++SUBSYSTEM=="firewire", ENV{ID_FFADO}=="1", TAG+="udev-acl" ++ ++# webcams, frame grabber, TV cards ++SUBSYSTEM=="video4linux", TAG+="udev-acl" ++SUBSYSTEM=="dvb", TAG+="udev-acl" ++ ++# IIDC devices: industrial cameras and some webcams ++SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x00010*", TAG+="udev-acl" ++SUBSYSTEM=="firewire", ATTR{units}=="*0x00b09d:0x00010*", TAG+="udev-acl" ++# AV/C devices: camcorders, set-top boxes, TV sets, audio devices, and more ++SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", TAG+="udev-acl" ++SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", TAG+="udev-acl" ++ ++# DRI video devices ++SUBSYSTEM=="drm", KERNEL=="card*", TAG+="udev-acl" ++ ++# KVM ++SUBSYSTEM=="misc", KERNEL=="kvm", TAG+="udev-acl" ++ ++# smart-card readers ++ENV{ID_SMARTCARD_READER}=="*?", TAG+="udev-acl" ++ ++# PDA devices ++ENV{ID_PDA}=="*?", TAG+="udev-acl" ++ ++# Programmable remote control ++ENV{ID_REMOTE_CONTROL}=="1", TAG+="udev-acl" ++ ++# joysticks ++SUBSYSTEM=="input", ENV{ID_INPUT_JOYSTICK}=="?*", TAG+="udev-acl" ++ ++# color measurement devices ++ENV{COLOR_MEASUREMENT_DEVICE}=="*?", TAG+="udev-acl" ++ ++# DDC/CI device, usually high-end monitors such as the DreamColor ++ENV{DDC_DEVICE}=="*?", TAG+="udev-acl" ++ ++# media player raw devices (for user-mode drivers, Android SDK, etc.) ++SUBSYSTEM=="usb", ENV{ID_MEDIA_PLAYER}=="?*", TAG+="udev-acl" ++ ++# apply ACL for all locally logged in users ++LABEL="acl_apply", TAG=="udev-acl", TEST=="/var/run/ConsoleKit/database", \ ++ RUN+="udev-acl --action=$env{ACTION} --device=$env{DEVNAME}" ++ ++LABEL="acl_end" +diff --git a/tools/Makefile.am b/tools/Makefile.am +index 13c191f..03ba5b7 100644 +--- a/tools/Makefile.am ++++ b/tools/Makefile.am +@@ -143,6 +143,17 @@ ck_get_x11_display_device_LDADD = \ + $(top_builddir)/src/libck.la \ + $(NULL) + ++if ENABLE_UDEV_ACL ++udevdir = $(UDEVDIR) ++udevrulesdir = $(UDEVDIR)/rules.d ++ ++dist_udevrules_DATA = 70-udev-acl.rules ++udev_PROGRAMS = udev-acl ++ ++udev_acl_SOURCES = udev-acl.c ++udev_acl_LDADD = $(UDEV_ACL_LIBS) ++udev_acl_CFLAGS = $(UDEV_ACL_CFLAGS) ++endif + + EXTRA_DIST = \ + $(NULL) +diff --git a/tools/udev-acl.c b/tools/udev-acl.c +new file mode 100644 +index 0000000..628cfbe +--- a/dev/null ++++ b/tools/udev-acl.c +@@ -0,0 +1,430 @@ ++/* ++ * Copyright (C) 2009 Kay Sievers <kay.sievers@vrfy.org> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details: ++ */ ++ ++#include <acl/libacl.h> ++#include <sys/stat.h> ++#include <errno.h> ++#include <getopt.h> ++#include <glib.h> ++#include <inttypes.h> ++#include <libudev.h> ++#include <stdbool.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <unistd.h> ++ ++static int debug; ++ ++enum{ ++ ACTION_NONE = 0, ++ ACTION_REMOVE, ++ ACTION_ADD, ++ ACTION_CHANGE ++}; ++ ++static int set_facl(const char* filename, uid_t uid, int add) ++{ ++ int get; ++ acl_t acl; ++ acl_entry_t entry = NULL; ++ acl_entry_t e; ++ acl_permset_t permset; ++ int ret; ++ ++ /* don't touch ACLs for root */ ++ if (uid == 0) ++ return 0; ++ ++ /* read current record */ ++ acl = acl_get_file(filename, ACL_TYPE_ACCESS); ++ if (!acl) ++ return -1; ++ ++ /* locate ACL_USER entry for uid */ ++ get = acl_get_entry(acl, ACL_FIRST_ENTRY, &e); ++ while (get == 1) { ++ acl_tag_t t; ++ ++ acl_get_tag_type(e, &t); ++ if (t == ACL_USER) { ++ uid_t *u; ++ ++ u = (uid_t*)acl_get_qualifier(e); ++ if (u == NULL) { ++ ret = -1; ++ goto out; ++ } ++ if (*u == uid) { ++ entry = e; ++ acl_free(u); ++ break; ++ } ++ acl_free(u); ++ } ++ ++ get = acl_get_entry(acl, ACL_NEXT_ENTRY, &e); ++ } ++ ++ /* remove ACL_USER entry for uid */ ++ if (!add) { ++ if (entry == NULL) { ++ ret = 0; ++ goto out; ++ } ++ acl_delete_entry(acl, entry); ++ goto update; ++ } ++ ++ /* create ACL_USER entry for uid */ ++ if (entry == NULL) { ++ ret = acl_create_entry(&acl, &entry); ++ if (ret != 0) ++ goto out; ++ acl_set_tag_type(entry, ACL_USER); ++ acl_set_qualifier(entry, &uid); ++ } ++ ++ /* add permissions for uid */ ++ acl_get_permset(entry, &permset); ++ acl_add_perm(permset, ACL_READ|ACL_WRITE); ++update: ++ /* update record */ ++ if (debug) ++ printf("%c%u %s\n", add ? '+' : '-', uid, filename); ++ acl_calc_mask(&acl); ++ ret = acl_set_file(filename, ACL_TYPE_ACCESS, acl); ++ if (ret != 0) ++ goto out; ++out: ++ acl_free(acl); ++ return ret; ++} ++ ++/* check if a given uid is listed */ ++static int uid_in_list(GSList *list, uid_t uid) ++{ ++ GSList *l; ++ ++ for (l = list; l != NULL; l = g_slist_next(l)) ++ if (uid == GPOINTER_TO_UINT(l->data)) ++ return 1; ++ return 0; ++} ++ ++/* return list of current uids of local active sessions */ ++static GSList *uids_with_local_active_session(const char *own_id) ++{ ++ GSList *list = NULL; ++ GKeyFile *keyfile; ++ ++ keyfile = g_key_file_new(); ++ if (g_key_file_load_from_file(keyfile, "/var/run/ConsoleKit/database", 0, NULL)) { ++ gchar **groups; ++ ++ groups = g_key_file_get_groups(keyfile, NULL); ++ if (groups != NULL) { ++ int i; ++ ++ for (i = 0; groups[i] != NULL; i++) { ++ uid_t u; ++ ++ if (!g_str_has_prefix(groups[i], "Session ")) ++ continue; ++ if (own_id != NULL &&g_str_has_suffix(groups[i], own_id)) ++ continue; ++ if (!g_key_file_get_boolean(keyfile, groups[i], "is_local", NULL)) ++ continue; ++ if (!g_key_file_get_boolean(keyfile, groups[i], "is_active", NULL)) ++ continue; ++ u = g_key_file_get_integer(keyfile, groups[i], "uid", NULL); ++ if (u > 0 && !uid_in_list(list, u)) ++ list = g_slist_prepend(list, GUINT_TO_POINTER(u)); ++ } ++ g_strfreev(groups); ++ } ++ } ++ g_key_file_free(keyfile); ++ ++ return list; ++} ++ ++/* ConsoleKit calls us with special variables */ ++static int consolekit_called(const char *ck_action, uid_t *uid, uid_t *uid2, const char **remove_session_id, int *action) ++{ ++ int a = ACTION_NONE; ++ uid_t u = 0; ++ uid_t u2 = 0; ++ const char *s; ++ const char *s2; ++ const char *old_session = NULL; ++ ++ if (ck_action == NULL || strcmp(ck_action, "seat_active_session_changed") != 0) ++ return -1; ++ ++ /* We can have one of: remove, add, change, no-change */ ++ s = getenv("CK_SEAT_OLD_SESSION_ID"); ++ s2 = getenv("CK_SEAT_SESSION_ID"); ++ if (s == NULL && s2 == NULL) { ++ return -1; ++ } else if (s2 == NULL) { ++ a = ACTION_REMOVE; ++ } else if (s == NULL) { ++ a = ACTION_ADD; ++ } else { ++ a = ACTION_CHANGE; ++ } ++ ++ switch (a) { ++ case ACTION_ADD: ++ s = getenv("CK_SEAT_SESSION_USER_UID"); ++ if (s == NULL) ++ return -1; ++ u = strtoul(s, NULL, 10); ++ ++ s = getenv("CK_SEAT_SESSION_IS_LOCAL"); ++ if (s == NULL) ++ return -1; ++ if (strcmp(s, "true") != 0) ++ return 0; ++ ++ break; ++ case ACTION_REMOVE: ++ s = getenv("CK_SEAT_OLD_SESSION_USER_UID"); ++ if (s == NULL) ++ return -1; ++ u = strtoul(s, NULL, 10); ++ ++ s = getenv("CK_SEAT_OLD_SESSION_IS_LOCAL"); ++ if (s == NULL) ++ return -1; ++ if (strcmp(s, "true") != 0) ++ return 0; ++ ++ old_session = getenv("CK_SEAT_OLD_SESSION_ID"); ++ if (old_session == NULL) ++ return -1; ++ ++ break; ++ case ACTION_CHANGE: ++ s = getenv("CK_SEAT_OLD_SESSION_USER_UID"); ++ if (s == NULL) ++ return -1; ++ u = strtoul(s, NULL, 10); ++ s = getenv("CK_SEAT_SESSION_USER_UID"); ++ if (s == NULL) ++ return -1; ++ u2 = strtoul(s, NULL, 10); ++ ++ s = getenv("CK_SEAT_OLD_SESSION_IS_LOCAL"); ++ s2 = getenv("CK_SEAT_SESSION_IS_LOCAL"); ++ if (s == NULL || s2 == NULL) ++ return -1; ++ /* don't process non-local session changes */ ++ if (strcmp(s, "true") != 0 && strcmp(s2, "true") != 0) ++ return 0; ++ ++ if (strcmp(s, "true") == 0 && strcmp(s, "true") == 0) { ++ /* process the change */ ++ if (u == u2) { ++ /* special case: we noop if we are ++ * changing between local sessions for ++ * the same uid */ ++ a = ACTION_NONE; ++ } ++ old_session = getenv("CK_SEAT_OLD_SESSION_ID"); ++ if (old_session == NULL) ++ return -1; ++ } else if (strcmp(s, "true") == 0) { ++ /* only process the removal */ ++ a = ACTION_REMOVE; ++ old_session = getenv("CK_SEAT_OLD_SESSION_ID"); ++ if (old_session == NULL) ++ return -1; ++ } else if (strcmp(s2, "true") == 0) { ++ /* only process the addition */ ++ a = ACTION_ADD; ++ u = u2; ++ } ++ break; ++ } ++ ++ *remove_session_id = old_session; ++ *uid = u; ++ *uid2 = u2; ++ *action = a; ++ return 0; ++} ++ ++/* add or remove a ACL for a given uid from all matching devices */ ++static void apply_acl_to_devices(uid_t uid, int add) ++{ ++ struct udev *udev; ++ struct udev_enumerate *enumerate; ++ struct udev_list_entry *list_entry; ++ ++ /* iterate over all devices tagged with ACL_SET */ ++ udev = udev_new(); ++ enumerate = udev_enumerate_new(udev); ++ udev_enumerate_add_match_tag(enumerate, "udev-acl"); ++ udev_enumerate_scan_devices(enumerate); ++ udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) { ++ struct udev_device *device; ++ const char *node; ++ ++ device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate), ++ udev_list_entry_get_name(list_entry)); ++ if (device == NULL) ++ continue; ++ node = udev_device_get_devnode(device); ++ if (node == NULL) { ++ udev_device_unref(device); ++ continue; ++ } ++ set_facl(node, uid, add); ++ udev_device_unref(device); ++ } ++ udev_enumerate_unref(enumerate); ++ udev_unref(udev); ++} ++ ++static void ++remove_uid (uid_t uid, const char *remove_session_id) ++{ ++ /* ++ * Remove ACL for given uid from all matching devices ++ * when there is currently no local active session. ++ */ ++ GSList *list; ++ ++ list = uids_with_local_active_session(remove_session_id); ++ if (!uid_in_list(list, uid)) ++ apply_acl_to_devices(uid, 0); ++ g_slist_free(list); ++} ++ ++int main (int argc, char* argv[]) ++{ ++ static const struct option options[] = { ++ { "action", required_argument, NULL, 'a' }, ++ { "device", required_argument, NULL, 'D' }, ++ { "user", required_argument, NULL, 'u' }, ++ { "debug", no_argument, NULL, 'd' }, ++ { "help", no_argument, NULL, 'h' }, ++ {} ++ }; ++ int action = -1; ++ const char *device = NULL; ++ bool uid_given = false; ++ uid_t uid = 0; ++ uid_t uid2 = 0; ++ const char* remove_session_id = NULL; ++ int rc = 0; ++ ++ /* valgrind is more important to us than a slice allocator */ ++ g_slice_set_config (G_SLICE_CONFIG_ALWAYS_MALLOC, 1); ++ ++ while (1) { ++ int option; ++ ++ option = getopt_long(argc, argv, "+a:D:u:dh", options, NULL); ++ if (option == -1) ++ break; ++ ++ switch (option) { ++ case 'a': ++ if (strcmp(optarg, "remove") == 0) ++ action = ACTION_REMOVE; ++ else ++ action = ACTION_ADD; ++ break; ++ case 'D': ++ device = optarg; ++ break; ++ case 'u': ++ uid_given = true; ++ uid = strtoul(optarg, NULL, 10); ++ break; ++ case 'd': ++ debug = 1; ++ break; ++ case 'h': ++ printf("Usage: udev-acl --action=ACTION [--device=DEVICEFILE] [--user=UID]\n\n"); ++ goto out; ++ } ++ } ++ ++ if (action < 0 && device == NULL && !uid_given) ++ if (!consolekit_called(argv[optind], &uid, &uid2, &remove_session_id, &action)) ++ uid_given = true; ++ ++ if (action < 0) { ++ fprintf(stderr, "missing action\n\n"); ++ rc = 2; ++ goto out; ++ } ++ ++ if (device != NULL && uid_given) { ++ fprintf(stderr, "only one option, --device=DEVICEFILE or --user=UID expected\n\n"); ++ rc = 3; ++ goto out; ++ } ++ ++ if (uid_given) { ++ switch (action) { ++ case ACTION_ADD: ++ /* Add ACL for given uid to all matching devices. */ ++ apply_acl_to_devices(uid, 1); ++ break; ++ case ACTION_REMOVE: ++ remove_uid(uid, remove_session_id); ++ break; ++ case ACTION_CHANGE: ++ remove_uid(uid, remove_session_id); ++ apply_acl_to_devices(uid2, 1); ++ break; ++ case ACTION_NONE: ++ goto out; ++ break; ++ default: ++ g_assert_not_reached(); ++ break; ++ } ++ } else if (device != NULL) { ++ /* ++ * Add ACLs for all current session uids to a given device. ++ * ++ * Or remove ACLs for uids which do not have any current local ++ * active session. Remove is not really interesting, because in ++ * most cases the device node is removed anyway. ++ */ ++ GSList *list; ++ GSList *l; ++ ++ list = uids_with_local_active_session(NULL); ++ for (l = list; l != NULL; l = g_slist_next(l)) { ++ uid_t u; ++ ++ u = GPOINTER_TO_UINT(l->data); ++ if (action == ACTION_ADD || !uid_in_list(list, u)) ++ set_facl(device, u, action == ACTION_ADD); ++ } ++ g_slist_free(list); ++ } else { ++ fprintf(stderr, "--device=DEVICEFILE or --user=UID expected\n\n"); ++ rc = 3; ++ } ++out: ++ return rc; ++} +-- +cgit v0.9.0.2-2-gbebe |