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