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 * 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 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 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 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 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 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