mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-07 15:40:31 +01:00
settings: check modify 'own' not 'system' for personal connections
When a connection is visible only to one user, check 'own' instead of 'system', allowing 'own' to be less restrictive since the change won't affect any other users.
This commit is contained in:
parent
2e2b4373eb
commit
562dc6e0b6
3 changed files with 103 additions and 55 deletions
|
|
@ -35,6 +35,7 @@
|
|||
#include "nm-polkit-helpers.h"
|
||||
#include "nm-manager-auth.h"
|
||||
#include "nm-setting-vpn.h"
|
||||
#include "nm-setting-connection.h"
|
||||
|
||||
G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT)
|
||||
|
||||
|
|
@ -762,9 +763,9 @@ get_agent_modify_auth_cb (NMAuthChain *chain,
|
|||
{
|
||||
Request *req = user_data;
|
||||
NMAuthCallResult result;
|
||||
const char *perm;
|
||||
|
||||
req->chain = NULL;
|
||||
nm_auth_chain_unref (chain);
|
||||
|
||||
if (error) {
|
||||
nm_log_dbg (LOGD_AGENTS, "(%p/%s) agent MODIFY check error: (%d) %s",
|
||||
|
|
@ -778,7 +779,9 @@ get_agent_modify_auth_cb (NMAuthChain *chain,
|
|||
* to it. If it didn't, we still ask it for secrets, but we don't send
|
||||
* any system secrets.
|
||||
*/
|
||||
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM);
|
||||
perm = nm_auth_chain_get_data (chain, "perm");
|
||||
g_assert (perm);
|
||||
result = nm_auth_chain_get_result (chain, perm);
|
||||
if (result == NM_AUTH_CALL_RESULT_YES)
|
||||
req->current_has_modify = TRUE;
|
||||
|
||||
|
|
@ -787,12 +790,14 @@ get_agent_modify_auth_cb (NMAuthChain *chain,
|
|||
|
||||
get_agent_request_secrets (req, req->current_has_modify);
|
||||
}
|
||||
nm_auth_chain_unref (chain);
|
||||
}
|
||||
|
||||
static void
|
||||
get_next_cb (Request *req)
|
||||
{
|
||||
const char *agent_dbus_owner;
|
||||
NMSettingConnection *s_con;
|
||||
const char *agent_dbus_owner, *perm;
|
||||
|
||||
if (!next_generic (req, "getting"))
|
||||
return;
|
||||
|
|
@ -813,7 +818,20 @@ get_next_cb (Request *req)
|
|||
get_agent_modify_auth_cb,
|
||||
req);
|
||||
g_assert (req->chain);
|
||||
nm_auth_chain_add_call (req->chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, TRUE);
|
||||
|
||||
/* If the caller is the only user in the connection's permissions, then
|
||||
* we use the 'modify.own' permission instead of 'modify.system'. If the
|
||||
* request affects more than just the caller, require 'modify.system'.
|
||||
*/
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (req->connection, NM_TYPE_SETTING_CONNECTION);
|
||||
g_assert (s_con);
|
||||
if (nm_setting_connection_get_num_permissions (s_con) == 1)
|
||||
perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
|
||||
else
|
||||
perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM;
|
||||
nm_auth_chain_set_data (req->chain, "perm", (gpointer) perm, NULL);
|
||||
|
||||
nm_auth_chain_add_call (req->chain, perm, TRUE);
|
||||
} else {
|
||||
nm_log_dbg (LOGD_AGENTS, "(%p/%s) requesting user-owned secrets from agent %s",
|
||||
req, req->setting_name, agent_dbus_owner);
|
||||
|
|
|
|||
|
|
@ -696,12 +696,6 @@ typedef void (*AuthCallback) (NMSettingsConnection *connection,
|
|||
GError *error,
|
||||
gpointer data);
|
||||
|
||||
typedef struct {
|
||||
AuthCallback callback;
|
||||
gpointer callback_data;
|
||||
gulong sender_uid;
|
||||
} PkAuthInfo;
|
||||
|
||||
static void
|
||||
pk_auth_cb (NMAuthChain *chain,
|
||||
GError *chain_error,
|
||||
|
|
@ -712,7 +706,10 @@ pk_auth_cb (NMAuthChain *chain,
|
|||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
GError *error = NULL;
|
||||
NMAuthCallResult result;
|
||||
PkAuthInfo *info;
|
||||
const char *perm;
|
||||
AuthCallback callback;
|
||||
gpointer callback_data;
|
||||
gulong sender_uid;
|
||||
|
||||
priv->pending_auths = g_slist_remove (priv->pending_auths, chain);
|
||||
|
||||
|
|
@ -723,7 +720,9 @@ pk_auth_cb (NMAuthChain *chain,
|
|||
"Error checking authorization: %s",
|
||||
chain_error->message ? chain_error->message : "(unknown)");
|
||||
} else {
|
||||
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM);
|
||||
perm = nm_auth_chain_get_data (chain, "perm");
|
||||
g_assert (perm);
|
||||
result = nm_auth_chain_get_result (chain, perm);
|
||||
|
||||
/* Caller didn't successfully authenticate */
|
||||
if (result != NM_AUTH_CALL_RESULT_YES) {
|
||||
|
|
@ -733,8 +732,10 @@ pk_auth_cb (NMAuthChain *chain,
|
|||
}
|
||||
}
|
||||
|
||||
info = nm_auth_chain_get_data (chain, "pk-auth-info");
|
||||
info->callback (self, context, info->sender_uid, error, info->callback_data);
|
||||
callback = nm_auth_chain_get_data (chain, "callback");
|
||||
callback_data = nm_auth_chain_get_data (chain, "callback-data");
|
||||
sender_uid = nm_auth_chain_get_data_ulong (chain, "sender-uid");
|
||||
callback (self, context, sender_uid, error, callback_data);
|
||||
|
||||
g_clear_error (&error);
|
||||
nm_auth_chain_unref (chain);
|
||||
|
|
@ -750,7 +751,6 @@ auth_start (NMSettingsConnection *self,
|
|||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
NMAuthChain *chain;
|
||||
gulong sender_uid = G_MAXULONG;
|
||||
PkAuthInfo *info;
|
||||
GError *error = NULL;
|
||||
char *error_desc = NULL;
|
||||
|
||||
|
|
@ -778,16 +778,28 @@ auth_start (NMSettingsConnection *self,
|
|||
}
|
||||
|
||||
if (check_modify) {
|
||||
NMSettingConnection *s_con;
|
||||
const char *perm;
|
||||
|
||||
/* If the caller is the only user in the connection's permissions, then
|
||||
* we use the 'modify.own' permission instead of 'modify.system'. If the
|
||||
* request affects more than just the caller, require 'modify.system'.
|
||||
*/
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION);
|
||||
g_assert (s_con);
|
||||
if (nm_setting_connection_get_num_permissions (s_con) == 1)
|
||||
perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
|
||||
else
|
||||
perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM;
|
||||
|
||||
chain = nm_auth_chain_new (priv->authority, context, NULL, pk_auth_cb, self);
|
||||
g_assert (chain);
|
||||
nm_auth_chain_set_data (chain, "perm", (gpointer) perm, NULL);
|
||||
nm_auth_chain_set_data (chain, "callback", callback, NULL);
|
||||
nm_auth_chain_set_data (chain, "callback-data", callback_data, NULL);
|
||||
nm_auth_chain_set_data_ulong (chain, "sender-uid", sender_uid);
|
||||
|
||||
info = g_malloc0 (sizeof (*info));
|
||||
info->callback = callback;
|
||||
info->callback_data = callback_data;
|
||||
info->sender_uid = sender_uid;
|
||||
nm_auth_chain_set_data (chain, "pk-auth-info", info, g_free);
|
||||
|
||||
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, TRUE);
|
||||
nm_auth_chain_add_call (chain, perm, TRUE);
|
||||
priv->pending_auths = g_slist_append (priv->pending_auths, chain);
|
||||
} else {
|
||||
/* Don't need polkit auth, automatic success */
|
||||
|
|
|
|||
|
|
@ -800,10 +800,9 @@ pk_add_cb (NMAuthChain *chain,
|
|||
GError *error = NULL, *add_error = NULL;
|
||||
NMConnection *connection;
|
||||
NMSettingsConnection *added = NULL;
|
||||
gulong caller_uid = G_MAXULONG;
|
||||
char *error_desc = NULL;
|
||||
NMSettingsAddCallback callback;
|
||||
gpointer callback_data;
|
||||
const char *perm;
|
||||
|
||||
priv->auths = g_slist_remove (priv->auths, chain);
|
||||
|
||||
|
|
@ -815,7 +814,9 @@ pk_add_cb (NMAuthChain *chain,
|
|||
goto done;
|
||||
}
|
||||
|
||||
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM);
|
||||
perm = nm_auth_chain_get_data (chain, "perm");
|
||||
g_assert (perm);
|
||||
result = nm_auth_chain_get_result (chain, perm);
|
||||
|
||||
/* Caller didn't successfully authenticate */
|
||||
if (result != NM_AUTH_CALL_RESULT_YES) {
|
||||
|
|
@ -825,35 +826,8 @@ pk_add_cb (NMAuthChain *chain,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* If the caller isn't root, make sure the connection can be viewed by
|
||||
* the user that's adding it.
|
||||
*/
|
||||
if (!nm_auth_get_caller_uid (context, priv->dbus_mgr, &caller_uid, &error_desc)) {
|
||||
error = g_error_new (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_NOT_PRIVILEGED,
|
||||
"Unable to determine UID of request: %s.",
|
||||
error_desc ? error_desc : "(unknown)");
|
||||
g_free (error_desc);
|
||||
goto done;
|
||||
}
|
||||
|
||||
connection = nm_auth_chain_get_data (chain, "connection");
|
||||
|
||||
/* Ensure the caller's username exists in the connection's permissions,
|
||||
* or that the permissions is empty (ie, visible by everyone).
|
||||
*/
|
||||
if (0 != caller_uid) {
|
||||
if (!nm_auth_uid_in_acl (connection, priv->session_monitor, caller_uid, &error_desc)) {
|
||||
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_NOT_PRIVILEGED,
|
||||
error_desc);
|
||||
g_free (error_desc);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Caller is allowed to add this connection */
|
||||
}
|
||||
|
||||
g_assert (connection);
|
||||
added = add_new_connection (self, connection, &add_error);
|
||||
if (!added) {
|
||||
error = g_error_new (NM_SETTINGS_ERROR,
|
||||
|
|
@ -895,8 +869,12 @@ nm_settings_add_connection (NMSettings *self,
|
|||
gpointer user_data)
|
||||
{
|
||||
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
||||
NMSettingConnection *s_con;
|
||||
NMAuthChain *chain;
|
||||
GError *error = NULL, *tmp_error = NULL;
|
||||
gulong caller_uid = G_MAXULONG;
|
||||
char *error_desc = NULL;
|
||||
const char *perm;
|
||||
|
||||
/* Connection must be valid, of course */
|
||||
if (!nm_connection_verify (connection, &tmp_error)) {
|
||||
|
|
@ -905,7 +883,6 @@ nm_settings_add_connection (NMSettings *self,
|
|||
"The connection was invalid: %s",
|
||||
tmp_error ? tmp_error->message : "(unknown)");
|
||||
g_error_free (tmp_error);
|
||||
|
||||
callback (self, NULL, error, context, user_data);
|
||||
g_error_free (error);
|
||||
return;
|
||||
|
|
@ -921,11 +898,52 @@ nm_settings_add_connection (NMSettings *self,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Get the caller's UID */
|
||||
if (!nm_auth_get_caller_uid (context, priv->dbus_mgr, &caller_uid, &error_desc)) {
|
||||
error = g_error_new (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_NOT_PRIVILEGED,
|
||||
"Unable to determine UID of request: %s.",
|
||||
error_desc ? error_desc : "(unknown)");
|
||||
g_free (error_desc);
|
||||
callback (self, NULL, error, context, user_data);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ensure the caller's username exists in the connection's permissions,
|
||||
* or that the permissions is empty (ie, visible by everyone).
|
||||
*/
|
||||
if (0 != caller_uid) {
|
||||
if (!nm_auth_uid_in_acl (connection, priv->session_monitor, caller_uid, &error_desc)) {
|
||||
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_NOT_PRIVILEGED,
|
||||
error_desc);
|
||||
g_free (error_desc);
|
||||
callback (self, NULL, error, context, user_data);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Caller is allowed to add this connection */
|
||||
}
|
||||
|
||||
/* If the caller is the only user in the connection's permissions, then
|
||||
* we use the 'modify.own' permission instead of 'modify.system'. If the
|
||||
* request affects more than just the caller, require 'modify.system'.
|
||||
*/
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
||||
g_assert (s_con);
|
||||
if (nm_setting_connection_get_num_permissions (s_con) == 1)
|
||||
perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
|
||||
else
|
||||
perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM;
|
||||
|
||||
/* Otherwise validate the user request */
|
||||
chain = nm_auth_chain_new (priv->authority, context, NULL, pk_add_cb, self);
|
||||
g_assert (chain);
|
||||
priv->auths = g_slist_append (priv->auths, chain);
|
||||
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, TRUE);
|
||||
nm_auth_chain_add_call (chain, perm, TRUE);
|
||||
nm_auth_chain_set_data (chain, "perm", (gpointer) perm, NULL);
|
||||
nm_auth_chain_set_data (chain, "connection", g_object_ref (connection), g_object_unref);
|
||||
nm_auth_chain_set_data (chain, "callback", callback, NULL);
|
||||
nm_auth_chain_set_data (chain, "callback-data", user_data, NULL);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue