#!/bin/bash

# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2026 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
#

[ -z "$LSAPICACHE_LOAD_DIRS" ] && exit 0

[ -z "$LSAPICACHE_LOGFILE" ] && LSAPICACHE_LOGFILE=/usr/share/lve/modlscapi/logs/lsapi-cache.log

D=`date`; echo "$D: the following dirs will be processed: $LSAPICACHE_LOAD_DIRS" >>$LSAPICACHE_LOGFILE

# Return 0 iff $1 is not a symlink and it plus every ancestor up to / are
# root-owned and not group/other-writable. Gates the root operations below.
is_root_safe_path() {
    local p="$1"
    [ -L "$p" ] && return 1
    while : ; do
        local owner mode
        owner=`/usr/bin/stat -c '%u' "$p" 2>/dev/null` || return 1
        mode=`/usr/bin/stat -c '%a' "$p" 2>/dev/null` || return 1
        [ "$owner" = "0" ] || return 1
        # %a is 3 or 4 octal digits; reject if the last (other) or the
        # 2nd-from-last (group) digit carries the write bit.
        case "$mode" in
            *2|*3|*6|*7) return 1 ;;
        esac
        case "$mode" in
            *[2367]?) return 1 ;;
        esac
        [ "$p" = "/" ] && break
        local parent
        parent=`dirname "$p"`
        [ "$parent" = "$p" ] && break
        p="$parent"
    done
    return 0
}

safe_exec_lsphp() {
    local f="$1"
    if is_root_safe_path "$f"; then
        "$f" -i >/dev/null 2>&1
    else
        D=`date`; echo "$D: skipping non-root-safe lsphp: ${f}" >>$LSAPICACHE_LOGFILE
    fi
}

# ldd can run code from its target binary, so gate it like exec.
safe_ldd() {
    local f="$1"
    if is_root_safe_path "$f"; then
        /usr/bin/ldd "$f" >/dev/null 2>&1
    else
        D=`date`; echo "$D: skipping non-root-safe executable: ${f}" >>$LSAPICACHE_LOGFILE
    fi
}

OIFS="$IFS"
IFS=":"

for d in $LSAPICACHE_LOAD_DIRS
do
    [ -d "$d" ] || continue
    D=`date`; echo "$D: loading shared libraries from ${d}..." >>$LSAPICACHE_LOGFILE
    while IFS= read -r -d '' f
    do
        safe_ldd "$f"
    done < <(/usr/bin/find "$d" -type f -executable -print0 2>/dev/null)
    D=`date`; echo "$D: ${d} - done." >>$LSAPICACHE_LOGFILE
done

for d in $LSAPICACHE_LOAD_DIRS
do
    [ -d "$d" ] || continue
    D=`date`; echo "$D: loading lsphp from ${d}..." >>$LSAPICACHE_LOGFILE
    while IFS= read -r -d '' f
    do
        safe_exec_lsphp "$f"
    done < <(/usr/bin/find "$d" -type f -executable -name lsphp -print0 2>/dev/null)
    D=`date`; echo "$D: ${d} - done." >>$LSAPICACHE_LOGFILE
done


IFS="$OIFS"
exit 0
