#!/bin/ash

#Errors Codes:
#defaults:
    # 0 Tudo certo
    # 1 Não consegui atualizar passwd
    # 2 Syntax invalida
    # 3 argumento invalido
    # 4 UID ja em uso
    # 6 Grupo especificado nao existe
    # 9 Username já existente
    # 10 Não consegui atualizao group file
    # 12 Não consegui criar o diretorio home
    # 13 Cant create mail spool
    # 14 Cant update SELinux user mapping


# 21 Tentar adicionar usuario no range do servidor sem flag
# 22 Tentar sobreescrever usuario global ou do sistema
# 23 Usuario de servidor ja existe
# 24 Tenta adicionar usuario com a flag de servidor mas fora da range

# 31 Usuario local ja existe
# 32 Usuario local fora do range do local_accounts

# 41 Usuario de pendrive nao valido

# 51 GID e/ou GroupName já em uso


add (){
    local passwd=$1
    local group=$2
    local shadow=$3

    local username=$( echo $passwd | cut -d':' -f1 )
    local uID=$( echo $passwd | cut -d':' -f3 )

    local groupname=$( echo $group | cut -d':' -f1 )
    local gID=$( echo $group | cut -d':' -f3 )

    #check if this uid is available
    local checkID=$( cat /etc/passwd | cut -d':' -f1-3 | grep -e ":$uID$" )
    if [ -n "$checkID" ]; then
        echo $0": Impossivel cadastrar usuario, já existe usuário com o mesmo id"
        exit 4;
    fi

    #check if this username is available
    local checkName=$( cat /etc/passwd | cut -d':' -f1-3 | grep -e "^$username:" )
    if [ -n "$checkName" ]; then
        echo $0": Impossível cadastrar usuário, nome de usaurio já está em uso"
        exit 9
    fi

    #checks if exist the same gruop id
    local checkGID=$( cat /etc/group | grep -e ":$gID:" )
    if [ -n "$checkGID" ]; then
        local checkGName=$( cat /etc/group | grep -e "^$groupname:" )
        if [ -n "$checkGName" ]; then
            if [ "$checkGname" != "$checkGID" ]; then
                echo $0": Impossível cadastrar usuário, nome e id de grupo já em uso"
                exit 51
            fi
        else
            echo $0": Impossivel cadastrar usuário, id de grupo já em uso"
        fi
    fi

    #checks if exist the same groupname
    local checkGName=$( cat /etc/group | grep -e "^$groupname:" )
    if [ -n "$checkGName" ]; then
        #checks if the group and gid isnt the same, if is the same, there is no problems
        if [ "$checkGName" != "$checkGID" ]; then
            echo $0": Impossível cadastrar usuário, nome de grupo já está em uso"
            exit 51
        fi
    fi

   #adds on files
    echo $passwd >> /etc/passwd
    echo $group >> /etc/group
    echo $shadow >> /etc/shadow

    #cria home
    local homedir=$( echo $passwd | cut -d':' -f6 )
    if [ ! -e $homedir ]; then
        mkdir -p "$homedir"
        #copy skel home
        cp -a /etc/skel/. "$homedir"
        #chown to the user
        chown -R $username:$groupname "$homedir"
    fi
}

remove_group(){
    local group=$1
    #get user that is direct from this group
    local username=$( echo $group | cut -d':' -f1);
    local userDetail=$( cat /etc/passwd | cut -d':' -f1-3 | grep -e "^$username:")
    echo $0": Removendo usuário "$username" do group"

    #remove user that is from this group
    remove_user "$userDetail"

    #remove group from groups
    local temp=$(mktemp)
    sed "/^$group$/d" /etc/group > $temp
    cp $temp /etc/group
    chown root:root /etc/group
    chmod 644 /etc/group
    rm $temp
}

remove_user(){
    local userDetail=$1
    local userName=$( echo $userDetail | cut -d':' -f1 );
    echo $0": Removendo usuário "$userName" do passwd e shadow"

    #remove from passwd
    local temp=$(mktemp)
    sed "/^$userDetail:/d" /etc/passwd > $temp
    cp $temp /etc/passwd
    chown root:root /etc/passwd
    chmod 644 /etc/passwd
    rm $temp

    #remove from shadow
    local temp=$(mktemp)
    sed "/^$userName:/d" /etc/shadow > $temp
    cp $temp /etc/shadow
    chown root:shadow /etc/shadow
    chmod 640 /etc/shadow
    rm $temp
}

#This script can only be executed by a root/sudoer user
if [ "$(/usr/bin/id -r -u)" != "0" ]; then
    echo $0": Você não possue as permissoes necessárias para realizar essa operação"
    exit 1
fi

passwd=$1
group=$2
shadow=$3
globalFlag=$4

username=$( echo $passwd | cut -d':' -f1 )
uID=$( echo $passwd | cut -d':' -f3 )
globalID=$( echo $uID | grep -e "^3....$" )
localID=$( echo $uID | grep -e "^2....$" -e "^1....$" )

groupname=$( echo $group | cut -d':' -f1 )
gID=$( echo $group | cut -d':' -f3 )
globalGID=$( echo $gID | grep -e "^3....$" )
localGID=$( echo $gID | grep -e "^2....$" -e "^1....$" )

#DEBUG
#echo "username: "$username;
#echo "uID: "$uID;
#echo "globalID: "$globalID;
#echo "localID: "$localID;
#echo ""
#echo "groupname: "$groupname;
#echo "gID: "$gID;
#echo "globalGID: "$globalGID;
#echo "localGID: "$localGID;
#echo ""
#echo "globalFlag: "$globalFlag;
#echo ""

#globalUser
#if not(globalFlag) && ( globalID || globalGID )
if [ "$globalFlag" != "global" ] && ( [ -n "$globalID" ] || [ -n "$globalGID" ] ); then
    exit 21
fi

#if globalFlag && ( not(globalID) || not(globalGID) )
if [ "$globalFlag" = "global" ] && ( [ -z "$globalID" ] || [ -z "$globalGID" ] ); then
    exit 24
fi

#if globalFlag && globalID && globalGID
if [ "$globalFlag" = "global" ] && [ -n "$globalID" ] && [ -n "$globalGID" ]; then
    #add user global
    add "$passwd" "$group" "$shadow"
    echo $0": Usuário global adicionado corretamente"
    exit 0
fi

#Uma vez que não possui uid ou gid global, se nao possuir id local esta fora do range
if [ -z "$localID" ] || [ -z "$localGID" ]; then
    echo $0": Usuario fora do range do local accounts"
    exit 32
fi

#See if exist the username that we are tryng to add with non local ID
checkNotLocalName=$( cat /etc/passwd | cut -d':' -f1,3 | grep -v -e ":2....$" -e ":1....$" | grep -e "^$username:" )
if [ -n "$checkNotLocalName" ]; then
    echo $0": Usuario não local com mesmo username"
    exit 22
fi

#See if exists the group name that we are trying to add with non local GID
checkNotLocalGroupName=$( cat /etc/group | grep -v -e ":2....:" -e ":1....:" | grep -e "^$groupname:" )
if [ -n "$checkNotLocalGroupName" ]; then
    echo $0": Usuario não local com mesmo group name"
    exit 22
fi

checkGID=$( cat /etc/group | grep -e ":$gID:" )
if [ -n "$checkGID" ]; then
    echo $0": encontrei outro usuario local com o mesmo id de grupo, devo remove-lo"
    remove_group "$checkGID"
fi

checkGName=$( cat /etc/group | grep -e "^$groupname:" )
if [ -n "$checkGName" ]; then
    echo $0": encontrei outro usuario local com o mesmo nome de grupo, devo remove-lo"
    remove_group "$checkGName"
fi

checkName=$( cat /etc/passwd | cut -d':' -f1-3 | grep -e "^$username:" )
if [ -n "$checkName" ]; then
    echo $0": encontrei outro usuario local com o mesmo nome, devo remove-lo"
    remove_user "$checkName"
fi

checkID=$( cat /etc/passwd | cut -d':' -f1-3 | grep -e ":$uID$" )
if [ -n "$checkID" ]; then
    echo $0": encontrei outro usuario local com o mesmo id, devo remove-lo"
    remove_user "$checkID"
fi

#add local user
add "$passwd" "$group" "$shadow"
echo $0": Usuario local adicionado corretamente"
exit 0

