bcea1a413b487537b02ea4d21fa85aab9fcc1ad8
[platform/upstream/glib.git] / gio / gcredentials.c
1 /* GDBus - GLib D-Bus Library
2  *
3  * Copyright (C) 2008-2010 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
27 #ifdef __linux__
28 #define __USE_GNU
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <unistd.h>
32 #include <string.h>
33 #endif
34
35 #include <gobject/gvaluecollector.h>
36
37 #include "gcredentials.h"
38 #include "gioerror.h"
39
40 #include "glibintl.h"
41 #include "gioalias.h"
42
43 /**
44  * SECTION:gcredentials
45  * @short_description: An object containing credentials
46  * @include: gio/gio.h
47  *
48  * The #GCredentials type is a reference-counted wrapper for the
49  * native credentials type. This information is typically used for
50  * identifying, authenticating and authorizing other processes.
51  *
52  * Some operating systems supports looking up the credentials of the
53  * remote peer of a communication endpoint - see e.g.
54  * g_socket_get_credentials().
55  *
56  * Some operating systems supports securely sending and receiving
57  * credentials over a Unix Domain Socket, see
58  * #GUnixCredentialsMessage, g_unix_connection_send_credentials() and
59  * g_unix_connection_receive_credentials() for details.
60  *
61  * On Linux, the native credential type is a <literal>struct ucred</literal> - see
62  * the <literal>unix(7)</literal> man page for details.
63  */
64
65 struct _GCredentialsPrivate
66 {
67 #ifdef __linux__
68   struct ucred native;
69 #else
70 #warning Please add GCredentials support for your OS
71   guint foo;
72 #endif
73 };
74
75 G_DEFINE_TYPE (GCredentials, g_credentials, G_TYPE_OBJECT);
76
77 static void
78 g_credentials_finalize (GObject *object)
79 {
80   G_GNUC_UNUSED GCredentials *credentials = G_CREDENTIALS (object);
81
82   if (G_OBJECT_CLASS (g_credentials_parent_class)->finalize != NULL)
83     G_OBJECT_CLASS (g_credentials_parent_class)->finalize (object);
84 }
85
86
87 static void
88 g_credentials_class_init (GCredentialsClass *klass)
89 {
90   GObjectClass *gobject_class;
91
92   g_type_class_add_private (klass, sizeof (GCredentialsPrivate));
93
94   gobject_class = G_OBJECT_CLASS (klass);
95   gobject_class->finalize = g_credentials_finalize;
96 }
97
98 static void
99 g_credentials_init (GCredentials *credentials)
100 {
101   credentials->priv = G_TYPE_INSTANCE_GET_PRIVATE (credentials, G_TYPE_CREDENTIALS, GCredentialsPrivate);
102 #ifdef __linux__
103   credentials->priv->native.pid = getpid ();
104   credentials->priv->native.uid = getuid ();
105   credentials->priv->native.gid = getgid ();
106 #endif
107 }
108
109 /* ---------------------------------------------------------------------------------------------------- */
110
111 /**
112  * g_credentials_new:
113  *
114  * Creates a new #GCredentials object with credentials matching the
115  * the current process.
116  *
117  * Returns: A #GCredentials. Free with g_object_unref().
118  *
119  * Since: 2.26
120  */
121 GCredentials *
122 g_credentials_new (void)
123 {
124   return g_object_new (G_TYPE_CREDENTIALS, NULL);
125 }
126
127 /* ---------------------------------------------------------------------------------------------------- */
128
129 /**
130  * g_credentials_to_string:
131  * @credentials: A #GCredentials object.
132  *
133  * Creates a human-readable textual representation of @credentials
134  * that can be used in logging and debug messages. The format of the
135  * returned string may change in future GLib release.
136  *
137  * Returns: A string that should be freed with g_free().
138  *
139  * Since: 2.26
140  */
141 gchar *
142 g_credentials_to_string (GCredentials *credentials)
143 {
144   GString *ret;
145
146   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
147
148   ret = g_string_new ("GCredentials:");
149 #ifdef __linux__
150   g_string_append (ret, "linux:");
151   if (credentials->priv->native.pid != -1)
152     g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->priv->native.pid);
153   if (credentials->priv->native.uid != -1)
154     g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->priv->native.uid);
155   if (credentials->priv->native.gid != -1)
156     g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->priv->native.gid);
157   if (ret->str[ret->len - 1] == ',')
158     ret->str[ret->len - 1] = '\0';
159 #else
160   g_string_append (ret, "unknown");
161 #endif
162
163   return g_string_free (ret, FALSE);
164 }
165
166 /* ---------------------------------------------------------------------------------------------------- */
167
168 /**
169  * g_credentials_is_same_user:
170  * @credentials: A #GCredentials.
171  * @other_credentials: A #GCredentials.
172  * @error: Return location for error or %NULL.
173  *
174  * Checks if @credentials and @other_credentials is the same user.
175  *
176  * This operation can fail if #GCredentials is not supported on the
177  * the OS.
178  *
179  * Returns: %TRUE if @credentials and @other_credentials has the same
180  * user, %FALSE otherwise or if @error is set.
181  *
182  * Since: 2.26
183  */
184 gboolean
185 g_credentials_is_same_user (GCredentials  *credentials,
186                             GCredentials  *other_credentials,
187                             GError       **error)
188 {
189   gboolean ret;
190
191   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
192   g_return_val_if_fail (G_IS_CREDENTIALS (other_credentials), FALSE);
193   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
194
195   ret = FALSE;
196 #ifdef __linux__
197   if (credentials->priv->native.uid == other_credentials->priv->native.uid)
198     ret = TRUE;
199 #else
200   g_set_error_literal (error,
201                        G_IO_ERROR,
202                        G_IO_ERROR_NOT_SUPPORTED,
203                        _("GCredentials is not implemented on this OS"));
204 #endif
205
206   return ret;
207 }
208
209 /**
210  * g_credentials_get_native:
211  * @credentials: A #GCredentials.
212  *
213  * Gets a pointer to the native credentials structure.
214  *
215  * Returns: The pointer or %NULL if there is no #GCredentials support
216  * for the OS. Do not free the returned data, it is owned by
217  * @credentials.
218  *
219  * Since: 2.26
220  */
221 gpointer
222 g_credentials_get_native (GCredentials *credentials)
223 {
224   gpointer ret;
225   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
226
227 #ifdef __linux__
228   ret = &credentials->priv->native;
229 #else
230   ret = NULL;
231 #endif
232
233   return ret;
234 }
235
236 /**
237  * g_credentials_set_native:
238  * @credentials: A #GCredentials.
239  * @native: A pointer to native credentials.
240  *
241  * Copies the native credentials from @native into @credentials.
242  *
243  * It is a programming error (which will cause an warning to be
244  * logged) to use this method if there is no #GCredentials support for
245  * the OS.
246  *
247  * Since: 2.26
248  */
249 void
250 g_credentials_set_native (GCredentials    *credentials,
251                           gpointer         native)
252 {
253 #ifdef __linux__
254   memcpy (&credentials->priv->native, native, sizeof (struct ucred));
255 #else
256   g_warning ("g_credentials_set_native: Trying to set credentials but GLib has no support "
257              "for the native credentials type. Please add support.");
258 #endif
259 }
260
261 /* ---------------------------------------------------------------------------------------------------- */
262
263 #ifdef G_OS_UNIX
264 /**
265  * g_credentials_get_unix_user:
266  * @credentials: A #GCredentials
267  * @error: Return location for error or %NULL.
268  *
269  * Tries to get the UNIX user identifier from @credentials. This
270  * method is only available on UNIX platforms.
271  *
272  * This operation can fail if #GCredentials is not supported on the
273  * OS or if the native credentials type does not contain information
274  * about the UNIX user.
275  *
276  * Returns: The UNIX user identifier or -1 if @error is set.
277  *
278  * Since: 2.26
279  */
280 uid_t
281 g_credentials_get_unix_user (GCredentials    *credentials,
282                              GError         **error)
283 {
284   uid_t ret;
285
286   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
287   g_return_val_if_fail (error == NULL || *error == NULL, -1);
288
289 #ifdef __linux__
290   ret = credentials->priv->native.uid;
291 #else
292   ret = -1;
293   g_set_error_literal (error,
294                        G_IO_ERROR,
295                        G_IO_ERROR_NOT_SUPPORTED,
296                        _("There no GCredentials support for your your platform"));
297 #endif
298
299   return ret;
300 }
301
302 /**
303  * g_credentials_set_unix_user:
304  * @credentials: A #GCredentials.
305  * @uid: The UNIX user identifier to set.
306  * @error: Return location for error or %NULL.
307  *
308  * Tries to set the UNIX user identifier on @credentials. This method
309  * is only available on UNIX platforms.
310  *
311  * This operation can fail if #GCredentials is not supported on the
312  * OS or if the native credentials type does not contain information
313  * about the UNIX user.
314  *
315  * Returns: %TRUE if @uid was set, %FALSE if error is set.
316  *
317  * Since: 2.26
318  */
319 gboolean
320 g_credentials_set_unix_user (GCredentials    *credentials,
321                              uid_t            uid,
322                              GError         **error)
323 {
324   gboolean ret;
325
326   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
327   g_return_val_if_fail (uid != -1, FALSE);
328   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
329
330   ret = FALSE;
331 #ifdef __linux__
332   credentials->priv->native.uid = uid;
333   ret = TRUE;
334 #else
335   g_set_error_literal (error,
336                        G_IO_ERROR,
337                        G_IO_ERROR_NOT_SUPPORTED,
338                        _("GCredentials is not implemented on this OS"));
339 #endif
340
341   return ret;
342 }
343 #endif /* G_OS_UNIX */
344
345 #define __G_CREDENTIALS_C__
346 #include "gioaliasdef.c"