*/
/**
- * SECTION: gunixcredentialsmessage
+ * SECTION:gunixcredentialsmessage
* @title: GUnixCredentialsMessage
* @short_description: A GSocketControlMessage containing credentials
+ * @include: gio/gunixcredentialsmessage.h
* @see_also: #GUnixConnection, #GSocketControlMessage
*
* This #GSocketControlMessage contains a #GCredentials instance. It
* may be sent using g_socket_send_message() and received using
* g_socket_receive_message() over UNIX sockets (ie: sockets in the
- * %G_SOCKET_ADDRESS_UNIX family).
+ * %G_SOCKET_FAMILY_UNIX family).
*
* For an easier way to send and receive credentials over
- * stream-oriented UNIX sockets, see g_unix_connection_send_credentials() and
- * g_unix_connection_receive_credentials().
- **/
+ * stream-oriented UNIX sockets, see
+ * g_unix_connection_send_credentials() and
+ * g_unix_connection_receive_credentials(). To receive credentials of
+ * a foreign process connected to a socket, use
+ * g_socket_get_credentials().
+ */
#include "config.h"
-#include <glib/gi18n.h>
-
/* ---------------------------------------------------------------------------------------------------- */
#ifdef __linux__
-
-#define _GNU_SOURCE
-#define __USE_GNU
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
#define G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
+#elif defined(__FreeBSD__)
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <fcntl.h>
+#define G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
#else
/* TODO: please add support for your UNIX flavor */
#define G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 0
#include "gunixcredentialsmessage.h"
#include "gcredentials.h"
+#include "glibintl.h"
+
struct _GUnixCredentialsMessagePrivate
{
GCredentials *credentials;
{
#ifdef __linux__
return sizeof (struct ucred);
+#elif defined(__FreeBSD__)
+ return sizeof (struct cmsgcred);
#else
return 0;
#endif
static int
g_unix_credentials_message_get_level (GSocketControlMessage *message)
{
+#ifdef __linux__
return SOL_SOCKET;
+#elif defined(__FreeBSD__)
+ return SOL_SOCKET;
+#else
+ return 0;
+#endif
}
static int
{
#ifdef __linux__
return SCM_CREDENTIALS;
+#elif defined(__FreeBSD__)
+ return SCM_CREDS;
#else
return 0;
#endif
ucred = data;
+ if (ucred->uid == (uid_t)-1 &&
+ ucred->gid == (gid_t)-1)
+ {
+ /* This happens if the remote side didn't pass the credentials */
+ goto out;
+ }
+
+ credentials = g_credentials_new ();
+ g_credentials_set_native (credentials, G_CREDENTIALS_TYPE_LINUX_UCRED, ucred);
+ message = g_unix_credentials_message_new_with_credentials (credentials);
+ g_object_unref (credentials);
+ out:
+ ;
+ }
+#elif defined(__FreeBSD__)
+ {
+ GCredentials *credentials;
+ struct cmsgcred *cred;
+
+ if (level != SOL_SOCKET || type != SCM_CREDS)
+ {
+ goto out;
+ }
+ if (size < sizeof *cred)
+ {
+ g_warning ("Expected a struct cmsgcred (%" G_GSIZE_FORMAT " bytes) but "
+ "got %" G_GSIZE_FORMAT " bytes of data",
+ CMSG_LEN (sizeof *cred),
+ size);
+ goto out;
+ }
+
+ cred = data;
+
credentials = g_credentials_new ();
- g_credentials_set_unix_user (credentials, ucred->uid);
- g_credentials_set_unix_group (credentials, ucred->gid);
- g_credentials_set_unix_process (credentials, ucred->pid);
+ g_credentials_set_native (credentials, G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED, cred);
message = g_unix_credentials_message_new_with_credentials (credentials);
g_object_unref (credentials);
out:
{
GUnixCredentialsMessage *message = G_UNIX_CREDENTIALS_MESSAGE (_message);
#ifdef __linux__
- {
- struct ucred *ucred = data;
- ucred->uid = g_credentials_get_unix_user (message->priv->credentials);
- ucred->gid = g_credentials_get_unix_group (message->priv->credentials);
- ucred->pid = g_credentials_get_unix_process (message->priv->credentials);
- }
+ memcpy (data,
+ g_credentials_get_native (message->priv->credentials,
+ G_CREDENTIALS_TYPE_LINUX_UCRED),
+ sizeof (struct ucred));
+#elif defined(__FreeBSD__)
+ memcpy (data,
+ g_credentials_get_native (message->priv->credentials,
+ G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED),
+ sizeof (struct cmsgcred));
+
#endif
}
if (message->priv->credentials != NULL)
g_object_unref (message->priv->credentials);
- if (G_OBJECT_CLASS (g_unix_credentials_message_parent_class)->finalize != NULL)
- G_OBJECT_CLASS (g_unix_credentials_message_parent_class)->finalize (object);
+ G_OBJECT_CLASS (g_unix_credentials_message_parent_class)->finalize (object);
}
static void
GUnixCredentialsMessage *message = G_UNIX_CREDENTIALS_MESSAGE (object);
if (message->priv->credentials == NULL)
- message->priv->credentials = g_credentials_new_for_process ();
+ message->priv->credentials = g_credentials_new ();
if (G_OBJECT_CLASS (g_unix_credentials_message_parent_class)->constructed != NULL)
G_OBJECT_CLASS (g_unix_credentials_message_parent_class)->constructed (object);
g_object_class_install_property (gobject_class,
PROP_CREDENTIALS,
g_param_spec_object ("credentials",
- _("Credentials"),
- _("The credentials stored in the message"),
+ P_("Credentials"),
+ P_("The credentials stored in the message"),
G_TYPE_CREDENTIALS,
G_PARAM_READABLE |
G_PARAM_WRITABLE |
/**
* g_unix_credentials_message_is_supported:
*
- * Checks if passing a #GCredential on a #GSocket is supported on this platform.
+ * Checks if passing #GCredentials on a #GSocket is supported on this platform.
*
* Returns: %TRUE if supported, %FALSE otherwise
*
}
/**
- * g_unix_credentials_message_new:
+ * g_unix_credentials_message_new_with_credentials:
* @credentials: A #GCredentials object.
*
* Creates a new #GUnixCredentialsMessage holding @credentials.
*
* Gets the credentials stored in @message.
*
- * Returns: A #GCredentials instance. Do not free, it is owned by @message.
+ * Returns: (transfer none): A #GCredentials instance. Do not free, it is owned by @message.
*
* Since: 2.26
*/
g_return_val_if_fail (G_IS_UNIX_CREDENTIALS_MESSAGE (message), NULL);
return message->priv->credentials;
}
-