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