# CCS Computer Science
#   Admin
#
# Douglas Thrift
#
# $Id$

from __future__ import with_statement
import common
import ldap
import subprocess
import sys

MASTER = 'zweihander.ccs.ucsb.edu'
BASE = 'dc=ccs,dc=ucsb,dc=edu'
SHELLS = map(lambda system: 'ucsbCcs' + system.capitalize(), common.SYSTEMS)

ldap.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, '/ccs/ssl/ccscert.pem')
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)

def _user(user):
	return 'uid=%s,ou=People,%s' % (user, BASE)

def ldap_connection():
	connection = ldap.initialize('ldaps://' + MASTER)

	with open('/ccs/etc/secret', 'rb') as secret:
		connection.simple_bind_s(_user('root'), secret.read())
	
	return connection

def master():
	return common.HOST == MASTER

def run(errors):
	if errors:
		for host, error in errors.iteritems():
			sys.stderr.write('%s: %s\n' % (host, error))

		sys.exit(1)

def error(error):
	sys.exit('%s: %s' % (sys.argv[0], error))

def eof():
	print

	sys.exit(130)

def chfn(user, name):
	connection = ldap_connection()

	connection.modify_s(_user(user), [(ldap.MOD_REPLACE, 'cn', name)])
	connection.unbind_s()

def chsh(user, shell, shells):
	if shell != 'custom':
		shells = dict(common.SHELLS)[shell]
	else:
		for _shell, _shells in common.SHELLS[:-1]:
			if shells == _shells:
				shell = _shell

	connection = ldap_connection()

	connection.modify_s(_user(user), map(lambda (key, value): (ldap.MOD_REPLACE, key, value), [('loginShell', shell)] + zip(SHELLS, shells)))
	connection.unbind_s()

def passwd(user, old_password, new_password):
	import warnings

	with warnings.catch_warnings():
		warnings.filterwarnings('ignore', 'the sets module is deprecated', DeprecationWarning)

		import MySQLdb

	connection = ldap_connection()

	connection.passwd_s(_user(user), old_password, new_password)
	connection.unbind_s()

	with open('/ccs/etc/secret', 'rb') as secret:
		db = MySQLdb.connect(passwd = secret.read(), db = 'mysql')

	cursor = db.cursor()

	cursor.execute('select count(User) from user where User = %s', (user,))

	if cursor.fetchone()[0]:
		cursor.execute('update user set Password = PASSWORD(%s) where User = %s', (new_password, user))
		cursor.execute('flush privileges');
	else:
		cursor.executemany('grant all on `' + db.escape_string(user) + r'\_%%`.* to %s@%s identified by %s', map(lambda host: (user, host, new_password), ('localhost', '%')))
