# Standard modules
import logging
import os
-import pwd
import getpass
# Third party modules
-from ldap3 import MODIFY_REPLACE, MODIFY_ADD, MODIFY_DELETE
+# from ldap3 import MODIFY_REPLACE, MODIFY_ADD, MODIFY_DELETE
+from ldap3.core.exceptions import LDAPBindError
import passlib.apps
# Own modules
-from fb_tools.common import to_bool, is_sequence, pp
+# from fb_tools.common import to_bool, is_sequence, pp
+from fb_tools.common import is_sequence
from ..xlate import XLATOR
-from . import AbortAppError, TimeoutOnPromptError
-
-from .ldap import LdapAppError, FatalLDAPError
+from .ldap import LdapAppError
from .ldap import BaseLdapApplication
from .ldap import PasswordFileOptionAction
-__version__ = '0.2.0'
+__version__ = '0.3.1'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
# -------------------------------------------------------------------------
def init_arg_parser(self):
- super(SetLdapPasswordApplication, self).init_arg_parser()
-
app_group = self.arg_parser.add_argument_group(_("Options for {}").format(
self.appname))
pw_group.add_argument(
'-w', '--password', metavar=_("PASSWORD"), dest="current_pw",
- help=_("Use PASSWORD as the current user password."),
+ help=_("Use {} as the current user password.").format(_("PASSWORD")),
)
pw_group.add_argument(
pw_group.add_argument(
'-y', '--password-file', metavar=_('PASSWORD_FILE'), dest="current_pw_file",
must_absolute=False, action=PasswordFileOptionAction,
- help=_("Use contents of PASSWORD_FILE as the current user password."),
+ help=_("Use contents of {} as the current user password.").format(_('PASSWORD_FILE')),
+ )
+
+ app_group.add_argument(
+ '-n', '--new-password', metavar=_("PASSWORD"), dest="new_pw",
+ help=_(
+ "Use {} as the new user password. If not given, it will be "
+ "asked for it.").format(_("PASSWORD")),
)
user_help = _(
- "The user, which password in the given LDAP instance should be changed. "
- "It may be given by its Uid (the alphanumeric POSIX name), its mail address "
- "or its LDAP DN.")
+ "The user, which password in the given LDAP instance should be changed. "
+ "It may be given by its Uid (the alphanumeric POSIX name), its mail address "
+ "or its LDAP DN.")
if self.current_user:
user_help += ' ' + _(
"If not given, then your current user name {!r} will be used.").format(
app_group.add_argument(
'user', metavar=_('USER'), help=user_help)
+ super(SetLdapPasswordApplication, self).init_arg_parser()
+
# -------------------------------------------------------------------------
def post_init(self):
"""
self.current_password = self.read_password_file(self.args.current_pw_file)
self.do_user_bind = True
+ if self.args.new_pw:
+ self.new_password = self.args.new_pw
+
inst = self.ldap_instances[0]
ldap = self.cfg.ldap_connection[inst]
if not ldap.is_admin or ldap.readonly:
LOG.debug("Pre running tasks ...")
super(SetLdapPasswordApplication, self).pre_run()
+ # -------------------------------------------------------------------------
+ def _run(self):
+
+ inst = self.ldap_instances[0]
+ connect_info = self.cfg.ldap_connection[inst]
+ msg = _("Using LDAP instance {inst!r} - {url}.").format(inst=inst, url=connect_info.url)
+ LOG.info(msg)
+
+ self.user_dn = self.search_user_dn()
+
if self.do_user_bind and not self.current_password:
first_prompt = _("Current password of user {!r}:").format(self.user_uid) + ' '
second_prompt = _('Repeat password:') + ' '
self.current_password = self.get_password(
first_prompt, second_prompt, may_empty=False, repeat=False)
+ if self.do_user_bind:
+ self.test_user_bind()
+
+ if not self.new_password:
+ first_prompt = _("New password of user {!r}:").format(self.user_uid) + ' '
+ second_prompt = _('Repeat password:') + ' '
+ self.new_password = self.get_password(
+ first_prompt, second_prompt, may_empty=False, repeat=True)
+
# -------------------------------------------------------------------------
- def _run(self):
+ def test_user_bind(self):
inst = self.ldap_instances[0]
- ldap = self.cfg.ldap_connection[inst]
- msg = _("Using LDAP instance {inst!r} - {url}.").format(inst=inst, url=ldap.url)
- LOG.info(msg)
+ connect_info = self.cfg.ldap_connection[inst]
+
+ msg = _(
+ "Testing connect to LDAP-Server {url} with current user {dn!r} and "
+ "password ...").format(url=connect_info.url, dn=self.user_dn)
+ LOG.debug(msg)
+
+ ldap_server = None
+ ldap_connection = None
+
+ try:
+ ldap_server = self.get_ldap_server_obj(inst)
+ ldap_connection = self.connect_to_ldap_server(
+ ldap_server, inst, bind_dn=self.user_dn, bind_pw=self.current_password)
+ msg = _("Successful connected as {dn!r} to {url}.").format(
+ url=connect_info.url, dn=self.user_dn)
+ LOG.debug(msg)
+
+ except LDAPBindError as e:
+ msg = _("Could not connect to {url} as {dn!r}: {e}").format(
+ url=connect_info.url, dn=self.user_dn, e=e)
+ self.exit(6, msg)
+
+ finally:
+ if ldap_connection:
+ if self.verbose > 1:
+ LOG.debug(_("Unbinding from LDAP server {!r} ...").format(connect_info.url))
+ ldap_connection.unbind()
+ ldap_connection = None
+ del ldap_connection
+
+ if ldap_server:
+ if self.verbose > 1:
+ LOG.debug(_("Disconnecting from LDAP server {!r} ...").format(
+ connect_info.url))
+ del ldap_server
+
+ # -------------------------------------------------------------------------
+ def search_user_dn(self):
+ """Searching the LDAP DN of the user, whos password should be changed."""
+
+ inst = self.ldap_instances[0]
+ connect_info = self.cfg.ldap_connection[inst]
+
+ dns = self.get_user_dn(self.user_uid, inst)
+ if dns:
+ if self.verbose > 2:
+ msg = _("Got DN {dn!r} for user {user!r} in LDAP instance {inst}.").format(
+ dn=dns, user=self.user_uid, inst=connect_info.url)
+ LOG.debug(msg)
+ if is_sequence(dns):
+ if len(dns) > 1:
+ msg = _("Found {nr} entries for user {u!r} in LDAP instance {i}.").format(
+ nr=len(dns), u=self.user_uid, i=connect_info.url)
+ msg += ' ' + _(
+ "Please use another username, or use the correct DN from the following "
+ "list as a parameter for this script instead of the username:")
+ for dn in dns:
+ msg += '\n * ' + dn
+ LOG.warn(msg)
+ self.exit(7)
+ return
+ self.user_dn = dns[0]
+ else:
+ self.user_dn = dns
+ else:
+ msg = _("Did not found user {user!r} in LDAP instance {inst}.").format(
+ user=self.user_uid, inst=connect_info.url)
+ LOG.error(msg)
+ self.exit(7)
+
+ LOG.info(_("Changing the password of user {dn!r} in LDAP instance {inst}.").format(
+ dn=self.user_dn, inst=connect_info.url))
# =============================================================================