#!/bin/bash
#
# This file is part of Plinth.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# Store anything available from stdin.
# This is used to receive passwords from Plinth.
if read -t 0; then
    IFS= read -r input
fi

set -e  # Exit on failure


create_user()
{
    username="$1"
    password="$2"

    # All users shall have 'users' (a group in /etc/group) as primary group.
    ldapadduser $username users > /dev/null

    set_user_password $username $password

    flush_cache
}


delete_user()
{
    username="$1"

    groups=$(get_user_groups $username)

    ldapdeleteuser $username

    while read -r group; do
        ldapdeleteuserfromgroup $username $group > /dev/null || true
    done <<< "$groups"

    flush_cache
}


rename_user()
{
    old_username="$1"
    new_username="$2"

    groups=$(get_user_groups $old_username)

    ldaprenameuser $old_username $new_username

    while read -r group; do
        ldapdeleteuserfromgroup $old_username $group > /dev/null || true
        ldapaddusertogroup $new_username $group > /dev/null || true
    done <<< "$groups"

    flush_cache
}


set_user_password()
{
    username="$1"
    password=$(slappasswd -s "$2")

    ldapsetpasswd "$username" "$password"
}


get_user_groups()
{
    # Return only supplimentary groups and don't include the 'users'
    # primary group.
    username="$1"

    ldapid $username | cut -f 3 -d ' ' | cut -d = -f 2 | sed 's+,+\n+g' | sed "s+.*(\(.*\))+\1+" | grep -v users || true
}


add_user_to_group()
{
    username="$1"
    groupname="$2"

    # Try to create group and ignore failure if group already exists
    ldapaddgroup $groupname > /dev/null 2>&1 || true

    ldapaddusertogroup $username $groupname > /dev/null

    flush_cache
}


remove_user_from_group()
{
    username="$1"
    groupname="$2"

    ldapdeleteuserfromgroup $username $groupname > /dev/null

    flush_cache
}


flush_cache()
{
    # Flush nscd cache
    nscd --invalidate=passwd
    nscd --invalidate=group
}


command=$1
shift
case $command in
    create-user)
        create_user "$1" "$input"
    ;;
    delete-user)
        delete_user "$@"
    ;;
    rename-user)
        rename_user "$@"
    ;;
    set-user-password)
        set_user_password "$1" "$input"
    ;;
    get-user-groups)
        get_user_groups "$@"
    ;;
    add-user-to-group)
        add_user_to_group "$@"
    ;;
    remove-user-from-group)
        remove_user_from_group "$@"
    ;;
    *)
        echo "Invalid sub-command"
        exit -1
    ;;
esac
