diff --git a/Makefile.am b/Makefile.am index 6e481ed4e604102b22e20eb3888b08b84a17eb7c..9c313f19b546ddc09482348e871b9d2a5c024306 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 7af5deb9589f5ac1d4071e1ebd4b3467f8070e4e..25fc9af25b65377a7ea8021baba0e3240b08b108 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 1c9d35566bd712f96ba8f6efaa1986b0ad94cea9..7909e916388a4c8b39ac9655cbb46845c2c7ae25 100644 --- a/doc/api/libpolkit/libpolkit-docs.xml +++ b/doc/api/libpolkit/libpolkit-docs.xml @@ -64,7 +64,6 @@ PolicyKit library. - @@ -77,6 +76,7 @@ + diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 5b99a1f9e60e26ebf9d45f78193fd81f367b2228..93de521a7e675b9ff3632fea01df3e518b078b19 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 0000000000000000000000000000000000000000..ca427e3f3727660b3f995534bb5d56528c886635 --- /dev/null +++ b/doc/man/PolicyKit.8.in @@ -0,0 +1,38 @@ +.\" +.\" PolicyKit manual page. +.\" Copyright (C) 2007 David Zeuthen +.\" +.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 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 0992d9b49088177adba2c39a9fdba5b5c6f8e630..fe67d4d4ff5190619b8989747ee508fba700cda9 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 b364104840fa55976f3979520d0f20d0a96778fe..cab454c7130939e4b55e0afb0343b89b2854c675 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 0000000000000000000000000000000000000000..decd09740862c360534e133885656dd8afae6f10 --- /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 +.\" +.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=] [user=] +.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= +Only consider requests where the privilege name matches the given +regular expression. Example: +.B privilege=hal-storage-mount* + +.TP 3n +.B user= +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@sysconfdir@/PolicyKit/privileges\fR\|, +\&\fI@sysconfdir@/PolicyKit/PolicyKit.conf\fR\| + +.SH AUTHOR +Written by David Zeuthen 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 0000000000000000000000000000000000000000..379d3320728b2e1f07d9ba697c09e11238e43819 --- /dev/null +++ b/doc/man/polkit-module-default.8.in @@ -0,0 +1,39 @@ +.\" +.\" polkit-module-default manual page. +.\" Copyright (C) 2007 David Zeuthen +.\" +.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@sysconfdir@/PolicyKit/privileges\fR\|, +\&\fI@sysconfdir@/PolicyKit/PolicyKit.conf\fR\| + +.SH AUTHOR +Written by David Zeuthen 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 0000000000000000000000000000000000000000..feee0669209fcd7f1704a9e44628533ff0617281 --- /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 +.\" +.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=] [user=] +.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= +Only consider requests where the privilege name matches the given +regular expression. Example: +.B privilege=hal-storage-mount* + +.TP 3n +.B user= +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@sysconfdir@/PolicyKit/privileges\fR\|, +\&\fI@sysconfdir@/PolicyKit/PolicyKit.conf\fR\| + +.SH AUTHOR +Written by David Zeuthen 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 035f8814536010c4525b58b1a439cc820e61a49c..8a02f6645c340a27904573962c4d824591ed71f1 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 244e21e04c600ffbc58f3f17a11d6bbd32d5d7a0..5961d9b84abd61b3fcf962f3918c244598dc6281 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 2a05fbe38e40c05c79f70b7fe00c94b6f53ca125..5dcc5b246b65608f1dda4ce559a88454d26c3559 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 *pk_context, 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 *pk_context, GError **error) } _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 *pk_context, GError **error) 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_context) 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 (PolKitContext *pk_context) 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 33705ffb64bb3da2e39eeffe78ac71de7a1e3803..31fd1da354da23dd9e68ae6fcfa1c9861b409207 100644 --- a/libpolkit/libpolkit-context.h +++ b/libpolkit/libpolkit-context.h @@ -31,6 +31,14 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include struct PolKitContext; @@ -126,19 +134,53 @@ typedef void (*PolKitContextFileMonitorRemoveWatch) (PolKitContext 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 1a0743592944baaa79cfc11a20d74fb59baae1f9..b4987a5b9b2d5613afeb0b14993aba7b1efc82a1 100644 --- a/libpolkit/libpolkit-debug.c +++ b/libpolkit/libpolkit-debug.c @@ -37,6 +37,7 @@ #include #include #include +#include #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 0000000000000000000000000000000000000000..562e90cceea911c5d532df9eb1f5937a100712cf --- /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, + * + * 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 +#endif +#include + +#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 0000000000000000000000000000000000000000..9f325e3fbed81be30d581ccd87eb11bf9c971d4f --- /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, + * + * 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 +#include +#include +#include + +#include + +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 8d23dd58971da38e3c482c673029e9b531769784..f19b7100b0aa82616b5057493e503048effb442d 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_representation (const char *string, PolKitResult *o } return FALSE; - found: return TRUE; - } diff --git a/libpolkit/libpolkit-result.h b/libpolkit/libpolkit-result.h index 7d9ea6f0a9056a79d5ec88c9c4a4fcab1ce8f2b1..6573f59ca89d8d26e7ff68d3b538d4b5fde226e7 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 651e54cf482be9560d2b7fb7b9c00f0812513962..0000000000000000000000000000000000000000 --- 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, - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#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 1fed4f1256562caa9611595d5d1231605f2e79bc..4088a8e21e3530ade892bc7001c1d9fe13aa6714 100644 --- a/libpolkit/libpolkit.h +++ b/libpolkit/libpolkit.h @@ -26,53 +26,7 @@ #ifndef LIBPOLKIT_H #define LIBPOLKIT_H -#include -#include -#include -#include - -#include -#include #include -#include -#include -#include -#include -#include - -/** - * 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 0000000000000000000000000000000000000000..c2d8d549401606f8338e1522d68fe18ff9ed4e14 --- /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 0000000000000000000000000000000000000000..ee8120bfc060f1aa2705427ec40fe0c7913c3813 --- /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 0000000000000000000000000000000000000000..8a09890de8f3beee59c28b060065805a19bff3f5 --- /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 0000000000000000000000000000000000000000..82701c2257a28340ced86cf16b65042904b69835 --- /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, + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* 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 0000000000000000000000000000000000000000..6167cc4f04be76cd85b925583be3230f4015e454 --- /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 0000000000000000000000000000000000000000..83f1e31f82c7a848c8d2e9e6b91141efc2760ae5 --- /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, + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* 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 0000000000000000000000000000000000000000..db5a282f6afd7a2397d1ef6576297465800028aa --- /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 d1f53aad9b1f94cf39f7c913e8a721fc800a69de..1c3b2ca6df66488696dee23561cbcf0e8b82a3cd 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 d6ee164649f803e72750cd707f3d1e93e26907e1..7ed3a2fccf53b43dd8db58d83ab658509937e4ba 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;