#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Univention Samba4 Password sync
#  sync the password from UCS to Samba4
#
# Like what you see? Join us!
# https://www.univention.com/about-us/careers/vacancies/
#
# Copyright 2010-2022 Univention GmbH
#
# https://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided 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 with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <https://www.gnu.org/licenses/>.

from __future__ import print_function

from univention.config_registry import ConfigRegistry
import univention.uldap
import univention.admin.uldap
import ldap
import univention.debug2 as ud
import univention.s4connector.s4.password
from argparse import ArgumentParser
import sys


class S4(object):

	def __init__(self, ucrbase, binddn, bindpwdfile):
		self.ucrbase = ucrbase
		self.ucr = ConfigRegistry()
		self.ucr.load()

		if binddn:
			self.ucr['%s/ldap/binddn' % (ucrbase,)] = binddn
		if bindpwdfile:
			self.ucr['%s/ldap/bindpw' % (ucrbase,)] = bindpwdfile

		self.s4 = univention.s4connector.s4.s4.main(self.ucr, ucrbase)
		self.s4.init_ldap_connections()
		self.s4._object_mapping = self._object_mapping
		self.s4.modules = {
			"user": univention.admin.modules.get("users/user")
		}

	def _object_mapping(self, key, object, connection):
		return key

	def sync_password(self, username):
		try:
			ucs_dn = self.s4.lo.lo.search(base=self.s4.lo.base, scope='sub', filter=ldap.filter.filter_format('(&(objectClass=sambaSamAccount)(uid=%s))', [username]), attr=['dn'])[0][0]
		except (ldap.NO_SUCH_OBJECT, IndexError):
			ud.debug(ud.LDAP, ud.PROCESS, "password_ucs_to_s4: The UCS user (%s) was not found." % username)
			print("password_ucs_to_s4: The UCS user (%s) was not found." % username)
			return
		ucs_object = {}
		ucs_object['dn'] = ucs_dn

		try:
			s4_dn = self.s4.lo_s4.lo.search_s(self.s4.lo_s4.base, ldap.SCOPE_SUBTREE, '(&(objectClass=user)(!(objectClass=computer))(cn=%s))' % username, ['dn'])[0][0]
		except (ldap.NO_SUCH_OBJECT, IndexError):
			ud.debug(ud.LDAP, ud.PROCESS, "password_ucs_to_s4: The Samba4 user (%s) was not found." % username)
			print("password_ucs_to_s4: The Samba4 user (%s) was not found." % username)
			return
		except ldap.SERVER_DOWN:
			print("Can't initialize Samba4 LDAP connection")
			raise

		s4_object = {}
		s4_object['dn'] = s4_dn
		univention.s4connector.s4.password.password_sync_ucs_to_s4(self.s4, ucs_object, s4_object)


def main():
	parser = ArgumentParser()
	parser.add_argument("--ucrbase", help="", metavar="ucrbase", default="connector")
	parser.add_argument("--binddn", help="Binddn for UCS LDAP connection", default=None)
	parser.add_argument("--bindpwd", help="Not supported anymore.", default=None)
	parser.add_argument("--bindpwdfile", help="Bindpwdfile for UCS LDAP connection", default=None)
	parser.add_argument('username')
	options = parser.parse_args()
	if options.bindpwd:
		parser.error('--bindpwd is not supported anymore!')  # joinscript api: bindpwdfile

	try:
		s4 = S4(options.ucrbase, options.binddn, options.bindpwdfile)
		s4.sync_password(options.username)
	except ldap.SERVER_DOWN:
		sys.exit(1)


if __name__ == '__main__':
	main()
