diff options
author | Luca Boccassi <luca.boccassi@gmail.com> | 2023-12-14 10:57:33 +0000 |
---|---|---|
committer | Jan Rybar <jrybar@redhat.com> | 2023-12-14 10:57:33 +0000 |
commit | 374a628038474a45fab47dc7dfc3c3473332cd87 (patch) | |
tree | 5bb5e38b119a18b1fdbb8b5528abf9d7ad42531f | |
parent | 23b764c9c1e47f27b9c0b6b92d6687f4c0de5628 (diff) |
Add pidfd parameter to CheckAuthorization()
-rw-r--r-- | data/org.freedesktop.PolicyKit1.Authority.xml | 2 | ||||
-rw-r--r-- | docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml | 2 | ||||
-rw-r--r-- | src/polkit/polkitprivate.h | 3 | ||||
-rw-r--r-- | src/polkit/polkitsubject.c | 81 | ||||
-rw-r--r-- | src/polkitbackend/polkitbackendauthority.c | 2 |
5 files changed, 65 insertions, 25 deletions
diff --git a/data/org.freedesktop.PolicyKit1.Authority.xml b/data/org.freedesktop.PolicyKit1.Authority.xml index 88da3c0..f5b67fb 100644 --- a/data/org.freedesktop.PolicyKit1.Authority.xml +++ b/data/org.freedesktop.PolicyKit1.Authority.xml @@ -12,7 +12,7 @@ <annotation name="org.gtk.EggDBus.DeclareStruct" value="Subject"> <annotation name="org.gtk.EggDBus.DocString.Summary" value="Subjects"/> <annotation name="org.gtk.EggDBus.DocString" value="<para>This struct describes subjects such as UNIX processes. It is typically used to check if a given process is authorized for an action.</para><para>The following kinds of subjects are known:</para> - <formalpara><title>Unix Process</title><para><literal>subject_kind</literal> should be set to <literal>unix-process</literal> with keys <literal>pid</literal> (of type <literal>uint32</literal>) and <literal>start-time</literal> (of type <literal>uint64</literal>).</para></formalpara> + <formalpara><title>Unix Process</title><para><literal>subject_kind</literal> should be set to <literal>unix-process</literal> with key <literal>pidfd</literal> (of type <literal>int32</literal>) (if the operating system supports ProcessID File Descriptors), or alternatively with keys <literal>pid</literal> (of type <literal>uint32</literal>) and <literal>start-time</literal> (of type <literal>uint64</literal>).</para></formalpara> <formalpara><title>Unix Session</title><para><literal>subject_kind</literal> should be set to <literal>unix-session</literal> with the key <literal>session-id</literal> (of type <literal>string</literal>).</para></formalpara> <formalpara><title>System Bus Name</title><para><literal>subject_kind</literal> should be set to <literal>system-bus-name</literal> with the key <literal>name</literal> (of type <literal>string</literal>).</para></formalpara>"/> diff --git a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml index f2eed63..b5cc195 100644 --- a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml +++ b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml @@ -275,7 +275,7 @@ The authority supports temporary authorizations that can be obtained through aut } </programlisting> <para> -<para>This struct describes subjects such as UNIX processes. It is typically used to check if a given process is authorized for an action.</para><para>The following kinds of subjects are known:</para> <formalpara><title>Unix Process</title><para><literal>subject_kind</literal> should be set to <literal>unix-process</literal> with keys <literal>pid</literal> (of type <literal>uint32</literal>) and <literal>start-time</literal> (of type <literal>uint64</literal>).</para></formalpara> <formalpara><title>Unix Session</title><para><literal>subject_kind</literal> should be set to <literal>unix-session</literal> with the key <literal>session-id</literal> (of type <literal>string</literal>).</para></formalpara> <formalpara><title>System Bus Name</title><para><literal>subject_kind</literal> should be set to <literal>system-bus-name</literal> with the key <literal>name</literal> (of type <literal>string</literal>).</para></formalpara> +<para>This struct describes subjects such as UNIX processes. It is typically used to check if a given process is authorized for an action.</para><para>The following kinds of subjects are known:</para> <formalpara><title>Unix Process</title><para><literal>subject_kind</literal> should be set to <literal>unix-process</literal> with key <literal>pidfd</literal> (of type <literal>int32</literal>) (if the operating system supports ProcessID File Descriptors), or alternatively with keys <literal>pid</literal> (of type <literal>uint32</literal>) and <literal>start-time</literal> (of type <literal>uint64</literal>).</para></formalpara> <formalpara><title>Unix Session</title><para><literal>subject_kind</literal> should be set to <literal>unix-session</literal> with the key <literal>session-id</literal> (of type <literal>string</literal>).</para></formalpara> <formalpara><title>System Bus Name</title><para><literal>subject_kind</literal> should be set to <literal>system-bus-name</literal> with the key <literal>name</literal> (of type <literal>string</literal>).</para></formalpara> </para> <variablelist role="struct"> <varlistentry> diff --git a/src/polkit/polkitprivate.h b/src/polkit/polkitprivate.h index c80142d..0ba8277 100644 --- a/src/polkit/polkitprivate.h +++ b/src/polkit/polkitprivate.h @@ -47,6 +47,9 @@ 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); +PolkitSubject *polkit_subject_new_for_gvariant_invocation (GVariant *variant, + GDBusMethodInvocation *invocation, + GError **error); PolkitIdentity *polkit_identity_new_for_gvariant (GVariant *variant, GError **error); PolkitAuthorizationResult *polkit_authorization_result_new_for_gvariant (GVariant *value); diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c index ccabd0a..e18b3e9 100644 --- a/src/polkit/polkitsubject.c +++ b/src/polkit/polkitsubject.c @@ -243,7 +243,14 @@ polkit_subject_from_string (const gchar *str, gint scanned_pid; guint64 scanned_starttime; gint scanned_uid; - if (sscanf (str, "unix-process:%d:%" G_GUINT64_FORMAT ":%d", &scanned_pid, &scanned_starttime, &scanned_uid) == 3) + gint scanned_pidfd; + if (sscanf (str, "unix-process:%d:%" G_GUINT64_FORMAT ":%d:%d", &scanned_pid, &scanned_starttime, &scanned_uid, &scanned_pidfd) == 4) + { + subject = polkit_unix_process_new_pidfd (scanned_pidfd, scanned_uid, NULL); + if (subject) + polkit_unix_process_set_start_time (POLKIT_UNIX_PROCESS (subject), scanned_starttime); + } + else if (sscanf (str, "unix-process:%d:%" G_GUINT64_FORMAT ":%d", &scanned_pid, &scanned_starttime, &scanned_uid) == 3) { subject = polkit_unix_process_new_for_owner (scanned_pid, scanned_starttime, scanned_uid); } @@ -312,6 +319,9 @@ polkit_subject_to_gvariant (PolkitSubject *subject) g_variant_new_uint64 (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject)))); g_variant_builder_add (&builder, "{sv}", "uid", g_variant_new_int32 (polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)))); + if (polkit_unix_process_get_pidfd_is_safe(POLKIT_UNIX_PROCESS (subject))) + g_variant_builder_add (&builder, "{sv}", "pidfd", + g_variant_new_handle (polkit_unix_process_get_pidfd (POLKIT_UNIX_PROCESS (subject)))); } else if (POLKIT_IS_UNIX_SESSION (subject)) { @@ -391,8 +401,9 @@ lookup_asv (GVariant *dict, } PolkitSubject * -polkit_subject_new_for_gvariant (GVariant *variant, - GError **error) +polkit_subject_new_for_gvariant_invocation (GVariant *variant, + GDBusMethodInvocation *invocation, + GError **error) { PolkitSubject *ret; const gchar *kind; @@ -407,29 +418,13 @@ polkit_subject_new_for_gvariant (GVariant *variant, if (g_strcmp0 (kind, "unix-process") == 0) { + GUnixFDList *fd_list; GVariant *v; + gint index, pidfd; guint32 pid; guint64 start_time; gint32 uid; - v = lookup_asv (details_gvariant, "pid", G_VARIANT_TYPE_UINT32, error); - if (v == NULL) - { - g_prefix_error (error, "Error parsing unix-process subject: "); - goto out; - } - pid = g_variant_get_uint32 (v); - g_variant_unref (v); - - v = lookup_asv (details_gvariant, "start-time", G_VARIANT_TYPE_UINT64, error); - if (v == NULL) - { - g_prefix_error (error, "Error parsing unix-process subject: "); - goto out; - } - start_time = g_variant_get_uint64 (v); - g_variant_unref (v); - v = lookup_asv (details_gvariant, "uid", G_VARIANT_TYPE_INT32, NULL); if (v != NULL) { @@ -441,7 +436,42 @@ polkit_subject_new_for_gvariant (GVariant *variant, uid = -1; } - ret = polkit_unix_process_new_for_owner (pid, start_time, uid); + fd_list = g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)); + if (fd_list) + { + v = lookup_asv (details_gvariant, "pidfd", G_VARIANT_TYPE_HANDLE, NULL); + if (v != NULL) + { + index = g_variant_get_handle (v); + pidfd = g_unix_fd_list_get (fd_list, index, NULL); + g_variant_unref (v); + + ret = polkit_unix_process_new_pidfd (pidfd, uid, NULL); + } + } + + if (!ret) + { + v = lookup_asv (details_gvariant, "pid", G_VARIANT_TYPE_UINT32, error); + if (v == NULL) + { + g_prefix_error (error, "Error parsing unix-process subject: "); + goto out; + } + pid = g_variant_get_uint32 (v); + g_variant_unref (v); + + v = lookup_asv (details_gvariant, "start-time", G_VARIANT_TYPE_UINT64, error); + if (v == NULL) + { + g_prefix_error (error, "Error parsing unix-process subject: "); + goto out; + } + start_time = g_variant_get_uint64 (v); + g_variant_unref (v); + + ret = polkit_unix_process_new_for_owner (pid, start_time, uid); + } } else if (g_strcmp0 (kind, "unix-session") == 0) { @@ -495,3 +525,10 @@ polkit_subject_new_for_gvariant (GVariant *variant, g_variant_unref (details_gvariant); return ret; } + +PolkitSubject * +polkit_subject_new_for_gvariant (GVariant *variant, + GError **error) +{ + return polkit_subject_new_for_gvariant_invocation (variant, NULL, error); +} diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c index 0d1fac4..d4c6f7d 100644 --- a/src/polkitbackend/polkitbackendauthority.c +++ b/src/polkitbackend/polkitbackendauthority.c @@ -742,7 +742,7 @@ server_handle_check_authorization (Server *server, &cancellation_id); error = NULL; - subject = polkit_subject_new_for_gvariant (subject_gvariant, &error); + subject = polkit_subject_new_for_gvariant_invocation (subject_gvariant, invocation, &error); if (subject == NULL) { g_prefix_error (&error, "Error getting subject: "); |