#!/opt/alt/python27/bin/python2.7

# Adds DA admin to fs.proc_super_gid and sudoers

import os
import sys
import grp
import subprocess

import clcontrollib
from clsudo import (Clsudo, NoSuchGroup, UnableToReadFile, UnableToWriteFile)
from clcommon.sysctl import SysCtlConf, SYSCTL_CL_CONF_FILE
from clcommon.clfunc import exit_with_error
from cl_proc_hidepid import remount_proc

# Default admins group
DEFAULT_GROUP_NAME = "admin"

# Group name for fs.proc_super_gid
SUPER_GROUP_NAME = "clsupergid"

# Groupname for sudoers
SUDOERS_GROUP_NAME = "clsudoers"

ADMINS_FILE = "/usr/local/directadmin/data/admin/admin.list"


# Add user to group
def add_user_to_group(user_name, group_name):
    retcode = subprocess.call(["/usr/bin/gpasswd", "-a", user_name, group_name])
    if retcode != 0:
        return False
    return True


def add_admins_into_group(group_name):
    if not os.path.exists(ADMINS_FILE):
        return
    try:
        admins_file = open(ADMINS_FILE, 'r')
        admins = admins_file.readlines()
        admins_file.close()
    except OSError:
        return
    for admin in admins:
        add_user_to_group(admin.strip('\n'), group_name)


# Create group
def create_group(group_name):
    retcode = subprocess.call(["/usr/sbin/groupadd", "-f", group_name])
    if retcode != 0:
        return False
    return True


def main():
    """To make admins fully functional on DA servers:
        On install
        1. add all admins into sudo list of admins /usr/local/directadmin/data/admin/admin.list
        2. create a separate clsupergid group (in /etc/groups), and add all admins there.
           We can possibly setup sudo to authorize commands for clsupergid group
           -> and stop updating sudo for each admin.
        3. create a separate clsupergid group (in /etc/groups), and add all admins there.
           Set fs.proc_super_gid to that group id

        On update:
        1. Check for all admins that they are in sudo
        2. create a separate clsupergid group (in /etc/groups) if it doesn't exist,
           and add any admins that are not in that group to that group
        3. if fs.proc_super_gid is set to default, switch it to clsupergid group
    :return:
    """
    if len(sys.argv) != 2:
        sys.exit(1)

    user_name = sys.argv[1]
    dir_adm = clcontrollib.DirectAdmin()
    # exit, if user is not DA admin
    if not dir_adm.is_da_admin_for_hook(user_name):
        sys.exit(1)

    try:
        # create groups
        if not create_group(SUPER_GROUP_NAME):
            raise Exception("ERROR: Can't create %s group\n" % SUPER_GROUP_NAME)

        if not create_group(SUDOERS_GROUP_NAME):
            raise Exception("ERROR: Can't create %s group\n" % SUDOERS_GROUP_NAME)

        # get group id of group: admin
        try:
            admin_gid = str(grp.getgrnam(DEFAULT_GROUP_NAME).gr_gid)
        except KeyError:
            create_group(DEFAULT_GROUP_NAME)
            admin_gid = str(grp.getgrnam(DEFAULT_GROUP_NAME).gr_gid)

        # Determine SUPER_GROUP_NAME gid
        super_gid = str(grp.getgrnam(SUPER_GROUP_NAME).gr_gid)

        sysctl_cfg = SysCtlConf(config_file=SYSCTL_CL_CONF_FILE)
        proc_super_gid = sysctl_cfg.get('fs.proc_super_gid')
        # fs.proc_super_gid option and gid found
        if proc_super_gid == admin_gid:
            # modify fs.proc_super_gid option to super_gid
            sysctl_cfg.set('fs.proc_super_gid', super_gid)
            add_admins_into_group(SUPER_GROUP_NAME)
        else:
            try:
                proc_super_gid = int(proc_super_gid)
            except ValueError:
                exit_with_error("Bad fs.proc_super_gid option value in /etc/sysctl.conf")
            # add admins into custom proc_super_gid group
            proc_super_name = grp.getgrgid(proc_super_gid).gr_name
            add_admins_into_group(proc_super_name)

        # Add new admin to all groups
        if not add_user_to_group(user_name, SUPER_GROUP_NAME):
            raise Exception("ERROR: Can't add user %s to %s group\n" % (
                user_name, SUPER_GROUP_NAME))

        if not add_user_to_group(user_name, SUDOERS_GROUP_NAME):
            raise Exception("ERROR: Can't add user %s to %s group\n" % (
                user_name, SUDOERS_GROUP_NAME))

        # Add SUDOERS_GROUP_NAME group to /etc/sudoers
        sudo = Clsudo()
        sudo.add_lvemanager_group(SUDOERS_GROUP_NAME)

        # CAG-796: use hidepid=2 when mounting /proc
        remount_proc()
    except Exception, e:
        exit_with_error(e)


if __name__ == "__main__":
    main()
