X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgcredentials.c;h=6673afddd460611b1051961161351c2ed13c0542;hb=d9ad40b4eaf1a9197ab363de4346a8d84f45f5c1;hp=2f3c7cebe1846e5d839f478713479948bff626f2;hpb=0fd6498cd89888023fb2161bfdde9339a4346986;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gcredentials.c b/gio/gcredentials.c index 2f3c7ce..6673afd 100644 --- a/gio/gcredentials.c +++ b/gio/gcredentials.c @@ -1,6 +1,6 @@ /* GDBus - GLib D-Bus Library * - * Copyright (C) 2008-2009 Red Hat, Inc. + * Copyright (C) 2008-2010 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -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 . * * Author: David Zeuthen */ @@ -23,37 +21,96 @@ #include "config.h" #include -#include +#include + #include #include "gcredentials.h" +#include "gcredentialsprivate.h" +#include "gnetworking.h" #include "gioerror.h" +#include "gioenumtypes.h" -#ifdef G_OS_UNIX -#include -#include -#endif +#include "glibintl.h" /** * SECTION:gcredentials * @short_description: An object containing credentials * @include: gio/gio.h * - * The #GCredentials type is used for storing information that can be - * used for identifying, authenticating and authorizing processes. + * The #GCredentials type is a reference-counted wrapper for native + * credentials. This information is typically used for identifying, + * authenticating and authorizing other processes. * - * Most UNIX and UNIX-like operating systems support a secure exchange - * of credentials over a Unix Domain Socket, see + * Some operating systems supports looking up the credentials of the + * remote peer of a communication endpoint - see e.g. + * g_socket_get_credentials(). + * + * Some operating systems supports securely sending and receiving + * credentials over a Unix Domain Socket, see * #GUnixCredentialsMessage, g_unix_connection_send_credentials() and * g_unix_connection_receive_credentials() for details. + * + * 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, Debian GNU/kFreeBSD, and GNU/Hurd, the native + * credential type is a struct cmsgcred. This corresponds + * to %G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED. + * + * 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. */ -struct _GCredentialsPrivate +/** + * GCredentials: + * + * The #GCredentials structure contains only private data and + * should only be accessed using the provided API. + * + * Since: 2.26 + */ +struct _GCredentials { - gint64 unix_user; - gint64 unix_group; - gint64 unix_process; - gchar *windows_user; + /*< private >*/ + GObject parent_instance; + +#if G_CREDENTIALS_USE_LINUX_UCRED + 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 + #endif +#endif +}; + +/** + * GCredentialsClass: + * + * Class structure for #GCredentials. + * + * Since: 2.26 + */ +struct _GCredentialsClass +{ + /*< private >*/ + GObjectClass parent_class; }; G_DEFINE_TYPE (GCredentials, g_credentials, G_TYPE_OBJECT); @@ -61,9 +118,11 @@ G_DEFINE_TYPE (GCredentials, g_credentials, G_TYPE_OBJECT); static void g_credentials_finalize (GObject *object) { +#if G_CREDENTIALS_USE_SOLARIS_UCRED GCredentials *credentials = G_CREDENTIALS (object); - g_free (credentials->priv->windows_user); + ucred_free (credentials->native); +#endif if (G_OBJECT_CLASS (g_credentials_parent_class)->finalize != NULL) G_OBJECT_CLASS (g_credentials_parent_class)->finalize (object); @@ -75,8 +134,6 @@ g_credentials_class_init (GCredentialsClass *klass) { GObjectClass *gobject_class; - g_type_class_add_private (klass, sizeof (GCredentialsPrivate)); - gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = g_credentials_finalize; } @@ -84,12 +141,26 @@ g_credentials_class_init (GCredentialsClass *klass) static void g_credentials_init (GCredentials *credentials) { - credentials->priv = G_TYPE_INSTANCE_GET_PRIVATE (credentials, G_TYPE_CREDENTIALS, GCredentialsPrivate); - - credentials->priv->unix_user = -1; - credentials->priv->unix_group = -1; - credentials->priv->unix_process = -1; - credentials->priv->windows_user = NULL; +#if G_CREDENTIALS_USE_LINUX_UCRED + credentials->native.pid = getpid (); + credentials->native.uid = geteuid (); + credentials->native.gid = getegid (); +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + memset (&credentials->native, 0, sizeof (struct cmsgcred)); + 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 } /* ---------------------------------------------------------------------------------------------------- */ @@ -97,7 +168,8 @@ g_credentials_init (GCredentials *credentials) /** * g_credentials_new: * - * Creates a new empty credentials object. + * Creates a new #GCredentials object with credentials matching the + * the current process. * * Returns: A #GCredentials. Free with g_object_unref(). * @@ -111,111 +183,13 @@ g_credentials_new (void) /* ---------------------------------------------------------------------------------------------------- */ -#ifdef G_OS_UNIX -static GCredentials * -g_credentials_new_for_unix_process (void) -{ - GCredentials *credentials; - credentials = g_credentials_new (); - credentials->priv->unix_user = getuid (); - credentials->priv->unix_group = getgid (); - credentials->priv->unix_process = getpid (); - return credentials; -} -#endif - -/* ---------------------------------------------------------------------------------------------------- */ - -/** - * g_credentials_new_for_process: - * - * Gets the credentials for the current process. Note that the exact - * set of credentials in the returned object vary according to - * platform. - * - * Returns: A #GCredentials. Free with g_object_unref(). - * - * Since: 2.26 - */ -GCredentials * -g_credentials_new_for_process (void) -{ -#ifdef G_OS_UNIX - return g_credentials_new_for_unix_process (); -#elif G_OS_WIN32 - return g_credentials_new_for_win32_process (); -#else -#warning Please implement g_credentials_new_for_process() for your OS. For now g_credentials_new_for_process() will return empty credentials. - return g_credentials_new (); -#endif -} - -/* ---------------------------------------------------------------------------------------------------- */ - -/** - * g_credentials_new_for_string: - * @str: A string returned from g_credentials_to_string(). - * @error: Return location for error. - * - * Constructs a #GCredentials instance from @str. - * - * Returns: A #GCredentials or %NULL if @error is set. The return - * object must be freed with g_object_unref(). - * - * Since: 2.26 - */ -GCredentials * -g_credentials_new_for_string (const gchar *str, - GError **error) -{ - GCredentials *credentials; - gchar **tokens; - guint n; - - g_return_val_if_fail (str != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - tokens = NULL; - credentials = g_credentials_new (); - - if (!g_str_has_prefix (str, "GCredentials:")) - goto fail; - - tokens = g_strsplit (str + sizeof "GCredentials:" - 1, ",", 0); - for (n = 0; tokens[n] != NULL; n++) - { - const gchar *token = tokens[n]; - if (g_str_has_prefix (token, "unix-user:")) - g_credentials_set_unix_user (credentials, atoi (token + sizeof ("unix-user:") - 1)); - else if (g_str_has_prefix (token, "unix-group:")) - g_credentials_set_unix_group (credentials, atoi (token + sizeof ("unix-group:") - 1)); - else if (g_str_has_prefix (token, "unix-process:")) - g_credentials_set_unix_process (credentials, atoi (token + sizeof ("unix-process:") - 1)); - else if (g_str_has_prefix (token, "windows-user:")) - g_credentials_set_windows_user (credentials, token + sizeof ("windows-user:")); - else - goto fail; - } - g_strfreev (tokens); - return credentials; - - fail: - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_FAILED, - _("The string `%s' is not a valid credentials string"), - str); - g_object_unref (credentials); - g_strfreev (tokens); - return NULL; -} - /** * g_credentials_to_string: * @credentials: A #GCredentials object. * - * Serializes @credentials to a string that can be used with - * g_credentials_new_for_string(). + * Creates a human-readable textual representation of @credentials + * that can be used in logging and debug messages. The format of the + * returned string may change in future GLib release. * * Returns: A string that should be freed with g_free(). * @@ -229,16 +203,59 @@ g_credentials_to_string (GCredentials *credentials) g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL); ret = g_string_new ("GCredentials:"); - if (credentials->priv->unix_user != -1) - g_string_append_printf (ret, "unix-user=%" G_GINT64_FORMAT ",", credentials->priv->unix_user); - if (credentials->priv->unix_group != -1) - g_string_append_printf (ret, "unix-group=%" G_GINT64_FORMAT ",", credentials->priv->unix_group); - if (credentials->priv->unix_process != -1) - g_string_append_printf (ret, "unix-process=%" G_GINT64_FORMAT ",", credentials->priv->unix_process); - if (credentials->priv->windows_user != NULL) - g_string_append_printf (ret, "windows-user=%s,", credentials->priv->windows_user); +#if G_CREDENTIALS_USE_LINUX_UCRED + g_string_append (ret, "linux-ucred:"); + if (credentials->native.pid != -1) + g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid); + if (credentials->native.uid != -1) + g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid); + if (credentials->native.gid != -1) + 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_FREEBSD_CMSGCRED + 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); +#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) + g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid); + if (credentials->native.uid != -1) + g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid); + if (credentials->native.gid != -1) + 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 return g_string_free (ret, FALSE); } @@ -246,214 +263,316 @@ g_credentials_to_string (GCredentials *credentials) /* ---------------------------------------------------------------------------------------------------- */ /** - * g_credentials_has_unix_user: + * g_credentials_is_same_user: * @credentials: A #GCredentials. + * @other_credentials: A #GCredentials. + * @error: Return location for error or %NULL. + * + * Checks if @credentials and @other_credentials is the same user. * - * Checks if @credentials has a UNIX user credential. + * This operation can fail if #GCredentials is not supported on the + * the OS. * - * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise. + * Returns: %TRUE if @credentials and @other_credentials has the same + * user, %FALSE otherwise or if @error is set. * * Since: 2.26 */ gboolean -g_credentials_has_unix_user (GCredentials *credentials) +g_credentials_is_same_user (GCredentials *credentials, + GCredentials *other_credentials, + GError **error) { + gboolean ret; + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE); - return credentials->priv->unix_user != -1; -} + g_return_val_if_fail (G_IS_CREDENTIALS (other_credentials), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + ret = FALSE; +#if G_CREDENTIALS_USE_LINUX_UCRED + if (credentials->native.uid == other_credentials->native.uid) + ret = TRUE; +#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, + G_IO_ERROR_NOT_SUPPORTED, + _("GCredentials is not implemented on this OS")); +#endif -/** - * g_credentials_get_unix_user: - * @credentials: A #GCredentials. - * - * Gets the UNIX user identifier from @credentials. - * - * Returns: The identifier or -1 if unset. - * - * Since: 2.26 - */ -gint64 -g_credentials_get_unix_user (GCredentials *credentials) -{ - g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1); - return credentials->priv->unix_user; + return ret; } -/** - * g_credentials_set_unix_user: - * @credentials: A #GCredentials. - * @user_id: A UNIX user identifier (typically type #uid_t) or -1 to unset it. - * - * Sets the UNIX user identifier. - * - * Since: 2.26 - */ -void -g_credentials_set_unix_user (GCredentials *credentials, - gint64 user_id) +static gboolean +credentials_native_type_check (GCredentialsType requested_type, + const char *op) { - g_return_if_fail (G_IS_CREDENTIALS (credentials)); - credentials->priv->unix_user = user_id; -} + GEnumClass *enum_class; + GEnumValue *requested; +#if G_CREDENTIALS_SUPPORTED + GEnumValue *supported; +#endif -/* ---------------------------------------------------------------------------------------------------- */ +#if G_CREDENTIALS_SUPPORTED + if (requested_type == G_CREDENTIALS_NATIVE_TYPE) + return TRUE; +#endif -/** - * g_credentials_has_unix_group: - * @credentials: A #GCredentials. - * - * Checks if @credentials has a UNIX group credential. - * - * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise. - * - * Since: 2.26 - */ -gboolean -g_credentials_has_unix_group (GCredentials *credentials) -{ - g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE); - return credentials->priv->unix_group != -1; + enum_class = g_type_class_ref (g_credentials_type_get_type ()); + requested = g_enum_get_value (enum_class, 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, + requested ? requested->value_name : "(unknown)", + supported->value_name); +#else + g_warning ("g_credentials_%s_native: Trying to %s credentials of type %s " + "but there is no support for GCredentials on this platform.", + op, op, + requested ? requested->value_name : "(unknown)"); +#endif + + g_type_class_unref (enum_class); + return FALSE; } /** - * g_credentials_get_unix_group: + * g_credentials_get_native: (skip) * @credentials: A #GCredentials. + * @native_type: The type of native credentials to get. * - * Gets the UNIX group identifier from @credentials. + * Gets a pointer to native credentials of type @native_type from + * @credentials. * - * Returns: The identifier or -1 if unset. + * It is a programming error (which will cause an warning to be + * logged) to use this method if there is no #GCredentials support for + * the OS or if @native_type isn't supported by the OS. + * + * Returns: The pointer to native credentials or %NULL if the + * operation there is no #GCredentials support for the OS or if + * @native_type isn't supported by the OS. Do not free the returned + * data, it is owned by @credentials. * * Since: 2.26 */ -gint64 -g_credentials_get_unix_group (GCredentials *credentials) +gpointer +g_credentials_get_native (GCredentials *credentials, + GCredentialsType native_type) { - g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1); - return credentials->priv->unix_group; + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL); + + if (!credentials_native_type_check (native_type, "get")) + return NULL; + +#if G_CREDENTIALS_USE_SOLARIS_UCRED + return credentials->native; +#elif G_CREDENTIALS_SUPPORTED + return &credentials->native; +#else + g_assert_not_reached (); +#endif } /** - * g_credentials_set_unix_group: + * g_credentials_set_native: * @credentials: A #GCredentials. - * @group_id: A UNIX group identifier (typically type #gid_t) or -1 to unset. + * @native_type: The type of native credentials to set. + * @native: A pointer to native credentials. + * + * Copies the native credentials of type @native_type from @native + * into @credentials. * - * Sets the UNIX group identifier. + * It is a programming error (which will cause an warning to be + * logged) to use this method if there is no #GCredentials support for + * the OS or if @native_type isn't supported by the OS. * * Since: 2.26 */ void -g_credentials_set_unix_group (GCredentials *credentials, - gint64 group_id) +g_credentials_set_native (GCredentials *credentials, + GCredentialsType native_type, + gpointer native) { - g_return_if_fail (G_IS_CREDENTIALS (credentials)); - credentials->priv->unix_group = group_id; + if (!credentials_native_type_check (native_type, "set")) + return; + +#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 (); +#endif } /* ---------------------------------------------------------------------------------------------------- */ +#ifdef G_OS_UNIX /** - * g_credentials_has_unix_process: - * @credentials: A #GCredentials. + * g_credentials_get_unix_user: + * @credentials: A #GCredentials + * @error: Return location for error or %NULL. + * + * Tries to get the UNIX user identifier from @credentials. This + * method is only available on UNIX platforms. * - * Checks if @credentials has a UNIX process credential. + * 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. * - * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise. + * Returns: The UNIX user identifier or -1 if @error is set. * * Since: 2.26 */ -gboolean -g_credentials_has_unix_process (GCredentials *credentials) +uid_t +g_credentials_get_unix_user (GCredentials *credentials, + GError **error) { - g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE); - return credentials->priv->unix_process != -1; + uid_t ret; + + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1); + g_return_val_if_fail (error == NULL || *error == NULL, -1); + +#if G_CREDENTIALS_USE_LINUX_UCRED + 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, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("There is no GCredentials support for your platform")); +#endif + + return ret; } /** - * g_credentials_get_unix_process: - * @credentials: A #GCredentials. + * g_credentials_get_unix_pid: + * @credentials: A #GCredentials + * @error: Return location for error or %NULL. * - * Gets the UNIX process identifier from @credentials. + * Tries to get the UNIX process identifier from @credentials. This + * method is only available on UNIX platforms. * - * Returns: The identifier or -1 if unset. + * 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 process ID. * - * Since: 2.26 + * Returns: The UNIX process ID, or -1 if @error is set. + * + * Since: 2.36 */ -gint64 -g_credentials_get_unix_process (GCredentials *credentials) +pid_t +g_credentials_get_unix_pid (GCredentials *credentials, + GError **error) { + pid_t ret; + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1); - return credentials->priv->unix_process; -} + g_return_val_if_fail (error == NULL || *error == NULL, -1); + +#if G_CREDENTIALS_USE_LINUX_UCRED + 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, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("GCredentials does not contain a process ID on this OS")); +#endif -/** - * g_credentials_set_unix_process: - * @credentials: A #GCredentials. - * @process_id: A UNIX process identifier (typically type #pid_t/#GPid) or -1 to unset. - * - * Sets the UNIX process identifier. - * - * Since: 2.26 - */ -void -g_credentials_set_unix_process (GCredentials *credentials, - gint64 process_id) -{ - g_return_if_fail (G_IS_CREDENTIALS (credentials)); - credentials->priv->unix_process = process_id; + return ret; } -/* ---------------------------------------------------------------------------------------------------- */ - /** - * g_credentials_has_windows_user: + * g_credentials_set_unix_user: * @credentials: A #GCredentials. + * @uid: The UNIX user identifier to set. + * @error: Return location for error or %NULL. + * + * Tries to set the UNIX user identifier on @credentials. This method + * is only available on UNIX platforms. * - * Checks if @credentials has a Windows user SID (Security Identifier). + * 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. It can also fail if the OS does not allow the + * use of "spoofed" credentials. * - * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise. + * Returns: %TRUE if @uid was set, %FALSE if error is set. * * Since: 2.26 */ gboolean -g_credentials_has_windows_user (GCredentials *credentials) +g_credentials_set_unix_user (GCredentials *credentials, + uid_t uid, + GError **error) { - g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE); - return credentials->priv->windows_user != NULL; -} + gboolean ret; -/** - * g_credentials_get_windows_user: - * @credentials: A #GCredentials. - * - * Gets the Windows User SID from @credentials. - * - * Returns: A string or %NULL if unset. Do not free, the string is owned by @credentials. - * - * Since: 2.26 - */ -const gchar * -g_credentials_get_windows_user (GCredentials *credentials) -{ - g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL); - return credentials->priv->windows_user; -} + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE); + g_return_val_if_fail (uid != -1, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + ret = FALSE; +#if G_CREDENTIALS_USE_LINUX_UCRED + credentials->native.uid = uid; + ret = TRUE; +#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 -/** - * g_credentials_set_windows_user: - * @credentials: A #GCredentials. - * @user_sid: The Windows User SID or %NULL to unset. - * - * Sets the Windows User SID. - * - * Since: 2.26 - */ -void -g_credentials_set_windows_user (GCredentials *credentials, - const gchar *user_sid) -{ - g_return_if_fail (G_IS_CREDENTIALS (credentials)); - g_free (credentials->priv->windows_user); - credentials->priv->windows_user = g_strdup (user_sid); + return ret; } -/* ---------------------------------------------------------------------------------------------------- */ +#endif /* G_OS_UNIX */