Commit 1c3d5691 authored by David Zeuthen's avatar David Zeuthen

Lots of changes! Almost ready for 0.2 release.

parent 12d20fc8
2006-06-05 David Zeuthen <davidz@redhat.com>
Lots of changes! Almost ready for 0.2 release.
* Makefile.am:
* README:
* configure.in:
* doc/TODO:
* doc/api/polkit-docs.xml:
* doc/spec/Makefile.am:
* doc/spec/polkit-spec.html:
* doc/spec/polkit-spec.xml.in:
* libpolkit/Makefile.am:
* libpolkit/libpolkit-grant.c: (have_questions_handler),
(libpolkit_grant_provide_answers), (auth_done_handler),
(libpolkit_grant_new_context),
(libpolkit_grant_get_libpolkit_context),
(libpolkit_grant_set_questions_handler),
(libpolkit_grant_set_grant_complete_handler),
(libpolkit_grant_initiate_temporary_grant),
(libpolkit_grant_get_user_for_auth),
(libpolkit_grant_get_pam_service_for_auth),
(libpolkit_grant_close), (libpolkit_grant_free_context),
(libpolkit_grant_get_user), (libpolkit_grant_get_privilege),
(libpolkit_grant_get_resource):
* libpolkit/libpolkit-grant.h:
* libpolkit/libpolkit.c:
(libpolkit_get_allowed_resources_for_privilege_for_uid),
(libpolkit_is_uid_allowed_for_privilege):
* libpolkit/libpolkit.h:
* pam-polkit-console/Makefile.am:
* pam-polkit-console/pam-polkit-console.c: (_pam_log),
(_parse_module_args), (_is_local_xconsole), (_poke_polkitd),
(pam_sm_authenticate), (pam_sm_setcred), (pam_sm_open_session),
(pam_sm_close_session):
* polkit-interface-manager.xml:
* polkit-interface-session.xml:
* polkit.pc.in:
* polkitd/PolicyKit.in:
* polkitd/main.c: (handle_sigusr1), (sigusr1_iochn_data), (main):
* polkitd/policy.c: (txt_backend_read_policy),
(txt_backend_read_list), (txt_backend_read_word),
(policy_get_sufficient_privileges),
(policy_get_required_privileges),
(policy_get_auth_details_for_policy),
(_policy_is_uid_gid_allowed_for_policy),
(policy_is_uid_gid_allowed_for_policy),
(policy_is_uid_allowed_for_policy):
* polkitd/policy.h:
* polkitd/polkit-manager.c: (_granting_temp_priv),
(_revoking_temp_priv), (polkit_manager_error_get_type),
(bus_name_owner_changed), (polkit_manager_get_caller_info),
(_check_for_temp_privilege),
(polkit_manager_initiate_temporary_privilege_grant),
(polkit_manager_is_user_privileged),
(polkit_manager_get_allowed_resources_for_privilege),
(polkit_manager_revoke_temporary_privilege),
(polkit_manager_add_temporary_privilege),
(polkit_manager_remove_temporary_privilege),
(polkit_manager_update_desktop_console_privileges):
* polkitd/polkit-manager.h:
* polkitd/polkit-session.c: (polkit_session_close),
(polkit_session_grant_privilege_temporarily), (polkit_session_new),
(polkit_session_initiator_disconnected):
* polkitd/polkit-session.h:
* privileges/desktop-console.privilege:
* tools/Makefile.am:
* tools/polkit-grant-privilege.c: (questions_cb),
(grant_complete_cb), (main):
* tools/polkit-is-privileged.c: (usage), (main):
* tools/polkit-list-privileges.c: (main):
* tools/polkit-revoke-privilege.c: (main):
2006-04-22 David Zeuthen <davidz@redhat.com>
* tools/polkit-list-privileges.c (main): Update to new D-BUS API;
......
## Process this file with automake to produce Makefile.in
SUBDIRS = libpolkit polkitd doc tools privileges
SUBDIRS = libpolkit pam-polkit-console polkitd doc tools privileges
pamdir = $(sysconfdir)/pam.d
pam_DATA = policy-kit
......
......@@ -2,7 +2,6 @@
PolicyKit is a framework for defining policy for system-wide components and
for desktop pieces to configure it. It is used by HAL.
See also the file HACKING for notes of interest to developers working
on PolicyKit.
......
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT(PolicyKit, 0.1, david@fubar.dk)
AM_INIT_AUTOMAKE(PolicyKit, 0.1)
AC_INIT(PolicyKit, 0.2, david@fubar.dk)
AM_INIT_AUTOMAKE(PolicyKit, 0.2)
AM_CONFIG_HEADER(config.h)
AM_MAINTAINER_MODE
......@@ -48,7 +48,7 @@ AC_DEFINE_UNQUOTED(POLKIT_GROUP,"$POLKIT_GROUP", [Group for PolicyKit])
# Taken from dbus
AC_ARG_ENABLE(ansi, [ --enable-ansi enable -ansi -pedantic gcc flags],enable_ansi=$enableval,enable_ansi=no)
AC_ARG_ENABLE(verbose-mode, [ --enable-verbose-mode support verbose debug mode],enable_verbose_mode=$enableval,enable_verbose_mode=$USE_MAINTAINER_MODE)
AC_ARG_ENABLE(docbook-docs, [ --enable-docbook-docs build documentation (requires docbook2html)],enable_docbook_docs=$enableval,enable_docbook_docs=auto)
AC_ARG_ENABLE(docbook-docs, [ --enable-docbook-docs build documentation (requires xmlto)],enable_docbook_docs=$enableval,enable_docbook_docs=auto)
GTK_DOC_CHECK([1.3])
......@@ -150,7 +150,7 @@ AC_CHECK_FUNCS(getgrouplist)
# DocBook Documentation
AC_PATH_PROG(DOCBOOK, docbook2html, no)
AC_PATH_PROG(XMLTO, xmlto, no)
AC_MSG_CHECKING([whether to build DocBook documentation])
......@@ -347,6 +347,7 @@ AC_OUTPUT([
policy-kit
polkit.pc
Makefile
pam-polkit-console/Makefile
polkitd/Makefile
polkitd/PolicyKit
polkitd/PolicyKit.conf
......
TODO
DONE
- Write up a nice spec about how all this works since it can be a bit
confusing
- Refine the .privilege file format so e.g. user 'foo' is always
allowed to grant privilege 'bar' to other users. Also other stuff.
- write polkit-revoke-privilege
- make polkit-list-privileges and polkit-is-privileged display if a
privilege is granted permanently or temporary. Also display if it's
confined to a certain D-BUS connection.
- Factor out auth code in polkit-is-privileged into a GObject and put
it in a libpolkit-gobject library (since the interaction is pretty
hairy (see interaction diagram in polkitd/polkit-session.c) I will
not put this in libpolkit as I want to use the glib bindings and
these require the glib main loop => not suitable for Qt etc.)
PENDING
- Make polkitd emit signals on an interface such that privileged apps
can be notified when privileges are granted and revoked. Also
export other useful query operations.
- make D-BUS interface in general and polkit-grant-privilege in
particular capable of granting privs permanently
- write some man pages
- write libpolkit-gnome that GNOME apps can consume
- implement D-BUS interfaces suitable for a GUI privilege editor
- write more tests; audit code
......@@ -7,8 +7,9 @@
</bookinfo>
<chapter>
<title>Client library</title>
<title>Client libraries</title>
<xi:include href="xml/libpolkit.xml"/>
<xi:include href="xml/libpolkit-grant.xml"/>
</chapter>
</book>
......@@ -9,7 +9,7 @@ htmldocdir = $(DOCDIR)/spec
htmldoc_DATA = polkit-spec.html $(FIGURE_FILES)
polkit-spec.html : polkit-spec.xml $(FIGURE_FILES)
$(DOCBOOK) --nochunks polkit-spec.xml -o .
$(XMLTO) html-nochunks polkit-spec.xml
clean-local:
rm -f *~
......
This diff is collapsed.
......@@ -6,9 +6,9 @@
<book id="index">
<bookinfo>
<title>PolicyKit 0.1 Specification</title>
<releaseinfo>Version 0.1</releaseinfo>
<date>March 28th, 2006</date> <!-- Update this manually -->
<title>PolicyKit 0.2 Specification</title>
<releaseinfo>Version 0.2</releaseinfo>
<date>May 12th, 2006</date> <!-- Update this manually -->
<authorgroup>
<author>
<firstname>David</firstname>
......@@ -120,7 +120,7 @@
<para>
Upon a user invoking the <literal>Mount</literal> method, HAL
simply asks the <literal>org.freedesktop.PolicyKit</literal>
D-BUS service if the calling user posses this privilege and if
D-BUS service if the calling user possess this privilege and if
this is not the case the <literal>Mount</literal> method
throws
the <literal>org.freedesktop.Hal.Device.PermissionDeniedByPolicy</literal>
......@@ -155,7 +155,11 @@
and <emphasis>temporary</emphasis> privileges. The latter may
even be restricted such that only callers from the D-BUS
connection (remember, D-BUS connections has unique names)
obtaining the privilege may use the obtained privilege.
obtaining the privilege may use the obtained
privilege. Consequently, if a temporary privilege is
restricted to a certain D-BUS connection, it is revoked when
the owner of this connection disconnects from the system
message bus.
</para>
<para>
......@@ -215,8 +219,17 @@
<sect1>
<title>Privilege Descriptors</title>
<para>
Applications, such as HAL, installs <emphasis>privilege descriptors</emphasis> using the <literal>polkit-policy-descriptor-install</literal> commandline utility. The descriptor contains the following information
<para>
Applications, such as HAL, installs <emphasis>privilege
descriptors</emphasis> into
the <literal>/etc/PolicyKit/privilege.d</literal> directory
(or more correct, into
the <literal>$sysconfdir/PolicyKit/privilege.d</literal>
directory depending on where PolicyKit is built).
</para>
<para>
A policy descriptor contains the following information:
</para>
<itemizedlist>
......@@ -228,7 +241,13 @@
<listitem>
<para>
What other privileges a given user must also possess.
What privileges are required to possess a given privilege.
</para>
</listitem>
<listitem>
<para>
What privileges are sufficient to possess to automatically possess a given privilege.
</para>
</listitem>
......@@ -259,12 +278,12 @@
<programlisting>
[Policy]
RequiredPrivileges=
SufficientPrivileges=
Allow=
Deny=
CanObtain=
CanGrant=
ObtainRequireRoot=
ObtainPAMService=
</programlisting>
<sect2>
......@@ -273,7 +292,24 @@
This is a list of privileges the user must possess in order
to possess the given privilege. If the user doesn't possess
all of these privileges he is not considered to possess the
given privilege. The list may be empty.
given privilege. The list may be empty. A privilege in this
list is considered being possessed if the user is privileged
for one or more resources. E.g., if <literal>foo</literal>
is a required privilege then just having this privilege on
one resource is sufficient.
</para>
</sect2>
<sect2>
<title><literal>SufficientPrivileges</literal>: Sufficient Privileges</title>
<para>
This is a list of privileges that, if a user possess any of
these, he is consider to possess the given privilege. The
list may be empty. A privilege in this list is considered
being possessed if the user is privileged for one or more
resources. As with <literal>RequiredPrivileges</literal>,
if <literal>foo</literal> is a sufficient privilege then
just having this privilege on one resource is sufficient.
</para>
</sect2>
......@@ -308,11 +344,15 @@
<para>
To determine if a given user is allowed for a given
privilege (for a given resource), first
the <literal>RequiredPrivileges</literal> list is consulted
as described above. If the user possess all of the listed
privileges, the <literal>Allow</literal> list is now
consulted. For each element we it is tested whether the user
matches. If there are no elements for which the user is
the <literal>SufficientPrivileges</literal> list is
consulted as described above. If the user possesses one or
more of the listed privileges we're done; the user is
automatically allowed for the given privilege. If this is
not the case, the <literal>RequiredPrivileges</literal> list
is consulted as described above. If the user possess all of
the listed privileges, the <literal>Allow</literal> list is
now consulted. For each element it is tested whether the
user matches. If there are no elements for which the user is
matches, the user is said not to possess the given privilege
(for the given resource).
</para>
......@@ -378,22 +418,42 @@
</sect2>
<sect2>
<sect2 id="can-obtain">
<title><literal>CanObtain</literal>: Obtaining Privileges</title>
<para>
This property denotes whether an user can obtain the
privilege by authentication. It can assume the values
privilege by authentication. This is useful when either
either the privilege in question or one of the privileges
listed in <literal>RequiredPrivileges</literal> is not
possessed.
</para>
<para>
The property can assume the values
<literal>True</literal> (the user can obtain the privilege
permanently), <literal>Temporary</literal> (the user can
only obtain the privilege temporarily) and
<literal>False</literal> (the user can never obtain the
privilege through authentication).
privilege through authentication).
</para>
<para>
The authentication required are specified in
the <literal>ObtainRequireRoot</literal>
and <literal>ObtainPAMService</literal> properties.
Whether the user needs to autenticate as himself or the
super user is specified in
the <literal>ObtainRequireRoot</literal> property. Note that
if the user is lacking one or more of the privileges listed
in <literal>RequiredPrivileges</literal> and one of these
has <literal>ObtainRequireRoot=True</literal> the user will
have to authenticate as the super user nonwithstanding that
the privilege he attempts to obtain
has <literal>ObtainRequireRoot=False</literal>. Moreover, if
any of the lacking privileges
in <literal>RequiredPrivileges</literal>
has <literal>CanObtain</literal> set
to <literal>False</literal>, the user will always have to
authenticate as the super user.
</para>
</sect2>
<sect2>
......@@ -401,43 +461,166 @@
<para>
This property (it can assume the
values <literal>True</literal> and <literal>False</literal>)
describes whether an user with the given privilege can grant
it to other users, e.g. modify the <literal>Allow</literal>
and <literal>Deny</literal> properties.
describes whether an user with the given privilege can
permanently grant it to himself and/or other users,.
</para>
<para>
Typically, the construct is used in the following kind of UI
dialogs:
</para>
<programlisting>
+----------------------------------------------------+
| You are not privileged to access the volume |
| 'Dave's USB key'. You need to authenticate as the |
| system administrator |
| |
| Super user password: [_______________] |
| |
| Would you also like to automatically allow |
| |
| (*) This user to mount 'Dave's USB key' |
| ( ) Any user to mount 'Dave's USB key' |
| ( ) This user to mount a removable storage device |
| ( ) Any user to mount a removable storage device |
| |
| [Cancel] [Mount] |
+----------------------------------------------------+
(TODO: replace with screenshot from gnome-mount)
</programlisting>
<para>
The property <literal>CanObtain</literal> needs to have the
value <literal>True</literal> if this property assumes the
value <literal>True</literal>.
The property <literal>CanObtain</literal> needs to assume
the value <literal>True</literal> if this property assumes
the value <literal>True</literal>. Otherwise this property
effectively assumes the value <literal>False</literal>.
</para>
</sect2>
<sect2>
<title><literal>ObtainRequireRoot, ObtainPAMService</literal>: Authentication Requirements</title>
<title><literal>ObtainRequireRoot</literal>: Authentication Requirements</title>
<para>
If the property <literal>CanObtain</literal> assumes the
value <literal>True</literal>
or <literal>Temporary</literal> it means the user can
authenticate to gain a privilege.
authenticate to gain a
privilege. The <literal>ObtainRequireRoot</literal> property
specifies whether authentication requires the super user
password (<literal>True</literal>) or the users own password
(<literal>False</literal>).
</para>
<para>
The <literal>ObtainRequireRoot</literal> property specifies
whether authentication requires the super user password
(<literal>True</literal>) or the users own password
(<literal>False</literal>). In addition, it can be specified
what PAM service (for example <literal>pam_rps</literal>) is
to be used for authentication through the
property <literal>ObtainPAMService</literal>.
See <xref linkend="can-obtain"/> for discussion on how
the <literal>RequiredPrivileges</literal> property affects
the effective value of this property.
</para>
</sect2>
</sect1>
<sect1>
<sect1 id="privs-by-polkit">
<title>Privileges defined by PolicyKit</title>
<para>
baz
This section describe privileges defined by PolicyKit and how
they can be used by other pieces of software. Some privileges
have special meaning and affects how PolicyKit works.
</para>
<sect2 id="priv-desktop-console">
<title><literal>desktop-console</literal> : Users at a local console</title>
<programlisting>
desktop-console.privilege:
# This privilege signfies that users holding it are logged into a
# physical console attached to the system. Thus, it is useful for
# other privileges for manipulating local devices to simply require
# this privilege.
[Privilege]
RequiredPrivileges=
SufficientPrivileges=
Allow=
Deny=
CanObtain=Temporary
CanGrant=False
ObtainRequireRoot=True
</programlisting>
<para>
This privilege signifies that the user holding it is logged
in at a local console. In this context, "local console"
means that the display / keyboard / pointing device is local
to the system which implies the user got physical access to
the box.
</para>
<para>
The PAM module <literal>pam-polkit-console</literal> shipped
with PolicyKit is used to maintain files
in <literal>/var/run/polkit-console</literal> for users
logging in and out, and signal the PolicyKit daemon to
reread these files and dynamically grant / revoke
the <literal>desktop-console</literal> privilege. Typically,
graphical login managers such as the GNOME Display Manager
(gdm) will want include this in it's stack of PAM modules.
</para>
<para>
Remote users (e.g. those not at a local console) can obtain
the <literal>desktop-console</literal> only by
authenticating as the super user.
</para>
<para>
The <literal>desktop-console</literal> privilege can be used
in conjunction with
the <literal>RequiredPrivileges</literal> property in a
privilege descriptor to ensure only users at a local console
is entitled to a privilege for putting a system to sleep
without having to autenticate. This is achieved by e.g. this
privilege descriptor:
</para>
<programlisting>
hal-system-suspend.privilege:
# This privilege specifies who is allowed to suspend the system.
[Privilege]
RequiredPrivileges=desktop-console
SufficientPrivileges=
Allow=uid:__all__
Deny=
CanObtain=True
CanGrant=True
ObtainRequireRoot=False
</programlisting>
<para>
For a remote user with the
privilege <literal>hal-system-suspend</literal> it means
that authentication as the super user is required
as <literal>desktop-console</literal>
has <literal>ObtainRequireRoot=True</literal> and this
trumps the <literal>ObtainRequireRoot=False</literal>
property that is in
the <literal>hal-system-suspend</literal> privilege (see
<xref linkend="can-obtain"/>). Of course, if the user is
logged in at a local console no authentication is required.
</para>
<para>
Typically, the <literal>desktop-console</literal> privilege
is granted on a specific resource, namely what console the
user is logged into. At the time of writing, this resource
can only be consider an opaque identifier (such
as <literal>console://:0</literal> which refers to X11
display ":0") and one cannot assign meaning to it. In the
future, it may be possible to assign meaning to it.
</para>
</sect2>
</sect1>
</chapter>
......
......@@ -12,7 +12,7 @@ INCLUDES = \
@GLIB_CFLAGS@ \
@DBUS_GLIB_CFLAGS@
lib_LTLIBRARIES=libpolkit.la
lib_LTLIBRARIES=libpolkit.la libpolkit-grant.la
libpolkitincludedir=$(includedir)/libpolkit
......@@ -26,6 +26,29 @@ libpolkit_la_LIBADD = @DBUS_GLIB_LIBS@ @GLIB_LIBS@
libpolkit_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
libpolkit_grantincludedir=$(includedir)/libpolkit
libpolkit_grantinclude_HEADERS = \
libpolkit-grant.h
libpolkit_grant_la_SOURCES = \
libpolkit-grant.c libpolkit-grant.h \
polkit-interface-manager-glue.h \
polkit-interface-session-glue.h
libpolkit_grant_la_LIBADD = @DBUS_GLIB_LIBS@ @GLIB_LIBS@
libpolkit_grant_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
polkit-interface-manager-glue.h: ../polkit-interface-manager.xml Makefile.am
dbus-binding-tool --prefix=polkit_manager --mode=glib-client --output=polkit-interface-manager-glue.h ../polkit-interface-manager.xml
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
BUILT_SOURCES = polkit-interface-manager-glue.h polkit-interface-session-glue.h
clean-local :
rm -f *~
rm -f *~ $(BUILT_SOURCES)
/***************************************************************************
*
* libpolkit-grant.c : Wraps temporary grant methods on the PolicyKit daemon
*
* Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
*
* Licensed under the Academic Free License version 2.1
*
* 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>
#include "libpolkit-grant.h"
#include "polkit-interface-manager-glue.h"
#include "polkit-interface-session-glue.h"
struct LibPolKitGrantContext_s
{
DBusGConnection *dbus_g_connection;
char *user;
char *privilege;
char *resource;
gboolean restrict_to_dbus_connection;
LibPolKitGrantQuestions questions_handler;
LibPolKitGrantComplete grant_complete_handler;
char *auth_user;
char *auth_service_name;
DBusGProxy *manager;
DBusGProxy *session;
LibPolKitContext *polkit_ctx;
gpointer user_data;
};
static void
have_questions_handler (DBusGProxy *session, gpointer user_data)
{
char **questions;
GError *error = NULL;