PolicyKit: Branch 'master'
David Zeuthen
david at kemper.freedesktop.org
Sun Apr 8 13:49:44 PDT 2007
configure.in | 1
doc/man/Makefile.am | 2
doc/man/polkit-module-allow-all.8.in | 22 -
doc/man/polkit-module-builtins.8.in | 55 +++
doc/man/polkit-module-deny-all.8.in | 24 -
doc/man/polkit-module-run-program.8.in | 198 +++++++++++++
libpolkit/libpolkit-context.c | 53 ++-
libpolkit/libpolkit-module.c | 256 +++++++++++++++++
libpolkit/libpolkit-module.h | 15 +
modules/Makefile.am | 2
modules/allow-all/polkit-module-allow-all.c | 153 ----------
modules/deny-all/Makefile.am | 4
modules/deny-all/polkit-module-deny-all.c | 92 ++++++
modules/run-program/Makefile.am | 25 +
modules/run-program/polkit-module-run-program.c | 359 ++++++++++++++++++++++++
15 files changed, 1063 insertions(+), 198 deletions(-)
New commits:
diff-tree e2a465d0f9a16b501754b03267d743ac20135973 (from 0973db30eaab0e12d48b1e1f8386960fb32e2343)
Author: David Zeuthen <davidz at redhat.com>
Date: Sun Apr 8 16:49:27 2007 -0400
add built-in options and a new module pam-polkit-run-program.so
diff --git a/configure.in b/configure.in
index 25fc9af..97d0aa0 100644
--- a/configure.in
+++ b/configure.in
@@ -178,6 +178,7 @@ modules/Makefile
modules/default/Makefile
modules/allow-all/Makefile
modules/deny-all/Makefile
+modules/run-program/Makefile
])
dnl ==========================================================================
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
index 93de521..7e9464c 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 PolicyKit.8.in polkit-module-default.8.in polkit-module-allow-all.8.in polkit-module-deny-all.8.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 polkit-module-run-program.8.in polkit-module-builtins.8.in
man_MANS = $(MAN_IN_FILES:.in=)
diff --git a/doc/man/polkit-module-allow-all.8.in b/doc/man/polkit-module-allow-all.8.in
index decd097..17de422 100644
--- a/doc/man/polkit-module-allow-all.8.in
+++ b/doc/man/polkit-module-allow-all.8.in
@@ -7,7 +7,7 @@
polkit-module-allow-all \- grant access to all privileges
.SH SYNOPSIS
.PP
-.B polkit-module-allow-all.so [privilege=<regexp>] [user=<username>]
+.B polkit-module-allow-all.so
.SH DESCRIPTION
.PP
This PolicyKit module will allow access to any privilege regardless of
@@ -20,26 +20,14 @@ spec\fP which can be found in
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
+This module does not require nor recognize any options.
.SH NOTES
.PP
Never use this module unless you
.B COMPLETELY
-trust anyone with either remote or local access to the system.
+trust anyone with either remote or local access to the system, or you
+have confined the module using built-in options.
.SH BUGS
.PP
@@ -51,8 +39,10 @@ on how to subscribe.
.SH SEE ALSO
.PP
\&\fIPolicyKit\fR\|(8),
+\&\fIpolkit-module-builtins\fR\|(8),
\&\fIpolkit-module-default\fR\|(8),
\&\fIpolkit-module-deny-all\fR\|(8),
+\&\fIpolkit-module-run-program\fR\|(8),
\&\fI at sysconfdir@/PolicyKit/privileges\fR\|,
\&\fI at sysconfdir@/PolicyKit/PolicyKit.conf\fR\|
diff --git a/doc/man/polkit-module-builtins.8.in b/doc/man/polkit-module-builtins.8.in
new file mode 100644
index 0000000..333076b
--- /dev/null
+++ b/doc/man/polkit-module-builtins.8.in
@@ -0,0 +1,55 @@
+.\"
+.\" polkit-module-builtins manual page.
+.\" Copyright (C) 2007 David Zeuthen <david at fubar.dk>
+.\"
+.TH POLKIT-MODULE-BUILTINS 8
+.SH NAME
+polkit-module-builtins \- options that apply to any PolicyKit module
+.SH SYNOPSIS
+.PP
+.B any-module.so [privilege=<regexp>] [user=<username> ...]
+.SH DESCRIPTION
+.PP
+This manual page describes options that can be used for any PolicyKit
+module to confine what requests it should deal with.
+
+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. This option can be used multiple times to specify
+multiple users. Example:
+.B user=davidz user=bateman
+
+.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-deny-all.8.in b/doc/man/polkit-module-deny-all.8.in
index feee066..f2648c5 100644
--- a/doc/man/polkit-module-deny-all.8.in
+++ b/doc/man/polkit-module-deny-all.8.in
@@ -7,7 +7,7 @@
polkit-module-deny-all \- grant access to all privileges
.SH SYNOPSIS
.PP
-.B polkit-module-deny-all.so [privilege=<regexp>] [user=<username>]
+.B polkit-module-deny-all.so
.SH DESCRIPTION
.PP
This PolicyKit module will deny access to any privilege regardless of
@@ -20,25 +20,13 @@ spec\fP which can be found in
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
+This module does not require nor recognize any options.
.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.
+Unless confined using built-in options, this module is only useful
+in situations where it's desirable to lock down the system so it's
+unusable by normal unprivileged users.
.SH BUGS
.PP
@@ -50,8 +38,10 @@ on how to subscribe.
.SH SEE ALSO
.PP
\&\fIPolicyKit\fR\|(8),
+\&\fIpolkit-module-builtins\fR\|(8),
\&\fIpolkit-module-default\fR\|(8),
\&\fIpolkit-module-allow-all\fR\|(8),
+\&\fIpolkit-module-run-program\fR\|(8),
\&\fI at sysconfdir@/PolicyKit/privileges\fR\|,
\&\fI at sysconfdir@/PolicyKit/PolicyKit.conf\fR\|
diff --git a/doc/man/polkit-module-run-program.8.in b/doc/man/polkit-module-run-program.8.in
new file mode 100644
index 0000000..96f0868
--- /dev/null
+++ b/doc/man/polkit-module-run-program.8.in
@@ -0,0 +1,198 @@
+.\"
+.\" polkit-module-run-program manual page.
+.\" Copyright (C) 2007 David Zeuthen <david at fubar.dk>
+.\"
+.TH POLKIT-MODULE-RUN-PROGRAM 8
+.SH NAME
+polkit-module-run-program \- determine policy by running a program
+.SH SYNOPSIS
+.PP
+.HP 31
+\fBpolkit-module-run-program.so\fR program=\fI<program>\fR
+.SH DESCRIPTION
+.PP
+This PolicyKit module will run a program every time a privilege is
+requested. 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 program=<program>
+Absolute path to program to run; this is a mandatory option. Examples:
+.B privilege=/usr/bin/my-program
+or
+.B privilege="/path/to/program --foo --bar"
+
+.SH DESCRIPTION
+This module will invoke the given program and will export a minimal
+environment with values identifying the request. The program
+.B SHOULD NOT
+have any side effects; it is only invoked to make a decision - not to
+alter state on the system. Further, the program is not guaranteed to
+run as
+.B uid 0
+(e.g. root); it is effectively invoked by a mechanism (such as
+\fBhald\fR(7)) that may run as an unprivileged system user.
+
+.PP
+If the program fails to run or exits with a non-zero exit code, it
+means that the request is denied (same as returning
+.B no
+- see below). If the program exits with exit code 0,
+.I stdout
+of the program is examined to determine the result of the decision
+(these values map directly to the possible values in the
+.I PolKitResult
+enumeration):
+
+.I
+.TP
+.B unknown
+The passed privilege is unknown.
+.TP
+.B not_authorized
+The mechanism / caller (e.g. the program using
+.I libpolkit
+that loads this module) is not sufficiently privileged to know the
+answer.
+.TP
+.B no
+Access denied.
+.TP
+.B auth_root
+Access denied, but authentication of the caller as root will grant
+access to only that caller.
+.TP
+.B auth_root_keep_session
+Access denied, but authentication of the caller as root will grant
+access for the remainder of the session the caller stems from.
+.TP
+.B auth_root_keep_always
+Access denied, but authentication of the caller as root will grant
+access to the user of the caller in the future.
+.TP
+.B auth_self
+Access denied, but authentication of the caller as himself will grant
+access to only that caller.
+.TP
+.B auth_self_keep_session
+Access denied, but authentication of the caller as himself will grant
+access for the remainder of the session the caller stems from.
+.TP
+.B auth_self_keep_always
+Access denied, but authentication of the caller as himself will grant
+access to the user of the caller in the future.
+.TP
+.B yes
+Access granted.
+
+.PP
+For a request concerning decisions for calls via the system message
+bus daemon, the environment will contain:
+
+.TP
+.B POLKIT_REQUEST_CALLER=1
+To identify the request to be concerning a decision about a caller on
+the system message bus.
+.TP
+.B POLKIT_PRIVILEGE_ID
+Privilege identifier
+.TP
+.B POLKIT_RESOURCE_ID
+Resource identifier
+.TP
+.B POLKIT_RESOURCE_TYPE
+Resource type
+.TP
+.B POLKIT_CALLER_UID
+UNIX user id of the caller
+.TP
+.B POLKIT_CALLER_DBUS_NAME
+Unique name of the caller on the system message bus
+.TP
+.B POLKIT_CALLER_PID
+UNIX process id of the caller
+.TP
+.B POLKIT_CALLER_SELINUX_CONTEXT
+SELinux security context of the caller (only set if SELinux is enabled)
+.TP
+.B POLKIT_SESSION_CK_IS_ACTIVE
+Whether ConsoleKit regards the session as active (only set if the caller belong to a session)
+.TP
+.B POLKIT_SESSION_CK_IS_LOCAL
+Whether ConsoleKit regards the session as local (only set if the caller belong to a session)
+.TP
+.B POLKIT_SESSION_CK_OBJREF
+ConsoleKit session D-Bus object reference (only set if the caller belong to a session)
+.TP
+.B POLKIT_SESSION_UID
+UNIX user ID of the user owning the session (only set if the caller belong to a session)
+.TP
+.B POLKIT_SEAT_CK_OBJREF
+ConsoleKit seat D-Bus object reference of the seat that the session belongs to (only set if the caller belong to a session)
+
+.PP
+For a request concerning session-wide decisions the environment will
+contain:
+
+.TP
+.B POLKIT_REQUEST_SESSION=1
+To identify the request to be session-wide.
+.TP
+.B POLKIT_PRIVILEGE_ID
+Privilege identifier
+.TP
+.B POLKIT_RESOURCE_ID
+Resource identifier
+.TP
+.B POLKIT_RESOURCE_TYPE
+Resource type
+.TP
+.B POLKIT_SESSION_CK_IS_ACTIVE
+Whether ConsoleKit regards the session as active
+.TP
+.B POLKIT_SESSION_CK_IS_LOCAL
+Whether ConsoleKit regards the session as local
+.TP
+.B POLKIT_SESSION_CK_OBJREF
+ConsoleKit session D-Bus object reference
+.TP
+.B POLKIT_SESSION_UID
+UNIX user ID of the user owning the session
+.TP
+.B POLKIT_SEAT_CK_OBJREF
+ConsoleKit seat D-Bus object reference of the seat that the session belongs to
+
+.SH NOTES
+.PP
+As PolicyKit modules are heavily used to enforce policy, running a
+program on every request may put unneccessary load on the system
+unless judicious use of built-in options to confine the module are
+employed.
+
+.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),
+\&\fIhald\fR\|(8),
+\&\fIdbus-daemon\fR\|(1),
+\&\fIpolkit-module-default\fR\|(8),
+\&\fIpolkit-module-builtins\fR\|(8),
+\&\fIpolkit-module-default\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/libpolkit/libpolkit-context.c b/libpolkit/libpolkit-context.c
index 5dcc5b2..0f71293 100644
--- a/libpolkit/libpolkit-context.c
+++ b/libpolkit/libpolkit-context.c
@@ -43,6 +43,13 @@
#include "libpolkit-module.h"
/**
+ * SECTION:libpolkit
+ * @short_description: Centralized policy management.
+ *
+ * libpolkit is a C library for centralized policy management.
+ **/
+
+/**
* SECTION:libpolkit-context
* @short_description: Context.
*
@@ -545,11 +552,24 @@ libpolkit_context_can_session_access_res
_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 (libpolkit_module_interface_check_builtin_confinement_for_session (
+ module_interface,
+ pk_context,
+ privilege,
+ resource,
+ session)) {
+ /* module is confined by built-in options */
+ module_result = LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE;
+ _pk_debug ("Module '%s' confined by built-in's",
+ libpolkit_module_get_name (module_interface));
+ } else {
+ 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)
@@ -653,11 +673,24 @@ libpolkit_context_can_caller_access_reso
_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 (libpolkit_module_interface_check_builtin_confinement_for_caller (
+ module_interface,
+ pk_context,
+ privilege,
+ resource,
+ caller)) {
+ /* module is confined by built-in options */
+ module_result = LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE;
+ _pk_debug ("Module '%s' confined by built-in's",
+ libpolkit_module_get_name (module_interface));
+ } else {
+ 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)
diff --git a/libpolkit/libpolkit-module.c b/libpolkit/libpolkit-module.c
index 562e90c..414d2c8 100644
--- a/libpolkit/libpolkit-module.c
+++ b/libpolkit/libpolkit-module.c
@@ -34,6 +34,9 @@
# include <config.h>
#endif
#include <dlfcn.h>
+#include <regex.h>
+#include <pwd.h>
+#include <grp.h>
#include "libpolkit-debug.h"
#include "libpolkit-module.h"
@@ -58,8 +61,114 @@ struct PolKitModuleInterface
PolKitModuleIsResourceAssociatedWithSeat func_is_resource_associated_with_seat;
PolKitModuleCanSessionAccessResource func_can_session_access_resource;
PolKitModuleCanCallerAccessResource func_can_caller_access_resource;
+
+ gboolean builtin_have_privilege_regex;
+ regex_t builtin_privilege_regex_compiled;
+
+ GSList *builtin_users;
};
+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 void
+_parse_builtin_remove_option (int *argc, char *argv[], int position)
+{
+ int n;
+ for (n = position; n < *argc; n++)
+ argv[n] = argv[n+1];
+ (*argc)--;
+}
+
+static gboolean
+_parse_builtin (PolKitModuleInterface *mi, int *argc, char *argv[])
+{
+ int n;
+ gboolean ret;
+
+ ret = FALSE;
+
+ for (n = 1; n < *argc; ) {
+ if (g_str_has_prefix (argv[n], "privilege=")) {
+ const char *regex;
+
+ if (mi->builtin_have_privilege_regex) {
+ _pk_debug ("Already have option 'privilege='");
+ goto error;
+ }
+
+ regex = argv[n] + 10;
+ if (regcomp (&(mi->builtin_privilege_regex_compiled), regex, REG_EXTENDED) != 0) {
+ _pk_debug ("Regex '%s' didn't compile", regex);
+ goto error;
+ }
+ mi->builtin_have_privilege_regex = TRUE;
+
+ _pk_debug ("Compiled regex '%s' for option 'privilege=' OK", regex);
+
+ _parse_builtin_remove_option (argc, argv, n);
+ } else if (g_str_has_prefix (argv[n], "user=")) {
+ const char *user;
+ uid_t uid;
+ GSList *i;
+
+ user = argv[n] + 5;
+ uid = _util_name_to_uid (user, NULL);
+ if ((int) uid == -1) {
+ _pk_debug ("Unknown user name '%s'", user);
+ goto error;
+ }
+
+ for (i = mi->builtin_users; i != NULL; i = g_slist_next (i)) {
+ uid_t uid_in_list = GPOINTER_TO_INT (i->data);
+ if (uid_in_list == uid) {
+ _pk_debug ("Already have user '%s'", user);
+ goto error;
+ }
+ }
+
+ _pk_debug ("adding uid %d", uid);
+ mi->builtin_users = g_slist_prepend (mi->builtin_users, GINT_TO_POINTER (uid));
+
+ _parse_builtin_remove_option (argc, argv, n);
+ } else {
+ n++;
+ }
+ }
+
+ ret = TRUE;
+
+error:
+ return ret;
+}
+
/**
* libpolkit_module_interface_load_module:
* @name: name of module, e.g. "polkit-module-default.so"
@@ -112,6 +221,11 @@ libpolkit_module_interface_load_module (
goto error;
}
+ if (!_parse_builtin (mi, &argc, argv)) {
+ _pk_debug ("Error parsing built-in module options for '%s'", name);
+ goto error;
+ }
+
if (!mi->func_initialize (mi, argc, argv)) {
_pk_debug ("Module '%s' returned FALSE in initialization function", name);
goto error;
@@ -193,6 +307,11 @@ libpolkit_module_interface_unref (PolKit
if (module_interface->refcount > 0)
return;
+ /* builtins */
+ if (module_interface->builtin_have_privilege_regex)
+ regfree (&module_interface->builtin_privilege_regex_compiled);
+ g_slist_free (module_interface->builtin_users);
+
/* shutdown the module and unload it */
if (module_interface->func_shutdown != NULL)
module_interface->func_shutdown (module_interface);
@@ -488,3 +607,140 @@ libpolkit_module_get_user_data (PolKit
return module_interface->module_user_data;
}
+static gboolean
+_check_privilege (PolKitModuleInterface *module_interface, PolKitPrivilege *privilege)
+{
+ gboolean ret;
+
+ ret = FALSE;
+
+ if (module_interface->builtin_have_privilege_regex) {
+ char *privilege_name;
+ if (libpolkit_privilege_get_privilege_id (privilege, &privilege_name)) {
+ if (regexec (&module_interface->builtin_privilege_regex_compiled,
+ privilege_name, 0, NULL, 0) == 0) {
+ ret = TRUE;
+ }
+ }
+ } else {
+ ret = TRUE;
+ }
+
+ return ret;
+}
+
+/*----*/
+
+static gboolean
+_check_uid_in_list (GSList *list, uid_t given_uid)
+{
+ GSList *i;
+
+ for (i = list; i != NULL; i = g_slist_next (i)) {
+ uid_t uid = GPOINTER_TO_INT (i->data);
+ if (given_uid == uid)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+_check_users_for_session (PolKitModuleInterface *module_interface, PolKitSession *session)
+{
+ uid_t uid;
+ GSList *list;
+ if ((list = module_interface->builtin_users) == NULL)
+ return TRUE;
+ if (session == NULL)
+ return FALSE;
+ if (!libpolkit_session_get_uid (session, &uid))
+ return FALSE;
+ return _check_uid_in_list (list, uid);
+}
+
+static gboolean
+_check_users_for_caller (PolKitModuleInterface *module_interface, PolKitCaller *caller)
+{
+ uid_t uid;
+ GSList *list;
+ if ((list = module_interface->builtin_users) == NULL)
+ return TRUE;
+ if (caller == NULL)
+ return FALSE;
+ if (!libpolkit_caller_get_uid (caller, &uid))
+ return FALSE;
+ return _check_uid_in_list (list, uid);
+}
+
+
+/**
+ * libpolkit_module_interface_check_builtin_confinement_for_session:
+ * @module_interface: the given module
+ * @pk_context: the PolicyKit context
+ * @privilege: the type of access to check for
+ * @resource: the resource in question
+ * @session: the session in question
+ *
+ * Check whether some of the built-in module options (e.g. privilege="hal-storage-*",
+ * user=davidz) confines the given module, e.g. whether it should be skipped.
+ *
+ * Returns: TRUE if, and only if, the module is confined from handling the request
+ **/
+gboolean
+libpolkit_module_interface_check_builtin_confinement_for_session (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitSession *session)
+{
+ gboolean ret;
+ ret = TRUE;
+
+ g_return_val_if_fail (module_interface != NULL, ret);
+
+ if (!_check_privilege (module_interface, privilege))
+ goto out;
+ if (!_check_users_for_session (module_interface, session))
+ goto out;
+
+ /* not confined */
+ ret = FALSE;
+out:
+ return ret;
+}
+
+/**
+ * libpolkit_module_interface_check_builtin_confinement_for_caller:
+ * @module_interface: the given module
+ * @pk_context: the PolicyKit context
+ * @privilege: the type of access to check for
+ * @resource: the resource in question
+ * @caller: the resource in question
+ *
+ * Check whether some of the built-in module options (e.g. privilege="hal-storage-*",
+ * user=davidz) confines the given module, e.g. whether it should be skipped.
+ *
+ * Returns: TRUE if, and only if, the module is confined from handling the request
+ **/
+gboolean
+libpolkit_module_interface_check_builtin_confinement_for_caller (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitCaller *caller)
+{
+ gboolean ret;
+ ret = TRUE;
+
+ g_return_val_if_fail (module_interface != NULL, ret);
+
+ if (!_check_privilege (module_interface, privilege))
+ goto out;
+ if (!_check_users_for_caller (module_interface, caller))
+ goto out;
+
+ /* not confined */
+ ret = FALSE;
+out:
+ return ret;
+}
diff --git a/libpolkit/libpolkit-module.h b/libpolkit/libpolkit-module.h
index 9f325e3..bb99383 100644
--- a/libpolkit/libpolkit-module.h
+++ b/libpolkit/libpolkit-module.h
@@ -189,4 +189,19 @@ PolKitModuleInterface *libpolkit_module_
PolKitModuleControl libpolkit_module_interface_get_control (PolKitModuleInterface *module_interface);
+
+gboolean
+libpolkit_module_interface_check_builtin_confinement_for_session (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitSession *session);
+
+gboolean
+libpolkit_module_interface_check_builtin_confinement_for_caller (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitCaller *caller);
+
#endif /* LIBPOLKIT_MODULE_H */
diff --git a/modules/Makefile.am b/modules/Makefile.am
index b8c1a0d..b4eee78 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -1,5 +1,5 @@
-SUBDIRS = default allow-all deny-all
+SUBDIRS = default allow-all deny-all run-program
polkitconfdir = $(sysconfdir)/PolicyKit
dist_polkitconf_DATA = PolicyKit.conf
diff --git a/modules/allow-all/polkit-module-allow-all.c b/modules/allow-all/polkit-module-allow-all.c
index 82701c2..507868c 100644
--- a/modules/allow-all/polkit-module-allow-all.c
+++ b/modules/allow-all/polkit-module-allow-all.c
@@ -35,90 +35,21 @@
#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
@@ -128,48 +59,7 @@ _module_can_session_access_resource (Pol
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;
+ return LIBPOLKIT_RESULT_YES;
}
static PolKitResult
@@ -179,46 +69,7 @@ _module_can_caller_access_resource (PolK
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;
+ return LIBPOLKIT_RESULT_YES;
}
gboolean
diff --git a/modules/deny-all/Makefile.am b/modules/deny-all/Makefile.am
index db5a282..d6a134a 100644
--- a/modules/deny-all/Makefile.am
+++ b/modules/deny-all/Makefile.am
@@ -9,7 +9,7 @@ INCLUDES = \
-DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
- @GLIB_CFLAGS@ @DBUS_CFLAGS@ -DIS_POLKIT_MODULE_DENY_ALL
+ @GLIB_CFLAGS@ @DBUS_CFLAGS@
polkitmoduledir = $(libdir)/PolicyKit/modules
polkitmodule_LTLIBRARIES = \
@@ -17,7 +17,7 @@ polkitmodule_LTLIBRARIES = \
$(NULL)
-polkit_module_deny_all_la_SOURCES = ../allow-all/polkit-module-allow-all.c
+polkit_module_deny_all_la_SOURCES = polkit-module-deny-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@
diff --git a/modules/deny-all/polkit-module-deny-all.c b/modules/deny-all/polkit-module-deny-all.c
new file mode 100644
index 0000000..feece30
--- /dev/null
+++ b/modules/deny-all/polkit-module-deny-all.c
@@ -0,0 +1,92 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-module-allow-all.c : PolicyKit module that says NO 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 <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)
+{
+ return LIBPOLKIT_RESULT_NO;
+}
+
+static PolKitResult
+_module_can_caller_access_resource (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitCaller *caller)
+{
+ return LIBPOLKIT_RESULT_NO;
+}
+
+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/run-program/Makefile.am b/modules/run-program/Makefile.am
new file mode 100644
index 0000000..057c996
--- /dev/null
+++ b/modules/run-program/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-run-program.la \
+ $(NULL)
+
+
+polkit_module_run_program_la_SOURCES = polkit-module-run-program.c
+polkit_module_run_program_la_LDFLAGS = -no-undefined -module -avoid-version
+polkit_module_run_program_la_LIBADD = $(top_builddir)/libpolkit/libpolkit.la @GLIB_LIBS@
+
+clean-local :
+ rm -f *~
diff --git a/modules/run-program/polkit-module-run-program.c b/modules/run-program/polkit-module-run-program.c
new file mode 100644
index 0000000..af641c6
--- /dev/null
+++ b/modules/run-program/polkit-module-run-program.c
@@ -0,0 +1,359 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-module-run-program.c : determine policy by running a program
+ *
+ * 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);
+
+typedef struct {
+ int program_argc;
+ char **program_argv;
+} UserData;
+
+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], "program=")) {
+ const char *program;
+ program = argv[n] + 8;
+
+ if (!g_shell_parse_argv (program,
+ &user_data->program_argc,
+ &user_data->program_argv, NULL)) {
+ printf ("Cannot parse '%s' - skipping\n", program);
+ goto error;
+ }
+
+ if (!g_file_test (user_data->program_argv[0],
+ G_FILE_TEST_IS_EXECUTABLE|G_FILE_TEST_IS_REGULAR)) {
+ printf ("Program '%s' is not an executable file - skipping\n",
+ user_data->program_argv[0]);
+ goto error;
+ }
+
+ printf ("program = '%s'\n", user_data->program_argv[0]);
+
+ /* TODO:
+ * O_o o_O... we could monitor the executable file :-) and trigger config changes!
+ */
+ }
+ }
+
+ if (user_data->program_argv == NULL)
+ goto error;
+
+ libpolkit_module_set_user_data (module_interface, user_data);
+
+ return TRUE;
+error:
+ if (user_data->program_argv != NULL)
+ g_strfreev (user_data->program_argv);
+ 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);
+ if (user_data != NULL) {
+ if (user_data->program_argv != NULL)
+ g_strfreev (user_data->program_argv);
+ g_free (user_data);
+ }
+}
+
+static gboolean
+_add_privilege_to_env (PolKitPrivilege *privilege, GPtrArray *envp)
+{
+ char *p_id;
+ if (!libpolkit_privilege_get_privilege_id (privilege, &p_id))
+ goto error;
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_PRIVILEGE_ID=%s", p_id));
+ return TRUE;
+error:
+ return FALSE;
+}
+
+static gboolean
+_add_resource_to_env (PolKitResource *resource, GPtrArray *envp)
+{
+ char *r_type;
+ char *r_id;
+ if (!libpolkit_resource_get_resource_type (resource, &r_type))
+ goto error;
+ if (!libpolkit_resource_get_resource_id (resource, &r_id))
+ goto error;
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_RESOURCE_TYPE=%s", r_type));
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_RESOURCE_ID=%s", r_id));
+ return TRUE;
+error:
+ return FALSE;
+}
+
+static gboolean
+_add_seat_to_env (PolKitSeat *seat, GPtrArray *envp)
+{
+ char *s_ck_objref;
+ if (!libpolkit_seat_get_ck_objref (seat, &s_ck_objref))
+ goto error;
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_SEAT_CK_OBJREF=%s", s_ck_objref));
+ return TRUE;
+error:
+ return FALSE;
+}
+
+static gboolean
+_add_session_to_env (PolKitSession *session, GPtrArray *envp)
+{
+ uid_t s_uid;
+ char *s_ck_objref;
+ gboolean s_ck_is_active;
+ gboolean s_ck_is_local;
+ char *s_ck_remote_host;
+ PolKitSeat *s_seat;
+
+ if (!libpolkit_session_get_uid (session, &s_uid))
+ goto error;
+ if (!libpolkit_session_get_ck_objref (session, &s_ck_objref))
+ goto error;
+ if (!libpolkit_session_get_ck_is_active (session, &s_ck_is_active))
+ goto error;
+ if (!libpolkit_session_get_ck_is_local (session, &s_ck_is_local))
+ goto error;
+ if (!s_ck_is_local)
+ if (!libpolkit_session_get_ck_remote_host (session, &s_ck_remote_host))
+ goto error;
+ if (!libpolkit_session_get_seat (session, &s_seat))
+ goto error;
+
+ if (!_add_seat_to_env (s_seat, envp))
+ goto error;
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_SESSION_UID=%d", (int) s_uid));
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_SESSION_CK_OBJREF=%s", s_ck_objref));
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_SESSION_CK_IS_ACTIVE=%d", s_ck_is_active));
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_SESSION_CK_IS_LOCAL=%d", s_ck_is_local));
+ if (!s_ck_is_local)
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_SESSION_CK_REMOTE_HOST=%s", s_ck_remote_host));
+ return TRUE;
+error:
+ return FALSE;
+}
+
+static gboolean
+_add_caller_to_env (PolKitCaller *caller, GPtrArray *envp)
+{
+ uid_t c_uid;
+ pid_t c_pid;
+ char *c_selinux_context;
+ char *c_dbus_name;
+ PolKitSession *c_session;
+
+ if (!libpolkit_caller_get_uid (caller, &c_uid))
+ goto error;
+ if (!libpolkit_caller_get_pid (caller, &c_pid))
+ goto error;
+ if (!libpolkit_caller_get_dbus_name (caller, &c_dbus_name))
+ goto error;
+ if (!libpolkit_caller_get_selinux_context (caller, &c_selinux_context)) /* SELinux may not be available */
+ c_selinux_context = NULL;
+ if (!libpolkit_caller_get_ck_session (caller, &c_session)) /* Caller may not originate from a session */
+ c_session = NULL;
+
+ if (c_session != NULL)
+ if (!_add_session_to_env (c_session, envp))
+ goto error;
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_CALLER_UID=%d", (int) c_uid));
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_CALLER_PID=%d", (int) c_pid));
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_CALLER_DBUS_NAME=%s", c_dbus_name));
+ if (c_selinux_context != NULL)
+ g_ptr_array_add (envp, g_strdup_printf ("POLKIT_CALLER_SELINUX_CONTEXT=%s", c_selinux_context));
+ return TRUE;
+error:
+ return FALSE;
+}
+
+static gboolean
+_run_program (UserData *user_data, char **envp, PolKitResult *result)
+{
+ int n;
+ int exit_status;
+ GError *g_error;
+ char *prog_stdout;
+ gboolean ret;
+
+ g_error = NULL;
+ prog_stdout = NULL;
+ ret = FALSE;
+
+ if (!g_spawn_sync ("/",
+ user_data->program_argv,
+ envp,
+ 0,
+ NULL,
+ NULL,
+ &prog_stdout,
+ NULL,
+ &exit_status,
+ &g_error)) {
+ printf ("error spawning '%s': %s\n", user_data->program_argv[0], g_error->message);
+ g_error_free (g_error);
+ goto error;
+ }
+
+ /* only care if the program returned 0 */
+ if (exit_status != 0)
+ goto error;
+
+ /* only care about the first line */
+ for (n = 0; prog_stdout[n] != '\n' && prog_stdout[n] != '\0'; n++)
+ ;
+ prog_stdout[n] = '\0';
+
+ if (!libpolkit_result_from_string_representation (prog_stdout, result)) {
+ printf ("malformed result '%s' from program\n", prog_stdout);
+ goto error;
+ }
+
+ ret = TRUE;
+error:
+ g_free (prog_stdout);
+ return ret;
+}
+
+
+static PolKitResult
+_module_can_session_access_resource (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitSession *session)
+{
+ PolKitResult result;
+ UserData *user_data;
+ GPtrArray *envp;
+
+ envp = NULL;
+ result = LIBPOLKIT_RESULT_UNKNOWN_PRIVILEGE;
+
+ user_data = libpolkit_module_get_user_data (module_interface);
+
+ envp = g_ptr_array_new ();
+
+ if (!_add_privilege_to_env (privilege, envp))
+ goto error;
+ if (!_add_resource_to_env (resource, envp))
+ goto error;
+ if (!_add_session_to_env (session, envp))
+ goto error;
+ g_ptr_array_add (envp, g_strdup ("PATH=/usr/bin:/bin"));
+ g_ptr_array_add (envp, g_strdup ("POLKIT_REQUEST_SESSION=1"));
+ g_ptr_array_add (envp, NULL);
+
+ if (!_run_program (user_data, (char **) envp->pdata, &result))
+ goto error;
+
+error:
+ if (envp != NULL) {
+ g_ptr_array_foreach (envp, (GFunc) g_free, NULL);
+ g_ptr_array_free (envp, TRUE);
+ }
+ return result;
+}
+
+static PolKitResult
+_module_can_caller_access_resource (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitPrivilege *privilege,
+ PolKitResource *resource,
+ PolKitCaller *caller)
+{
+ PolKitResult result;
+ UserData *user_data;
+ GPtrArray *envp;
+
+ envp = NULL;
+ result = LIBPOLKIT_RESULT_NO;
+ user_data = libpolkit_module_get_user_data (module_interface);
+
+ envp = g_ptr_array_new ();
+ if (!_add_privilege_to_env (privilege, envp))
+ goto error;
+ if (!_add_resource_to_env (resource, envp))
+ goto error;
+ if (!_add_caller_to_env (caller, envp))
+ goto error;
+ g_ptr_array_add (envp, g_strdup ("PATH=/usr/bin:/bin"));
+ g_ptr_array_add (envp, g_strdup ("POLKIT_REQUEST_CALLER=1"));
+ g_ptr_array_add (envp, NULL);
+ if(!_run_program (user_data, (char **) envp->pdata, &result))
+ goto error;
+
+error:
+ if (envp != NULL) {
+ g_ptr_array_foreach (envp, (GFunc) g_free, NULL);
+ g_ptr_array_free (envp, TRUE);
+ }
+ 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;
+}
More information about the hal-commit
mailing list