Add "Since: 2.26" to all new GDBus API
[platform/upstream/glib.git] / gio / gcredentials.c
1 /* GDBus - GLib D-Bus Library
2  *
3  * Copyright (C) 2008-2009 Red Hat, Inc.
4  *
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.
9  *
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.
14  *
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.
19  *
20  * Author: David Zeuthen <davidz@redhat.com>
21  */
22
23 #include "config.h"
24
25 #include <stdlib.h>
26 #include <glib/gi18n.h>
27 #include <gobject/gvaluecollector.h>
28
29 #include "gcredentials.h"
30 #include "gioerror.h"
31
32 #ifdef G_OS_UNIX
33 #include <sys/types.h>
34 #include <unistd.h>
35 #endif
36
37 /**
38  * SECTION:gcredentials
39  * @short_description: An object containing credentials
40  * @include: gio/gio.h
41  *
42  * The #GCredentials type is used for storing information that can be
43  * used for identifying, authenticating and authorizing processes.
44  *
45  * Most UNIX and UNIX-like operating systems support a secure exchange
46  * of credentials over a Unix Domain Socket, see
47  * #GUnixCredentialsMessage, g_unix_connection_send_credentials() and
48  * g_unix_connection_receive_credentials() for details.
49  */
50
51 struct _GCredentialsPrivate
52 {
53   gint64 unix_user;
54   gint64 unix_group;
55   gint64 unix_process;
56   gchar *windows_user;
57 };
58
59 G_DEFINE_TYPE (GCredentials, g_credentials, G_TYPE_OBJECT);
60
61 static void
62 g_credentials_finalize (GObject *object)
63 {
64   GCredentials *credentials = G_CREDENTIALS (object);
65
66   g_free (credentials->priv->windows_user);
67
68   if (G_OBJECT_CLASS (g_credentials_parent_class)->finalize != NULL)
69     G_OBJECT_CLASS (g_credentials_parent_class)->finalize (object);
70 }
71
72
73 static void
74 g_credentials_class_init (GCredentialsClass *klass)
75 {
76   GObjectClass *gobject_class;
77
78   g_type_class_add_private (klass, sizeof (GCredentialsPrivate));
79
80   gobject_class = G_OBJECT_CLASS (klass);
81   gobject_class->finalize = g_credentials_finalize;
82 }
83
84 static void
85 g_credentials_init (GCredentials *credentials)
86 {
87   credentials->priv = G_TYPE_INSTANCE_GET_PRIVATE (credentials, G_TYPE_CREDENTIALS, GCredentialsPrivate);
88
89   credentials->priv->unix_user = -1;
90   credentials->priv->unix_group = -1;
91   credentials->priv->unix_process = -1;
92   credentials->priv->windows_user = NULL;
93 }
94
95 /* ---------------------------------------------------------------------------------------------------- */
96
97 /**
98  * g_credentials_new:
99  *
100  * Creates a new empty credentials object.
101  *
102  * Returns: A #GCredentials. Free with g_object_unref().
103  *
104  * Since: 2.26
105  */
106 GCredentials *
107 g_credentials_new (void)
108 {
109   return g_object_new (G_TYPE_CREDENTIALS, NULL);
110 }
111
112 /* ---------------------------------------------------------------------------------------------------- */
113
114 #ifdef G_OS_UNIX
115 static GCredentials *
116 g_credentials_new_for_unix_process (void)
117 {
118   GCredentials *credentials;
119   credentials = g_credentials_new ();
120   credentials->priv->unix_user = getuid ();
121   credentials->priv->unix_group = getgid ();
122   credentials->priv->unix_process = getpid ();
123   return credentials;
124 }
125 #endif
126
127 /* ---------------------------------------------------------------------------------------------------- */
128
129 /**
130  * g_credentials_new_for_process:
131  *
132  * Gets the credentials for the current process. Note that the exact
133  * set of credentials in the returned object vary according to
134  * platform.
135  *
136  * Returns: A #GCredentials. Free with g_object_unref().
137  *
138  * Since: 2.26
139  */
140 GCredentials *
141 g_credentials_new_for_process (void)
142 {
143 #ifdef G_OS_UNIX
144   return g_credentials_new_for_unix_process ();
145 #elif G_OS_WIN32
146   return g_credentials_new_for_win32_process ();
147 #else
148 #warning Please implement g_credentials_new_for_process() for your OS. For now g_credentials_new_for_process() will return empty credentials.
149   return g_credentials_new ();
150 #endif
151 }
152
153 /* ---------------------------------------------------------------------------------------------------- */
154
155 /**
156  * g_credentials_new_for_string:
157  * @str: A string returned from g_credentials_to_string().
158  * @error: Return location for error.
159  *
160  * Constructs a #GCredentials instance from @str.
161  *
162  * Returns: A #GCredentials or %NULL if @error is set. The return
163  * object must be freed with g_object_unref().
164  *
165  * Since: 2.26
166  */
167 GCredentials *
168 g_credentials_new_for_string (const gchar  *str,
169                               GError      **error)
170 {
171   GCredentials *credentials;
172   gchar **tokens;
173   guint n;
174
175   g_return_val_if_fail (str != NULL, NULL);
176   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
177
178   tokens = NULL;
179   credentials = g_credentials_new ();
180
181   if (!g_str_has_prefix (str, "GCredentials:"))
182     goto fail;
183
184   tokens = g_strsplit (str + sizeof "GCredentials:" - 1, ",", 0);
185   for (n = 0; tokens[n] != NULL; n++)
186     {
187       const gchar *token = tokens[n];
188       if (g_str_has_prefix (token, "unix-user:"))
189         g_credentials_set_unix_user (credentials, atoi (token + sizeof ("unix-user:") - 1));
190       else if (g_str_has_prefix (token, "unix-group:"))
191         g_credentials_set_unix_group (credentials, atoi (token + sizeof ("unix-group:") - 1));
192       else if (g_str_has_prefix (token, "unix-process:"))
193         g_credentials_set_unix_process (credentials, atoi (token + sizeof ("unix-process:") - 1));
194       else if (g_str_has_prefix (token, "windows-user:"))
195         g_credentials_set_windows_user (credentials, token + sizeof ("windows-user:"));
196       else
197         goto fail;
198     }
199   g_strfreev (tokens);
200   return credentials;
201
202  fail:
203   g_set_error (error,
204                G_IO_ERROR,
205                G_IO_ERROR_FAILED,
206                _("The string `%s' is not a valid credentials string"),
207                str);
208   g_object_unref (credentials);
209   g_strfreev (tokens);
210   return NULL;
211 }
212
213 /**
214  * g_credentials_to_string:
215  * @credentials: A #GCredentials object.
216  *
217  * Serializes @credentials to a string that can be used with
218  * g_credentials_new_for_string().
219  *
220  * Returns: A string that should be freed with g_free().
221  *
222  * Since: 2.26
223  */
224 gchar *
225 g_credentials_to_string (GCredentials *credentials)
226 {
227   GString *ret;
228
229   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
230
231   ret = g_string_new ("GCredentials:");
232   if (credentials->priv->unix_user != -1)
233     g_string_append_printf (ret, "unix-user=%" G_GINT64_FORMAT ",", credentials->priv->unix_user);
234   if (credentials->priv->unix_group != -1)
235     g_string_append_printf (ret, "unix-group=%" G_GINT64_FORMAT ",", credentials->priv->unix_group);
236   if (credentials->priv->unix_process != -1)
237     g_string_append_printf (ret, "unix-process=%" G_GINT64_FORMAT ",", credentials->priv->unix_process);
238   if (credentials->priv->windows_user != NULL)
239     g_string_append_printf (ret, "windows-user=%s,", credentials->priv->windows_user);
240   if (ret->str[ret->len - 1] == ',')
241     ret->str[ret->len - 1] = '\0';
242
243   return g_string_free (ret, FALSE);
244 }
245
246 /* ---------------------------------------------------------------------------------------------------- */
247
248 /**
249  * g_credentials_has_unix_user:
250  * @credentials: A #GCredentials.
251  *
252  * Checks if @credentials has a UNIX user credential.
253  *
254  * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise.
255  *
256  * Since: 2.26
257  */
258 gboolean
259 g_credentials_has_unix_user (GCredentials *credentials)
260 {
261   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
262   return credentials->priv->unix_user != -1;
263 }
264
265 /**
266  * g_credentials_get_unix_user:
267  * @credentials: A #GCredentials.
268  *
269  * Gets the UNIX user identifier from @credentials.
270  *
271  * Returns: The identifier or -1 if unset.
272  *
273  * Since: 2.26
274  */
275 gint64
276 g_credentials_get_unix_user (GCredentials *credentials)
277 {
278   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
279   return credentials->priv->unix_user;
280 }
281
282 /**
283  * g_credentials_set_unix_user:
284  * @credentials: A #GCredentials.
285  * @user_id: A UNIX user identifier (typically type #uid_t) or -1 to unset it.
286  *
287  * Sets the UNIX user identifier.
288  *
289  * Since: 2.26
290  */
291 void
292 g_credentials_set_unix_user (GCredentials *credentials,
293                              gint64        user_id)
294 {
295   g_return_if_fail (G_IS_CREDENTIALS (credentials));
296   credentials->priv->unix_user = user_id;
297 }
298
299 /* ---------------------------------------------------------------------------------------------------- */
300
301 /**
302  * g_credentials_has_unix_group:
303  * @credentials: A #GCredentials.
304  *
305  * Checks if @credentials has a UNIX group credential.
306  *
307  * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise.
308  *
309  * Since: 2.26
310  */
311 gboolean
312 g_credentials_has_unix_group (GCredentials *credentials)
313 {
314   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
315   return credentials->priv->unix_group != -1;
316 }
317
318 /**
319  * g_credentials_get_unix_group:
320  * @credentials: A #GCredentials.
321  *
322  * Gets the UNIX group identifier from @credentials.
323  *
324  * Returns: The identifier or -1 if unset.
325  *
326  * Since: 2.26
327  */
328 gint64
329 g_credentials_get_unix_group (GCredentials *credentials)
330 {
331   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
332   return credentials->priv->unix_group;
333 }
334
335 /**
336  * g_credentials_set_unix_group:
337  * @credentials: A #GCredentials.
338  * @group_id: A UNIX group identifier (typically type #gid_t) or -1 to unset.
339  *
340  * Sets the UNIX group identifier.
341  *
342  * Since: 2.26
343  */
344 void
345 g_credentials_set_unix_group (GCredentials *credentials,
346                               gint64        group_id)
347 {
348   g_return_if_fail (G_IS_CREDENTIALS (credentials));
349   credentials->priv->unix_group = group_id;
350 }
351
352 /* ---------------------------------------------------------------------------------------------------- */
353
354 /**
355  * g_credentials_has_unix_process:
356  * @credentials: A #GCredentials.
357  *
358  * Checks if @credentials has a UNIX process credential.
359  *
360  * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise.
361  *
362  * Since: 2.26
363  */
364 gboolean
365 g_credentials_has_unix_process (GCredentials *credentials)
366 {
367   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
368   return credentials->priv->unix_process != -1;
369 }
370
371 /**
372  * g_credentials_get_unix_process:
373  * @credentials: A #GCredentials.
374  *
375  * Gets the UNIX process identifier from @credentials.
376  *
377  * Returns: The identifier or -1 if unset.
378  *
379  * Since: 2.26
380  */
381 gint64
382 g_credentials_get_unix_process (GCredentials *credentials)
383 {
384   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
385   return credentials->priv->unix_process;
386 }
387
388 /**
389  * g_credentials_set_unix_process:
390  * @credentials: A #GCredentials.
391  * @process_id: A UNIX process identifier (typically type #pid_t/#GPid) or -1 to unset.
392  *
393  * Sets the UNIX process identifier.
394  *
395  * Since: 2.26
396  */
397 void
398 g_credentials_set_unix_process (GCredentials *credentials,
399                                 gint64        process_id)
400 {
401   g_return_if_fail (G_IS_CREDENTIALS (credentials));
402   credentials->priv->unix_process = process_id;
403 }
404
405 /* ---------------------------------------------------------------------------------------------------- */
406
407 /**
408  * g_credentials_has_windows_user:
409  * @credentials: A #GCredentials.
410  *
411  * Checks if @credentials has a Windows user SID (Security Identifier).
412  *
413  * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise.
414  *
415  * Since: 2.26
416  */
417 gboolean
418 g_credentials_has_windows_user  (GCredentials *credentials)
419 {
420   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
421   return credentials->priv->windows_user != NULL;
422 }
423
424 /**
425  * g_credentials_get_windows_user:
426  * @credentials: A #GCredentials.
427  *
428  * Gets the Windows User SID from @credentials.
429  *
430  * Returns: A string or %NULL if unset. Do not free, the string is owned by @credentials.
431  *
432  * Since: 2.26
433  */
434 const gchar *
435 g_credentials_get_windows_user  (GCredentials *credentials)
436 {
437   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
438   return credentials->priv->windows_user;
439 }
440
441 /**
442  * g_credentials_set_windows_user:
443  * @credentials: A #GCredentials.
444  * @user_sid: The Windows User SID or %NULL to unset.
445  *
446  * Sets the Windows User SID.
447  *
448  * Since: 2.26
449  */
450 void
451 g_credentials_set_windows_user (GCredentials    *credentials,
452                                 const gchar     *user_sid)
453 {
454   g_return_if_fail (G_IS_CREDENTIALS (credentials));
455   g_free (credentials->priv->windows_user);
456   credentials->priv->windows_user = g_strdup (user_sid);
457 }
458
459 /* ---------------------------------------------------------------------------------------------------- */