Coverage Report

Created: 2025-06-13 06:55

/src/glib/gio/gcredentials.c
Line
Count
Source (jump to first uncovered line)
1
/* GDBus - GLib D-Bus Library
2
 *
3
 * Copyright (C) 2008-2010 Red Hat, Inc.
4
 *
5
 * SPDX-License-Identifier: LGPL-2.1-or-later
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General
18
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19
 *
20
 * Author: David Zeuthen <davidz@redhat.com>
21
 */
22
23
#include "config.h"
24
25
#include <stdlib.h>
26
#include <string.h>
27
28
#include <gobject/gvaluecollector.h>
29
30
#include "gcredentials.h"
31
#include "gcredentialsprivate.h"
32
#include "gnetworking.h"
33
#include "gioerror.h"
34
#include "gioenumtypes.h"
35
36
#include "glibintl.h"
37
38
/**
39
 * SECTION:gcredentials
40
 * @short_description: An object containing credentials
41
 * @include: gio/gio.h
42
 *
43
 * The #GCredentials type is a reference-counted wrapper for native
44
 * credentials. This information is typically used for identifying,
45
 * authenticating and authorizing other processes.
46
 *
47
 * Some operating systems supports looking up the credentials of the
48
 * remote peer of a communication endpoint - see e.g.
49
 * g_socket_get_credentials().
50
 *
51
 * Some operating systems supports securely sending and receiving
52
 * credentials over a Unix Domain Socket, see
53
 * #GUnixCredentialsMessage, g_unix_connection_send_credentials() and
54
 * g_unix_connection_receive_credentials() for details.
55
 *
56
 * On Linux, the native credential type is a `struct ucred` - see the
57
 * unix(7) man page for details. This corresponds to
58
 * %G_CREDENTIALS_TYPE_LINUX_UCRED.
59
 *
60
 * On Apple operating systems (including iOS, tvOS, and macOS),
61
 * the native credential type is a `struct xucred`.
62
 * This corresponds to %G_CREDENTIALS_TYPE_APPLE_XUCRED.
63
 *
64
 * On FreeBSD, Debian GNU/kFreeBSD, and GNU/Hurd, the native
65
 * credential type is a `struct cmsgcred`. This corresponds
66
 * to %G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED.
67
 *
68
 * On NetBSD, the native credential type is a `struct unpcbid`.
69
 * This corresponds to %G_CREDENTIALS_TYPE_NETBSD_UNPCBID.
70
 *
71
 * On OpenBSD, the native credential type is a `struct sockpeercred`.
72
 * This corresponds to %G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED.
73
 *
74
 * On Solaris (including OpenSolaris and its derivatives), the native
75
 * credential type is a `ucred_t`. This corresponds to
76
 * %G_CREDENTIALS_TYPE_SOLARIS_UCRED.
77
 *
78
 * Since GLib 2.72, on Windows, the native credentials may contain the PID of a
79
 * process. This corresponds to %G_CREDENTIALS_TYPE_WIN32_PID.
80
 */
81
82
/**
83
 * GCredentials:
84
 *
85
 * The #GCredentials structure contains only private data and
86
 * should only be accessed using the provided API.
87
 *
88
 * Since: 2.26
89
 */
90
struct _GCredentials
91
{
92
  /*< private >*/
93
  GObject parent_instance;
94
95
#if G_CREDENTIALS_USE_LINUX_UCRED
96
  struct ucred native;
97
#elif G_CREDENTIALS_USE_APPLE_XUCRED
98
  struct xucred native;
99
  pid_t pid;
100
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
101
  struct cmsgcred native;
102
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
103
  struct unpcbid native;
104
#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
105
  struct sockpeercred native;
106
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
107
  ucred_t *native;
108
#elif G_CREDENTIALS_USE_WIN32_PID
109
  DWORD native;
110
#else
111
  #ifdef __GNUC__
112
  #pragma GCC diagnostic push
113
  #pragma GCC diagnostic warning "-Wcpp"
114
  #warning Please add GCredentials support for your OS
115
  #pragma GCC diagnostic pop
116
  #endif
117
#endif
118
};
119
120
/**
121
 * GCredentialsClass:
122
 *
123
 * Class structure for #GCredentials.
124
 *
125
 * Since: 2.26
126
 */
127
struct _GCredentialsClass
128
{
129
  /*< private >*/
130
  GObjectClass parent_class;
131
};
132
133
G_DEFINE_TYPE (GCredentials, g_credentials, G_TYPE_OBJECT)
134
135
static void
136
g_credentials_finalize (GObject *object)
137
0
{
138
#if G_CREDENTIALS_USE_SOLARIS_UCRED
139
  GCredentials *credentials = G_CREDENTIALS (object);
140
141
  ucred_free (credentials->native);
142
#endif
143
144
0
  if (G_OBJECT_CLASS (g_credentials_parent_class)->finalize != NULL)
145
0
    G_OBJECT_CLASS (g_credentials_parent_class)->finalize (object);
146
0
}
147
148
149
static void
150
g_credentials_class_init (GCredentialsClass *klass)
151
0
{
152
0
  GObjectClass *gobject_class;
153
154
0
  gobject_class = G_OBJECT_CLASS (klass);
155
0
  gobject_class->finalize = g_credentials_finalize;
156
0
}
157
158
static void
159
g_credentials_init (GCredentials *credentials)
160
0
{
161
0
#if G_CREDENTIALS_USE_LINUX_UCRED
162
0
  credentials->native.pid = getpid ();
163
0
  credentials->native.uid = geteuid ();
164
0
  credentials->native.gid = getegid ();
165
#elif G_CREDENTIALS_USE_APPLE_XUCRED
166
  gsize i;
167
168
  credentials->native.cr_version = XUCRED_VERSION;
169
  credentials->native.cr_uid = geteuid ();
170
  credentials->native.cr_ngroups = 1;
171
  credentials->native.cr_groups[0] = getegid ();
172
173
  /* FIXME: In principle this could use getgroups() to fill in the rest
174
   * of cr_groups, but then we'd have to handle the case where a process
175
   * can have more than NGROUPS groups, if that's even possible. A macOS
176
   * user would have to develop and test this.
177
   *
178
   * For now we fill it with -1 (meaning "no data"). */
179
  for (i = 1; i < NGROUPS; i++)
180
    credentials->native.cr_groups[i] = -1;
181
182
  credentials->pid = -1;
183
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
184
  memset (&credentials->native, 0, sizeof (struct cmsgcred));
185
  credentials->native.cmcred_pid  = getpid ();
186
  credentials->native.cmcred_euid = geteuid ();
187
  credentials->native.cmcred_gid  = getegid ();
188
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
189
  credentials->native.unp_pid = getpid ();
190
  credentials->native.unp_euid = geteuid ();
191
  credentials->native.unp_egid = getegid ();
192
#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
193
  credentials->native.pid = getpid ();
194
  credentials->native.uid = geteuid ();
195
  credentials->native.gid = getegid ();
196
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
197
  credentials->native = ucred_get (P_MYID);
198
#elif G_CREDENTIALS_USE_WIN32_PID
199
  credentials->native = GetCurrentProcessId ();
200
#endif
201
0
}
202
203
/* ---------------------------------------------------------------------------------------------------- */
204
205
/**
206
 * g_credentials_new:
207
 *
208
 * Creates a new #GCredentials object with credentials matching the
209
 * the current process.
210
 *
211
 * Returns: (transfer full): A #GCredentials. Free with g_object_unref().
212
 *
213
 * Since: 2.26
214
 */
215
GCredentials *
216
g_credentials_new (void)
217
0
{
218
0
  return g_object_new (G_TYPE_CREDENTIALS, NULL);
219
0
}
220
221
/* ---------------------------------------------------------------------------------------------------- */
222
223
/**
224
 * g_credentials_to_string:
225
 * @credentials: A #GCredentials object.
226
 *
227
 * Creates a human-readable textual representation of @credentials
228
 * that can be used in logging and debug messages. The format of the
229
 * returned string may change in future GLib release.
230
 *
231
 * Returns: (transfer full): A string that should be freed with g_free().
232
 *
233
 * Since: 2.26
234
 */
235
gchar *
236
g_credentials_to_string (GCredentials *credentials)
237
0
{
238
0
  GString *ret;
239
#if G_CREDENTIALS_USE_APPLE_XUCRED
240
  glib_typeof (credentials->native.cr_ngroups) i;
241
#endif
242
243
0
  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
244
245
0
  ret = g_string_new ("GCredentials:");
246
0
#if G_CREDENTIALS_USE_LINUX_UCRED
247
0
  g_string_append (ret, "linux-ucred:");
248
0
  if (credentials->native.pid != (pid_t) -1)
249
0
    g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid);
250
0
  if (credentials->native.uid != (uid_t) -1)
251
0
    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid);
252
0
  if (credentials->native.gid != (gid_t) -1)
253
0
    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
254
0
  if (ret->str[ret->len - 1] == ',')
255
0
    ret->str[ret->len - 1] = '\0';
256
#elif G_CREDENTIALS_USE_APPLE_XUCRED
257
  g_string_append (ret, "apple-xucred:");
258
  g_string_append_printf (ret, "version=%u,", credentials->native.cr_version);
259
  if (credentials->native.cr_uid != (uid_t) -1)
260
    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cr_uid);
261
  for (i = 0; i < credentials->native.cr_ngroups; i++)
262
    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cr_groups[i]);
263
  if (ret->str[ret->len - 1] == ',')
264
    ret->str[ret->len - 1] = '\0';
265
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
266
  g_string_append (ret, "freebsd-cmsgcred:");
267
  if (credentials->native.cmcred_pid != (pid_t) -1)
268
    g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_pid);
269
  if (credentials->native.cmcred_euid != (uid_t) -1)
270
    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_euid);
271
  if (credentials->native.cmcred_gid != (gid_t) -1)
272
    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_gid);
273
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
274
  g_string_append (ret, "netbsd-unpcbid:");
275
  if (credentials->native.unp_pid != (pid_t) -1)
276
    g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_pid);
277
  if (credentials->native.unp_euid != (uid_t) -1)
278
    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_euid);
279
  if (credentials->native.unp_egid != (gid_t) -1)
280
    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_egid);
281
  ret->str[ret->len - 1] = '\0';
282
#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
283
  g_string_append (ret, "openbsd-sockpeercred:");
284
  if (credentials->native.pid != (pid_t) -1)
285
    g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid);
286
  if (credentials->native.uid != (uid_t) -1)
287
    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid);
288
  if (credentials->native.gid != (gid_t) -1)
289
    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
290
  if (ret->str[ret->len - 1] == ',')
291
    ret->str[ret->len - 1] = '\0';
292
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
293
  g_string_append (ret, "solaris-ucred:");
294
  {
295
    id_t id;
296
    if ((id = ucred_getpid (credentials->native)) != (id_t) -1)
297
      g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) id);
298
    if ((id = ucred_geteuid (credentials->native)) != (id_t) -1)
299
      g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) id);
300
    if ((id = ucred_getegid (credentials->native)) != (id_t) -1)
301
      g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) id);
302
    if (ret->str[ret->len - 1] == ',')
303
      ret->str[ret->len - 1] = '\0';
304
  }
305
#elif G_CREDENTIALS_USE_WIN32_PID
306
  g_string_append_printf (ret, "win32-pid:pid=%lu", credentials->native);
307
#else
308
  g_string_append (ret, "unknown");
309
#endif
310
311
0
  return g_string_free (ret, FALSE);
312
0
}
313
314
/* ---------------------------------------------------------------------------------------------------- */
315
316
#if G_CREDENTIALS_USE_LINUX_UCRED
317
/*
318
 * Check whether @native contains invalid data. If getsockopt SO_PEERCRED
319
 * is used on a TCP socket, it succeeds but yields a credentials structure
320
 * with pid 0, uid -1 and gid -1. Similarly, if SO_PASSCRED is used on a
321
 * receiving Unix socket when the sending socket did not also enable
322
 * SO_PASSCRED, it can succeed but yield a credentials structure with
323
 * pid 0, uid /proc/sys/kernel/overflowuid and gid
324
 * /proc/sys/kernel/overflowgid.
325
 */
326
static gboolean
327
linux_ucred_check_valid (struct ucred  *native,
328
                         GError       **error)
329
0
{
330
0
  if (native->pid == 0
331
0
      || native->uid == (uid_t) -1
332
0
      || native->gid == (gid_t) -1)
333
0
    {
334
0
      g_set_error_literal (error,
335
0
                           G_IO_ERROR,
336
0
                           G_IO_ERROR_INVALID_DATA,
337
0
                           _("GCredentials contains invalid data"));
338
0
      return FALSE;
339
0
    }
340
341
0
  return TRUE;
342
0
}
343
#endif
344
345
/**
346
 * g_credentials_is_same_user:
347
 * @credentials: A #GCredentials.
348
 * @other_credentials: A #GCredentials.
349
 * @error: Return location for error or %NULL.
350
 *
351
 * Checks if @credentials and @other_credentials is the same user.
352
 *
353
 * This operation can fail if #GCredentials is not supported on the
354
 * the OS.
355
 *
356
 * Returns: %TRUE if @credentials and @other_credentials has the same
357
 * user, %FALSE otherwise or if @error is set.
358
 *
359
 * Since: 2.26
360
 */
361
gboolean
362
g_credentials_is_same_user (GCredentials  *credentials,
363
                            GCredentials  *other_credentials,
364
                            GError       **error)
365
0
{
366
0
  gboolean ret;
367
368
0
  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
369
0
  g_return_val_if_fail (G_IS_CREDENTIALS (other_credentials), FALSE);
370
0
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
371
372
0
  ret = FALSE;
373
0
#if G_CREDENTIALS_USE_LINUX_UCRED
374
0
  if (linux_ucred_check_valid (&credentials->native, NULL)
375
0
      && credentials->native.uid == other_credentials->native.uid)
376
0
    ret = TRUE;
377
#elif G_CREDENTIALS_USE_APPLE_XUCRED
378
  if (credentials->native.cr_version == other_credentials->native.cr_version &&
379
      credentials->native.cr_uid == other_credentials->native.cr_uid)
380
    ret = TRUE;
381
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
382
  if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
383
    ret = TRUE;
384
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
385
  if (credentials->native.unp_euid == other_credentials->native.unp_euid)
386
    ret = TRUE;
387
#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
388
  if (credentials->native.uid == other_credentials->native.uid)
389
    ret = TRUE;
390
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
391
  if (ucred_geteuid (credentials->native) == ucred_geteuid (other_credentials->native))
392
    ret = TRUE;
393
#else
394
  g_set_error_literal (error,
395
                       G_IO_ERROR,
396
                       G_IO_ERROR_NOT_SUPPORTED,
397
                       _("GCredentials is not implemented on this OS"));
398
#endif
399
400
0
  return ret;
401
0
}
402
403
static gboolean
404
credentials_native_type_check (GCredentialsType  requested_type,
405
                               const char       *op)
406
0
{
407
0
  GEnumClass *enum_class;
408
0
  GEnumValue *requested;
409
0
#if G_CREDENTIALS_SUPPORTED
410
0
  GEnumValue *supported;
411
0
#endif
412
413
0
#if G_CREDENTIALS_SUPPORTED
414
0
  if (requested_type == G_CREDENTIALS_NATIVE_TYPE)
415
0
    return TRUE;
416
0
#endif
417
418
0
  enum_class = g_type_class_ref (g_credentials_type_get_type ());
419
0
  requested = g_enum_get_value (enum_class, requested_type);
420
421
0
#if G_CREDENTIALS_SUPPORTED
422
0
  supported = g_enum_get_value (enum_class, G_CREDENTIALS_NATIVE_TYPE);
423
0
  g_assert (supported);
424
0
  g_warning ("g_credentials_%s_native: Trying to %s credentials of type %s "
425
0
             "but only %s is supported on this platform.",
426
0
             op, op,
427
0
             requested ? requested->value_name : "(unknown)",
428
0
             supported->value_name);
429
#else
430
  g_warning ("g_credentials_%s_native: Trying to %s credentials of type %s "
431
             "but there is no support for GCredentials on this platform.",
432
             op, op,
433
             requested ? requested->value_name : "(unknown)");
434
#endif
435
436
0
  g_type_class_unref (enum_class);
437
0
  return FALSE;
438
0
}
439
440
/**
441
 * g_credentials_get_native: (skip)
442
 * @credentials: A #GCredentials.
443
 * @native_type: The type of native credentials to get.
444
 *
445
 * Gets a pointer to native credentials of type @native_type from
446
 * @credentials.
447
 *
448
 * It is a programming error (which will cause a warning to be
449
 * logged) to use this method if there is no #GCredentials support for
450
 * the OS or if @native_type isn't supported by the OS.
451
 *
452
 * Returns: (transfer none) (nullable): The pointer to native credentials or
453
 *     %NULL if there is no #GCredentials support for the OS or if @native_type
454
 *     isn't supported by the OS. Do not free the returned data, it is owned
455
 *     by @credentials.
456
 *
457
 * Since: 2.26
458
 */
459
gpointer
460
g_credentials_get_native (GCredentials     *credentials,
461
                          GCredentialsType  native_type)
462
0
{
463
0
  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
464
465
0
  if (!credentials_native_type_check (native_type, "get"))
466
0
    return NULL;
467
468
#if G_CREDENTIALS_USE_SOLARIS_UCRED
469
  return credentials->native;
470
#elif G_CREDENTIALS_SUPPORTED
471
0
  return &credentials->native;
472
#else
473
  g_assert_not_reached ();
474
#endif
475
0
}
476
477
/**
478
 * g_credentials_set_native:
479
 * @credentials: A #GCredentials.
480
 * @native_type: The type of native credentials to set.
481
 * @native: (not nullable): A pointer to native credentials.
482
 *
483
 * Copies the native credentials of type @native_type from @native
484
 * into @credentials.
485
 *
486
 * It is a programming error (which will cause a warning to be
487
 * logged) to use this method if there is no #GCredentials support for
488
 * the OS or if @native_type isn't supported by the OS.
489
 *
490
 * Since: 2.26
491
 */
492
void
493
g_credentials_set_native (GCredentials     *credentials,
494
                          GCredentialsType  native_type,
495
                          gpointer          native)
496
0
{
497
0
  if (!credentials_native_type_check (native_type, "set"))
498
0
    return;
499
500
#if G_CREDENTIALS_USE_SOLARIS_UCRED
501
  memcpy (credentials->native, native, ucred_size ());
502
#elif G_CREDENTIALS_SUPPORTED
503
0
  memcpy (&credentials->native, native, sizeof (credentials->native));
504
#else
505
  g_assert_not_reached ();
506
#endif
507
0
}
508
509
/* ---------------------------------------------------------------------------------------------------- */
510
511
#ifdef G_OS_UNIX
512
/**
513
 * g_credentials_get_unix_user:
514
 * @credentials: A #GCredentials
515
 * @error: Return location for error or %NULL.
516
 *
517
 * Tries to get the UNIX user identifier from @credentials. This
518
 * method is only available on UNIX platforms.
519
 *
520
 * This operation can fail if #GCredentials is not supported on the
521
 * OS or if the native credentials type does not contain information
522
 * about the UNIX user.
523
 *
524
 * Returns: The UNIX user identifier or `-1` if @error is set.
525
 *
526
 * Since: 2.26
527
 */
528
uid_t
529
g_credentials_get_unix_user (GCredentials    *credentials,
530
                             GError         **error)
531
0
{
532
0
  uid_t ret;
533
534
0
  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
535
0
  g_return_val_if_fail (error == NULL || *error == NULL, -1);
536
537
0
#if G_CREDENTIALS_USE_LINUX_UCRED
538
0
  if (linux_ucred_check_valid (&credentials->native, error))
539
0
    ret = credentials->native.uid;
540
0
  else
541
0
    ret = -1;
542
#elif G_CREDENTIALS_USE_APPLE_XUCRED
543
  if (credentials->native.cr_version == XUCRED_VERSION)
544
    {
545
      ret = credentials->native.cr_uid;
546
    }
547
  else
548
    {
549
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
550
                   /* No point in translating the part in parentheses... */
551
                   "%s (struct xucred cr_version %u != %u)",
552
                   _("There is no GCredentials support for your platform"),
553
                   credentials->native.cr_version,
554
                   XUCRED_VERSION);
555
      ret = -1;
556
    }
557
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
558
  ret = credentials->native.cmcred_euid;
559
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
560
  ret = credentials->native.unp_euid;
561
#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
562
  ret = credentials->native.uid;
563
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
564
  ret = ucred_geteuid (credentials->native);
565
#else
566
  ret = -1;
567
  g_set_error_literal (error,
568
                       G_IO_ERROR,
569
                       G_IO_ERROR_NOT_SUPPORTED,
570
                       _("There is no GCredentials support for your platform"));
571
#endif
572
573
0
  return ret;
574
0
}
575
576
/**
577
 * g_credentials_get_unix_pid:
578
 * @credentials: A #GCredentials
579
 * @error: Return location for error or %NULL.
580
 *
581
 * Tries to get the UNIX process identifier from @credentials. This
582
 * method is only available on UNIX platforms.
583
 *
584
 * This operation can fail if #GCredentials is not supported on the
585
 * OS or if the native credentials type does not contain information
586
 * about the UNIX process ID.
587
 *
588
 * Returns: The UNIX process ID, or `-1` if @error is set.
589
 *
590
 * Since: 2.36
591
 */
592
pid_t
593
g_credentials_get_unix_pid (GCredentials    *credentials,
594
                            GError         **error)
595
0
{
596
0
  pid_t ret;
597
598
0
  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
599
0
  g_return_val_if_fail (error == NULL || *error == NULL, -1);
600
601
0
#if G_CREDENTIALS_USE_LINUX_UCRED
602
0
  if (linux_ucred_check_valid (&credentials->native, error))
603
0
    ret = credentials->native.pid;
604
0
  else
605
0
    ret = -1;
606
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
607
  ret = credentials->native.cmcred_pid;
608
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
609
  ret = credentials->native.unp_pid;
610
#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
611
  ret = credentials->native.pid;
612
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
613
  ret = ucred_getpid (credentials->native);
614
#elif G_CREDENTIALS_USE_WIN32_PID
615
  ret = credentials->native;
616
#else
617
618
#if G_CREDENTIALS_USE_APPLE_XUCRED
619
  ret = credentials->pid;
620
#else
621
  ret = -1;
622
#endif
623
624
  if (ret == -1)
625
    g_set_error_literal (error,
626
                         G_IO_ERROR,
627
                         G_IO_ERROR_NOT_SUPPORTED,
628
                         _("GCredentials does not contain a process ID on this OS"));
629
#endif
630
631
0
  return ret;
632
0
}
633
634
/**
635
 * g_credentials_set_unix_user:
636
 * @credentials: A #GCredentials.
637
 * @uid: The UNIX user identifier to set.
638
 * @error: Return location for error or %NULL.
639
 *
640
 * Tries to set the UNIX user identifier on @credentials. This method
641
 * is only available on UNIX platforms.
642
 *
643
 * This operation can fail if #GCredentials is not supported on the
644
 * OS or if the native credentials type does not contain information
645
 * about the UNIX user. It can also fail if the OS does not allow the
646
 * use of "spoofed" credentials.
647
 *
648
 * Returns: %TRUE if @uid was set, %FALSE if error is set.
649
 *
650
 * Since: 2.26
651
 */
652
gboolean
653
g_credentials_set_unix_user (GCredentials    *credentials,
654
                             uid_t            uid,
655
                             GError         **error)
656
0
{
657
0
  gboolean ret = FALSE;
658
659
0
  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
660
0
  g_return_val_if_fail (uid != (uid_t) -1, FALSE);
661
0
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
662
663
0
#if G_CREDENTIALS_USE_LINUX_UCRED
664
0
  credentials->native.uid = uid;
665
0
  ret = TRUE;
666
#elif G_CREDENTIALS_USE_APPLE_XUCRED
667
  credentials->native.cr_uid = uid;
668
  ret = TRUE;
669
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
670
  credentials->native.cmcred_euid = uid;
671
  ret = TRUE;
672
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
673
  credentials->native.unp_euid = uid;
674
  ret = TRUE;
675
#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
676
  credentials->native.uid = uid;
677
  ret = TRUE;
678
#elif !G_CREDENTIALS_SPOOFING_SUPPORTED
679
  g_set_error_literal (error,
680
                       G_IO_ERROR,
681
                       G_IO_ERROR_PERMISSION_DENIED,
682
                       _("Credentials spoofing is not possible on this OS"));
683
  ret = FALSE;
684
#else
685
  g_set_error_literal (error,
686
                       G_IO_ERROR,
687
                       G_IO_ERROR_NOT_SUPPORTED,
688
                       _("GCredentials is not implemented on this OS"));
689
  ret = FALSE;
690
#endif
691
692
0
  return ret;
693
0
}
694
695
#ifdef __APPLE__
696
void
697
_g_credentials_set_local_peerid (GCredentials *credentials,
698
                                 pid_t         pid)
699
{
700
  g_return_if_fail (G_IS_CREDENTIALS (credentials));
701
  g_return_if_fail (pid >= 0);
702
703
  credentials->pid = pid;
704
}
705
#endif /* __APPLE__ */
706
707
#endif /* G_OS_UNIX */