1 /* GDBus - GLib D-Bus Library
3 * Copyright (C) 2008-2010 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: David Zeuthen <davidz@redhat.com>
26 #include <sys/types.h>
27 #include <sys/socket.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
37 #include <gobject/gvaluecollector.h>
39 #include "gcredentials.h"
40 #include "gnetworkingprivate.h"
46 * SECTION:gcredentials
47 * @short_description: An object containing credentials
50 * The #GCredentials type is a reference-counted wrapper for native
51 * credentials. This information is typically used for identifying,
52 * authenticating and authorizing other processes.
54 * Some operating systems supports looking up the credentials of the
55 * remote peer of a communication endpoint - see e.g.
56 * g_socket_get_credentials().
58 * Some operating systems supports securely sending and receiving
59 * credentials over a Unix Domain Socket, see
60 * #GUnixCredentialsMessage, g_unix_connection_send_credentials() and
61 * g_unix_connection_receive_credentials() for details.
63 * On Linux, the native credential type is a <type>struct ucred</type>
65 * <citerefentry><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry>
66 * man page for details. This corresponds to
67 * %G_CREDENTIALS_TYPE_LINUX_UCRED.
69 * On FreeBSD, the native credential type is a <type>struct cmsgcred</type>.
70 * This corresponds to %G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED.
72 * On OpenBSD, the native credential type is a <type>struct sockpeercred</type>.
73 * This corresponds to %G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED.
79 * The #GCredentials structure contains only private data and
80 * should only be accessed using the provided API.
87 GObject parent_instance;
91 #elif defined(__FreeBSD__)
92 struct cmsgcred native;
93 #elif defined(__OpenBSD__)
94 struct sockpeercred native;
97 #warning Please add GCredentials support for your OS
105 * Class structure for #GCredentials.
109 struct _GCredentialsClass
112 GObjectClass parent_class;
115 G_DEFINE_TYPE (GCredentials, g_credentials, G_TYPE_OBJECT);
118 g_credentials_finalize (GObject *object)
120 G_GNUC_UNUSED GCredentials *credentials = G_CREDENTIALS (object);
122 if (G_OBJECT_CLASS (g_credentials_parent_class)->finalize != NULL)
123 G_OBJECT_CLASS (g_credentials_parent_class)->finalize (object);
128 g_credentials_class_init (GCredentialsClass *klass)
130 GObjectClass *gobject_class;
132 gobject_class = G_OBJECT_CLASS (klass);
133 gobject_class->finalize = g_credentials_finalize;
137 g_credentials_init (GCredentials *credentials)
140 credentials->native.pid = getpid ();
141 credentials->native.uid = geteuid ();
142 credentials->native.gid = getegid ();
143 #elif defined(__FreeBSD__)
144 memset (&credentials->native, 0, sizeof (struct cmsgcred));
145 credentials->native.cmcred_pid = getpid ();
146 credentials->native.cmcred_euid = geteuid ();
147 credentials->native.cmcred_gid = getegid ();
148 #elif defined(__OpenBSD__)
149 credentials->native.pid = getpid ();
150 credentials->native.uid = geteuid ();
151 credentials->native.gid = getegid ();
155 /* ---------------------------------------------------------------------------------------------------- */
160 * Creates a new #GCredentials object with credentials matching the
161 * the current process.
163 * Returns: A #GCredentials. Free with g_object_unref().
168 g_credentials_new (void)
170 return g_object_new (G_TYPE_CREDENTIALS, NULL);
173 /* ---------------------------------------------------------------------------------------------------- */
176 * g_credentials_to_string:
177 * @credentials: A #GCredentials object.
179 * Creates a human-readable textual representation of @credentials
180 * that can be used in logging and debug messages. The format of the
181 * returned string may change in future GLib release.
183 * Returns: A string that should be freed with g_free().
188 g_credentials_to_string (GCredentials *credentials)
192 g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
194 ret = g_string_new ("GCredentials:");
196 g_string_append (ret, "linux-ucred:");
197 if (credentials->native.pid != -1)
198 g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid);
199 if (credentials->native.uid != -1)
200 g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid);
201 if (credentials->native.gid != -1)
202 g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
203 if (ret->str[ret->len - 1] == ',')
204 ret->str[ret->len - 1] = '\0';
205 #elif defined(__FreeBSD__)
206 g_string_append (ret, "freebsd-cmsgcred:");
207 if (credentials->native.cmcred_pid != -1)
208 g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_pid);
209 if (credentials->native.cmcred_euid != -1)
210 g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_euid);
211 if (credentials->native.cmcred_gid != -1)
212 g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_gid);
213 #elif defined(__OpenBSD__)
214 g_string_append (ret, "openbsd-sockpeercred:");
215 if (credentials->native.pid != -1)
216 g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid);
217 if (credentials->native.uid != -1)
218 g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid);
219 if (credentials->native.gid != -1)
220 g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
221 if (ret->str[ret->len - 1] == ',')
222 ret->str[ret->len - 1] = '\0';
224 g_string_append (ret, "unknown");
227 return g_string_free (ret, FALSE);
230 /* ---------------------------------------------------------------------------------------------------- */
233 * g_credentials_is_same_user:
234 * @credentials: A #GCredentials.
235 * @other_credentials: A #GCredentials.
236 * @error: Return location for error or %NULL.
238 * Checks if @credentials and @other_credentials is the same user.
240 * This operation can fail if #GCredentials is not supported on the
243 * Returns: %TRUE if @credentials and @other_credentials has the same
244 * user, %FALSE otherwise or if @error is set.
249 g_credentials_is_same_user (GCredentials *credentials,
250 GCredentials *other_credentials,
255 g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
256 g_return_val_if_fail (G_IS_CREDENTIALS (other_credentials), FALSE);
257 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
261 if (credentials->native.uid == other_credentials->native.uid)
263 #elif defined(__FreeBSD__)
264 if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
266 #elif defined(__OpenBSD__)
267 if (credentials->native.uid == other_credentials->native.uid)
270 g_set_error_literal (error,
272 G_IO_ERROR_NOT_SUPPORTED,
273 _("GCredentials is not implemented on this OS"));
280 * g_credentials_get_native: (skip)
281 * @credentials: A #GCredentials.
282 * @native_type: The type of native credentials to get.
284 * Gets a pointer to native credentials of type @native_type from
287 * It is a programming error (which will cause an warning to be
288 * logged) to use this method if there is no #GCredentials support for
289 * the OS or if @native_type isn't supported by the OS.
291 * Returns: The pointer to native credentials or %NULL if the
292 * operation there is no #GCredentials support for the OS or if
293 * @native_type isn't supported by the OS. Do not free the returned
294 * data, it is owned by @credentials.
299 g_credentials_get_native (GCredentials *credentials,
300 GCredentialsType native_type)
304 g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
309 if (native_type != G_CREDENTIALS_TYPE_LINUX_UCRED)
311 g_warning ("g_credentials_get_native: Trying to get credentials of type %d but only "
312 "G_CREDENTIALS_TYPE_LINUX_UCRED is supported.",
317 ret = &credentials->native;
319 #elif defined(__FreeBSD__)
320 if (native_type != G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED)
322 g_warning ("g_credentials_get_native: Trying to get credentials of type %d but only "
323 "G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED is supported.",
328 ret = &credentials->native;
330 #elif defined(__OpenBSD__)
331 if (native_type != G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED)
333 g_warning ("g_credentials_get_native: Trying to get credentials of type %d but only "
334 "G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED is supported.",
339 ret = &credentials->native;
342 g_warning ("g_credentials_get_native: Trying to get credentials but GLib has no support "
343 "for the native credentials type. Please add support.");
350 * g_credentials_set_native:
351 * @credentials: A #GCredentials.
352 * @native_type: The type of native credentials to set.
353 * @native: A pointer to native credentials.
355 * Copies the native credentials of type @native_type from @native
358 * It is a programming error (which will cause an warning to be
359 * logged) to use this method if there is no #GCredentials support for
360 * the OS or if @native_type isn't supported by the OS.
365 g_credentials_set_native (GCredentials *credentials,
366 GCredentialsType native_type,
370 if (native_type != G_CREDENTIALS_TYPE_LINUX_UCRED)
372 g_warning ("g_credentials_set_native: Trying to set credentials of type %d "
373 "but only G_CREDENTIALS_TYPE_LINUX_UCRED is supported.",
378 memcpy (&credentials->native, native, sizeof (struct ucred));
380 #elif defined(__FreeBSD__)
381 if (native_type != G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED)
383 g_warning ("g_credentials_set_native: Trying to set credentials of type %d "
384 "but only G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED is supported.",
389 memcpy (&credentials->native, native, sizeof (struct cmsgcred));
391 #elif defined(__OpenBSD__)
392 if (native_type != G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED)
394 g_warning ("g_credentials_set_native: Trying to set credentials of type %d "
395 "but only G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED is supported.",
400 memcpy (&credentials->native, native, sizeof (struct sockpeercred));
403 g_warning ("g_credentials_set_native: Trying to set credentials but GLib has no support "
404 "for the native credentials type. Please add support.");
408 /* ---------------------------------------------------------------------------------------------------- */
412 * g_credentials_get_unix_user:
413 * @credentials: A #GCredentials
414 * @error: Return location for error or %NULL.
416 * Tries to get the UNIX user identifier from @credentials. This
417 * method is only available on UNIX platforms.
419 * This operation can fail if #GCredentials is not supported on the
420 * OS or if the native credentials type does not contain information
421 * about the UNIX user.
423 * Returns: The UNIX user identifier or -1 if @error is set.
428 g_credentials_get_unix_user (GCredentials *credentials,
433 g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
434 g_return_val_if_fail (error == NULL || *error == NULL, -1);
437 ret = credentials->native.uid;
438 #elif defined(__FreeBSD__)
439 ret = credentials->native.cmcred_euid;
440 #elif defined(__OpenBSD__)
441 ret = credentials->native.uid;
444 g_set_error_literal (error,
446 G_IO_ERROR_NOT_SUPPORTED,
447 _("There is no GCredentials support for your platform"));
454 * g_credentials_set_unix_user:
455 * @credentials: A #GCredentials.
456 * @uid: The UNIX user identifier to set.
457 * @error: Return location for error or %NULL.
459 * Tries to set the UNIX user identifier on @credentials. This method
460 * is only available on UNIX platforms.
462 * This operation can fail if #GCredentials is not supported on the
463 * OS or if the native credentials type does not contain information
464 * about the UNIX user.
466 * Returns: %TRUE if @uid was set, %FALSE if error is set.
471 g_credentials_set_unix_user (GCredentials *credentials,
477 g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
478 g_return_val_if_fail (uid != -1, FALSE);
479 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
483 credentials->native.uid = uid;
485 #elif defined(__FreeBSD__)
486 credentials->native.cmcred_euid = uid;
488 #elif defined(__OpenBSD__)
489 credentials->native.uid = uid;
492 g_set_error_literal (error,
494 G_IO_ERROR_NOT_SUPPORTED,
495 _("GCredentials is not implemented on this OS"));
500 #endif /* G_OS_UNIX */