source: projects/specs/trunk/x/xorg-x11-xinit/ck-xinit-session.c @ 10989

Revision 10989, 4.6 KB checked in by iwaim, 7 years ago (diff)

xorg-x11-xinit: add flies

Line 
1/*
2 * Copyright Red Hat, Inc. 2007,2009.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 *  * Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *  * Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in
12 *    the documentation and/or other materials provided with the
13 *    distribution.
14 *  * Neither the name of Red Hat, Inc., nor the names of its
15 *    contributors may be used to endorse or promote products derived
16 *    from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
19 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Gate a process inside of a ConsoleKit session.
31 *
32 * We want to do this instead of doing it from inside of xinit because at the
33 * point we're doing it, we've already added the user's UID to the list of
34 * allowed clients for the X server, so the ConsoleKit daemon, which assumes
35 * the user's UID, will be able to connect without needing to be able to read
36 * the user's X cookies.
37 */
38
39#include <sys/types.h>
40#include <sys/wait.h>
41#include <paths.h>
42#include <stdlib.h>
43#include <string.h>
44#include <syslog.h>
45#include <unistd.h>
46#include <ck-connector.h>
47#include <dbus/dbus.h>
48
49static void
50setbusenv(const char *var, const char *val)
51{
52        DBusConnection *conn;
53        DBusMessage *req, *rep;
54        DBusMessageIter iter, sub, subsub;
55        DBusError error;
56
57        dbus_error_init (&error);
58
59        conn = dbus_bus_get(DBUS_BUS_SESSION, &error);
60        if (conn == NULL) {
61                return;
62        }
63
64        req = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
65        if (req == NULL) {
66                return;
67        }
68
69        memset(&iter, 0, sizeof(iter));
70        memset(&sub, 0, sizeof(sub));
71        memset(&subsub, 0, sizeof(subsub));
72        dbus_message_iter_init_append(req, &iter);
73        if (!dbus_message_set_destination(req, DBUS_SERVICE_DBUS) ||
74            !dbus_message_set_path(req, DBUS_PATH_DBUS) ||
75            !dbus_message_set_interface(req, DBUS_INTERFACE_DBUS) ||
76            !dbus_message_set_member(req, "UpdateActivationEnvironment") ||
77            !dbus_message_iter_open_container(&iter,
78                                              DBUS_TYPE_ARRAY,
79                                              DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
80                                              DBUS_TYPE_STRING_AS_STRING
81                                              DBUS_TYPE_STRING_AS_STRING
82                                              DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
83                                              &sub) ||
84            !dbus_message_iter_open_container(&sub,
85                                              DBUS_TYPE_DICT_ENTRY,
86                                              NULL,
87                                              &subsub) ||
88            !dbus_message_iter_append_basic(&subsub, DBUS_TYPE_STRING, &var) ||
89            !dbus_message_iter_append_basic(&subsub, DBUS_TYPE_STRING, &val) ||
90            !dbus_message_iter_close_container(&sub, &subsub) ||
91            !dbus_message_iter_close_container(&iter, &sub)) {
92                dbus_message_unref(req);
93                return;
94        }
95        rep = dbus_connection_send_with_reply_and_block(conn, req,
96                                                        30000, &error);
97        dbus_message_unref(req);
98        if (rep) {
99                dbus_message_unref(rep);
100        }
101}
102
103int
104main(int argc, char **argv)
105{
106        CkConnector *ckc = NULL;
107        DBusError error;
108        const char *shell, *cookie;
109        pid_t pid;
110        int status;
111
112        ckc = ck_connector_new();
113        if (ckc != NULL) {
114                dbus_error_init (&error);
115                if (ck_connector_open_session(ckc, &error)) {
116                        pid = fork();
117                        switch (pid) {
118                        case -1:
119                                syslog(LOG_ERR, "error forking child");
120                                break;
121                        case 0:
122                                cookie = ck_connector_get_cookie(ckc);
123                                setenv("XDG_SESSION_COOKIE", cookie, 1);
124                                setbusenv("XDG_SESSION_COOKIE", cookie);
125                                break;
126                        default:
127                                waitpid(pid, &status, 0);
128                                exit(status);
129                                break;
130                        }
131                } else {
132                        syslog(LOG_ERR, "error connecting to console-kit");
133                }
134        } else {
135                syslog(LOG_ERR, "error setting up to connect to console-kit");
136        }
137        if (argc > 1) {
138                execvp(argv[1], argv + 1);
139        } else {
140                shell = getenv("SHELL");
141                if (shell == NULL) {
142                        shell = _PATH_BSHELL;
143                }
144                execlp(shell, shell, NULL);
145        }
146        _exit(1);
147}
Note: See TracBrowser for help on using the repository browser.