Commit 12d20fc8 authored by David Zeuthen's avatar David Zeuthen

Update to new D-BUS API; print " (temporary)" for privilege if appropriate.

Update to new D-BUS API
Update to new D-BUS API (main): --do--
New file
Add build rules for polkit-revoke-privilege
Fix up prototypes
Update to new D-BUS API
    (polkit_manager_get_allowed_resources_for_privilege): --do--
    (polkit_manager_revoke_temporary_privilege): New function
    (polkit_manager_remove_temporary_privilege): Fix up resource handling
    (polkit_manager_add_temporary_privilege): --do--
Update to new D-BUS API and export libpolkit_revoke_temporary_privilege()
Update to new D-BUS API
    (libpolkit_get_allowed_resources_for_privilege_for_uid): --do--
    (libpolkit_revoke_temporary_privilege): New function
Rename InitiatePrivilegeGrant() to InitiateTemporaryPrivilegeGrant(). Add
    new function RevokeTemporaryPrivilege(). Make IsUserPrivileged() output
    a boolean is_temporary. GetAllowedResourcesForPrivilege() now also
    outputs an integer num_non_temp.
parent 5122b4d8
2006-04-22 David Zeuthen <davidz@redhat.com>
* tools/polkit-list-privileges.c (main): Update to new D-BUS API;
print " (temporary)" for privilege if appropriate.
* tools/polkit-is-privileged.c (main): Update to new D-BUS API
* tools/polkit-grant-privilege.c:
(do_grant_privilege): Update to new D-BUS API
(main): --do--
* tools/polkit-revoke-privilege.c: New file
* tools/Makefile.am: Add build rules for polkit-revoke-privilege
* polkitd/polkit-manager.h: Fix up prototypes
* polkitd/polkit-manager.c:
(polkit_manager_initiate_temporary_privilege_grant): Update to new
D-BUS API
(polkit_manager_get_allowed_resources_for_privilege): --do--
(polkit_manager_revoke_temporary_privilege): New function
(polkit_manager_remove_temporary_privilege): Fix up resource handling
(polkit_manager_add_temporary_privilege): --do--
* libpolkit/libpolkit.h:
(libpolkit_get_allowed_resources_for_privilege_for_uid): Update to
new D-BUS API and export libpolkit_revoke_temporary_privilege()
* libpolkit/libpolkit.c:
(libpolkit_is_uid_allowed_for_privilege): Update to new D-BUS API
(libpolkit_get_allowed_resources_for_privilege_for_uid): --do--
(libpolkit_revoke_temporary_privilege): New function
* polkit-interface-manager.xml: Rename InitiatePrivilegeGrant() to
InitiateTemporaryPrivilegeGrant(). Add new function
RevokeTemporaryPrivilege(). Make IsUserPrivileged() output a
boolean is_temporary. GetAllowedResourcesForPrivilege() now also
outputs an integer num_non_temp.
2006-04-21 David Zeuthen <davidz@redhat.com>
* doc/spec/polkit-spec.xml.in: Write some more stuff
......
......@@ -102,7 +102,8 @@ LibPolKitResult
libpolkit_get_allowed_resources_for_privilege_for_uid (LibPolKitContext *ctx,
const char *user,
const char *privilege,
GList **result)
GList **result,
int *num_non_temporary)
{
LibPolKitResult res;
DBusMessage *message = NULL;
......@@ -148,6 +149,7 @@ libpolkit_get_allowed_resources_for_privilege_for_uid (LibPolKitContext *ctx,
if (!dbus_message_get_args (reply, &error,
DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &resource_list, &num_resources,
DBUS_TYPE_INT32, num_non_temporary,
DBUS_TYPE_INVALID)) {
g_warning ("Could not extract args from D-BUS message: %s : %s", error.name, error.message);
dbus_error_free (&error);
......@@ -175,7 +177,8 @@ libpolkit_is_uid_allowed_for_privilege (LibPolKitContext *ctx,
const char *user,
const char *privilege,
const char *resource,
gboolean *result)
gboolean *is_allowed,
gboolean *is_temporary)
{
LibPolKitResult res;
DBusMessage *message = NULL;
......@@ -186,7 +189,8 @@ libpolkit_is_uid_allowed_for_privilege (LibPolKitContext *ctx,
LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
res = LIBPOLKIT_RESULT_ERROR;
*result = FALSE;
*is_allowed = FALSE;
*is_temporary = FALSE;
message = dbus_message_new_method_call ("org.freedesktop.PolicyKit",
"/org/freedesktop/PolicyKit/Manager",
......@@ -228,7 +232,8 @@ libpolkit_is_uid_allowed_for_privilege (LibPolKitContext *ctx,
if (!dbus_message_get_args (reply, &error,
DBUS_TYPE_BOOLEAN, result,
DBUS_TYPE_BOOLEAN, is_allowed,
DBUS_TYPE_BOOLEAN, is_temporary,
DBUS_TYPE_INVALID)) {
g_warning ("Could not extract args from D-BUS message: %s : %s", error.name, error.message);
dbus_error_free (&error);
......@@ -245,6 +250,80 @@ out:
return res;
}
LibPolKitResult
libpolkit_revoke_temporary_privilege (LibPolKitContext *ctx,
const char *user,
const char *privilege,
const char *resource,
gboolean *result)
{
LibPolKitResult res;
DBusMessage *message = NULL;
DBusMessage *reply = NULL;
DBusError error;
const char *myresource = "";
LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
res = LIBPOLKIT_RESULT_ERROR;
*result = FALSE;
message = dbus_message_new_method_call ("org.freedesktop.PolicyKit",
"/org/freedesktop/PolicyKit/Manager",
"org.freedesktop.PolicyKit.Manager",
"RevokeTemporaryPrivilege");
if (message == NULL) {
g_warning ("Could not allocate D-BUS message");
goto out;
}
if (resource != NULL)
myresource = resource;
if (!dbus_message_append_args (message,
DBUS_TYPE_STRING, &user,
DBUS_TYPE_STRING, &privilege,
DBUS_TYPE_STRING, &myresource,
DBUS_TYPE_INVALID)) {
g_warning ("Could not append args to D-BUS message");
goto out;
}
dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (ctx->connection, message, -1, &error);
if (dbus_error_is_set (&error)) {
if (strcmp (error.name, "org.freedesktop.PolicyKit.Manager.NoSuchUser") == 0) {
res = LIBPOLKIT_RESULT_NO_SUCH_USER;
} else if (strcmp (error.name, "org.freedesktop.PolicyKit.Manager.NoSuchPrivilege") == 0) {
res = LIBPOLKIT_RESULT_NO_SUCH_PRIVILEGE;
} else if (strcmp (error.name, "org.freedesktop.PolicyKit.Manager.NotPrivileged") == 0) {
res = LIBPOLKIT_RESULT_NOT_PRIVILEGED;
} else if (strcmp (error.name, "org.freedesktop.PolicyKit.Manager.Error") == 0) {
res = LIBPOLKIT_RESULT_ERROR;
}
dbus_error_free (&error);
goto out;
}
if (!dbus_message_get_args (reply, &error,
DBUS_TYPE_BOOLEAN, result,
DBUS_TYPE_INVALID)) {
g_warning ("Could not extract args from D-BUS message: %s : %s", error.name, error.message);
dbus_error_free (&error);
goto out;
}
res = LIBPOLKIT_RESULT_OK;
out:
if (reply != NULL)
dbus_message_unref (reply);
if (message != NULL)
dbus_message_unref (message);
return res;
}
LibPolKitResult
libpolkit_get_privilege_list (LibPolKitContext *ctx,
GList **result)
......
......@@ -52,6 +52,13 @@ LibPolKitResult libpolkit_get_privilege_list (LibPolKit
LibPolKitResult libpolkit_is_uid_allowed_for_privilege (LibPolKitContext *ctx,
pid_t pid,
const char *user,
const char *privilege,
const char *resource,
gboolean *is_allowed,
gboolean *is_temporary);
LibPolKitResult libpolkit_revoke_temporary_privilege (LibPolKitContext *ctx,
const char *user,
const char *privilege,
const char *resource,
......@@ -60,7 +67,8 @@ LibPolKitResult libpolkit_is_uid_allowed_for_privilege (LibPolKit
LibPolKitResult libpolkit_get_allowed_resources_for_privilege_for_uid (LibPolKitContext *ctx,
const char *user,
const char *privilege,
GList **result);
GList **result,
int *num_non_temporary);
#endif /* LIBPOLKIT_H */
......
......@@ -3,7 +3,7 @@
<node name="/org/freedesktop/PolicyKit/Manager">
<interface name="org.freedesktop.PolicyKit.Manager">
<method name="InitiatePrivilegeGrant">
<method name="InitiateTemporaryPrivilegeGrant">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="user" type="s" direction="in"/>
<arg name="privilege" type="s" direction="in"/>
......@@ -11,6 +11,14 @@
<arg name="session_objpath" type="o" direction="out"/>
</method>
<method name="RevokeTemporaryPrivilege">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="user" type="s" direction="in"/>
<arg name="privilege" type="s" direction="in"/>
<arg name="resource" type="s" direction="in"/>
<arg name="was_revoked" type="b" direction="out"/>
</method>
<method name="IsUserPrivileged">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="pid" type="i" direction="in"/>
......@@ -18,13 +26,15 @@
<arg name="privilege" type="s" direction="in"/>
<arg name="resource" type="s" direction="in"/>
<arg name="is_privileged" type="b" direction="out"/>
<arg name="is_temporary" type="b" direction="out"/>
</method>
<method name="GetAllowedResourcesForPrivilege">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="user" type="s" direction="in"/>
<arg name="privilege" type="s" direction="in"/>
<arg name="resource_list" type="as" direction="out"/>
<arg name="user" type="s" direction="in"/>
<arg name="privilege" type="s" direction="in"/>
<arg name="resource_list" type="as" direction="out"/>
<arg name="num_non_temp" type="i" direction="out"/>
</method>
<method name="ListPrivileges">
......
......@@ -325,11 +325,11 @@ out:
}
gboolean
polkit_manager_initiate_privilege_grant (PolicyKitManager *manager,
char *user,
char *privilege,
char *resource,
DBusGMethodInvocation *context)
polkit_manager_initiate_temporary_privilege_grant (PolicyKitManager *manager,
char *user,
char *privilege,
char *resource,
DBusGMethodInvocation *context)
{
uid_t calling_uid;
pid_t calling_pid;
......@@ -402,6 +402,7 @@ polkit_manager_is_user_privileged (PolicyKitManager *manager,
uid_t uid;
PolicyResult res;
gboolean is_privileged;
gboolean is_temporary;
if (!polkit_manager_get_caller_info (manager,
......@@ -462,6 +463,8 @@ polkit_manager_is_user_privileged (PolicyKitManager *manager,
return FALSE;
}
is_temporary = FALSE;
/* check temporary lists */
if (!is_privileged) {
GList *i;
......@@ -482,12 +485,13 @@ polkit_manager_is_user_privileged (PolicyKitManager *manager,
((p->pid_restriction == -1) || (p->pid_restriction == pid))) {
is_privileged = TRUE;
is_temporary = TRUE;
break;
}
}
}
dbus_g_method_return (context, is_privileged);
dbus_g_method_return (context, is_privileged, is_temporary);
return TRUE;
}
......@@ -508,6 +512,7 @@ polkit_manager_get_allowed_resources_for_privilege (PolicyKitManager *manag
PolicyResult res;
TemporaryPrivilege *p;
char **resource_list;
int num_non_temporary;
if (!polkit_manager_get_caller_info (manager,
dbus_g_method_get_sender (context),
......@@ -565,6 +570,8 @@ polkit_manager_get_allowed_resources_for_privilege (PolicyKitManager *manag
return FALSE;
}
num_non_temporary = g_list_length (resources);
/* check temporary list */
for (i = manager->priv->temporary_privileges; i != NULL; i = g_list_next (i)) {
p = (TemporaryPrivilege *) i->data;
......@@ -580,14 +587,15 @@ polkit_manager_get_allowed_resources_for_privilege (PolicyKitManager *manag
resource_list = g_new0 (char *, g_list_length (resources) + 1);
for (i = resources, n = 0; i != NULL; i = g_list_next (i)) {
char *resource = (char *) i->data;
resource_list[n++] = g_strdup (resource);
resource_list[n] = g_strdup (resource);
n++;
}
resource_list[n] = NULL;
g_list_foreach (resources, (GFunc) g_free, NULL);
g_list_free (resources);
dbus_g_method_return (context, resource_list);
dbus_g_method_return (context, resource_list, num_non_temporary);
return TRUE;
}
......@@ -654,6 +662,72 @@ polkit_manager_list_privileges (PolicyKitManager *manager,
return TRUE;
}
gboolean
polkit_manager_revoke_temporary_privilege (PolicyKitManager *manager,
char *user,
char *privilege,
char *resource,
DBusGMethodInvocation *context)
{
uid_t uid;
uid_t calling_uid;
pid_t calling_pid;
gboolean result;
if (!polkit_manager_get_caller_info (manager,
dbus_g_method_get_sender (context),
&calling_uid,
&calling_pid)) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_ERROR,
"An error occured."));
return FALSE;
}
uid = uid_from_username (user);
if (uid == (uid_t) -1) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_NO_SUCH_USER,
"There is no user '%s'.",
user));
return FALSE;
}
/* check if given uid is privileged to revoke privilege; only allow own user to do this */
/* TODO: also allow callers with privilege 'polkit-manage-privileges-TODO-RENAME' */
if (uid != calling_uid) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_NOT_PRIVILEGED,
"You are not authorized to revoke the privilege."));
return FALSE;
}
if (resource != NULL && strlen (resource) == 0)
resource = NULL;
if (!polkit_manager_remove_temporary_privilege (manager,
uid,
privilege,
resource,
-1)) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_NO_SUCH_PRIVILEGE,
"There is no such privilege '%s'.",
privilege));
return FALSE;
}
result = TRUE;
dbus_g_method_return (context, result);
return TRUE;
}
/* local methods */
......@@ -671,7 +745,7 @@ polkit_manager_add_temporary_privilege (PolicyKitManager *manager,
p = (TemporaryPrivilege *) i->data;
if ((strcmp (p->privilege, privilege) == 0) &&
(safe_strcmp (p->resource, resource) == 0) &&
((resource != NULL) && (safe_strcmp (p->resource, resource)) == 0) &&
(p->user == user) &&
(p->pid_restriction == pid_restriction))
return FALSE;
......@@ -702,7 +776,8 @@ polkit_manager_remove_temporary_privilege (PolicyKitManager *manager,
p = (TemporaryPrivilege *) i->data;
if ((strcmp (p->privilege, privilege) == 0) &&
(safe_strcmp (p->resource, resource) == 0) &&
((resource == NULL) ? (p->resource == NULL)
: ((p->resource != NULL) ? (strcmp (p->resource, resource) == 0) : FALSE)) &&
(p->user == user) &&
(p->pid_restriction == pid_restriction)) {
......
......@@ -77,7 +77,13 @@ PolicyKitManager *polkit_manager_new (DBusGConne
/* remote methods */
gboolean polkit_manager_initiate_privilege_grant (PolicyKitManager *manager,
gboolean polkit_manager_initiate_temporary_privilege_grant (PolicyKitManager *manager,
char *user,
char *privilege,
char *resource,
DBusGMethodInvocation *context);
gboolean polkit_manager_revoke_temporary_privilege (PolicyKitManager *manager,
char *user,
char *privilege,
char *resource,
......
......@@ -15,7 +15,8 @@ INCLUDES = \
bin_PROGRAMS = \
polkit-is-privileged \
polkit-list-privileges \
polkit-grant-privilege
polkit-grant-privilege \
polkit-revoke-privilege
polkit_is_privileged_SOURCES = polkit-is-privileged.c
polkit_is_privileged_LDADD = @DBUS_CFLAGS@ @GLIB_LIBS@ $(top_builddir)/libpolkit/libpolkit.la
......@@ -29,13 +30,19 @@ polkit-interface-manager-glue.h: ../polkit-interface-manager.xml Makefile.am
polkit-interface-session-glue.h: ../polkit-interface-session.xml Makefile.am
dbus-binding-tool --prefix=polkit_session --mode=glib-client --output=polkit-interface-session-glue.h ../polkit-interface-session.xml
polkit_grant_privilege_SOURCES= \
polkit-grant-privilege.c \
polkit-interface-manager-glue.h \
polkit-interface-session-glue.h
polkit_grant_privilege_LDADD= @DBUS_GLIB_LIBS@ @GLIB_LIBS@ $(top_builddir)/libpolkit/libpolkit.la
polkit_revoke_privilege_SOURCES= \
polkit-revoke-privilege.c
polkit_revoke_privilege_LDADD= @DBUS_GLIB_LIBS@ @GLIB_LIBS@ $(top_builddir)/libpolkit/libpolkit.la
BUILT_SOURCES = polkit-interface-manager-glue.h polkit-interface-session-glue.h
clean-local :
......
......@@ -224,12 +224,12 @@ do_grant_privilege (DBusGConnection *conn, const char *user, const char *privile
goto out;
}
if (!org_freedesktop_PolicyKit_Manager_initiate_privilege_grant (manager,
user,
privilege,
resource,
&session_objpath,
&error)) {
if (!org_freedesktop_PolicyKit_Manager_initiate_temporary_privilege_grant (manager,
user,
privilege,
resource,
&session_objpath,
&error)) {
g_warning ("GrantPrivilege: %s", error->message);
g_error_free (error);
goto out;
......@@ -318,6 +318,9 @@ main (int argc, char **argv)
{"version", no_argument, NULL, 'V'},
{NULL, 0, NULL, 0}
};
gboolean is_privileged = FALSE;
gboolean is_temporary = FALSE;
LibPolKitResult result;
g_type_init ();
......@@ -382,15 +385,13 @@ main (int argc, char **argv)
ctx = libpolkit_new_context (dbus_g_connection_get_connection (bus));
gboolean is_privileged = FALSE;
LibPolKitResult result;
result = libpolkit_is_uid_allowed_for_privilege (ctx,
-1,
user,
privilege,
resource,
&is_privileged);
&is_privileged,
&is_temporary);
switch (result) {
case LIBPOLKIT_RESULT_OK:
if (is_privileged) {
......
......@@ -78,6 +78,7 @@ main (int argc, char *argv[])
};
LibPolKitContext *ctx = NULL;
gboolean is_allowed;
gboolean is_temporary;
LibPolKitResult result;
gboolean is_verbose = FALSE;
DBusError error;
......@@ -160,7 +161,8 @@ main (int argc, char *argv[])
user,
privilege,
resource,
&is_allowed);
&is_allowed,
&is_temporary);
switch (result) {
case LIBPOLKIT_RESULT_OK:
rc = is_allowed ? 0 : 1;
......
......@@ -135,8 +135,10 @@ main (int argc, char *argv[])
for (l = privilege_list, i = 0; l != NULL; l = g_list_next (l), i++) {
const char *privilege;
gboolean is_allowed;
gboolean is_temporary;
GList *j;
GList *resources;
int num_non_temporary;
privilege = (const char *) l->data;
if (is_verbose) {
......@@ -148,22 +150,29 @@ main (int argc, char *argv[])
user,
privilege,
NULL,
&is_allowed) == LIBPOLKIT_RESULT_OK) {
&is_allowed,
&is_temporary) == LIBPOLKIT_RESULT_OK) {
if (is_allowed) {
g_print ("privilege %s\n", privilege);
} else {
if (libpolkit_get_allowed_resources_for_privilege_for_uid (ctx,
user,
privilege,
&resources) == LIBPOLKIT_RESULT_OK) {
for (j = resources; j != NULL; j = g_list_next (j)) {
const char *resource;
resource = (const char *) j->data;
g_print ("resource %s privilege %s\n", resource, privilege);
}
g_list_foreach (resources, (GFunc) g_free, NULL);
g_list_free (resources);
g_print ("privilege %s%s\n", privilege, is_temporary ? " (temporary)" : "");
}
if (libpolkit_get_allowed_resources_for_privilege_for_uid (
ctx,
user,
privilege,
&resources,
&num_non_temporary) == LIBPOLKIT_RESULT_OK) {
int n;
for (j = resources, n = 0; j != NULL; j = g_list_next (j), n++) {
const char *resource;
resource = (const char *) j->data;
g_print ("resource %s privilege %s%s\n",
resource, privilege,
n >= num_non_temporary ? " (temporary)" : "");
}
g_list_foreach (resources, (GFunc) g_free, NULL);
g_list_free (resources);
}
}
......
/***************************************************************************
* CVSID: $Id$
*
* polkit-grant-privilege.c : Grant privileges
*
* Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include <string.h>
#include <errno.h>
#include <glib/gstdio.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <libpolkit/libpolkit.h>
static void
usage (int argc, char *argv[])
{
fprintf (stderr, "polkit-revoke-privilege version " PACKAGE_VERSION "\n");
fprintf (stderr, "\n" "usage : %s -p <privilege> [-u user] [-r <resource>]\n", argv[0]);
fprintf (stderr,
"\n"
"Options:\n"
" -u, --user User to revoke privilege from\n"
" -p, --privilege Privilege to revoke\n"
" -r, --resource Resource\n"
" -h, --help Show this information and exit\n"
" -v, --verbose Verbose operation\n"
" -V, --version Print version number\n"
"\n"
"Revokes a privilege for accessing a resource. The resource may\n"
"be omitted.\n");
}
static gboolean is_verbose = FALSE;
int
main (int argc, char **argv)
{
int rc;
GError *error = NULL;
DBusGConnection *bus;
LibPolKitContext *ctx;
char *user = NULL;
char *resource = NULL;
char *privilege = NULL;
static const struct option long_options[] = {