xref: /titanic_51/usr/src/cmd/hal/tools/hal-is-caller-privileged.c (revision d2ec54f7875f7e05edd56195adbeb593c947763f)
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