Hello community,
here is the log from the commit of package hal-resmgr
checked in at Thu Sep 7 01:16:43 CEST 2006.
--------
--- hal-resmgr/hal-resmgr.changes 2006-08-23 10:29:17.000000000 +0200
+++ hal-resmgr/hal-resmgr.changes 2006-09-06 12:10:59.000000000 +0200
@@ -1,0 +2,12 @@
+Wed Sep 6 12:09:43 CEST 2006 - lnussel@suse.de
+
+- install file system ACLs directly instead of passing device names
+ to resmgr
+- install Grant and Revoke methods in HAL
+
+-------------------------------------------------------------------
+Mon Sep 4 16:13:12 CEST 2006 - dgollub@suse.de
+
+- added match rule for palm devices (pda.platform) in resmgr.fdi
+
+-------------------------------------------------------------------
Old:
----
hal-resmgr-0.1_SVNr92.tar.bz2
New:
----
hal-resmgr-0.1_SVNr109.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ hal-resmgr.spec ++++++
--- /var/tmp/diff_new_pack.7dmJfN/_old 2006-09-07 01:15:57.000000000 +0200
+++ /var/tmp/diff_new_pack.7dmJfN/_new 2006-09-07 01:15:57.000000000 +0200
@@ -1,5 +1,5 @@
#
-# spec file for package hal-resmgr (Version 0.1_SVNr92)
+# spec file for package hal-resmgr (Version 0.1_SVNr109)
#
# Copyright (c) 2006 SUSE LINUX Products GmbH, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
@@ -11,10 +11,10 @@
# norootforbuild
Name: hal-resmgr
-BuildRequires: hal-devel resmgr
+BuildRequires: hal-devel libacl-devel resmgr
License: GPL, Other License(s), see package
Group: System/Daemons
-Version: 0.1_SVNr92
+Version: 0.1_SVNr109
Release: 1
Summary: Automatically Register HAL Devices with resmgr
Source: %{name}-%{version}.tar.bz2
@@ -22,6 +22,7 @@
BuildRoot: %{_tmppath}/%{name}-%{version}-build
PreReq: %insserv_prereq %fillup_prereq
Provides: resmgr:/etc/hotplug/usb/desktopdev
+Requires: resmgr
%description
hal-resmgr hooks into hald and dynamically registers devices with
@@ -51,11 +52,20 @@
%defattr(-,root,root)
%doc README
/etc/hal
+/etc/resmgr.conf.d/91-hal-resmgr.conf
/usr/sbin/*
/usr/share/hal
%{_libdir}/hal/hal-resmgr
+%{_libdir}/hal/scripts/hal-resmgr-grant
+%{_libdir}/hal/scripts/hal-resmgr-revoke
%changelog -n hal-resmgr
+* Wed Sep 06 2006 - lnussel@suse.de
+- install file system ACLs directly instead of passing device names
+ to resmgr
+- install Grant and Revoke methods in HAL
+* Mon Sep 04 2006 - dgollub@suse.de
+- added match rule for palm devices (pda.platform) in resmgr.fdi
* Wed Aug 23 2006 - lnussel@suse.de
- install hal-resmgr symlink in hal libdir so newer hal find it
(#201055)
++++++ hal-resmgr-0.1_SVNr92.tar.bz2 -> hal-resmgr-0.1_SVNr109.tar.bz2 ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/hal-resmgr-0.1_SVNr92/Makefile new/hal-resmgr-0.1_SVNr109/Makefile
--- old/hal-resmgr-0.1_SVNr92/Makefile 2006-08-23 10:27:40.000000000 +0200
+++ new/hal-resmgr-0.1_SVNr109/Makefile 2006-09-06 12:02:30.000000000 +0200
@@ -11,8 +11,8 @@
all: hal-resmgr
-hal-resmgr: hal-resmgr.o mainloop.o debug.o mainloop-dbus.o
- $(CC) -o $@ $^ -Wl,--as-needed $(DBUS_LIBS) $(HAL_LIBS) -lresmgr
+hal-resmgr: hal-resmgr.o mainloop.o debug.o mainloop-dbus.o facl.o file.o
+ $(CC) -o $@ $^ -Wl,--as-needed $(DBUS_LIBS) $(HAL_LIBS) -lresmgr -lacl
.c.o:
$(CC) $(CFLAGS) $(DBUS_CFLAGS) $(HAL_CFLAGS) -o $@ -c $<
@@ -20,11 +20,15 @@
install: hal-resmgr
install -d -m 755 $(DESTDIR)$(sbindir)
install -d -m 755 $(DESTDIR)$(fdidir) $(DESTDIR)$(fdidir2)
- install -d -m 755 $(DESTDIR)$(hal_libdir)
+ install -d -m 755 $(DESTDIR)$(hal_libdir)/scripts
+ install -d -m 755 $(DESTDIR)/etc/resmgr.conf.d
install -m 755 hal-resmgr $(DESTDIR)$(sbindir)
- ln -s $(sbindir)/hal-resmgr $(DESTDIR)$(hal_libdir)/hal-resmgr
+ ln -sf $(sbindir)/hal-resmgr $(DESTDIR)$(hal_libdir)/hal-resmgr
+ install -m 755 hal-resmgr-grant $(DESTDIR)$(hal_libdir)/scripts
+ install -m 755 hal-resmgr-revoke $(DESTDIR)$(hal_libdir)/scripts
install -m 644 resmgr.fdi $(DESTDIR)$(fdidir)/80-resmgr.fdi
install -m 644 resmgr-callouts.fdi $(DESTDIR)$(fdidir2)/80-resmgr.fdi
+ install -m 644 resmgr.conf $(DESTDIR)/etc/resmgr.conf.d/91-hal-resmgr.conf
clean:
rm -f *.o hal-resmgr tags
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/hal-resmgr-0.1_SVNr92/facl.c new/hal-resmgr-0.1_SVNr109/facl.c
--- old/hal-resmgr-0.1_SVNr92/facl.c 1970-01-01 01:00:00.000000000 +0100
+++ new/hal-resmgr-0.1_SVNr109/facl.c 2006-09-05 14:20:29.000000000 +0200
@@ -0,0 +1,223 @@
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef TEST
+#include
+#endif
+
+#include "debug.h"
+#include "facl.h"
+
+static int preverrno;
+static unsigned errcount;
+
+#define ERROR(x) do { \
+ if(errno != preverrno || errcount++ < 3) { \
+ if (errno != preverrno) { preverrno = errno; errcount = 1; } \
+ warning("%s() - ACL error on %s, %s: %s\n", \
+ __FUNCTION__, fn, x, strerror(errno)); \
+ } \
+ } while(0)
+
+static acl_entry_t find_entry_for(const char* fn, acl_t acl, uid_t uid)
+{
+ int ret;
+ acl_entry_t entry;
+
+ ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
+ while(ret == 1)
+ {
+ acl_tag_t t;
+ ret = acl_get_tag_type(entry, &t);
+ if(ret == -1) { ERROR("acl_get_tag_type"); goto error; }
+
+ if(t == ACL_USER)
+ {
+ uid_t* u;
+ u = (uid_t*)acl_get_qualifier(entry);
+ if(!u) { ERROR("acl_get_qualifier"); goto error; }
+
+ if(*u == uid)
+ {
+ acl_free(u);
+ return entry;
+ }
+ acl_free(u);
+ }
+
+ ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
+ }
+error:
+ return NULL;
+}
+
+static int set_perms(const char* fn, acl_t* aclp, acl_entry_t entry, uid_t uid, unsigned perms)
+{
+ int ret;
+ acl_permset_t permset;
+
+ if(!entry)
+ {
+ ret = acl_create_entry(aclp, &entry );
+ if(ret == -1) { ERROR("acl_create_entry"); goto error; }
+
+ ret = acl_set_tag_type(entry, ACL_USER);
+ if(ret == -1) { ERROR("acl_set_tag_type"); goto error; }
+
+ ret = acl_set_qualifier(entry, &uid);
+ if(ret == -1) { ERROR("acl_set_qualifier"); goto error; }
+ }
+
+ ret = acl_get_permset(entry, &permset);
+ if(ret == -1) { ERROR("acl_get_permset"); goto error; }
+
+ ret = acl_clear_perms(permset);
+ if(ret == -1) { ERROR("acl_clear_perms"); goto error; }
+
+ ret = acl_add_perm(permset, perms);
+ if(ret == -1) { ERROR("acl_add_perm"); goto error; }
+
+ ret = 0;
+
+error:
+ return ret;
+}
+
+static inline void print_acl(acl_t acl)
+{
+#ifdef TEST
+ char* txt;
+ txt = acl_to_text(acl, NULL);
+ puts(txt);
+ acl_free(txt);
+#endif
+}
+
+/** add or remove an acl
+ @param fn file to modify
+ @param uid affected user
+ @perms ACL_READ or ACL_READ|ACL_WRITE to add an acl, 0 to remove it
+ @return 0 on success
+ */
+static int set_facl(const char* fn, uid_t uid, unsigned perms)
+{
+ struct stat stb;
+ int ret = -1;
+ acl_t acl;
+ acl_entry_t entry;
+
+ if(stat(fn, &stb) == -1)
+ {
+ // don't complain if we are supposed to remove ACLs but the
+ // file doesn't exist
+ if(perms) ERROR("stat");
+ goto error;
+ }
+
+ acl = acl_get_file(fn, ACL_TYPE_ACCESS);
+ if(!acl) { ERROR("acl_get_file"); goto error; }
+
+ /* create entry, reuse existing one if possible */
+ entry = find_entry_for(fn, acl, uid);
+
+ if(perms)
+ {
+ if(set_perms(fn, &acl, entry, uid, perms) != 0)
+ goto error;
+ }
+ else
+ {
+ if(!entry)
+ goto out;
+
+ ret = acl_delete_entry(acl, entry);
+ if(ret == -1) { ERROR("acl_delete_entry"); goto error; }
+ }
+
+ ret = acl_calc_mask(&acl);
+ if(ret == -1) { ERROR("acl_calc_mask"); goto error; }
+
+ print_acl(acl);
+
+ ret = acl_valid(acl);
+ if(ret == -1) { ERROR("acl_valid"); goto error; }
+
+ ret = acl_set_file(fn, ACL_TYPE_ACCESS, acl);
+ if(ret == -1) { ERROR("acl_set_file"); goto error; }
+
+out:
+ ret = 0;
+error:
+ acl_free(acl);
+ return ret;
+}
+
+/** remove any acls from the file */
+int facl_clear(const char* fn)
+{
+ struct stat stb;
+ acl_t acl = NULL;
+ int ret = -1;
+
+ // no file? no need to clear
+ if(stat(fn, &stb) == -1)
+ return -1;
+
+ // this will remove any acls from the file
+ acl = acl_from_mode(stb.st_mode&0777);
+ if(!acl) { ERROR("acl_from_mode"); goto error; }
+
+ print_acl(acl);
+
+ ret = acl_set_file(fn, ACL_TYPE_ACCESS, acl);
+ if(ret == -1) { ERROR("acl_set_file"); goto error; }
+
+error:
+ acl_free(acl);
+ return ret;
+}
+
+/** grant read access */
+int add_facl_r(const char* fn, uid_t uid)
+{
+ return set_facl(fn, uid, ACL_READ);
+}
+
+/** grant read and write access */
+int add_facl_rw(const char* fn, uid_t uid)
+{
+ return set_facl(fn, uid, ACL_READ|ACL_WRITE);
+}
+
+/** remove access */
+int remove_facl(const char* fn, uid_t uid)
+{
+ return set_facl(fn, uid, 0);
+}
+
+#ifdef TEST
+int main (int argc, char* argv[])
+{
+ int mainret = 0;
+ const char* fn = argv[0];
+ uid_t uid = 0;
+
+ if(add_facl_r(fn, uid) != 0)
+ mainret = 1;
+
+ if(!mainret && add_facl_rw(fn, uid) != 0)
+ mainret = 1;
+
+ if(!mainret && remove_facl(fn, uid) != 0)
+ mainret = 1;
+
+ if(!mainret && facl_clear(fn) != 0)
+ mainret = 1;
+
+ return mainret;
+}
+#endif
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/hal-resmgr-0.1_SVNr92/facl.h new/hal-resmgr-0.1_SVNr109/facl.h
--- old/hal-resmgr-0.1_SVNr92/facl.h 1970-01-01 01:00:00.000000000 +0100
+++ new/hal-resmgr-0.1_SVNr109/facl.h 2006-09-05 14:20:29.000000000 +0200
@@ -0,0 +1,18 @@
+#ifndef RESMGR_FACL_H
+#define RESMGR_FACL_H
+
+#include
+
+/** remove any acls from the file */
+int facl_clear(const char* fn);
+
+/** grant read access */
+extern int add_facl_r(const char* fn, uid_t uid);
+
+/** grant read and write access */
+extern int add_facl_rw(const char* fn, uid_t uid);
+
+/** remove access */
+extern int remove_facl(const char* fn, uid_t uid);
+
+#endif
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/hal-resmgr-0.1_SVNr92/file.c new/hal-resmgr-0.1_SVNr109/file.c
--- old/hal-resmgr-0.1_SVNr92/file.c 1970-01-01 01:00:00.000000000 +0100
+++ new/hal-resmgr-0.1_SVNr109/file.c 2006-09-05 14:20:29.000000000 +0200
@@ -0,0 +1,158 @@
+/*
+ * Device file resource family
+ *
+ * Copyright (C) 2002, Olaf Kirch
+ * Copyright (C) 2005, Ludwig Nussel
+ */
+
+#define _GNU_SOURCE /* O_NOFOLLOW */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "file.h"
+#include "facl.h"
+#include "debug.h"
+
+res_file_t* res_file_new(const char* name, const char* flags)
+{
+ res_file_t* dev;
+
+ dev = calloc(1, sizeof(res_file_t)+strlen(name)+1);
+ strcpy(dev->name, name);
+ // TODO: parse flags
+
+ return dev;
+}
+
+void res_file_free(res_file_t* dev)
+{
+ free(dev);
+}
+
+int
+res_file_grant(res_file_t *dev, uid_t uid)
+{
+ int ret = -1;
+
+ if(dev->flags & DEV_FLAGS_NOFACL || 0 == uid)
+ return 0;
+
+ debug(1, "grant uid %d on %s", uid, dev->name);
+
+ if(dev->flags & DEV_FLAGS_NEW)
+ {
+ facl_clear(dev->name);
+ }
+ else if(dev->flags & DEV_FLAGS_OWNER)
+ {
+ warning("acl support missing on %s, cannot grant uid %d additional access\n",
+ dev->name, uid);
+ return -1;
+ }
+
+ if(dev->flags & DEV_FLAGS_RO)
+ ret = add_facl_r(dev->name, uid);
+ else
+ ret = add_facl_rw(dev->name, uid);
+
+ debug(1, "%s %x %d\n", dev->name, dev->flags, ret);
+
+ if(dev->flags & DEV_FLAGS_NEW)
+ {
+ if(ret != 0) // no ACL support?
+ {
+ int fd = -1;
+ struct stat stb;
+ /* RO doesn't work as the user could just
+ * chmod if he is owner of the device */
+ if(dev->flags & DEV_FLAGS_RO)
+ {
+ warning("can't grant read-only access via chown method on %s\n",
+ dev->name);
+ ret = -1;
+ }
+ else if((fd = open(dev->name, O_RDONLY|O_NONBLOCK|O_NOFOLLOW)) == -1
+ || fstat(fd, &stb) == -1
+ || fchown(fd, uid, -1) == -1
+ || fchmod(fd, (stb.st_mode&0777)|0600) == -1)
+ {
+ if(fd != -1)
+ close(fd);
+ warning("failed to change owner of %s to uid %d: %s\n",
+ dev->name, uid, strerror(errno));
+ ret = -1;
+ }
+ else
+ {
+ close(fd);
+ dev->saved_uid = stb.st_uid;
+ dev->saved_gid = stb.st_gid;
+ dev->saved_mode = stb.st_mode&0777;
+ dev->flags |= DEV_FLAGS_OWNER;
+ ret = 0;
+
+ debug(1, "used chown %d instead of ACL on %s\n", uid, dev->name);
+ }
+ }
+ }
+
+ return ret;
+}
+
+int
+res_file_revoke(res_file_t *dev, uid_t uid)
+{
+ if(dev->flags & DEV_FLAGS_NOFACL || 0 == uid)
+ return 0;
+
+ debug(1, "revoke uid %d on %s", uid, dev->name);
+
+ if(dev->flags & DEV_FLAGS_OWNER)
+ {
+ int fd = -1;
+ errno = 0;
+ if((fd = open(dev->name, O_RDONLY|O_NONBLOCK|O_NOFOLLOW)) == -1
+ || fchown(fd, dev->saved_uid, dev->saved_gid) == -1
+ || fchmod(fd, dev->saved_mode) == -1)
+ {
+ if(fd != -1)
+ close(fd);
+
+ if(errno != ENOENT)
+ warning("failed to change owner of %s to uid %d: %s\n",
+ dev->name, 0, strerror(errno));
+ return -1;
+ }
+ else
+ {
+ close(fd);
+ dev->flags ^= DEV_FLAGS_OWNER;
+ dev->flags |= DEV_FLAGS_NEW;
+ return 0;
+ }
+ }
+ else
+ {
+ return remove_facl(dev->name, uid);
+ }
+}
+
+int
+res_file_create(res_file_t *dev)
+{
+ dev->flags |= DEV_FLAGS_NEW;
+ return 0;
+}
+
+int
+res_file_destroy(res_file_t *dev)
+{
+ if(!(dev->flags & DEV_FLAGS_NOACCES)
+ && !(dev->flags & DEV_FLAGS_NOFACL))
+ facl_clear(dev->name);
+ return 0;
+}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/hal-resmgr-0.1_SVNr92/file.h new/hal-resmgr-0.1_SVNr109/file.h
--- old/hal-resmgr-0.1_SVNr92/file.h 1970-01-01 01:00:00.000000000 +0100
+++ new/hal-resmgr-0.1_SVNr109/file.h 2006-09-05 14:20:29.000000000 +0200
@@ -0,0 +1,28 @@
+#ifndef RESMGR_FILE_H
+#define RESMGR_FILE_H
+
+typedef struct {
+ uid_t saved_uid;
+ gid_t saved_gid;
+ unsigned short saved_mode;
+ unsigned short flags;
+ char name[];
+} res_file_t;
+
+enum {
+ DEV_FLAGS_RO = 0x01,
+ DEV_FLAGS_NOFACL = 0x02,
+ // private
+ DEV_FLAGS_NOACCES = 0x20,
+ DEV_FLAGS_NEW = 0x40,
+ DEV_FLAGS_OWNER = 0x80,
+};
+
+res_file_t* res_file_new(const char* name, const char* flags);
+void res_file_free(res_file_t* dev);
+int res_file_grant(res_file_t *dev, uid_t uid);
+int res_file_revoke(res_file_t *dev, uid_t uid);
+int res_file_create(res_file_t *dev);
+int res_file_destroy(res_file_t *dev);
+
+#endif
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/hal-resmgr-0.1_SVNr92/hal-resmgr-grant new/hal-resmgr-0.1_SVNr109/hal-resmgr-grant
--- old/hal-resmgr-0.1_SVNr92/hal-resmgr-grant 1970-01-01 01:00:00.000000000 +0100
+++ new/hal-resmgr-0.1_SVNr109/hal-resmgr-grant 2006-09-05 14:20:29.000000000 +0200
@@ -0,0 +1,13 @@
+#!/bin/sh
+if [ "$UDI" = '/org/freedesktop/Hal/devices/computer' ]; then
+ udi=
+else
+ udi="--udi=$UDI"
+fi
+result=`/usr/sbin/hal-resmgr $udi --grant="$HAL_METHOD_INVOKED_BY_UID" 2>&1`
+if [ "$?" != 0 ]; then
+ echo 'org.freedesktop.Hal.Device.resmgr.error'
+ echo "$result"
+ exit 1
+fi
+exit 0
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/hal-resmgr-0.1_SVNr92/hal-resmgr-revoke new/hal-resmgr-0.1_SVNr109/hal-resmgr-revoke
--- old/hal-resmgr-0.1_SVNr92/hal-resmgr-revoke 1970-01-01 01:00:00.000000000 +0100
+++ new/hal-resmgr-0.1_SVNr109/hal-resmgr-revoke 2006-09-05 14:20:29.000000000 +0200
@@ -0,0 +1,13 @@
+#!/bin/sh
+if [ "$UDI" = '/org/freedesktop/Hal/devices/computer' ]; then
+ udi=
+else
+ udi="--udi=$UDI"
+fi
+result=`/usr/sbin/hal-resmgr $udi --revoke="$HAL_METHOD_INVOKED_BY_UID" 2>&1`
+if [ "$?" != 0 ]; then
+ echo 'org.freedesktop.Hal.Device.resmgr.error'
+ echo "$result"
+ exit 1
+fi
+exit 0
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/hal-resmgr-0.1_SVNr92/hal-resmgr.c new/hal-resmgr-0.1_SVNr109/hal-resmgr.c
--- old/hal-resmgr-0.1_SVNr92/hal-resmgr.c 2006-08-23 10:21:35.000000000 +0200
+++ new/hal-resmgr-0.1_SVNr109/hal-resmgr.c 2006-09-05 14:20:29.000000000 +0200
@@ -41,11 +41,15 @@
#include
#include
+#include
+#include
+
#include
#include "mainloop.h"
#include "mainloop-dbus.h"
#include "debug.h"
+#include "file.h"
static int diesilently;
/** Macro for terminating the program on an unrecoverable error */
@@ -53,30 +57,129 @@
static LibHalContext *hal_ctx;
static int retries = 0;
-static int dryrun = 0;
static int do_monitor = FALSE;
+static int do_list = FALSE;
+
+static int add_all_users = TRUE;
+
+static char** login_users;
+static uid_t* login_uids;
+static unsigned num_login_users;
+static char** logout_users;
+static uid_t* logout_uids;
+static unsigned num_logout_users;
+
+static int num_devices;
+static char **devices = NULL;
+
+#define RESMGR_LOGINCLASSES_PATH "/var/run/resmgr/classes/"
static void
-rsm_doit(char** classes, const char* device, const char* flags, int add)
+resmgr_get_users()
{
- if(add)
+ unsigned i;
+
+ if(!add_all_users)
+ return;
+
+ login_users = rsm_list_users();
+
+ if(login_users && login_users[0])
{
- unsigned i;
- for(i = 0; classes && classes[i]; ++i)
+ for(i = 0; login_users[i]; ++i);
+ num_login_users = i;
+
+ login_uids = malloc(sizeof(uid_t)*num_login_users);
+
+ for(i = 0; i < num_login_users; ++i)
{
- debug(1, "add %s %s %s", device, classes[i], flags?flags:"");
- if(!dryrun)
- rsm_command(NULL, "add %s %s %s", device, classes[i], flags?flags:"");
+ struct passwd* pw;
+
+ pw = getpwnam(login_users[i]);
+ if(!pw)
+ {
+ warning("cannot determine uid for %s", login_users[i]);
+ login_uids[i] = -1;
+ free(login_users[i]);
+ login_users[i] = NULL;
+ }
+ else
+ {
+ login_uids[i] = pw->pw_uid;
+ }
}
}
else
{
- debug(1, "remove %s", device);
- if(!dryrun)
- rsm_command(NULL, "remove %s", device);
+ free(login_users);
+ login_users = NULL;
+ num_login_users = 0;
}
}
+static int
+is_user_privileged(const char* user, const char* priv)
+{
+ char path[PATH_MAX];
+
+// TODO: use cache and resmgr C api instead of fs
+ snprintf(path, sizeof(path), RESMGR_LOGINCLASSES_PATH "%s/%s", priv, user);
+
+ if(access(path, F_OK) == 0)
+ return 1;
+
+ return 0;
+}
+
+static void
+rsm_doit(char** classes, const char* device, const char* flags)
+{
+ unsigned i, j;
+ res_file_t* dev;
+
+ dev = res_file_new(device, flags);
+
+ debug(1, "%s", device);
+
+ if(num_login_users)
+ {
+ for(i = 0; i < num_login_users; ++i)
+ {
+ if(!login_users[i])
+ continue;
+
+ for(j = 0; classes && classes[j]; ++j)
+ {
+ if(is_user_privileged(login_users[i], classes[j])) {
+ res_file_grant(dev, login_uids[i]);
+ }
+ else {
+ res_file_revoke(dev, login_uids[i]);
+ }
+ }
+ }
+ }
+
+ if(num_logout_users)
+ {
+ for(i = 0; i < num_logout_users; ++i)
+ {
+ if(!logout_users[i])
+ continue;
+
+ for(j = 0; classes && classes[j]; ++j)
+ {
+ res_file_revoke(dev, logout_uids[i]);
+ }
+ }
+ }
+
+ if(!num_login_users && !num_logout_users)
+ res_file_destroy(dev);
+
+ res_file_free(dev);
+}
+
#define IF_ERROR_PRINT(x) \
do { if(dbus_error_is_set(&error)) { \
error("%s: %s", (x), error.name, error.message); \
@@ -129,8 +232,31 @@
return TRUE;
}
+static char*
+guess_device_name(LibHalContext* ctx, const char* udi)
+{
+ char* device = NULL;
+ if((device = libhal_device_get_property_string (ctx, udi, "resmgr.device", NULL)))
+ {
+ }
+ /* block devices have these */
+ else if((device = libhal_device_get_property_string (ctx, udi, "block.device", NULL)))
+ {
+ }
+ /* alsa devs have these */
+ else if((device = libhal_device_get_property_string (ctx, udi, "linux.device_file", NULL)))
+ {
+ }
+ /* /dev/bus/usb/... */
+ else if((device = libhal_device_get_property_string (ctx, udi, "usbraw.device", NULL)))
+ {
+ }
+
+ return device;
+}
+
static void
-device_register_resmgr (LibHalContext *ctx, const char *udi, int add)
+device_register_resmgr (LibHalContext *ctx, const char *udi)
{
unsigned i;
LibHalPropertyType proptype;
@@ -139,15 +265,10 @@
char* device = NULL;
char* flags = NULL;
- if(add
- && libhal_device_property_exists (ctx, udi, key, NULL)
+ if(libhal_device_property_exists (ctx, udi, key, NULL)
&& usb_interface_hack(ctx, udi))
return;
- if(!add
- && libhal_device_property_exists (ctx, udi, "resmgr.hack_ignore_remove", NULL))
- return;
-
proptype = libhal_device_get_property_type(ctx, udi, key, NULL );
switch(proptype)
@@ -167,7 +288,7 @@
if(!classes)
return;
- if(add)
+ if(1)
{
char** flaglist = NULL;
flaglist = libhal_device_get_property_strlist (hal_ctx, udi, "resmgr.flags", NULL);
@@ -192,27 +313,27 @@
}
}
- if((device = libhal_device_get_property_string (hal_ctx, udi, "resmgr.device", NULL)))
- {
- rsm_doit(classes, device, flags, add);
- libhal_free_string(device);
- }
- /* block devices have these */
- else if((device = libhal_device_get_property_string (hal_ctx, udi, "block.device", NULL)))
- {
- rsm_doit(classes, device, flags, add);
- libhal_free_string(device);
- }
- /* alsa devs have these */
- else if((device = libhal_device_get_property_string (hal_ctx, udi, "linux.device_file", NULL)))
+ if((device = guess_device_name(hal_ctx, udi)))
{
- rsm_doit(classes, device, flags, add);
- libhal_free_string(device);
- }
- /* /dev/bus/usb/... */
- else if((device = libhal_device_get_property_string (hal_ctx, udi, "usbraw.device", NULL)))
- {
- rsm_doit(classes, device, flags, add);
+ if(do_list)
+ {
+ unsigned i;
+ printf("UDI %s\n", udi);
+ printf("Device %s\n", device);
+ fputs("Class", stdout);
+ for(i = 0; classes && classes[i]; ++i)
+ {
+ printf(" %s", classes[i]);
+ }
+ puts("");
+ if(flags)
+ printf("Flags %s\n", flags);
+ puts("");
+ }
+ else
+ {
+ rsm_doit(classes, device, flags);
+ }
libhal_free_string(device);
}
@@ -220,35 +341,6 @@
libhal_free_string_array(classes);
}
-/** Invoked when a device is added to the Global Device List. Simply prints
- * a message on stderr.
- *
- * @param udi Universal Device Id
- */
-static void
-device_added (LibHalContext *ctx,
- const char *udi)
-{
- debug (1, "*** lshal: device_added, udi='%s'", udi);
- device_register_resmgr(ctx, udi, 1);
-}
-
-/** Invoked when a device is removed from the Global Device List. Simply
- * prints a message on stderr.
- *
- * @param udi Universal Device Id
- */
-static void
-device_removed (LibHalContext *ctx,
- const char *udi)
-{
- // XXX: that doesn't work. The device is already gone by the time we
- // are notified so we can't find out the device node anymore. So we
- // would need to store the udi<->device relation somewhere ourself
- debug (1, "*** lshal: device_removed, udi='%s'", udi);
- device_register_resmgr(ctx, udi, 0);
-}
-
/** Print out program usage.
*
* @param argc Number of arguments given to program
@@ -260,9 +352,11 @@
printf ("\n" "usage : %s [OPTIONS]\n", argv[0]);
printf ("\nOPTIONS:\n"
" --monitor Monitor device list\n"
- " --retries NUM try to get device list NUM times if it failed\n"
- " --debug [NUM] set debug level\n"
- " --dry don't actually register with resmgr\n"
+ " --retries=NUM try to get device list NUM times if it failed\n"
+ " --debug[=NUM] set debug level\n"
+ " --grant=USER grant USER access to devices\n"
+ " --revoke=USER revoke USER's access to devices\n"
+ " --udi=UDI set ACLs on UDI\n"
" --help Show this information and exit\n"
"\n"
"Registers devices with resmgr. If the --monitor option is given\n"
@@ -275,19 +369,20 @@
/** scan already known devices
*/
static void
-scan_all (void)
+get_all_devices (void)
{
int i;
- int num_devices;
- char **device_names = NULL;
DBusError error;
+ if(devices)
+ return;
+
dbus_error_init (&error);
for(i = 0; i < retries+1; ++i)
{
- device_names = libhal_get_all_devices (hal_ctx, &num_devices, &error);
- if(device_names)
+ devices = libhal_get_all_devices (hal_ctx, &num_devices, &error);
+ if(devices)
break;
if(dbus_error_is_set(&error))
{
@@ -298,7 +393,7 @@
fflush(stdout);
sleep(1);
}
- if (device_names == NULL)
+ if (devices == NULL)
{
if(dbus_error_is_set(&error))
{
@@ -309,12 +404,20 @@
DIE(("Couldn't obtain list of devices\n"));
}
}
+}
+
+static void
+register_devices()
+{
+ int i;
for (i = 0; i < num_devices; i++) {
- device_register_resmgr(hal_ctx, device_names[i], 1);
+ device_register_resmgr(hal_ctx, devices[i]);
}
- libhal_free_string_array (device_names);
+ libhal_free_string_array (devices);
+ devices = NULL;
+ num_devices = 0;
}
static void parse_options(int argc, char* argv[])
@@ -328,7 +431,10 @@
{"retries", 1, NULL, 3},
{"debug", 2, NULL, 4},
{"diesilently", 0, NULL, 5},
- {"dry", 0, NULL, 6},
+ {"grant", 1, NULL, 7},
+ {"revoke", 1, NULL, 8},
+ {"udi", 1, NULL, 9},
+ {"list", 0, NULL, 10},
{NULL, 0, NULL, 0}
};
@@ -365,8 +471,83 @@
diesilently = 1;
break;
- case 6:
- dryrun = 1;
+ case 7:
+ {
+ uid_t uid;
+ struct passwd* pw = NULL;
+ char* endp;
+ unsigned i = num_login_users++;
+
+ login_users = realloc(login_users, sizeof(char*)*num_login_users);
+ login_uids = realloc(login_uids, sizeof(uid_t)*num_login_users);
+
+ uid = strtol(optarg, &endp, 10);
+
+ if(optarg != endp && !*endp)
+ pw = getpwuid(uid);
+ else
+ pw = getpwnam(optarg);
+
+ if(!pw)
+ {
+ warning("cannot determine uid for %s", optarg);
+ login_uids[i] = -1;
+ login_users[i] = NULL;
+ }
+ else
+ {
+ login_users[i] = strdup(pw->pw_name);
+ login_uids[i] = pw->pw_uid;
+ }
+
+ add_all_users = FALSE;
+ }
+ break;
+
+ case 8:
+ {
+ uid_t uid;
+ struct passwd* pw = NULL;
+ char* endp;
+ unsigned i = num_logout_users++;
+
+ logout_users = realloc(logout_users, sizeof(char*)*num_logout_users);
+ logout_uids = realloc(logout_uids, sizeof(uid_t)*num_logout_users);
+
+ uid = strtol(optarg, &endp, 10);
+
+ if(optarg != endp && !*endp)
+ pw = getpwuid(uid);
+ else
+ pw = getpwnam(optarg);
+
+ if(!pw)
+ {
+ warning("cannot determine uid for %s", optarg);
+ logout_uids[i] = -1;
+ logout_users[i] = NULL;
+ }
+ else
+ {
+ logout_users[i] = strdup(pw->pw_name);
+ logout_uids[i] = pw->pw_uid;
+ }
+
+ add_all_users = FALSE;
+ }
+ break;
+
+ case 9:
+ {
+ int i = num_devices++;
+ devices = realloc(devices, sizeof(char*)*num_devices+1);
+ devices[i] = strdup(optarg);
+ devices[i+1] = NULL;
+ }
+ break;
+
+ case 10:
+ do_list = TRUE;
break;
default:
@@ -378,14 +559,12 @@
}
-static void main_dbus(int argc, char* argv[])
+static void main_dbus()
{
DBusError error;
MainLoop *loop = NULL;
DBusConnection *conn;
- parse_options(argc, argv);
-
if (do_monitor)
{
loop = main_loop_new();
@@ -412,11 +591,15 @@
if(loop)
{
- libhal_ctx_set_device_added (hal_ctx, device_added);
- libhal_ctx_set_device_removed (hal_ctx, device_removed);
+ libhal_ctx_set_device_added (hal_ctx, device_register_resmgr);
}
- scan_all();
+ get_all_devices();
+
+ if(!do_list)
+ resmgr_get_users();
+
+ register_devices();
if(loop)
{
@@ -432,18 +615,18 @@
}
/* use direct hal connection to make callout work during hal startup */
-static void process_device(const char* action, const char* udi)
+static void process_device(const char* udi)
{
DBusError error;
- unsigned add = !strcmp(action, "add");
+
+ debug(1, "adding single device %s", udi);
dbus_error_init (&error);
if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
DIE(("libhal_ctx_init_direct: %s: %s\n", error.name, error.message));
}
-
- device_register_resmgr(hal_ctx, udi, add);
+ device_register_resmgr(hal_ctx, udi);
libhal_ctx_shutdown (hal_ctx, &error);
libhal_ctx_free (hal_ctx);
@@ -452,18 +635,21 @@
int main (int argc, char *argv[])
{
const char* udi;
- const char* action;
udi = getenv("UDI");
- action = getenv("HALD_ACTION");
if(rsm_connect() == -1)
DIE(("can't connect to resmgrd"));
- if(action && udi)
- process_device(action, udi);
+ parse_options(argc, argv);
+
+ if(udi && !login_users && !logout_users)
+ {
+ resmgr_get_users();
+ process_device(udi);
+ }
else
- main_dbus(argc, argv);
+ main_dbus();
rsm_disconnect();
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/hal-resmgr-0.1_SVNr92/resmgr-callouts.fdi new/hal-resmgr-0.1_SVNr109/resmgr-callouts.fdi
--- old/hal-resmgr-0.1_SVNr92/resmgr-callouts.fdi 2006-02-16 16:41:26.000000000 +0100
+++ new/hal-resmgr-0.1_SVNr109/resmgr-callouts.fdi 2006-09-06 12:08:17.000000000 +0200
@@ -15,16 +15,42 @@
<merge key="resmgr.class" type="copy_property">@info.parent:@resmgr.hack_add_usbraw_as:resmgr.class</merge>
</match>
</match>
- <!-- allow open via usb family (#118794) -->
- <match key="resmgr.class" exists="true">
- <append key="resmgr.flags" type="strlist">usb</append>
- </match>
</match>
<!-- now add the callout to all resmgr devices -->
<match key="resmgr.class" exists="true">
+
<append key="info.callouts.add" type="strlist">hal-resmgr</append>
<append key="info.callouts.remove" type="strlist">hal-resmgr</append>
+
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.resmgr</append>
+
+ <append key="org.freedesktop.Hal.Device.resmgr.method_names" type="strlist">Grant</append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_signatures" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_argnames" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_execpaths" type="strlist">hal-resmgr-grant</append>
+
+ <append key="org.freedesktop.Hal.Device.resmgr.method_names" type="strlist">Revoke</append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_signatures" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_argnames" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_execpaths" type="strlist">hal-resmgr-revoke</append>
+
+ </match>
+
+ <match key="info.udi" string="/org/freedesktop/Hal/devices/computer">
+
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.resmgr</append>
+
+ <append key="org.freedesktop.Hal.Device.resmgr.method_names" type="strlist">Grant</append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_signatures" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_argnames" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_execpaths" type="strlist">hal-resmgr-grant</append>
+
+ <append key="org.freedesktop.Hal.Device.resmgr.method_names" type="strlist">Revoke</append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_signatures" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_argnames" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.resmgr.method_execpaths" type="strlist">hal-resmgr-revoke</append>
+
</match>
</device>
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/hal-resmgr-0.1_SVNr92/resmgr.conf new/hal-resmgr-0.1_SVNr109/resmgr.conf
--- old/hal-resmgr-0.1_SVNr92/resmgr.conf 1970-01-01 01:00:00.000000000 +0100
+++ new/hal-resmgr-0.1_SVNr109/resmgr.conf 2006-09-05 14:20:29.000000000 +0200
@@ -0,0 +1,2 @@
+ongrant desktop run /bin/sh -c "/usr/sbin/hal-resmgr --grant=$RES_USER"
+onrevoke desktop run /bin/sh -c "/usr/sbin/hal-resmgr --revoke=$RES_USER"
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/hal-resmgr-0.1_SVNr92/resmgr.fdi new/hal-resmgr-0.1_SVNr109/resmgr.fdi
--- old/hal-resmgr-0.1_SVNr92/resmgr.fdi 2006-02-16 16:41:26.000000000 +0100
+++ new/hal-resmgr-0.1_SVNr109/resmgr.fdi 2006-09-06 12:08:37.000000000 +0200
@@ -78,14 +78,14 @@
<match key="serial.device" exists="true">
<merge key="resmgr.device" type="copy_property">serial.device</merge>
<merge key="resmgr.class" type="string">modem</merge>
-
- <!-- someone decided that this is a pda rather than a modem -->
- <match key="pda.platform" exists="true">
- <merge key="resmgr.class" type="string">pda</merge>
- </match>
</match>
</match>
+ <!-- after serial on purpose -->
+ <match key="pda.platform" exists="true">
+ <merge key="resmgr.class" type="string">pda</merge>
+ </match>
+
</device>
</deviceinfo>
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
---------------------------------------------------------------------
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org