summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-11-17 09:01:53 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-11-20 10:30:23 +0100
commitb8bd90f68fb787cc321365c6de161d6b77c8353f (patch)
treecd78640ad422bebb2fe5c9a5dcf92f4f00646fa3 /cpukit/libcsupport
parentsamples/fileio: Use unlimited objects (diff)
downloadrtems-b8bd90f68fb787cc321365c6de161d6b77c8353f.tar.bz2
Add supplementary groups to user environment
Diffstat (limited to 'cpukit/libcsupport')
-rw-r--r--cpukit/libcsupport/Makefile.am1
-rw-r--r--cpukit/libcsupport/include/rtems/libio_.h27
-rw-r--r--cpukit/libcsupport/src/sup_fs_check_permissions.c47
-rw-r--r--cpukit/libcsupport/src/uenvgetgroups.c36
4 files changed, 94 insertions, 17 deletions
diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am
index 6803fe6036..bd3f90a648 100644
--- a/cpukit/libcsupport/Makefile.am
+++ b/cpukit/libcsupport/Makefile.am
@@ -58,6 +58,7 @@ BASE_FS_C_FILES = src/base_fs.c src/mount.c src/unmount.c src/libio.c \
src/libio_helper_null.c \
src/libio_exit.c \
src/open_dev_console.c src/__usrenv.c src/rtems_mkdir.c
+BASE_FS_C_FILES += src/uenvgetgroups.c
TERMIOS_C_FILES = src/cfgetispeed.c src/cfgetospeed.c src/cfsetispeed.c \
src/cfsetospeed.c src/tcgetattr.c src/tcsetattr.c src/tcdrain.c \
diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h
index c0f4432d0e..458201ea3f 100644
--- a/cpukit/libcsupport/include/rtems/libio_.h
+++ b/cpukit/libcsupport/include/rtems/libio_.h
@@ -810,11 +810,30 @@ int rtems_filesystem_location_exists_in_same_instance_as(
const rtems_filesystem_location_info_t *b
);
+/**
+ * @brief Checks if access to an object is allowed for the current user.
+ *
+ * If the effective UID is zero or equals the UID of the object, then the user
+ * permission flags of the object will be used. Otherwise if the effective GID
+ * is zero or equals the GID of the object or one of the supplementary group
+ * IDs is equal to the GID of the object, then the group permission flags of
+ * the object will be used. Otherwise the other permission flags of the object
+ * will be used.
+ *
+ * @param[in] flags The flags determining the access type. It can be
+ * RTEMS_FS_PERMS_READ, RTEMS_FS_PERMS_WRITE or RTEMS_FS_PERMS_EXEC.
+ * @param[in] object_mode The mode of the object specifying the permission flags.
+ * @param[in] object_uid The UID of the object.
+ * @param[in] object_gid The GID of the object.
+ *
+ * @retval true Access is allowed.
+ * @retval false Otherwise.
+ */
bool rtems_filesystem_check_access(
- int eval_flags,
- mode_t node_mode,
- uid_t node_uid,
- gid_t node_gid
+ int flags,
+ mode_t object_mode,
+ uid_t object_uid,
+ gid_t object_gid
);
bool rtems_filesystem_eval_path_check_access(
diff --git a/cpukit/libcsupport/src/sup_fs_check_permissions.c b/cpukit/libcsupport/src/sup_fs_check_permissions.c
index f6fd0e91c9..394f945b0b 100644
--- a/cpukit/libcsupport/src/sup_fs_check_permissions.c
+++ b/cpukit/libcsupport/src/sup_fs_check_permissions.c
@@ -70,29 +70,50 @@ RTEMS_STATIC_ASSERT(
S_IXOTH
);
+static bool equals_supplementary_group(
+ const rtems_user_env_t *uenv,
+ gid_t object_gid
+)
+{
+ size_t i;
+
+ for (i = 0; i < uenv->ngroups; ++i) {
+ if (uenv->groups[i] == object_gid) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool rtems_filesystem_check_access(
- int eval_flags,
- mode_t node_mode,
- uid_t node_uid,
- gid_t node_gid
+ int flags,
+ mode_t object_mode,
+ uid_t object_uid,
+ gid_t object_gid
)
{
- mode_t perm_flags = eval_flags & RTEMS_FS_PERMS_RWX;
- uid_t task_uid = geteuid();
+ const rtems_user_env_t *uenv = rtems_current_user_env_get();
+ mode_t access_flags = flags & RTEMS_FS_PERMS_RWX;
+ uid_t task_uid = uenv->euid;
- if (task_uid == 0 || task_uid == node_uid) {
- perm_flags <<= RTEMS_FS_USR_SHIFT;
+ if (task_uid == 0 || task_uid == object_uid) {
+ access_flags <<= RTEMS_FS_USR_SHIFT;
} else {
- gid_t task_gid = getegid();
+ gid_t task_gid = uenv->egid;
- if (task_gid == 0 || task_gid == node_gid) {
- perm_flags <<= RTEMS_FS_GRP_SHIFT;
+ if (
+ task_gid == 0
+ || task_gid == object_gid
+ || equals_supplementary_group(uenv, object_gid)
+ ) {
+ access_flags <<= RTEMS_FS_GRP_SHIFT;
} else {
- perm_flags <<= RTEMS_FS_OTH_SHIFT;
+ access_flags <<= RTEMS_FS_OTH_SHIFT;
}
}
- return (perm_flags & node_mode) == perm_flags;
+ return (access_flags & object_mode) == access_flags;
}
bool rtems_filesystem_eval_path_check_access(
diff --git a/cpukit/libcsupport/src/uenvgetgroups.c b/cpukit/libcsupport/src/uenvgetgroups.c
new file mode 100644
index 0000000000..9645a9618b
--- /dev/null
+++ b/cpukit/libcsupport/src/uenvgetgroups.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * D-82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/userenv.h>
+#include <rtems.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+void rtems_current_user_env_getgroups(void)
+{
+ rtems_user_env_t *uenv = rtems_current_user_env_get();
+ int ngroups = (int) RTEMS_ARRAY_SIZE( uenv->groups );
+
+ ngroups = getgroups( ngroups, &uenv->groups[ 0 ] );
+ if ( ngroups > 0 ) {
+ uenv->ngroups = (size_t) ngroups;
+ } else {
+ uenv->ngroups = 0;
+ }
+}