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