![]() |
![]() |
![]() |
PolicyKit Library Reference Manual | ![]() |
---|---|---|---|---|
Caller DeterminationCaller Determination — Obtaining seat, session and caller information via D-Bus and ConsoleKit. |
PolKitSession* polkit_session_new_from_objpath (DBusConnection *con, const char *objpath, uid_t uid, DBusError *error); PolKitSession* polkit_session_new_from_cookie (DBusConnection *con, const char *cookie, DBusError *error); PolKitCaller* polkit_caller_new_from_dbus_name (DBusConnection *con, const char *dbus_name, DBusError *error); PolKitCaller* polkit_caller_new_from_pid (DBusConnection *con, pid_t pid, DBusError *error); polkit_bool_t polkit_is_authorization_relevant (DBusConnection *con, PolKitAuthorization *auth, DBusError *error); PolKitTracker; PolKitTracker* polkit_tracker_new (void); PolKitTracker* polkit_tracker_ref (PolKitTracker *pk_tracker); void polkit_tracker_unref (PolKitTracker *pk_tracker); void polkit_tracker_set_system_bus_connection (PolKitTracker *pk_tracker, DBusConnection *con); void polkit_tracker_init (PolKitTracker *pk_tracker); polkit_bool_t polkit_tracker_dbus_func (PolKitTracker *pk_tracker, DBusMessage *message); PolKitCaller* polkit_tracker_get_caller_from_dbus_name (PolKitTracker *pk_tracker, const char *dbus_name, DBusError *error); PolKitCaller* polkit_tracker_get_caller_from_pid (PolKitTracker *pk_tracker, pid_t pid, DBusError *error); polkit_bool_t polkit_tracker_is_authorization_relevant (PolKitTracker *pk_tracker, PolKitAuthorization *auth, DBusError *error);
Helper library for obtaining seat, session and caller information via D-Bus and ConsoleKit. This library is only useful when writing a mechanism.
If the mechanism itself is a daemon exposing a remote services via
the system message bus it's often a better idea, to reduce
roundtrips, to use the high-level PolKitTracker class rather than
the low-level functions polkit_caller_new_from_dbus_name()
and
polkit_caller_new_from_pid()
.
These functions are in libpolkit-dbus
.
PolKitSession* polkit_session_new_from_objpath (DBusConnection *con, const char *objpath, uid_t uid, DBusError *error);
This function will construct a PolKitSession object by querying
the ConsoleKit daemon for information. Note that this will do a lot
of blocking IO so it is best avoided if your process already
tracks/caches all the information. If you pass in uid
as a
non-negative number, a round trip can be saved.
This function is in libpolkit-dbus
.
|
D-Bus system bus connection |
|
object path of ConsoleKit session object |
|
the user owning the session or -1 if unknown |
|
D-Bus error |
Returns: |
the new object or NULL if an error occured (in which case
error will be set)
|
PolKitSession* polkit_session_new_from_cookie (DBusConnection *con, const char *cookie, DBusError *error);
This function will construct a PolKitSession object by querying the ConsoleKit daemon for information. Note that this will do a lot of blocking IO so it is best avoided if your process already tracks/caches all the information.
This function is in libpolkit-dbus
.
|
D-Bus system bus connection |
|
a ConsoleKit XDG_SESSION_COOKIE |
|
D-Bus error |
Returns: |
the new object or NULL if an error occured (in which case
error will be set)
|
PolKitCaller* polkit_caller_new_from_dbus_name (DBusConnection *con, const char *dbus_name, DBusError *error);
This function will construct a PolKitCaller object by querying both the system bus daemon and the ConsoleKit daemon for information. Note that this will do a lot of blocking IO so it is best avoided if your process already tracks/caches all the information. You can use the PolKitTracker class for this.
This function is in libpolkit-dbus
.
|
D-Bus system bus connection |
|
unique system bus connection name |
|
D-Bus error |
Returns: |
the new object or NULL if an error occured (in which case
error will be set)
|
PolKitCaller* polkit_caller_new_from_pid (DBusConnection *con, pid_t pid, DBusError *error);
This function will construct a PolKitCaller object by querying both information in /proc (on Linux) and the ConsoleKit daemon for information about a given process. Note that this will do a lot of blocking IO so it is best avoided if your process already tracks/caches all the information. You can use the PolKitTracker class for this.
This function is in libpolkit-dbus
.
|
D-Bus system bus connection |
|
process id |
|
D-Bus error |
Returns: |
the new object or NULL if an error occured (in which case
error will be set)
|
polkit_bool_t polkit_is_authorization_relevant (DBusConnection *con, PolKitAuthorization *auth, DBusError *error);
As explicit authorizations are scoped (process single shot, process, session or everything), they become irrelevant once the entity (process or session) ceases to exist. This function determines whether the authorization is still relevant; it's useful for reporting and graphical tools displaying authorizations.
Note that this may do blocking IO to check for session
authorizations so it is best avoided if your process already
tracks/caches all the information. You can use the
polkit_tracker_is_authorization_relevant()
method on the
PolKitTracker class for this.
|
D-Bus system bus connection |
|
authorization to check for |
|
return location for error |
Returns: |
TRUE if the authorization still applies, FALSE if an
error occurred (then error will be set) or if the entity the
authorization refers to has gone out of scope.
This function is in libpolkit-dbus .
|
Since 0.7
typedef struct _PolKitTracker PolKitTracker;
Instances of this class are used to cache information about callers; typically this is used in scenarios where the same caller is calling into a mechanism multiple times.
Thus, an application can use this class to get the PolKitCaller object; the class will listen to both NameOwnerChanged and ActivityChanged signals from the message bus and update / retire the PolKitCaller objects.
An example of how to use PolKitTracker is provided here. First, build the following program
/* * Small example of how to use the PolKitTracker class. * * Copyright (C) 2007 David Zeuthen, <david@fubar.dk> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #include <stdio.h> #include <glib.h> #include <dbus/dbus.h> #include <polkit-dbus/polkit-dbus.h> /* Note, on purpose, there is little or no error checking done * anywhere in this program. Use at your own risk. */ static void print_caller (PolKitTracker *pk_tracker, const char *dbus_name) { DBusError error; PolKitCaller *caller; dbus_error_init (&error); caller = polkit_tracker_get_caller_from_dbus_name (pk_tracker, dbus_name, &error); if (caller == NULL) { g_warning ("Error getting PolKitCaller for '%s': %s: %s", dbus_name, error.name, error.message); dbus_error_free (&error); } else { /* got it; print it to stdout */ printf ("\n"); polkit_caller_debug (caller); polkit_caller_unref (caller); } } static DBusHandlerResult filter (DBusConnection *connection, DBusMessage *message, void *user_data) { PolKitTracker *pk_tracker = (PolKitTracker *) user_data; char *name; char *new_service_name; char *old_service_name; /* pass NameOwnerChanged signals from the bus and ConsoleKit to PolKitTracker */ if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged") || g_str_has_prefix (dbus_message_get_interface (message), "org.freedesktop.ConsoleKit")) { polkit_tracker_dbus_func (pk_tracker, message); } /* handle calls into our test service */ if (dbus_message_is_method_call (message, "dk.fubar.PolKitTestService", "Test")) { DBusMessage *reply; const char *reply_str = "Right back at y'all!"; print_caller (pk_tracker, dbus_message_get_sender (message)); reply = dbus_message_new_method_return (message); dbus_message_append_args (reply, DBUS_TYPE_STRING, &reply_str, DBUS_TYPE_INVALID); dbus_connection_send (connection, reply, NULL); dbus_message_unref (reply); /* this one we do handle */ return DBUS_HANDLER_RESULT_HANDLED; } /* other filters might want to process this message too */ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } int main (int argc, char *argv[]) { DBusError error; DBusConnection *con; GMainLoop *loop; PolKitTracker *pk_tracker; /* This is needed to get something out of polkit_caller_debug() */ g_setenv ("POLKIT_DEBUG", "1", TRUE); loop = g_main_loop_new (NULL, FALSE); dbus_error_init (&error); con = dbus_bus_get (DBUS_BUS_SYSTEM, &error); pk_tracker = polkit_tracker_new (); polkit_tracker_set_system_bus_connection (pk_tracker, con); polkit_tracker_init (pk_tracker); /* need to listen to NameOwnerChanged */ dbus_bus_add_match (con, "type='signal'" ",interface='"DBUS_INTERFACE_DBUS"'" ",sender='"DBUS_SERVICE_DBUS"'" ",member='NameOwnerChanged'", &error); /* need to listen to ConsoleKit signals */ dbus_bus_add_match (con, "type='signal',sender='org.freedesktop.ConsoleKit'", &error); /* own a simple service */ dbus_bus_request_name (con, "dk.fubar.PolKitTestService", DBUS_NAME_FLAG_REPLACE_EXISTING, &error); dbus_connection_add_filter (con, filter, pk_tracker, NULL); dbus_connection_setup_with_g_main (con, g_main_loop_get_context (loop)); g_main_loop_run (loop); return 0; }
with
gcc -o tracker-example `pkg-config --cflags --libs dbus-glib-1 polkit-dbus` tracker-example.c
Then put the following content
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- --> <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <policy context="default"> <allow own="dk.fubar.PolKitTestService"/> </policy> </busconfig>
in the file /etc/dbus-1/system.d/dk.fubar.PolKitTestService.conf
. Finally,
create a small Python client like this
#!/usr/bin/python import dbus import time bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM) obj = dbus.Interface(bus.get_object("dk.fubar.PolKitTestService", "/"), "dk.fubar.PolKitTestService") while True: print obj.Test() time.sleep(1)
as tracker-example-client.py
. Now, run tracker-example
in one window and tracker-example-client
in another. The output of
the former should look like this
18:20:00.414: PolKitCaller: refcount=1 dbus_name=:1.473 uid=500 pid=8636 selinux_context=system_u:system_r:unconfined_t 18:20:00.414: PolKitSession: refcount=1 uid=0 objpath=/org/freedesktop/ConsoleKit/Session1 is_active=1 is_local=1 remote_host=(null) 18:20:00.414: PolKitSeat: refcount=1 objpath=/org/freedesktop/ConsoleKit/Seat1 18:20:01.424: PolKitCaller: refcount=1 dbus_name=:1.473 uid=500 pid=8636 selinux_context=system_u:system_r:unconfined_t 18:20:01.424: PolKitSession: refcount=1 uid=0 objpath=/org/freedesktop/ConsoleKit/Session1 is_active=1 is_local=1 remote_host=(null) 18:20:01.424: PolKitSeat: refcount=1 objpath=/org/freedesktop/ConsoleKit/Seat1 18:20:02.434: PolKitCaller: refcount=1 dbus_name=:1.473 uid=500 pid=8636 selinux_context=system_u:system_r:unconfined_t 18:20:02.434: PolKitSession: refcount=1 uid=0 objpath=/org/freedesktop/ConsoleKit/Session1 is_active=0 is_local=1 remote_host=(null) 18:20:02.434: PolKitSeat: refcount=1 objpath=/org/freedesktop/ConsoleKit/Seat1 18:20:03.445: PolKitCaller: refcount=1 dbus_name=:1.473 uid=500 pid=8636 selinux_context=system_u:system_r:unconfined_t 18:20:03.445: PolKitSession: refcount=1 uid=0 objpath=/org/freedesktop/ConsoleKit/Session1 is_active=1 is_local=1 remote_host=(null) 18:20:03.445: PolKitSeat: refcount=1 objpath=/org/freedesktop/ConsoleKit/Seat1
The point of the test program is simply to gather caller
information about clients (the small Python program, you may launch
multiple instances of it) that repeatedly calls into the D-Bus
service; if one runs strace(1)
in front of the
test program one will notice that there is only syscall / IPC
overhead (except for printing to stdout) on the first call from the
client.
The careful reader will notice that, during the testing session, we did a quick VT switch away from the session (and back) which is reflected in the output.
These functions are in libpolkit-dbus
.
PolKitTracker* polkit_tracker_new (void);
Creates a new PolKitTracker object.
This function is in libpolkit-dbus
.
Returns: |
the new object |
Since 0.7
PolKitTracker* polkit_tracker_ref (PolKitTracker *pk_tracker);
Increase reference count.
This function is in libpolkit-dbus
.
|
the tracker object |
Returns: |
the object |
Since 0.7
void polkit_tracker_unref (PolKitTracker *pk_tracker);
Decreases the reference count of the object. If it becomes zero, the object is freed. Before freeing, reference counts on embedded objects are decresed by one.
This function is in libpolkit-dbus
.
|
the tracker object |
Since 0.7
void polkit_tracker_set_system_bus_connection (PolKitTracker *pk_tracker, DBusConnection *con);
Tell the PolKitTracker object to use the given D-Bus connection when it needs to fetch information from the system message bus and ConsoleKit services. This is used for priming the cache.
This function is in libpolkit-dbus
.
|
the tracker object |
|
the connection to the system message bus |
Since 0.7
void polkit_tracker_init (PolKitTracker *pk_tracker);
Initialize the tracker.
This function is in libpolkit-dbus
.
|
the tracker object |
Since 0.7
polkit_bool_t polkit_tracker_dbus_func (PolKitTracker *pk_tracker, DBusMessage *message);
The owner of the PolKitTracker object must pass signals from the system message bus (just NameOwnerChanged will do) and all signals from the ConsoleKit service into this function.
This function is in libpolkit-dbus
.
|
the tracker object |
|
message to pass |
Returns: |
TRUE only if there was a change in the ConsoleKit database. |
Since 0.7
PolKitCaller* polkit_tracker_get_caller_from_dbus_name (PolKitTracker *pk_tracker, const char *dbus_name, DBusError *error);
This function is similar to polkit_caller_new_from_dbus_name()
except that it uses the cache in PolKitTracker. So on the second
and subsequent calls, for the same D-Bus name, there will be no
syscall or IPC overhead in calling this function.
|
the tracker object |
|
unique name on the system message bus |
|
D-Bus error |
Returns: |
A PolKitCaller object; the caller must use
polkit_caller_unref() on the object when done with it. Returns
NULL if an error occured (in which case error will be set).
This function is in libpolkit-dbus .
|
Since 0.7
PolKitCaller* polkit_tracker_get_caller_from_pid (PolKitTracker *pk_tracker, pid_t pid, DBusError *error);
This function is similar to polkit_caller_new_from_pid()
except that it uses the cache in PolKitTracker. So on the second
and subsequent calls, for the same D-Bus name, there will be no
IPC overhead in calling this function.
There will be some syscall overhead to lookup the time when the given process is started (on Linux, looking up /proc/$pid/stat); this is needed because pid's can be recycled and the cache thus needs to record this in addition to the pid.
|
the tracker object |
|
UNIX process id to look at |
|
D-Bus error |
Returns: |
A PolKitCaller object; the caller must use
polkit_caller_unref() on the object when done with it. Returns
NULL if an error occured (in which case error will be set).
This function is in libpolkit-dbus .
|
Since 0.7
polkit_bool_t polkit_tracker_is_authorization_relevant (PolKitTracker *pk_tracker, PolKitAuthorization *auth, DBusError *error);
As explicit authorizations are scoped (process single shot, process, session or everything), they become irrelevant once the entity (process or session) ceases to exist. This function determines whether the authorization is still relevant; it's useful for reporting and graphical tools displaying authorizations.
This function is similar to polkit_is_authorization_relevant()
only
that it avoids IPC overhead on the 2nd and subsequent calls when
checking authorizations scoped for a session.
|
the tracker |
|
authorization to check for |
|
return location for error |
Returns: |
TRUE if the authorization still applies, FALSE if an
error occurred (then error will be set) or if the entity the
authorization refers to has gone out of scope.
This function is in libpolkit-dbus .
|
Since 0.7