12912Sartem /***************************************************************************
22912Sartem *
32912Sartem * libpolkit-rbac.c : RBAC implementation of the libpolkit API
42912Sartem *
56573Sphitran * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
62912Sartem * Use is subject to license terms.
72912Sartem *
82912Sartem * Licensed under the Academic Free License version 2.1
92912Sartem *
102912Sartem **************************************************************************/
112912Sartem
122916Sartem #pragma ident "%Z%%M% %I% %E% SMI"
132912Sartem
142912Sartem #ifdef HAVE_CONFIG_H
152912Sartem # include <config.h>
162912Sartem #endif
172912Sartem
182912Sartem #include <stdio.h>
192912Sartem #include <stdlib.h>
202912Sartem #include <string.h>
212912Sartem #include <sys/types.h>
222912Sartem #include <pwd.h>
232912Sartem #include <grp.h>
242912Sartem #include <unistd.h>
252912Sartem #include <errno.h>
262912Sartem #include <auth_attr.h>
272912Sartem #include <secdb.h>
282912Sartem
292912Sartem #include <glib.h>
302912Sartem #include <dbus/dbus-glib.h>
312912Sartem
322912Sartem #include "libpolkit.h"
332912Sartem
342912Sartem #define LIBPOLKIT_MAGIC 0x3117beef
352912Sartem
362912Sartem #ifdef __SUNPRO_C
372912Sartem #define __FUNCTION__ __func__
382912Sartem #endif
392912Sartem
402912Sartem #define LIBPOLKIT_CHECK_CONTEXT(_ctx_, _ret_) \
412912Sartem do { \
422912Sartem if (_ctx_ == NULL) { \
432912Sartem g_warning ("%s: given LibPolKitContext is NULL", \
442912Sartem __FUNCTION__); \
452912Sartem return _ret_; \
462912Sartem } \
472912Sartem if (_ctx_->magic != LIBPOLKIT_MAGIC) { \
482912Sartem g_warning ("%s: given LibPolKitContext is invalid (read magic 0x%08x, should be 0x%08x)", \
492912Sartem __FUNCTION__, _ctx_->magic, LIBPOLKIT_MAGIC); \
502912Sartem return _ret_; \
512912Sartem } \
522912Sartem } while(0)
532912Sartem
542912Sartem
552912Sartem struct LibPolKitContext_s
562912Sartem {
572912Sartem guint32 magic;
582912Sartem };
592912Sartem
602912Sartem /** Get a new context.
612912Sartem *
622912Sartem * @return Pointer to new context or NULL if an error occured
632912Sartem */
642912Sartem LibPolKitContext *
libpolkit_new_context(DBusConnection * connection)652912Sartem libpolkit_new_context (DBusConnection *connection)
662912Sartem {
672912Sartem LibPolKitContext *ctx;
682912Sartem
692912Sartem ctx = g_new0 (LibPolKitContext, 1);
702912Sartem ctx->magic = LIBPOLKIT_MAGIC;
712912Sartem
722912Sartem return ctx;
732912Sartem }
742912Sartem
752912Sartem /** Free a context
762912Sartem *
772912Sartem * @param ctx The context obtained from libpolkit_new_context
782912Sartem * @return Pointer to new context or NULL if an error occured
792912Sartem */
802912Sartem gboolean
libpolkit_free_context(LibPolKitContext * ctx)812912Sartem libpolkit_free_context (LibPolKitContext *ctx)
822912Sartem {
832912Sartem LIBPOLKIT_CHECK_CONTEXT (ctx, FALSE);
842912Sartem
852912Sartem ctx->magic = 0;
862912Sartem g_free (ctx);
872912Sartem return TRUE;
882912Sartem }
892912Sartem
902912Sartem 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)912912Sartem libpolkit_get_allowed_resources_for_privilege_for_uid (LibPolKitContext *ctx,
922912Sartem const char *user,
932912Sartem const char *privilege,
942912Sartem GList **resources,
952912Sartem GList **restrictions,
962912Sartem int *num_non_temporary)
972912Sartem {
982912Sartem LibPolKitResult res;
992912Sartem char **resource_list;
1002912Sartem int num_resources;
1012912Sartem char **restriction_list;
1022912Sartem int num_restrictions;
1032912Sartem
1042912Sartem LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
1052912Sartem
1062912Sartem res = LIBPOLKIT_RESULT_ERROR;
1072912Sartem *resources = NULL;
1082912Sartem *restrictions = NULL;
1092912Sartem
1102912Sartem res = LIBPOLKIT_RESULT_OK;
1112912Sartem
1122912Sartem return res;
1132912Sartem }
1142912Sartem
1152912Sartem 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)1162912Sartem libpolkit_is_uid_allowed_for_privilege (LibPolKitContext *ctx,
1172912Sartem const char *system_bus_unique_name,
1182912Sartem const char *user,
1192912Sartem const char *privilege,
1202912Sartem const char *resource,
1212912Sartem gboolean *out_is_allowed,
1222912Sartem gboolean *out_is_temporary,
1232912Sartem char **out_is_privileged_but_restricted_to_system_bus_unique_name)
1242912Sartem {
1252912Sartem LibPolKitResult res;
1262912Sartem const char *myresource = "";
1272912Sartem const char *mysystem_bus_unique_name = "";
1282912Sartem char *but_restricted_to = NULL;
1292912Sartem uid_t uid;
1302912Sartem struct passwd *pw;
1312912Sartem char *authname;
1322912Sartem int i;
1332912Sartem gboolean authname_free = FALSE;
1342912Sartem
1352912Sartem LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
1362912Sartem
1372912Sartem uid = (uid_t)atol (user);
1382912Sartem if ((pw = getpwuid (uid)) == NULL) {
1392912Sartem *out_is_allowed = FALSE;
1402912Sartem *out_is_temporary = FALSE;
1412912Sartem return LIBPOLKIT_RESULT_NO_SUCH_USER;
1422912Sartem }
1432912Sartem
1442912Sartem /* map PolicyKit privilege to RBAC authorization */
1452912Sartem if (strcmp (privilege, "hal-storage-removable-mount") == 0) {
1462912Sartem authname = "solaris.device.mount.removable";
1472912Sartem } else if (strcmp (privilege, "hal-storage-removable-mount-all-options") == 0) {
1482912Sartem authname = "solaris.device.mount.alloptions.removable";
1492912Sartem } else if (strcmp (privilege, "hal-storage-fixed-mount") == 0) {
1502912Sartem authname = "solaris.device.mount.fixed";
1512912Sartem } else if (strcmp (privilege, "hal-storage-fixed-mount-all-options") == 0) {
1522912Sartem authname = "solaris.device.mount.alloptions.fixed";
1536573Sphitran } else if (strcmp(privilege, "hal-power-suspend") == 0) {
1546573Sphitran authname = "solaris.system.power.suspend.ram";
1556573Sphitran } else if (strcmp(privilege, "hal-power-hibernate") == 0) {
1566573Sphitran authname = "solaris.system.power.suspend.disk";
1576573Sphitran } else if ((strcmp(privilege, "hal-power-shutdown") == 0) ||
1586573Sphitran (strcmp(privilege, "hal-power-reboot") == 0)) {
1596573Sphitran authname = "solaris.system.shutdown";
1606573Sphitran } else if (strcmp(privilege, "hal-power-cpu") == 0) {
1616573Sphitran authname = "solaris.system.power.cpu";
1626573Sphitran } else if (strcmp(privilege, "hal-power-brightness") == 0) {
1636573Sphitran authname = "solaris.system.power.brightness";
164*6654Snp146283 } else if (strcmp (privilege, "hal-power-cpu") == 0) {
165*6654Snp146283 authname = "solaris.system.power.cpu";
1662912Sartem } else {
1672912Sartem /* replace '-' with '.' */
1682912Sartem authname = g_strdup (privilege);
1692912Sartem authname_free = TRUE;
1702912Sartem for (i = 0; i < strlen (authname); i++) {
1712912Sartem if (authname[i] == '-') {
1722912Sartem authname[i] = '.';
1732912Sartem }
1742912Sartem }
1752912Sartem }
1762912Sartem
1772912Sartem *out_is_allowed = (chkauthattr(authname, pw->pw_name) != 0);
1782912Sartem *out_is_temporary = FALSE;
1792912Sartem
1802912Sartem if (authname_free) {
1812912Sartem g_free(authname);
1822912Sartem }
1832912Sartem
1842912Sartem return LIBPOLKIT_RESULT_OK;
1852912Sartem }
1862912Sartem
1872912Sartem LibPolKitResult
libpolkit_get_privilege_list(LibPolKitContext * ctx,GList ** result)1882912Sartem libpolkit_get_privilege_list (LibPolKitContext *ctx,
1892912Sartem GList **result)
1902912Sartem {
1912912Sartem LibPolKitResult res;
1922912Sartem char **privilege_list;
1932912Sartem int num_privileges = 0;
1942912Sartem int i;
1952912Sartem
1962912Sartem LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
1972912Sartem
1982912Sartem *result = NULL;
1992912Sartem
2002912Sartem for (i = 0; i < num_privileges; i++) {
2012912Sartem *result = g_list_append (*result, g_strdup (privilege_list[i]));
2022912Sartem }
2032912Sartem
2042912Sartem res = LIBPOLKIT_RESULT_OK;
2052912Sartem
2062912Sartem return res;
2072912Sartem }
2082912Sartem
2092912Sartem LibPolKitResult
libpolkit_revoke_temporary_privilege(LibPolKitContext * ctx,const char * user,const char * privilege,const char * resource,gboolean * result)2102912Sartem libpolkit_revoke_temporary_privilege (LibPolKitContext *ctx,
2112912Sartem const char *user,
2122912Sartem const char *privilege,
2132912Sartem const char *resource,
2142912Sartem gboolean *result)
2152912Sartem {
2162912Sartem return LIBPOLKIT_RESULT_OK;
2172912Sartem }
218