[glib] Bug 628904 – Add credential support for FreeBSD and fix a socket issue



commit 964eb62343b53cf9172d409adacbb58d78896092
Author: Joe Marcus Clarke <marcus freebsd org>
Date:   Thu Sep 9 14:10:01 2010 -0400

    Bug 628904 â?? Add credential support for FreeBSD and fix a socket issue
    
    Signed-off-by: David Zeuthen <davidz redhat com>

 gio/gcredentials.c            |   53 +++++++++++++++++++++++++++++++++++++++++
 gio/gioenums.h                |    4 ++-
 gio/gsocket.c                 |    9 +++++-
 gio/gunixcredentialsmessage.c |   46 +++++++++++++++++++++++++++++++++++
 4 files changed, 109 insertions(+), 3 deletions(-)
---
diff --git a/gio/gcredentials.c b/gio/gcredentials.c
index a9c2b5a..e2cc7ba 100644
--- a/gio/gcredentials.c
+++ b/gio/gcredentials.c
@@ -22,6 +22,11 @@
 
 #include "config.h"
 
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+#endif
 #include <stdlib.h>
 
 #include <gobject/gvaluecollector.h>
@@ -55,6 +60,9 @@
  * <citerefentry><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry>
  * man page for details. This corresponds to
  * %G_CREDENTIALS_TYPE_LINUX_UCRED.
+ *
+ * On FreeBSD, the native credential type is a <type>struct cmsgcred</type>.
+ * This corresponds to %G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED.
  */
 
 /**
@@ -72,6 +80,8 @@ struct _GCredentials
 
 #ifdef __linux__
   struct ucred native;
+#elif defined(__FreeBSD__)
+  struct cmsgcred native;
 #else
 #ifdef __GNUC__
 #warning Please add GCredentials support for your OS
@@ -120,6 +130,11 @@ g_credentials_init (GCredentials *credentials)
   credentials->native.pid = getpid ();
   credentials->native.uid = geteuid ();
   credentials->native.gid = getegid ();
+#elif defined(__FreeBSD__)
+  memset (&credentials->native, 0, sizeof (struct cmsgcred));
+  credentials->native.cmcred_pid  = getpid ();
+  credentials->native.cmcred_euid = geteuid ();
+  credentials->native.cmcred_gid  = getegid ();
 #endif
 }
 
@@ -173,6 +188,14 @@ g_credentials_to_string (GCredentials *credentials)
     g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
   if (ret->str[ret->len - 1] == ',')
     ret->str[ret->len - 1] = '\0';
+#elif defined(__FreeBSD__)
+  g_string_append (ret, "freebsd-cmsgcred:");
+  if (credentials->native.cmcred_pid != -1)
+    g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_pid);
+  if (credentials->native.cmcred_euid != -1)
+    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_euid);
+  if (credentials->native.cmcred_gid != -1)
+    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_gid);
 #else
   g_string_append (ret, "unknown");
 #endif
@@ -213,6 +236,9 @@ g_credentials_is_same_user (GCredentials  *credentials,
 #ifdef __linux__
   if (credentials->native.uid == other_credentials->native.uid)
     ret = TRUE;
+#elif defined(__FreeBSD__)
+  if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
+    ret = TRUE;
 #else
   g_set_error_literal (error,
                        G_IO_ERROR,
@@ -263,6 +289,17 @@ g_credentials_get_native (GCredentials     *credentials,
     {
       ret = &credentials->native;
     }
+#elif defined(__FreeBSD__)
+  if (native_type != G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED)
+    {
+      g_warning ("g_credentials_get_native: Trying to get credentials of type %d but only "
+		 "G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED is supported.",
+		 native_type);
+    }
+  else
+    {
+      ret = &credentials->native;
+    }
 #else
   g_warning ("g_credentials_get_native: Trying to get credentials but GLib has no support "
              "for the native credentials type. Please add support.");
@@ -302,6 +339,17 @@ g_credentials_set_native (GCredentials     *credentials,
     {
       memcpy (&credentials->native, native, sizeof (struct ucred));
     }
+#elif defined(__FreeBSD__)
+  if (native_type != G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED)
+    {
+      g_warning ("g_credentials_set_native: Trying to set credentials of type %d "
+		  "but only G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED is supported.",
+		  native_type);
+    }
+  else
+    {
+      memcpy (&credentials->native, native, sizeof (struct cmsgcred));
+    }
 #else
   g_warning ("g_credentials_set_native: Trying to set credentials but GLib has no support "
              "for the native credentials type. Please add support.");
@@ -338,6 +386,8 @@ g_credentials_get_unix_user (GCredentials    *credentials,
 
 #ifdef __linux__
   ret = credentials->native.uid;
+#elif defined(__FreeBSD__)
+  ret = credentials->native.cmcred_euid;
 #else
   ret = -1;
   g_set_error_literal (error,
@@ -381,6 +431,9 @@ g_credentials_set_unix_user (GCredentials    *credentials,
 #ifdef __linux__
   credentials->native.uid = uid;
   ret = TRUE;
+#elif defined(__FreeBSD__)
+  credentials->native.cmcred_euid = uid;
+  ret = TRUE;
 #else
   g_set_error_literal (error,
                        G_IO_ERROR,
diff --git a/gio/gioenums.h b/gio/gioenums.h
index 967b061..10eedfd 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -1188,6 +1188,7 @@ typedef enum
  * GCredentialsType:
  * @G_CREDENTIALS_TYPE_INVALID: Indicates an invalid native credential type.
  * @G_CREDENTIALS_TYPE_LINUX_UCRED: The native credentials type is a <type>struct ucred</type>.
+ * @G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED: The native credentials type is a <type>struct cmsgcred</type>.
  *
  * Enumeration describing different kinds of native credential types.
  *
@@ -1196,7 +1197,8 @@ typedef enum
 typedef enum
 {
   G_CREDENTIALS_TYPE_INVALID,
-  G_CREDENTIALS_TYPE_LINUX_UCRED
+  G_CREDENTIALS_TYPE_LINUX_UCRED,
+  G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED
 } GCredentialsType;
 
 /**
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 57be472..ba7be01 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -2928,8 +2928,13 @@ g_socket_send_message (GSocket                *socket,
       for (i = 0; i < num_messages; i++)
 	msg.msg_controllen += CMSG_SPACE (g_socket_control_message_get_size (messages[i]));
 
-      msg.msg_control = g_alloca (msg.msg_controllen);
-      memset (msg.msg_control, '\0', msg.msg_controllen);
+      if (msg.msg_controllen == 0)
+        msg.msg_control = NULL;
+      else
+        {
+          msg.msg_control = g_alloca (msg.msg_controllen);
+          memset (msg.msg_control, '\0', msg.msg_controllen);
+        }
 
       cmsg = CMSG_FIRSTHDR (&msg);
       for (i = 0; i < num_messages; i++)
diff --git a/gio/gunixcredentialsmessage.c b/gio/gunixcredentialsmessage.c
index e6dadfb..82224ab 100644
--- a/gio/gunixcredentialsmessage.c
+++ b/gio/gunixcredentialsmessage.c
@@ -46,6 +46,13 @@
 #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
@@ -79,6 +86,8 @@ g_unix_credentials_message_get_size (GSocketControlMessage *message)
 {
 #ifdef __linux__
   return sizeof (struct ucred);
+#elif defined(__FreeBSD__)
+  return sizeof (struct cmsgcred);
 #else
   return 0;
 #endif
@@ -89,6 +98,8 @@ g_unix_credentials_message_get_level (GSocketControlMessage *message)
 {
 #ifdef __linux__
   return SOL_SOCKET;
+#elif defined(__FreeBSD__)
+  return SOL_SOCKET;
 #else
   return 0;
 #endif
@@ -99,6 +110,8 @@ g_unix_credentials_message_get_msg_type (GSocketControlMessage *message)
 {
 #ifdef __linux__
   return SCM_CREDENTIALS;
+#elif defined(__FreeBSD__)
+  return SCM_CREDS;
 #else
   return 0;
 #endif
@@ -140,6 +153,33 @@ g_unix_credentials_message_deserialize (gint     level,
  out:
     ;
   }
+#elif defined(__FreeBSD__)
+  {
+    GCredentials *credentials;
+    struct cmsgcred *cred;
+
+    if (level != SOL_SOCKET || type != SCM_CREDS)
+      {
+        goto out;
+      }
+    if (size < CMSG_LEN (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_native (credentials, G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED, cred);
+    message = g_unix_credentials_message_new_with_credentials (credentials);
+    g_object_unref (credentials);
+ out:
+    ;
+  }
 #endif
 
   return message;
@@ -155,6 +195,12 @@ g_unix_credentials_message_serialize (GSocketControlMessage *_message,
           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
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]