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 */