1*d2ec54f7Sphitran /*************************************************************************** 2*d2ec54f7Sphitran * CVSID: $Id$ 3*d2ec54f7Sphitran * 4*d2ec54f7Sphitran * hal-is-caller-privileged.c : Determine if a caller is privileged 5*d2ec54f7Sphitran * 6*d2ec54f7Sphitran * Copyright (C) 2007 David Zeuthen, <david@fubar.dk> 7*d2ec54f7Sphitran * 8*d2ec54f7Sphitran * Licensed under the Academic Free License version 2.1 9*d2ec54f7Sphitran * 10*d2ec54f7Sphitran * This program is free software; you can redistribute it and/or modify 11*d2ec54f7Sphitran * it under the terms of the GNU General Public License as published by 12*d2ec54f7Sphitran * the Free Software Foundation; either version 2 of the License, or 13*d2ec54f7Sphitran * (at your option) any later version. 14*d2ec54f7Sphitran * 15*d2ec54f7Sphitran * This program is distributed in the hope that it will be useful, 16*d2ec54f7Sphitran * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*d2ec54f7Sphitran * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*d2ec54f7Sphitran * GNU General Public License for more details. 19*d2ec54f7Sphitran * 20*d2ec54f7Sphitran * You should have received a copy of the GNU General Public License 21*d2ec54f7Sphitran * along with this program; if not, write to the Free Software 22*d2ec54f7Sphitran * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23*d2ec54f7Sphitran * 24*d2ec54f7Sphitran **************************************************************************/ 25*d2ec54f7Sphitran 26*d2ec54f7Sphitran 27*d2ec54f7Sphitran #ifdef HAVE_CONFIG_H 28*d2ec54f7Sphitran # include <config.h> 29*d2ec54f7Sphitran #endif 30*d2ec54f7Sphitran 31*d2ec54f7Sphitran #include <stdio.h> 32*d2ec54f7Sphitran #include <string.h> 33*d2ec54f7Sphitran #include <unistd.h> 34*d2ec54f7Sphitran #include <getopt.h> 35*d2ec54f7Sphitran #include <glib.h> 36*d2ec54f7Sphitran #include <stdlib.h> 37*d2ec54f7Sphitran 38*d2ec54f7Sphitran #include <libhal.h> 39*d2ec54f7Sphitran #ifdef HAVE_POLKIT 40*d2ec54f7Sphitran #include <libpolkit.h> 41*d2ec54f7Sphitran #endif 42*d2ec54f7Sphitran 43*d2ec54f7Sphitran /** 44*d2ec54f7Sphitran * usage: 45*d2ec54f7Sphitran * @argc: Number of arguments given to program 46*d2ec54f7Sphitran * @argv: Arguments given to program 47*d2ec54f7Sphitran * 48*d2ec54f7Sphitran * Print out program usage. 49*d2ec54f7Sphitran */ 50*d2ec54f7Sphitran static void 51*d2ec54f7Sphitran usage (int argc, char *argv[]) 52*d2ec54f7Sphitran { 53*d2ec54f7Sphitran fprintf (stderr, 54*d2ec54f7Sphitran "\n" 55*d2ec54f7Sphitran "usage : hal-is-caller-privileged --udi <udi> --action <action>\n" 56*d2ec54f7Sphitran " --caller <caller-name>\n" 57*d2ec54f7Sphitran " [--help] [--version]\n"); 58*d2ec54f7Sphitran fprintf (stderr, 59*d2ec54f7Sphitran "\n" 60*d2ec54f7Sphitran " --udi Unique Device Id\n" 61*d2ec54f7Sphitran " --action PolicyKit action to check for\n" 62*d2ec54f7Sphitran " --caller The name of the caller\n" 63*d2ec54f7Sphitran " --version Show version and exit\n" 64*d2ec54f7Sphitran " --help Show this information and exit\n" 65*d2ec54f7Sphitran "\n" 66*d2ec54f7Sphitran "This program determines if a given process on the system bus is\n" 67*d2ec54f7Sphitran "privileged for a given PolicyKit action for a given device. If an error\n" 68*d2ec54f7Sphitran "occurs this program exits with a non-zero exit code. Otherwise\n" 69*d2ec54f7Sphitran "the textual reply will be printed on stdout and this program will\n" 70*d2ec54f7Sphitran "exit with exit code 0. Note that only the super user (root)\n" 71*d2ec54f7Sphitran "or other privileged users can use this tool.\n" 72*d2ec54f7Sphitran "\n"); 73*d2ec54f7Sphitran } 74*d2ec54f7Sphitran 75*d2ec54f7Sphitran #ifdef HAVE_POLKIT 76*d2ec54f7Sphitran static void 77*d2ec54f7Sphitran permission_denied_privilege (const char *privilege, const char *uid) 78*d2ec54f7Sphitran { 79*d2ec54f7Sphitran fprintf (stderr, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy\n" 80*d2ec54f7Sphitran ); 81*d2ec54f7Sphitran fprintf (stderr, "%s refused uid %s\n", privilege, uid); 82*d2ec54f7Sphitran exit (1); 83*d2ec54f7Sphitran } 84*d2ec54f7Sphitran #endif 85*d2ec54f7Sphitran 86*d2ec54f7Sphitran /** 87*d2ec54f7Sphitran * main: 88*d2ec54f7Sphitran * @argc: Number of arguments given to program 89*d2ec54f7Sphitran * @argv: Arguments given to program 90*d2ec54f7Sphitran * 91*d2ec54f7Sphitran * Returns: Return code 92*d2ec54f7Sphitran * 93*d2ec54f7Sphitran * Main entry point 94*d2ec54f7Sphitran */ 95*d2ec54f7Sphitran int 96*d2ec54f7Sphitran main (int argc, char *argv[]) 97*d2ec54f7Sphitran { 98*d2ec54f7Sphitran char *udi = NULL; 99*d2ec54f7Sphitran char *action = NULL; 100*d2ec54f7Sphitran char *caller = NULL; 101*d2ec54f7Sphitran dbus_bool_t is_version = FALSE; 102*d2ec54f7Sphitran DBusError error; 103*d2ec54f7Sphitran #ifdef HAVE_POLKIT 104*d2ec54f7Sphitran LibPolKitContext *pol_ctx = NULL; 105*d2ec54f7Sphitran #endif 106*d2ec54f7Sphitran DBusConnection *system_bus = NULL; 107*d2ec54f7Sphitran uid_t calling_uid; 108*d2ec54f7Sphitran char *privilege = NULL; 109*d2ec54f7Sphitran const char *invoked_by_uid; 110*d2ec54f7Sphitran gboolean allowed_by_privilege = FALSE; 111*d2ec54f7Sphitran gboolean is_temporary_privilege; 112*d2ec54f7Sphitran 113*d2ec54f7Sphitran if (argc <= 1) { 114*d2ec54f7Sphitran usage (argc, argv); 115*d2ec54f7Sphitran return 1; 116*d2ec54f7Sphitran } 117*d2ec54f7Sphitran 118*d2ec54f7Sphitran while (1) { 119*d2ec54f7Sphitran int c; 120*d2ec54f7Sphitran int option_index = 0; 121*d2ec54f7Sphitran const char *opt; 122*d2ec54f7Sphitran static struct option long_options[] = { 123*d2ec54f7Sphitran {"udi", 1, NULL, 0}, 124*d2ec54f7Sphitran {"action", 1, NULL, 0}, 125*d2ec54f7Sphitran {"caller", 1, NULL, 0}, 126*d2ec54f7Sphitran {"version", 0, NULL, 0}, 127*d2ec54f7Sphitran {"help", 0, NULL, 0}, 128*d2ec54f7Sphitran {NULL, 0, NULL, 0} 129*d2ec54f7Sphitran }; 130*d2ec54f7Sphitran 131*d2ec54f7Sphitran c = getopt_long (argc, argv, "", 132*d2ec54f7Sphitran long_options, &option_index); 133*d2ec54f7Sphitran if (c == -1) 134*d2ec54f7Sphitran break; 135*d2ec54f7Sphitran 136*d2ec54f7Sphitran switch (c) { 137*d2ec54f7Sphitran case 0: 138*d2ec54f7Sphitran opt = long_options[option_index].name; 139*d2ec54f7Sphitran 140*d2ec54f7Sphitran if (strcmp (opt, "help") == 0) { 141*d2ec54f7Sphitran usage (argc, argv); 142*d2ec54f7Sphitran return 0; 143*d2ec54f7Sphitran } else if (strcmp (opt, "version") == 0) { 144*d2ec54f7Sphitran is_version = TRUE; 145*d2ec54f7Sphitran } else if (strcmp (opt, "udi") == 0) { 146*d2ec54f7Sphitran udi = strdup (optarg); 147*d2ec54f7Sphitran } else if (strcmp (opt, "caller") == 0) { 148*d2ec54f7Sphitran caller = strdup (optarg); 149*d2ec54f7Sphitran } else if (strcmp (opt, "action") == 0) { 150*d2ec54f7Sphitran privilege = strdup (optarg); 151*d2ec54f7Sphitran } 152*d2ec54f7Sphitran break; 153*d2ec54f7Sphitran 154*d2ec54f7Sphitran default: 155*d2ec54f7Sphitran usage (argc, argv); 156*d2ec54f7Sphitran return 1; 157*d2ec54f7Sphitran break; 158*d2ec54f7Sphitran } 159*d2ec54f7Sphitran } 160*d2ec54f7Sphitran 161*d2ec54f7Sphitran if (is_version) { 162*d2ec54f7Sphitran printf ("hal-is-caller-privileged " PACKAGE_VERSION "\n"); 163*d2ec54f7Sphitran return 0; 164*d2ec54f7Sphitran } 165*d2ec54f7Sphitran 166*d2ec54f7Sphitran if (udi == NULL || caller == NULL || privilege == NULL) { 167*d2ec54f7Sphitran usage (argc, argv); 168*d2ec54f7Sphitran return 1; 169*d2ec54f7Sphitran } 170*d2ec54f7Sphitran 171*d2ec54f7Sphitran dbus_error_init (&error); 172*d2ec54f7Sphitran system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error); 173*d2ec54f7Sphitran if (system_bus == NULL) { 174*d2ec54f7Sphitran printf ("Cannot connect to the system bus\n"); 175*d2ec54f7Sphitran LIBHAL_FREE_DBUS_ERROR (&error); 176*d2ec54f7Sphitran fprintf (stderr, "This program should only be started by hald.\n"); 177*d2ec54f7Sphitran exit (1); 178*d2ec54f7Sphitran } 179*d2ec54f7Sphitran 180*d2ec54f7Sphitran #ifdef HAVE_POLKIT 181*d2ec54f7Sphitran pol_ctx = libpolkit_new_context (system_bus); 182*d2ec54f7Sphitran if (pol_ctx == NULL) { 183*d2ec54f7Sphitran printf ("Cannot get libpolkit context\n"); 184*d2ec54f7Sphitran } 185*d2ec54f7Sphitran invoked_by_uid = getenv("HAL_METHOD_INVOKED_BY_UID"); 186*d2ec54f7Sphitran 187*d2ec54f7Sphitran if (libpolkit_is_uid_allowed_for_privilege (pol_ctx, 188*d2ec54f7Sphitran caller, 189*d2ec54f7Sphitran invoked_by_uid, 190*d2ec54f7Sphitran privilege, 191*d2ec54f7Sphitran udi, 192*d2ec54f7Sphitran &allowed_by_privilege, 193*d2ec54f7Sphitran &is_temporary_privilege, 194*d2ec54f7Sphitran NULL) != LIBPOLKIT_RESULT_OK 195*d2ec54f7Sphitran ) { 196*d2ec54f7Sphitran printf ("cannot lookup privilege\n"); 197*d2ec54f7Sphitran fprintf (stderr, "Cannot lookup privilege from PolicyKit"); 198*d2ec54f7Sphitran exit (1); 199*d2ec54f7Sphitran } 200*d2ec54f7Sphitran 201*d2ec54f7Sphitran if (!allowed_by_privilege) { 202*d2ec54f7Sphitran printf ("caller don't possess privilege\n"); 203*d2ec54f7Sphitran permission_denied_privilege (privilege, invoked_by_uid); 204*d2ec54f7Sphitran } 205*d2ec54f7Sphitran #endif 206*d2ec54f7Sphitran 207*d2ec54f7Sphitran printf("yes\n"); 208*d2ec54f7Sphitran return 0; 209*d2ec54f7Sphitran } 210