X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgcredentials.c;h=ccbd143754ce2a873213a8cc2e746518c8385c25;hb=6f7dc3a44f966e69a7495cd5af5017ec02b3938c;hp=a9c2b5a9865719356abf423c1de59fb417b44261;hpb=173977a7015c45e5dc3c43534cd3deb81159ad1f;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gcredentials.c b/gio/gcredentials.c index a9c2b5a..ccbd143 100644 --- a/gio/gcredentials.c +++ b/gio/gcredentials.c @@ -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,12 +21,15 @@ #include "config.h" #include +#include #include #include "gcredentials.h" -#include "gnetworkingprivate.h" +#include "gcredentialsprivate.h" +#include "gnetworking.h" #include "gioerror.h" +#include "gioenumtypes.h" #include "glibintl.h" @@ -50,11 +51,20 @@ * #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 - * unix7 - * 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, 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 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. */ /** @@ -70,12 +80,18 @@ struct _GCredentials /*< private >*/ GObject parent_instance; -#ifdef __linux__ +#if G_CREDENTIALS_USE_LINUX_UCRED struct ucred native; +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + struct cmsgcred 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 + #ifdef __GNUC__ + #warning Please add GCredentials support for your OS + #endif #endif }; @@ -97,7 +113,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); @@ -116,10 +136,21 @@ g_credentials_class_init (GCredentialsClass *klass) static void g_credentials_init (GCredentials *credentials) { -#ifdef __linux__ +#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_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 } @@ -163,7 +194,7 @@ g_credentials_to_string (GCredentials *credentials) g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL); ret = g_string_new ("GCredentials:"); -#ifdef __linux__ +#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); @@ -173,6 +204,37 @@ 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_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_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 @@ -210,9 +272,18 @@ g_credentials_is_same_user (GCredentials *credentials, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); ret = FALSE; -#ifdef __linux__ +#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_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, @@ -223,8 +294,44 @@ g_credentials_is_same_user (GCredentials *credentials, return ret; } +static gboolean +credentials_native_type_check (GCredentialsType requested_type, + const char *op) +{ + 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 + + 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_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_native: + * g_credentials_get_native: (skip) * @credentials: A #GCredentials. * @native_type: The type of native credentials to get. * @@ -246,29 +353,18 @@ gpointer g_credentials_get_native (GCredentials *credentials, GCredentialsType native_type) { - gpointer ret; - g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL); - ret = NULL; - -#ifdef __linux__ - if (native_type != G_CREDENTIALS_TYPE_LINUX_UCRED) - { - g_warning ("g_credentials_get_native: Trying to get credentials of type %d but only " - "G_CREDENTIALS_TYPE_LINUX_UCRED is supported.", - native_type); - } - else - { - ret = &credentials->native; - } + 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_warning ("g_credentials_get_native: Trying to get credentials but GLib has no support " - "for the native credentials type. Please add support."); + g_assert_not_reached (); #endif - - return ret; } /** @@ -291,20 +387,15 @@ g_credentials_set_native (GCredentials *credentials, GCredentialsType native_type, gpointer native) { -#ifdef __linux__ - if (native_type != G_CREDENTIALS_TYPE_LINUX_UCRED) - { - g_warning ("g_credentials_set_native: Trying to set credentials of type %d " - "but only G_CREDENTIALS_TYPE_LINUX_UCRED is supported.", - native_type); - } - else - { - memcpy (&credentials->native, native, sizeof (struct ucred)); - } + 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_warning ("g_credentials_set_native: Trying to set credentials but GLib has no support " - "for the native credentials type. Please add support."); + g_assert_not_reached (); #endif } @@ -336,8 +427,14 @@ g_credentials_get_unix_user (GCredentials *credentials, g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1); g_return_val_if_fail (error == NULL || *error == NULL, -1); -#ifdef __linux__ +#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_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, @@ -350,6 +447,50 @@ g_credentials_get_unix_user (GCredentials *credentials, } /** + * g_credentials_get_unix_pid: + * @credentials: A #GCredentials + * @error: Return location for error or %NULL. + * + * Tries to get the UNIX process identifier from @credentials. This + * method is only available on UNIX platforms. + * + * 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. + * + * Returns: The UNIX process ID, or -1 if @error is set. + * + * Since: 2.36 + */ +pid_t +g_credentials_get_unix_pid (GCredentials *credentials, + GError **error) +{ + pid_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.pid; +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + ret = credentials->native.cmcred_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 + + return ret; +} + +/** * g_credentials_set_unix_user: * @credentials: A #GCredentials. * @uid: The UNIX user identifier to set. @@ -360,7 +501,8 @@ g_credentials_get_unix_user (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. * @@ -378,16 +520,30 @@ g_credentials_set_unix_user (GCredentials *credentials, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); ret = FALSE; -#ifdef __linux__ +#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_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; } + #endif /* G_OS_UNIX */