core: add NMAuthSubject object to encapsulate authentication info

This object encapsulates all authentication information we need
about some entity that requests that NetworkManager perform an
action on its behalf.
This commit is contained in:
Dan Williams
2013-07-25 22:53:43 -05:00
parent 7a9d5a262a
commit 49d098f29d
4 changed files with 281 additions and 0 deletions

View File

@@ -248,6 +248,8 @@ nm_sources = \
nm-ip6-config.h \
nm-manager-auth.c \
nm-manager-auth.h \
nm-auth-subject.c \
nm-auth-subject.h \
nm-manager.c \
nm-manager.h \
nm-netlink-monitor.c \

View File

@@ -9,6 +9,7 @@ AM_CPPFLAGS = \
-I${top_builddir}/libnm-util \
-I${top_srcdir}/libnm-util \
$(DBUS_CFLAGS) \
$(POLKIT_CFLAGS) \
$(IWMX_SDK_CFLAGS) \
$(LIBNL_CFLAGS) \
$(GUDEV_CFLAGS)

210
src/nm-auth-subject.c Normal file
View File

@@ -0,0 +1,210 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2013 Red Hat, Inc.
*/
/**
* SECTION:nm-auth-subject
* @short_description: Encapsulates authentication information about a requestor
*
* #NMAuthSubject encpasulates identifying information about an entity that
* makes requests, like process identifier and user UID.
*/
#include <config.h>
#include <glib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#if WITH_POLKIT
#include <polkit/polkit.h>
#endif
#include "nm-auth-subject.h"
#include "nm-dbus-manager.h"
G_DEFINE_TYPE (NMAuthSubject, nm_auth_subject, G_TYPE_OBJECT)
#define NM_AUTH_SUBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_AUTH_SUBJECT, NMAuthSubjectPrivate))
typedef struct {
gulong pid;
gulong uid;
char *dbus_sender;
#if WITH_POLKIT
PolkitSubject *pk_subject;
#endif
} NMAuthSubjectPrivate;
static NMAuthSubject *
_new_common (DBusGMethodInvocation *context,
DBusConnection *connection,
DBusMessage *message,
gboolean internal)
{
NMAuthSubject *subject;
NMAuthSubjectPrivate *priv;
NMDBusManager *dbus_mgr;
gboolean success = FALSE;
g_return_val_if_fail (context || (connection && message) || internal, NULL);
if (internal)
g_return_val_if_fail (context == NULL && connection == NULL && message == NULL, NULL);
subject = NM_AUTH_SUBJECT (g_object_new (NM_TYPE_AUTH_SUBJECT, NULL));
priv = NM_AUTH_SUBJECT_GET_PRIVATE (subject);
dbus_mgr = nm_dbus_manager_get ();
if (internal) {
priv->uid = 0;
priv->pid = 0;
return subject;
}
if (context) {
success = nm_dbus_manager_get_caller_info (dbus_mgr,
context,
&priv->dbus_sender,
&priv->uid,
&priv->pid);
} else if (message) {
success = nm_dbus_manager_get_caller_info_from_message (dbus_mgr,
connection,
message,
&priv->dbus_sender,
&priv->uid,
&priv->pid);
} else
g_assert_not_reached ();
if (!success) {
g_object_unref (subject);
return NULL;
}
g_assert (priv->dbus_sender);
g_assert_cmpuint (priv->pid, !=, 0);
#if WITH_POLKIT
/* FIXME: should we use polkit_unix_session_new() to store the session ID
* of a short-lived process, so that the process can exit but we can still
* ask that user for authorization?
*/
priv->pk_subject = polkit_unix_process_new_for_owner (priv->pid, 0, priv->uid);
if (!priv->pk_subject)
return NULL;
#endif
return subject;
}
NMAuthSubject *
nm_auth_subject_new_from_context (DBusGMethodInvocation *context)
{
return _new_common (context, NULL, NULL, FALSE);
}
NMAuthSubject *
nm_auth_subject_new_from_message (DBusConnection *connection,
DBusMessage *message)
{
return _new_common (NULL, connection, message, FALSE);
}
/**
* nm_auth_subject_new_internal():
*
* Creates a new auth subject representing the NetworkManager process itself.
*
* Returns: the new #NMAuthSubject
*/
NMAuthSubject *
nm_auth_subject_new_internal (void)
{
return _new_common (NULL, NULL, NULL, TRUE);
}
/**************************************************************/
gulong
nm_auth_subject_get_uid (NMAuthSubject *subject)
{
return NM_AUTH_SUBJECT_GET_PRIVATE (subject)->uid;
}
const char *
nm_auth_subject_get_dbus_sender (NMAuthSubject *subject)
{
return NM_AUTH_SUBJECT_GET_PRIVATE (subject)->dbus_sender;
}
gboolean
nm_auth_subject_get_internal (NMAuthSubject *subject)
{
/* internal requests will have no dbus sender */
return NM_AUTH_SUBJECT_GET_PRIVATE (subject)->dbus_sender ? FALSE : TRUE;
}
#if WITH_POLKIT
PolkitSubject *
nm_auth_subject_get_polkit_subject (NMAuthSubject *subject)
{
return NM_AUTH_SUBJECT_GET_PRIVATE (subject)->pk_subject;
}
#endif
/******************************************************************/
static void
nm_auth_subject_init (NMAuthSubject *self)
{
NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (self);
priv->pid = G_MAXULONG;
priv->uid = G_MAXULONG;
}
static void
finalize (GObject *object)
{
NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object);
g_free (priv->dbus_sender);
#if WITH_POLKIT
if (priv->pk_subject)
g_object_unref (priv->pk_subject);
#endif
G_OBJECT_CLASS (nm_auth_subject_parent_class)->finalize (object);
}
static void
nm_auth_subject_class_init (NMAuthSubjectClass *config_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (config_class);
g_type_class_add_private (config_class, sizeof (NMAuthSubjectPrivate));
/* virtual methods */
object_class->finalize = finalize;
}

68
src/nm-auth-subject.h Normal file
View File

@@ -0,0 +1,68 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2013 Red Hat, Inc.
*/
#ifndef NM_AUTH_SUBJECT_H
#define NM_AUTH_SUBJECT_H
#include <config.h>
#include <glib.h>
#include <glib-object.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#if WITH_POLKIT
#include <polkit/polkit.h>
#endif
#define NM_TYPE_AUTH_SUBJECT (nm_auth_subject_get_type ())
#define NM_AUTH_SUBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AUTH_SUBJECT, NMAuthSubject))
#define NM_AUTH_SUBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AUTH_SUBJECT, NMAuthSubjectClass))
#define NM_IS_AUTH_SUBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_AUTH_SUBJECT))
#define NM_IS_AUTH_SUBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_AUTH_SUBJECT))
#define NM_AUTH_SUBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AUTH_SUBJECT, NMAuthSubjectClass))
typedef struct {
GObject parent;
} NMAuthSubject;
typedef struct {
GObjectClass parent;
} NMAuthSubjectClass;
GType nm_auth_subject_get_type (void);
NMAuthSubject *nm_auth_subject_new_from_context (DBusGMethodInvocation *context);
NMAuthSubject *nm_auth_subject_new_from_message (DBusConnection *connection, DBusMessage *message);
NMAuthSubject *nm_auth_subject_new_internal (void);
gulong nm_auth_subject_get_uid (NMAuthSubject *subject);
const char *nm_auth_subject_get_dbus_sender (NMAuthSubject *subject);
gboolean nm_auth_subject_get_internal (NMAuthSubject *subject);
#if WITH_POLKIT
PolkitSubject *nm_auth_subject_get_polkit_subject (NMAuthSubject *subject);
#endif
#endif /* NM_AUTH_SUBJECT_H */