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