Visual C++ projects: Clean/fix up
[glib.git] / gio / gcredentials.c
blob3a98333e189eb04586e5fe1fc674e85e0f47ad4e
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>
23 #include "config.h"
25 #ifdef __FreeBSD__
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <string.h>
29 #endif
30 #ifdef __OpenBSD__
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <string.h>
34 #endif
35 #include <stdlib.h>
37 #include <gobject/gvaluecollector.h>
39 #include "gcredentials.h"
40 #include "gnetworkingprivate.h"
41 #include "gioerror.h"
43 #include "glibintl.h"
45 /**
46 * SECTION:gcredentials
47 * @short_description: An object containing credentials
48 * @include: gio/gio.h
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>
64 * - see the
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.
76 /**
77 * GCredentials:
79 * The #GCredentials structure contains only private data and
80 * should only be accessed using the provided API.
82 * Since: 2.26
84 struct _GCredentials
86 /*< private >*/
87 GObject parent_instance;
89 #ifdef __linux__
90 struct ucred native;
91 #elif defined(__FreeBSD__)
92 struct cmsgcred native;
93 #elif defined(__OpenBSD__)
94 struct sockpeercred native;
95 #else
96 #ifdef __GNUC__
97 #warning Please add GCredentials support for your OS
98 #endif
99 #endif
103 * GCredentialsClass:
105 * Class structure for #GCredentials.
107 * Since: 2.26
109 struct _GCredentialsClass
111 /*< private >*/
112 GObjectClass parent_class;
115 G_DEFINE_TYPE (GCredentials, g_credentials, G_TYPE_OBJECT);
117 static void
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);
127 static void
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;
136 static void
137 g_credentials_init (GCredentials *credentials)
139 #ifdef __linux__
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 ();
152 #endif
155 /* ---------------------------------------------------------------------------------------------------- */
158 * g_credentials_new:
160 * Creates a new #GCredentials object with credentials matching the
161 * the current process.
163 * Returns: A #GCredentials. Free with g_object_unref().
165 * Since: 2.26
167 GCredentials *
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().
185 * Since: 2.26
187 gchar *
188 g_credentials_to_string (GCredentials *credentials)
190 GString *ret;
192 g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
194 ret = g_string_new ("GCredentials:");
195 #ifdef __linux__
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';
223 #else
224 g_string_append (ret, "unknown");
225 #endif
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
241 * the OS.
243 * Returns: %TRUE if @credentials and @other_credentials has the same
244 * user, %FALSE otherwise or if @error is set.
246 * Since: 2.26
248 gboolean
249 g_credentials_is_same_user (GCredentials *credentials,
250 GCredentials *other_credentials,
251 GError **error)
253 gboolean ret;
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);
259 ret = FALSE;
260 #ifdef __linux__
261 if (credentials->native.uid == other_credentials->native.uid)
262 ret = TRUE;
263 #elif defined(__FreeBSD__)
264 if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
265 ret = TRUE;
266 #elif defined(__OpenBSD__)
267 if (credentials->native.uid == other_credentials->native.uid)
268 ret = TRUE;
269 #else
270 g_set_error_literal (error,
271 G_IO_ERROR,
272 G_IO_ERROR_NOT_SUPPORTED,
273 _("GCredentials is not implemented on this OS"));
274 #endif
276 return ret;
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
285 * @credentials.
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.
296 * Since: 2.26
298 gpointer
299 g_credentials_get_native (GCredentials *credentials,
300 GCredentialsType native_type)
302 gpointer ret;
304 g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
306 ret = NULL;
308 #ifdef __linux__
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.",
313 native_type);
315 else
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.",
324 native_type);
326 else
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.",
335 native_type);
337 else
339 ret = &credentials->native;
341 #else
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.");
344 #endif
346 return ret;
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
356 * into @credentials.
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.
362 * Since: 2.26
364 void
365 g_credentials_set_native (GCredentials *credentials,
366 GCredentialsType native_type,
367 gpointer native)
369 #ifdef __linux__
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.",
374 native_type);
376 else
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.",
385 native_type);
387 else
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.",
396 native_type);
398 else
400 memcpy (&credentials->native, native, sizeof (struct sockpeercred));
402 #else
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.");
405 #endif
408 /* ---------------------------------------------------------------------------------------------------- */
410 #ifdef G_OS_UNIX
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.
425 * Since: 2.26
427 uid_t
428 g_credentials_get_unix_user (GCredentials *credentials,
429 GError **error)
431 uid_t ret;
433 g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
434 g_return_val_if_fail (error == NULL || *error == NULL, -1);
436 #ifdef __linux__
437 ret = credentials->native.uid;
438 #elif defined(__FreeBSD__)
439 ret = credentials->native.cmcred_euid;
440 #elif defined(__OpenBSD__)
441 ret = credentials->native.uid;
442 #else
443 ret = -1;
444 g_set_error_literal (error,
445 G_IO_ERROR,
446 G_IO_ERROR_NOT_SUPPORTED,
447 _("There is no GCredentials support for your platform"));
448 #endif
450 return ret;
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.
468 * Since: 2.26
470 gboolean
471 g_credentials_set_unix_user (GCredentials *credentials,
472 uid_t uid,
473 GError **error)
475 gboolean ret;
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);
481 ret = FALSE;
482 #ifdef __linux__
483 credentials->native.uid = uid;
484 ret = TRUE;
485 #elif defined(__FreeBSD__)
486 credentials->native.cmcred_euid = uid;
487 ret = TRUE;
488 #elif defined(__OpenBSD__)
489 credentials->native.uid = uid;
490 ret = TRUE;
491 #else
492 g_set_error_literal (error,
493 G_IO_ERROR,
494 G_IO_ERROR_NOT_SUPPORTED,
495 _("GCredentials is not implemented on this OS"));
496 #endif
498 return ret;
500 #endif /* G_OS_UNIX */