libpolkit-rbac.c revision 6654:e02478f0bcde
1/***************************************************************************
2 *
3 * libpolkit-rbac.c : RBAC implementation of the libpolkit API
4 *
5 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
6 * Use is subject to license terms.
7 *
8 * Licensed under the Academic Free License version 2.1
9 *
10 **************************************************************************/
11
12#pragma ident	"%Z%%M%	%I%	%E% SMI"
13
14#ifdef HAVE_CONFIG_H
15#  include <config.h>
16#endif
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/types.h>
22#include <pwd.h>
23#include <grp.h>
24#include <unistd.h>
25#include <errno.h>
26#include <auth_attr.h>
27#include <secdb.h>
28
29#include <glib.h>
30#include <dbus/dbus-glib.h>
31
32#include "libpolkit.h"
33
34#define LIBPOLKIT_MAGIC 0x3117beef
35
36#ifdef __SUNPRO_C
37#define __FUNCTION__ __func__
38#endif
39
40#define LIBPOLKIT_CHECK_CONTEXT(_ctx_, _ret_)				\
41	do {									\
42		if (_ctx_ == NULL) {						\
43			g_warning ("%s: given LibPolKitContext is NULL",     \
44				   __FUNCTION__);			        \
45			return _ret_;					        \
46		}								\
47		if (_ctx_->magic != LIBPOLKIT_MAGIC) {			\
48			g_warning ("%s: given LibPolKitContext is invalid (read magic 0x%08x, should be 0x%08x)",  \
49				   __FUNCTION__, _ctx_->magic, LIBPOLKIT_MAGIC);	\
50			return _ret_;					        \
51		}								\
52	} while(0)
53
54
55struct LibPolKitContext_s
56{
57	guint32 magic;
58};
59
60/** Get a new context.
61 *
62 *  @return                     Pointer to new context or NULL if an error occured
63 */
64LibPolKitContext *
65libpolkit_new_context (DBusConnection *connection)
66{
67	LibPolKitContext *ctx;
68
69	ctx = g_new0 (LibPolKitContext, 1);
70	ctx->magic = LIBPOLKIT_MAGIC;
71
72	return ctx;
73}
74
75/** Free a context
76 *
77 *  @param  ctx                 The context obtained from libpolkit_new_context
78 *  @return                     Pointer to new context or NULL if an error occured
79 */
80gboolean
81libpolkit_free_context (LibPolKitContext *ctx)
82{
83	LIBPOLKIT_CHECK_CONTEXT (ctx, FALSE);
84
85	ctx->magic = 0;
86	g_free (ctx);
87	return TRUE;
88}
89
90LibPolKitResult
91libpolkit_get_allowed_resources_for_privilege_for_uid (LibPolKitContext    *ctx,
92						       const char          *user,
93						       const char          *privilege,
94						       GList              **resources,
95						       GList              **restrictions,
96						       int                 *num_non_temporary)
97{
98	LibPolKitResult res;
99	char **resource_list;
100	int num_resources;
101	char **restriction_list;
102	int num_restrictions;
103
104	LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
105
106	res = LIBPOLKIT_RESULT_ERROR;
107	*resources = NULL;
108	*restrictions = NULL;
109
110	res = LIBPOLKIT_RESULT_OK;
111
112	return res;
113}
114
115LibPolKitResult
116libpolkit_is_uid_allowed_for_privilege (LibPolKitContext   *ctx,
117					const char         *system_bus_unique_name,
118					const char         *user,
119					const char         *privilege,
120					const char         *resource,
121					gboolean           *out_is_allowed,
122					gboolean           *out_is_temporary,
123					char              **out_is_privileged_but_restricted_to_system_bus_unique_name)
124{
125	LibPolKitResult res;
126	const char *myresource = "";
127	const char *mysystem_bus_unique_name = "";
128	char *but_restricted_to = NULL;
129	uid_t uid;
130	struct passwd *pw;
131	char *authname;
132	int i;
133	gboolean authname_free = FALSE;
134
135	LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
136
137	uid = (uid_t)atol (user);
138	if ((pw = getpwuid (uid)) == NULL) {
139		*out_is_allowed = FALSE;
140		*out_is_temporary = FALSE;
141		return LIBPOLKIT_RESULT_NO_SUCH_USER;
142	}
143
144	/* map PolicyKit privilege to RBAC authorization */
145	if (strcmp (privilege, "hal-storage-removable-mount") == 0) {
146		authname = "solaris.device.mount.removable";
147	} else if (strcmp (privilege, "hal-storage-removable-mount-all-options") == 0) {
148		authname = "solaris.device.mount.alloptions.removable";
149	} else if (strcmp (privilege, "hal-storage-fixed-mount") == 0) {
150		authname = "solaris.device.mount.fixed";
151	} else if (strcmp (privilege, "hal-storage-fixed-mount-all-options") == 0) {
152		authname = "solaris.device.mount.alloptions.fixed";
153	} else if (strcmp(privilege, "hal-power-suspend") == 0) {
154		authname = "solaris.system.power.suspend.ram";
155	} else if (strcmp(privilege, "hal-power-hibernate") == 0) {
156                authname = "solaris.system.power.suspend.disk";
157	} else if ((strcmp(privilege, "hal-power-shutdown") == 0) ||
158	    (strcmp(privilege, "hal-power-reboot") == 0)) {
159                authname = "solaris.system.shutdown";
160	} else if (strcmp(privilege, "hal-power-cpu") == 0) {
161                authname = "solaris.system.power.cpu";
162	} else if (strcmp(privilege, "hal-power-brightness") == 0) {
163                authname = "solaris.system.power.brightness";
164	} else if (strcmp (privilege, "hal-power-cpu") == 0) {
165		authname = "solaris.system.power.cpu";
166	} else {
167		/* replace '-' with '.' */
168		authname = g_strdup (privilege);
169		authname_free = TRUE;
170		for (i = 0; i < strlen (authname); i++) {
171			if (authname[i] == '-') {
172				authname[i] = '.';
173			}
174		}
175	}
176
177	*out_is_allowed = (chkauthattr(authname, pw->pw_name) != 0);
178	*out_is_temporary = FALSE;
179
180	if (authname_free) {
181		g_free(authname);
182	}
183
184	return LIBPOLKIT_RESULT_OK;
185}
186
187LibPolKitResult
188libpolkit_get_privilege_list (LibPolKitContext      *ctx,
189			      GList                **result)
190{
191	LibPolKitResult res;
192	char **privilege_list;
193	int num_privileges = 0;
194	int i;
195
196	LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
197
198	*result = NULL;
199
200	for (i = 0; i < num_privileges; i++) {
201		*result = g_list_append (*result, g_strdup (privilege_list[i]));
202	}
203
204	res = LIBPOLKIT_RESULT_OK;
205
206	return res;
207}
208
209LibPolKitResult
210libpolkit_revoke_temporary_privilege (LibPolKitContext      *ctx,
211                                      const char            *user,
212                                      const char            *privilege,
213                                      const char            *resource,
214                                      gboolean              *result)
215{
216	return LIBPOLKIT_RESULT_OK;
217}
218