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