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 55 struct 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 */ 64 LibPolKitContext * 65 libpolkit_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 */ 80 gboolean 81 libpolkit_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 90 LibPolKitResult 91 libpolkit_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 115 LibPolKitResult 116 libpolkit_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 { 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