commit f2c19a6996b616e51ef1078fc909bafed078f300 Author: fbt Date: Mon Aug 17 13:33:34 2015 +0300 init diff --git a/make.sh b/make.sh new file mode 100755 index 0000000..03d4257 --- /dev/null +++ b/make.sh @@ -0,0 +1,63 @@ +#!/bin/sh +set -e + +# Functions +set_vars() { + printf 'Setting vars...\n' >&2 + + sed -r \ + -e "s%@CONFIG@%${CONFIG}%" \ + -r "s%@LOGDIR@%${LOGDIR}%" +} + +do_tell() { + printf 'Executing: %s\n' "$*" + "$@" +} + +# Targets +target_userrc() { + declare target='userrc' + + printf '%s\n' "Building $target..." + set_vars < "$target".in > "$target" + do_tell chmod 755 "$target" + ls -l "$target" +} + +target_clean() { + do_tell rm -f userrc +} + +target_install() { + mkdir -p "$BINDIR" + + do_tell cp userrc "${BINDIR}/userrc" + do_tell chmod 755 "${BINDIR}/userrc" +} + +target_all() { + target_userrc +} + +main() { + while [ -n "$1" ]; do + case "$1" in + *=*) export "${1%%=*}=${1#*=}";; + --) shift; break;; + *) break;; + esac + shift + done + + target="${1:-all}" + + # Build configuration + . './config.mk.sh' + + printf '%s\n' "Building target: $target" + + "target_$target" +} + +main "$@" diff --git a/userrc.in b/userrc.in new file mode 100644 index 0000000..9dcf5e2 --- /dev/null +++ b/userrc.in @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +msg() { printf '%s\n' "$*"; } +err() { printf '%s\n' "$*" >&2; } + +usage() { + msg "Usage: userrc [-c config] [-l logdir]" +} + +rc_run_wait() { + su "$username" -s "$SHELL" -c "$homedir/.config/rc.local" &>"$logdir/${username}.log" & + wait "$!" + + if (( $? )); then + msg "$homedir/.config/rc.local has returned a non-zero exit code." + fi +} + +is_blacklisted() { + declare u target=$1 + + for u in "${users_deny[@]}"; do + if [[ "$u" == "$target" ]]; then + return 0 + fi + done + + return 1 +} + +is_whitelisted() { + declare u target=$1 + + for u in "${users_allow[@]}"; do + if [[ "$u" == "$target" ]]; then + return 0 + fi + done + + return 1 +} + +get_allowed_users() { + if ! [[ "$access_mode" ]]; then + access_mode='blacklist' + fi + + msg "Running in $access_mode access mode." + + case "${access_mode:-freeforall}" in + explicit) + while IFS=':' read -r username pass uid gid description homedir shell; do + if is_whitelisted "$username"; then + users+=( "$username:$homedir" ) + fi + done < /etc/passwd + ;; + + blacklist) + while IFS=':' read -r username pass uid gid description homedir shell; do + if ! is_blacklisted "$username"; then + users+=( "$username:$homedir" ) + fi + done < /etc/passwd + ;; + esac +} + +runtime_config() { + config='/etc/userrc.conf' + cfg_logdir='/tmp/userrc' + + while (( $# )); do + case "$1" in + (-c) config="$2"; shift;; + (-l) logdir="$2"; shift;; + esac + shift + done + + if [[ -f "$config" ]]; then + source "$config" || { return $?; } + else + msg "Config not found at $config. Using defaults." + fi + + if ! [[ "$logdir" ]]; then + logdir="$cfg_logdir" + fi + + if [[ ! -d "$logdir" ]]; then + mkdir -p "$logdir" || { + return 1 + } + fi + + chmod 700 "$logdir" +} + +main() { + runtime_config + get_allowed_users + + for u in "${users[@]}"; do + IFS=':' read -r username homedir <<< "$u" + + if [[ "$homedir" && "$homedir" != '/' ]]; then + if [[ -f "$homedir/.config/rc.local" ]]; then + if [[ -x "$homedir/.config/rc.local" ]]; then + msg "Executing $homedir/.config/rc.local" + rc_run_wait + else + msg "$homedir/.config/rc.local exists, but is not executable" + fi + fi + fi + done +} + +main "$@"