Set up gtk-doc for GDBus
[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 GCredentials *
105 g_credentials_new (void)
106 {
107   return g_object_new (G_TYPE_CREDENTIALS, NULL);
108 }
109
110 /* ---------------------------------------------------------------------------------------------------- */
111
112 #ifdef G_OS_UNIX
113 static GCredentials *
114 g_credentials_new_for_unix_process (void)
115 {
116   GCredentials *credentials;
117   credentials = g_credentials_new ();
118   credentials->priv->unix_user = getuid ();
119   credentials->priv->unix_group = getgid ();
120   credentials->priv->unix_process = getpid ();
121   return credentials;
122 }
123 #endif
124
125 /* ---------------------------------------------------------------------------------------------------- */
126
127 /**
128  * g_credentials_new_for_process:
129  *
130  * Gets the credentials for the current process. Note that the exact
131  * set of credentials in the returned object vary according to
132  * platform.
133  *
134  * Returns: A #GCredentials. Free with g_object_unref().
135  */
136 GCredentials *
137 g_credentials_new_for_process (void)
138 {
139 #ifdef G_OS_UNIX
140   return g_credentials_new_for_unix_process ();
141 #elif G_OS_WIN32
142   return g_credentials_new_for_win32_process ();
143 #else
144 #warning Please implement g_credentials_new_for_process() for your OS. For now g_credentials_new_for_process() will return empty credentials.
145   return g_credentials_new ();
146 #endif
147 }
148
149 /* ---------------------------------------------------------------------------------------------------- */
150
151 /**
152  * g_credentials_new_for_string:
153  * @str: A string returned from g_credentials_to_string().
154  * @error: Return location for error.
155  *
156  * Constructs a #GCredentials instance from @str.
157  *
158  * Returns: A #GCredentials or %NULL if @error is set. The return
159  * object must be freed with g_object_unref().
160  */
161 GCredentials *
162 g_credentials_new_for_string (const gchar  *str,
163                               GError      **error)
164 {
165   GCredentials *credentials;
166   gchar **tokens;
167   guint n;
168
169   g_return_val_if_fail (str != NULL, NULL);
170   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
171
172   tokens = NULL;
173   credentials = g_credentials_new ();
174
175   if (!g_str_has_prefix (str, "GCredentials:"))
176     goto fail;
177
178   tokens = g_strsplit (str + sizeof "GCredentials:" - 1, ",", 0);
179   for (n = 0; tokens[n] != NULL; n++)
180     {
181       const gchar *token = tokens[n];
182       if (g_str_has_prefix (token, "unix-user:"))
183         g_credentials_set_unix_user (credentials, atoi (token + sizeof ("unix-user:") - 1));
184       else if (g_str_has_prefix (token, "unix-group:"))
185         g_credentials_set_unix_group (credentials, atoi (token + sizeof ("unix-group:") - 1));
186       else if (g_str_has_prefix (token, "unix-process:"))
187         g_credentials_set_unix_process (credentials, atoi (token + sizeof ("unix-process:") - 1));
188       else if (g_str_has_prefix (token, "windows-user:"))
189         g_credentials_set_windows_user (credentials, token + sizeof ("windows-user:"));
190       else
191         goto fail;
192     }
193   g_strfreev (tokens);
194   return credentials;
195
196  fail:
197   g_set_error (error,
198                G_IO_ERROR,
199                G_IO_ERROR_FAILED,
200                _("The string `%s' is not a valid credentials string"),
201                str);
202   g_object_unref (credentials);
203   g_strfreev (tokens);
204   return NULL;
205 }
206
207 /**
208  * g_credentials_to_string:
209  * @credentials: A #GCredentials object.
210  *
211  * Serializes @credentials to a string that can be used with
212  * g_credentials_new_for_string().
213  *
214  * Returns: A string that should be freed with g_free().
215  */
216 gchar *
217 g_credentials_to_string (GCredentials *credentials)
218 {
219   GString *ret;
220
221   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
222
223   ret = g_string_new ("GCredentials:");
224   if (credentials->priv->unix_user != -1)
225     g_string_append_printf (ret, "unix-user=%" G_GINT64_FORMAT ",", credentials->priv->unix_user);
226   if (credentials->priv->unix_group != -1)
227     g_string_append_printf (ret, "unix-group=%" G_GINT64_FORMAT ",", credentials->priv->unix_group);
228   if (credentials->priv->unix_process != -1)
229     g_string_append_printf (ret, "unix-process=%" G_GINT64_FORMAT ",", credentials->priv->unix_process);
230   if (credentials->priv->windows_user != NULL)
231     g_string_append_printf (ret, "windows-user=%s,", credentials->priv->windows_user);
232   if (ret->str[ret->len - 1] == ',')
233     ret->str[ret->len - 1] = '\0';
234
235   return g_string_free (ret, FALSE);
236 }
237
238 /* ---------------------------------------------------------------------------------------------------- */
239
240 /**
241  * g_credentials_has_unix_user:
242  * @credentials: A #GCredentials.
243  *
244  * Checks if @credentials has a UNIX user credential.
245  *
246  * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise.
247  */
248 gboolean
249 g_credentials_has_unix_user (GCredentials *credentials)
250 {
251   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
252   return credentials->priv->unix_user != -1;
253 }
254
255 /**
256  * g_credentials_get_unix_user:
257  * @credentials: A #GCredentials.
258  *
259  * Gets the UNIX user identifier from @credentials.
260  *
261  * Returns: The identifier or -1 if unset.
262  */
263 gint64
264 g_credentials_get_unix_user (GCredentials *credentials)
265 {
266   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
267   return credentials->priv->unix_user;
268 }
269
270 /**
271  * g_credentials_set_unix_user:
272  * @credentials: A #GCredentials.
273  * @user_id: A UNIX user identifier (typically type #uid_t) or -1 to unset it.
274  *
275  * Sets the UNIX user identifier.
276  */
277 void
278 g_credentials_set_unix_user (GCredentials *credentials,
279                              gint64        user_id)
280 {
281   g_return_if_fail (G_IS_CREDENTIALS (credentials));
282   credentials->priv->unix_user = user_id;
283 }
284
285 /* ---------------------------------------------------------------------------------------------------- */
286
287 /**
288  * g_credentials_has_unix_group:
289  * @credentials: A #GCredentials.
290  *
291  * Checks if @credentials has a UNIX group credential.
292  *
293  * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise.
294  */
295 gboolean
296 g_credentials_has_unix_group (GCredentials *credentials)
297 {
298   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
299   return credentials->priv->unix_group != -1;
300 }
301
302 /**
303  * g_credentials_get_unix_group:
304  * @credentials: A #GCredentials.
305  *
306  * Gets the UNIX group identifier from @credentials.
307  *
308  * Returns: The identifier or -1 if unset.
309  */
310 gint64
311 g_credentials_get_unix_group (GCredentials *credentials)
312 {
313   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
314   return credentials->priv->unix_group;
315 }
316
317 /**
318  * g_credentials_set_unix_group:
319  * @credentials: A #GCredentials.
320  * @group_id: A UNIX group identifier (typically type #gid_t) or -1 to unset.
321  *
322  * Sets the UNIX group identifier.
323  */
324 void
325 g_credentials_set_unix_group (GCredentials *credentials,
326                               gint64        group_id)
327 {
328   g_return_if_fail (G_IS_CREDENTIALS (credentials));
329   credentials->priv->unix_group = group_id;
330 }
331
332 /* ---------------------------------------------------------------------------------------------------- */
333
334 /**
335  * g_credentials_has_unix_process:
336  * @credentials: A #GCredentials.
337  *
338  * Checks if @credentials has a UNIX process credential.
339  *
340  * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise.
341  */
342 gboolean
343 g_credentials_has_unix_process (GCredentials *credentials)
344 {
345   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
346   return credentials->priv->unix_process != -1;
347 }
348
349 /**
350  * g_credentials_get_unix_process:
351  * @credentials: A #GCredentials.
352  *
353  * Gets the UNIX process identifier from @credentials.
354  *
355  * Returns: The identifier or -1 if unset.
356  */
357 gint64
358 g_credentials_get_unix_process (GCredentials *credentials)
359 {
360   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
361   return credentials->priv->unix_process;
362 }
363
364 /**
365  * g_credentials_set_unix_process:
366  * @credentials: A #GCredentials.
367  * @process_id: A UNIX process identifier (typically type #pid_t/#GPid) or -1 to unset.
368  *
369  * Sets the UNIX process identifier.
370  */
371 void
372 g_credentials_set_unix_process (GCredentials *credentials,
373                                 gint64        process_id)
374 {
375   g_return_if_fail (G_IS_CREDENTIALS (credentials));
376   credentials->priv->unix_process = process_id;
377 }
378
379 /* ---------------------------------------------------------------------------------------------------- */
380
381 /**
382  * g_credentials_has_windows_user:
383  * @credentials: A #GCredentials.
384  *
385  * Checks if @credentials has a Windows user SID (Security Identifier).
386  *
387  * Returns: %TRUE if @credentials has this type of credential, %FALSE otherwise.
388  */
389 gboolean
390 g_credentials_has_windows_user  (GCredentials *credentials)
391 {
392   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
393   return credentials->priv->windows_user != NULL;
394 }
395
396 /**
397  * g_credentials_get_windows_user:
398  * @credentials: A #GCredentials.
399  *
400  * Gets the Windows User SID from @credentials.
401  *
402  * Returns: A string or %NULL if unset. Do not free, the string is owned by @credentials.
403  */
404 const gchar *
405 g_credentials_get_windows_user  (GCredentials *credentials)
406 {
407   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
408   return credentials->priv->windows_user;
409 }
410
411 /**
412  * g_credentials_set_windows_user:
413  * @credentials: A #GCredentials.
414  * @user_sid: The Windows User SID or %NULL to unset.
415  *
416  * Sets the Windows User SID.
417  */
418 void
419 g_credentials_set_windows_user (GCredentials    *credentials,
420                                 const gchar     *user_sid)
421 {
422   g_return_if_fail (G_IS_CREDENTIALS (credentials));
423   g_free (credentials->priv->windows_user);
424   credentials->priv->windows_user = g_strdup (user_sid);
425 }
426
427 /* ---------------------------------------------------------------------------------------------------- */