X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgcredentials.c;h=6673afddd460611b1051961161351c2ed13c0542;hb=91821974e1e9e71fb5f2c623f68c0c9e2a6a59a9;hp=f54ea24aad152c0418b0bfb3404917272e7f0c9a;hpb=631d0c3534661e549f7df18fbb9832bdf19c5eaf;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gcredentials.c b/gio/gcredentials.c index f54ea24..6673afd 100644 --- a/gio/gcredentials.c +++ b/gio/gcredentials.c @@ -13,27 +13,23 @@ * 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 */ #include "config.h" -#ifdef __FreeBSD__ -#include -#include -#include -#endif #include +#include #include #include "gcredentials.h" -#include "gnetworkingprivate.h" +#include "gcredentialsprivate.h" +#include "gnetworking.h" #include "gioerror.h" +#include "gioenumtypes.h" #include "glibintl.h" @@ -55,14 +51,23 @@ * #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, the native credential type is a struct cmsgcred. - * 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 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. */ /** @@ -78,14 +83,20 @@ struct _GCredentials /*< private >*/ GObject parent_instance; -#ifdef __linux__ +#if G_CREDENTIALS_USE_LINUX_UCRED struct ucred native; -#elif defined(__FreeBSD__) +#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 + #ifdef __GNUC__ + #warning Please add GCredentials support for your OS + #endif #endif }; @@ -107,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); @@ -126,15 +141,25 @@ 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 defined(__FreeBSD__) +#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 } @@ -178,7 +203,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); @@ -188,7 +213,7 @@ 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__) +#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); @@ -196,6 +221,38 @@ 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) + 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 @@ -233,12 +290,21 @@ 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 defined(__FreeBSD__) +#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, @@ -249,6 +315,43 @@ 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_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_native: (skip) * @credentials: A #GCredentials. @@ -272,40 +375,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; - } -#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; - } + 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; } /** @@ -328,31 +409,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)); - } -#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)); - } + 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 } @@ -384,10 +449,16 @@ 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 defined(__FreeBSD__) +#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, @@ -400,6 +471,52 @@ 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_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 + + return ret; +} + +/** * g_credentials_set_unix_user: * @credentials: A #GCredentials. * @uid: The UNIX user identifier to set. @@ -410,7 +527,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. * @@ -428,19 +546,33 @@ 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 defined(__FreeBSD__) +#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; } + #endif /* G_OS_UNIX */