diff --git a/src/com.meego.usb_moded.xml b/src/com.meego.usb_moded.xml
index 32d04e4..513e375 100644
--- a/src/com.meego.usb_moded.xml
+++ b/src/com.meego.usb_moded.xml
@@ -36,6 +36,9 @@
+
+
+
diff --git a/src/usb_moded-dbus.c b/src/usb_moded-dbus.c
index e17dce4..24c27b7 100644
--- a/src/usb_moded-dbus.c
+++ b/src/usb_moded-dbus.c
@@ -163,6 +163,9 @@ static const char umdbus_introspect_usbmoded[] =
" \n"
" \n"
" \n"
+" \n"
+" \n"
+" \n"
" \n"
" \n"
" \n"
@@ -286,6 +289,7 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
const char *member = dbus_message_get_member(msg);
const char *object = dbus_message_get_path(msg);
int type = dbus_message_get_type(msg);
+ const char *sender = dbus_message_get_sender(msg);
(void)user_data;
@@ -342,11 +346,17 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
const char *mode = control_get_external_mode();
char *use = 0;
DBusError err = DBUS_ERROR_INIT;
+ uid_t uid = umdbus_get_sender_uid(sender);
if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &use, DBUS_TYPE_INVALID)) {
log_err("parse error: %s: %s", err.name, err.message);
reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
}
+ else if( !usbmoded_is_mode_permitted(use, uid) ) {
+ /* Insufficient permissions */
+ log_warning("Mode '%s' is not allowed for uid %d", use, uid);
+ reply = dbus_message_new_error(msg, DBUS_ERROR_ACCESS_DENIED, member);
+ }
else if( control_get_cable_state() != CABLE_STATE_PC_CONNECTED ) {
/* Mode change makes no sence unless we have a PC connection */
log_warning("Mode '%s' requested while not connected to pc", use);
@@ -403,6 +413,11 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID))
reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
+#ifdef SAILFISH_ACCESS_CONTROL
+ /* do not let non-owner user hide modes */
+ else if (!sailfish_access_control_hasgroup(umdbus_get_sender_uid(sender), "sailfish-system"))
+ reply = dbus_message_new_error(msg, DBUS_ERROR_ACCESS_DENIED, member);
+#endif
else
{
/* error checking is done when setting configuration */
@@ -424,6 +439,11 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID))
reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
+#ifdef SAILFISH_ACCESS_CONTROL
+ /* do not let non-owner user unhide modes */
+ else if (!sailfish_access_control_hasgroup(umdbus_get_sender_uid(sender), "sailfish-system"))
+ reply = dbus_message_new_error(msg, DBUS_ERROR_ACCESS_DENIED, member);
+#endif
else
{
/* error checking is done when setting configuration */
@@ -516,6 +536,17 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
dbus_message_append_args (reply, DBUS_TYPE_STRING, (const char *) &mode_list, DBUS_TYPE_INVALID);
g_free(mode_list);
}
+ else if(!strcmp(member, USB_MODE_AVAILABLE_MODES_FOR_USER))
+ {
+ uid_t uid = umdbus_get_sender_uid(sender);
+ gchar *mode_list = common_get_mode_list(AVAILABLE_MODES_LIST, uid);
+
+ if((reply = dbus_message_new_method_return(msg)))
+ dbus_message_append_args (reply, DBUS_TYPE_STRING, (const char *) &mode_list, DBUS_TYPE_INVALID);
+ g_free(mode_list);
+
+ control_set_last_seen_user(uid);
+ }
else if(!strcmp(member, USB_MODE_RESCUE_OFF))
{
usbmoded_set_rescue_mode(false);
@@ -1366,7 +1397,7 @@ uid_t umdbus_get_sender_uid(const char *name)
/* Synchronous D-Bus call */
rsp = dbus_connection_send_with_reply_and_block(umdbus_connection, req, -1, &err);
- if( rsp == NULL && dbus_error_is_set(&err) ) {
+ if( !rsp && dbus_error_is_set(&err) ) {
log_err("could not get sender pid for %s: %s: %s", name, err.name, err.message);
goto EXIT;
}
@@ -1380,7 +1411,7 @@ uid_t umdbus_get_sender_uid(const char *name)
snprintf(path, sizeof path, "/proc/%d", (int)pid);
memset(&st, 0, sizeof st);
- if( stat(path, &st) == 0 ) {
+ if( stat(path, &st) != -1 ) {
uid = st.st_uid;
}
diff --git a/src/usb_moded-dbus.h b/src/usb_moded-dbus.h
index d03e37e..0e0fd8c 100644
--- a/src/usb_moded-dbus.h
+++ b/src/usb_moded-dbus.h
@@ -59,23 +59,24 @@
# define USB_MODE_TARGET_CONFIG_SIGNAL_NAME "sig_usb_taget_mode_config_ind"
/* supported methods */
-# define USB_MODE_STATE_REQUEST "mode_request" /* returns the current mode */
-# define USB_MODE_TARGET_STATE_GET "get_target_state" /* returns the target mode */
-# define USB_MODE_RESCUE_OFF "rescue_off" /* turns rescue mode off so normal mode selection is restored */
-# define USB_MODE_CONFIG_GET "get_config" /* returns the mode set in the config */
-# define USB_MODE_LIST "get_modes" /* returns a comma-separated list of supported modes for ui's */
-# define USB_MODE_HIDE "hide_mode" /* hide a mode */
-# define USB_MODE_UNHIDE "unhide_mode" /* unhide a mode */
-# define USB_MODE_HIDDEN_GET "get_hidden" /* return the hidden modes */
-# define USB_MODE_STATE_SET "set_mode" /* set a mode (only works when connected) */
-# define USB_MODE_CONFIG_SET "set_config" /* set the mode that needs to be activated in the config file */
-# define USB_MODE_NETWORK_SET "net_config" /* set the network config in the config file */
-# define USB_MODE_NETWORK_GET "get_net_config" /* get the network config from the config file */
-# define USB_MODE_WHITELISTED_MODES_GET "get_whitelisted_modes" /* get the list of whitelisted modes */
-# define USB_MODE_WHITELISTED_MODES_SET "set_whitelisted_modes" /* set the list of whitelisted modes */
-# define USB_MODE_WHITELISTED_SET "set_whitelisted" /* sets whether an specific mode is in the whitelist */
-# define USB_MODE_AVAILABLE_MODES_GET "get_available_modes" /* returns a comma separated list of modes which are currently available for selection */
-# define USB_MODE_TARGET_CONFIG_GET "get_target_mode_config" /* returns current target mode configuration */
+# define USB_MODE_STATE_REQUEST "mode_request" /* returns the current mode */
+# define USB_MODE_TARGET_STATE_GET "get_target_state" /* returns the target mode */
+# define USB_MODE_RESCUE_OFF "rescue_off" /* turns rescue mode off so normal mode selection is restored */
+# define USB_MODE_CONFIG_GET "get_config" /* returns the mode set in the config */
+# define USB_MODE_LIST "get_modes" /* returns a comma-separated list of supported modes for ui's */
+# define USB_MODE_HIDE "hide_mode" /* hide a mode */
+# define USB_MODE_UNHIDE "unhide_mode" /* unhide a mode */
+# define USB_MODE_HIDDEN_GET "get_hidden" /* return the hidden modes */
+# define USB_MODE_STATE_SET "set_mode" /* set a mode (only works when connected) */
+# define USB_MODE_CONFIG_SET "set_config" /* set the mode that needs to be activated in the config file */
+# define USB_MODE_NETWORK_SET "net_config" /* set the network config in the config file */
+# define USB_MODE_NETWORK_GET "get_net_config" /* get the network config from the config file */
+# define USB_MODE_WHITELISTED_MODES_GET "get_whitelisted_modes" /* get the list of whitelisted modes */
+# define USB_MODE_WHITELISTED_MODES_SET "set_whitelisted_modes" /* set the list of whitelisted modes */
+# define USB_MODE_WHITELISTED_SET "set_whitelisted" /* sets whether an specific mode is in the whitelist */
+# define USB_MODE_AVAILABLE_MODES_GET "get_available_modes" /* returns a comma separated list of modes which are currently available for selection */
+# define USB_MODE_AVAILABLE_MODES_FOR_USER "get_available_modes_for_user" /* returns a comma separated list of modes which are currently available and permitted for user to select */
+# define USB_MODE_TARGET_CONFIG_GET "get_target_mode_config" /* returns current target mode configuration */
/**
* (Transient) states reported by "sig_usb_state_ind" that are not modes.