Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

agent helper: support separate socket-activated service to run without SETUID #501

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .packit/polkit.spec
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
%{_datadir}/dbus-1/system.d/org.freedesktop.PolicyKit1.conf
%{_datadir}/dbus-1/system-services/*
%{_unitdir}/polkit.service
%{_unitdir}/polkit-agent-helper.socket
%{_unitdir}/[email protected]
%dir %{_datadir}/polkit-1/
%dir %{_datadir}/polkit-1/actions
%attr(0750,root,polkitd) %dir %{_datadir}/polkit-1/rules.d
Expand Down
13 changes: 13 additions & 0 deletions data/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ if not get_option('libs-only')
install_dir: systemdsystemunitdir,
)

configure_file(
input: '[email protected]',
output: '@BASENAME@',
configuration: service_conf,
install: true,
install_dir: systemdsystemunitdir,
)

install_data(
'polkit-agent-helper.socket',
install_dir: systemdsystemunitdir,
)

configure_file(
input: 'polkit.conf.in',
output: '@BASENAME@',
Expand Down
11 changes: 11 additions & 0 deletions data/polkit-agent-helper.socket
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
Description=Authorization Manager Agent Helper
Documentation=man:polkit(8)

[Socket]
Accept=yes
RemoveOnStop=yes
ListenStream=/run/polkit/agent-helper.socket

[Install]
WantedBy=sockets.target
34 changes: 34 additions & 0 deletions data/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[Unit]
Description=Authorization Manager Agent Helper
Documentation=man:polkit(8)

[Service]
Type=oneshot
DeviceAllow=/dev/null rw
DevicePolicy=strict
ExecStart=@libprivdir@/polkit-agent-helper-1 --socket-activated
StandardInput=socket
StandardOutput=socket
LimitMEMLOCK=0
LockPersonality=yes
MemoryDenyWriteExecute=yes
NoNewPrivileges=yes
PrivateDevices=yes
PrivateNetwork=yes
PrivateTmp=yes
ProtectControlGroups=yes
ProtectHome=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectKernelTunables=yes
ProtectSystem=strict
ProtectClock=yes
ProtectHostname=yes
RemoveIPC=yes
RestrictAddressFamilies=AF_UNIX
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
SystemCallArchitectures=native
SystemCallFilter=@system-service
UMask=0077
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ Structure <link linkend="eggdbus-struct-TemporaryAuthorization">TemporaryAuth
IN <link linkend="eggdbus-struct-Identity">Identity</link> identity)
<link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse2">AuthenticationAgentResponse2</link> (IN uint32 uid, IN String cookie,
IN <link linkend="eggdbus-struct-Identity">Identity</link> identity)
<link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse3">AuthenticationAgentResponse3</link> (IN String cookie,
IN <link linkend="eggdbus-struct-Identity">Identity</link> identity,
IN <link linkend="eggdbus-struct-Subject">Subject</link> subject)
<link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.EnumerateTemporaryAuthorizations">EnumerateTemporaryAuthorizations</link> (IN <link linkend="eggdbus-struct-Subject">Subject</link> subject,
OUT Array&lt;<link linkend="eggdbus-struct-TemporaryAuthorization">TemporaryAuthorization</link>&gt; temporary_authorizations)
<link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.RevokeTemporaryAuthorizations">RevokeTemporaryAuthorizations</link> (IN <link linkend="eggdbus-struct-Subject">Subject</link> subject)
Expand Down Expand Up @@ -316,7 +319,7 @@ Details about the subject. Depending of the value of <parameter>subject_kind</pa
}
</programlisting>
<para>
<para>This struct describes identities such as UNIX users and UNIX groups. It is typically used to check if a given process is authorized for an action.</para><para>The following kinds of identities are known:</para> <formalpara><title>Unix User</title><para><literal>identity_kind</literal> should be set to <literal>unix-user</literal> with key <literal>uid</literal> (of type <literal>uint32</literal>).</para></formalpara> <formalpara><title>Unix Group</title><para><literal>identity_kind</literal> should be set to <literal>unix-group</literal> with key <literal>gid</literal> (of type <literal>uint32</literal>).</para></formalpara>
<para>This struct describes identities such as UNIX users and UNIX groups. It is typically used to check if a given process is authorized for an action.</para><para>The following kinds of identities are known:</para> <formalpara><title>Unix User</title><para><literal>identity_kind</literal> should be set to <literal>unix-user</literal> with key <literal>uid</literal> (of type <literal>uint32</literal>).</para></formalpara> <formalpara><title>Unix Group</title><para><literal>identity_kind</literal> should be set to <literal>unix-group</literal> with key <literal>gid</literal> (of type <literal>uint32</literal>).</para></formalpara>
</para>
<variablelist role="struct">
<varlistentry>
Expand Down Expand Up @@ -853,6 +856,47 @@ A <link linkend="eggdbus-struct-Identity">Identity</link> struct describing what
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2 role="function" id="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse3">
<title>AuthenticationAgentResponse3 ()</title>
<programlisting>
AuthenticationAgentResponse3 (IN String cookie,
IN <link linkend="eggdbus-struct-Identity">Identity</link> identity,
IN <link linkend="eggdbus-struct-Subject">Subject</link> subject)
</programlisting>
<para>
Method for authentication agents to invoke on successful
authentication, intended only for use by a privileged helper process
running via socket activation. This method will fail unless a sufficiently privileged
caller invokes it. In contract to other methods this takes a subject as input, which
allows reliably tracking the requester via PID FD.
</para>
<variablelist role="params">
<varlistentry>
<term><literal>IN String <parameter>cookie</parameter></literal>:</term>
<listitem>
<para>
The cookie identifying the authentication request that was passed to the authentication agent.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>IN <link linkend="eggdbus-struct-Identity">Identity</link> <parameter>identity</parameter></literal>:</term>
<listitem>
<para>
A <link linkend="eggdbus-struct-Identity">Identity</link> struct describing what identity was authenticated.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>IN <link linkend="eggdbus-struct-Subject">Subject</link> <parameter>subject</parameter></literal>:</term>
<listitem>
<para>
A <link linkend="eggdbus-struct-Subject">Subject</link> struct describing what entity requested the authentication.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2 role="function" id="eggdbus-method-org.freedesktop.PolicyKit1.Authority.EnumerateTemporaryAuthorizations">
Expand Down
2 changes: 2 additions & 0 deletions docs/polkit/polkit-1-sections.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ polkit_authority_unregister_authentication_agent_sync
polkit_authority_authentication_agent_response
polkit_authority_authentication_agent_response_finish
polkit_authority_authentication_agent_response_sync
polkit_authority_authentication_agent_response_with_subject
polkit_authority_authentication_agent_response_with_subject_sync
polkit_authority_enumerate_temporary_authorizations
polkit_authority_enumerate_temporary_authorizations_finish
polkit_authority_enumerate_temporary_authorizations_sync
Expand Down
108 changes: 108 additions & 0 deletions src/polkit/polkitauthority.c
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,67 @@ polkit_authority_unregister_authentication_agent_sync (PolkitAuthority *auth

/* ---------------------------------------------------------------------------------------------------- */

/**
* polkit_authority_authentication_agent_response:
* @authority: A #PolkitAuthority.
* @cookie: The cookie passed to the authentication agent from the authority.
* @identity: The identity that was authenticated.
* @subject: The subject that requested the authentication.
* @cancellable: (allow-none): A #GCancellable or %NULL.
* @callback: A #GAsyncReadyCallback to call when the request is satisfied.
* @user_data: The data to pass to @callback.
*
* Asynchronously provide response that @identity successfully authenticated
* for the authentication request identified by @cookie as requested by @subject.
*
* This function is only used by the socket-activated agent helper, running as uiid
* 0, and will fail otherwise. The requesting process is identified via @subject
* which will contain a PID FD identifying the process.
*
* When the operation is finished, @callback will be invoked in the
* <link linkend="g-main-context-push-thread-default">thread-default
* main loop</link> of the thread you are calling this method
* from. You can then call
* polkit_authority_authentication_agent_response_finish() to get the
* result of the operation.
**/
void
polkit_authority_authentication_agent_response_with_subject (PolkitAuthority *authority,
const gchar *cookie,
PolkitIdentity *identity,
PolkitSubject *subject,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Unlike the polkit_authority_authentication_agent_response variant,
* this one is called from a socket-activated service, rather than a
* setuid helper invoked directly by the authenticating process.
*/
g_return_if_fail (POLKIT_IS_AUTHORITY (authority));
g_return_if_fail (cookie != NULL);
g_return_if_fail (POLKIT_IS_IDENTITY (identity));
g_return_if_fail (POLKIT_IS_SUBJECT (subject));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));

g_dbus_proxy_call (authority->proxy,
"AuthenticationAgentResponse3",
g_variant_new ("(s@(sa{sv})@(sa{sv}))",
cookie,
polkit_identity_to_gvariant (identity), /* Floating value */
polkit_subject_to_gvariant (subject)), /* Floating value */
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
generic_async_cb,
g_simple_async_result_new (G_OBJECT (authority),
callback,
user_data,
polkit_authority_authentication_agent_response));
}

/* ---------------------------------------------------------------------------------------------------- */

/**
* polkit_authority_authentication_agent_response:
* @authority: A #PolkitAuthority.
Expand Down Expand Up @@ -1630,6 +1691,53 @@ polkit_authority_authentication_agent_response_sync (PolkitAuthority *author
return ret;
}


/**
* polkit_authority_authentication_agent_response_with_subject_sync:
* @authority: A #PolkitAuthority.
* @cookie: The cookie passed to the authentication agent from the authority.
* @identity: The identity that was authenticated.
* @subject: The subject that requested the authentication.
* @cancellable: (allow-none): A #GCancellable or %NULL.
* @error: (allow-none): Return location for error or %NULL.
*
* Provide response that @identity successfully authenticated for the
* authentication request identified by @cookie. See polkit_authority_authentication_agent_response_with_subject()
* for limitations on who is allowed is to call this method.
*
* The calling thread is blocked until a reply is received. See
* polkit_authority_authentication_agent_response_with_subject() for the
* asynchronous version.
*
* Returns: %TRUE if @authority acknowledged the call, %FALSE if @error is set.
**/
gboolean
polkit_authority_authentication_agent_response_with_subject_sync (PolkitAuthority *authority,
const gchar *cookie,
PolkitIdentity *identity,
PolkitSubject *subject,
GCancellable *cancellable,
GError **error)
{
gboolean ret;
CallSyncData *data;

g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
g_return_val_if_fail (cookie != NULL, FALSE);
g_return_val_if_fail (POLKIT_IS_IDENTITY (identity), FALSE);
g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

data = call_sync_new ();
polkit_authority_authentication_agent_response_with_subject (authority, cookie, identity, subject, cancellable, call_sync_cb, data);
call_sync_block (data);
ret = polkit_authority_authentication_agent_response_finish (authority, data->res, error);
call_sync_free (data);

return ret;
}

/* ---------------------------------------------------------------------------------------------------- */

/**
Expand Down
15 changes: 15 additions & 0 deletions src/polkit/polkitauthority.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ gboolean polkit_authority_authentication_agent_response_sync (
GCancellable *cancellable,
GError **error);

gboolean polkit_authority_authentication_agent_response_with_subject_sync (PolkitAuthority *authority,
const gchar *cookie,
PolkitIdentity *identity,
PolkitSubject *subject,
GCancellable *cancellable,
GError **error);

GList *polkit_authority_enumerate_temporary_authorizations_sync (PolkitAuthority *authority,
PolkitSubject *subject,
GCancellable *cancellable,
Expand Down Expand Up @@ -186,6 +193,14 @@ void polkit_authority_authentication_agent_response (Polki
GAsyncReadyCallback callback,
gpointer user_data);

void polkit_authority_authentication_agent_response_with_subject (PolkitAuthority *authority,
const gchar *cookie,
PolkitIdentity *identity,
PolkitSubject *subject,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);

gboolean polkit_authority_authentication_agent_response_finish (PolkitAuthority *authority,
GAsyncResult *res,
GError **error);
Expand Down
2 changes: 1 addition & 1 deletion src/polkitagent/polkitagenthelper-bsdauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ main (int argc, char *argv[])
/* now send a D-Bus message to the polkit daemon that
* includes a) the cookie; and b) the user we authenticated
*/
if (!send_dbus_message (cookie, user_to_auth))
if (!send_dbus_message (cookie, user_to_auth, -1, -1))
{
#ifdef PAH_DEBUG
fprintf (stderr, "polkit-agent-helper-1: error sending D-Bus message to polkit daemon\n");
Expand Down
Loading