implement EnumerateUsers()
authorDavid Zeuthen <davidz@redhat.com>
Thu, 4 Dec 2008 00:01:07 +0000 (19:01 -0500)
committerDavid Zeuthen <davidz@redhat.com>
Thu, 4 Dec 2008 00:01:07 +0000 (19:01 -0500)
12 files changed:
data/org.freedesktop.PolicyKit1.Authority.xml
docs/polkit/polkit-docs.xml
src/polkit/Makefile.am
src/polkit/polkit.h
src/polkit/polkitauthorizationclaim.h
src/polkit/polkitprocess.c [deleted file]
src/polkit/polkitprocess.h [deleted file]
src/polkit/polkitsubject.c
src/polkit/polkitsubject.h
src/polkit/polkituser.c [deleted file]
src/polkit/polkituser.h [deleted file]
src/polkitbackend/polkitbackendlocal.c

index dbd5b4c..c31c173 100644 (file)
@@ -1,18 +1,21 @@
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node name="/">
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+
+  <!-- User defined struct -->
+  <annotation name="org.gtk.EggDBus.DeclareStruct"       value="Subject">
+    <annotation name="org.gtk.EggDBus.Struct.Signature"    value="(sa{sv})"/>
+  </annotation>
 
   <interface name="org.freedesktop.PolicyKit1.Authority">
 
     <method name="SayHello">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
       <arg name="message" direction="in" type="s"/>
       <arg name="result" direction="out" type="s"/>
     </method>
 
-    <method name="CheckClaims">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg name="claims" direction="in" type="a(ssa{ss})"/>
-      <arg name="result" direction="out" type="s"/>
+    <method name="EnumerateUsers">
+      <arg name="users" direction="out" type="a(sa{sv})"/>
     </method>
 
   </interface>
index 26b5cf2..557ebfa 100644 (file)
@@ -69,8 +69,6 @@
     <xi:include href="xml/polkitactiondescription.xml"/>
     <xi:include href="xml/polkiterror.xml"/>
     <xi:include href="xml/polkitsubject.xml"/>
-    <xi:include href="xml/polkituser.xml"/>
-    <xi:include href="xml/polkitprocess.xml"/>
     <chapter id="extending">
       <title>Extending PolicyKit</title>
       <xi:include href="../polkitbackend/xml/polkitbackendlocal.xml"/>
index d3d34d9..4f64341 100644 (file)
@@ -42,8 +42,6 @@ libpolkit_gobject_1include_HEADERS =                                  \
         polkitauthorizationresult.h                                    \
         polkiterror.h                                                  \
         polkitsubject.h                                                        \
-        polkituser.h                                                   \
-        polkitprocess.h                                                        \
        polkitbindings.h                                                \
        polkitbindingstypes.h                                           \
        polkitauthority.h                                               \
@@ -57,8 +55,6 @@ libpolkit_gobject_1_la_SOURCES =                                      \
         polkitauthorizationresult.h    polkitauthorizationresult.c     \
         polkiterror.h                  polkiterror.c                   \
         polkitsubject.h                        polkitsubject.c                 \
-        polkituser.h                   polkituser.c                    \
-        polkitprocess.h                        polkitprocess.c                 \
         $(BUILT_SOURCES)                                               \
         $(NULL)
 
index 57bc2f5..1f701f8 100644 (file)
@@ -32,8 +32,6 @@
 #include <polkit/polkitsubject.h>
 #include <polkit/polkitauthorizationclaim.h>
 #include <polkit/polkitauthorizationresult.h>
-#include <polkit/polkituser.h>
-#include <polkit/polkitprocess.h>
 #include <polkit/polkitactiondescription.h>
 
 #undef _POLKIT_INSIDE_POLKIT_H
index b04304b..7689897 100644 (file)
 #error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents."
 #endif
 
-#ifndef __POLKIT_AUTHORIZATION_CLAIM_H__
-#define __POLKIT_AUTHORIZATION_CLAIM_H__
-
 #include <glib-object.h>
 #include <polkit/polkitsubject.h>
 
+#ifndef __POLKIT_AUTHORIZATION_CLAIM_H__
+#define __POLKIT_AUTHORIZATION_CLAIM_H__
+
 G_BEGIN_DECLS
 
 #define POLKIT_TYPE_AUTHORIZATION_CLAIM         (polkit_authorization_claim_get_type ())
diff --git a/src/polkit/polkitprocess.c b/src/polkit/polkitprocess.c
deleted file mode 100644 (file)
index a522682..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-
-/*
- * Copyright (C) 2008 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#include "config.h"
-#include <string.h>
-
-#include "polkitprocess.h"
-
-/**
- * SECTION:polkitprocess
- * @short_description: Process
- * @include: polkit/polkit.h
- *
- * Represents a process.
- */
-
-/*--------------------------------------------------------------------------------------------------------------*/
-
-struct _PolkitProcessPrivate
-{
-        GPid pid;
-};
-
-enum {
-        PROP_0,
-        PROP_PID,
-};
-
-static void polkit_process_subject_iface_init (PolkitSubjectIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (PolkitProcess, polkit_process, G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (POLKIT_TYPE_SUBJECT,
-                                                polkit_process_subject_iface_init))
-
-#define POLKIT_PROCESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_TYPE_PROCESS, PolkitProcessPrivate))
-
-static void
-polkit_process_get_property (GObject    *object,
-                             guint       prop_id,
-                             GValue     *value,
-                             GParamSpec *pspec)
-{
-        PolkitProcess *process = POLKIT_PROCESS (object);
-
-        switch (prop_id) {
-        case PROP_PID:
-                g_value_set_int (value, process->priv->pid);
-                break;
-
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-                break;
-        }
-}
-
-static void
-polkit_process_set_property (GObject      *object,
-                             guint         prop_id,
-                             const GValue *value,
-                             GParamSpec   *pspec)
-{
-        PolkitProcess *process = POLKIT_PROCESS (object);
-
-        switch (prop_id) {
-        case PROP_PID:
-                polkit_process_set_pid (process, g_value_get_int (value));
-                break;
-
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-                break;
-        }
-}
-
-static void
-polkit_process_init (PolkitProcess *process)
-{
-        process->priv = POLKIT_PROCESS_GET_PRIVATE (process);
-}
-
-static void
-polkit_process_finalize (GObject *object)
-{
-        PolkitProcess *process;
-
-        g_return_if_fail (object != NULL);
-        g_return_if_fail (POLKIT_IS_PROCESS (object));
-
-        process = POLKIT_PROCESS (object);
-
-        G_OBJECT_CLASS (polkit_process_parent_class)->finalize (object);
-}
-
-static void
-polkit_process_class_init (PolkitProcessClass *klass)
-{
-        GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-        object_class->get_property = polkit_process_get_property;
-        object_class->set_property = polkit_process_set_property;
-        object_class->finalize = polkit_process_finalize;
-
-        /**
-         * PolkitProcess:pid:
-         *
-         * The process id.
-         */
-        g_object_class_install_property (object_class,
-                                         PROP_PID,
-                                         g_param_spec_int ("pid",
-                                                           "pid",
-                                                           "The process id",
-                                                           -1,
-                                                           G_MAXINT, /* TODO: maybe there's a MAX_PID? */
-                                                           -1,
-                                                           G_PARAM_CONSTRUCT |
-                                                           G_PARAM_READWRITE |
-                                                           G_PARAM_STATIC_NAME |
-                                                           G_PARAM_STATIC_NICK |
-                                                           G_PARAM_STATIC_BLURB));
-
-        g_type_class_add_private (klass, sizeof (PolkitProcessPrivate));
-}
-
-pid_t
-polkit_process_get_pid (PolkitProcess *process)
-{
-        g_return_val_if_fail (POLKIT_IS_PROCESS (process), -1);
-        return process->priv->pid;
-}
-
-void
-polkit_process_set_pid (PolkitProcess *process,
-                          pid_t           pid)
-{
-        g_return_if_fail (POLKIT_IS_PROCESS (process));
-        if (pid != process->priv->pid) {
-                process->priv->pid = pid;
-                g_object_notify (G_OBJECT (process), "pid");
-        }
-}
-
-PolkitSubject *
-polkit_process_new (pid_t pid)
-{
-        return POLKIT_SUBJECT (g_object_new (POLKIT_TYPE_PROCESS,
-                                             "pid", pid,
-                                             NULL));
-}
-
-static gboolean
-polkit_process_equal (PolkitSubject *subject1,
-                        PolkitSubject *subject2)
-{
-        PolkitProcess *process1 = POLKIT_PROCESS (subject1);
-        PolkitProcess *process2 = POLKIT_PROCESS (subject2);
-
-        return process1->priv->pid == process2->priv->pid;
-}
-
-static void
-polkit_process_subject_iface_init (PolkitSubjectIface *iface)
-{
-        iface->equal = polkit_process_equal;
-}
diff --git a/src/polkit/polkitprocess.h b/src/polkit/polkitprocess.h
deleted file mode 100644 (file)
index c992801..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-
-/*
- * Copyright (C) 2008 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
-#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents."
-#endif
-
-#ifndef __POLKIT_PROCESS_H__
-#define __POLKIT_PROCESS_H__
-
-#include <sys/types.h>
-#include <glib-object.h>
-#include <polkit/polkitsubject.h>
-
-G_BEGIN_DECLS
-
-#define POLKIT_TYPE_PROCESS         (polkit_process_get_type ())
-#define POLKIT_PROCESS(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_PROCESS, PolkitProcess))
-#define POLKIT_PROCESS_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_TYPE_PROCESS, PolkitProcessClass))
-#define POLKIT_IS_PROCESS(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_PROCESS))
-#define POLKIT_IS_PROCESS_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_PROCESS))
-#define POLKIT_PROCESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_PROCESS, PolkitProcessClass))
-
-typedef struct _PolkitProcess        PolkitProcess;
-typedef struct _PolkitProcessClass   PolkitProcessClass;
-typedef struct _PolkitProcessPrivate PolkitProcessPrivate;
-
-struct _PolkitProcess
-{
-        GObject              parent_instance;
-        PolkitProcessPrivate *priv;
-};
-
-struct _PolkitProcessClass
-{
-        GObjectClass parent_class;
-};
-
-GType            polkit_process_get_type  (void) G_GNUC_CONST;
-PolkitSubject   *polkit_process_new       (pid_t           pid);
-pid_t            polkit_process_get_pid   (PolkitProcess  *process);
-void             polkit_process_set_pid   (PolkitProcess  *process,
-                                           pid_t           pid);
-
-G_END_DECLS
-
-#endif /* __POLKIT_PROCESS_H__ */
index 062a7de..7db6c80 100644 (file)
@@ -1,5 +1,3 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-
 /*
  * Copyright (C) 2008 Red Hat, Inc.
  *
  * Author: David Zeuthen <davidz@redhat.com>
  */
 
-#include "config.h"
-
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+#include <string.h>
+#include "polkitbindings.h"
 #include "polkitsubject.h"
 
 /**
  * SECTION:polkitsubject
  * @title: PolkitSubject
- * @short_description: Interface for subjects
- * @include: polkit/polkit.h
- *
- * #PolkitSubject is a very minimal interface for subjects. It provides functions
- * for checking the equality of two subjects
+ * @short_description: Subjects
  *
- * To check if two #PolkitSubjects are equal, see polkit_subject_equal().
- **/
+ * The #PolkitSubject type is used for representing subject such as
+ * users, groups and processes.
+ */
 
-static void polkit_subject_base_init  (gpointer g_class);
-static void polkit_subject_class_init (gpointer g_class,
-                                         gpointer class_data);
+static void
+base_init (gpointer g_iface)
+{
+}
 
 GType
 polkit_subject_get_type (void)
 {
-        static volatile gsize g_define_type_id__volatile = 0;
-
-        if (g_once_init_enter (&g_define_type_id__volatile)) {
-                const GTypeInfo subject_info = {
-                        sizeof (PolkitSubjectIface), /* class_size */
-                        polkit_subject_base_init,   /* base_init */
-                        NULL,                        /* base_finalize */
-                        polkit_subject_class_init,  /* class_init */
-                        NULL,                        /* class_finalize */
-                        NULL,                        /* class_data */
-                        0,
-                        0,                            /* n_preallocs */
-                        NULL
-                };
-
-                GType g_define_type_id =
-                        g_type_register_static (G_TYPE_INTERFACE,
-                                                "PolkitSubject",
-                                                &subject_info,
-                                                0);
-
-                g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT);
-
-                g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
-        }
-
-        return g_define_type_id__volatile;
+  static GType iface_type = 0;
+
+  if (iface_type == 0)
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (PolkitSubjectIface),
+        base_init,              /* base_init      */
+        NULL,                   /* base_finalize  */
+        NULL,                   /* class_init     */
+        NULL,                   /* class_finalize */
+        NULL,                   /* class_data     */
+        0,                      /* instance_size  */
+        0,                      /* n_preallocs    */
+        NULL,                   /* instance_init  */
+        NULL                    /* value_table    */
+      };
+
+      iface_type = g_type_register_static (G_TYPE_INTERFACE, "PolkitSubject", &info, 0);
+
+      g_type_interface_add_prerequisite (iface_type, EGG_DBUS_TYPE_STRUCTURE);
+    }
+
+  return iface_type;
 }
 
-static void
-polkit_subject_class_init (gpointer g_class,
-                             gpointer class_data)
+/**
+ * polkit_subject_new_for_unix_process:
+ * @unix_process_id: The Process ID.
+ *
+ * Constructs a new #PolkitSubject for a the UNIX process with PID @process_id.
+ *
+ * Returns: A #PolkitSubject.
+ */
+PolkitSubject *
+polkit_subject_new_for_unix_process (pid_t unix_process_id)
 {
+  GValue *values;
+  EggDBusHashTable *properties;
+
+  properties = g_hash_table_new_full (g_str_hash,
+                                      g_str_equal,
+                                      (GDestroyNotify) g_free,
+                                      (GDestroyNotify) g_object_unref);
+  egg_dbus_hash_table_set_signature (properties, "s", "v");
+
+  g_hash_table_insert (properties,
+                       g_strdup ("unix-process-id"),
+                       egg_dbus_variant_new_for_uint32 (unix_process_id));
+
+  values = g_new0 (GValue, 2);
+  g_value_init (&(values[0]), G_TYPE_STRING);
+  g_value_set_string (&(values[0]), "unix-process");
+  g_value_init (&(values[1]), EGG_DBUS_TYPE_HASH_TABLE);
+  g_value_set_boxed (&(values[1]), properties);
+
+  return POLKIT_SUBJECT (egg_dbus_structure_new ("(sa{sv})", 2, values));
 }
 
-static void
-polkit_subject_base_init (gpointer g_class)
+/**
+ * polkit_subject_new_for_unix_user:
+ * @unix_user_id: The User ID.
+ *
+ * Constructs a new #PolkitSubject for a the UNIX user with UID @user_id.
+ *
+ * Returns: A #PolkitSubject.
+ */
+PolkitSubject *
+polkit_subject_new_for_unix_user (uid_t unix_user_id)
 {
+  GValue *values;
+  EggDBusHashTable *properties;
+
+  properties = g_hash_table_new_full (g_str_hash,
+                                      g_str_equal,
+                                      (GDestroyNotify) g_free,
+                                      (GDestroyNotify) g_object_unref);
+  egg_dbus_hash_table_set_signature (properties, "s", "v");
+
+  g_hash_table_insert (properties,
+                       g_strdup ("unix-user-id"),
+                       egg_dbus_variant_new_for_uint32 (unix_user_id));
+
+  values = g_new0 (GValue, 2);
+  g_value_init (&(values[0]), G_TYPE_STRING);
+  g_value_set_string (&(values[0]), "unix-user");
+  g_value_init (&(values[1]), EGG_DBUS_TYPE_HASH_TABLE);
+  g_value_set_boxed (&(values[1]), properties);
+
+  return POLKIT_SUBJECT (egg_dbus_structure_new ("(sa{sv})", 2, values));
 }
 
+/**
+ * polkit_subject_new_for_unix_group:
+ * @unix_group_id: The Group ID.
+ *
+ * Constructs a new #PolkitSubject for a the UNIX group with GID @group_id.
+ *
+ * Returns: A #PolkitSubject.
+ */
+PolkitSubject *
+polkit_subject_new_for_unix_group (gid_t unix_group_id)
+{
+  GValue *values;
+  EggDBusHashTable *properties;
+
+  properties = g_hash_table_new_full (g_str_hash,
+                                      g_str_equal,
+                                      (GDestroyNotify) g_free,
+                                      (GDestroyNotify) g_object_unref);
+  egg_dbus_hash_table_set_signature (properties, "s", "v");
+
+  g_hash_table_insert (properties,
+                       g_strdup ("unix-group-id"),
+                       egg_dbus_variant_new_for_uint32 (unix_group_id));
+
+  values = g_new0 (GValue, 2);
+  g_value_init (&(values[0]), G_TYPE_STRING);
+  g_value_set_string (&(values[0]), "unix-group");
+  g_value_init (&(values[1]), EGG_DBUS_TYPE_HASH_TABLE);
+  g_value_set_boxed (&(values[1]), properties);
+
+  return POLKIT_SUBJECT (egg_dbus_structure_new ("(sa{sv})", 2, values));
+}
+
+/**
+ * polkit_subject_get_kind:
+ * @subject: A #PolkitSubject.
+ *
+ * Gets the kind of @subject.
+ *
+ * Returns: A #PolkitSubjectKind.
+ */
+PolkitSubjectKind
+polkit_subject_get_kind (PolkitSubject *subject)
+{
+  gchar *kind_str;
+  PolkitSubjectKind kind;
+
+  g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), -1);
+  g_return_val_if_fail (strcmp (egg_dbus_structure_get_signature (EGG_DBUS_STRUCTURE (subject)), "(sa{sv})") == 0, -1);
+
+  egg_dbus_structure_get_element (EGG_DBUS_STRUCTURE (subject),
+                                  0, &kind_str,
+                                  -1);
+
+  if (strcmp (kind_str, "unix-process") == 0)
+    kind = POLKIT_SUBJECT_KIND_UNIX_PROCESS;
+  else if (strcmp (kind_str, "unix-user") == 0)
+    kind = POLKIT_SUBJECT_KIND_UNIX_USER;
+  else if (strcmp (kind_str, "unix-group") == 0)
+    kind = POLKIT_SUBJECT_KIND_UNIX_GROUP;
+  else
+    {
+      g_warning ("unknown kind str '%s'", kind_str);
+      kind = -1;
+    }
+
+  g_free (kind_str);
+
+  return kind;
+}
 
 /**
  * polkit_subject_equal:
- * @subject1: pointer to the first #PolkitSubject.
- * @subject2: pointer to the second #PolkitSubject.
+ * @a: A #PolkitSubject.
+ * @b: A #PolkitSubject.
  *
- * Checks if two subjects are equal.
+ * Checks if the two subjects @a and @b are equal.
  *
- * Returns: %TRUE if @subject1 is equal to @subject2. %FALSE otherwise.
+ * Returns: %TRUE if @a and @b are equal, %FALSE otherwise.
  **/
 gboolean
-polkit_subject_equal (PolkitSubject *subject1,
-                      PolkitSubject *subject2)
+polkit_subject_equal (PolkitSubject *a,
+                      PolkitSubject *b)
+{
+  gboolean ret;
+  PolkitSubjectKind kind_a;
+  PolkitSubjectKind kind_b;
+
+  g_return_val_if_fail (POLKIT_IS_SUBJECT (a), FALSE);
+  g_return_val_if_fail (POLKIT_IS_SUBJECT (b), FALSE);
+  g_return_val_if_fail (strcmp (egg_dbus_structure_get_signature (EGG_DBUS_STRUCTURE (a)), "(sa{sv})") == 0, FALSE);
+  g_return_val_if_fail (strcmp (egg_dbus_structure_get_signature (EGG_DBUS_STRUCTURE (b)), "(sa{sv})") == 0, FALSE);
+
+  ret = FALSE;
+
+  kind_a = polkit_subject_get_kind (a);
+  kind_b = polkit_subject_get_kind (b);
+
+  if (kind_a != kind_b)
+    goto out;
+
+  switch (kind_a)
+    {
+    case POLKIT_SUBJECT_KIND_UNIX_PROCESS:
+      if (polkit_subject_unix_process_get_id (a) == polkit_subject_unix_process_get_id (b))
+        ret = TRUE;
+      break;
+
+    case POLKIT_SUBJECT_KIND_UNIX_USER:
+      if (polkit_subject_unix_user_get_id (a) == polkit_subject_unix_user_get_id (b))
+        ret = TRUE;
+      break;
+
+    case POLKIT_SUBJECT_KIND_UNIX_GROUP:
+      if (polkit_subject_unix_group_get_id (a) == polkit_subject_unix_group_get_id (b))
+        ret = TRUE;
+      break;
+
+    default:
+      /* get_kind() will already have warned */
+      goto out;
+    }
+
+ out:
+  return ret;
+}
+
+/**
+ * polkit_subject_unix_process_get_id:
+ * @subject: A #PolkitSubject of the @POLKIT_SUBJECT_KIND_UNIX_PROCESS kind.
+ *
+ * Gets the UNIX process id for @subject.
+ *
+ * Returns: UNIX process id.
+ **/
+pid_t
+polkit_subject_unix_process_get_id (PolkitSubject *subject)
+{
+  EggDBusHashTable *value;
+  EggDBusVariant *variant;
+  pid_t pid;
+
+  g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), 0);
+  g_return_val_if_fail (strcmp (egg_dbus_structure_get_signature (EGG_DBUS_STRUCTURE (subject)), "(sa{sv})") == 0, 0);
+  g_return_val_if_fail (polkit_subject_get_kind (subject) != POLKIT_SUBJECT_KIND_UNIX_PROCESS, 0);
+
+  egg_dbus_structure_get_element (EGG_DBUS_STRUCTURE (subject),
+                1, &value,
+                -1);
+
+  variant = g_hash_table_lookup (value, "unix-process-id");
+  pid = (pid_t) egg_dbus_variant_get_uint32 (variant);
+
+  egg_dbus_hash_table_unref (value);
+
+  return pid;
+}
+
+/**
+ * polkit_subject_unix_user_get_id:
+ * @subject: A #PolkitSubject of the @POLKIT_SUBJECT_KIND_UNIX_USER kind.
+ *
+ * Gets the UNIX user id for @subject.
+ *
+ * Returns: UNIX user id.
+ **/
+uid_t
+polkit_subject_unix_user_get_id (PolkitSubject *subject)
 {
-        PolkitSubjectIface *iface;
+  EggDBusHashTable *value;
+  EggDBusVariant *variant;
+  uid_t uid;
 
-        if (subject1 == NULL && subject2 == NULL)
-                return TRUE;
+  g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), 0);
+  g_return_val_if_fail (strcmp (egg_dbus_structure_get_signature (EGG_DBUS_STRUCTURE (subject)), "(sa{sv})") == 0, 0);
+  g_return_val_if_fail (polkit_subject_get_kind (subject) != POLKIT_SUBJECT_KIND_UNIX_USER, 0);
 
-        if (subject1 == NULL || subject2 == NULL)
-                return FALSE;
+  egg_dbus_structure_get_element (EGG_DBUS_STRUCTURE (subject),
+                1, &value,
+                -1);
 
-        if (G_TYPE_FROM_INSTANCE (subject1) != G_TYPE_FROM_INSTANCE (subject2))
-                return FALSE;
+  variant = g_hash_table_lookup (value, "unix-user-id");
+  uid = (uid_t) egg_dbus_variant_get_uint32 (variant);
 
-        iface = POLKIT_SUBJECT_GET_IFACE (subject1);
+  egg_dbus_hash_table_unref (value);
 
-        return (* iface->equal) (subject1, subject2);
+  return uid;
 }
+
+/**
+ * polkit_subject_unix_group_get_id:
+ * @subject: A #PolkitSubject of the @POLKIT_SUBJECT_KIND_UNIX_GROUP kind.
+ *
+ * Gets the UNIX group id for @subject.
+ *
+ * Returns: UNIX group id.
+ **/
+gid_t
+polkit_subject_unix_group_get_id (PolkitSubject *subject)
+{
+  EggDBusHashTable *value;
+  EggDBusVariant *variant;
+  gid_t gid;
+
+  g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), 0);
+  g_return_val_if_fail (strcmp (egg_dbus_structure_get_signature (EGG_DBUS_STRUCTURE (subject)), "(sa{sv})") == 0, 0);
+  g_return_val_if_fail (polkit_subject_get_kind (subject) != POLKIT_SUBJECT_KIND_UNIX_GROUP, 0);
+
+  egg_dbus_structure_get_element (EGG_DBUS_STRUCTURE (subject),
+                1, &value,
+                -1);
+
+  variant = g_hash_table_lookup (value, "unix-group-id");
+  gid = (gid_t) egg_dbus_variant_get_uint32 (variant);
+
+  egg_dbus_hash_table_unref (value);
+
+  return gid;
+}
+
index df29922..8b47786 100644 (file)
@@ -1,5 +1,3 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-
 /*
  * Copyright (C) 2008 Red Hat, Inc.
  *
  * Author: David Zeuthen <davidz@redhat.com>
  */
 
-#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
-#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents."
-#endif
-
-#ifndef __POLKIT_SUBJECT_H__
-#define __POLKIT_SUBJECT_H__
+#ifndef __POLKIT_SUBJECT_H
+#define __POLKIT_SUBJECT_H
 
+#include <sys/types.h>
+#include <unistd.h>
 #include <glib-object.h>
+#include <polkit/polkitbindings.h>
 
 G_BEGIN_DECLS
 
-#define POLKIT_TYPE_SUBJECT            (polkit_subject_get_type ())
-#define POLKIT_SUBJECT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), POLKIT_TYPE_SUBJECT, PolkitSubject))
-#define POLKIT_IS_SUBJECT(obj)  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POLKIT_TYPE_SUBJECT))
-#define POLKIT_SUBJECT_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), POLKIT_TYPE_SUBJECT, PolkitSubjectIface))
+#define POLKIT_TYPE_SUBJECT         (polkit_subject_get_type())
+#define POLKIT_SUBJECT(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_SUBJECT, PolkitSubject))
+#define POLKIT_IS_SUBJECT(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_SUBJECT))
+#define POLKIT_SUBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE((o), POLKIT_TYPE_SUBJECT, PolkitSubjectIface))
 
-/**
- * PolkitSubject:
- *
- * An abstract type that specifies a subject.
- **/
-typedef struct _PolkitSubject      PolkitSubject;
+#if 0
+typedef struct _PolkitSubject PolkitSubject; /* Dummy typedef */
+#endif
 typedef struct _PolkitSubjectIface PolkitSubjectIface;
 
-/**
- * PolkitSubjectIface:
- * @g_iface: The parent interface.
- * @equal: Checks if two #PolkitSubject<!-- -->s are equal.
- *
- * #PolkitSubjectIface is used to implement #PolkitSubject types for various
- * different subjects
- */
-struct _PolkitSubjectIface
+typedef enum
 {
-        GTypeInterface g_iface;
-
-        /* Virtual Table */
+  POLKIT_SUBJECT_KIND_UNIX_PROCESS,
+  POLKIT_SUBJECT_KIND_UNIX_USER,
+  POLKIT_SUBJECT_KIND_UNIX_GROUP,
+} PolkitSubjectKind;
 
-        gboolean (* equal) (PolkitSubject *subject1,
-                            PolkitSubject *subject2);
+struct _PolkitSubjectIface
+{
+  GTypeInterface g_iface;
 };
 
-GType    polkit_subject_get_type  (void) G_GNUC_CONST;
-gboolean polkit_subject_equal     (PolkitSubject  *subject1,
-                                   PolkitSubject  *subject2);
+GType              polkit_subject_get_type              (void) G_GNUC_CONST;
+PolkitSubject     *polkit_subject_new_for_unix_process  (pid_t          unix_process_id);
+PolkitSubject     *polkit_subject_new_for_unix_user     (uid_t          unix_user_id);
+PolkitSubject     *polkit_subject_new_for_unix_group    (gid_t          unix_group_id);
+PolkitSubjectKind  polkit_subject_get_kind              (PolkitSubject *subject);
+pid_t              polkit_subject_unix_process_get_id   (PolkitSubject *subject);
+uid_t              polkit_subject_unix_user_get_id      (PolkitSubject *subject);
+gid_t              polkit_subject_unix_group_get_id     (PolkitSubject *subject);
+gboolean           polkit_subject_equal                 (PolkitSubject *a,
+                                                         PolkitSubject *b);
 
 G_END_DECLS
 
-#endif /* __POLKIT_SUBJECT_H__ */
+#endif /* __POLKIT_SUBJECT_H */
diff --git a/src/polkit/polkituser.c b/src/polkit/polkituser.c
deleted file mode 100644 (file)
index 32d691f..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-
-/*
- * Copyright (C) 2008 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#include "config.h"
-#include <string.h>
-
-#include "polkituser.h"
-
-/**
- * SECTION:polkituser
- * @short_description: User
- * @include: polkit/polkit.h
- *
- * Represents a user.
- */
-
-/*--------------------------------------------------------------------------------------------------------------*/
-
-struct _PolkitUserPrivate
-{
-        char *user_name;
-};
-
-enum {
-        PROP_0,
-        PROP_USER_NAME,
-};
-
-static void polkit_user_subject_iface_init (PolkitSubjectIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (PolkitUser, polkit_user, G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (POLKIT_TYPE_SUBJECT,
-                                                polkit_user_subject_iface_init))
-
-#define POLKIT_USER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_TYPE_USER, PolkitUserPrivate))
-
-static void
-polkit_user_get_property (GObject    *object,
-                          guint       prop_id,
-                          GValue     *value,
-                          GParamSpec *pspec)
-{
-        PolkitUser *user = POLKIT_USER (object);
-
-        switch (prop_id) {
-        case PROP_USER_NAME:
-                g_value_set_string (value, user->priv->user_name);
-                break;
-
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-                break;
-        }
-}
-
-static void
-polkit_user_set_property (GObject      *object,
-                          guint         prop_id,
-                          const GValue *value,
-                          GParamSpec   *pspec)
-{
-        PolkitUser *user = POLKIT_USER (object);
-
-        switch (prop_id) {
-        case PROP_USER_NAME:
-                polkit_user_set_user_name (user, g_value_get_string (value));
-                break;
-
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-                break;
-        }
-}
-
-static void
-polkit_user_init (PolkitUser *user)
-{
-        user->priv = POLKIT_USER_GET_PRIVATE (user);
-}
-
-static void
-polkit_user_finalize (GObject *object)
-{
-        PolkitUser *user;
-
-        g_return_if_fail (object != NULL);
-        g_return_if_fail (POLKIT_IS_USER (object));
-
-        user = POLKIT_USER (object);
-
-        g_free (user->priv->user_name);
-
-        G_OBJECT_CLASS (polkit_user_parent_class)->finalize (object);
-}
-
-static void
-polkit_user_class_init (PolkitUserClass *klass)
-{
-        GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-        object_class->get_property = polkit_user_get_property;
-        object_class->set_property = polkit_user_set_property;
-        object_class->finalize = polkit_user_finalize;
-
-        /**
-         * PolkitUser:user-name:
-         *
-         * The user name.
-         */
-        g_object_class_install_property (object_class,
-                                         PROP_USER_NAME,
-                                         g_param_spec_string ("user-name",
-                                                              "user-name",
-                                                              "The user name",
-                                                              NULL,
-                                                              G_PARAM_CONSTRUCT |
-                                                              G_PARAM_READWRITE |
-                                                              G_PARAM_STATIC_NAME |
-                                                              G_PARAM_STATIC_NICK |
-                                                              G_PARAM_STATIC_BLURB));
-
-        g_type_class_add_private (klass, sizeof (PolkitUserPrivate));
-}
-
-gchar *
-polkit_user_get_user_name (PolkitUser *user)
-{
-        g_return_val_if_fail (POLKIT_IS_USER (user), NULL);
-        return g_strdup (user->priv->user_name);
-}
-
-void
-polkit_user_set_user_name (PolkitUser *user,
-                           const char  *user_name)
-{
-        g_return_if_fail (POLKIT_IS_USER (user));
-        g_return_if_fail (user_name != NULL);
-
-        if (user->priv->user_name == NULL || strcmp (user_name, user->priv->user_name) != 0) {
-                g_free (user->priv->user_name);
-                user->priv->user_name = g_strdup (user_name);
-                g_object_notify (G_OBJECT (user), "user-name");
-        }
-}
-
-PolkitSubject *
-polkit_user_new (const gchar *user_name)
-{
-        return POLKIT_SUBJECT (g_object_new (POLKIT_TYPE_USER,
-                                             "user-name", user_name,
-                                             NULL));
-}
-
-static gboolean
-polkit_user_equal (PolkitSubject *subject1,
-                   PolkitSubject *subject2)
-{
-        PolkitUser *user1 = POLKIT_USER (subject1);
-        PolkitUser *user2 = POLKIT_USER (subject2);
-
-        return strcmp (user1->priv->user_name, user2->priv->user_name) == 0;
-}
-
-static void
-polkit_user_subject_iface_init (PolkitSubjectIface *iface)
-{
-        iface->equal = polkit_user_equal;
-}
diff --git a/src/polkit/polkituser.h b/src/polkit/polkituser.h
deleted file mode 100644 (file)
index 44e4a56..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-
-/*
- * Copyright (C) 2008 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
-#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents."
-#endif
-
-#ifndef __POLKIT_USER_H__
-#define __POLKIT_USER_H__
-
-#include <glib-object.h>
-#include <polkit/polkitsubject.h>
-
-G_BEGIN_DECLS
-
-#define POLKIT_TYPE_USER         (polkit_user_get_type ())
-#define POLKIT_USER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_USER, PolkitUser))
-#define POLKIT_USER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_TYPE_USER, PolkitUserClass))
-#define POLKIT_IS_USER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_USER))
-#define POLKIT_IS_USER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_USER))
-#define POLKIT_USER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_USER, PolkitUserClass))
-
-typedef struct _PolkitUser        PolkitUser;
-typedef struct _PolkitUserClass   PolkitUserClass;
-typedef struct _PolkitUserPrivate PolkitUserPrivate;
-
-struct _PolkitUser
-{
-        GObject             parent_instance;
-        PolkitUserPrivate  *priv;
-};
-
-struct _PolkitUserClass
-{
-        GObjectClass parent_class;
-};
-
-GType          polkit_user_get_type       (void) G_GNUC_CONST;
-PolkitSubject *polkit_user_new            (const char   *user_name);
-gchar         *polkit_user_get_user_name  (PolkitUser   *user);
-void           polkit_user_set_user_name  (PolkitUser  *user,
-                                           const gchar  *user_name);
-
-G_END_DECLS
-
-#endif /* __POLKIT_USER_H__ */
index 044cc15..8de4cdf 100644 (file)
@@ -22,6 +22,9 @@
  */
 
 #include "config.h"
+#include <errno.h>
+#include <pwd.h>
+#include <string.h>
 #include <polkit/polkit.h>
 #include "polkitbackendlocal.h"
 
@@ -100,10 +103,49 @@ authority_iface_handle_say_hello (PolkitAuthority *instance,
         g_free (result);
 }
 
+static void
+authority_iface_handle_enumerate_users (PolkitAuthority *instance,
+                                        EggDBusMethodInvocation *method_invocation)
+{
+        struct passwd *passwd;
+        GList *list;
+
+        list = NULL;
+
+        passwd = getpwent ();
+        if (passwd == NULL) {
+                egg_dbus_method_invocation_return_error (method_invocation,
+                                                         POLKIT_ERROR,
+                                                         POLKIT_ERROR_FAILED,
+                                                         "getpwent failed: %s",
+                                                         strerror (errno));
+                goto out;
+        }
+
+        do {
+                PolkitSubject *subject;
+
+                subject = polkit_subject_new_for_unix_user (passwd->pw_uid);
+
+                list = g_list_prepend (list, subject);
+        } while ((passwd = getpwent ()) != NULL);
+        endpwent ();
+
+        list = g_list_reverse (list);
+
+        polkit_authority_handle_enumerate_users_finish (instance,
+                                                        list,
+                                                        method_invocation);
+
+ out:
+        g_list_foreach (list, (GFunc) g_object_unref, NULL);
+        g_list_free (list);
+}
 
 static void
 authority_iface_init (PolkitAuthorityIface *authority_iface,
                       gpointer              iface_data)
 {
-        authority_iface->handle_say_hello = authority_iface_handle_say_hello;
+        authority_iface->handle_say_hello        = authority_iface_handle_say_hello;
+        authority_iface->handle_enumerate_users  = authority_iface_handle_enumerate_users;
 }