~ubuntu-branches/debian/sid/hal/sid

« back to all changes in this revision

Viewing changes to hald/ci-tracker.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2007-10-23 12:33:58 UTC
  • Revision ID: james.westby@ubuntu.com-20071023123358-xaf8mjc5n84d5gtz
Tags: upstream-0.5.10
ImportĀ upstreamĀ versionĀ 0.5.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
#include "logger.h"
42
42
#include "ci-tracker.h"
43
43
 
 
44
/* ripped from dbus/dbus-marshal-validate.c and adapted */
 
45
 
 
46
/**
 
47
 * Determine wether the given character is valid as the first character
 
48
 * in a bus name.
 
49
 */
 
50
#define VALID_INITIAL_BUS_NAME_CHARACTER(c)         \
 
51
  ( ((c) >= 'A' && (c) <= 'Z') ||               \
 
52
    ((c) >= 'a' && (c) <= 'z') ||               \
 
53
    ((c) == '_') || ((c) == '-'))
 
54
 
 
55
 
 
56
/**
 
57
 * Determine wether the given character is valid as a second or later
 
58
 * character in a bus name
 
59
 */
 
60
#define VALID_BUS_NAME_CHARACTER(c)                 \
 
61
  ( ((c) >= '0' && (c) <= '9') ||               \
 
62
    ((c) >= 'A' && (c) <= 'Z') ||               \
 
63
    ((c) >= 'a' && (c) <= 'z') ||               \
 
64
    ((c) == '_') || ((c) == '-'))
 
65
 
 
66
static gboolean
 
67
validate_bus_name (const char *name)
 
68
{
 
69
        int len;
 
70
        const char *s;
 
71
        const char *end;
 
72
        const char *last_dot;
 
73
        gboolean ret;
 
74
 
 
75
        s = name;
 
76
        len = strlen (name);
 
77
        end = name + len;
 
78
        last_dot = NULL;
 
79
 
 
80
        ret = FALSE;
 
81
 
 
82
        /* check special cases of first char so it doesn't have to be done
 
83
         * in the loop. Note we know len > 0
 
84
         */
 
85
        if (*s == ':') {
 
86
                /* unique name */
 
87
                ++s;
 
88
                while (s != end) {
 
89
                        if (*s == '.') {
 
90
                                if (G_UNLIKELY ((s + 1) == end))
 
91
                                        goto error;
 
92
                                if (G_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1))))
 
93
                                        goto error;
 
94
                                ++s; /* we just validated the next char, so skip two */
 
95
                        } else if (G_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s))) {
 
96
                                goto error;
 
97
                        }
 
98
                        ++s;
 
99
                }
 
100
                return TRUE;
 
101
        } else if (G_UNLIKELY (*s == '.')) /* disallow starting with a . */ {
 
102
                goto error;
 
103
        } else if (G_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*s))) {
 
104
                goto error;
 
105
        } else {
 
106
                ++s;
 
107
        }
 
108
        
 
109
        while (s != end) {
 
110
                if (*s == '.') {
 
111
                        if (G_UNLIKELY ((s + 1) == end))
 
112
                                goto error;
 
113
                        else if (G_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*(s + 1))))
 
114
                                goto error;
 
115
                        last_dot = s;
 
116
                        ++s; /* we just validated the next char, so skip two */
 
117
                } else if (G_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s))) {
 
118
                        goto error;
 
119
                }
 
120
                ++s;
 
121
        }
 
122
        
 
123
        if (G_UNLIKELY (last_dot == NULL))
 
124
                goto error;
 
125
 
 
126
        ret = TRUE;
 
127
 
 
128
error:
 
129
        if (!ret)
 
130
                HAL_INFO (("name '%s' did not validate", name));
 
131
        return ret;
 
132
}
 
133
 
 
134
 
44
135
struct CITracker_s {
45
136
        GHashTable *connection_name_to_caller_info;
46
137
        DBusConnection *dbus_connection;
54
145
        gboolean in_active_session;   /* caller is in an active session */
55
146
        gboolean is_local;            /* session is on a local seat */
56
147
        char *session_objpath;        /* obj path of ConsoleKit session */
 
148
        char *selinux_context;        /* SELinux security context */
57
149
#endif
58
150
        char *system_bus_unique_name; /* unique name of caller on the system bus */
59
151
};
71
163
{
72
164
#ifdef HAVE_CONKIT
73
165
        g_free (ci->session_objpath);
 
166
        g_free (ci->selinux_context);
74
167
#endif
75
168
        g_free (ci->system_bus_unique_name);
76
169
        g_free (ci);
172
265
        DBusMessage *message;
173
266
        DBusMessage *reply;
174
267
        DBusMessageIter iter;
 
268
        DBusMessageIter sub_iter;
175
269
        char *dbus_session_name;
 
270
        char *str;
 
271
        int num_elems;
176
272
#endif /* HAVE_CONKIT */
177
273
        
178
274
        ci = NULL;
180
276
        if (system_bus_unique_name == NULL)
181
277
                goto error;
182
278
 
 
279
        if (!validate_bus_name (system_bus_unique_name))
 
280
                goto error;
 
281
 
183
282
        /*HAL_INFO (("========================="));
184
283
          HAL_INFO (("Looking up CICallerInfo for system_bus_unique_name = %s", system_bus_unique_name));*/
185
284
 
223
322
        dbus_message_unref (message);
224
323
        dbus_message_unref (reply);
225
324
 
 
325
        message = dbus_message_new_method_call ("org.freedesktop.DBus", 
 
326
                                                "/org/freedesktop/DBus/Bus",
 
327
                                                "org.freedesktop.DBus",
 
328
                                                "GetConnectionSELinuxSecurityContext");
 
329
        dbus_message_iter_init_append (message, &iter);
 
330
        dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &system_bus_unique_name);
 
331
        reply = dbus_connection_send_with_reply_and_block (cit->dbus_connection, message, -1, &error);
 
332
        /* SELinux might not be enabled */
 
333
        if (dbus_error_is_set (&error) && 
 
334
            strcmp (error.name, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown") == 0) {
 
335
                dbus_message_unref (message);
 
336
                if (reply != NULL)
 
337
                        dbus_message_unref (reply);
 
338
                dbus_error_init (&error);
 
339
        } else if (reply == NULL || dbus_error_is_set (&error)) {
 
340
                g_warning ("Error doing GetConnectionSELinuxSecurityContext on Bus: %s: %s", error.name, error.message);
 
341
                dbus_message_unref (message);
 
342
                if (reply != NULL)
 
343
                        dbus_message_unref (reply);
 
344
                goto error;
 
345
        } else {
 
346
                /* TODO: verify signature */
 
347
                dbus_message_iter_init (reply, &iter);
 
348
                dbus_message_iter_recurse (&iter, &sub_iter);
 
349
                dbus_message_iter_get_fixed_array (&sub_iter, (void *) &str, &num_elems);
 
350
                if (str != NULL && num_elems > 0)
 
351
                        ci->selinux_context = g_strndup (str, num_elems);
 
352
                dbus_message_unref (message);
 
353
                dbus_message_unref (reply);
 
354
        }
 
355
 
 
356
 
226
357
        message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", 
227
358
                                                "/org/freedesktop/ConsoleKit/Manager",
228
359
                                                "org.freedesktop.ConsoleKit.Manager",
347
478
{
348
479
        return ci->session_objpath;
349
480
}
 
481
 
 
482
const char *
 
483
ci_tracker_caller_get_selinux_context (CICallerInfo *ci)
 
484
{
 
485
        return ci->selinux_context;
 
486
}
 
487
 
350
488
#endif