118c2aff7Sartem /***************************************************************************
218c2aff7Sartem  * CVSID: $Id$
318c2aff7Sartem  *
418c2aff7Sartem  * polkit-is-privileged.c : Determine if a user has privileges
518c2aff7Sartem  *
618c2aff7Sartem  * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
718c2aff7Sartem  *
818c2aff7Sartem  * This program is free software; you can redistribute it and/or modify
918c2aff7Sartem  * it under the terms of the GNU General Public License as published by
1018c2aff7Sartem  * the Free Software Foundation; either version 2 of the License, or
1118c2aff7Sartem  * (at your option) any later version.
1218c2aff7Sartem  *
1318c2aff7Sartem  * This program is distributed in the hope that it will be useful,
1418c2aff7Sartem  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1518c2aff7Sartem  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1618c2aff7Sartem  * GNU General Public License for more details.
1718c2aff7Sartem  *
1818c2aff7Sartem  * You should have received a copy of the GNU General Public License
1918c2aff7Sartem  * along with this program; if not, write to the Free Software
2018c2aff7Sartem  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
2118c2aff7Sartem  *
2218c2aff7Sartem  **************************************************************************/
2318c2aff7Sartem 
24d1c9087bSJohn Levon /*
25d1c9087bSJohn Levon  * Copyright (c) 2018, Joyent, Inc.
26d1c9087bSJohn Levon  */
2718c2aff7Sartem 
2818c2aff7Sartem #ifdef HAVE_CONFIG_H
2918c2aff7Sartem #  include <config.h>
3018c2aff7Sartem #endif
3118c2aff7Sartem 
3218c2aff7Sartem #include <stdio.h>
3318c2aff7Sartem #include <stdlib.h>
3418c2aff7Sartem #include <getopt.h>
3518c2aff7Sartem #include <dbus/dbus.h>
3618c2aff7Sartem 
3718c2aff7Sartem #include <libpolkit/libpolkit.h>
3818c2aff7Sartem 
3918c2aff7Sartem static void
usage(int argc,char * argv[])4018c2aff7Sartem usage (int argc, char *argv[])
4118c2aff7Sartem {
4218c2aff7Sartem 	fprintf (stderr, "polkit-is-privileged version " PACKAGE_VERSION "\n");
4318c2aff7Sartem 
44*55fea89dSDan Cross 	fprintf (stderr,
45*55fea89dSDan Cross 		 "\n"
46*55fea89dSDan Cross 		 "usage : %s -u <uid> -p <privilege> [-r <resource>]\n"
4718c2aff7Sartem 		 "        [-s <system-bus-connection-name>]", argv[0]);
4818c2aff7Sartem 	fprintf (stderr,
4918c2aff7Sartem 		 "\n"
5018c2aff7Sartem 		 "Options:\n"
5118c2aff7Sartem 		 "    -u, --user                    Username or user id\n"
5218c2aff7Sartem 		 "    -s, --system-bus-unique-name  Unique system bus connection name\n"
5318c2aff7Sartem 		 "    -r, --resource                Resource\n"
5418c2aff7Sartem 		 "    -p, --privilege               Privilege to test for\n"
5518c2aff7Sartem 		 "    -h, --help                    Show this information and exit\n"
5618c2aff7Sartem 		 "    -v, --verbose                 Verbose operation\n"
5718c2aff7Sartem 		 "    -V, --version                 Print version number\n"
5818c2aff7Sartem 		 "\n"
5918c2aff7Sartem 		 "Queries system policy whether a given user is allowed for a given\n"
6018c2aff7Sartem 		 "privilege for a given resource. The resource may be omitted.\n"
6118c2aff7Sartem 		 "\n");
6218c2aff7Sartem }
6318c2aff7Sartem 
64*55fea89dSDan Cross int
main(int argc,char * argv[])6518c2aff7Sartem main (int argc, char *argv[])
6618c2aff7Sartem {
6718c2aff7Sartem 	int rc;
6818c2aff7Sartem 	char *user = NULL;
6918c2aff7Sartem 	char *privilege = NULL;
7018c2aff7Sartem 	char *resource = NULL;
7118c2aff7Sartem 	char *system_bus_unique_name = NULL;
7218c2aff7Sartem 	static const struct option long_options[] = {
7318c2aff7Sartem 		{"user", required_argument, NULL, 'u'},
7418c2aff7Sartem 		{"system-bus-unique-name", required_argument, NULL, 's'},
7518c2aff7Sartem 		{"resource", required_argument, NULL, 'r'},
7618c2aff7Sartem 		{"privilege", required_argument, NULL, 'p'},
7718c2aff7Sartem 		{"help", no_argument, NULL, 'h'},
7818c2aff7Sartem 		{"verbose", no_argument, NULL, 'v'},
7918c2aff7Sartem 		{"version", no_argument, NULL, 'V'},
8018c2aff7Sartem 		{NULL, 0, NULL, 0}
8118c2aff7Sartem 	};
8218c2aff7Sartem 	LibPolKitContext *ctx = NULL;
8318c2aff7Sartem 	gboolean is_allowed;
8418c2aff7Sartem 	gboolean is_temporary;
8518c2aff7Sartem 	LibPolKitResult result;
8618c2aff7Sartem 	gboolean is_verbose = FALSE;
8718c2aff7Sartem 	DBusError error;
8818c2aff7Sartem 	DBusConnection *connection = NULL;
8918c2aff7Sartem 
9018c2aff7Sartem 	rc = 1;
91*55fea89dSDan Cross 
9218c2aff7Sartem 	while (TRUE) {
9318c2aff7Sartem 		int c;
94*55fea89dSDan Cross 
9518c2aff7Sartem 		c = getopt_long (argc, argv, "u:r:p:s:hVv", long_options, NULL);
9618c2aff7Sartem 
9718c2aff7Sartem 		if (c == -1)
9818c2aff7Sartem 			break;
99*55fea89dSDan Cross 
10018c2aff7Sartem 		switch (c) {
10118c2aff7Sartem 		case 's':
10218c2aff7Sartem 			system_bus_unique_name = g_strdup (optarg);
10318c2aff7Sartem 			break;
10418c2aff7Sartem 
10518c2aff7Sartem 		case 'u':
10618c2aff7Sartem 			user = g_strdup (optarg);
10718c2aff7Sartem 			break;
108*55fea89dSDan Cross 
10918c2aff7Sartem 		case 'r':
11018c2aff7Sartem 			resource = g_strdup (optarg);
11118c2aff7Sartem 			break;
112*55fea89dSDan Cross 
11318c2aff7Sartem 		case 'p':
11418c2aff7Sartem 			privilege = g_strdup (optarg);
11518c2aff7Sartem 			break;
116*55fea89dSDan Cross 
11718c2aff7Sartem 		case 'v':
11818c2aff7Sartem 			is_verbose = TRUE;
11918c2aff7Sartem 			break;
12018c2aff7Sartem 
12118c2aff7Sartem 		case 'h':
12218c2aff7Sartem 			usage (argc, argv);
12318c2aff7Sartem 			rc = 0;
12418c2aff7Sartem 			goto out;
12518c2aff7Sartem 
12618c2aff7Sartem 		case 'V':
12718c2aff7Sartem 			printf ("polkit-is-privileged version " PACKAGE_VERSION "\n");
12818c2aff7Sartem 			rc = 0;
12918c2aff7Sartem 			goto out;
130*55fea89dSDan Cross 
13118c2aff7Sartem 		default:
13218c2aff7Sartem 			usage (argc, argv);
13318c2aff7Sartem 			goto out;
13418c2aff7Sartem 		}
13518c2aff7Sartem 	}
13618c2aff7Sartem 
13718c2aff7Sartem 	if (user == NULL || privilege == NULL) {
13818c2aff7Sartem 		usage (argc, argv);
13918c2aff7Sartem 		return 1;
14018c2aff7Sartem 	}
14118c2aff7Sartem 
14218c2aff7Sartem 	if (is_verbose) {
14318c2aff7Sartem 		printf ("user      = '%s'\n", user);
14418c2aff7Sartem 		printf ("privilege = '%s'\n", privilege);
14518c2aff7Sartem 		if (resource != NULL)
14618c2aff7Sartem 			printf ("resource  = '%s'\n", resource);
14718c2aff7Sartem 	}
14818c2aff7Sartem 
14918c2aff7Sartem #ifdef POLKITD_ENABLED
15018c2aff7Sartem 	dbus_error_init (&error);
15118c2aff7Sartem 	connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
15218c2aff7Sartem 	if (connection == NULL) {
15318c2aff7Sartem 		g_warning ("Cannot connect to system message bus");
15418c2aff7Sartem 		return 1;
15518c2aff7Sartem 	}
15618c2aff7Sartem #endif /* POLKITD_ENABLED */
15718c2aff7Sartem 
15818c2aff7Sartem 	ctx = libpolkit_new_context (connection);
15918c2aff7Sartem 	if (ctx == NULL) {
16018c2aff7Sartem 		g_warning ("Cannot get libpolkit context");
16118c2aff7Sartem 		goto out;
16218c2aff7Sartem 	}
16318c2aff7Sartem 
164*55fea89dSDan Cross 	result = libpolkit_is_uid_allowed_for_privilege (ctx,
16518c2aff7Sartem 							 system_bus_unique_name,
16618c2aff7Sartem 							 user,
16718c2aff7Sartem 							 privilege,
16818c2aff7Sartem 							 resource,
16918c2aff7Sartem 							 &is_allowed,
17018c2aff7Sartem 							 &is_temporary,
17118c2aff7Sartem 							 NULL);
17218c2aff7Sartem 	switch (result) {
17318c2aff7Sartem 	case LIBPOLKIT_RESULT_OK:
17418c2aff7Sartem 		rc = is_allowed ? 0 : 1;
17518c2aff7Sartem 		break;
17618c2aff7Sartem 
17718c2aff7Sartem 	case LIBPOLKIT_RESULT_ERROR:
17818c2aff7Sartem 		g_warning ("Error determing whether user is privileged.");
17918c2aff7Sartem 		break;
18018c2aff7Sartem 
18118c2aff7Sartem 	case LIBPOLKIT_RESULT_INVALID_CONTEXT:
18218c2aff7Sartem 		g_print ("Invalid context.\n");
18318c2aff7Sartem 		goto out;
18418c2aff7Sartem 
18518c2aff7Sartem 	case LIBPOLKIT_RESULT_NOT_PRIVILEGED:
18618c2aff7Sartem 		g_print ("Not privileged.\n");
187f7c0c795SToomas Soome 		goto out;
18818c2aff7Sartem 
18918c2aff7Sartem 	case LIBPOLKIT_RESULT_NO_SUCH_PRIVILEGE:
19018c2aff7Sartem 		g_print ("No such privilege '%s'.\n", privilege);
19118c2aff7Sartem 		goto out;
19218c2aff7Sartem 
19318c2aff7Sartem 	case LIBPOLKIT_RESULT_NO_SUCH_USER:
19418c2aff7Sartem 		g_print ("No such user '%s'.\n", user);
19518c2aff7Sartem 		goto out;
19618c2aff7Sartem 	}
19718c2aff7Sartem 
19818c2aff7Sartem 	if (is_verbose) {
19918c2aff7Sartem 		printf ("result %d\n", result);
20018c2aff7Sartem 		printf ("is_allowed %d\n", is_allowed);
20118c2aff7Sartem 	}
20218c2aff7Sartem 
20318c2aff7Sartem out:
20418c2aff7Sartem 	if (ctx != NULL)
205d1c9087bSJohn Levon 		(void) libpolkit_free_context (ctx);
20618c2aff7Sartem 
20718c2aff7Sartem 	return rc;
20818c2aff7Sartem }
20918c2aff7Sartem 
210