1f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes/* activation-helper.c Setuid helper for launching programs as a custom 3f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * user. This file is security sensitive. 4f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * 5f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * Copyright (C) 2007 Red Hat, Inc. 6f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * 7f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * Licensed under the Academic Free License version 2.1 8f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * 9f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * This program is free software; you can redistribute it and/or modify 10f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * it under the terms of the GNU General Public License as published by 11f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * the Free Software Foundation; either version 2 of the License, or 12f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * (at your option) any later version. 13f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * 14f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * This program is distributed in the hope that it will be useful, 15f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * but WITHOUT ANY WARRANTY; without even the implied warranty of 16f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * GNU General Public License for more details. 18f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * 19f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * You should have received a copy of the GNU General Public License 20f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * along with this program; if not, write to the Free Software 215baf2f856a9c6625993234855b07680da1c8916fTobias Mueller * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * 23f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes */ 24f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 25f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include <config.h> 26f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 27f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include "bus.h" 28f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include "driver.h" 29f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include "utils.h" 30f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include "desktop-file.h" 31f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include "config-parser-trivial.h" 32f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include "activation-helper.h" 33f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include "activation-exit-codes.h" 34f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 35f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include <stdio.h> 36f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include <stdlib.h> 37f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include <string.h> 38f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include <unistd.h> 39f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include <sys/types.h> 40f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include <pwd.h> 41f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include <grp.h> 42f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 43f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include <dbus/dbus-shell.h> 44f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#include <dbus/dbus-marshal-validate.h> 45f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 46f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesstatic BusDesktopFile * 47f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesdesktop_file_for_name (BusConfigParser *parser, 48f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes const char *name, 49f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBusError *error) 50f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 51f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes BusDesktopFile *desktop_file; 52f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBusList **service_dirs; 53f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBusList *link; 54f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBusError tmp_error; 55f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBusString full_path; 56f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBusString filename; 57f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes const char *dir; 58f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 59f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _DBUS_ASSERT_ERROR_IS_CLEAR (error); 60f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 61f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes desktop_file = NULL; 62f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 63f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!_dbus_string_init (&filename)) 64f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 65f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes BUS_SET_OOM (error); 66f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto out_all; 67f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 68f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 69f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!_dbus_string_init (&full_path)) 70f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 71f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes BUS_SET_OOM (error); 72f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto out_filename; 73f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 74f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 75f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!_dbus_string_append (&filename, name) || 76f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes !_dbus_string_append (&filename, ".service")) 77f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 78f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes BUS_SET_OOM (error); 79f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto out; 80f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 81f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 82f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes service_dirs = bus_config_parser_get_service_dirs (parser); 83f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes for (link = _dbus_list_get_first_link (service_dirs); 84f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes link != NULL; 85f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes link = _dbus_list_get_next_link (service_dirs, link)) 86f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 87f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dir = link->data; 88f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_verbose ("Looking at '%s'\n", dir); 89f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 90f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_error_init (&tmp_error); 91f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 92f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* clear the path from last time */ 93f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_string_set_length (&full_path, 0); 94f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 95f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* build the full path */ 96f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!_dbus_string_append (&full_path, dir) || 97f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes !_dbus_concat_dir_and_file (&full_path, &filename)) 98f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 99f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes BUS_SET_OOM (error); 100f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto out; 101f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 102f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 103f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_verbose ("Trying to load file '%s'\n", _dbus_string_get_data (&full_path)); 104f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes desktop_file = bus_desktop_file_load (&full_path, &tmp_error); 105f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (desktop_file == NULL) 106f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 107f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); 108f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_verbose ("Could not load %s: %s: %s\n", 109f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_string_get_const_data (&full_path), 110f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes tmp_error.name, tmp_error.message); 111f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 112f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* we may have failed if the file is not found; this is not fatal */ 113f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY)) 114f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 115f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_move_error (&tmp_error, error); 116f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* we only bail out on OOM */ 117f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto out; 118f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 119f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_error_free (&tmp_error); 120f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 121f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 122f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* did we find the desktop file we want? */ 123f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (desktop_file != NULL) 124f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes break; 125f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 126f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 127f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* Didn't find desktop file; set error */ 128f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (desktop_file == NULL) 129f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 130f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND, 131f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "The name %s was not provided by any .service files", 132f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes name); 133f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 134f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 135f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesout: 136f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_string_free (&full_path); 137f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesout_filename: 138f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_string_free (&filename); 139f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesout_all: 140f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return desktop_file; 141f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 142f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 1434299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat/* Clears the environment, except for DBUS_STARTER_x, 1444299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat * which we hardcode to the system bus. 1454299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat */ 146f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesstatic dbus_bool_t 147f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesclear_environment (DBusError *error) 148f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 149f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#ifndef ACTIVATION_LAUNCHER_TEST 150f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* totally clear the environment */ 151f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!_dbus_clearenv ()) 152f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 153f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_SETUP_FAILED, 154f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "could not clear environment\n"); 155f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 156f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 157f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#endif 158f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 1594299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat /* Ensure the bus is set to system */ 1604299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _dbus_setenv ("DBUS_STARTER_ADDRESS", DBUS_SYSTEM_BUS_DEFAULT_ADDRESS); 161f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_setenv ("DBUS_STARTER_BUS_TYPE", "system"); 162f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 163f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return TRUE; 164f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 165f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 166f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesstatic dbus_bool_t 167f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughescheck_permissions (const char *dbus_user, DBusError *error) 168f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 1694299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat#ifndef ACTIVATION_LAUNCHER_TEST 170f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes uid_t uid, euid; 171f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes struct passwd *pw; 172f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 173f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes pw = NULL; 174f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes uid = 0; 175f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes euid = 0; 176f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 177f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* bail out unless the dbus user is invoking the helper */ 178f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes pw = getpwnam(dbus_user); 179f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!pw) 180f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 181f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_PERMISSIONS_INVALID, 182f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "cannot find user '%s'", dbus_user); 183f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 184f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 185f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes uid = getuid(); 186f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (pw->pw_uid != uid) 187f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 188f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_PERMISSIONS_INVALID, 189f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "not invoked from user '%s'", dbus_user); 190f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 191f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 192f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 193f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* bail out unless we are setuid to user root */ 194f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes euid = geteuid(); 195f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (euid != 0) 196f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 197f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_PERMISSIONS_INVALID, 198f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "not setuid root"); 199f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 200f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 201f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#endif 202f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 203f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return TRUE; 204f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 205f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 206f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesstatic dbus_bool_t 207f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughescheck_service_name (BusDesktopFile *desktop_file, 208f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes const char *service_name, 209f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBusError *error) 210f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 211f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes char *name_tmp; 212f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_bool_t retval; 213f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 214f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes retval = FALSE; 215f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 216f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* try to get Name */ 217f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!bus_desktop_file_get_string (desktop_file, 218f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBUS_SERVICE_SECTION, 219f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBUS_SERVICE_NAME, 220f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes &name_tmp, 221f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes error)) 222f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto failed; 223f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 224f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* verify that the name is the same as the file service name */ 225f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (strcmp (service_name, name_tmp) != 0) 226f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 227f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_FILE_INVALID, 228f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "Service '%s' does not match expected value", name_tmp); 229f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto failed_free; 230f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 231f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 232f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes retval = TRUE; 233f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 234f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesfailed_free: 235f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* we don't return the name, so free it here */ 236f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_free (name_tmp); 237f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesfailed: 238f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return retval; 239f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 240f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 241f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesstatic dbus_bool_t 242f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesget_parameters_for_service (BusDesktopFile *desktop_file, 243f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes const char *service_name, 244f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes char **exec, 245f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes char **user, 246f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBusError *error) 247f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 248f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes char *exec_tmp; 249f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes char *user_tmp; 250f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 251f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes exec_tmp = NULL; 252f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes user_tmp = NULL; 253f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 254f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* check the name of the service */ 255f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!check_service_name (desktop_file, service_name, error)) 256f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto failed; 257f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 258f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* get the complete path of the executable */ 259f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!bus_desktop_file_get_string (desktop_file, 260f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBUS_SERVICE_SECTION, 261f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBUS_SERVICE_EXEC, 262f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes &exec_tmp, 263f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes error)) 264f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 265f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _DBUS_ASSERT_ERROR_IS_SET (error); 266f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto failed; 267f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 268f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 269f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* get the user that should run this service - user is compulsary for system activation */ 270f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!bus_desktop_file_get_string (desktop_file, 271f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBUS_SERVICE_SECTION, 272f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBUS_SERVICE_USER, 273f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes &user_tmp, 274f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes error)) 275f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 276f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _DBUS_ASSERT_ERROR_IS_SET (error); 277f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto failed; 278f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 279f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 280f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* only assign if all the checks passed */ 281f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes *exec = exec_tmp; 282f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes *user = user_tmp; 283f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return TRUE; 284f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 285f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesfailed: 286f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_free (exec_tmp); 287f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_free (user_tmp); 288f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 289f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 290f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 291f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesstatic dbus_bool_t 292f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesswitch_user (char *user, DBusError *error) 293f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 294f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#ifndef ACTIVATION_LAUNCHER_TEST 295f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes struct passwd *pw; 296f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 297f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* find user */ 298f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes pw = getpwnam (user); 299f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!pw) 300f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 301f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_SETUP_FAILED, 302f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "cannot find user '%s'\n", user); 303f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 304f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 305f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 306f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* initialize the group access list */ 307f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (initgroups (user, pw->pw_gid)) 308f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 309f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_SETUP_FAILED, 310f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "could not initialize groups"); 311f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 312f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 313f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 314f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* change to the primary group for the user */ 315f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (setgid (pw->pw_gid)) 316f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 317f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_SETUP_FAILED, 318f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "cannot setgid group %i", pw->pw_gid); 319f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 320f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 321f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 322f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* change to the user specified */ 323f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (setuid (pw->pw_uid) < 0) 324f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 325f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_SETUP_FAILED, 326f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "cannot setuid user %i", pw->pw_uid); 327f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 328f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 329f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#endif 330f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return TRUE; 331f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 332f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 333f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesstatic dbus_bool_t 334f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesexec_for_correct_user (char *exec, char *user, DBusError *error) 335f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 336f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes char **argv; 337f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes int argc; 338f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_bool_t retval; 339f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 340f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes argc = 0; 341f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes retval = TRUE; 342f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes argv = NULL; 343f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 344f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!switch_user (user, error)) 345f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 346f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 347f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* convert command into arguments */ 348f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!_dbus_shell_parse_argv (exec, &argc, &argv, error)) 349f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 350f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 351f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#ifndef ACTIVATION_LAUNCHER_DO_OOM 352f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* replace with new binary, with no environment */ 353f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (execv (argv[0], argv) < 0) 354f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 355f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 356f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "Failed to exec: %s", argv[0]); 357f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes retval = FALSE; 358f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 359f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#endif 360f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 361f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_free_string_array (argv); 362f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return retval; 363f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 364f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 365f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesstatic dbus_bool_t 366ae4a1586969aaca534508837830d7d3de4ade070Havoc Penningtoncheck_bus_name (const char *bus_name, 367ae4a1586969aaca534508837830d7d3de4ade070Havoc Pennington DBusError *error) 368f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 369ae4a1586969aaca534508837830d7d3de4ade070Havoc Pennington DBusString str; 370ae4a1586969aaca534508837830d7d3de4ade070Havoc Pennington 371ae4a1586969aaca534508837830d7d3de4ade070Havoc Pennington _dbus_string_init_const (&str, bus_name); 372ae4a1586969aaca534508837830d7d3de4ade070Havoc Pennington if (!_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str))) 373f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 374f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND, 375ae4a1586969aaca534508837830d7d3de4ade070Havoc Pennington "bus name '%s' is not a valid bus name\n", 376ae4a1586969aaca534508837830d7d3de4ade070Havoc Pennington bus_name); 377f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 378f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 379ae4a1586969aaca534508837830d7d3de4ade070Havoc Pennington 380f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return TRUE; 381f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 382f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 383f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesstatic dbus_bool_t 384f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesget_correct_parser (BusConfigParser **parser, DBusError *error) 385f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 386f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes DBusString config_file; 387f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_bool_t retval; 3884299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat#ifdef ACTIVATION_LAUNCHER_TEST 389f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes const char *test_config_file; 3904299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat#endif 391f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 392f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes retval = FALSE; 393f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 394f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#ifdef ACTIVATION_LAUNCHER_TEST 3954299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat test_config_file = NULL; 3964299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 397f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* there is no _way_ we should be setuid if this define is set. 398f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * but we should be doubly paranoid and check... */ 399f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (getuid() != geteuid()) 400f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_assert_not_reached ("dbus-daemon-launch-helper-test binary is setuid!"); 401f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 402f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* this is not a security hole. The environment variable is only passed in the 403f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes * dbus-daemon-lauch-helper-test NON-SETUID launcher */ 404f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes test_config_file = _dbus_getenv ("TEST_LAUNCH_HELPER_CONFIG"); 405f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (test_config_file == NULL) 406f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 407f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_SETUP_FAILED, 408f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "the TEST_LAUNCH_HELPER_CONFIG env variable is not set"); 409f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto out; 410f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 411f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#endif 412f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 413f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* we _only_ use the predefined system config file */ 414f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!_dbus_string_init (&config_file)) 415f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 416f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes BUS_SET_OOM (error); 417f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto out; 418f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 419f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#ifndef ACTIVATION_LAUNCHER_TEST 420f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!_dbus_string_append (&config_file, DBUS_SYSTEM_CONFIG_FILE)) 421f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 422f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes BUS_SET_OOM (error); 423f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto out_free_config; 424f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 425f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#else 426f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!_dbus_string_append (&config_file, test_config_file)) 427f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 428f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes BUS_SET_OOM (error); 429f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto out_free_config; 430f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 431f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes#endif 432f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 433f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* where are we pointing.... */ 434f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_verbose ("dbus-daemon-activation-helper: using config file: %s\n", 435f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_string_get_const_data (&config_file)); 436f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 437f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* get the dbus user */ 438f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes *parser = bus_config_load (&config_file, TRUE, NULL, error); 439f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (*parser == NULL) 440f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 441f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto out_free_config; 442f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 443f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 444f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* woot */ 445f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes retval = TRUE; 446f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 447f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesout_free_config: 448f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_string_free (&config_file); 449f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesout: 450f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return retval; 451f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 452f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 453f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesstatic dbus_bool_t 454f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hugheslaunch_bus_name (const char *bus_name, BusConfigParser *parser, DBusError *error) 455f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 456f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes BusDesktopFile *desktop_file; 457f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes char *exec, *user; 458f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_bool_t retval; 459f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 460f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes exec = NULL; 461f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes user = NULL; 462f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes retval = FALSE; 463f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 464f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* get the correct service file for the name we are trying to activate */ 465f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes desktop_file = desktop_file_for_name (parser, bus_name, error); 466f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (desktop_file == NULL) 467f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 468f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 469f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* get exec and user for service name */ 470f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!get_parameters_for_service (desktop_file, bus_name, &exec, &user, error)) 471f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto finish; 472f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 473f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_verbose ("dbus-daemon-activation-helper: Name='%s'\n", bus_name); 474f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_verbose ("dbus-daemon-activation-helper: Exec='%s'\n", exec); 475f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes _dbus_verbose ("dbus-daemon-activation-helper: User='%s'\n", user); 476f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 477f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* actually execute */ 478f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!exec_for_correct_user (exec, user, error)) 479f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto finish; 480f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 481f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes retval = TRUE; 482f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 483f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesfinish: 484f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_free (exec); 485f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_free (user); 486f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes bus_desktop_file_free (desktop_file); 487f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return retval; 488f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 489f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 490f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesstatic dbus_bool_t 491f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughescheck_dbus_user (BusConfigParser *parser, DBusError *error) 492f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 493f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes const char *dbus_user; 494f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 495f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_user = bus_config_parser_get_user (parser); 496f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (dbus_user == NULL) 497f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes { 498f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_set_error (error, DBUS_ERROR_SPAWN_CONFIG_INVALID, 499f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes "could not get user from config file\n"); 500f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 501f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes } 502f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 503f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* check to see if permissions are correct */ 504f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!check_permissions (dbus_user, error)) 505f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return FALSE; 506f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 507f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return TRUE; 508f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 509f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 510f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughesdbus_bool_t 511ae4a1586969aaca534508837830d7d3de4ade070Havoc Penningtonrun_launch_helper (const char *bus_name, 512ae4a1586969aaca534508837830d7d3de4ade070Havoc Pennington DBusError *error) 513f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes{ 514f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes BusConfigParser *parser; 515f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes dbus_bool_t retval; 516f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 517f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes parser = NULL; 518f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes retval = FALSE; 519f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 520f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* clear the environment, apart from a few select settings */ 521f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!clear_environment (error)) 522f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto error; 523f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 524f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* check to see if we have a valid bus name */ 525f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!check_bus_name (bus_name, error)) 526f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto error; 527f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 528f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* get the correct parser, either the test or default parser */ 529f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!get_correct_parser (&parser, error)) 530f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto error; 531f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 532f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* check we are being invoked by the correct dbus user */ 533f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!check_dbus_user (parser, error)) 534f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto error_free_parser; 535f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 536f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* launch the bus with the service defined user */ 537f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes if (!launch_bus_name (bus_name, parser, error)) 538f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes goto error_free_parser; 539f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 540f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes /* woohoo! */ 541f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes retval = TRUE; 542f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 543f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hugheserror_free_parser: 544f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes bus_config_parser_unref (parser); 545f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hugheserror: 546f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes return retval; 547f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes} 548f4082146e91014c56c6215fb4e471f9f1baa8f60Richard Hughes 549