shared: nm-auth-subject: add unix-session type

This commit is contained in:
Antonio Cardace 2019-12-17 20:36:18 +01:00
parent 0f7994328d
commit 1e45865e4f
10 changed files with 134 additions and 64 deletions

View file

@ -23,6 +23,7 @@ enum {
PROP_UNIX_PROCESS_DBUS_SENDER,
PROP_UNIX_PROCESS_PID,
PROP_UNIX_PROCESS_UID,
PROP_UNIX_SESSION_ID,
PROP_LAST,
};
@ -35,6 +36,10 @@ typedef struct {
guint64 start_time;
char *dbus_sender;
} unix_process;
struct {
char *id;
} unix_session;
} NMAuthSubjectPrivate;
struct _NMAuthSubject {
@ -76,6 +81,10 @@ nm_auth_subject_to_string (NMAuthSubject *self, char *buf, gsize buf_len)
case NM_AUTH_SUBJECT_TYPE_INTERNAL:
g_strlcpy (buf, "internal", buf_len);
break;
case NM_AUTH_SUBJECT_TYPE_UNIX_SESSION:
g_snprintf (buf, buf_len, "unix-session[id=%s]",
priv->unix_session.id);
break;
default:
g_strlcpy (buf, "invalid", buf_len);
break;
@ -85,23 +94,32 @@ nm_auth_subject_to_string (NMAuthSubject *self, char *buf, gsize buf_len)
/* returns a floating variant */
GVariant *
nm_auth_subject_unix_process_to_polkit_gvariant (NMAuthSubject *self)
nm_auth_subject_unix_to_polkit_gvariant (NMAuthSubject *self)
{
GVariantBuilder builder;
GVariant *dict;
GVariant *ret;
CHECK_SUBJECT_TYPED (self, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, NULL);
CHECK_SUBJECT (self, NULL);
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&builder, "{sv}", "pid",
g_variant_new_uint32 (priv->unix_process.pid));
g_variant_builder_add (&builder, "{sv}", "start-time",
g_variant_new_uint64 (priv->unix_process.start_time));
g_variant_builder_add (&builder, "{sv}", "uid",
g_variant_new_int32 (priv->unix_process.uid));
dict = g_variant_builder_end (&builder);
ret = g_variant_new ("(s@a{sv})", "unix-process", dict);
return ret;
switch (priv->subject_type) {
case NM_AUTH_SUBJECT_TYPE_UNIX_SESSION:
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&builder, "{sv}", "session-id",
g_variant_new_string (priv->unix_session.id));
return g_variant_new ("(sa{sv})", "unix-session", &builder);
case NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS:
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&builder, "{sv}", "pid",
g_variant_new_uint32 (priv->unix_process.pid));
g_variant_builder_add (&builder, "{sv}", "start-time",
g_variant_new_uint64 (priv->unix_process.start_time));
g_variant_builder_add (&builder, "{sv}", "uid",
g_variant_new_int32 (priv->unix_process.uid));
return g_variant_new ("(sa{sv})", "unix-process", &builder);
default:
g_return_val_if_reached (NULL);
}
}
NMAuthSubjectType
@ -112,18 +130,6 @@ nm_auth_subject_get_subject_type (NMAuthSubject *subject)
return priv->subject_type;
}
gboolean
nm_auth_subject_is_internal (NMAuthSubject *subject)
{
return nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL;
}
gboolean
nm_auth_subject_is_unix_process (NMAuthSubject *subject)
{
return nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS;
}
gulong
nm_auth_subject_get_unix_process_pid (NMAuthSubject *subject)
{
@ -148,6 +154,14 @@ nm_auth_subject_get_unix_process_dbus_sender (NMAuthSubject *subject)
return priv->unix_process.dbus_sender;
}
const char *
nm_auth_subject_get_unix_session_id (NMAuthSubject *subject)
{
CHECK_SUBJECT_TYPED (subject, NM_AUTH_SUBJECT_TYPE_UNIX_SESSION, NULL);
return priv->unix_session.id;
}
/*****************************************************************************/
/**
@ -165,10 +179,26 @@ nm_auth_subject_new_internal (void)
NULL));
}
/**
* nm_auth_subject_new_unix_session():
*
* Creates a new auth subject representing a given unix session.
*
* Returns: the new #NMAuthSubject
*/
NMAuthSubject *
nm_auth_subject_new_unix_session (const char *session_id)
{
return NM_AUTH_SUBJECT (g_object_new (NM_TYPE_AUTH_SUBJECT,
NM_AUTH_SUBJECT_SUBJECT_TYPE, (int) NM_AUTH_SUBJECT_TYPE_UNIX_SESSION,
NM_AUTH_SUBJECT_UNIX_SESSION_ID, session_id,
NULL));
}
/**
* nm_auth_subject_new_unix_process():
*
* Creates a new auth subject representing a give unix process.
* Creates a new auth subject representing a given unix process.
*
* Returns: the new #NMAuthSubject
*/
@ -176,11 +206,11 @@ NMAuthSubject *
nm_auth_subject_new_unix_process (const char *dbus_sender, gulong pid, gulong uid)
{
return NM_AUTH_SUBJECT (g_object_new (NM_TYPE_AUTH_SUBJECT,
NM_AUTH_SUBJECT_SUBJECT_TYPE, (int) NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS,
NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER, dbus_sender,
NM_AUTH_SUBJECT_UNIX_PROCESS_PID, pid,
NM_AUTH_SUBJECT_UNIX_PROCESS_UID, uid,
NULL));
NM_AUTH_SUBJECT_SUBJECT_TYPE, (int) NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS,
NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER, dbus_sender,
NM_AUTH_SUBJECT_UNIX_PROCESS_PID, pid,
NM_AUTH_SUBJECT_UNIX_PROCESS_UID, uid,
NULL));
}
/**
@ -216,6 +246,9 @@ get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
case PROP_UNIX_PROCESS_UID:
g_value_set_ulong (value, priv->unix_process.uid);
break;
case PROP_UNIX_SESSION_ID:
g_value_set_string (value, priv->unix_session.id);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -235,7 +268,10 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *p
case PROP_SUBJECT_TYPE:
/* construct-only */
i = g_value_get_int (value);
g_return_if_fail (NM_IN_SET (i, (int) NM_AUTH_SUBJECT_TYPE_INTERNAL, (int) NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS));
g_return_if_fail (NM_IN_SET (i,
(int) NM_AUTH_SUBJECT_TYPE_INTERNAL,
(int) NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS,
(int) NM_AUTH_SUBJECT_TYPE_UNIX_SESSION));
subject_type = i;
priv->subject_type |= subject_type;
g_return_if_fail (priv->subject_type == subject_type);
@ -264,6 +300,14 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *p
priv->unix_process.uid = id;
}
break;
case PROP_UNIX_SESSION_ID:
/* construct-only */
if ((str = g_value_get_string (value))) {
priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_SESSION;
g_return_if_fail (priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_SESSION);
priv->unix_session.id = g_strdup (str);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -278,7 +322,9 @@ _clear_private (NMAuthSubject *self)
priv->subject_type = NM_AUTH_SUBJECT_TYPE_INVALID;
priv->unix_process.pid = G_MAXULONG;
priv->unix_process.uid = G_MAXULONG;
g_clear_pointer (&priv->unix_process.dbus_sender, g_free);
nm_clear_g_free (&priv->unix_process.dbus_sender);
nm_clear_g_free (&priv->unix_session.id);
}
static void
@ -328,6 +374,8 @@ constructed (GObject *object)
* start-time, but polkit is not. */
}
return;
case NM_AUTH_SUBJECT_TYPE_UNIX_SESSION:
return;
default:
break;
}
@ -358,7 +406,7 @@ nm_auth_subject_class_init (NMAuthSubjectClass *config_class)
(object_class, PROP_SUBJECT_TYPE,
g_param_spec_int (NM_AUTH_SUBJECT_SUBJECT_TYPE, "", "",
NM_AUTH_SUBJECT_TYPE_INVALID,
NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS,
NM_AUTH_SUBJECT_TYPE_UNIX_SESSION,
NM_AUTH_SUBJECT_TYPE_INVALID,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
@ -388,4 +436,11 @@ nm_auth_subject_class_init (NMAuthSubjectClass *config_class)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_UNIX_SESSION_ID,
g_param_spec_string (NM_AUTH_SUBJECT_UNIX_SESSION_ID, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}

View file

@ -17,12 +17,14 @@ typedef enum {
NM_AUTH_SUBJECT_TYPE_INVALID = 0,
NM_AUTH_SUBJECT_TYPE_INTERNAL = 1,
NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS = 2,
NM_AUTH_SUBJECT_TYPE_UNIX_SESSION = 4,
} NMAuthSubjectType;
#define NM_AUTH_SUBJECT_SUBJECT_TYPE "subject-type"
#define NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER "unix-process-dbus-sender"
#define NM_AUTH_SUBJECT_UNIX_PROCESS_PID "unix-process-pid"
#define NM_AUTH_SUBJECT_UNIX_PROCESS_UID "unix-process-uid"
#define NM_AUTH_SUBJECT_SUBJECT_TYPE "subject-type"
#define NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER "unix-process-dbus-sender"
#define NM_AUTH_SUBJECT_UNIX_PROCESS_PID "unix-process-pid"
#define NM_AUTH_SUBJECT_UNIX_PROCESS_UID "unix-process-uid"
#define NM_AUTH_SUBJECT_UNIX_SESSION_ID "unix-session-id"
typedef struct _NMAuthSubjectClass NMAuthSubjectClass;
typedef struct _NMAuthSubject NMAuthSubject;
@ -31,24 +33,24 @@ GType nm_auth_subject_get_type (void);
NMAuthSubject *nm_auth_subject_new_internal (void);
NMAuthSubject *nm_auth_subject_new_unix_session (const char *session_id);
NMAuthSubject *nm_auth_subject_new_unix_process (const char *dbus_sender, gulong pid, gulong uid);
NMAuthSubject *nm_auth_subject_new_unix_process_self (void);
NMAuthSubjectType nm_auth_subject_get_subject_type (NMAuthSubject *subject);
gboolean nm_auth_subject_is_internal (NMAuthSubject *subject);
gboolean nm_auth_subject_is_unix_process (NMAuthSubject *subject);
gulong nm_auth_subject_get_unix_process_pid (NMAuthSubject *subject);
const char *nm_auth_subject_get_unix_process_dbus_sender (NMAuthSubject *subject);
gulong nm_auth_subject_get_unix_process_uid (NMAuthSubject *subject);
const char *nm_auth_subject_get_unix_session_id (NMAuthSubject *subject);
const char *nm_auth_subject_to_string (NMAuthSubject *self, char *buf, gsize buf_len);
GVariant * nm_auth_subject_unix_process_to_polkit_gvariant (NMAuthSubject *self);
GVariant *nm_auth_subject_unix_to_polkit_gvariant (NMAuthSubject *self);
#endif /* __NETWORKMANAGER_AUTH_SUBJECT_H__ */

View file

@ -598,7 +598,9 @@ nm_active_connection_get_user_requested (NMActiveConnection *self)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
return nm_auth_subject_is_unix_process (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->subject);
return nm_auth_subject_get_subject_type (
NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->subject
) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS;
}
NMDevice *

View file

@ -200,7 +200,8 @@ _audit_log_helper (NMAuditManager *self,
} else
g_warn_if_reached ();
}
if (subject && nm_auth_subject_is_unix_process (subject)) {
if (subject &&
nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) {
pid = nm_auth_subject_get_unix_process_pid (subject);
uid = nm_auth_subject_get_unix_process_uid (subject);
if (pid != G_MAXULONG) {

View file

@ -322,7 +322,7 @@ nm_auth_manager_check_authorization (NMAuthManager *self,
};
c_list_link_tail (&priv->calls_lst_head, &call_id->calls_lst);
if (nm_auth_subject_is_internal (subject)) {
if (nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL) {
_LOG2T (call_id, "CheckAuthorization(%s), subject=%s (succeeding for internal request)", action_id, nm_auth_subject_to_string (subject, subject_buf, sizeof (subject_buf)));
call_id->idle_id = g_idle_add (_call_on_idle, call_id);
} else if (nm_auth_subject_get_unix_process_uid (subject) == 0) {
@ -339,7 +339,7 @@ nm_auth_manager_check_authorization (NMAuthManager *self,
GVariant *subject_value;
GVariant *details_value;
subject_value = nm_auth_subject_unix_process_to_polkit_gvariant (subject);
subject_value = nm_auth_subject_unix_to_polkit_gvariant (subject);
nm_assert (g_variant_is_floating (subject_value));
/* ((PolkitDetails *)NULL) */

View file

@ -342,8 +342,10 @@ nm_auth_chain_add_call_unsafe (NMAuthChain *self,
g_return_if_fail (!self->is_finishing);
g_return_if_fail (!self->is_destroyed);
g_return_if_fail (permission && *permission);
nm_assert ( nm_auth_subject_is_unix_process (self->subject)
|| nm_auth_subject_is_internal (self->subject));
nm_assert ( nm_auth_subject_get_subject_type (self->subject)
== NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS
|| nm_auth_subject_get_subject_type (self->subject)
== NM_AUTH_SUBJECT_TYPE_INTERNAL);
/* duplicate permissions are not supported, also because nm_auth_chain_get_result()
* can only return one-permission. */
@ -417,8 +419,10 @@ nm_auth_chain_new_subject (NMAuthSubject *subject,
NMAuthChain *self;
g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
nm_assert ( nm_auth_subject_is_unix_process (subject)
|| nm_auth_subject_is_internal (subject));
nm_assert ( nm_auth_subject_get_subject_type (subject)
== NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS
|| nm_auth_subject_get_subject_type (subject)
== NM_AUTH_SUBJECT_TYPE_INTERNAL);
nm_assert (done_func);
self = g_slice_new (NMAuthChain);
@ -505,10 +509,12 @@ nm_auth_is_subject_in_acl (NMConnection *connection,
g_return_val_if_fail (connection, FALSE);
g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), FALSE);
nm_assert ( nm_auth_subject_is_internal (subject)
|| nm_auth_subject_is_unix_process (subject));
nm_assert ( nm_auth_subject_get_subject_type (subject)
== NM_AUTH_SUBJECT_TYPE_INTERNAL
|| nm_auth_subject_get_subject_type (subject)
== NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS);
if (nm_auth_subject_is_internal (subject))
if (nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL)
return TRUE;
uid = nm_auth_subject_get_unix_process_uid (subject);

View file

@ -4514,7 +4514,7 @@ unmanaged_to_disconnected (NMDevice *device)
static NMActivationStateFlags
_activation_bind_lifetime_to_profile_visibility (NMAuthSubject *subject)
{
if ( nm_auth_subject_is_internal (subject)
if ( nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL
|| nm_auth_subject_get_unix_process_uid (subject) == 0) {
/* internal requests and requests from root are always unbound. */
return NM_ACTIVATION_STATE_FLAG_NONE;
@ -5098,8 +5098,10 @@ nm_manager_activate_connection (NMManager *self,
if ( sett_conn == nm_active_connection_get_settings_connection (active)
&& nm_streq0 (nm_active_connection_get_specific_object (active), specific_object)
&& (!device || nm_active_connection_get_device (active) == device)
&& nm_auth_subject_is_internal (nm_active_connection_get_subject (active))
&& nm_auth_subject_is_internal (subject)
&& nm_auth_subject_get_subject_type (nm_active_connection_get_subject (active))
== NM_AUTH_SUBJECT_TYPE_INTERNAL
&& nm_auth_subject_get_subject_type (subject)
== NM_AUTH_SUBJECT_TYPE_INTERNAL
&& nm_active_connection_get_activation_reason (active) == activation_reason)
return active;
}

View file

@ -1633,7 +1633,8 @@ activate_slave_connections (NMPolicy *self, NMDevice *device)
}
subject = nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req));
internal_activation = subject && nm_auth_subject_is_internal (subject);
internal_activation = subject
&& (nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL);
}
changed = FALSE;

View file

@ -626,7 +626,7 @@ agent_compare_func (gconstpointer aa, gconstpointer bb, gpointer user_data)
b_pid = nm_secret_agent_get_pid (b);
/* Prefer agents in the process the request came from */
if (nm_auth_subject_is_unix_process (req->subject)) {
if (nm_auth_subject_get_subject_type (req->subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) {
requester = nm_auth_subject_get_unix_process_pid (req->subject);
if (a_pid != b_pid) {
@ -682,7 +682,7 @@ request_add_agent (Request *req, NMSecretAgent *agent)
}
/* If the request should filter agents by UID, do that now */
if (nm_auth_subject_is_unix_process (req->subject)) {
if (nm_auth_subject_get_subject_type (req->subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) {
uid_t agent_uid, subject_uid;
agent_uid = nm_secret_agent_get_owner_uid (agent);
@ -1409,8 +1409,8 @@ nm_agent_manager_all_agents_have_capability (NMAgentManager *manager,
NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (manager);
GHashTableIter iter;
NMSecretAgent *agent;
gboolean subject_is_unix_process = nm_auth_subject_is_unix_process (subject);
gulong subject_uid = subject_is_unix_process ? nm_auth_subject_get_unix_process_uid (subject) : 0;
gboolean subject_is_unix_process = (nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS);
gulong subject_uid = subject_is_unix_process ? nm_auth_subject_get_unix_process_uid (subject) : 0u;
g_hash_table_iter_init (&iter, priv->agents);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &agent)) {

View file

@ -709,7 +709,8 @@ nm_secret_agent_new (GDBusMethodInvocation *context,
g_return_val_if_fail (context != NULL, NULL);
g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
g_return_val_if_fail (nm_auth_subject_is_unix_process (subject), NULL);
g_return_val_if_fail (nm_auth_subject_get_subject_type (subject)
== NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, NULL);
g_return_val_if_fail (identifier != NULL, NULL);
dbus_connection = g_dbus_method_invocation_get_connection (context);