From 0cde8d85bedd07241326a69ca746f71d1490e35c Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Wed, 3 Dec 2008 19:01:07 -0500 Subject: [PATCH] implement EnumerateUsers() --- data/org.freedesktop.PolicyKit1.Authority.xml | 17 +- docs/polkit/polkit-docs.xml | 2 - src/polkit/Makefile.am | 4 - src/polkit/polkit.h | 2 - src/polkit/polkitauthorizationclaim.h | 6 +- src/polkit/polkitprocess.c | 185 ------------- src/polkit/polkitprocess.h | 67 ----- src/polkit/polkitsubject.c | 364 +++++++++++++++++++++----- src/polkit/polkitsubject.h | 67 +++-- src/polkit/polkituser.c | 188 ------------- src/polkit/polkituser.h | 66 ----- src/polkitbackend/polkitbackendlocal.c | 44 +++- 12 files changed, 390 insertions(+), 622 deletions(-) delete mode 100644 src/polkit/polkitprocess.c delete mode 100644 src/polkit/polkitprocess.h delete mode 100644 src/polkit/polkituser.c delete mode 100644 src/polkit/polkituser.h diff --git a/data/org.freedesktop.PolicyKit1.Authority.xml b/data/org.freedesktop.PolicyKit1.Authority.xml index dbd5b4c..c31c173 100644 --- a/data/org.freedesktop.PolicyKit1.Authority.xml +++ b/data/org.freedesktop.PolicyKit1.Authority.xml @@ -1,18 +1,21 @@ - - + + + + + + + - - - - - + + diff --git a/docs/polkit/polkit-docs.xml b/docs/polkit/polkit-docs.xml index 26b5cf2..557ebfa 100644 --- a/docs/polkit/polkit-docs.xml +++ b/docs/polkit/polkit-docs.xml @@ -69,8 +69,6 @@ - - Extending PolicyKit diff --git a/src/polkit/Makefile.am b/src/polkit/Makefile.am index d3d34d9..4f64341 100644 --- a/src/polkit/Makefile.am +++ b/src/polkit/Makefile.am @@ -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) diff --git a/src/polkit/polkit.h b/src/polkit/polkit.h index 57bc2f5..1f701f8 100644 --- a/src/polkit/polkit.h +++ b/src/polkit/polkit.h @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include #undef _POLKIT_INSIDE_POLKIT_H diff --git a/src/polkit/polkitauthorizationclaim.h b/src/polkit/polkitauthorizationclaim.h index b04304b..7689897 100644 --- a/src/polkit/polkitauthorizationclaim.h +++ b/src/polkit/polkitauthorizationclaim.h @@ -25,12 +25,12 @@ #error "Only can be included directly, this file may disappear or change contents." #endif -#ifndef __POLKIT_AUTHORIZATION_CLAIM_H__ -#define __POLKIT_AUTHORIZATION_CLAIM_H__ - #include #include +#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 index a522682..0000000 --- a/src/polkit/polkitprocess.c +++ /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 - */ - -#include "config.h" -#include - -#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 index c992801..0000000 --- a/src/polkit/polkitprocess.h +++ /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 - */ - -#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) -#error "Only can be included directly, this file may disappear or change contents." -#endif - -#ifndef __POLKIT_PROCESS_H__ -#define __POLKIT_PROCESS_H__ - -#include -#include -#include - -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__ */ diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c index 062a7de..7db6c80 100644 --- a/src/polkit/polkitsubject.c +++ b/src/polkit/polkitsubject.c @@ -1,5 +1,3 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ - /* * Copyright (C) 2008 Red Hat, Inc. * @@ -21,95 +19,339 @@ * Author: David Zeuthen */ -#include "config.h" - +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#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; +} + diff --git a/src/polkit/polkitsubject.h b/src/polkit/polkitsubject.h index df29922..8b47786 100644 --- a/src/polkit/polkitsubject.h +++ b/src/polkit/polkitsubject.h @@ -1,5 +1,3 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ - /* * Copyright (C) 2008 Red Hat, Inc. * @@ -21,52 +19,49 @@ * Author: David Zeuthen */ -#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) -#error "Only 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 +#include #include +#include 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 #PolkitSubjects 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 index 32d691f..0000000 --- a/src/polkit/polkituser.c +++ /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 - */ - -#include "config.h" -#include - -#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 index 44e4a56..0000000 --- a/src/polkit/polkituser.h +++ /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 - */ - -#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) -#error "Only can be included directly, this file may disappear or change contents." -#endif - -#ifndef __POLKIT_USER_H__ -#define __POLKIT_USER_H__ - -#include -#include - -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__ */ diff --git a/src/polkitbackend/polkitbackendlocal.c b/src/polkitbackend/polkitbackendlocal.c index 044cc15..8de4cdf 100644 --- a/src/polkitbackend/polkitbackendlocal.c +++ b/src/polkitbackend/polkitbackendlocal.c @@ -22,6 +22,9 @@ */ #include "config.h" +#include +#include +#include #include #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; } -- 2.7.4