Current File : //proc/thread-self/root/kunden/usr/share/gtk-doc/html/polkit-1/polkit-apps.html |
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Writing polkit applications: polkit Reference Manual</title>
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
<link rel="home" href="index.html" title="polkit Reference Manual">
<link rel="up" href="overview.html" title="Part I. polkit Overview">
<link rel="prev" href="polkit-intro.html" title="Introduction">
<link rel="next" href="polkit-agents.html" title="Writing polkit Authentication Agents">
<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
<td width="100%" align="left" class="shortcuts"></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
<td><a accesskey="u" href="overview.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
<td><a accesskey="p" href="polkit-intro.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
<td><a accesskey="n" href="polkit-agents.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
</tr></table>
<div class="chapter">
<div class="titlepage"><div><div><h2 class="title">
<a name="polkit-apps"></a>Writing polkit applications</h2></div></div></div>
<p>
polkit applications are applications using the polkit authority
as a decider component. They do this by installing a <code class="filename">.policy</code> file into the <code class="filename">/usr/share/polkit-1/actions</code>
directory and communicating with the polkit authority at runtime
(either via the <a class="link" href="ref-dbus-api.html" title="Part II. D-Bus API Reference">D-Bus API</a> or
indirectly through the <a class="link" href="ref-api.html" title="Part III. Library API Reference">libpolkit-gobject-1</a> library or the
<a class="link" href="pkcheck.1.html" title="pkcheck">pkcheck</a> command).
</p>
<div class="simplesect">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="polkit-apps-best-practices"></a>Best practices</h2></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: opencircle; ">
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DO</strong></span> use polkit if you are
writing a privileged mechanism (that is, running as
<span class="emphasis"><em>root</em></span> or otherwise has special
permissions) that is intended to be used by unprivileged
programs.
</p></li>
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DO</strong></span> carefully consider
what actions to define. In many cases there isn't a 1:1
mapping between operations and polkit actions. Often a
polkit action has more to do with the object the operation
is acting on than the operation itself. It is important to
strike the right balance between too fine-grained and too
coarse-grained.
</p></li>
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DO</strong></span> try to pick actions
and implicit authorizations so applications using your
mechanism will work out-of-the box for users logged in at
the console. Not interrupting console users with
authentication dialogs should be considered a
priority. For example, it is not wise to require console
users to authenticate for such mundane tasks as adding a
printer queue (if the administrator really wants the OS to
act this way, he can always deploy suitable authorization
rules).
</p></li>
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DO</strong></span> consider the impact of the
chosen implicit authorizations on multi-user systems. Generally,
ordinary users should be able to neither modify important system's
behavior for other users, nor view other users' private data. If
your application needs an authorization framework at all, it is
fairly likely that the default configuration should deny
authorization in at least some cases. Default to using
<code class="literal">auth_admin</code>* instead of
<code class="literal">auth_self</code>*. (On single-user desktops, the
single user is typically configured as a polkit administrator, so
the two variants behave equally. On multi-user systems,
non-administrator users will be restricted by the default
configuration.)
</p></li>
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DO</strong></span> pass polkit variables
along with <a class="link" href="eggdbus-interface-org.freedesktop.PolicyKit1.Authority.html#eggdbus-method-org.freedesktop.PolicyKit1.Authority.CheckAuthorization" title="CheckAuthorization ()">CheckAuthorization()</a>
requests so it's possible to write <span class="emphasis"><em>authorization
rules</em></span> matching on these. Also document these
variables in your documentation (for example, see the
<a class="ulink" href="http://udisks.freedesktop.org/docs/latest/udisks-polkit-actions.html" target="_top">udisks2
actions and variables</a>).
</p></li>
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DO</strong></span> pass a customized
authentication message (using the
<code class="literal">polkit.message</code> and
<code class="literal">polkit.gettext_domain</code> variables) that
include more detailed information about the request than
whatever is declared in the <code class="filename">.policy</code> file's
<code class="literal">message</code> element. For example, it's
better to show <span class="quote">“<span class="quote">Authentication is needed to format
INTEL SSDSA2MH080G1GC (/dev/sda)</span>”</span> than just
<span class="quote">“<span class="quote">Authentication is needed to format the
device</span>”</span>.
</p></li>
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DO</strong></span> make sure
your application works even when the
<code class="literal">org.freedesktop.PolicyKit1</code>
D-Bus service is not available (this can
happen if
<a class="link" href="polkitd.8.html" title="polkitd"><span class="citerefentry"><span class="refentrytitle">polkitd</span>(8)</span></a>
is not installed or if the <span class="emphasis"><em>polkit.service</em></span> systemd unit/service has been
<a class="ulink" href="http://0pointer.de/blog/projects/three-levels-of-off.html" target="_top">masked</a>). If you are using the
<a class="link" href="ref-api.html" title="Part III. Library API Reference">libpolkit-gobject-1</a> library this
means handling
<a class="link" href="PolkitAuthority.html#polkit-authority-get-sync" title="polkit_authority_get_sync ()">polkit_authority_get_sync()</a>
or
<a class="link" href="PolkitAuthority.html#polkit-authority-get-finish" title="polkit_authority_get_finish ()">polkit_authority_get_finish()</a>
returning <code class="constant">NULL</code> or
<a class="link" href="PolkitAuthority.html#polkit-authority-check-authorization" title="polkit_authority_check_authorization ()">polkit_authority_check_authorization()</a> /
<a class="link" href="PolkitAuthority.html#polkit-authority-check-authorization-sync" title="polkit_authority_check_authorization_sync ()">polkit_authority_check_authorization_sync()</a>
failing with an error not in the
<a class="link" href="polkit-1-PolkitError.html#POLKIT-ERROR:CAPS" title="POLKIT_ERROR">POLKIT_ERROR</a>
domain.
An appropriate way of dealing with the polkit authority
not being available, could be to allow only uid 0 to
perform operations, forbid all operations or something
else.
</p></li>
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DON'T</strong></span> use polkit if your
program isn't intended to be used by unprivileged
programs. For example, if you are writing developer tools
or low-level core OS command-line tools it's fine to just
require the user to be root. Users can always run your
tool through e.g.
<span class="citerefentry"><span class="refentrytitle">sudo</span>(8)</span>,
<a class="link" href="pkexec.1.html" title="pkexec"><span class="citerefentry"><span class="refentrytitle">pkexec</span>(1)</span></a>
or write a simple polkit-using mechanism that allows
access to a (safe) subset of your tool.
</p></li>
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DON'T</strong></span> use polkit unless
you actually have to. In other words, not every single
privileged program providing service to unprivileged
programs has to use polkit. For example, if you have a
small well-written <a class="ulink" href="http://en.wikipedia.org/wiki/Setuid" target="_top">setuid</a>
helper to help deal with some implementation-detail of the
OS (such as elevating the priority of the sound server
process to real-time for console users) it's not really
helpful to define a polkit action for this since,
realistically, no-one is going to choose to
<span class="emphasis"><em>not</em></span> grant the privilege. Remember, a
secure program is often one with little amount of code and
few dependencies.
</p></li>
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DON'T</strong></span> call <a class="link" href="eggdbus-interface-org.freedesktop.PolicyKit1.Authority.html#eggdbus-method-org.freedesktop.PolicyKit1.Authority.CheckAuthorization" title="CheckAuthorization ()">CheckAuthorization()</a>
for all your actions every time the authority emits the
<a class="link" href="eggdbus-interface-org.freedesktop.PolicyKit1.Authority.html#eggdbus-signal-org.freedesktop.PolicyKit1.Authority::Changed" title='The "Changed" signal'>Changed</a>
signal. Not only is this a waste of resources, the result
may also be inaccurate as authorization rules can return
whatever they want, whenever they want.
</p></li>
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DON'T</strong></span> block the main
thread in your mechanism (e.g. the one used to service IPC
requests from unprivileged programs) while waiting for the
authority to reply - calls to <a class="link" href="eggdbus-interface-org.freedesktop.PolicyKit1.Authority.html#eggdbus-method-org.freedesktop.PolicyKit1.Authority.CheckAuthorization" title="CheckAuthorization ()">CheckAuthorization()</a>
may take a very long time (seconds, even minutes) to
complete as user interaction may be involved. Instead,
use either the <a class="link" href="PolkitAuthority.html#polkit-authority-check-authorization" title="polkit_authority_check_authorization ()">asynchronous
API</a> or a dedicated thread with the <a class="link" href="PolkitAuthority.html#polkit-authority-check-authorization-sync" title="polkit_authority_check_authorization_sync ()">synchronous
API</a>.
</p></li>
<li class="listitem" style="list-style-type: circle"><p>
<span class="bold"><strong>DON'T</strong></span> include any
authorization rules with your application as this is only
intended for administrators and special-purpose operating
systems / environments. See <a class="xref" href="polkit.8.html#polkit-rules" title="AUTHORIZATION RULES">the section called “AUTHORIZATION RULES”</a>
for more information.
</p></li>
</ul></div>
</div>
<div class="simplesect">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="polkit-apps-unprivileged"></a>Usage in unprivileged programs</h2></div></div></div>
<p>
An unprivileged program normally does not use polkit directly
- it simply calls into a privileged mechanism and the
mechanism either renders service (or refuses the request)
after checking with polkit (which may include presenting an
authentication dialog). In this setup, the unprivileged
program is oblivious to the fact that polkit is being used -
it simply just waits for the privileged mechanism to carry out
the request (which, if authentication dialogs are involved may
take many seconds). This is a good thing because not worrying
about implementation details like polkit, helps simplify the
unprivileged program.
</p>
<p>
Occasionally unprivileged programs need to disable, modify or
remove UI elements to convey to the user that a certain action
cannot be carried out (because e.g. the user is not
authorized) or authentication is needed (by e.g. displaying a
padlock icon in the UI). In this case, the best approach is
usually to have the unprivileged program get this information
from the privileged mechanism instead of polkit. This is
especially true because often there is no reliable way that
the unprivileged program can know what polkit action is going
to be used. In general, there is no guarantee that operations
(such as D-Bus methods) map 1:1: to polkit action - for
example, a disk manager service's <code class="literal">Format()</code>
method may check for the action
<code class="literal">net.company.diskmanager.format-removable</code> if
the disk is removable and
<code class="literal">net.company.diskmanager.format-fixed</code>
otherwise.
</p>
<p>
However, in certain cases, for example when using the
<span class="emphasis"><em>org.freedesktop.policykit.imply</em></span> annotation
(see the
<a class="link" href="polkit.8.html" title="polkit"><span class="citerefentry"><span class="refentrytitle">polkit</span>(8)</span></a> man page),
it is meaningful for an unprivileged program to query the
polkit authority (to e.g. update UI elements) and it is
in fact allowed to do so as long as the unprivileged program doesn't pass any variables along with the
<a class="link" href="eggdbus-interface-org.freedesktop.PolicyKit1.Authority.html#eggdbus-method-org.freedesktop.PolicyKit1.Authority.CheckAuthorization" title="CheckAuthorization ()">CheckAuthorization()</a>
call (otherwise it would be easy to spoof authentication dialogs and bypass authorization rules).
In fact, since this use-case is so common,
<a class="link" href="ref-api.html" title="Part III. Library API Reference">libpolkit-gobject-1</a> provides the
<a class="link" href="PolkitPermission.html" title="PolkitPermission"><span class="type">PolkitPermission</span></a> type (which is derived from
<a class="ulink" href="http://developer.gnome.org/gio/unstable/GPermission.html" target="_top"><span class="type">GPermission</span></a>)
that can be used together with
<a class="ulink" href="http://developer.gnome.org/gtk3/unstable/GtkLockButton.html" target="_top"><span class="type">GtkLockButton</span></a>.
Note that for <span class="type">GtkLockButton</span> to work well, the
polkit action backing it should use <code class="literal">auth_admin_keep</code>
for its implicit authorizations (or more rarely
<code class="literal">auth_self_keep</code> for services which don't affect other
users).
This is often used to implement an <a class="ulink" href="http://developer.gnome.org/hig-book/3.2/hig-book.html#windows-instant-apply" target="_top">instant
apply</a> paradigm whereby the user
<span class="emphasis"><em>unlocks</em></span> (by authenticating) e.g. a
preference pane window and is then free to change settings
until the authorization expires or is revoked.
</p>
</div>
<div class="simplesect">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="polkit-apps-no-auth-agent"></a>No authentication agent</h2></div></div></div>
<p>
If a polkit application wants to handle the case where no
authentication agent exists (for example if the app is launched
via a
<span class="citerefentry"><span class="refentrytitle">ssh</span>(1)</span>
login), the application can use the <a class="link" href="PolkitAgentTextListener.html" title="PolkitAgentTextListener">PolkitAgentTextListener</a>
type to spawn its own authentication agent as
needed. Alternatively, the <a class="xref" href="pkttyagent.1.html" title="pkttyagent"><span class="refentrytitle">pkttyagent</span>(1)</a>
helper can be used to do this.
</p>
</div>
</div>
<div class="footer">
<hr>Generated by GTK-Doc V1.33.1</div>
</body>
</html>