From 50610d9ac41684a1e65439a21d61eecfe546d26a Mon Sep 17 00:00:00 2001 From: Andy Thompson Date: Wed, 23 Aug 2017 16:32:25 +0100 Subject: [PATCH 1/8] A possible alternative abstraction for permissions Assumes for facl/stickybit that all users are umask 0002 It doesn't have the performance improvements of #332 yet, though I'm unsure if that's possible with setfacl --- .../local/share/bootstrap/common_functions.sh | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh index a8f6a22e..2e5ed78c 100755 --- a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh +++ b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh @@ -255,6 +255,44 @@ function canonical_port() { echo "$PORT" } +function set_path_permissions() { + local -r READABLE_USERS=($1) + local -r WRITEABLE_USERS=($2) + local -r PATHS=("${@:3}") + + case "$PERMISSION_MODE" in + facl) + setfacl -R $(printf '-m user:%s:rwX ' "${WRITEABLE_USERS[@]}") \ + $(printf '-m default:user:%s:rwX ' "${WRITEABLE_USERS[@]}") \ + $(printf '-m user:%s:rX ' "${READABLE_USERS[@]}") \ + $(printf '-m default:user:%s:rX ' "${READABLE_USERS[@]}") \ + "${PATHS[@]}" + chmod -R ug+rw,o-rwx "${PATHS[@]}" + ;; + stickybit) + GROUP="$(printf '%s' "${WRITEABLE_USERS[@]}")" + + if ! getent group "$GROUP" >/dev/null; then + groupadd "$GROUP" + fi + + for USER in "${WRITEABLE_USERS[@]}"; do + usermod -a -G "$GROUP" "$USER" + done + + chgrp -R "$GROUP" "${PATHS[@]}" + find "${PATHS[@]}" -type d -exec chmod g+ws \; + find "${PATHS[@]}" -type f -exec chmod g+w \; + ;; + chmod) + chmod -R a+rw "${PATHS[@]}" + ;; + *) + echo "unsupported permission mode '$PERMISSION_MODE'" >&2 + ;; + esac +} + function wait_for_remote_ports() ( set +x From 9c14e67db2a531b925fa693d1d3ab0cd70074a41 Mon Sep 17 00:00:00 2001 From: Kieren Evans Date: Wed, 20 Sep 2017 17:55:46 +0100 Subject: [PATCH 2/8] Fix for printf treating -m as an arg --- .../16.04/usr/local/share/bootstrap/common_functions.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh index 2e5ed78c..64698334 100755 --- a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh +++ b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh @@ -262,10 +262,10 @@ function set_path_permissions() { case "$PERMISSION_MODE" in facl) - setfacl -R $(printf '-m user:%s:rwX ' "${WRITEABLE_USERS[@]}") \ - $(printf '-m default:user:%s:rwX ' "${WRITEABLE_USERS[@]}") \ - $(printf '-m user:%s:rX ' "${READABLE_USERS[@]}") \ - $(printf '-m default:user:%s:rX ' "${READABLE_USERS[@]}") \ + setfacl -R $(printf -- '-m user:%s:rwX ' "${WRITEABLE_USERS[@]}") \ + $(printf -- '-m default:user:%s:rwX ' "${WRITEABLE_USERS[@]}") \ + $(printf -- '-m user:%s:rX ' "${READABLE_USERS[@]}") \ + $(printf -- '-m default:user:%s:rX ' "${READABLE_USERS[@]}") \ "${PATHS[@]}" chmod -R ug+rw,o-rwx "${PATHS[@]}" ;; From ed5ad46d6ce1610fa5e0c9a66bbf5e88a0092346 Mon Sep 17 00:00:00 2001 From: Kieren Evans Date: Wed, 20 Sep 2017 17:59:28 +0100 Subject: [PATCH 3/8] Auto-detect compatible permissions method, with possibility to deny acl if needed. --- .../usr/local/share/bootstrap/common_functions.sh | 14 ++++++++++++++ ubuntu/16.04/usr/local/share/env/50-bootstrap | 2 ++ 2 files changed, 16 insertions(+) diff --git a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh index 64698334..46cc94f9 100755 --- a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh +++ b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh @@ -346,3 +346,17 @@ function do_list_functions() { function do_shell() { bash "$@" } + +function has_acl() { + return 0 +} + +function permission_mode() { + if [ "$IS_CHOWN_FORBIDDEN" == "true" ]; then + echo "chmod" + elif has_acl; then + echo "facl" + else + echo "stickybit" + fi +} diff --git a/ubuntu/16.04/usr/local/share/env/50-bootstrap b/ubuntu/16.04/usr/local/share/env/50-bootstrap index cc217f6f..9af0341b 100644 --- a/ubuntu/16.04/usr/local/share/env/50-bootstrap +++ b/ubuntu/16.04/usr/local/share/env/50-bootstrap @@ -34,6 +34,8 @@ export APP_USER_LOCAL APP_USER_LOCAL_RANDOM="$(convert_to_boolean_string "${APP_USER_LOCAL_RANDOM:-false}")" export APP_USER_LOCAL_RANDOM +export PERMISSION_MODE=${PERMISSION_MODE:="$(permission_mode)"} + export BUILD_USER_SSH_PRIVATE_KEY=${BUILD_USER_SSH_PRIVATE_KEY:-} export BUILD_USER_SSH_PUBLIC_KEY=${BUILD_USER_SSH_PUBLIC_KEY:-} export BUILD_USER_SSH_KNOWN_HOSTS=${BUILD_USER_SSH_KNOWN_HOSTS:-} From 40768420d8120819b95ac22f552e7aa5bae3d4f4 Mon Sep 17 00:00:00 2001 From: Kieren Evans Date: Mon, 25 Sep 2017 12:26:06 +0100 Subject: [PATCH 4/8] Fixes for multiple users being specified and turning off setfacl for fuse.osx --- .../local/share/bootstrap/common_functions.sh | 67 +++++++++++++------ 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh index 46cc94f9..b3253684 100755 --- a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh +++ b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh @@ -136,19 +136,30 @@ is_hem_project() { return "$?" } +get_filesystem_for_work_directory() ( + set +e + grep "$WORK_DIRECTORY" /proc/mounts | awk '{ print $3 }' +) + is_app_mountpoint() { - grep -q -E "/app (nfs|vboxsf|fuse\\.osxfs)" /proc/mounts + local FILESYSTEM='' + FILESYSTEM="$(get_filesystem_for_work_directory)" + echo "$FILESYSTEM" | grep -q -E "(nfs|vboxsf|fuse\\.osxfs)" return "$?" } is_chown_forbidden() { # Determine if the app directory is an NFS mountpoint, which doesn't allow chowning. - grep -q -E "/app (nfs|vboxsf)" /proc/mounts + local FILESYSTEM='' + FILESYSTEM="$(get_filesystem_for_work_directory)" + echo "$FILESYSTEM" | grep -q -E "(nfs|vboxsf)" return "$?" } is_vboxsf_mountpoint() { - grep -q "/app vboxsf" /proc/mounts + local FILESYSTEM='' + FILESYSTEM="$(get_filesystem_for_work_directory)" + echo "$FILESYSTEM" | grep -q "vboxsf" return "$?" } @@ -255,6 +266,29 @@ function canonical_port() { echo "$PORT" } +function has_acl() { + local FILESYSTEM='' + FILESYSTEM="$(get_filesystem_for_work_directory)" + case "$FILESYSTEM" in + fuse.osx) + return 1 + ;; + *) + return 0 + ;; + esac +} + +function permission_mode() { + if [ "$IS_CHOWN_FORBIDDEN" == "true" ]; then + echo "chmod" + elif has_acl; then + echo "facl" + else + echo "stickybit" + fi +} + function set_path_permissions() { local -r READABLE_USERS=($1) local -r WRITEABLE_USERS=($2) @@ -262,11 +296,14 @@ function set_path_permissions() { case "$PERMISSION_MODE" in facl) - setfacl -R $(printf -- '-m user:%s:rwX ' "${WRITEABLE_USERS[@]}") \ - $(printf -- '-m default:user:%s:rwX ' "${WRITEABLE_USERS[@]}") \ - $(printf -- '-m user:%s:rX ' "${READABLE_USERS[@]}") \ - $(printf -- '-m default:user:%s:rX ' "${READABLE_USERS[@]}") \ - "${PATHS[@]}" + PERMISSIONS=() + for user in "${WRITEABLE_USERS[@]}"; do + PERMISSIONS+=(-m "$(printf -- 'user:%s:rwX' "$user")" -m "$(printf -- 'default:user:%s:rwX' "$user")") + done + for user in "${READABLE_USERS[@]}"; do + PERMISSIONS+=(-m "$(printf -- 'user:%s:rX' "$user")" -m "$(printf -- 'default:user:%s:rX' "$user")") + done + setfacl -R ${PERMISSIONS[@]} "${PATHS[@]}" chmod -R ug+rw,o-rwx "${PATHS[@]}" ;; stickybit) @@ -346,17 +383,3 @@ function do_list_functions() { function do_shell() { bash "$@" } - -function has_acl() { - return 0 -} - -function permission_mode() { - if [ "$IS_CHOWN_FORBIDDEN" == "true" ]; then - echo "chmod" - elif has_acl; then - echo "facl" - else - echo "stickybit" - fi -} From 0ecb594424c6b4a2662f51cf5cd3af44a46f4660 Mon Sep 17 00:00:00 2001 From: Kieren Evans Date: Sat, 17 Mar 2018 15:02:21 +0200 Subject: [PATCH 5/8] Quoting for shellcheck --- ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh index b3253684..fd20d5c9 100755 --- a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh +++ b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh @@ -303,7 +303,7 @@ function set_path_permissions() { for user in "${READABLE_USERS[@]}"; do PERMISSIONS+=(-m "$(printf -- 'user:%s:rX' "$user")" -m "$(printf -- 'default:user:%s:rX' "$user")") done - setfacl -R ${PERMISSIONS[@]} "${PATHS[@]}" + setfacl -R "${PERMISSIONS[@]}" "${PATHS[@]}" chmod -R ug+rw,o-rwx "${PATHS[@]}" ;; stickybit) From b9bc23dfae26f8470c4cdeaa96842e22a2f03384 Mon Sep 17 00:00:00 2001 From: Kieren Evans Date: Sun, 18 Mar 2018 00:59:14 +0200 Subject: [PATCH 6/8] Fix stickybit chmod --- ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh index fd20d5c9..d71be58f 100755 --- a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh +++ b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh @@ -318,8 +318,8 @@ function set_path_permissions() { done chgrp -R "$GROUP" "${PATHS[@]}" - find "${PATHS[@]}" -type d -exec chmod g+ws \; - find "${PATHS[@]}" -type f -exec chmod g+w \; + find "${PATHS[@]}" -type d -exec chmod g+ws {} + + find "${PATHS[@]}" -type f -exec chmod g+w {} + ;; chmod) chmod -R a+rw "${PATHS[@]}" From 558b9a3a204930864eaa55038593ec7187acd7f4 Mon Sep 17 00:00:00 2001 From: Kieren Evans Date: Mon, 19 Mar 2018 22:33:00 +0200 Subject: [PATCH 7/8] Apply "find" based speed improvements. --- .../local/share/bootstrap/common_functions.sh | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh index d71be58f..c9c7a15a 100755 --- a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh +++ b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh @@ -290,9 +290,12 @@ function permission_mode() { } function set_path_permissions() { - local -r READABLE_USERS=($1) - local -r WRITEABLE_USERS=($2) - local -r PATHS=("${@:3}") + local -a READABLE_USERS=() + IFS=" " read -r -a READABLE_USERS <<< "$1" + local -a WRITEABLE_USERS=() + IFS=" " read -r -a WRITEABLE_USERS <<< "$2" + local -a PATHS=() + IFS=" " read -r -a PATHS <<< "${@:3}" case "$PERMISSION_MODE" in facl) @@ -304,7 +307,7 @@ function set_path_permissions() { PERMISSIONS+=(-m "$(printf -- 'user:%s:rX' "$user")" -m "$(printf -- 'default:user:%s:rX' "$user")") done setfacl -R "${PERMISSIONS[@]}" "${PATHS[@]}" - chmod -R ug+rw,o-rwx "${PATHS[@]}" + find "${PATHS[@]}" ! -perm /660 -exec chmod ug+rw,o-rwx {} + ;; stickybit) GROUP="$(printf '%s' "${WRITEABLE_USERS[@]}")" @@ -317,16 +320,16 @@ function set_path_permissions() { usermod -a -G "$GROUP" "$USER" done - chgrp -R "$GROUP" "${PATHS[@]}" - find "${PATHS[@]}" -type d -exec chmod g+ws {} + - find "${PATHS[@]}" -type f -exec chmod g+w {} + + find "${PATHS[@]}" ! -group "$GROUP" -exec chgrp "$GROUP" {} + + find "${PATHS[@]}" -type d ! -perm -2070 -exec chmod g+ws {} + + find "${PATHS[@]}" -type f ! -perm -0060 -exec chmod g+w {} + ;; chmod) - chmod -R a+rw "${PATHS[@]}" - ;; + find "${PATHS[@]}" ! -perm -0666 -exec chmod a+rw {} + + ;; *) - echo "unsupported permission mode '$PERMISSION_MODE'" >&2 - ;; + echo "unsupported permission mode '$PERMISSION_MODE'" >&2 + ;; esac } From 4334c12066dc583a913722c21a0dd77b776e9c49 Mon Sep 17 00:00:00 2001 From: Kieren Evans Date: Mon, 19 Mar 2018 23:40:27 +0200 Subject: [PATCH 8/8] Use setgid bit over setfacl --- ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh index c9c7a15a..6e87125f 100755 --- a/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh +++ b/ubuntu/16.04/usr/local/share/bootstrap/common_functions.sh @@ -282,8 +282,6 @@ function has_acl() { function permission_mode() { if [ "$IS_CHOWN_FORBIDDEN" == "true" ]; then echo "chmod" - elif has_acl; then - echo "facl" else echo "stickybit" fi