GVariant: add support for single precision floats
[platform/upstream/glib.git] / gio / gcredentials.c
index 8ac7a39..6673afd 100644 (file)
@@ -13,9 +13,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: David Zeuthen <davidz@redhat.com>
  */
  * #GUnixCredentialsMessage, g_unix_connection_send_credentials() and
  * g_unix_connection_receive_credentials() for details.
  *
- * On Linux, the native credential type is a <type>struct ucred</type>
- * - see the
- * <citerefentry><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- * man page for details. This corresponds to
+ * On Linux, the native credential type is a struct ucred - see the
+ * unix(7) 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.
+ * On FreeBSD, Debian GNU/kFreeBSD, and GNU/Hurd, the native
+ * credential type is a struct cmsgcred. This corresponds
+ * to %G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED.
  *
- * On OpenBSD, the native credential type is a <type>struct sockpeercred</type>.
+ * On NetBSD, the native credential type is a struct unpcbid.
+ * This corresponds to %G_CREDENTIALS_TYPE_NETBSD_UNPCBID.
+ *
+ * On OpenBSD, the native credential type is a struct sockpeercred.
  * This corresponds to %G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED.
+ *
+ * On Solaris (including OpenSolaris and its derivatives), the native
+ * credential type is a ucred_t. This corresponds to
+ * %G_CREDENTIALS_TYPE_SOLARIS_UCRED.
  */
 
 /**
@@ -83,8 +87,12 @@ struct _GCredentials
   struct ucred native;
 #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   struct cmsgcred native;
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  struct unpcbid native;
 #elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   struct sockpeercred native;
+#elif G_CREDENTIALS_USE_SOLARIS_UCRED
+  ucred_t *native;
 #else
   #ifdef __GNUC__
   #warning Please add GCredentials support for your OS
@@ -110,7 +118,11 @@ G_DEFINE_TYPE (GCredentials, g_credentials, G_TYPE_OBJECT);
 static void
 g_credentials_finalize (GObject *object)
 {
-  G_GNUC_UNUSED GCredentials *credentials = G_CREDENTIALS (object);
+#if G_CREDENTIALS_USE_SOLARIS_UCRED
+  GCredentials *credentials = G_CREDENTIALS (object);
+
+  ucred_free (credentials->native);
+#endif
 
   if (G_OBJECT_CLASS (g_credentials_parent_class)->finalize != NULL)
     G_OBJECT_CLASS (g_credentials_parent_class)->finalize (object);
@@ -138,10 +150,16 @@ g_credentials_init (GCredentials *credentials)
   credentials->native.cmcred_pid  = getpid ();
   credentials->native.cmcred_euid = geteuid ();
   credentials->native.cmcred_gid  = getegid ();
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  credentials->native.unp_pid = getpid ();
+  credentials->native.unp_euid = geteuid ();
+  credentials->native.unp_egid = getegid ();
 #elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   credentials->native.pid = getpid ();
   credentials->native.uid = geteuid ();
   credentials->native.gid = getegid ();
+#elif G_CREDENTIALS_USE_SOLARIS_UCRED
+  credentials->native = ucred_get (P_MYID);
 #endif
 }
 
@@ -203,6 +221,15 @@ g_credentials_to_string (GCredentials *credentials)
     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);
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  g_string_append (ret, "netbsd-unpcbid:");
+  if (credentials->native.unp_pid != -1)
+    g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_pid);
+  if (credentials->native.unp_euid != -1)
+    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_euid);
+  if (credentials->native.unp_egid != -1)
+    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_egid);
+  ret->str[ret->len - 1] = '\0';
 #elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   g_string_append (ret, "openbsd-sockpeercred:");
   if (credentials->native.pid != -1)
@@ -213,6 +240,19 @@ 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 G_CREDENTIALS_USE_SOLARIS_UCRED
+  g_string_append (ret, "solaris-ucred:");
+  {
+    id_t id;
+    if ((id = ucred_getpid (credentials->native)) != -1)
+      g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) id);
+    if ((id = ucred_geteuid (credentials->native)) != -1)
+      g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) id);
+    if ((id = ucred_getegid (credentials->native)) != -1)
+      g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) id);
+    if (ret->str[ret->len - 1] == ',')
+      ret->str[ret->len - 1] = '\0';
+  }
 #else
   g_string_append (ret, "unknown");
 #endif
@@ -256,9 +296,15 @@ g_credentials_is_same_user (GCredentials  *credentials,
 #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
     ret = TRUE;
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  if (credentials->native.unp_euid == other_credentials->native.unp_euid)
+    ret = TRUE;
 #elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   if (credentials->native.uid == other_credentials->native.uid)
     ret = TRUE;
+#elif G_CREDENTIALS_USE_SOLARIS_UCRED
+  if (ucred_geteuid (credentials->native) == ucred_geteuid (other_credentials->native))
+    ret = TRUE;
 #else
   g_set_error_literal (error,
                        G_IO_ERROR,
@@ -289,6 +335,7 @@ credentials_native_type_check (GCredentialsType  requested_type,
 
 #if G_CREDENTIALS_SUPPORTED
   supported = g_enum_get_value (enum_class, G_CREDENTIALS_NATIVE_TYPE);
+  g_assert (supported);
   g_warning ("g_credentials_%s_native: Trying to %s credentials of type %s "
              "but only %s is supported on this platform.",
              op, op,
@@ -333,7 +380,9 @@ g_credentials_get_native (GCredentials     *credentials,
   if (!credentials_native_type_check (native_type, "get"))
     return NULL;
 
-#if G_CREDENTIALS_SUPPORTED
+#if G_CREDENTIALS_USE_SOLARIS_UCRED
+  return credentials->native;
+#elif G_CREDENTIALS_SUPPORTED
   return &credentials->native;
 #else
   g_assert_not_reached ();
@@ -363,7 +412,9 @@ g_credentials_set_native (GCredentials     *credentials,
   if (!credentials_native_type_check (native_type, "set"))
     return;
 
-#if G_CREDENTIALS_SUPPORTED
+#if G_CREDENTIALS_USE_SOLARIS_UCRED
+  memcpy (credentials->native, native, ucred_size ());
+#elif G_CREDENTIALS_SUPPORTED
   memcpy (&credentials->native, native, sizeof (credentials->native));
 #else
   g_assert_not_reached ();
@@ -402,8 +453,12 @@ g_credentials_get_unix_user (GCredentials    *credentials,
   ret = credentials->native.uid;
 #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   ret = credentials->native.cmcred_euid;
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  ret = credentials->native.unp_euid;
 #elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   ret = credentials->native.uid;
+#elif G_CREDENTIALS_USE_SOLARIS_UCRED
+  ret = ucred_geteuid (credentials->native);
 #else
   ret = -1;
   g_set_error_literal (error,
@@ -444,8 +499,12 @@ g_credentials_get_unix_pid (GCredentials    *credentials,
   ret = credentials->native.pid;
 #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   ret = credentials->native.cmcred_pid;
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  ret = credentials->native.unp_pid;
 #elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   ret = credentials->native.pid;
+#elif G_CREDENTIALS_USE_SOLARIS_UCRED
+  ret = ucred_getpid (credentials->native);
 #else
   ret = -1;
   g_set_error_literal (error,
@@ -468,7 +527,8 @@ g_credentials_get_unix_pid (GCredentials    *credentials,
  *
  * This operation can fail if #GCredentials is not supported on the
  * OS or if the native credentials type does not contain information
- * about the UNIX user.
+ * about the UNIX user. It can also fail if the OS does not allow the
+ * use of "spoofed" credentials.
  *
  * Returns: %TRUE if @uid was set, %FALSE if error is set.
  *
@@ -492,14 +552,24 @@ g_credentials_set_unix_user (GCredentials    *credentials,
 #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   credentials->native.cmcred_euid = uid;
   ret = TRUE;
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  credentials->native.unp_euid = uid;
+  ret = TRUE;
 #elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   credentials->native.uid = uid;
   ret = TRUE;
+#elif !G_CREDENTIALS_SPOOFING_SUPPORTED
+  g_set_error_literal (error,
+                       G_IO_ERROR,
+                       G_IO_ERROR_PERMISSION_DENIED,
+                       _("Credentials spoofing is not possible on this OS"));
+  ret = FALSE;
 #else
   g_set_error_literal (error,
                        G_IO_ERROR,
                        G_IO_ERROR_NOT_SUPPORTED,
                        _("GCredentials is not implemented on this OS"));
+  ret = FALSE;
 #endif
 
   return ret;