12912Sartem /***************************************************************************
22912Sartem  *
32912Sartem  * libpolkit-rbac.c : RBAC implementation of the libpolkit API
42912Sartem  *
5*6573Sphitran  * 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 *
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
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
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
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";
153*6573Sphitran 	} else if (strcmp(privilege, "hal-power-suspend") == 0) {
154*6573Sphitran 		authname = "solaris.system.power.suspend.ram";
155*6573Sphitran 	} else if (strcmp(privilege, "hal-power-hibernate") == 0) {
156*6573Sphitran                 authname = "solaris.system.power.suspend.disk";
157*6573Sphitran 	} else if ((strcmp(privilege, "hal-power-shutdown") == 0) ||
158*6573Sphitran 	    (strcmp(privilege, "hal-power-reboot") == 0)) {
159*6573Sphitran                 authname = "solaris.system.shutdown";
160*6573Sphitran 	} else if (strcmp(privilege, "hal-power-cpu") == 0) {
161*6573Sphitran                 authname = "solaris.system.power.cpu";
162*6573Sphitran 	} else if (strcmp(privilege, "hal-power-brightness") == 0) {
163*6573Sphitran                 authname = "solaris.system.power.brightness";
1642912Sartem 	} else {
1652912Sartem 		/* replace '-' with '.' */
1662912Sartem 		authname = g_strdup (privilege);
1672912Sartem 		authname_free = TRUE;
1682912Sartem 		for (i = 0; i < strlen (authname); i++) {
1692912Sartem 			if (authname[i] == '-') {
1702912Sartem 				authname[i] = '.';
1712912Sartem 			}
1722912Sartem 		}
1732912Sartem 	}
1742912Sartem 
1752912Sartem 	*out_is_allowed = (chkauthattr(authname, pw->pw_name) != 0);
1762912Sartem 	*out_is_temporary = FALSE;
1772912Sartem 
1782912Sartem 	if (authname_free) {
1792912Sartem 		g_free(authname);
1802912Sartem 	}
1812912Sartem 
1822912Sartem 	return LIBPOLKIT_RESULT_OK;
1832912Sartem }
1842912Sartem 
1852912Sartem LibPolKitResult
1862912Sartem libpolkit_get_privilege_list (LibPolKitContext      *ctx,
1872912Sartem 			      GList                **result)
1882912Sartem {
1892912Sartem 	LibPolKitResult res;
1902912Sartem 	char **privilege_list;
1912912Sartem 	int num_privileges = 0;
1922912Sartem 	int i;
1932912Sartem 
1942912Sartem 	LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
1952912Sartem 
1962912Sartem 	*result = NULL;
1972912Sartem 
1982912Sartem 	for (i = 0; i < num_privileges; i++) {
1992912Sartem 		*result = g_list_append (*result, g_strdup (privilege_list[i]));
2002912Sartem 	}
2012912Sartem 
2022912Sartem 	res = LIBPOLKIT_RESULT_OK;
2032912Sartem 
2042912Sartem 	return res;
2052912Sartem }
2062912Sartem 
2072912Sartem LibPolKitResult
2082912Sartem libpolkit_revoke_temporary_privilege (LibPolKitContext      *ctx,
2092912Sartem                                       const char            *user,
2102912Sartem                                       const char            *privilege,
2112912Sartem                                       const char            *resource,
2122912Sartem                                       gboolean              *result)
2132912Sartem {
2142912Sartem 	return LIBPOLKIT_RESULT_OK;
2152912Sartem }
216