xref: /illumos-gate/usr/src/cmd/policykit/polkit-is-privileged.c (revision b12258b69ac245658b0ca5ae070b3ff004186148)
1 /***************************************************************************
2  * CVSID: $Id$
3  *
4  * polkit-is-privileged.c : Determine if a user has privileges
5  *
6  * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  **************************************************************************/
23 
24 /*
25  * Copyright (c) 2018, Joyent, Inc.
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #  include <config.h>
30 #endif
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <getopt.h>
35 #include <dbus/dbus.h>
36 
37 #include <libpolkit/libpolkit.h>
38 
39 static void
40 usage (int argc, char *argv[])
41 {
42 	fprintf (stderr, "polkit-is-privileged version " PACKAGE_VERSION "\n");
43 
44 	fprintf (stderr,
45 		 "\n"
46 		 "usage : %s -u <uid> -p <privilege> [-r <resource>]\n"
47 		 "        [-s <system-bus-connection-name>]", argv[0]);
48 	fprintf (stderr,
49 		 "\n"
50 		 "Options:\n"
51 		 "    -u, --user                    Username or user id\n"
52 		 "    -s, --system-bus-unique-name  Unique system bus connection name\n"
53 		 "    -r, --resource                Resource\n"
54 		 "    -p, --privilege               Privilege to test for\n"
55 		 "    -h, --help                    Show this information and exit\n"
56 		 "    -v, --verbose                 Verbose operation\n"
57 		 "    -V, --version                 Print version number\n"
58 		 "\n"
59 		 "Queries system policy whether a given user is allowed for a given\n"
60 		 "privilege for a given resource. The resource may be omitted.\n"
61 		 "\n");
62 }
63 
64 int
65 main (int argc, char *argv[])
66 {
67 	int rc;
68 	char *user = NULL;
69 	char *privilege = NULL;
70 	char *resource = NULL;
71 	char *system_bus_unique_name = NULL;
72 	static const struct option long_options[] = {
73 		{"user", required_argument, NULL, 'u'},
74 		{"system-bus-unique-name", required_argument, NULL, 's'},
75 		{"resource", required_argument, NULL, 'r'},
76 		{"privilege", required_argument, NULL, 'p'},
77 		{"help", no_argument, NULL, 'h'},
78 		{"verbose", no_argument, NULL, 'v'},
79 		{"version", no_argument, NULL, 'V'},
80 		{NULL, 0, NULL, 0}
81 	};
82 	LibPolKitContext *ctx = NULL;
83 	gboolean is_allowed;
84 	gboolean is_temporary;
85 	LibPolKitResult result;
86 	gboolean is_verbose = FALSE;
87 	DBusError error;
88 	DBusConnection *connection = NULL;
89 
90 	rc = 1;
91 
92 	while (TRUE) {
93 		int c;
94 
95 		c = getopt_long (argc, argv, "u:r:p:s:hVv", long_options, NULL);
96 
97 		if (c == -1)
98 			break;
99 
100 		switch (c) {
101 		case 's':
102 			system_bus_unique_name = g_strdup (optarg);
103 			break;
104 
105 		case 'u':
106 			user = g_strdup (optarg);
107 			break;
108 
109 		case 'r':
110 			resource = g_strdup (optarg);
111 			break;
112 
113 		case 'p':
114 			privilege = g_strdup (optarg);
115 			break;
116 
117 		case 'v':
118 			is_verbose = TRUE;
119 			break;
120 
121 		case 'h':
122 			usage (argc, argv);
123 			rc = 0;
124 			goto out;
125 
126 		case 'V':
127 			printf ("polkit-is-privileged version " PACKAGE_VERSION "\n");
128 			rc = 0;
129 			goto out;
130 
131 		default:
132 			usage (argc, argv);
133 			goto out;
134 		}
135 	}
136 
137 	if (user == NULL || privilege == NULL) {
138 		usage (argc, argv);
139 		return 1;
140 	}
141 
142 	if (is_verbose) {
143 		printf ("user      = '%s'\n", user);
144 		printf ("privilege = '%s'\n", privilege);
145 		if (resource != NULL)
146 			printf ("resource  = '%s'\n", resource);
147 	}
148 
149 #ifdef POLKITD_ENABLED
150 	dbus_error_init (&error);
151 	connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
152 	if (connection == NULL) {
153 		g_warning ("Cannot connect to system message bus");
154 		return 1;
155 	}
156 #endif /* POLKITD_ENABLED */
157 
158 	ctx = libpolkit_new_context (connection);
159 	if (ctx == NULL) {
160 		g_warning ("Cannot get libpolkit context");
161 		goto out;
162 	}
163 
164 	result = libpolkit_is_uid_allowed_for_privilege (ctx,
165 							 system_bus_unique_name,
166 							 user,
167 							 privilege,
168 							 resource,
169 							 &is_allowed,
170 							 &is_temporary,
171 							 NULL);
172 	switch (result) {
173 	case LIBPOLKIT_RESULT_OK:
174 		rc = is_allowed ? 0 : 1;
175 		break;
176 
177 	case LIBPOLKIT_RESULT_ERROR:
178 		g_warning ("Error determing whether user is privileged.");
179 		break;
180 
181 	case LIBPOLKIT_RESULT_INVALID_CONTEXT:
182 		g_print ("Invalid context.\n");
183 		goto out;
184 
185 	case LIBPOLKIT_RESULT_NOT_PRIVILEGED:
186 		g_print ("Not privileged.\n");
187 		goto out;
188 
189 	case LIBPOLKIT_RESULT_NO_SUCH_PRIVILEGE:
190 		g_print ("No such privilege '%s'.\n", privilege);
191 		goto out;
192 
193 	case LIBPOLKIT_RESULT_NO_SUCH_USER:
194 		g_print ("No such user '%s'.\n", user);
195 		goto out;
196 	}
197 
198 	if (is_verbose) {
199 		printf ("result %d\n", result);
200 		printf ("is_allowed %d\n", is_allowed);
201 	}
202 
203 out:
204 	if (ctx != NULL)
205 		(void) libpolkit_free_context (ctx);
206 
207 	return rc;
208 }
209 
210