diff --git a/profiles/coreos/arm64/package.use b/profiles/coreos/arm64/package.use index 6e5cf08154..993a6052ee 100644 --- a/profiles/coreos/arm64/package.use +++ b/profiles/coreos/arm64/package.use @@ -5,5 +5,3 @@ net-dns/bind-tools -gssapi # FIXME: why isn't this set by default??? sys-libs/ncurses unicode - -sys-auth/polkit -introspection diff --git a/profiles/coreos/arm64/package.use.force b/profiles/coreos/arm64/package.use.force index 782eff3ff2..cc901cedad 100644 --- a/profiles/coreos/arm64/package.use.force +++ b/profiles/coreos/arm64/package.use.force @@ -1,4 +1,3 @@ -sys-auth/polkit -introspection sys-apps/systemd -introspection # Matt Turner (2020-03-28) diff --git a/profiles/coreos/base/package.use b/profiles/coreos/base/package.use index 7de235cf76..4d9306ec3f 100644 --- a/profiles/coreos/base/package.use +++ b/profiles/coreos/base/package.use @@ -75,9 +75,6 @@ dev-libs/cyrus-sasl kerberos -berkdb -gdbm # don't build manpages for sssd sys-auth/sssd -python samba kerberos gssapi ssh sudo -# needed for realmd build -sys-auth/polkit introspection - # enable logging command-line options in update_engine dev-cpp/glog gflags @@ -147,3 +144,6 @@ dev-lang/perl minimal # Disable cgroup-hybrid as we use the unified mode sys-apps/systemd -cgroup-hybrid + +# Remove support for GObject introspection +sys-auth/polkit -introspection diff --git a/sys-auth/polkit/Manifest b/sys-auth/polkit/Manifest index 6b6923d42f..151dfefa1b 100644 --- a/sys-auth/polkit/Manifest +++ b/sys-auth/polkit/Manifest @@ -1 +1 @@ -DIST polkit-0.113.tar.gz 1448865 SHA256 e1c095093c654951f78f8618d427faf91cf62abdefed98de40ff65eca6413c81 SHA512 ab177c89a20eeb2978ddbe28afb205d3619f9c5defe833eb68a85e71a0f2c905367f1295cbbfb85da5eafdd661bce474d5d84aca9195cd425a18c9b4170eb5f9 WHIRLPOOL 106db7e6085a4ce49da44929138671eff2fd6007c80533518abe2d91ede9242b1e3cd0a1801190eeac5d4d5c1e978a30a18e47a6b604497b38853fa60c935a81 +DIST polkit-0.119.tar.gz 1387409 BLAKE2B aeb605598393d1cab40f7c77954008a0392600584c5fe8cc9acaa0e122418ee48b9cce0b6839189ea415277ff0ae4dbd5b7c71cb910aa349dcaf7e1f3f70ef06 SHA512 0260fb15da1c4c1f429e8223260981e64e297f1be8ced42f6910f09ea6581b8205aca06c9c601eb4a128acba2f468de0223118f96862ba769f95721894cf1578 diff --git a/sys-auth/polkit/files/35_WIP_Add_duktape_as_javascript_engine.patch b/sys-auth/polkit/files/35_WIP_Add_duktape_as_javascript_engine.patch new file mode 100644 index 0000000000..2dba8094ab --- /dev/null +++ b/sys-auth/polkit/files/35_WIP_Add_duktape_as_javascript_engine.patch @@ -0,0 +1,1596 @@ +diff --git a/configure.ac b/configure.ac +index 4ac2219770513e41b10605a48bc445144bfc8c06..d51cfbd922e289d30e0fdc0c3df745d0c9bd947f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -80,11 +80,22 @@ PKG_CHECK_MODULES(GLIB, [gmodule-2.0 gio-unix-2.0 >= 2.30.0]) + AC_SUBST(GLIB_CFLAGS) + AC_SUBST(GLIB_LIBS) + +-PKG_CHECK_MODULES(LIBJS, [mozjs-78]) +- +-AC_SUBST(LIBJS_CFLAGS) +-AC_SUBST(LIBJS_CXXFLAGS) +-AC_SUBST(LIBJS_LIBS) ++dnl --------------------------------------------------------------------------- ++dnl - Check javascript backend ++dnl --------------------------------------------------------------------------- ++AC_ARG_WITH(duktape, AS_HELP_STRING([--with-duktape],[Use Duktape as javascript backend]),with_duktape=yes,with_duktape=no) ++AS_IF([test x${with_duktape} == xyes], [ ++ PKG_CHECK_MODULES(LIBJS, [duktape >= 2.0.0 ]) ++ AC_SUBST(LIBJS_CFLAGS) ++ AC_SUBST(LIBJS_LIBS) ++], [ ++ PKG_CHECK_MODULES(LIBJS, [mozjs-78]) ++ ++ AC_SUBST(LIBJS_CFLAGS) ++ AC_SUBST(LIBJS_CXXFLAGS) ++ AC_SUBST(LIBJS_LIBS) ++]) ++AM_CONDITIONAL(USE_DUKTAPE, [test x$with_duktape == xyes], [Using duktape as javascript engine library]) + + EXPAT_LIB="" + AC_ARG_WITH(expat, [ --with-expat= Use expat from here], +@@ -581,6 +592,13 @@ echo " + PAM support: ${have_pam} + systemdsystemunitdir: ${systemdsystemunitdir} + polkitd user: ${POLKITD_USER}" ++if test "x${with_duktape}" = xyes; then ++echo " ++ Javascript engine: Duktape" ++else ++echo " ++ Javascript engine: Mozjs" ++fi + + if test "$have_pam" = yes ; then + echo " +diff --git a/meson.build b/meson.build +index 6997e7f7c6812cc58ac8b74246e557e9c0b03085..75513c2caf3a6fae7744675f9b4bcecd94d59d42 100644 +--- a/meson.build ++++ b/meson.build +@@ -126,7 +126,13 @@ expat_dep = dependency('expat') + assert(cc.has_header('expat.h', dependencies: expat_dep), 'Can\'t find expat.h. Please install expat.') + assert(cc.has_function('XML_ParserCreate', dependencies: expat_dep), 'Can\'t find expat library. Please install expat.') + +-mozjs_dep = dependency('mozjs-78') ++js_engine = get_option('js_engine') ++if js_engine == 'duktape' ++ js_dep = dependency('duktape') ++ libm_dep = cc.find_library('m') ++elif js_engine == 'mozjs' ++ js_dep = dependency('mozjs-78') ++endif + + dbus_dep = dependency('dbus-1') + dbus_sysconfdir = dbus_dep.get_pkgconfig_variable('sysconfdir', define_variable: ['sysconfdir', pk_prefix / pk_sysconfdir]) +@@ -350,6 +356,9 @@ if enable_logind + output += ' systemdsystemunitdir: ' + systemd_systemdsystemunitdir + '\n' + endif + output += ' polkitd user: ' + polkitd_user + ' \n' ++output += ' Javascript engine: ' + js_engine + '\n' ++if enable_logind ++endif + output += ' PAM support: ' + enable_pam.to_string() + '\n\n' + if enable_pam + output += ' PAM file auth: ' + pam_conf['PAM_FILE_INCLUDE_AUTH'] + '\n' +diff --git a/meson_options.txt b/meson_options.txt +index 25e3e7793ae1671fc65e172386b9392abf4e9352..76aa311c99620129b3594b0d95d675df91dc483b 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -16,3 +16,4 @@ option('introspection', type: 'boolean', value: true, description: 'Enable intro + + option('gtk_doc', type: 'boolean', value: false, description: 'use gtk-doc to build documentation') + option('man', type: 'boolean', value: false, description: 'build manual pages') ++option('js_engine', type: 'combo', choices: ['mozjs', 'duktape'], value: 'duktape', description: 'javascript engine') +diff --git a/src/polkitbackend/Makefile.am b/src/polkitbackend/Makefile.am +index 7e3c0809984987d8e77ff6c7717248f132e990f3..abcbc6ff7457965bbedce95a702921bbcd626428 100644 +--- a/src/polkitbackend/Makefile.am ++++ b/src/polkitbackend/Makefile.am +@@ -33,7 +33,7 @@ libpolkit_backend_1_la_SOURCES = \ + polkitbackendprivate.h \ + polkitbackendauthority.h polkitbackendauthority.c \ + polkitbackendinteractiveauthority.h polkitbackendinteractiveauthority.c \ +- polkitbackendjsauthority.h polkitbackendjsauthority.cpp \ ++ polkitbackendjsauthority.h \ + polkitbackendactionpool.h polkitbackendactionpool.c \ + polkitbackendactionlookup.h polkitbackendactionlookup.c \ + $(NULL) +@@ -51,19 +51,27 @@ libpolkit_backend_1_la_CFLAGS = \ + -D_POLKIT_BACKEND_COMPILATION \ + $(GLIB_CFLAGS) \ + $(LIBSYSTEMD_CFLAGS) \ +- $(LIBJS_CFLAGS) \ ++ $(LIBJS_CFLAGS) \ + $(NULL) + + libpolkit_backend_1_la_CXXFLAGS = $(libpolkit_backend_1_la_CFLAGS) + + libpolkit_backend_1_la_LIBADD = \ + $(GLIB_LIBS) \ ++ $(DUKTAPE_LIBS) \ + $(LIBSYSTEMD_LIBS) \ + $(top_builddir)/src/polkit/libpolkit-gobject-1.la \ + $(EXPAT_LIBS) \ +- $(LIBJS_LIBS) \ ++ $(LIBJS_LIBS) \ + $(NULL) + ++if USE_DUKTAPE ++libpolkit_backend_1_la_SOURCES += polkitbackendduktapeauthority.c ++libpolkit_backend_1_la_LIBADD += -lm ++else ++libpolkit_backend_1_la_SOURCES += polkitbackendjsauthority.cpp ++endif ++ + rulesdir = $(sysconfdir)/polkit-1/rules.d + rules_DATA = 50-default.rules + +diff --git a/src/polkitbackend/meson.build b/src/polkitbackend/meson.build +index 93c3c34574efbedb62cb8f3cc63f6acdfef5563f..d7d3b025679dee94f658e3562172f72de0bf9ddf 100644 +--- a/src/polkitbackend/meson.build ++++ b/src/polkitbackend/meson.build +@@ -5,7 +5,6 @@ sources = files( + 'polkitbackendactionpool.c', + 'polkitbackendauthority.c', + 'polkitbackendinteractiveauthority.c', +- 'polkitbackendjsauthority.cpp', + ) + + output = 'initjs.h' +@@ -21,7 +20,7 @@ sources += custom_target( + deps = [ + expat_dep, + libpolkit_gobject_dep, +- mozjs_dep, ++ js_dep, + ] + + c_flags = [ +@@ -31,6 +30,13 @@ c_flags = [ + '-DPACKAGE_SYSCONF_DIR="@0@"'.format(pk_prefix / pk_sysconfdir), + ] + ++if js_engine == 'duktape' ++ sources += files('polkitbackendduktapeauthority.c') ++ deps += libm_dep ++elif js_engine == 'mozjs' ++ sources += files('polkitbackendjsauthority.cpp') ++endif ++ + if enable_logind + sources += files('polkitbackendsessionmonitor-systemd.c') + +diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c +new file mode 100644 +index 0000000000000000000000000000000000000000..4b4f8fda7102223de1300e9ba9f2fa943708b653 +--- /dev/null ++++ b/src/polkitbackend/polkitbackendduktapeauthority.c +@@ -0,0 +1,1428 @@ ++/* ++ * Copyright (C) 2008-2012 Red Hat, Inc. ++ * Copyright (C) 2015 Tangent Space ++ * Copyright (C) 2019 Wu Xiaotian ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library 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 ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++ * Boston, MA 02111-1307, USA. ++ * ++ * Author: David Zeuthen ++ */ ++ ++#include "config.h" ++#include ++#include ++#include ++#include ++#ifdef HAVE_NETGROUP_H ++#include ++#else ++#include ++#endif ++#include ++#include ++#include ++#include ++ ++#include ++#include "polkitbackendjsauthority.h" ++ ++#include ++ ++#ifdef HAVE_LIBSYSTEMD ++#include ++#endif /* HAVE_LIBSYSTEMD */ ++ ++#include "initjs.h" /* init.js */ ++#include "duktape.h" ++ ++/** ++ * SECTION:polkitbackendjsauthority ++ * @title: PolkitBackendJsAuthority ++ * @short_description: JS Authority ++ * @stability: Unstable ++ * ++ * An implementation of #PolkitBackendAuthority that reads and ++ * evalates Javascript files and supports interaction with ++ * authentication agents (virtue of being based on ++ * #PolkitBackendInteractiveAuthority). ++ */ ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++struct _PolkitBackendJsAuthorityPrivate ++{ ++ gchar **rules_dirs; ++ GFileMonitor **dir_monitors; /* NULL-terminated array of GFileMonitor instances */ ++ duk_context *cx; ++}; ++ ++ ++static void utils_spawn (const gchar *const *argv, ++ guint timeout_seconds, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data); ++ ++gboolean utils_spawn_finish (GAsyncResult *res, ++ gint *out_exit_status, ++ gchar **out_standard_output, ++ gchar **out_standard_error, ++ GError **error); ++ ++static void on_dir_monitor_changed (GFileMonitor *monitor, ++ GFile *file, ++ GFile *other_file, ++ GFileMonitorEvent event_type, ++ gpointer user_data); ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++enum ++{ ++ PROP_0, ++ PROP_RULES_DIRS, ++}; ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static GList *polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *authority, ++ PolkitSubject *caller, ++ PolkitSubject *subject, ++ PolkitIdentity *user_for_subject, ++ gboolean subject_is_local, ++ gboolean subject_is_active, ++ const gchar *action_id, ++ PolkitDetails *details); ++ ++static PolkitImplicitAuthorization polkit_backend_js_authority_check_authorization_sync ( ++ PolkitBackendInteractiveAuthority *authority, ++ PolkitSubject *caller, ++ PolkitSubject *subject, ++ PolkitIdentity *user_for_subject, ++ gboolean subject_is_local, ++ gboolean subject_is_active, ++ const gchar *action_id, ++ PolkitDetails *details, ++ PolkitImplicitAuthorization implicit); ++ ++G_DEFINE_TYPE (PolkitBackendJsAuthority, polkit_backend_js_authority, POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY); ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static duk_ret_t js_polkit_log (duk_context *cx); ++static duk_ret_t js_polkit_spawn (duk_context *cx); ++static duk_ret_t js_polkit_user_is_in_netgroup (duk_context *cx); ++ ++static const duk_function_list_entry js_polkit_functions[] = ++{ ++ { "log", js_polkit_log, 1 }, ++ { "spawn", js_polkit_spawn, 1 }, ++ { "_userIsInNetGroup", js_polkit_user_is_in_netgroup, 2 }, ++ { NULL, NULL, 0 }, ++}; ++ ++static void ++polkit_backend_js_authority_init (PolkitBackendJsAuthority *authority) ++{ ++ authority->priv = G_TYPE_INSTANCE_GET_PRIVATE (authority, ++ POLKIT_BACKEND_TYPE_JS_AUTHORITY, ++ PolkitBackendJsAuthorityPrivate); ++} ++ ++static gint ++rules_file_name_cmp (const gchar *a, ++ const gchar *b) ++{ ++ gint ret; ++ const gchar *a_base; ++ const gchar *b_base; ++ ++ a_base = strrchr (a, '/'); ++ b_base = strrchr (b, '/'); ++ ++ g_assert (a_base != NULL); ++ g_assert (b_base != NULL); ++ a_base += 1; ++ b_base += 1; ++ ++ ret = g_strcmp0 (a_base, b_base); ++ if (ret == 0) ++ { ++ /* /etc wins over /usr */ ++ ret = g_strcmp0 (a, b); ++ g_assert (ret != 0); ++ } ++ ++ return ret; ++} ++ ++static void ++load_scripts (PolkitBackendJsAuthority *authority) ++{ ++ duk_context *cx = authority->priv->cx; ++ GList *files = NULL; ++ GList *l; ++ guint num_scripts = 0; ++ GError *error = NULL; ++ guint n; ++ ++ files = NULL; ++ ++ for (n = 0; authority->priv->rules_dirs != NULL && authority->priv->rules_dirs[n] != NULL; n++) ++ { ++ const gchar *dir_name = authority->priv->rules_dirs[n]; ++ GDir *dir = NULL; ++ ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Loading rules from directory %s", ++ dir_name); ++ ++ dir = g_dir_open (dir_name, ++ 0, ++ &error); ++ if (dir == NULL) ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Error opening rules directory: %s (%s, %d)", ++ error->message, g_quark_to_string (error->domain), error->code); ++ g_clear_error (&error); ++ } ++ else ++ { ++ const gchar *name; ++ while ((name = g_dir_read_name (dir)) != NULL) ++ { ++ if (g_str_has_suffix (name, ".rules")) ++ files = g_list_prepend (files, g_strdup_printf ("%s/%s", dir_name, name)); ++ } ++ g_dir_close (dir); ++ } ++ } ++ ++ files = g_list_sort (files, (GCompareFunc) rules_file_name_cmp); ++ ++ for (l = files; l != NULL; l = l->next) ++ { ++ const gchar *filename = (gchar *)l->data; ++#if (DUK_VERSION >= 20000) ++ GFile *file = g_file_new_for_path (filename); ++ char *contents; ++ gsize len; ++ if (!g_file_load_contents (file, NULL, &contents, &len, NULL, NULL)) ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Error compiling script %s", ++ filename); ++ g_object_unref (file); ++ continue; ++ } ++ ++ g_object_unref (file); ++ if (duk_peval_lstring_noresult(cx, contents,len) != 0) ++#else ++ if (duk_peval_file_noresult (cx, filename) != 0) ++#endif ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Error compiling script %s: %s", ++ filename, duk_safe_to_string (authority->priv->cx, -1)); ++#if (DUK_VERSION >= 20000) ++ g_free (contents); ++#endif ++ continue; ++ } ++#if (DUK_VERSION >= 20000) ++ g_free (contents); ++#endif ++ num_scripts++; ++ } ++ ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Finished loading, compiling and executing %d rules", ++ num_scripts); ++ g_list_free_full (files, g_free); ++} ++ ++static void ++reload_scripts (PolkitBackendJsAuthority *authority) ++{ ++ duk_context *cx = authority->priv->cx; ++ ++ duk_set_top (cx, 0); ++ if (!duk_get_global_string (cx, "polkit")) { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Error deleting old rules, not loading new ones"); ++ return; ++ } ++ duk_push_string (cx, "_deleteRules"); ++ ++ duk_call_prop (cx, 0, 0); ++ ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Collecting garbage unconditionally..."); ++ ++ load_scripts (authority); ++ ++ /* Let applications know we have new rules... */ ++ g_signal_emit_by_name (authority, "changed"); ++} ++ ++static void ++on_dir_monitor_changed (GFileMonitor *monitor, ++ GFile *file, ++ GFile *other_file, ++ GFileMonitorEvent event_type, ++ gpointer user_data) ++{ ++ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (user_data); ++ ++ /* TODO: maybe rate-limit so storms of events are collapsed into one with a 500ms resolution? ++ * Because when editing a file with emacs we get 4-8 events.. ++ */ ++ ++ if (file != NULL) ++ { ++ gchar *name; ++ ++ name = g_file_get_basename (file); ++ ++ /* g_print ("event_type=%d file=%p name=%s\n", event_type, file, name); */ ++ if (!g_str_has_prefix (name, ".") && ++ !g_str_has_prefix (name, "#") && ++ g_str_has_suffix (name, ".rules") && ++ (event_type == G_FILE_MONITOR_EVENT_CREATED || ++ event_type == G_FILE_MONITOR_EVENT_DELETED || ++ event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)) ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Reloading rules"); ++ reload_scripts (authority); ++ } ++ g_free (name); ++ } ++} ++ ++ ++static void ++setup_file_monitors (PolkitBackendJsAuthority *authority) ++{ ++ guint n; ++ GPtrArray *p; ++ ++ p = g_ptr_array_new (); ++ for (n = 0; authority->priv->rules_dirs != NULL && authority->priv->rules_dirs[n] != NULL; n++) ++ { ++ GFile *file; ++ GError *error; ++ GFileMonitor *monitor; ++ ++ file = g_file_new_for_path (authority->priv->rules_dirs[n]); ++ error = NULL; ++ monitor = g_file_monitor_directory (file, ++ G_FILE_MONITOR_NONE, ++ NULL, ++ &error); ++ g_object_unref (file); ++ if (monitor == NULL) ++ { ++ g_warning ("Error monitoring directory %s: %s", ++ authority->priv->rules_dirs[n], ++ error->message); ++ g_clear_error (&error); ++ } ++ else ++ { ++ g_signal_connect (monitor, ++ "changed", ++ G_CALLBACK (on_dir_monitor_changed), ++ authority); ++ g_ptr_array_add (p, monitor); ++ } ++ } ++ g_ptr_array_add (p, NULL); ++ authority->priv->dir_monitors = (GFileMonitor**) g_ptr_array_free (p, FALSE); ++} ++ ++static void ++polkit_backend_js_authority_constructed (GObject *object) ++{ ++ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object); ++ duk_context *cx; ++ ++ cx = duk_create_heap (NULL, NULL, NULL, authority, NULL); ++ if (cx == NULL) ++ goto fail; ++ ++ authority->priv->cx = cx; ++ ++ duk_push_global_object (cx); ++ duk_push_object (cx); ++ duk_put_function_list (cx, -1, js_polkit_functions); ++ duk_put_prop_string (cx, -2, "polkit"); ++ ++ duk_eval_string (cx, init_js); ++ ++ if (authority->priv->rules_dirs == NULL) ++ { ++ authority->priv->rules_dirs = g_new0 (gchar *, 3); ++ authority->priv->rules_dirs[0] = g_strdup (PACKAGE_SYSCONF_DIR "/polkit-1/rules.d"); ++ authority->priv->rules_dirs[1] = g_strdup (PACKAGE_DATA_DIR "/polkit-1/rules.d"); ++ } ++ ++ setup_file_monitors (authority); ++ load_scripts (authority); ++ ++ G_OBJECT_CLASS (polkit_backend_js_authority_parent_class)->constructed (object); ++ return; ++ ++ fail: ++ g_critical ("Error initializing JavaScript environment"); ++ g_assert_not_reached (); ++} ++ ++static void ++polkit_backend_js_authority_finalize (GObject *object) ++{ ++ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object); ++ guint n; ++ ++ for (n = 0; authority->priv->dir_monitors != NULL && authority->priv->dir_monitors[n] != NULL; n++) ++ { ++ GFileMonitor *monitor = authority->priv->dir_monitors[n]; ++ g_signal_handlers_disconnect_by_func (monitor, ++ G_CALLBACK (on_dir_monitor_changed), ++ authority); ++ g_object_unref (monitor); ++ } ++ g_free (authority->priv->dir_monitors); ++ g_strfreev (authority->priv->rules_dirs); ++ ++ duk_destroy_heap (authority->priv->cx); ++ ++ G_OBJECT_CLASS (polkit_backend_js_authority_parent_class)->finalize (object); ++} ++ ++static void ++polkit_backend_js_authority_set_property (GObject *object, ++ guint property_id, ++ const GValue *value, ++ GParamSpec *pspec) ++{ ++ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object); ++ ++ switch (property_id) ++ { ++ case PROP_RULES_DIRS: ++ g_assert (authority->priv->rules_dirs == NULL); ++ authority->priv->rules_dirs = (gchar **) g_value_dup_boxed (value); ++ break; ++ ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); ++ break; ++ } ++} ++ ++static const gchar * ++polkit_backend_js_authority_get_name (PolkitBackendAuthority *authority) ++{ ++ return "js"; ++} ++ ++static const gchar * ++polkit_backend_js_authority_get_version (PolkitBackendAuthority *authority) ++{ ++ return PACKAGE_VERSION; ++} ++ ++static PolkitAuthorityFeatures ++polkit_backend_js_authority_get_features (PolkitBackendAuthority *authority) ++{ ++ return POLKIT_AUTHORITY_FEATURES_TEMPORARY_AUTHORIZATION; ++} ++ ++static void ++polkit_backend_js_authority_class_init (PolkitBackendJsAuthorityClass *klass) ++{ ++ GObjectClass *gobject_class; ++ PolkitBackendAuthorityClass *authority_class; ++ PolkitBackendInteractiveAuthorityClass *interactive_authority_class; ++ ++ ++ gobject_class = G_OBJECT_CLASS (klass); ++ gobject_class->finalize = polkit_backend_js_authority_finalize; ++ gobject_class->set_property = polkit_backend_js_authority_set_property; ++ gobject_class->constructed = polkit_backend_js_authority_constructed; ++ ++ authority_class = POLKIT_BACKEND_AUTHORITY_CLASS (klass); ++ authority_class->get_name = polkit_backend_js_authority_get_name; ++ authority_class->get_version = polkit_backend_js_authority_get_version; ++ authority_class->get_features = polkit_backend_js_authority_get_features; ++ ++ interactive_authority_class = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_CLASS (klass); ++ interactive_authority_class->get_admin_identities = polkit_backend_js_authority_get_admin_auth_identities; ++ interactive_authority_class->check_authorization_sync = polkit_backend_js_authority_check_authorization_sync; ++ ++ g_object_class_install_property (gobject_class, ++ PROP_RULES_DIRS, ++ g_param_spec_boxed ("rules-dirs", ++ NULL, ++ NULL, ++ G_TYPE_STRV, ++ G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE)); ++ ++ ++ g_type_class_add_private (klass, sizeof (PolkitBackendJsAuthorityPrivate)); ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static void ++set_property_str (duk_context *cx, ++ const gchar *name, ++ const gchar *value) ++{ ++ duk_push_string (cx, value); ++ duk_put_prop_string (cx, -2, name); ++} ++ ++static void ++set_property_strv (duk_context *cx, ++ const gchar *name, ++ GPtrArray *value) ++{ ++ guint n; ++ duk_push_array (cx); ++ for (n = 0; n < value->len; n++) ++ { ++ duk_push_string (cx, g_ptr_array_index (value, n)); ++ duk_put_prop_index (cx, -2, n); ++ } ++ duk_put_prop_string (cx, -2, name); ++} ++ ++static void ++set_property_int32 (duk_context *cx, ++ const gchar *name, ++ gint32 value) ++{ ++ duk_push_int (cx, value); ++ duk_put_prop_string (cx, -2, name); ++} ++ ++static void ++set_property_bool (duk_context *cx, ++ const char *name, ++ gboolean value) ++{ ++ duk_push_boolean (cx, value); ++ duk_put_prop_string (cx, -2, name); ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static gboolean ++push_subject (duk_context *cx, ++ PolkitSubject *subject, ++ PolkitIdentity *user_for_subject, ++ gboolean subject_is_local, ++ gboolean subject_is_active, ++ GError **error) ++{ ++ gboolean ret = FALSE; ++ pid_t pid; ++ uid_t uid; ++ gchar *user_name = NULL; ++ GPtrArray *groups = NULL; ++ struct passwd *passwd; ++ char *seat_str = NULL; ++ char *session_str = NULL; ++ ++ if (!duk_get_global_string (cx, "Subject")) { ++ return FALSE; ++ } ++ ++ duk_new (cx, 0); ++ ++ if (POLKIT_IS_UNIX_PROCESS (subject)) ++ { ++ pid = polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject)); ++ } ++ else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) ++ { ++ PolkitSubject *process; ++ process = polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error); ++ if (process == NULL) ++ goto out; ++ pid = polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (process)); ++ g_object_unref (process); ++ } ++ else ++ { ++ g_assert_not_reached (); ++ } ++ ++#ifdef HAVE_LIBSYSTEMD ++ if (sd_pid_get_session (pid, &session_str) == 0) ++ { ++ if (sd_session_get_seat (session_str, &seat_str) == 0) ++ { ++ /* do nothing */ ++ } ++ } ++#endif /* HAVE_LIBSYSTEMD */ ++ ++ g_assert (POLKIT_IS_UNIX_USER (user_for_subject)); ++ uid = polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_for_subject)); ++ ++ groups = g_ptr_array_new_with_free_func (g_free); ++ ++ passwd = getpwuid (uid); ++ if (passwd == NULL) ++ { ++ user_name = g_strdup_printf ("%d", (gint) uid); ++ g_warning ("Error looking up info for uid %d: %m", (gint) uid); ++ } ++ else ++ { ++ gid_t gids[512]; ++ int num_gids = 512; ++ ++ user_name = g_strdup (passwd->pw_name); ++ ++ if (getgrouplist (passwd->pw_name, ++ passwd->pw_gid, ++ gids, ++ &num_gids) < 0) ++ { ++ g_warning ("Error looking up groups for uid %d: %m", (gint) uid); ++ } ++ else ++ { ++ gint n; ++ for (n = 0; n < num_gids; n++) ++ { ++ struct group *group; ++ group = getgrgid (gids[n]); ++ if (group == NULL) ++ { ++ g_ptr_array_add (groups, g_strdup_printf ("%d", (gint) gids[n])); ++ } ++ else ++ { ++ g_ptr_array_add (groups, g_strdup (group->gr_name)); ++ } ++ } ++ } ++ } ++ ++ set_property_int32 (cx, "pid", pid); ++ set_property_str (cx, "user", user_name); ++ set_property_strv (cx, "groups", groups); ++ set_property_str (cx, "seat", seat_str); ++ set_property_str (cx, "session", session_str); ++ set_property_bool (cx, "local", subject_is_local); ++ set_property_bool (cx, "active", subject_is_active); ++ ++ ret = TRUE; ++ ++ out: ++ free (session_str); ++ free (seat_str); ++ g_free (user_name); ++ if (groups != NULL) ++ g_ptr_array_unref (groups); ++ ++ return ret; ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static gboolean ++push_action_and_details (duk_context *cx, ++ const gchar *action_id, ++ PolkitDetails *details, ++ GError **error) ++{ ++ gchar **keys; ++ guint n; ++ ++ if (!duk_get_global_string (cx, "Action")) { ++ return FALSE; ++ } ++ ++ duk_new (cx, 0); ++ ++ set_property_str (cx, "id", action_id); ++ ++ keys = polkit_details_get_keys (details); ++ for (n = 0; keys != NULL && keys[n] != NULL; n++) ++ { ++ gchar *key; ++ const gchar *value; ++ key = g_strdup_printf ("_detail_%s", keys[n]); ++ value = polkit_details_lookup (details, keys[n]); ++ set_property_str (cx, key, value); ++ g_free (key); ++ } ++ g_strfreev (keys); ++ ++ return TRUE; ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static GList * ++polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *_authority, ++ PolkitSubject *caller, ++ PolkitSubject *subject, ++ PolkitIdentity *user_for_subject, ++ gboolean subject_is_local, ++ gboolean subject_is_active, ++ const gchar *action_id, ++ PolkitDetails *details) ++{ ++ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (_authority); ++ GList *ret = NULL; ++ guint n; ++ GError *error = NULL; ++ const char *ret_str = NULL; ++ gchar **ret_strs = NULL; ++ duk_context *cx = authority->priv->cx; ++ ++ duk_set_top (cx, 0); ++ if (!duk_get_global_string (cx, "polkit")) { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Error deleting old rules, not loading new ones"); ++ goto out; ++ } ++ ++ duk_push_string (cx, "_runAdminRules"); ++ ++ if (!push_action_and_details (cx, action_id, details, &error)) ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Error converting action and details to JS object: %s", ++ error->message); ++ g_clear_error (&error); ++ goto out; ++ } ++ ++ if (!push_subject (cx, subject, user_for_subject, subject_is_local, subject_is_active, &error)) ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Error converting subject to JS object: %s", ++ error->message); ++ g_clear_error (&error); ++ goto out; ++ } ++ ++ if (duk_pcall_prop (cx, 0, 2) != DUK_ERR_NONE) ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Error evaluating admin rules: ", ++ duk_safe_to_string (cx, -1)); ++ goto out; ++ } ++ ++ ret_str = duk_require_string (cx, -1); ++ ++ ret_strs = g_strsplit (ret_str, ",", -1); ++ for (n = 0; ret_strs != NULL && ret_strs[n] != NULL; n++) ++ { ++ const gchar *identity_str = ret_strs[n]; ++ PolkitIdentity *identity; ++ ++ error = NULL; ++ identity = polkit_identity_from_string (identity_str, &error); ++ if (identity == NULL) ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Identity `%s' is not valid, ignoring: %s", ++ identity_str, error->message); ++ g_clear_error (&error); ++ } ++ else ++ { ++ ret = g_list_prepend (ret, identity); ++ } ++ } ++ ret = g_list_reverse (ret); ++ ++ out: ++ g_strfreev (ret_strs); ++ /* fallback to root password auth */ ++ if (ret == NULL) ++ ret = g_list_prepend (ret, polkit_unix_user_new (0)); ++ ++ return ret; ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static PolkitImplicitAuthorization ++polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAuthority *_authority, ++ PolkitSubject *caller, ++ PolkitSubject *subject, ++ PolkitIdentity *user_for_subject, ++ gboolean subject_is_local, ++ gboolean subject_is_active, ++ const gchar *action_id, ++ PolkitDetails *details, ++ PolkitImplicitAuthorization implicit) ++{ ++ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (_authority); ++ PolkitImplicitAuthorization ret = implicit; ++ GError *error = NULL; ++ gchar *ret_str = NULL; ++ gboolean good = FALSE; ++ duk_context *cx = authority->priv->cx; ++ ++ duk_set_top (cx, 0); ++ if (!duk_get_global_string (cx, "polkit")) { ++ goto out; ++ } ++ ++ duk_push_string (cx, "_runRules"); ++ ++ if (!push_action_and_details (cx, action_id, details, &error)) ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Error converting action and details to JS object: %s", ++ error->message); ++ g_clear_error (&error); ++ goto out; ++ } ++ ++ if (!push_subject (cx, subject, user_for_subject, subject_is_local, subject_is_active, &error)) ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Error converting subject to JS object: %s", ++ error->message); ++ g_clear_error (&error); ++ goto out; ++ } ++ ++ if (duk_pcall_prop (cx, 0, 2) != DUK_ERR_NONE) ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Error evaluating authorization rules: ", ++ duk_safe_to_string (cx, -1)); ++ goto out; ++ } ++ ++ if (duk_is_null(cx, -1)) { ++ good = TRUE; ++ goto out; ++ } ++ ret_str = g_strdup (duk_require_string (cx, -1)); ++ if (!polkit_implicit_authorization_from_string (ret_str, &ret)) ++ { ++ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), ++ "Returned result `%s' is not valid", ++ ret_str); ++ goto out; ++ } ++ ++ good = TRUE; ++ ++ out: ++ if (!good) ++ ret = POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED; ++ if (ret_str != NULL) ++ g_free (ret_str); ++ ++ return ret; ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static duk_ret_t ++js_polkit_log (duk_context *cx) ++{ ++ const char *str = duk_require_string (cx, 0); ++ fprintf (stderr, "%s\n", str); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static const gchar * ++get_signal_name (gint signal_number) ++{ ++ switch (signal_number) ++ { ++#define _HANDLE_SIG(sig) case sig: return #sig; ++ _HANDLE_SIG (SIGHUP); ++ _HANDLE_SIG (SIGINT); ++ _HANDLE_SIG (SIGQUIT); ++ _HANDLE_SIG (SIGILL); ++ _HANDLE_SIG (SIGABRT); ++ _HANDLE_SIG (SIGFPE); ++ _HANDLE_SIG (SIGKILL); ++ _HANDLE_SIG (SIGSEGV); ++ _HANDLE_SIG (SIGPIPE); ++ _HANDLE_SIG (SIGALRM); ++ _HANDLE_SIG (SIGTERM); ++ _HANDLE_SIG (SIGUSR1); ++ _HANDLE_SIG (SIGUSR2); ++ _HANDLE_SIG (SIGCHLD); ++ _HANDLE_SIG (SIGCONT); ++ _HANDLE_SIG (SIGSTOP); ++ _HANDLE_SIG (SIGTSTP); ++ _HANDLE_SIG (SIGTTIN); ++ _HANDLE_SIG (SIGTTOU); ++ _HANDLE_SIG (SIGBUS); ++#ifdef SIGPOLL ++ _HANDLE_SIG (SIGPOLL); ++#endif ++ _HANDLE_SIG (SIGPROF); ++ _HANDLE_SIG (SIGSYS); ++ _HANDLE_SIG (SIGTRAP); ++ _HANDLE_SIG (SIGURG); ++ _HANDLE_SIG (SIGVTALRM); ++ _HANDLE_SIG (SIGXCPU); ++ _HANDLE_SIG (SIGXFSZ); ++#undef _HANDLE_SIG ++ default: ++ break; ++ } ++ return "UNKNOWN_SIGNAL"; ++} ++ ++typedef struct ++{ ++ GMainLoop *loop; ++ GAsyncResult *res; ++} SpawnData; ++ ++static void ++spawn_cb (GObject *source_object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ SpawnData *data = (SpawnData *)user_data; ++ data->res = (GAsyncResult*)g_object_ref (res); ++ g_main_loop_quit (data->loop); ++} ++ ++static duk_ret_t ++js_polkit_spawn (duk_context *cx) ++{ ++#if (DUK_VERSION >= 20000) ++ duk_ret_t ret = DUK_RET_ERROR; ++#else ++ duk_ret_t ret = DUK_RET_INTERNAL_ERROR; ++#endif ++ gchar *standard_output = NULL; ++ gchar *standard_error = NULL; ++ gint exit_status; ++ GError *error = NULL; ++ guint32 array_len; ++ gchar **argv = NULL; ++ GMainContext *context = NULL; ++ GMainLoop *loop = NULL; ++ SpawnData data = {0}; ++ char *err_str = NULL; ++ guint n; ++ ++ if (!duk_is_array (cx, 0)) ++ goto out; ++ ++ array_len = duk_get_length (cx, 0); ++ ++ argv = g_new0 (gchar*, array_len + 1); ++ for (n = 0; n < array_len; n++) ++ { ++ duk_get_prop_index (cx, 0, n); ++ argv[n] = g_strdup (duk_to_string (cx, -1)); ++ duk_pop (cx); ++ } ++ ++ context = g_main_context_new (); ++ loop = g_main_loop_new (context, FALSE); ++ ++ g_main_context_push_thread_default (context); ++ ++ data.loop = loop; ++ utils_spawn ((const gchar *const *) argv, ++ 10, /* timeout_seconds */ ++ NULL, /* cancellable */ ++ spawn_cb, ++ &data); ++ ++ g_main_loop_run (loop); ++ ++ g_main_context_pop_thread_default (context); ++ ++ if (!utils_spawn_finish (data.res, ++ &exit_status, ++ &standard_output, ++ &standard_error, ++ &error)) ++ { ++ err_str = g_strdup_printf ("Error spawning helper: %s (%s, %d)", ++ error->message, g_quark_to_string (error->domain), error->code); ++ g_clear_error (&error); ++ goto out; ++ } ++ ++ if (!(WIFEXITED (exit_status) && WEXITSTATUS (exit_status) == 0)) ++ { ++ GString *gstr; ++ gstr = g_string_new (NULL); ++ if (WIFEXITED (exit_status)) ++ { ++ g_string_append_printf (gstr, ++ "Helper exited with non-zero exit status %d", ++ WEXITSTATUS (exit_status)); ++ } ++ else if (WIFSIGNALED (exit_status)) ++ { ++ g_string_append_printf (gstr, ++ "Helper was signaled with signal %s (%d)", ++ get_signal_name (WTERMSIG (exit_status)), ++ WTERMSIG (exit_status)); ++ } ++ g_string_append_printf (gstr, ", stdout=`%s', stderr=`%s'", ++ standard_output, standard_error); ++ err_str = g_string_free (gstr, FALSE); ++ goto out; ++ } ++ ++ duk_push_string (cx, standard_output); ++ ret = 1; ++ ++ out: ++ g_strfreev (argv); ++ g_free (standard_output); ++ g_free (standard_error); ++ g_clear_object (&data.res); ++ if (loop != NULL) ++ g_main_loop_unref (loop); ++ if (context != NULL) ++ g_main_context_unref (context); ++ ++ if (err_str) ++ duk_error (cx, DUK_ERR_ERROR, err_str); ++ ++ return ret; ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++ ++static duk_ret_t ++js_polkit_user_is_in_netgroup (duk_context *cx) ++{ ++ const char *user; ++ const char *netgroup; ++ gboolean is_in_netgroup = FALSE; ++ ++ user = duk_require_string (cx, 0); ++ netgroup = duk_require_string (cx, 1); ++ ++ if (innetgr (netgroup, ++ NULL, /* host */ ++ user, ++ NULL)) /* domain */ ++ { ++ is_in_netgroup = TRUE; ++ } ++ ++ duk_push_boolean (cx, is_in_netgroup); ++ return 1; ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++typedef struct ++{ ++ GSimpleAsyncResult *simple; /* borrowed reference */ ++ GMainContext *main_context; /* may be NULL */ ++ ++ GCancellable *cancellable; /* may be NULL */ ++ gulong cancellable_handler_id; ++ ++ GPid child_pid; ++ gint child_stdout_fd; ++ gint child_stderr_fd; ++ ++ GIOChannel *child_stdout_channel; ++ GIOChannel *child_stderr_channel; ++ ++ GSource *child_watch_source; ++ GSource *child_stdout_source; ++ GSource *child_stderr_source; ++ ++ guint timeout_seconds; ++ gboolean timed_out; ++ GSource *timeout_source; ++ ++ GString *child_stdout; ++ GString *child_stderr; ++ ++ gint exit_status; ++} UtilsSpawnData; ++ ++static void ++utils_child_watch_from_release_cb (GPid pid, ++ gint status, ++ gpointer user_data) ++{ ++} ++ ++static void ++utils_spawn_data_free (UtilsSpawnData *data) ++{ ++ if (data->timeout_source != NULL) ++ { ++ g_source_destroy (data->timeout_source); ++ data->timeout_source = NULL; ++ } ++ ++ /* Nuke the child, if necessary */ ++ if (data->child_watch_source != NULL) ++ { ++ g_source_destroy (data->child_watch_source); ++ data->child_watch_source = NULL; ++ } ++ ++ if (data->child_pid != 0) ++ { ++ GSource *source; ++ kill (data->child_pid, SIGTERM); ++ /* OK, we need to reap for the child ourselves - we don't want ++ * to use waitpid() because that might block the calling ++ * thread (the child might handle SIGTERM and use several ++ * seconds for cleanup/rollback). ++ * ++ * So we use GChildWatch instead. ++ * ++ * Avoid taking a references to ourselves. but note that we need ++ * to pass the GSource so we can nuke it once handled. ++ */ ++ source = g_child_watch_source_new (data->child_pid); ++ g_source_set_callback (source, ++ (GSourceFunc) utils_child_watch_from_release_cb, ++ source, ++ (GDestroyNotify) g_source_destroy); ++ g_source_attach (source, data->main_context); ++ g_source_unref (source); ++ data->child_pid = 0; ++ } ++ ++ if (data->child_stdout != NULL) ++ { ++ g_string_free (data->child_stdout, TRUE); ++ data->child_stdout = NULL; ++ } ++ ++ if (data->child_stderr != NULL) ++ { ++ g_string_free (data->child_stderr, TRUE); ++ data->child_stderr = NULL; ++ } ++ ++ if (data->child_stdout_channel != NULL) ++ { ++ g_io_channel_unref (data->child_stdout_channel); ++ data->child_stdout_channel = NULL; ++ } ++ if (data->child_stderr_channel != NULL) ++ { ++ g_io_channel_unref (data->child_stderr_channel); ++ data->child_stderr_channel = NULL; ++ } ++ ++ if (data->child_stdout_source != NULL) ++ { ++ g_source_destroy (data->child_stdout_source); ++ data->child_stdout_source = NULL; ++ } ++ if (data->child_stderr_source != NULL) ++ { ++ g_source_destroy (data->child_stderr_source); ++ data->child_stderr_source = NULL; ++ } ++ ++ if (data->child_stdout_fd != -1) ++ { ++ g_warn_if_fail (close (data->child_stdout_fd) == 0); ++ data->child_stdout_fd = -1; ++ } ++ if (data->child_stderr_fd != -1) ++ { ++ g_warn_if_fail (close (data->child_stderr_fd) == 0); ++ data->child_stderr_fd = -1; ++ } ++ ++ if (data->cancellable_handler_id > 0) ++ { ++ g_cancellable_disconnect (data->cancellable, data->cancellable_handler_id); ++ data->cancellable_handler_id = 0; ++ } ++ ++ if (data->main_context != NULL) ++ g_main_context_unref (data->main_context); ++ ++ if (data->cancellable != NULL) ++ g_object_unref (data->cancellable); ++ ++ g_slice_free (UtilsSpawnData, data); ++} ++ ++/* called in the thread where @cancellable was cancelled */ ++static void ++utils_on_cancelled (GCancellable *cancellable, ++ gpointer user_data) ++{ ++ UtilsSpawnData *data = (UtilsSpawnData *)user_data; ++ GError *error; ++ ++ error = NULL; ++ g_warn_if_fail (g_cancellable_set_error_if_cancelled (cancellable, &error)); ++ g_simple_async_result_take_error (data->simple, error); ++ g_simple_async_result_complete_in_idle (data->simple); ++ g_object_unref (data->simple); ++} ++ ++static gboolean ++utils_read_child_stderr (GIOChannel *channel, ++ GIOCondition condition, ++ gpointer user_data) ++{ ++ UtilsSpawnData *data = (UtilsSpawnData *)user_data; ++ gchar buf[1024]; ++ gsize bytes_read; ++ ++ g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL); ++ g_string_append_len (data->child_stderr, buf, bytes_read); ++ return TRUE; ++} ++ ++static gboolean ++utils_read_child_stdout (GIOChannel *channel, ++ GIOCondition condition, ++ gpointer user_data) ++{ ++ UtilsSpawnData *data = (UtilsSpawnData *)user_data; ++ gchar buf[1024]; ++ gsize bytes_read; ++ ++ g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL); ++ g_string_append_len (data->child_stdout, buf, bytes_read); ++ return TRUE; ++} ++ ++static void ++utils_child_watch_cb (GPid pid, ++ gint status, ++ gpointer user_data) ++{ ++ UtilsSpawnData *data = (UtilsSpawnData *)user_data; ++ gchar *buf; ++ gsize buf_size; ++ ++ if (g_io_channel_read_to_end (data->child_stdout_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL) ++ { ++ g_string_append_len (data->child_stdout, buf, buf_size); ++ g_free (buf); ++ } ++ if (g_io_channel_read_to_end (data->child_stderr_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL) ++ { ++ g_string_append_len (data->child_stderr, buf, buf_size); ++ g_free (buf); ++ } ++ ++ data->exit_status = status; ++ ++ /* ok, child watch is history, make sure we don't free it in spawn_data_free() */ ++ data->child_pid = 0; ++ data->child_watch_source = NULL; ++ ++ /* we're done */ ++ g_simple_async_result_complete_in_idle (data->simple); ++ g_object_unref (data->simple); ++} ++ ++static gboolean ++utils_timeout_cb (gpointer user_data) ++{ ++ UtilsSpawnData *data = (UtilsSpawnData *)user_data; ++ ++ data->timed_out = TRUE; ++ ++ /* ok, timeout is history, make sure we don't free it in spawn_data_free() */ ++ data->timeout_source = NULL; ++ ++ /* we're done */ ++ g_simple_async_result_complete_in_idle (data->simple); ++ g_object_unref (data->simple); ++ ++ return FALSE; /* remove source */ ++} ++ ++static void ++utils_spawn (const gchar *const *argv, ++ guint timeout_seconds, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ UtilsSpawnData *data; ++ GError *error; ++ ++ data = g_slice_new0 (UtilsSpawnData); ++ data->timeout_seconds = timeout_seconds; ++ data->simple = g_simple_async_result_new (NULL, ++ callback, ++ user_data, ++ (gpointer*)utils_spawn); ++ data->main_context = g_main_context_get_thread_default (); ++ if (data->main_context != NULL) ++ g_main_context_ref (data->main_context); ++ ++ data->cancellable = cancellable != NULL ? (GCancellable*)g_object_ref (cancellable) : NULL; ++ ++ data->child_stdout = g_string_new (NULL); ++ data->child_stderr = g_string_new (NULL); ++ data->child_stdout_fd = -1; ++ data->child_stderr_fd = -1; ++ ++ /* the life-cycle of UtilsSpawnData is tied to its GSimpleAsyncResult */ ++ g_simple_async_result_set_op_res_gpointer (data->simple, data, (GDestroyNotify) utils_spawn_data_free); ++ ++ error = NULL; ++ if (data->cancellable != NULL) ++ { ++ /* could already be cancelled */ ++ error = NULL; ++ if (g_cancellable_set_error_if_cancelled (data->cancellable, &error)) ++ { ++ g_simple_async_result_take_error (data->simple, error); ++ g_simple_async_result_complete_in_idle (data->simple); ++ g_object_unref (data->simple); ++ goto out; ++ } ++ ++ data->cancellable_handler_id = g_cancellable_connect (data->cancellable, ++ G_CALLBACK (utils_on_cancelled), ++ data, ++ NULL); ++ } ++ ++ error = NULL; ++ if (!g_spawn_async_with_pipes (NULL, /* working directory */ ++ (gchar **) argv, ++ NULL, /* envp */ ++ G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, ++ NULL, /* child_setup */ ++ NULL, /* child_setup's user_data */ ++ &(data->child_pid), ++ NULL, /* gint *stdin_fd */ ++ &(data->child_stdout_fd), ++ &(data->child_stderr_fd), ++ &error)) ++ { ++ g_prefix_error (&error, "Error spawning: "); ++ g_simple_async_result_take_error (data->simple, error); ++ g_simple_async_result_complete_in_idle (data->simple); ++ g_object_unref (data->simple); ++ goto out; ++ } ++ ++ if (timeout_seconds > 0) ++ { ++ data->timeout_source = g_timeout_source_new_seconds (timeout_seconds); ++ g_source_set_priority (data->timeout_source, G_PRIORITY_DEFAULT); ++ g_source_set_callback (data->timeout_source, utils_timeout_cb, data, NULL); ++ g_source_attach (data->timeout_source, data->main_context); ++ g_source_unref (data->timeout_source); ++ } ++ ++ data->child_watch_source = g_child_watch_source_new (data->child_pid); ++ g_source_set_callback (data->child_watch_source, (GSourceFunc) utils_child_watch_cb, data, NULL); ++ g_source_attach (data->child_watch_source, data->main_context); ++ g_source_unref (data->child_watch_source); ++ ++ data->child_stdout_channel = g_io_channel_unix_new (data->child_stdout_fd); ++ g_io_channel_set_flags (data->child_stdout_channel, G_IO_FLAG_NONBLOCK, NULL); ++ data->child_stdout_source = g_io_create_watch (data->child_stdout_channel, G_IO_IN); ++ g_source_set_callback (data->child_stdout_source, (GSourceFunc) utils_read_child_stdout, data, NULL); ++ g_source_attach (data->child_stdout_source, data->main_context); ++ g_source_unref (data->child_stdout_source); ++ ++ data->child_stderr_channel = g_io_channel_unix_new (data->child_stderr_fd); ++ g_io_channel_set_flags (data->child_stderr_channel, G_IO_FLAG_NONBLOCK, NULL); ++ data->child_stderr_source = g_io_create_watch (data->child_stderr_channel, G_IO_IN); ++ g_source_set_callback (data->child_stderr_source, (GSourceFunc) utils_read_child_stderr, data, NULL); ++ g_source_attach (data->child_stderr_source, data->main_context); ++ g_source_unref (data->child_stderr_source); ++ ++ out: ++ ; ++} ++ ++gboolean ++utils_spawn_finish (GAsyncResult *res, ++ gint *out_exit_status, ++ gchar **out_standard_output, ++ gchar **out_standard_error, ++ GError **error) ++{ ++ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); ++ UtilsSpawnData *data; ++ gboolean ret = FALSE; ++ ++ g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE); ++ g_return_val_if_fail (error == NULL || *error == NULL, FALSE); ++ ++ g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == utils_spawn); ++ ++ if (g_simple_async_result_propagate_error (simple, error)) ++ goto out; ++ ++ data = (UtilsSpawnData*)g_simple_async_result_get_op_res_gpointer (simple); ++ ++ if (data->timed_out) ++ { ++ g_set_error (error, ++ G_IO_ERROR, ++ G_IO_ERROR_TIMED_OUT, ++ "Timed out after %d seconds", ++ data->timeout_seconds); ++ goto out; ++ } ++ ++ if (out_exit_status != NULL) ++ *out_exit_status = data->exit_status; ++ ++ if (out_standard_output != NULL) ++ *out_standard_output = g_strdup (data->child_stdout->str); ++ ++ if (out_standard_error != NULL) ++ *out_standard_error = g_strdup (data->child_stderr->str); ++ ++ ret = TRUE; ++ ++ out: ++ return ret; ++} diff --git a/sys-auth/polkit/files/polkit-0.113-allow-negative-uids-gids.patch b/sys-auth/polkit/files/polkit-0.113-allow-negative-uids-gids.patch deleted file mode 100644 index 9a2a5038dd..0000000000 --- a/sys-auth/polkit/files/polkit-0.113-allow-negative-uids-gids.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 2cb40c4d5feeaa09325522bd7d97910f1b59e379 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= -Date: Mon, 3 Dec 2018 10:28:58 +0100 -Subject: [PATCH] Allow negative uids/gids in PolkitUnixUser and Group objects - -(uid_t) -1 is still used as placeholder to mean "unset". This is OK, since -there should be no users with such number, see -https://systemd.io/UIDS-GIDS#special-linux-uids. - -(uid_t) -1 is used as the default value in class initialization. - -When a user or group above INT32_MAX is created, the numeric uid or -gid wraps around to negative when the value is assigned to gint, and -polkit gets confused. Let's accept such gids, except for -1. - -A nicer fix would be to change the underlying type to e.g. uint32 to -not have negative values. But this cannot be done without breaking the -API, so likely new functions will have to be added (a -polkit_unix_user_new variant that takes a unsigned, and the same for -_group_new, _set_uid, _get_uid, _set_gid, _get_gid, etc.). This will -require a bigger patch. - -Fixes https://gitlab.freedesktop.org/polkit/polkit/issues/74. ---- - src/polkit/polkitunixgroup.c | 15 +++++++++++---- - src/polkit/polkitunixprocess.c | 12 ++++++++---- - src/polkit/polkitunixuser.c | 13 ++++++++++--- - 3 files changed, 29 insertions(+), 11 deletions(-) - -diff --git a/src/polkit/polkitunixgroup.c b/src/polkit/polkitunixgroup.c -index c57a1aa..309f689 100644 ---- a/src/polkit/polkitunixgroup.c -+++ b/src/polkit/polkitunixgroup.c -@@ -71,6 +71,7 @@ G_DEFINE_TYPE_WITH_CODE (PolkitUnixGroup, polkit_unix_group, G_TYPE_OBJECT, - static void - polkit_unix_group_init (PolkitUnixGroup *unix_group) - { -+ unix_group->gid = -1; /* (git_t) -1 is not a valid GID under Linux */ - } - - static void -@@ -100,11 +101,14 @@ polkit_unix_group_set_property (GObject *object, - GParamSpec *pspec) - { - PolkitUnixGroup *unix_group = POLKIT_UNIX_GROUP (object); -+ gint val; - - switch (prop_id) - { - case PROP_GID: -- unix_group->gid = g_value_get_int (value); -+ val = g_value_get_int (value); -+ g_return_if_fail (val != -1); -+ unix_group->gid = val; - break; - - default: -@@ -131,9 +135,9 @@ polkit_unix_group_class_init (PolkitUnixGroupClass *klass) - g_param_spec_int ("gid", - "Group ID", - "The UNIX group ID", -- 0, -+ G_MININT, - G_MAXINT, -- 0, -+ -1, - G_PARAM_CONSTRUCT | - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | -@@ -166,9 +170,10 @@ polkit_unix_group_get_gid (PolkitUnixGroup *group) - */ - void - polkit_unix_group_set_gid (PolkitUnixGroup *group, -- gint gid) -+ gint gid) - { - g_return_if_fail (POLKIT_IS_UNIX_GROUP (group)); -+ g_return_if_fail (gid != -1); - group->gid = gid; - } - -@@ -183,6 +188,8 @@ polkit_unix_group_set_gid (PolkitUnixGroup *group, - PolkitIdentity * - polkit_unix_group_new (gint gid) - { -+ g_return_val_if_fail (gid != -1, NULL); -+ - return POLKIT_IDENTITY (g_object_new (POLKIT_TYPE_UNIX_GROUP, - "gid", gid, - NULL)); -diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c -index 972b777..b02b258 100644 ---- a/src/polkit/polkitunixprocess.c -+++ b/src/polkit/polkitunixprocess.c -@@ -159,9 +159,14 @@ polkit_unix_process_set_property (GObject *object, - polkit_unix_process_set_pid (unix_process, g_value_get_int (value)); - break; - -- case PROP_UID: -- polkit_unix_process_set_uid (unix_process, g_value_get_int (value)); -+ case PROP_UID: { -+ gint val; -+ -+ val = g_value_get_int (value); -+ g_return_if_fail (val != -1); -+ polkit_unix_process_set_uid (unix_process, val); - break; -+ } - - case PROP_START_TIME: - polkit_unix_process_set_start_time (unix_process, g_value_get_uint64 (value)); -@@ -239,7 +244,7 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass) - g_param_spec_int ("uid", - "User ID", - "The UNIX user ID", -- -1, -+ G_MININT, - G_MAXINT, - -1, - G_PARAM_CONSTRUCT | -@@ -303,7 +308,6 @@ polkit_unix_process_set_uid (PolkitUnixProcess *process, - gint uid) - { - g_return_if_fail (POLKIT_IS_UNIX_PROCESS (process)); -- g_return_if_fail (uid >= -1); - process->uid = uid; - } - -diff --git a/src/polkit/polkitunixuser.c b/src/polkit/polkitunixuser.c -index 8bfd3a1..234a697 100644 ---- a/src/polkit/polkitunixuser.c -+++ b/src/polkit/polkitunixuser.c -@@ -72,6 +72,7 @@ G_DEFINE_TYPE_WITH_CODE (PolkitUnixUser, polkit_unix_user, G_TYPE_OBJECT, - static void - polkit_unix_user_init (PolkitUnixUser *unix_user) - { -+ unix_user->uid = -1; /* (uid_t) -1 is not a valid UID under Linux */ - unix_user->name = NULL; - } - -@@ -112,11 +113,14 @@ polkit_unix_user_set_property (GObject *object, - GParamSpec *pspec) - { - PolkitUnixUser *unix_user = POLKIT_UNIX_USER (object); -+ gint val; - - switch (prop_id) - { - case PROP_UID: -- unix_user->uid = g_value_get_int (value); -+ val = g_value_get_int (value); -+ g_return_if_fail (val != -1); -+ unix_user->uid = val; - break; - - default: -@@ -144,9 +148,9 @@ polkit_unix_user_class_init (PolkitUnixUserClass *klass) - g_param_spec_int ("uid", - "User ID", - "The UNIX user ID", -- 0, -+ G_MININT, - G_MAXINT, -- 0, -+ -1, - G_PARAM_CONSTRUCT | - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | -@@ -182,6 +186,7 @@ polkit_unix_user_set_uid (PolkitUnixUser *user, - gint uid) - { - g_return_if_fail (POLKIT_IS_UNIX_USER (user)); -+ g_return_if_fail (uid != -1); - user->uid = uid; - } - -@@ -196,6 +201,8 @@ polkit_unix_user_set_uid (PolkitUnixUser *user, - PolkitIdentity * - polkit_unix_user_new (gint uid) - { -+ g_return_val_if_fail (uid != -1, NULL); -+ - return POLKIT_IDENTITY (g_object_new (POLKIT_TYPE_UNIX_USER, - "uid", uid, - NULL)); --- -2.18.1 - diff --git a/sys-auth/polkit/files/polkit-0.113-allow-uid-of-1-for-a-PolkitUnixProcess.patch b/sys-auth/polkit/files/polkit-0.113-allow-uid-of-1-for-a-PolkitUnixProcess.patch deleted file mode 100644 index e9f5649532..0000000000 --- a/sys-auth/polkit/files/polkit-0.113-allow-uid-of-1-for-a-PolkitUnixProcess.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 87aec8b7275665c85fe22bcc8e74d2a0422535ce Mon Sep 17 00:00:00 2001 -From: Matthew Leeds -Date: Tue, 11 Dec 2018 12:04:26 -0800 -Subject: [PATCH] Allow uid of -1 for a PolkitUnixProcess - -Commit 2cb40c4d5 changed PolkitUnixUser, PolkitUnixGroup, and -PolkitUnixProcess to allow negative values for their uid/gid properties, -since these are values above INT_MAX which wrap around but are still -valid, with the exception of -1 which is not valid. However, -PolkitUnixProcess allows a uid of -1 to be passed to -polkit_unix_process_new_for_owner() which means polkit is expected to -figure out the uid on its own (this happens in the _constructed -function). So this commit removes the check in -polkit_unix_process_set_property() so that new_for_owner() can be used -as documented without producing a critical error message. - -This does not affect the protection against CVE-2018-19788 which is -based on creating a user with a UID up to but not including 4294967295 -(-1). ---- - src/polkit/polkitunixprocess.c | 9 ++------- - 1 file changed, 2 insertions(+), 7 deletions(-) - -diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c -index 2c57813..93dea3c 100644 ---- a/src/polkit/polkitunixprocess.c -+++ b/src/polkit/polkitunixprocess.c -@@ -142,14 +142,9 @@ polkit_unix_process_set_property (GObject *object, - polkit_unix_process_set_pid (unix_process, g_value_get_int (value)); - break; - -- case PROP_UID: { -- gint val; -- -- val = g_value_get_int (value); -- g_return_if_fail (val != -1); -- polkit_unix_process_set_uid (unix_process, val); -+ case PROP_UID: -+ polkit_unix_process_set_uid (unix_process, g_value_get_int (value)); - break; -- } - - case PROP_START_TIME: - polkit_unix_process_set_start_time (unix_process, g_value_get_uint64 (value)); --- -2.21.0 - diff --git a/sys-auth/polkit/files/polkit-0.113-fix-CVE-2018-1116-Trusting-client-supplied-UID.patch b/sys-auth/polkit/files/polkit-0.113-fix-CVE-2018-1116-Trusting-client-supplied-UID.patch deleted file mode 100644 index 983acf4723..0000000000 --- a/sys-auth/polkit/files/polkit-0.113-fix-CVE-2018-1116-Trusting-client-supplied-UID.patch +++ /dev/null @@ -1,572 +0,0 @@ -From 82494ed6bcff05b5a65c00bcf5212dcd2b559f70 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= -Date: Fri, 23 Aug 2019 20:31:11 -0400 -Subject: [PATCH] Fix CVE-2018-1116: Trusting client-supplied UID -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -As part of CVE-2013-4288, the D-Bus clients were allowed (and -encouraged) to submit the UID of the subject of authorization checks -to avoid races against UID changes (notably using executables -set-UID to root). - -However, that also allowed any client to submit an arbitrary UID, and -that could be used to bypass "can only ask about / affect the same UID" -checks in CheckAuthorization / RegisterAuthenticationAgent / -UnregisterAuthenticationAgent. This allowed an attacker: - -- With CheckAuthorization, to cause the registered authentication - agent in victim's session to pop up a dialog, or to determine whether - the victim currently has a temporary authorization to perform an - operation. - - (In principle, the attacker can also determine whether JavaScript - rules allow the victim process to perform an operation; however, - usually rules base their decisions on information determined from - the supplied UID, so the attacker usually won't learn anything new.) - -- With RegisterAuthenticationAgent, to prevent the victim's - authentication agent to work (for a specific victim process), - or to learn about which operations requiring authorization - the victim is attempting. - -To fix this, expose internal _polkit_unix_process_get_owner() / -obsolete polkit_unix_process_get_owner() as a private -polkit_unix_process_get_racy_uid__() (being more explicit about the -dangers on relying on it), and use it in -polkit_backend_session_monitor_get_user_for_subject() to return -a boolean indicating whether the subject UID may be caller-chosen. - -Then, in the permission checks that require the subject to be -equal to the caller, fail on caller-chosen UIDs (and continue -through the pre-existing code paths which allow root, or root-designated -server processes, to ask about arbitrary subjects.) - -Signed-off-by: Miloslav Trmač ---- - src/polkit/polkitprivate.h | 2 + - src/polkit/polkitunixprocess.c | 60 +++++++++++++++---- - .../polkitbackendinteractiveauthority.c | 39 +++++++----- - .../polkitbackendsessionmonitor-systemd.c | 38 ++++++++++-- - .../polkitbackendsessionmonitor.c | 40 +++++++++++-- - .../polkitbackendsessionmonitor.h | 1 + - 6 files changed, 147 insertions(+), 33 deletions(-) - -diff --git a/src/polkit/polkitprivate.h b/src/polkit/polkitprivate.h -index 9f07063..c80142d 100644 ---- a/src/polkit/polkitprivate.h -+++ b/src/polkit/polkitprivate.h -@@ -44,6 +44,8 @@ GVariant *polkit_action_description_to_gvariant (PolkitActionDescription *action - GVariant *polkit_subject_to_gvariant (PolkitSubject *subject); - GVariant *polkit_identity_to_gvariant (PolkitIdentity *identity); - -+gint polkit_unix_process_get_racy_uid__ (PolkitUnixProcess *process, GError **error); -+ - PolkitSubject *polkit_subject_new_for_gvariant (GVariant *variant, GError **error); - PolkitIdentity *polkit_identity_new_for_gvariant (GVariant *variant, GError **error); - -diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c -index 93dea3c..f799942 100644 ---- a/src/polkit/polkitunixprocess.c -+++ b/src/polkit/polkitunixprocess.c -@@ -49,6 +49,14 @@ - * To uniquely identify processes, both the process id and the start - * time of the process (a monotonic increasing value representing the - * time since the kernel was started) is used. -+ * -+ * NOTE: This object stores, and provides access to, the real UID of the -+ * process. That value can change over time (with set*uid*(2) and exec*(2)). -+ * Checks whether an operation is allowed need to take care to use the UID -+ * value as of the time when the operation was made (or, following the open() -+ * privilege check model, when the connection making the operation possible -+ * was initiated). That is usually done by initializing this with -+ * polkit_unix_process_new_for_owner() with trusted data. - */ - - /** -@@ -83,9 +91,6 @@ static void subject_iface_init (PolkitSubjectIface *subject_iface); - static guint64 get_start_time_for_pid (gint pid, - GError **error); - --static gint _polkit_unix_process_get_owner (PolkitUnixProcess *process, -- GError **error); -- - #ifdef HAVE_FREEBSD - static gboolean get_kinfo_proc (gint pid, struct kinfo_proc *p); - #endif -@@ -170,7 +175,7 @@ polkit_unix_process_constructed (GObject *object) - { - GError *error; - error = NULL; -- process->uid = _polkit_unix_process_get_owner (process, &error); -+ process->uid = polkit_unix_process_get_racy_uid__ (process, &error); - if (error != NULL) - { - process->uid = -1; -@@ -259,6 +264,12 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass) - * Gets the user id for @process. Note that this is the real user-id, - * not the effective user-id. - * -+ * NOTE: The UID may change over time, so the returned value may not match the -+ * current state of the underlying process; or the UID may have been set by -+ * polkit_unix_process_new_for_owner() or polkit_unix_process_set_uid(), -+ * in which case it may not correspond to the actual UID of the referenced -+ * process at all (at any point in time). -+ * - * Returns: The user id for @process or -1 if unknown. - */ - gint -@@ -654,18 +665,26 @@ out: - return start_time; - } - --static gint --_polkit_unix_process_get_owner (PolkitUnixProcess *process, -- GError **error) -+/* -+ * Private: Return the "current" UID. Note that this is inherently racy, -+ * and the value may already be obsolete by the time this function returns; -+ * this function only guarantees that the UID was valid at some point during -+ * its execution. -+ */ -+gint -+polkit_unix_process_get_racy_uid__ (PolkitUnixProcess *process, -+ GError **error) - { - gint result; - gchar *contents; - gchar **lines; -+ guint64 start_time; - #ifdef HAVE_FREEBSD - struct kinfo_proc p; - #else - gchar filename[64]; - guint n; -+ GError *local_error; - #endif - - g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), 0); -@@ -688,6 +707,7 @@ _polkit_unix_process_get_owner (PolkitUnixProcess *process, - } - - result = p.ki_uid; -+ start_time = (guint64) p.ki_start.tv_sec; - #else - - /* see 'man proc' for layout of the status file -@@ -721,17 +741,37 @@ _polkit_unix_process_get_owner (PolkitUnixProcess *process, - else - { - result = real_uid; -- goto out; -+ goto found; - } - } -- - g_set_error (error, - POLKIT_ERROR, - POLKIT_ERROR_FAILED, - "Didn't find any line starting with `Uid:' in file %s", - filename); -+ goto out; -+ -+found: -+ /* The UID and start time are, sadly, not available in a single file. So, -+ * read the UID first, and then the start time; if the start time is the same -+ * before and after reading the UID, it couldn't have changed. -+ */ -+ local_error = NULL; -+ start_time = get_start_time_for_pid (process->pid, &local_error); -+ if (local_error != NULL) -+ { -+ g_propagate_error (error, local_error); -+ goto out; -+ } - #endif - -+ if (process->start_time != start_time) -+ { -+ g_set_error (error, POLKIT_ERROR, POLKIT_ERROR_FAILED, -+ "process with PID %d has been replaced", process->pid); -+ goto out; -+ } -+ - out: - g_strfreev (lines); - g_free (contents); -@@ -750,5 +790,5 @@ gint - polkit_unix_process_get_owner (PolkitUnixProcess *process, - GError **error) - { -- return _polkit_unix_process_get_owner (process, error); -+ return polkit_unix_process_get_racy_uid__ (process, error); - } -diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c -index 7019356..0b587a3 100644 ---- a/src/polkitbackend/polkitbackendinteractiveauthority.c -+++ b/src/polkitbackend/polkitbackendinteractiveauthority.c -@@ -572,7 +572,7 @@ log_result (PolkitBackendInteractiveAuthority *authority, - if (polkit_authorization_result_get_is_authorized (result)) - log_result_str = "ALLOWING"; - -- user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL); -+ user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL, NULL); - - subject_str = polkit_subject_to_string (subject); - -@@ -844,6 +844,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority - gchar *subject_str; - PolkitIdentity *user_of_caller; - PolkitIdentity *user_of_subject; -+ gboolean user_of_subject_matches; - gchar *user_of_caller_str; - gchar *user_of_subject_str; - PolkitAuthorizationResult *result; -@@ -889,7 +890,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority - action_id); - - user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, -- caller, -+ caller, NULL, - &error); - if (error != NULL) - { -@@ -904,7 +905,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority - g_debug (" user of caller is %s", user_of_caller_str); - - user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, -- subject, -+ subject, &user_of_subject_matches, - &error); - if (error != NULL) - { -@@ -934,7 +935,10 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority - * We only allow this if, and only if, - * - * - processes may check for another process owned by the *same* user but not -- * if details are passed (otherwise you'd be able to spoof the dialog) -+ * if details are passed (otherwise you'd be able to spoof the dialog); -+ * the caller supplies the user_of_subject value, so we additionally -+ * require it to match at least at one point in time (via -+ * user_of_subject_matches). - * - * - processes running as uid 0 may check anything and pass any details - * -@@ -942,7 +946,9 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority - * then any uid referenced by that annotation is also allowed to check - * to check anything and pass any details - */ -- if (!polkit_identity_equal (user_of_caller, user_of_subject) || has_details) -+ if (!user_of_subject_matches -+ || !polkit_identity_equal (user_of_caller, user_of_subject) -+ || has_details) - { - if (!may_identity_check_authorization (interactive_authority, action_id, user_of_caller)) - { -@@ -1107,9 +1113,10 @@ check_authorization_sync (PolkitBackendAuthority *authority, - goto out; - } - -- /* every subject has a user */ -+ /* every subject has a user; this is supplied by the client, so we rely -+ * on the caller to validate its acceptability. */ - user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, -- subject, -+ subject, NULL, - error); - if (user_of_subject == NULL) - goto out; -@@ -2475,6 +2482,7 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken - PolkitSubject *session_for_caller; - PolkitIdentity *user_of_caller; - PolkitIdentity *user_of_subject; -+ gboolean user_of_subject_matches; - AuthenticationAgent *agent; - gboolean ret; - gchar *caller_cmdline; -@@ -2527,7 +2535,7 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken - goto out; - } - -- user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL); -+ user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL, NULL); - if (user_of_caller == NULL) - { - g_set_error (error, -@@ -2536,7 +2544,7 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken - "Cannot determine user of caller"); - goto out; - } -- user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL); -+ user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, &user_of_subject_matches, NULL); - if (user_of_subject == NULL) - { - g_set_error (error, -@@ -2545,7 +2553,8 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken - "Cannot determine user of subject"); - goto out; - } -- if (!polkit_identity_equal (user_of_caller, user_of_subject)) -+ if (!user_of_subject_matches -+ || !polkit_identity_equal (user_of_caller, user_of_subject)) - { - if (identity_is_root_user (user_of_caller)) - { -@@ -2638,6 +2647,7 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack - PolkitSubject *session_for_caller; - PolkitIdentity *user_of_caller; - PolkitIdentity *user_of_subject; -+ gboolean user_of_subject_matches; - AuthenticationAgent *agent; - gboolean ret; - gchar *scope_str; -@@ -2686,7 +2696,7 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack - goto out; - } - -- user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL); -+ user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL, NULL); - if (user_of_caller == NULL) - { - g_set_error (error, -@@ -2695,7 +2705,7 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack - "Cannot determine user of caller"); - goto out; - } -- user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL); -+ user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, &user_of_subject_matches, NULL); - if (user_of_subject == NULL) - { - g_set_error (error, -@@ -2704,7 +2714,8 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack - "Cannot determine user of subject"); - goto out; - } -- if (!polkit_identity_equal (user_of_caller, user_of_subject)) -+ if (!user_of_subject_matches -+ || !polkit_identity_equal (user_of_caller, user_of_subject)) - { - if (identity_is_root_user (user_of_caller)) - { -@@ -2814,7 +2825,7 @@ polkit_backend_interactive_authority_authentication_agent_response (PolkitBacken - identity_str); - - user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, -- caller, -+ caller, NULL, - error); - if (user_of_caller == NULL) - goto out; -diff --git a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c -index 2a6c739..b00cdbd 100644 ---- a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c -+++ b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c -@@ -29,6 +29,7 @@ - #include - - #include -+#include - #include "polkitbackendsessionmonitor.h" - - /* -@@ -246,26 +247,40 @@ polkit_backend_session_monitor_get_sessions (PolkitBackendSessionMonitor *monito - * polkit_backend_session_monitor_get_user: - * @monitor: A #PolkitBackendSessionMonitor. - * @subject: A #PolkitSubject. -+ * @result_matches: If not %NULL, set to indicate whether the return value matches current (RACY) state. - * @error: Return location for error. - * - * Gets the user corresponding to @subject or %NULL if no user exists. - * -+ * NOTE: For a #PolkitUnixProcess, the UID is read from @subject (which may -+ * come from e.g. a D-Bus client), so it may not correspond to the actual UID -+ * of the referenced process (at any point in time). This is indicated by -+ * setting @result_matches to %FALSE; the caller may reject such subjects or -+ * require additional privileges. @result_matches == %TRUE only indicates that -+ * the UID matched the underlying process at ONE point in time, it may not match -+ * later. -+ * - * Returns: %NULL if @error is set otherwise a #PolkitUnixUser that should be freed with g_object_unref(). - */ - PolkitIdentity * - polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor *monitor, - PolkitSubject *subject, -+ gboolean *result_matches, - GError **error) - { - PolkitIdentity *ret; -- guint32 uid; -+ gboolean matches; - - ret = NULL; -+ matches = FALSE; - - if (POLKIT_IS_UNIX_PROCESS (subject)) - { -- uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); -- if ((gint) uid == -1) -+ gint subject_uid, current_uid; -+ GError *local_error; -+ -+ subject_uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); -+ if (subject_uid == -1) - { - g_set_error (error, - POLKIT_ERROR, -@@ -273,14 +288,24 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor - "Unix process subject does not have uid set"); - goto out; - } -- ret = polkit_unix_user_new (uid); -+ local_error = NULL; -+ current_uid = polkit_unix_process_get_racy_uid__ (POLKIT_UNIX_PROCESS (subject), &local_error); -+ if (local_error != NULL) -+ { -+ g_propagate_error (error, local_error); -+ goto out; -+ } -+ ret = polkit_unix_user_new (subject_uid); -+ matches = (subject_uid == current_uid); - } - else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) - { - ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error); -+ matches = TRUE; - } - else if (POLKIT_IS_UNIX_SESSION (subject)) - { -+ uid_t uid; - - if (sd_session_get_uid (polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (subject)), &uid) < 0) - { -@@ -292,9 +317,14 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor - } - - ret = polkit_unix_user_new (uid); -+ matches = TRUE; - } - - out: -+ if (result_matches != NULL) -+ { -+ *result_matches = matches; -+ } - return ret; - } - -diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c -index e1a9ab3..ed30755 100644 ---- a/src/polkitbackend/polkitbackendsessionmonitor.c -+++ b/src/polkitbackend/polkitbackendsessionmonitor.c -@@ -27,6 +27,7 @@ - #include - - #include -+#include - #include "polkitbackendsessionmonitor.h" - - #define CKDB_PATH "/var/run/ConsoleKit/database" -@@ -273,28 +274,40 @@ polkit_backend_session_monitor_get_sessions (PolkitBackendSessionMonitor *monito - * polkit_backend_session_monitor_get_user: - * @monitor: A #PolkitBackendSessionMonitor. - * @subject: A #PolkitSubject. -+ * @result_matches: If not %NULL, set to indicate whether the return value matches current (RACY) state. - * @error: Return location for error. - * - * Gets the user corresponding to @subject or %NULL if no user exists. - * -+ * NOTE: For a #PolkitUnixProcess, the UID is read from @subject (which may -+ * come from e.g. a D-Bus client), so it may not correspond to the actual UID -+ * of the referenced process (at any point in time). This is indicated by -+ * setting @result_matches to %FALSE; the caller may reject such subjects or -+ * require additional privileges. @result_matches == %TRUE only indicates that -+ * the UID matched the underlying process at ONE point in time, it may not match -+ * later. -+ * - * Returns: %NULL if @error is set otherwise a #PolkitUnixUser that should be freed with g_object_unref(). - */ - PolkitIdentity * - polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor *monitor, - PolkitSubject *subject, -+ gboolean *result_matches, - GError **error) - { - PolkitIdentity *ret; -+ gboolean matches; - GError *local_error; -- gchar *group; -- guint32 uid; - - ret = NULL; -+ matches = FALSE; - - if (POLKIT_IS_UNIX_PROCESS (subject)) - { -- uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); -- if ((gint) uid == -1) -+ gint subject_uid, current_uid; -+ -+ subject_uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); -+ if (subject_uid == -1) - { - g_set_error (error, - POLKIT_ERROR, -@@ -302,14 +315,26 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor - "Unix process subject does not have uid set"); - goto out; - } -- ret = polkit_unix_user_new (uid); -+ local_error = NULL; -+ current_uid = polkit_unix_process_get_racy_uid__ (POLKIT_UNIX_PROCESS (subject), &local_error); -+ if (local_error != NULL) -+ { -+ g_propagate_error (error, local_error); -+ goto out; -+ } -+ ret = polkit_unix_user_new (subject_uid); -+ matches = (subject_uid == current_uid); - } - else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) - { - ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error); -+ matches = TRUE; - } - else if (POLKIT_IS_UNIX_SESSION (subject)) - { -+ gint uid; -+ gchar *group; -+ - if (!ensure_database (monitor, error)) - { - g_prefix_error (error, "Error getting user for session: Error ensuring CK database at " CKDB_PATH ": "); -@@ -328,9 +353,14 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor - g_free (group); - - ret = polkit_unix_user_new (uid); -+ matches = TRUE; - } - - out: -+ if (result_matches != NULL) -+ { -+ *result_matches = matches; -+ } - return ret; - } - -diff --git a/src/polkitbackend/polkitbackendsessionmonitor.h b/src/polkitbackend/polkitbackendsessionmonitor.h -index 8f8a2ca..3972326 100644 ---- a/src/polkitbackend/polkitbackendsessionmonitor.h -+++ b/src/polkitbackend/polkitbackendsessionmonitor.h -@@ -47,6 +47,7 @@ GList *polkit_backend_session_monitor_get_sessions (Polkit - - PolkitIdentity *polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor *monitor, - PolkitSubject *subject, -+ gboolean *result_matches, - GError **error); - - PolkitSubject *polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMonitor *monitor, --- -2.21.0 - diff --git a/sys-auth/polkit/files/polkit-0.113-gir-cross-compile.patch b/sys-auth/polkit/files/polkit-0.113-gir-cross-compile.patch deleted file mode 100644 index 64bff277a7..0000000000 --- a/sys-auth/polkit/files/polkit-0.113-gir-cross-compile.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- polkit-0.113.orig/configure 2015-06-19 13:31:13.000000000 -0700 -+++ polkit-0.113/configure 2016-04-27 16:00:31.800252583 -0700 -@@ -14949,14 +14949,14 @@ - INTROSPECTION_GIRDIR= - INTROSPECTION_TYPELIBDIR= - if test "x$found_introspection" = "xyes"; then -- INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` -- INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` -- INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0` -+ INTROSPECTION_SCANNER=${SYSROOT}/`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` -+ INTROSPECTION_COMPILER=${SYROOT}/`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` -+ INTROSPECTION_GENERATE=${SYSROOT}/`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0` - INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0` - INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)" - INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0` - INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0` -- INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection -+ INTROSPECTION_MAKEFILE=${SYSROOT}/`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection - fi - - diff --git a/sys-auth/polkit/files/polkit-0.115-elogind.patch b/sys-auth/polkit/files/polkit-0.115-elogind.patch new file mode 100644 index 0000000000..93d672015d --- /dev/null +++ b/sys-auth/polkit/files/polkit-0.115-elogind.patch @@ -0,0 +1,28 @@ +From 08bb656496cd3d6213bbe9473f63f2d4a110da6e Mon Sep 17 00:00:00 2001 +From: Rasmus Thomsen +Date: Wed, 11 Apr 2018 13:14:14 +0200 +Subject: [PATCH] configure: fix elogind support + +HAVE_LIBSYSTEMD is used to determine which source files to use. +We have to check if either have_libsystemd or have_libelogind is +true, as both of these need the source files which are used when +HAVE_LIBSYSTEMD is true. +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 36df239..da47ecb 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -221,7 +221,7 @@ AS_IF([test "x$cross_compiling" != "xyes" ], [ + + AC_SUBST(LIBSYSTEMD_CFLAGS) + AC_SUBST(LIBSYSTEMD_LIBS) +-AM_CONDITIONAL(HAVE_LIBSYSTEMD, [test "$have_libsystemd" = "yes"], [Using libsystemd]) ++AM_CONDITIONAL(HAVE_LIBSYSTEMD, [test "$have_libsystemd" = "yes" || test "$have_libelogind" = "yes" ], [Using libsystemd]) + + dnl --------------------------------------------------------------------------- + dnl - systemd unit / service files +-- +2.17.0 diff --git a/sys-auth/polkit/metadata.xml b/sys-auth/polkit/metadata.xml index d553f2f472..b6d2fdc3ca 100644 --- a/sys-auth/polkit/metadata.xml +++ b/sys-auth/polkit/metadata.xml @@ -1,11 +1,11 @@ - freedesktop - + freedesktop-bugs@gentoo.org - Use sys-apps/systemd instead of sys-auth/consolekit for session tracking + Use sys-auth/elogind for session tracking + Use sys-apps/systemd for session tracking diff --git a/sys-auth/polkit/polkit-0.113-r5.ebuild b/sys-auth/polkit/polkit-0.113-r5.ebuild deleted file mode 100644 index dee08f002b..0000000000 --- a/sys-auth/polkit/polkit-0.113-r5.ebuild +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 1999-2015 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Id$ - -EAPI=5 -inherit eutils multilib pam pax-utils toolchain-funcs systemd user - -DESCRIPTION="Policy framework for controlling privileges for system-wide services" -HOMEPAGE="http://www.freedesktop.org/wiki/Software/polkit" -SRC_URI="http://www.freedesktop.org/software/${PN}/releases/${P}.tar.gz" - -LICENSE="LGPL-2" -SLOT="0" -KEYWORDS="alpha amd64 arm64 arm hppa ia64 ~mips ppc ppc64 ~s390 ~sh ~sparc x86" -IUSE="examples gtk +introspection jit kde nls pam selinux systemd test" - -CDEPEND=" - dev-lang/spidermonkey:0/mozjs185[-debug] - >=dev-libs/glib-2.32:2 - >=dev-libs/expat-2:= - pam? ( - sys-auth/pambase - sys-libs/pam - ) - systemd? ( sys-apps/systemd:0= ) -" -DEPEND="${CDEPEND} - app-text/docbook-xml-dtd:4.1.2 - app-text/docbook-xsl-stylesheets - introspection? ( >=dev-libs/gobject-introspection-1:= ) - dev-libs/libxslt - dev-util/gtk-doc-am - dev-util/intltool - virtual/pkgconfig -" -RDEPEND="${CDEPEND} - selinux? ( sec-policy/selinux-policykit ) -" -PDEPEND=" - gtk? ( || ( - >=gnome-extra/polkit-gnome-0.105 - lxde-base/lxpolkit - ) ) - kde? ( || ( - kde-plasma/polkit-kde-agent - sys-auth/polkit-kde-agent - ) ) - !systemd? ( sys-auth/consolekit[policykit] ) -" - -QA_MULTILIB_PATHS=" - usr/lib/polkit-1/polkit-agent-helper-1 - usr/lib/polkit-1/polkitd" - -pkg_setup() { - local u=polkitd - local g=polkitd - local h=/var/lib/polkit-1 - - enewgroup ${g} - enewuser ${u} -1 -1 ${h} ${g} - esethome ${u} ${h} -} - -src_prepare() { - sed -i -e 's|unix-group:wheel|unix-user:0|' src/polkitbackend/*-default.rules || die #401513 - epatch ${FILESDIR}/polkit-0.113-gir-cross-compile.patch - epatch ${FILESDIR}/polkit-0.113-allow-negative-uids-gids.patch - epatch ${FILESDIR}/polkit-0.113-allow-uid-of-1-for-a-PolkitUnixProcess.patch - epatch ${FILESDIR}/polkit-0.113-fix-CVE-2018-1116-Trusting-client-supplied-UID.patch -} - -src_configure() { - tc-export CC - econf \ - --localstatedir="${EPREFIX}"/var \ - --disable-static \ - --enable-man-pages \ - --disable-gtk-doc \ - $(use_enable systemd libsystemd-login) \ - $(use_enable introspection) \ - --disable-examples \ - $(use_enable nls) \ - --with-mozjs=mozjs185 \ - "$(systemd_with_unitdir)" \ - --with-authfw=$(usex pam pam shadow) \ - $(use pam && echo --with-pam-module-dir="$(getpam_mod_dir)") \ - $(use_enable test) \ - --with-os-type=gentoo -} - -src_compile() { - default - - # Required for polkitd on hardened/PaX due to spidermonkey's JIT - pax-mark mr src/polkitbackend/.libs/polkitd test/polkitbackend/.libs/polkitbackendjsauthoritytest -} - -src_install() { - emake DESTDIR="${D}" install - - dodoc docs/TODO HACKING NEWS README - - # relocate default configs from /etc to /usr - dodir /usr/share/dbus-1/system.d - mv "${D}"/{etc,usr/share}/dbus-1/system.d/org.freedesktop.PolicyKit1.conf || die - mv "${D}"/{etc,usr/share}/polkit-1/rules.d/50-default.rules || die - rmdir "${D}"/etc/dbus-1/system.d "${D}"/etc/dbus-1 || die - - systemd_dotmpfilesd "${FILESDIR}/polkit.conf" - diropts -m0700 -o polkitd -g polkitd - dodir /var/lib/polkit-1 - - if use examples; then - insinto /usr/share/doc/${PF}/examples - doins src/examples/{*.c,*.policy*} - fi - - prune_libtool_files -} diff --git a/sys-auth/polkit/polkit-0.119-r2.ebuild b/sys-auth/polkit/polkit-0.119-r2.ebuild new file mode 100644 index 0000000000..5acbca3381 --- /dev/null +++ b/sys-auth/polkit/polkit-0.119-r2.ebuild @@ -0,0 +1,141 @@ +# Copyright 1999-2021 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=7 + +inherit autotools pam pax-utils systemd xdg-utils + +DESCRIPTION="Policy framework for controlling privileges for system-wide services" +HOMEPAGE="https://www.freedesktop.org/wiki/Software/polkit https://gitlab.freedesktop.org/polkit/polkit" +SRC_URI="https://www.freedesktop.org/software/${PN}/releases/${P}.tar.gz" + +LICENSE="LGPL-2" +SLOT="0" +KEYWORDS="amd64 arm arm64 ~mips ppc64 ~riscv ~s390 x86" +IUSE="elogind examples gtk +introspection kde nls pam selinux systemd test" +RESTRICT="!test? ( test )" + +REQUIRED_USE="^^ ( elogind systemd )" + +BDEPEND=" + acct-user/polkitd + app-text/docbook-xml-dtd:4.1.2 + app-text/docbook-xsl-stylesheets + dev-libs/glib + dev-libs/gobject-introspection-common + dev-libs/libxslt + dev-util/glib-utils + dev-util/gtk-doc-am + dev-util/intltool + sys-devel/gettext + virtual/pkgconfig + introspection? ( dev-libs/gobject-introspection ) +" +DEPEND=" + dev-lang/duktape + dev-libs/glib:2 + dev-libs/expat + elogind? ( sys-auth/elogind ) + pam? ( + sys-auth/pambase + sys-libs/pam + ) + !pam? ( virtual/libcrypt:= ) + systemd? ( sys-apps/systemd:0=[policykit] ) +" +RDEPEND="${DEPEND} + acct-user/polkitd + selinux? ( sec-policy/selinux-policykit ) +" +PDEPEND=" + gtk? ( || ( + >=gnome-extra/polkit-gnome-0.105 + >=lxde-base/lxsession-0.5.2 + ) ) + kde? ( kde-plasma/polkit-kde-agent ) +" + +DOCS=( docs/TODO HACKING NEWS README ) + +PATCHES=( + "${FILESDIR}"/${PN}-0.115-elogind.patch # bug 660880 + + # from https://gitlab.freedesktop.org/polkit/polkit/-/merge_requests/35 + "${FILESDIR}"/35_WIP_Add_duktape_as_javascript_engine.patch +) + +QA_MULTILIB_PATHS=" + usr/lib/polkit-1/polkit-agent-helper-1 + usr/lib/polkit-1/polkitd" + +src_prepare() { + default + + sed -i -e 's|unix-group:wheel|unix-user:0|' src/polkitbackend/*-default.rules || die #401513 + + # Workaround upstream hack around standard gtk-doc behavior, bug #552170 + sed -i -e 's/@ENABLE_GTK_DOC_TRUE@\(TARGET_DIR\)/\1/' \ + -e '/install-data-local:/,/uninstall-local:/ s/@ENABLE_GTK_DOC_TRUE@//' \ + -e 's/@ENABLE_GTK_DOC_FALSE@install-data-local://' \ + docs/polkit/Makefile.in || die + + # disable broken test - bug #624022 + sed -i -e "/^SUBDIRS/s/polkitbackend//" test/Makefile.am || die + + # Fix cross-building, bug #590764, elogind patch, bug #598615 + eautoreconf +} + +src_configure() { + xdg_environment_reset + + local myeconfargs=( + --localstatedir="${EPREFIX}"/var + --disable-static + --enable-man-pages + --disable-gtk-doc + --disable-examples + --with-duktape + $(use_enable elogind libelogind) + $(use_enable introspection) + $(use_enable nls) + $(usex pam "--with-pam-module-dir=$(getpam_mod_dir)" '') + --with-authfw=$(usex pam pam shadow) + $(use_enable systemd libsystemd-login) + --with-systemdsystemunitdir="$(systemd_get_systemunitdir)" + $(use_enable test) + --with-os-type=gentoo + ) + econf "${myeconfargs[@]}" +} + +src_compile() { + default + + # Required for polkitd on hardened/PaX due to spidermonkey's JIT + pax-mark mr src/polkitbackend/.libs/polkitd test/polkitbackend/.libs/polkitbackendjsauthoritytest +} + +src_install() { + default + + dodir /usr/share/polkit-1/rules.d + dodir /usr/lib/pam.d + + mv "${D}"/{etc,usr/share}/polkit-1/rules.d/50-default.rules || die + mv "${D}"/{etc,usr/lib}/pam.d/polkit-1 || die + rmdir "${D}"/etc/polkit-1/rules.d "${D}"/etc/polkit-1 || die + rmdir "${D}"/etc/pam.d || die + + systemd_dotmpfilesd "${FILESDIR}/polkit.conf" + + if use examples; then + docinto examples + dodoc src/examples/{*.c,*.policy*} + fi + + diropts -m 0700 -o polkitd + keepdir /usr/share/polkit-1/rules.d + + find "${ED}" -name '*.la' -delete || die +} diff --git a/sys-auth/realmd/realmd-0.17.0.ebuild b/sys-auth/realmd/realmd-0.17.0.ebuild index 41eea75f64..deffd89ac5 100644 --- a/sys-auth/realmd/realmd-0.17.0.ebuild +++ b/sys-auth/realmd/realmd-0.17.0.ebuild @@ -14,7 +14,7 @@ SLOT="0" KEYWORDS="amd64 x86 arm64" IUSE="systemd" -DEPEND="sys-auth/polkit[introspection] +DEPEND="sys-auth/polkit sys-devel/gettext dev-libs/glib:2 net-nds/openldap