PolicyKit: Branch 'master'
David Zeuthen
david at kemper.freedesktop.org
Sat Apr 7 23:07:49 PDT 2007
Makefile.am | 2
configure.in | 4
doc/api/libpolkit/libpolkit-docs.xml | 2
doc/man/Makefile.am | 4
doc/man/PolicyKit.8.in | 38 ++
doc/man/polkit-check-caller.1.in | 1
doc/man/polkit-check-session.1.in | 1
doc/man/polkit-module-allow-all.8.in | 61 +++
doc/man/polkit-module-default.8.in | 39 ++
doc/man/polkit-module-deny-all.8.in | 60 +++
doc/man/polkit-privilege-file-validate.1.in | 1
libpolkit/Makefile.am | 11
libpolkit/libpolkit-context.c | 443 ++++++++++++++++++++++++-
libpolkit/libpolkit-context.h | 50 ++
libpolkit/libpolkit-debug.c | 10
libpolkit/libpolkit-module.c | 490 ++++++++++++++++++++++++++++
libpolkit/libpolkit-module.h | 192 ++++++++++
libpolkit/libpolkit-result.c | 4
libpolkit/libpolkit-result.h | 9
libpolkit/libpolkit.c | 219 ------------
libpolkit/libpolkit.h | 46 --
modules/Makefile.am | 5
modules/PolicyKit.conf | 5
modules/allow-all/Makefile.am | 25 +
modules/allow-all/polkit-module-allow-all.c | 241 +++++++++++++
modules/default/Makefile.am | 25 +
modules/default/polkit-module-default.c | 116 ++++++
modules/deny-all/Makefile.am | 25 +
tools/polkit-check-caller.c | 2
tools/polkit-check-session.c | 2
30 files changed, 1842 insertions(+), 291 deletions(-)
New commits:
diff-tree 3638c6c15eb33ec64559dc9f075c3f82f9cbcb66 (from a1b5a12bd768c2d34d33c24af1853a424b875527)
Author: David Zeuthen <davidz at redhat.com>
Date: Sun Apr 8 02:07:42 2007 -0400
add module loading to PolicyKit
This paves the way for writing
1. A module that tracks temporary (look in /var/run) and permanent (look
in /var/lib) privilege grants
2. A D-Bus service to authenticate a client to obtain to a privilege
grant and then writing the grant in temporary or permanent storage
Also, this feature lets people very easily lock down the system; just
edit /etc/PolicyKit/PolicyKit.conf; add pam-module-deny-all / -allow-all
stanzas with various privilege=<regexp> and user=<username> options.
diff --git a/Makefile.am b/Makefile.am
index 6e481ed..9c313f1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
-SUBDIRS = libpolkit doc tools privileges
+SUBDIRS = libpolkit modules doc tools privileges
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libpolkit.pc
diff --git a/configure.in b/configure.in
index 7af5deb..25fc9af 100644
--- a/configure.in
+++ b/configure.in
@@ -174,6 +174,10 @@ doc/spec/Makefile
doc/spec/polkit-spec.xml.in
doc/man/Makefile
privileges/Makefile
+modules/Makefile
+modules/default/Makefile
+modules/allow-all/Makefile
+modules/deny-all/Makefile
])
dnl ==========================================================================
diff --git a/doc/api/libpolkit/libpolkit-docs.xml b/doc/api/libpolkit/libpolkit-docs.xml
index 1c9d355..7909e91 100644
--- a/doc/api/libpolkit/libpolkit-docs.xml
+++ b/doc/api/libpolkit/libpolkit-docs.xml
@@ -64,7 +64,6 @@
PolicyKit library.
</para>
</partintro>
- <xi:include href="xml/libpolkit.xml"/>
<xi:include href="xml/libpolkit-error.xml"/>
<xi:include href="xml/libpolkit-result.xml"/>
<xi:include href="xml/libpolkit-context.xml"/>
@@ -77,6 +76,7 @@
<xi:include href="xml/libpolkit-seat.xml"/>
<xi:include href="xml/libpolkit-session.xml"/>
<xi:include href="xml/libpolkit-caller.xml"/>
+ <xi:include href="xml/libpolkit-module.xml"/>
</reference>
<index>
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
index 5b99a1f..93de521 100644
--- a/doc/man/Makefile.am
+++ b/doc/man/Makefile.am
@@ -1,7 +1,7 @@
if MAN_PAGES_ENABLED
-MAN_IN_FILES = polkit-check-caller.1.in polkit-check-session.1.in polkit-privilege-file-validate.1.in
+MAN_IN_FILES = polkit-check-caller.1.in polkit-check-session.1.in polkit-privilege-file-validate.1.in PolicyKit.8.in polkit-module-default.8.in polkit-module-allow-all.8.in polkit-module-deny-all.8.in
man_MANS = $(MAN_IN_FILES:.in=)
@@ -10,7 +10,7 @@ endif # MAN_PAGES_ENABLED
EXTRA_DIST=$(man_MANS) $(MAN_IN_FILES)
clean-local:
- rm -f *~ *.1
+ rm -f *~ *.1 *.8
%: %.in Makefile
$(edit) $< >$@
diff --git a/doc/man/PolicyKit.8.in b/doc/man/PolicyKit.8.in
new file mode 100644
index 0000000..ca427e3
--- /dev/null
+++ b/doc/man/PolicyKit.8.in
@@ -0,0 +1,38 @@
+.\"
+.\" PolicyKit manual page.
+.\" Copyright (C) 2007 David Zeuthen <david at fubar.dk>
+.\"
+.TH POLICYKIT 8
+.SH NAME
+PolicyKit \- centralized policy management
+.SH DESCRIPTION
+.PP
+
+For more information about the big picture refer to the \fIPolicyKit
+spec\fP which can be found in
+.I "@docdir@/spec/polkit-spec.html"
+depending on the distribution.
+
+.SH BUGS
+.PP
+Please send bug reports to either the distribution or the HAL
+mailing list, see
+.I "http://lists.freedesktop.org/mailman/listinfo/hal"
+on how to subscribe.
+
+.SH SEE ALSO
+.PP
+\&\fIpolkit-module-default\fR\|(8),
+\&\fIpolkit-module-allow-all\fR\|(8),
+\&\fIpolkit-module-deny-all\fR\|(8),
+\&\fIpolkit-check-caller\fR\|(1),
+\&\fIpolkit-check-session\fR\|(1),
+\&\fIpolkit-privilege-file-validate\fR\|(1),
+\&\fIdbus-daemon\fR\|(1),
+\&\fIhald\fR\|(8)
+
+
+.SH AUTHOR
+Written by David Zeuthen <david at fubar.dk> with a lot of help from many
+others.
+
diff --git a/doc/man/polkit-check-caller.1.in b/doc/man/polkit-check-caller.1.in
index 0992d9b..fe67d4d 100644
--- a/doc/man/polkit-check-caller.1.in
+++ b/doc/man/polkit-check-caller.1.in
@@ -56,6 +56,7 @@ on how to subscribe.
.SH SEE ALSO
.PP
+\&\fIPolicyKit\fR\|(8),
\&\fIdbus-daemon\fR\|(1),
\&\fIpolkit-check-session\fR\|(1)
diff --git a/doc/man/polkit-check-session.1.in b/doc/man/polkit-check-session.1.in
index b364104..cab454c 100644
--- a/doc/man/polkit-check-session.1.in
+++ b/doc/man/polkit-check-session.1.in
@@ -56,6 +56,7 @@ on how to subscribe.
.SH SEE ALSO
.PP
+\&\fIPolicyKit\fR\|(8),
\&\fIdbus-daemon\fR\|(1),
\&\fIpolkit-check-caller\fR\|(1)
diff --git a/doc/man/polkit-module-allow-all.8.in b/doc/man/polkit-module-allow-all.8.in
new file mode 100644
index 0000000..decd097
--- /dev/null
+++ b/doc/man/polkit-module-allow-all.8.in
@@ -0,0 +1,61 @@
+.\"
+.\" polkit-module-allow-all manual page.
+.\" Copyright (C) 2007 David Zeuthen <david at fubar.dk>
+.\"
+.TH POLKIT-MODULE-ALLOW-ALL 8
+.SH NAME
+polkit-module-allow-all \- grant access to all privileges
+.SH SYNOPSIS
+.PP
+.B polkit-module-allow-all.so [privilege=<regexp>] [user=<username>]
+.SH DESCRIPTION
+.PP
+This PolicyKit module will allow access to any privilege regardless of
+the entity requesting it, what the requested privilege is and what
+resource is involved.
+
+For more information about the big picture refer to the \fIPolicyKit
+spec\fP which can be found in
+.I "@docdir@/spec/polkit-spec.html"
+depending on the distribution.
+
+.SH OPTIONS
+
+.TP 3n
+.B privilege=<regexp>
+Only consider requests where the privilege name matches the given
+regular expression. Example:
+.B privilege=hal-storage-mount*
+
+.TP 3n
+.B user=<username>
+Only consider requests matching the given username. May be both a
+numerical
+.B uid
+value or a username. Example:
+.B user=davidz
+
+.SH NOTES
+.PP
+Never use this module unless you
+.B COMPLETELY
+trust anyone with either remote or local access to the system.
+
+.SH BUGS
+.PP
+Please send bug reports to either the distribution or the HAL
+mailing list, see
+.I "http://lists.freedesktop.org/mailman/listinfo/hal"
+on how to subscribe.
+
+.SH SEE ALSO
+.PP
+\&\fIPolicyKit\fR\|(8),
+\&\fIpolkit-module-default\fR\|(8),
+\&\fIpolkit-module-deny-all\fR\|(8),
+\&\fI at sysconfdir@/PolicyKit/privileges\fR\|,
+\&\fI at sysconfdir@/PolicyKit/PolicyKit.conf\fR\|
+
+.SH AUTHOR
+Written by David Zeuthen <david at fubar.dk> with a lot of help from many
+others.
diff --git a/doc/man/polkit-module-default.8.in b/doc/man/polkit-module-default.8.in
new file mode 100644
index 0000000..379d332
--- /dev/null
+++ b/doc/man/polkit-module-default.8.in
@@ -0,0 +1,39 @@
+.\"
+.\" polkit-module-default manual page.
+.\" Copyright (C) 2007 David Zeuthen <david at fubar.dk>
+.\"
+.TH POLKIT-MODULE-DEFAULT 8
+.SH NAME
+polkit-module-default \- use default policy for privileges
+.SH SYNOPSIS
+.PP
+.B standard polkit-module-default.so
+.SH DESCRIPTION
+.PP
+This PolicyKit module uses the default policy as specified (and
+required) for by the privilege definition file for a given privilege.
+
+For more information about the big picture refer to the \fIPolicyKit
+spec\fP which can be found in
+.I "@docdir@/spec/polkit-spec.html"
+depending on the distribution.
+
+.SH BUGS
+.PP
+Please send bug reports to either the distribution or the HAL
+mailing list, see
+.I "http://lists.freedesktop.org/mailman/listinfo/hal"
+on how to subscribe.
+
+.SH SEE ALSO
+.PP
+\&\fIPolicyKit\fR\|(8),
+\&\fIpolkit-module-allow-all\fR\|(8),
+\&\fIpolkit-module-deny-all\fR\|(8),
+\&\fI at sysconfdir@/PolicyKit/privileges\fR\|,
+\&\fI at sysconfdir@/PolicyKit/PolicyKit.conf\fR\|
+
+.SH AUTHOR
+Written by David Zeuthen <david at fubar.dk> with a lot of help from many
+others.
+
diff --git a/doc/man/polkit-module-deny-all.8.in b/doc/man/polkit-module-deny-all.8.in
new file mode 100644
index 0000000..feee066
--- /dev/null
+++ b/doc/man/polkit-module-deny-all.8.in
@@ -0,0 +1,60 @@
+.\"
+.\" polkit-module-deny-all manual page.
+.\" Copyright (C) 2007 David Zeuthen <david at fubar.dk>
+.\"
+.TH POLKIT-MODULE-DENY-ALL 8
+.SH NAME
+polkit-module-deny-all \- grant access to all privileges
+.SH SYNOPSIS
+.PP
+.B polkit-module-deny-all.so [privilege=<regexp>] [user=<username>]
+.SH DESCRIPTION
+.PP
+This PolicyKit module will deny access to any privilege regardless of
+the entity requesting it, what the requested privilege is and what
+resource is involved.
+
+For more information about the big picture refer to the \fIPolicyKit
+spec\fP which can be found in
+.I "@docdir@/spec/polkit-spec.html"
+depending on the distribution.
+
+.SH OPTIONS
+
+.TP 3n
+.B privilege=<regexp>
+Only consider requests where the privilege name matches the given
+regular expression. Example:
+.B privilege=hal-storage-mount*
+
+.TP 3n
+.B user=<username>
+Only consider requests matching the given username. May be both a
+numerical
+.B uid
+value or a username. Example:
+.B user=davidz
+
+.SH NOTES
+.PP
+This module is mostly useful in situations where it's desirable to
+lock down the system so it's unusable by normal unprivileged users.
+
+.SH BUGS
+.PP
+Please send bug reports to either the distribution or the HAL
+mailing list, see
+.I "http://lists.freedesktop.org/mailman/listinfo/hal"
+on how to subscribe.
+
+.SH SEE ALSO
+.PP
+\&\fIPolicyKit\fR\|(8),
+\&\fIpolkit-module-default\fR\|(8),
+\&\fIpolkit-module-allow-all\fR\|(8),
+\&\fI at sysconfdir@/PolicyKit/privileges\fR\|,
+\&\fI at sysconfdir@/PolicyKit/PolicyKit.conf\fR\|
+
+.SH AUTHOR
+Written by David Zeuthen <david at fubar.dk> with a lot of help from many
+others.
diff --git a/doc/man/polkit-privilege-file-validate.1.in b/doc/man/polkit-privilege-file-validate.1.in
index 035f881..8a02f66 100644
--- a/doc/man/polkit-privilege-file-validate.1.in
+++ b/doc/man/polkit-privilege-file-validate.1.in
@@ -43,6 +43,7 @@ on how to subscribe.
.SH SEE ALSO
.PP
+\&\fIPolicyKit\fR\|(8),
\&\fIpolkit-check-caller\fR\|(1),
\&\fIpolkit-check-session\fR\|(1)
diff --git a/libpolkit/Makefile.am b/libpolkit/Makefile.am
index 244e21e..5961d9b 100644
--- a/libpolkit/Makefile.am
+++ b/libpolkit/Makefile.am
@@ -8,6 +8,7 @@ INCLUDES = \
-DPACKAGE_BIN_DIR=\""$(bindir)"\" \
-DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -DPACKAGE_LIB_DIR=\""$(libdir)"\" \
-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
@GLIB_CFLAGS@ @DBUS_CFLAGS@
@@ -28,10 +29,11 @@ libpolkitinclude_HEADERS =
libpolkit-privilege-file-entry.h \
libpolkit-privilege-file.h \
libpolkit-privilege-cache.h \
- libpolkit-privilege-default.h
+ libpolkit-privilege-default.h \
+ libpolkit-module.h
libpolkit_la_SOURCES = \
- libpolkit.h libpolkit.c \
+ libpolkit.h \
libpolkit-error.h libpolkit-error.c \
libpolkit-result.h libpolkit-result.c \
libpolkit-context.h libpolkit-context.c \
@@ -44,9 +46,10 @@ libpolkit_la_SOURCES =
libpolkit-privilege-file.h libpolkit-privilege-file.c \
libpolkit-privilege-cache.h libpolkit-privilege-cache.c \
libpolkit-privilege-default.h libpolkit-privilege-default.c \
- libpolkit-debug.h libpolkit-debug.c
+ libpolkit-debug.h libpolkit-debug.c \
+ libpolkit-module.h libpolkit-module.c
-libpolkit_la_LIBADD = @GLIB_LIBS@ @DBUS_LIBS@
+libpolkit_la_LIBADD = @GLIB_LIBS@ @DBUS_LIBS@ -ldl
libpolkit_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
diff --git a/libpolkit/libpolkit-context.c b/libpolkit/libpolkit-context.c
index 2a05fbe..5dcc5b2 100644
--- a/libpolkit/libpolkit-context.c
+++ b/libpolkit/libpolkit-context.c
@@ -40,6 +40,7 @@
#include "libpolkit-debug.h"
#include "libpolkit-context.h"
#include "libpolkit-privilege-cache.h"
+#include "libpolkit-module.h"
/**
* SECTION:libpolkit-context
@@ -66,6 +67,8 @@ struct PolKitContext
char *priv_dir;
PolKitPrivilegeCache *priv_cache;
+
+ GSList *modules;
};
/**
@@ -84,6 +87,147 @@ libpolkit_context_new (void)
return pk_context;
}
+static gboolean
+unload_modules (PolKitContext *pk_context)
+{
+ GSList *i;
+ for (i = pk_context->modules; i != NULL; i = g_slist_next (i)) {
+ PolKitModuleInterface *module_interface = i->data;
+ libpolkit_module_interface_unref (module_interface);
+ }
+ g_slist_free (pk_context->modules);
+ pk_context->modules = NULL;
+ _pk_debug ("Unloaded modules");
+
+ return TRUE;
+}
+
+static gboolean
+load_modules (PolKitContext *pk_context, GError **error)
+{
+ const char *config_file;
+ gboolean ret;
+ char *buf;
+ char *end;
+ char line[256];
+ char *p;
+ char *q;
+ gsize len;
+ int line_number;
+ int mod_number;
+
+ ret = FALSE;
+ buf = NULL;
+ mod_number = 0;
+
+ config_file = PACKAGE_SYSCONF_DIR "/PolicyKit/PolicyKit.conf";
+ if (!g_file_get_contents (config_file,
+ &buf,
+ &len,
+ error)) {
+ _pk_debug ("Cannot load PolicyKit configuration file at '%s'", config_file);
+ goto out;
+ }
+
+ end = buf + len;
+
+ /* parse the config file; one line at a time (yes, this is super ugly code) */
+ p = buf;
+ line_number = -1;
+ while (TRUE) {
+ int argc;
+ char **tokens;
+ char *module_name;
+ char *module_path;
+ PolKitModuleControl module_control;
+ PolKitModuleInterface *module_interface;
+
+ line_number++;
+
+ q = p;
+ while (*q != '\n' && q != '\0' && q < end)
+ q++;
+ if (*q == '\0' || q >= end) {
+ /* skip last line if it's not terminated by whitespace */
+ break;
+ }
+ if ((unsigned int) (q - p) > sizeof(line) - 1) {
+ _pk_debug ("Line is too long; skipping it");
+ continue;
+ }
+ strncpy (line, p, q - p);
+ line[q - p] = '\0';
+ p = q + 1;
+
+ /* remove leading and trailing white space */
+ g_strstrip (line);
+
+ /* comments, blank lines are fine; just skip them */
+ if (line[0] == '#' || strlen (line) == 0) {
+ continue;
+ }
+
+ /*_pk_debug ("Looking at line: '%s'", line);*/
+
+ if (!g_shell_parse_argv (line, &argc, &tokens, NULL)) {
+ _pk_debug ("Cannot parse line %d - skipping", line_number);
+ continue;
+ }
+ if (argc < 2) {
+ _pk_debug ("Line %d is malformed - skipping line", line_number);
+ g_strfreev (tokens);
+ continue;
+ }
+ if (!libpolkit_module_control_from_string_representation (tokens[0], &module_control)) {
+ _pk_debug ("Unknown module_control '%s' at line %d - skipping line", tokens[0], line_number);
+ g_strfreev (tokens);
+ continue;
+ }
+ module_name = tokens[1];
+
+ module_path = g_strdup_printf (PACKAGE_LIB_DIR "/PolicyKit/modules/%s", module_name);
+ _pk_debug ("MODULE: number=%d control=%d name=%s argc=%d",
+ mod_number, module_control, module_name, argc - 1);
+ module_interface = libpolkit_module_interface_load_module (module_path,
+ module_control,
+ argc - 1,
+ tokens + 1);
+ g_free (module_path);
+
+ if (module_interface != NULL) {
+ pk_context->modules = g_slist_append (pk_context->modules, module_interface);
+ mod_number++;
+ }
+ g_strfreev (tokens);
+
+ }
+
+ ret = TRUE;
+
+out:
+ if (buf != NULL)
+ g_free (buf);
+
+ _pk_debug ("Loaded %d modules in total", mod_number);
+ return ret;
+}
+
+static void
+_config_file_events (PolKitContext *pk_context,
+ PolKitContextFileMonitorEvent event_mask,
+ const char *path,
+ gpointer user_data)
+{
+ _pk_debug ("Config file changed");
+ unload_modules (pk_context);
+ load_modules (pk_context, NULL);
+
+ /* signal that our configuration (may have) changed */
+ if (pk_context->config_changed_cb) {
+ pk_context->config_changed_cb (pk_context, pk_context->config_changed_user_data);
+ }
+}
+
static void
_privilege_dir_events (PolKitContext *pk_context,
PolKitContextFileMonitorEvent event_mask,
@@ -117,11 +261,8 @@ _privilege_dir_events (PolKitContext
gboolean
libpolkit_context_init (PolKitContext *pk_context, GError **error)
{
- gboolean ret;
const char *dirname;
- ret = FALSE;
-
dirname = getenv ("POLKIT_PRIVILEGE_DIR");
if (dirname != NULL) {
pk_context->priv_dir = g_strdup (dirname);
@@ -130,11 +271,16 @@ libpolkit_context_init (PolKitContext *p
}
_pk_debug ("Using privilege files from directory %s", pk_context->priv_dir);
+ /* Load modules */
+ if (!load_modules (pk_context, error))
+ goto error;
+
/* don't populate the cache until it's needed.. */
if (pk_context->file_monitor_add_watch_func == NULL) {
_pk_debug ("No file monitor; cannot monitor '%s' for .priv file changes", dirname);
} else {
+ /* Watch when privilege definitions file change */
pk_context->file_monitor_add_watch_func (pk_context,
pk_context->priv_dir,
POLKIT_CONTEXT_FILE_MONITOR_EVENT_CREATE|
@@ -142,12 +288,23 @@ libpolkit_context_init (PolKitContext *p
POLKIT_CONTEXT_FILE_MONITOR_EVENT_CHANGE,
_privilege_dir_events,
NULL);
+
+ /* Config file changes */
+ pk_context->file_monitor_add_watch_func (pk_context,
+ PACKAGE_SYSCONF_DIR "/PolicyKit",
+ POLKIT_CONTEXT_FILE_MONITOR_EVENT_CREATE|
+ POLKIT_CONTEXT_FILE_MONITOR_EVENT_DELETE|
+ POLKIT_CONTEXT_FILE_MONITOR_EVENT_CHANGE,
+ _config_file_events,
+ NULL);
}
- /* right now we can't fail - but in the future modules we load may */
+ return TRUE;
+error:
+ if (pk_context != NULL)
+ libpolkit_context_unref (pk_context);
- ret = TRUE;
- return ret;
+ return FALSE;
}
/**
@@ -177,10 +334,14 @@ libpolkit_context_ref (PolKitContext *pk
void
libpolkit_context_unref (PolKitContext *pk_context)
{
+
g_return_if_fail (pk_context != NULL);
pk_context->refcount--;
if (pk_context->refcount > 0)
return;
+
+ unload_modules (pk_context);
+
g_free (pk_context);
}
@@ -263,3 +424,273 @@ libpolkit_context_get_privilege_cache (P
return pk_context->priv_cache;
}
+
+
+/**
+ * libpolkit_context_get_seat_resource_association:
+ * @pk_context: the PolicyKit context
+ * @visitor: visitor function
+ * @user_data: user data
+ *
+ * Retrieve information about what resources are associated to what
+ * seats. Note that a resource may be associated to more than one
+ * seat. This information stems from user configuration and consumers
+ * of this information that know better (e.g. HAL) may choose to
+ * override it.
+ *
+ * Typically, this information is used to e.g. bootstrap the system
+ * insofar that it can be used to start login greeters on the given
+ * video hardware (e.g. resources) on the given user-configured seats.
+ *
+ * If a resource is not associated with any seat, it is assumed to be
+ * available to any local seat.
+ *
+ * Returns: A #PolKitResult - can only be one of
+ * #LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW or
+ * #LIBPOLKIT_RESULT_YES (if the callback was invoked)
+ */
+PolKitResult
+libpolkit_context_get_seat_resource_association (PolKitContext *pk_context,
+ PolKitSeatVisitorCB visitor,
+ gpointer *user_data)
+{
+ return LIBPOLKIT_RESULT_YES;
+}
+
+/**
+ * libpolkit_context_is_resource_associated_with_seat:
+ * @pk_context: the PolicyKit context
+ * @resource: the resource in question
+ * @seat: the seat
+ *
+ * Determine if a given resource is associated with a given seat. The
+ * same comments noted in libpolkit_get_seat_resource_association() about the
+ * source purely being user configuration applies here as well.
+ *
+ * Returns: A #PolKitResult - can only be one of
+ * #LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW,
+ * #LIBPOLKIT_RESULT_YES, #LIBPOLKIT_RESULT_NO.
+ */
+PolKitResult
+libpolkit_context_is_resource_associated_with_seat (PolKitContext *pk_context,
+ PolKitResource *resource,
+ PolKitSeat *seat)
+{
+ return LIBPOLKIT_RESULT_NO;
+}
+
+/**
+ * libpolkit_context_can_session_access_resource:
+ * @pk_context: the PolicyKit context
+ * @privilege: the type of access to check for
+ * @resource: the resource in question
+ * @session: the session in question
+ *
+ * Determine if a given session can access a given resource in a given way.
+ *
+ * Returns: A #PolKitResult - can only be one of
+ * #LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW,
+ * #LIBPOLKIT_RESULT_YES, #LIBPOLKIT_RESULT_NO.
+ */
+PolKitResult
+libpolkit_context_can_session_access_resource (PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitSession *session)
+{
+ PolKitPrivilegeCache *cache;
+ PolKitPrivilegeFileEntry *pfe;
+ PolKitResult current_result;
+ PolKitModuleControl current_control;
+ GSList *i;
+
+ current_result = LIBPOLKIT_RESULT_NO;
+
+ cache = libpolkit_context_get_privilege_cache (pk_context);
+ if (cache == NULL)
+ goto out;
+
+ _pk_debug ("entering libpolkit_can_session_access_resource()");
+ libpolkit_privilege_debug (privilege);
+ libpolkit_resource_debug (resource);
+ libpolkit_session_debug (session);
+
+ pfe = libpolkit_privilege_cache_get_entry (cache, privilege);
+ if (pfe == NULL) {
+ char *privilege_name;
+ if (!libpolkit_privilege_get_privilege_id (privilege, &privilege_name)) {
+ g_warning ("given privilege has no name");
+ } else {
+ g_warning ("no privilege with name '%s'", privilege_name);
+ }
+ current_result = LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE;
+ goto out;
+ }
+
+ libpolkit_privilege_file_entry_debug (pfe);
+
+ current_result = LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE;
+ current_control = LIBPOLKIT_MODULE_CONTROL_ADVISE; /* start with advise */
+
+ /* visit modules */
+ for (i = pk_context->modules; i != NULL; i = g_slist_next (i)) {
+ PolKitModuleInterface *module_interface = i->data;
+ PolKitModuleCanSessionAccessResource func;
+
+ func = libpolkit_module_get_func_can_session_access_resource (module_interface);
+ if (func != NULL) {
+ PolKitModuleControl module_control;
+ PolKitResult module_result;
+
+ _pk_debug ("Asking module '%s'", libpolkit_module_get_name (module_interface));
+
+ module_control = libpolkit_module_interface_get_control (module_interface);
+ module_result = func (module_interface,
+ pk_context,
+ privilege,
+ resource,
+ session);
+
+ /* if a module returns _UNKNOWN_PRIVILEGE, it means that it doesn't
+ * have an opinion about the query; e.g. polkit-module-allow-all(8)
+ * will return this if it's confined to only consider certain privileges
+ * or certain users.
+ */
+ if (module_result != LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE) {
+
+ if (current_control == LIBPOLKIT_MODULE_CONTROL_ADVISE &&
+ module_control == LIBPOLKIT_MODULE_CONTROL_ADVISE) {
+
+ /* take the less strict result */
+ if (current_result < module_result) {
+ current_result = module_result;
+ }
+
+ } else if (current_control == LIBPOLKIT_MODULE_CONTROL_ADVISE &&
+ module_control == LIBPOLKIT_MODULE_CONTROL_MANDATORY) {
+
+ /* here we just override */
+ current_result = module_result;
+
+ /* we are now in mandatory mode */
+ current_control = LIBPOLKIT_MODULE_CONTROL_MANDATORY;
+ }
+ }
+ }
+ }
+
+ /* Never return UNKNOWN_PRIVILEGE to user */
+ if (current_result == LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE)
+ current_result = LIBPOLKIT_RESULT_NO;
+
+out:
+ _pk_debug ("... result was %s", libpolkit_result_to_string_representation (current_result));
+ return current_result;
+}
+
+/**
+ * libpolkit_context_can_caller_access_resource:
+ * @pk_context: the PolicyKit context
+ * @privilege: the type of access to check for
+ * @resource: the resource in question
+ * @caller: the resource in question
+ *
+ * Determine if a given caller can access a given resource in a given way.
+ *
+ * Returns: A #PolKitResult specifying if, and how, the caller can
+ * access the resource in the given way
+ */
+PolKitResult
+libpolkit_context_can_caller_access_resource (PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitCaller *caller)
+{
+ PolKitPrivilegeCache *cache;
+ PolKitPrivilegeFileEntry *pfe;
+ PolKitResult current_result;
+ PolKitModuleControl current_control;
+ GSList *i;
+
+ current_result = LIBPOLKIT_RESULT_NO;
+
+ cache = libpolkit_context_get_privilege_cache (pk_context);
+ if (cache == NULL)
+ goto out;
+
+ _pk_debug ("entering libpolkit_can_caller_access_resource()");
+ libpolkit_privilege_debug (privilege);
+ libpolkit_resource_debug (resource);
+ libpolkit_caller_debug (caller);
+
+ pfe = libpolkit_privilege_cache_get_entry (cache, privilege);
+ if (pfe == NULL) {
+ char *privilege_name;
+ if (!libpolkit_privilege_get_privilege_id (privilege, &privilege_name)) {
+ g_warning ("given privilege has no name");
+ } else {
+ g_warning ("no privilege with name '%s'", privilege_name);
+ }
+ current_result = LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE;
+ goto out;
+ }
+
+ libpolkit_privilege_file_entry_debug (pfe);
+
+ current_result = LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE;
+ current_control = LIBPOLKIT_MODULE_CONTROL_ADVISE; /* start with advise */
+
+ /* visit modules */
+ for (i = pk_context->modules; i != NULL; i = g_slist_next (i)) {
+ PolKitModuleInterface *module_interface = i->data;
+ PolKitModuleCanCallerAccessResource func;
+
+ func = libpolkit_module_get_func_can_caller_access_resource (module_interface);
+ if (func != NULL) {
+ PolKitModuleControl module_control;
+ PolKitResult module_result;
+
+ _pk_debug ("Asking module '%s'", libpolkit_module_get_name (module_interface));
+
+ module_control = libpolkit_module_interface_get_control (module_interface);
+ module_result = func (module_interface,
+ pk_context,
+ privilege,
+ resource,
+ caller);
+
+ /* if a module returns _UNKNOWN_PRIVILEGE, it means that it doesn't
+ * have an opinion about the query; e.g. polkit-module-allow-all(8)
+ * will return this if it's confined to only consider certain privileges
+ * or certain users.
+ */
+ if (module_result != LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE) {
+
+ if (current_control == LIBPOLKIT_MODULE_CONTROL_ADVISE &&
+ module_control == LIBPOLKIT_MODULE_CONTROL_ADVISE) {
+
+ /* take the less strict result */
+ if (current_result < module_result) {
+ current_result = module_result;
+ }
+
+ } else if (current_control == LIBPOLKIT_MODULE_CONTROL_ADVISE &&
+ module_control == LIBPOLKIT_MODULE_CONTROL_MANDATORY) {
+
+ /* here we just override */
+ current_result = module_result;
+
+ /* we are now in mandatory mode */
+ current_control = LIBPOLKIT_MODULE_CONTROL_MANDATORY;
+ }
+ }
+ }
+ }
+
+ /* Never return UNKNOWN_PRIVILEGE to user */
+ if (current_result == LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE)
+ current_result = LIBPOLKIT_RESULT_NO;
+out:
+ _pk_debug ("... result was %s", libpolkit_result_to_string_representation (current_result));
+ return current_result;
+}
diff --git a/libpolkit/libpolkit-context.h b/libpolkit/libpolkit-context.h
index 33705ff..31fd1da 100644
--- a/libpolkit/libpolkit-context.h
+++ b/libpolkit/libpolkit-context.h
@@ -31,6 +31,14 @@
#include <sys/types.h>
#include <glib.h>
+#include <libpolkit/libpolkit-error.h>
+#include <libpolkit/libpolkit-result.h>
+#include <libpolkit/libpolkit-context.h>
+#include <libpolkit/libpolkit-privilege.h>
+#include <libpolkit/libpolkit-resource.h>
+#include <libpolkit/libpolkit-seat.h>
+#include <libpolkit/libpolkit-session.h>
+#include <libpolkit/libpolkit-caller.h>
#include <libpolkit/libpolkit-privilege-cache.h>
struct PolKitContext;
@@ -126,19 +134,53 @@ typedef void (*PolKitContextFileMonitorR
PolKitContext *libpolkit_context_new (void);
-gboolean libpolkit_context_init (PolKitContext *pk_context,
- GError **error);
-PolKitContext *libpolkit_context_ref (PolKitContext *pk_context);
-void libpolkit_context_unref (PolKitContext *pk_context);
void libpolkit_context_set_config_changed (PolKitContext *pk_context,
PolKitContextConfigChangedCB cb,
gpointer user_data);
void libpolkit_context_set_file_monitor (PolKitContext *pk_context,
PolKitContextFileMonitorAddWatch add_watch_func,
PolKitContextFileMonitorRemoveWatch remove_watch_func);
+gboolean libpolkit_context_init (PolKitContext *pk_context,
+ GError **error);
+PolKitContext *libpolkit_context_ref (PolKitContext *pk_context);
+void libpolkit_context_unref (PolKitContext *pk_context);
PolKitPrivilegeCache *libpolkit_context_get_privilege_cache (PolKitContext *pk_context);
+/**
+ * PolKitSeatVisitorCB:
+ * @seat: the seat
+ * @resources_associated_with_seat: A NULL terminated array of resources associated with the seat
+ * @user_data: user data
+ *
+ * Visitor function for libpolkit_get_seat_resource_association(). The caller should _not_ unref the passed objects.
+ */
+typedef void (*PolKitSeatVisitorCB) (PolKitSeat *seat,
+ PolKitResource **resources_associated_with_seat,
+ gpointer user_data);
+
+PolKitResult
+libpolkit_context_get_seat_resource_association (PolKitContext *pk_context,
+ PolKitSeatVisitorCB visitor,
+ gpointer *user_data);
+
+PolKitResult
+libpolkit_context_is_resource_associated_with_seat (PolKitContext *pk_context,
+ PolKitResource *resource,
+ PolKitSeat *seat);
+
+PolKitResult
+libpolkit_context_can_session_access_resource (PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitSession *session);
+
+PolKitResult
+libpolkit_context_can_caller_access_resource (PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitCaller *caller);
+
#endif /* LIBPOLKIT_CONTEXT_H */
diff --git a/libpolkit/libpolkit-debug.c b/libpolkit/libpolkit-debug.c
index 1a07435..b4987a5 100644
--- a/libpolkit/libpolkit-debug.c
+++ b/libpolkit/libpolkit-debug.c
@@ -37,6 +37,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <sys/time.h>
#include "libpolkit-debug.h"
@@ -61,6 +62,15 @@ _pk_debug (const char *format, ...)
}
if (show_debug) {
+ struct timeval tnow;
+ struct tm *tlocaltime;
+ struct timezone tzone;
+ char tbuf[256];
+ gettimeofday (&tnow, &tzone);
+ tlocaltime = localtime ((time_t *) &tnow.tv_sec);
+ strftime (tbuf, sizeof (tbuf), "%H:%M:%S", tlocaltime);
+ fprintf (stdout, "%s.%03d: ", tbuf, (int)(tnow.tv_usec/1000));
+
va_start (args, format);
vfprintf (stdout, format, args);
va_end (args);
diff --git a/libpolkit/libpolkit-module.c b/libpolkit/libpolkit-module.c
new file mode 100644
index 0000000..562e90c
--- /dev/null
+++ b/libpolkit/libpolkit-module.c
@@ -0,0 +1,490 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-module.c : PolicyKit loadable module interface
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **************************************************************************/
+
+/**
+ * SECTION:libpolkit-module
+ * @short_description: PolicyKit loadable module interface
+ *
+ * These functions are used by loadable PolicyKit modules.
+ **/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <dlfcn.h>
+
+#include "libpolkit-debug.h"
+#include "libpolkit-module.h"
+
+/**
+ * PolKitModuleInterface:
+ *
+ * Objects of this class are used to interface with PolicyKit modules
+ **/
+struct PolKitModuleInterface
+{
+ int refcount;
+ void *dlopen_handle;
+ char *name;
+
+ gpointer module_user_data;
+ PolKitModuleControl module_control;
+
+ PolKitModuleInitialize func_initialize;
+ PolKitModuleShutdown func_shutdown;
+ PolKitModuleGetSeatResourceAssociation func_get_seat_resource_association;
+ PolKitModuleIsResourceAssociatedWithSeat func_is_resource_associated_with_seat;
+ PolKitModuleCanSessionAccessResource func_can_session_access_resource;
+ PolKitModuleCanCallerAccessResource func_can_caller_access_resource;
+};
+
+/**
+ * libpolkit_module_interface_load_module:
+ * @name: name of module, e.g. "polkit-module-default.so"
+ * @module_control: the module control; from the configuration file
+ * @argc: number arguments to pass
+ * @argv: argument vector, the first argument must be the filename/path to the module
+ *
+ * Load and initialize a PolicyKit module
+ *
+ * Returns: A #PolKitModuleInterface object on success; #NULL on failure.
+ **/
+PolKitModuleInterface *
+libpolkit_module_interface_load_module (const char *name, PolKitModuleControl module_control, int argc, char *argv[])
+{
+ void *handle;
+ PolKitModuleInterface *mi;
+ gboolean (*func) (PolKitModuleInterface *);
+
+ mi = NULL;
+
+ _pk_debug ("loading %s", name);
+
+ handle = dlopen (name, RTLD_NOW | RTLD_LOCAL);
+ if (handle == NULL) {
+ _pk_debug ("Cannot load module '%s'", name);
+ goto error;
+ }
+
+ func = dlsym (handle, "libpolkit_module_set_functions");
+ if (func == NULL) {
+ _pk_debug ("Cannot get symbol 'libpolkit_module_set_functions' in module '%s'", name);
+ goto error;
+ }
+
+ _pk_debug ("func = %p", func);
+
+ mi = libpolkit_module_interface_new ();
+ if (!func (mi)) {
+ _pk_debug ("Module '%s' returned FALSE when asked to set functions", name);
+ goto error;
+ }
+
+ if (mi->func_initialize == NULL) {
+ _pk_debug ("Module '%s' didn't set initialize function", name);
+ goto error;
+ }
+
+ if (mi->func_shutdown == NULL) {
+ _pk_debug ("Module '%s' didn't set shutdown function", name);
+ goto error;
+ }
+
+ if (!mi->func_initialize (mi, argc, argv)) {
+ _pk_debug ("Module '%s' returned FALSE in initialization function", name);
+ goto error;
+ }
+
+ mi->dlopen_handle = handle;
+ mi->name = g_strdup (name);
+ mi->module_control = module_control;
+ return mi;
+error:
+ if (mi != NULL)
+ libpolkit_module_interface_unref (mi);
+ if (handle != NULL)
+ dlclose (handle);
+ return NULL;
+}
+
+/**
+ * libpolkit_module_get_name:
+ * @module_interface: the module interface
+ *
+ * Get the name of the module
+ *
+ * Returns: name or #NULL if an error occured
+ **/
+const char *
+libpolkit_module_get_name (PolKitModuleInterface *module_interface)
+{
+ g_return_val_if_fail (module_interface != NULL, NULL);
+ return module_interface->name;
+}
+
+
+/**
+ * libpolkit_module_interface_new:
+ *
+ * Create a new #PolKitModuleInterface object.
+ *
+ * Returns: the new object
+ **/
+PolKitModuleInterface *
+libpolkit_module_interface_new (void)
+{
+ PolKitModuleInterface *module_interface;
+ module_interface = g_new0 (PolKitModuleInterface, 1);
+ module_interface->refcount = 1;
+ return module_interface;
+}
+
+/**
+ * libpolkit_module_interface_ref:
+ * @module_interface: the module_interface object
+ *
+ * Increase reference count.
+ *
+ * Returns: the object
+ **/
+PolKitModuleInterface *
+libpolkit_module_interface_ref (PolKitModuleInterface *module_interface)
+{
+ g_return_val_if_fail (module_interface != NULL, module_interface);
+ module_interface->refcount++;
+ return module_interface;
+}
+
+/**
+ * libpolkit_module_interface_unref:
+ * @module_interface: the module_interface object
+ *
+ * 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.
+ **/
+void
+libpolkit_module_interface_unref (PolKitModuleInterface *module_interface)
+{
+ g_return_if_fail (module_interface != NULL);
+ module_interface->refcount--;
+ if (module_interface->refcount > 0)
+ return;
+
+ /* shutdown the module and unload it */
+ if (module_interface->func_shutdown != NULL)
+ module_interface->func_shutdown (module_interface);
+ if (module_interface->dlopen_handle != NULL)
+ dlclose (module_interface->dlopen_handle);
+
+ g_free (module_interface->name);
+ g_free (module_interface);
+}
+
+/**
+ * libpolkit_module_set_func_initialize:
+ * @module_interface: the module interface
+ * @func: the function pointer
+ *
+ * Set the function pointer.
+ **/
+void
+libpolkit_module_set_func_initialize (PolKitModuleInterface *module_interface,
+ PolKitModuleInitialize func)
+{
+ g_return_if_fail (module_interface != NULL);
+ module_interface->func_initialize = func;
+}
+
+/**
+ * libpolkit_module_set_func_shutdown:
+ * @module_interface: the module interface
+ * @func: the function pointer
+ *
+ * Set the function pointer.
+ **/
+void
+libpolkit_module_set_func_shutdown (PolKitModuleInterface *module_interface,
+ PolKitModuleShutdown func)
+{
+ g_return_if_fail (module_interface != NULL);
+ module_interface->func_shutdown = func;
+}
+
+/**
+ * libpolkit_module_set_func_get_seat_resource_association:
+ * @module_interface: the module interface
+ * @func: the function pointer
+ *
+ * Set the function pointer.
+ **/
+void
+libpolkit_module_set_func_get_seat_resource_association (PolKitModuleInterface *module_interface,
+ PolKitModuleGetSeatResourceAssociation func)
+{
+ g_return_if_fail (module_interface != NULL);
+ module_interface->func_get_seat_resource_association = func;
+}
+
+/**
+ * libpolkit_module_set_func_is_resource_associated_with_seat:
+ * @module_interface: the module interface
+ * @func: the function pointer
+ *
+ * Set the function pointer.
+ **/
+void libpolkit_module_set_func_is_resource_associated_with_seat (PolKitModuleInterface *module_interface,
+ PolKitModuleIsResourceAssociatedWithSeat func)
+{
+ g_return_if_fail (module_interface != NULL);
+ module_interface->func_is_resource_associated_with_seat = func;
+}
+
+/**
+ * libpolkit_module_set_func_can_session_access_resource:
+ * @module_interface: the module interface
+ * @func: the function pointer
+ *
+ * Set the function pointer.
+ **/
+void libpolkit_module_set_func_can_session_access_resource (PolKitModuleInterface *module_interface,
+ PolKitModuleCanSessionAccessResource func)
+{
+ g_return_if_fail (module_interface != NULL);
+ module_interface->func_can_session_access_resource = func;
+}
+
+/**
+ * libpolkit_module_set_func_can_caller_access_resource:
+ * @module_interface: the module interface
+ * @func: the function pointer
+ *
+ * Set the function pointer.
+ **/
+void libpolkit_module_set_func_can_caller_access_resource (PolKitModuleInterface *module_interface,
+ PolKitModuleCanCallerAccessResource func)
+{
+ g_return_if_fail (module_interface != NULL);
+ module_interface->func_can_caller_access_resource = func;
+}
+
+/**
+ * libpolkit_module_get_func_initialize:
+ * @module_interface: the module interface
+ *
+ * Get the function pointer.
+ *
+ * Returns: Function pointer or #NULL if it's unavailable or an error occured
+ **/
+PolKitModuleInitialize
+libpolkit_module_get_func_initialize (PolKitModuleInterface *module_interface)
+{
+ g_return_val_if_fail (module_interface != NULL, NULL);
+ return module_interface->func_initialize;
+}
+
+/**
+ * libpolkit_module_get_func_shutdown:
+ * @module_interface: the module interface
+ *
+ * Get the function pointer.
+ *
+ * Returns: Function pointer or #NULL if it's unavailable or an error occured
+ **/
+PolKitModuleShutdown
+libpolkit_module_get_func_shutdown (PolKitModuleInterface *module_interface)
+{
+ g_return_val_if_fail (module_interface != NULL, NULL);
+ return module_interface->func_shutdown;
+}
+
+/**
+ * libpolkit_module_get_func_get_seat_resource_association:
+ * @module_interface: the module interface
+ *
+ * Get the function pointer.
+ *
+ * Returns: Function pointer or #NULL if it's unavailable or an error occured
+ **/
+PolKitModuleGetSeatResourceAssociation
+libpolkit_module_get_func_get_seat_resource_association (PolKitModuleInterface *module_interface)
+{
+ g_return_val_if_fail (module_interface != NULL, NULL);
+ return module_interface->func_get_seat_resource_association;
+}
+
+/**
+ * libpolkit_module_get_func_is_resource_associated_with_seat:
+ * @module_interface: the module interface
+ *
+ * Get the function pointer.
+ *
+ * Returns: Function pointer or #NULL if it's unavailable or an error occured
+ **/
+PolKitModuleIsResourceAssociatedWithSeat
+libpolkit_module_get_func_is_resource_associated_with_seat (PolKitModuleInterface *module_interface)
+{
+ g_return_val_if_fail (module_interface != NULL, NULL);
+ return module_interface->func_is_resource_associated_with_seat;
+}
+
+/**
+ * libpolkit_module_get_func_can_session_access_resource:
+ * @module_interface: the module interface
+ *
+ * Get the function pointer.
+ *
+ * Returns: Function pointer or #NULL if it's unavailable or an error occured
+ **/
+PolKitModuleCanSessionAccessResource
+libpolkit_module_get_func_can_session_access_resource (PolKitModuleInterface *module_interface)
+{
+ g_return_val_if_fail (module_interface != NULL, NULL);
+ return module_interface->func_can_session_access_resource;
+}
+
+/**
+ * libpolkit_module_get_func_can_caller_access_resource:
+ * @module_interface: the module interface
+ *
+ * Get the function pointer.
+ *
+ * Returns: Function pointer or #NULL if it's unavailable or an error occured
+ **/
+PolKitModuleCanCallerAccessResource
+libpolkit_module_get_func_can_caller_access_resource (PolKitModuleInterface *module_interface)
+{
+ g_return_val_if_fail (module_interface != NULL, NULL);
+ return module_interface->func_can_caller_access_resource;
+}
+
+
+/**
+ * libpolkit_module_interface_get_control:
+ * @module_interface: the module interface
+ *
+ * Get the control for this module.
+ *
+ * Returns: A #PolKitModuleControl value.
+ **/
+PolKitModuleControl
+libpolkit_module_interface_get_control (PolKitModuleInterface *module_interface)
+{
+ /* hmm, should we have UNKNOWN? */
+ g_return_val_if_fail (module_interface != NULL, LIBPOLKIT_MODULE_CONTROL_MANDATORY);
+ return module_interface->module_control;
+}
+
+static const struct {
+ PolKitModuleControl module_control;
+ const char *str;
+} mapping[] =
+{
+ {LIBPOLKIT_MODULE_CONTROL_ADVISE, "advise"},
+ {LIBPOLKIT_MODULE_CONTROL_MANDATORY, "mandatory"},
+ {0, NULL}
+};
+
+/**
+ * libpolkit_module_control_to_string_representation:
+ * @module_control: the given value
+ *
+ * Gives a textual representation of a #PolKitModuleControl object.
+ *
+ * Returns: The textual representation or #NULL if the value passed is invalid
+ **/
+const char *
+libpolkit_module_control_to_string_representation (PolKitModuleControl module_control)
+{
+ if (module_control < 0 || module_control >= LIBPOLKIT_MODULE_CONTROL_N_CONTROLS) {
+ g_warning ("The passed module control identifier, %d, is not valid", module_control);
+ return NULL;
+ }
+
+ return mapping[module_control].str;
+}
+
+/**
+ * libpolkit_module_control_from_string_representation:
+ * @string: the textual representation
+ * @out_module_control: return location for the value
+ *
+ * Given a textual representation of a #PolKitModuleControl object, find the #PolKitModuleControl value.
+ *
+ * Returns: TRUE if the textual representation was valid, otherwise FALSE
+ **/
+gboolean
+libpolkit_module_control_from_string_representation (const char *string, PolKitModuleControl *out_module_control)
+{
+ int n;
+
+ g_return_val_if_fail (out_module_control != NULL, FALSE);
+
+ for (n = 0; n < LIBPOLKIT_MODULE_CONTROL_N_CONTROLS; n++) {
+ if (mapping[n].str == NULL)
+ break;
+ if (g_ascii_strcasecmp (mapping[n].str, string) == 0) {
+ *out_module_control = mapping[n].module_control;
+ goto found;
+ }
+ }
+
+ return FALSE;
+found:
+ return TRUE;
+}
+
+
+/**
+ * libpolkit_module_set_user_data:
+ * @module_interface: module interface
+ * @user_data: user data to set
+ *
+ * Set user data. A PolicyKit module should use these instead of
+ * global variables as multiple instances of the module may be
+ * instantiated at the same time.
+ **/
+void
+libpolkit_module_set_user_data (PolKitModuleInterface *module_interface, gpointer user_data)
+{
+ g_return_if_fail (module_interface != NULL);
+ module_interface->module_user_data = user_data;
+}
+
+/**
+ * libpolkit_module_get_user_data:
+ * @module_interface: module interface
+ *
+ * Get user data.
+ *
+ * Returns: The user data set with libpolkit_module_set_user_data()
+ **/
+gpointer
+libpolkit_module_get_user_data (PolKitModuleInterface *module_interface)
+{
+ g_return_val_if_fail (module_interface != NULL, NULL);
+ return module_interface->module_user_data;
+}
+
diff --git a/libpolkit/libpolkit-module.h b/libpolkit/libpolkit-module.h
new file mode 100644
index 0000000..9f325e3
--- /dev/null
+++ b/libpolkit/libpolkit-module.h
@@ -0,0 +1,192 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-module.h : PolicyKit loadable module interface
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at 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
+ *
+ **************************************************************************/
+
+#ifndef LIBPOLKIT_MODULE_H
+#define LIBPOLKIT_MODULE_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <glib.h>
+
+#include <libpolkit/libpolkit.h>
+
+struct PolKitModuleInterface;
+typedef struct PolKitModuleInterface PolKitModuleInterface;
+
+/**
+ * PolKitModuleInitialize:
+ * @module_interface: the module interface
+ * @argc: number of arguments to pass to module
+ * @argv: arguments passed to module; the first argument is the filename/path to the module
+ *
+ * Type of PolicyKit module function to initialize the module.
+ *
+ * Returns: Whether the module was initialized.
+ **/
+typedef gboolean (*PolKitModuleInitialize) (PolKitModuleInterface *module_interface,
+ int argc,
+ char *argv[]);
+
+/**
+ * PolKitModuleShutdown:
+ * @module_interface: the module interface
+ *
+ * Type of PolicyKit module function to shutdown the module.
+ **/
+typedef void (*PolKitModuleShutdown) (PolKitModuleInterface *module_interface);
+
+/**
+ * PolKitModuleGetSeatResourceAssociation:
+ * @module_interface: the module interface
+ * @pk_context: the PolicyKit context
+ * @visitor: visitor function
+ * @user_data: user data
+ *
+ * Type of PolicyKit module function to implement libpolkit_get_seat_resource_association().
+ *
+ * Returns: the #PolKitResult
+ **/
+typedef PolKitResult (*PolKitModuleGetSeatResourceAssociation) (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitSeatVisitorCB visitor,
+ gpointer *user_data);
+
+/**
+ * PolKitModuleIsResourceAssociatedWithSeat:
+ * @module_interface: the module interface
+ * @pk_context: the PolicyKit context
+ * @resource: the resource in question
+ * @seat: the seat
+ *
+ * Type of PolicyKit module function to implement libpolkit_is_resource_associated_with_seat().
+ *
+ * Returns: the #PolKitResult
+ **/
+typedef PolKitResult (*PolKitModuleIsResourceAssociatedWithSeat) (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitResource *resource,
+ PolKitSeat *seat);
+
+/**
+ * PolKitModuleCanSessionAccessResource:
+ * @module_interface: the module interface
+ * @pk_context: the PolicyKit context
+ * @privilege: the type of access to check for
+ * @resource: the resource in question
+ * @session: the session in question
+ *
+ * Type of PolicyKit module function to implement libpolkit_can_session_access_resource().
+ *
+ * Returns: the #PolKitResult
+ **/
+typedef PolKitResult (*PolKitModuleCanSessionAccessResource) (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitSession *session);
+
+/**
+ * PolKitModuleCanCallerAccessResource:
+ * @module_interface: the module interface
+ * @pk_context: the PolicyKit context
+ * @privilege: the type of access to check for
+ * @resource: the resource in question
+ * @caller: the resource in question
+ *
+ * Type of PolicyKit module function to implement libpolkit_can_caller_access_resource().
+ *
+ * Returns: the #PolKitResult
+ **/
+typedef PolKitResult (*PolKitModuleCanCallerAccessResource) (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitCaller *caller);
+
+PolKitModuleInterface *libpolkit_module_interface_new (void);
+PolKitModuleInterface *libpolkit_module_interface_ref (PolKitModuleInterface *module_interface);
+void libpolkit_module_interface_unref (PolKitModuleInterface *module_interface);
+const char *libpolkit_module_get_name (PolKitModuleInterface *module_interface);
+
+void libpolkit_module_set_user_data (PolKitModuleInterface *module_interface, gpointer user_data);
+gpointer libpolkit_module_get_user_data (PolKitModuleInterface *module_interface);
+
+void libpolkit_module_set_func_initialize (PolKitModuleInterface *module_interface,
+ PolKitModuleInitialize func);
+void libpolkit_module_set_func_shutdown (PolKitModuleInterface *module_interface,
+ PolKitModuleShutdown func);
+void libpolkit_module_set_func_get_seat_resource_association (PolKitModuleInterface *module_interface,
+ PolKitModuleGetSeatResourceAssociation func);
+void libpolkit_module_set_func_is_resource_associated_with_seat (PolKitModuleInterface *module_interface,
+ PolKitModuleIsResourceAssociatedWithSeat func);
+void libpolkit_module_set_func_can_session_access_resource (PolKitModuleInterface *module_interface,
+ PolKitModuleCanSessionAccessResource func);
+void libpolkit_module_set_func_can_caller_access_resource (PolKitModuleInterface *module_interface,
+ PolKitModuleCanCallerAccessResource func);
+
+PolKitModuleInitialize libpolkit_module_get_func_initialize (PolKitModuleInterface *module_interface);
+PolKitModuleShutdown libpolkit_module_get_func_shutdown (PolKitModuleInterface *module_interface);
+PolKitModuleGetSeatResourceAssociation libpolkit_module_get_func_get_seat_resource_association (PolKitModuleInterface *module_interface);
+PolKitModuleIsResourceAssociatedWithSeat libpolkit_module_get_func_is_resource_associated_with_seat (PolKitModuleInterface *module_interface);
+PolKitModuleCanSessionAccessResource libpolkit_module_get_func_can_session_access_resource (PolKitModuleInterface *module_interface);
+PolKitModuleCanCallerAccessResource libpolkit_module_get_func_can_caller_access_resource (PolKitModuleInterface *module_interface);
+
+/**
+ * PolKitModuleControl:
+ * @LIBPOLKIT_MODULE_CONTROL_ADVISE: Allow modules, marked with #LIBPOLKIT_MODULE_CONTROL_MANDATORY, down the
+ * stack to override results from this module. Modules down the stack that are also marked with
+ * the #LIBPOLKIT_MODULE_CONTROL_ADVISE control will only take effect it they change the result to be "less strict".
+ * @LIBPOLKIT_MODULE_CONTROL_MANDATORY: Always use results (unless it returns
+ * #LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE for a given request) from this module, even if it changes whether the
+ * result to be "more strict". . If a later module also uses this control, results from that module will override it.
+ * @LIBPOLKIT_MODULE_CONTROL_N_CONTROLS: Number of control stanzas
+ *
+ * The control stanza for a PolicyKit module. This is read from the
+ * PolicyKit configuration file (/etc/PolicyKit/PolicyKit.conf) that
+ * defines the stacked order of the modules and is chosen by the
+ * system administrator. See the definition of #PolKitResult for
+ * the definition of "strict" with respect to result values.
+ **/
+typedef enum
+{
+ LIBPOLKIT_MODULE_CONTROL_ADVISE,
+ LIBPOLKIT_MODULE_CONTROL_MANDATORY,
+ LIBPOLKIT_MODULE_CONTROL_N_CONTROLS
+} PolKitModuleControl;
+
+const char *
+libpolkit_module_control_to_string_representation (PolKitModuleControl module_control);
+
+gboolean
+libpolkit_module_control_from_string_representation (const char *string, PolKitModuleControl *out_module_control);
+
+PolKitModuleInterface *libpolkit_module_interface_load_module (const char *name,
+ PolKitModuleControl module_control,
+ int argc, char *argv[]);
+
+PolKitModuleControl libpolkit_module_interface_get_control (PolKitModuleInterface *module_interface);
+
+#endif /* LIBPOLKIT_MODULE_H */
diff --git a/libpolkit/libpolkit-result.c b/libpolkit/libpolkit-result.c
index 8d23dd5..f19b710 100644
--- a/libpolkit/libpolkit-result.c
+++ b/libpolkit/libpolkit-result.c
@@ -54,7 +54,6 @@ static const struct {
{
{LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE, "unknown"},
{LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW, "not_authorized"},
- {LIBPOLKIT_RESULT_YES, "yes"},
{LIBPOLKIT_RESULT_NO, "no"},
{LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH, "auth_root"},
{LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION, "auth_root_keep_session"},
@@ -62,6 +61,7 @@ static const struct {
{LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH, "auth_self"},
{LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION, "auth_self_keep_session"},
{LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS, "auth_self_keep_always"},
+ {LIBPOLKIT_RESULT_YES, "yes"},
{0, NULL}
};
@@ -111,8 +111,6 @@ libpolkit_result_from_string_representat
}
return FALSE;
-
found:
return TRUE;
-
}
diff --git a/libpolkit/libpolkit-result.h b/libpolkit/libpolkit-result.h
index 7d9ea6f..6573f59 100644
--- a/libpolkit/libpolkit-result.h
+++ b/libpolkit/libpolkit-result.h
@@ -32,7 +32,6 @@
* PolKitResult:
* @LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE: The passed privilege is unknown.
* @LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW: The caller of libpolkit is not sufficiently privilege to know the answer.
- * @LIBPOLKIT_RESULT_YES: Access granted.
* @LIBPOLKIT_RESULT_NO: Access denied.
* @LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH: Access denied, but authentication of the caller as
* root will grant access to only that caller.
@@ -46,15 +45,18 @@
* his user will grant access for the remainder of the session the caller stems from.
* @LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS: Access denied, but authentication of the caller as
* his user will grant access to the user of the caller in the future.
+ * @LIBPOLKIT_RESULT_YES: Access granted.
* @LIBPOLKIT_RESULT_N_RESULTS: Number of result codes
*
- * Result codes from queries to PolicyKit.
+ * Result codes from queries to PolicyKit. These are ordered and we
+ * say that a result A is "more strict" than a result B, if A has a
+ * lower numerical value. (e.g. #LIBPOLKIT_RESULT_NO is more strict
+ * than #LIBPOLKIT_RESULT_YES).
*/
typedef enum
{
LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE,
LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW,
- LIBPOLKIT_RESULT_YES,
LIBPOLKIT_RESULT_NO,
LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH,
LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION,
@@ -62,6 +64,7 @@ typedef enum
LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH,
LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION,
LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS,
+ LIBPOLKIT_RESULT_YES,
LIBPOLKIT_RESULT_N_RESULTS
} PolKitResult;
diff --git a/libpolkit/libpolkit.c b/libpolkit/libpolkit.c
deleted file mode 100644
index 651e54c..0000000
--- a/libpolkit/libpolkit.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-/***************************************************************************
- *
- * libpolkit.c : library for querying system-wide policy
- *
- * Copyright (C) 2007 David Zeuthen, <david at 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- **************************************************************************/
-
-/**
- * SECTION:libpolkit
- * @short_description: Policy functions.
- *
- * These functions are used to query system policy.
- **/
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <grp.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <glib.h>
-#include "libpolkit.h"
-#include "libpolkit-debug.h"
-
-/**
- * libpolkit_get_seat_resource_association:
- * @pk_context: the PolicyKit context
- * @visitor: visitor function
- * @user_data: user data
- *
- * Retrieve information about what resources are associated to what
- * seats. Note that a resource may be associated to more than one
- * seat. This information stems from user configuration and consumers
- * of this information that know better (e.g. HAL) may choose to
- * override it.
- *
- * Typically, this information is used to e.g. bootstrap the system
- * insofar that it can be used to start login greeters on the given
- * video hardware (e.g. resources) on the given user-configured seats.
- *
- * If a resource is not associated with any seat, it is assumed to be
- * available to any local seat.
- *
- * Returns: A #PolKitResult - can only be one of
- * #LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW or
- * #LIBPOLKIT_RESULT_YES (if the callback was invoked)
- */
-PolKitResult
-libpolkit_get_seat_resource_association (PolKitContext *pk_context,
- PolKitSeatVisitorCB visitor,
- gpointer *user_data)
-{
- return LIBPOLKIT_RESULT_YES;
-}
-
-/**
- * libpolkit_is_resource_associated_with_seat:
- * @pk_context: the PolicyKit context
- * @resource: the resource in question
- * @seat: the seat
- *
- * Determine if a given resource is associated with a given seat. The
- * same comments noted in libpolkit_get_seat_resource_association() about the
- * source purely being user configuration applies here as well.
- *
- * Returns: A #PolKitResult - can only be one of
- * #LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW,
- * #LIBPOLKIT_RESULT_YES, #LIBPOLKIT_RESULT_NO.
- */
-PolKitResult
-libpolkit_is_resource_associated_with_seat (PolKitContext *pk_context,
- PolKitResource *resource,
- PolKitSeat *seat)
-{
- return LIBPOLKIT_RESULT_NO;
-}
-
-/**
- * libpolkit_can_session_access_resource:
- * @pk_context: the PolicyKit context
- * @privilege: the type of access to check for
- * @resource: the resource in question
- * @session: the session in question
- *
- * Determine if a given session can access a given resource in a given way.
- *
- * Returns: A #PolKitResult - can only be one of
- * #LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW,
- * #LIBPOLKIT_RESULT_YES, #LIBPOLKIT_RESULT_NO.
- */
-PolKitResult
-libpolkit_can_session_access_resource (PolKitContext *pk_context,
- PolKitPrivilege *privilege,
- PolKitResource *resource,
- PolKitSession *session)
-{
- PolKitPrivilegeCache *cache;
- PolKitResult result;
- PolKitPrivilegeFileEntry *pfe;
-
- result = LIBPOLKIT_RESULT_NO;
-
- cache = libpolkit_context_get_privilege_cache (pk_context);
- if (cache == NULL)
- goto out;
-
- _pk_debug ("entering libpolkit_can_session_access_resource()");
- libpolkit_privilege_debug (privilege);
- libpolkit_resource_debug (resource);
- libpolkit_session_debug (session);
-
- pfe = libpolkit_privilege_cache_get_entry (cache, privilege);
- if (pfe == NULL) {
- char *privilege_name;
- if (!libpolkit_privilege_get_privilege_id (privilege, &privilege_name)) {
- g_warning ("given privilege has no name");
- } else {
- g_warning ("no privilege with name '%s'", privilege_name);
- }
- result = LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE;
- goto out;
- }
-
- libpolkit_privilege_file_entry_debug (pfe);
-
- /* for now, hardcode to defaults */
- result = libpolkit_privilege_default_can_session_access_resource (
- libpolkit_privilege_file_entry_get_default (pfe),
- privilege,
- resource,
- session);
-out:
- _pk_debug ("... result was %s", libpolkit_result_to_string_representation (result));
- return result;
-}
-
-/**
- * libpolkit_can_caller_access_resource:
- * @pk_context: the PolicyKit context
- * @privilege: the type of access to check for
- * @resource: the resource in question
- * @caller: the resource in question
- *
- * Determine if a given caller can access a given resource in a given way.
- *
- * Returns: A #PolKitResult specifying if, and how, the caller can
- * access the resource in the given way
- */
-PolKitResult
-libpolkit_can_caller_access_resource (PolKitContext *pk_context,
- PolKitPrivilege *privilege,
- PolKitResource *resource,
- PolKitCaller *caller)
-{
- PolKitPrivilegeCache *cache;
- PolKitResult result;
- PolKitPrivilegeFileEntry *pfe;
-
- result = LIBPOLKIT_RESULT_NO;
-
- cache = libpolkit_context_get_privilege_cache (pk_context);
- if (cache == NULL)
- goto out;
-
- _pk_debug ("entering libpolkit_can_caller_access_resource()");
- libpolkit_privilege_debug (privilege);
- libpolkit_resource_debug (resource);
- libpolkit_caller_debug (caller);
-
- pfe = libpolkit_privilege_cache_get_entry (cache, privilege);
- if (pfe == NULL) {
- char *privilege_name;
- if (!libpolkit_privilege_get_privilege_id (privilege, &privilege_name)) {
- g_warning ("given privilege has no name");
- } else {
- g_warning ("no privilege with name '%s'", privilege_name);
- }
- result = LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE;
- goto out;
- }
-
- libpolkit_privilege_file_entry_debug (pfe);
-
- /* for now, hardcode to defaults */
- result = libpolkit_privilege_default_can_caller_access_resource (
- libpolkit_privilege_file_entry_get_default (pfe),
- privilege,
- resource,
- caller);
-
-out:
- _pk_debug ("... result was %s", libpolkit_result_to_string_representation (result));
- return result;
-}
diff --git a/libpolkit/libpolkit.h b/libpolkit/libpolkit.h
index 1fed4f1..4088a8e 100644
--- a/libpolkit/libpolkit.h
+++ b/libpolkit/libpolkit.h
@@ -26,53 +26,7 @@
#ifndef LIBPOLKIT_H
#define LIBPOLKIT_H
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <glib.h>
-
-#include <libpolkit/libpolkit-error.h>
-#include <libpolkit/libpolkit-result.h>
#include <libpolkit/libpolkit-context.h>
-#include <libpolkit/libpolkit-privilege.h>
-#include <libpolkit/libpolkit-resource.h>
-#include <libpolkit/libpolkit-seat.h>
-#include <libpolkit/libpolkit-session.h>
-#include <libpolkit/libpolkit-caller.h>
-
-/**
- * PolKitSeatVisitorCB:
- * @seat: the seat
- * @resources_associated_with_seat: A NULL terminated array of resources associated with the seat
- * @user_data: user data
- *
- * Visitor function for libpolkit_get_seat_resource_association(). The caller should _not_ unref the passed objects.
- */
-typedef void (*PolKitSeatVisitorCB) (PolKitSeat *seat,
- PolKitResource **resources_associated_with_seat,
- gpointer user_data);
-
-PolKitResult
-libpolkit_get_seat_resource_association (PolKitContext *pk_context,
- PolKitSeatVisitorCB visitor,
- gpointer *user_data);
-
-PolKitResult
-libpolkit_is_resource_associated_with_seat (PolKitContext *pk_context,
- PolKitResource *resource,
- PolKitSeat *seat);
-
-PolKitResult
-libpolkit_can_session_access_resource (PolKitContext *pk_context,
- PolKitPrivilege *privilege,
- PolKitResource *resource,
- PolKitSession *session);
-
-PolKitResult
-libpolkit_can_caller_access_resource (PolKitContext *pk_context,
- PolKitPrivilege *privilege,
- PolKitResource *resource,
- PolKitCaller *caller);
#endif /* LIBPOLKIT_H */
diff --git a/modules/Makefile.am b/modules/Makefile.am
new file mode 100644
index 0000000..c2d8d54
--- /dev/null
+++ b/modules/Makefile.am
@@ -0,0 +1,5 @@
+
+SUBDIRS = default allow-all deny-all
+
+polkitconfdir = $(sysconfdir)/PolicyKit
+polkitconf_DATA = PolicyKit.conf
diff --git a/modules/PolicyKit.conf b/modules/PolicyKit.conf
new file mode 100644
index 0000000..ee8120b
--- /dev/null
+++ b/modules/PolicyKit.conf
@@ -0,0 +1,5 @@
+# PolicyKit modules - see PolicyKit(8)
+#
+# NOTE: Changes made to this file may be applied instantly
+
+advise polkit-module-default.so
diff --git a/modules/allow-all/Makefile.am b/modules/allow-all/Makefile.am
new file mode 100644
index 0000000..8a09890
--- /dev/null
+++ b/modules/allow-all/Makefile.am
@@ -0,0 +1,25 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = \
+ -I$(top_builddir) -I$(top_srcdir) \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
+ @GLIB_CFLAGS@ @DBUS_CFLAGS@
+
+polkitmoduledir = $(libdir)/PolicyKit/modules
+polkitmodule_LTLIBRARIES = \
+ polkit-module-allow-all.la \
+ $(NULL)
+
+
+polkit_module_allow_all_la_SOURCES = polkit-module-allow-all.c
+polkit_module_allow_all_la_LDFLAGS = -no-undefined -module -avoid-version
+polkit_module_allow_all_la_LIBADD = $(top_builddir)/libpolkit/libpolkit.la @GLIB_LIBS@
+
+clean-local :
+ rm -f *~
diff --git a/modules/allow-all/polkit-module-allow-all.c b/modules/allow-all/polkit-module-allow-all.c
new file mode 100644
index 0000000..82701c2
--- /dev/null
+++ b/modules/allow-all/polkit-module-allow-all.c
@@ -0,0 +1,241 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-module-allow-all.c : PolicyKit module that says YES to everything
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <errno.h>
+#include <regex.h>
+
+#include <libpolkit/libpolkit-module.h>
+
+/* The symbol that libpolkit looks up when loading this module */
+gboolean libpolkit_module_set_functions (PolKitModuleInterface *module_interface);
+
+typedef struct {
+ regex_t preg;
+ uid_t uid;
+ gboolean have_regex;
+ gboolean have_uid;
+} UserData;
+
+static uid_t
+_util_name_to_uid (const char *username, gid_t *default_gid)
+{
+ int rc;
+ uid_t res;
+ char *buf = NULL;
+ unsigned int bufsize;
+ struct passwd pwd;
+ struct passwd *pwdp;
+
+ res = (uid_t) -1;
+
+ bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
+ buf = g_new0 (char, bufsize);
+
+ rc = getpwnam_r (username, &pwd, buf, bufsize, &pwdp);
+ if (rc != 0 || pwdp == NULL) {
+ /*g_warning ("getpwnam_r() returned %d", rc);*/
+ goto out;
+ }
+
+ res = pwdp->pw_uid;
+ if (default_gid != NULL)
+ *default_gid = pwdp->pw_gid;
+
+out:
+ g_free (buf);
+ return res;
+}
+
+static gboolean
+_module_init (PolKitModuleInterface *module_interface, int argc, char *argv[])
+{
+ int n;
+ UserData *user_data;
+
+ user_data = g_new0 (UserData, 1);
+ for (n = 1; n < argc; n++) {
+ if (g_str_has_prefix (argv[n], "privilege=")) {
+ const char *regex;
+ regex = argv[n] + 10;
+ if (regcomp (&(user_data->preg), regex, REG_EXTENDED) != 0) {
+ printf ("Regex '%s' didn't compile\n", regex);
+ goto error;
+ }
+ user_data->have_regex = TRUE;
+ } else if (g_str_has_prefix (argv[n], "user=")) {
+ const char *user;
+ user = argv[n] + 5;
+ user_data->uid = _util_name_to_uid (user, NULL);
+ if ((int) user_data->uid == -1)
+ goto error;
+ user_data->have_uid = TRUE;
+ }
+ }
+
+ libpolkit_module_set_user_data (module_interface, user_data);
+
+ return TRUE;
+error:
+ g_free (user_data);
+ return FALSE;
+}
+
+static void
+_module_shutdown (PolKitModuleInterface *module_interface)
+{
+ UserData *user_data;
+ user_data = libpolkit_module_get_user_data (module_interface);
+ g_free (user_data);
+}
+
+static PolKitResult
+_module_can_session_access_resource (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitSession *session)
+{
+ UserData *user_data;
+ PolKitResult result;
+ gboolean user_check_ok;
+ gboolean regex_check_ok;
+
+ user_check_ok = FALSE;
+ regex_check_ok = FALSE;
+
+ user_data = libpolkit_module_get_user_data (module_interface);
+
+ if (user_data->have_regex) {
+ char *privilege_name;
+ if (libpolkit_privilege_get_privilege_id (privilege, &privilege_name)) {
+ if (regexec (&user_data->preg, privilege_name, 0, NULL, 0) == 0) {
+ regex_check_ok = TRUE;
+ }
+ }
+ } else {
+ regex_check_ok = TRUE;
+ }
+
+ if (user_data->have_uid) {
+ if (session != NULL) {
+ uid_t session_uid;
+ if (libpolkit_session_get_uid (session, &session_uid) && session_uid == user_data->uid) {
+ user_check_ok = TRUE;
+ }
+ }
+ } else {
+ user_check_ok = TRUE;
+ }
+
+ if (user_check_ok && regex_check_ok) {
+#ifdef IS_POLKIT_MODULE_DENY_ALL
+ result = LIBPOLKIT_RESULT_NO;
+#else
+ result = LIBPOLKIT_RESULT_YES;
+#endif
+ } else {
+ result = LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE;
+ }
+ return result;
+}
+
+static PolKitResult
+_module_can_caller_access_resource (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitCaller *caller)
+{
+ UserData *user_data;
+ PolKitResult result;
+ gboolean user_check_ok;
+ gboolean regex_check_ok;
+
+ user_check_ok = FALSE;
+ regex_check_ok = FALSE;
+
+ user_data = libpolkit_module_get_user_data (module_interface);
+
+ if (user_data->have_regex) {
+ char *privilege_name;
+ if (libpolkit_privilege_get_privilege_id (privilege, &privilege_name)) {
+ if (regexec (&user_data->preg, privilege_name, 0, NULL, 0) == 0) {
+ regex_check_ok = TRUE;
+ }
+ }
+ } else {
+ regex_check_ok = TRUE;
+ }
+
+ if (user_data->have_uid) {
+ uid_t caller_uid;
+ if (libpolkit_caller_get_uid (caller, &caller_uid) && caller_uid == user_data->uid) {
+ user_check_ok = TRUE;
+ }
+ } else {
+ user_check_ok = TRUE;
+ }
+
+ if (user_check_ok && regex_check_ok) {
+#ifdef IS_POLKIT_MODULE_DENY_ALL
+ result = LIBPOLKIT_RESULT_NO;
+#else
+ result = LIBPOLKIT_RESULT_YES;
+#endif
+ } else {
+ result = LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE;
+ }
+ return result;
+}
+
+gboolean
+libpolkit_module_set_functions (PolKitModuleInterface *module_interface)
+{
+ gboolean ret;
+
+ ret = FALSE;
+ if (module_interface == NULL)
+ goto out;
+
+ libpolkit_module_set_func_initialize (module_interface, _module_init);
+ libpolkit_module_set_func_shutdown (module_interface, _module_shutdown);
+ libpolkit_module_set_func_can_session_access_resource (module_interface, _module_can_session_access_resource);
+ libpolkit_module_set_func_can_caller_access_resource (module_interface, _module_can_caller_access_resource);
+
+ ret = TRUE;
+out:
+ return ret;
+}
diff --git a/modules/default/Makefile.am b/modules/default/Makefile.am
new file mode 100644
index 0000000..6167cc4
--- /dev/null
+++ b/modules/default/Makefile.am
@@ -0,0 +1,25 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = \
+ -I$(top_builddir) -I$(top_srcdir) \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
+ @GLIB_CFLAGS@ @DBUS_CFLAGS@
+
+polkitmoduledir = $(libdir)/PolicyKit/modules
+polkitmodule_LTLIBRARIES = \
+ polkit-module-default.la \
+ $(NULL)
+
+
+polkit_module_default_la_SOURCES = polkit-module-default.c
+polkit_module_default_la_LDFLAGS = -no-undefined -module -avoid-version
+polkit_module_default_la_LIBADD = $(top_builddir)/libpolkit/libpolkit.la @GLIB_LIBS@
+
+clean-local :
+ rm -f *~
diff --git a/modules/default/polkit-module-default.c b/modules/default/polkit-module-default.c
new file mode 100644
index 0000000..83f1e31
--- /dev/null
+++ b/modules/default/polkit-module-default.c
@@ -0,0 +1,116 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-module-default.c : PolicyKit module for default policy
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <libpolkit/libpolkit-module.h>
+
+/* The symbol that libpolkit looks up when loading this module */
+gboolean libpolkit_module_set_functions (PolKitModuleInterface *module_interface);
+
+static gboolean
+_module_init (PolKitModuleInterface *module_interface,
+ int argc,
+ char *argv[])
+{
+ return TRUE;
+}
+
+static void
+_module_shutdown (PolKitModuleInterface *module_interface)
+{
+}
+
+static PolKitResult
+_module_can_session_access_resource (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitSession *session)
+{
+ PolKitResult result;
+ PolKitPrivilegeCache *cache;
+ PolKitPrivilegeFileEntry *pfe;
+
+ result = LIBPOLKIT_RESULT_NO;
+ cache = libpolkit_context_get_privilege_cache (pk_context);
+ pfe = libpolkit_privilege_cache_get_entry (cache, privilege);
+ return libpolkit_privilege_default_can_session_access_resource (
+ libpolkit_privilege_file_entry_get_default (pfe),
+ privilege,
+ resource,
+ session);
+}
+
+static PolKitResult
+_module_can_caller_access_resource (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitCaller *caller)
+{
+ PolKitResult result;
+ PolKitPrivilegeCache *cache;
+ PolKitPrivilegeFileEntry *pfe;
+
+ result = LIBPOLKIT_RESULT_NO;
+ cache = libpolkit_context_get_privilege_cache (pk_context);
+ pfe = libpolkit_privilege_cache_get_entry (cache, privilege);
+ return libpolkit_privilege_default_can_caller_access_resource (
+ libpolkit_privilege_file_entry_get_default (pfe),
+ privilege,
+ resource,
+ caller);
+}
+
+gboolean
+libpolkit_module_set_functions (PolKitModuleInterface *module_interface)
+{
+ gboolean ret;
+
+ ret = FALSE;
+ if (module_interface == NULL)
+ goto out;
+
+ libpolkit_module_set_func_initialize (module_interface, _module_init);
+ libpolkit_module_set_func_shutdown (module_interface, _module_shutdown);
+ libpolkit_module_set_func_can_session_access_resource (module_interface, _module_can_session_access_resource);
+ libpolkit_module_set_func_can_caller_access_resource (module_interface, _module_can_caller_access_resource);
+
+ ret = TRUE;
+out:
+ return ret;
+}
diff --git a/modules/deny-all/Makefile.am b/modules/deny-all/Makefile.am
new file mode 100644
index 0000000..db5a282
--- /dev/null
+++ b/modules/deny-all/Makefile.am
@@ -0,0 +1,25 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = \
+ -I$(top_builddir) -I$(top_srcdir) \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
+ @GLIB_CFLAGS@ @DBUS_CFLAGS@ -DIS_POLKIT_MODULE_DENY_ALL
+
+polkitmoduledir = $(libdir)/PolicyKit/modules
+polkitmodule_LTLIBRARIES = \
+ polkit-module-deny-all.la \
+ $(NULL)
+
+
+polkit_module_deny_all_la_SOURCES = ../allow-all/polkit-module-allow-all.c
+polkit_module_deny_all_la_LDFLAGS = -no-undefined -module -avoid-version
+polkit_module_deny_all_la_LIBADD = $(top_builddir)/libpolkit/libpolkit.la @GLIB_LIBS@
+
+clean-local :
+ rm -f *~
diff --git a/tools/polkit-check-caller.c b/tools/polkit-check-caller.c
index d1f53aa..1c3b2ca 100644
--- a/tools/polkit-check-caller.c
+++ b/tools/polkit-check-caller.c
@@ -170,7 +170,7 @@ main (int argc, char *argv[])
}
}
- allowed = libpolkit_can_caller_access_resource (pol_ctx, privilege, resource, caller);
+ allowed = libpolkit_context_can_caller_access_resource (pol_ctx, privilege, resource, caller);
if (allowed)
return 0;
diff --git a/tools/polkit-check-session.c b/tools/polkit-check-session.c
index d6ee164..7ed3a2f 100644
--- a/tools/polkit-check-session.c
+++ b/tools/polkit-check-session.c
@@ -178,7 +178,7 @@ main (int argc, char *argv[])
libpolkit_resource_set_resource_type (resource, resource_type);
libpolkit_resource_set_resource_id (resource, resource_id);
- allowed = libpolkit_can_session_access_resource (pol_ctx, privilege, resource, session);
+ allowed = libpolkit_context_can_session_access_resource (pol_ctx, privilege, resource, session);
if (allowed)
return 0;
More information about the hal-commit
mailing list