#!/usr/bin/python -u
# -*- coding: utf-8 -*-

"""Apply configuration of EOLE servers.
Demande le mot de passe de l'utilisateur "Administrator" et le stocke dans le fichier
/var/lib/samba/.eole-ad-dc
Fichier utilisé par les autres eole-ad-dc joints au domaine
"""

import os
import sys
import getpass
import traceback

def checkPassword( pw ):
    """ See https://wiki.samba.org/index.php/Samba_AD_DC_HOWTO
       Containing at least three of the following five character groups
       Uppercase characters of European languages (A through Z, with diacritic marks, Greek and Cyrillic characters)
       Lowercase characters of European languages (a through z, sharp-s, with diacritic marks, Greek and Cyrillic characters)
       Base 10 digits (0 through 9)
       Nonalphanumeric characters: ~!@#$%^&*_-+=`|\(){}[]:;"'<>,.?/
       Any Unicode character that is categorized as an alphabetic character but is not uppercase or lowercase. This includes Unicode characters from Asian languages.

       If the password doesn't fulfil the complexity requirements, the provisioning will fail and you will have to start over (remove the generated new "smb.conf" in that case).
    """
    s_lc = set(['a', 'c', 'b', 'e', 'd', 'g', 'f', 'i', 'h', 'k', 'j', 'm', 'l', 'o', 'n', 'q', 'p', 's', 'r', 'u', 't', 'w', 'v', 'y', 'x', 'z'])
    s_uc = set(['A', 'C', 'B', 'E', 'D', 'G', 'F', 'I', 'H', 'K', 'J', 'M', 'L', 'O', 'N', 'Q', 'P', 'S', 'R', 'U', 'T', 'W', 'V', 'Y', 'X', 'Z'])
    s_dg = set(['1', '0', '3', '2', '5', '4', '7', '6', '9', '8'])
    s_sp = set([ '~', '!', '@','#','$','%','^','&','*',"'",'_','-','+','=','`','|','\\','(',')','{','}','[',']',':',';','"',"'",'<','>',',','.','?','/',',','.'])
    s_pw = set(pw)
    pw_l = len(pw)

    c_lc = len(s_pw & s_lc)
    c_uc = len(s_pw & s_uc)
    c_dg = len(s_pw & s_dg)
    c_sp = len(s_pw & s_sp)

    forbidden = s_pw - s_lc - s_uc - s_dg - s_sp

    if (forbidden):
        print("Forbidden chracter{}: {}".format('s' * (len(forbidden) > 1),
                                                list(forbidden)))
        return False

    if ( c_lc == 0 ) :
        print( "Password must have at least one lower case char")
        return False

    if ( c_uc == 0 ):
        print( "Password must have at least one upper case char")
        return False

    if ( c_dg == 0 ):
        print( "Password must have at least one digit char")
        return False

    if ( c_sp == 0 ):
        print( "Password must have at least one char in : ~!@#$%^&*_-+=`|\\(){}[]:;""''<>,.?/ " )
        return False

    if ( pw_l < 8 ):
        print ('password must have more than 8 characters')
        return False

    return True

def getADPwd(verify=True):
    """
    Check exist /root/.eole-ac-dc
    even get pwd and write file
    """
    passordFile = '/var/lib/samba/.eole-ad-dc'
    try:
        if os.path.isfile(passordFile):
            print(u"Active Directory Administrator password has been initialized")
            print(passordFile)
            sys.exit(0)

        print (u'Active Directory "Administrator" password')
        for attempt in range(1, 15):
            passwd = getpass.getpass(u"Enter password :")
            if checkPassword( passwd ):
                if verify:
                    confirm_pass = getpass.getpass(u"Retype password :")
                    if passwd != confirm_pass:
                        print (u"Passwords mismatch.")
                        continue
                with file( passordFile ,"w") as fh:
                    fh.write( passwd + "\n" );
                    os.chmod( passordFile, 0600)
                sys.exit(0)

        print (u"Too many try, Cancel." )
        sys.exit(1)
    except Exception, err:
        traceback.print_exc()
        print (u"Exception in get AD Administrator password" )
        sys.exit(2)

if __name__ == '__main__':
    if len(sys.argv) > 1 and 'noverify' == sys.argv[1].lower():
        # Ne pas demander confirmation du mot de passe sur le "member"
        getADPwd(False)
    else:
        getADPwd()
