Source code for univention.admincli.passwd

#!/usr/bin/python3
# SPDX-FileCopyrightText: 2004-2025 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only

"""passwd part for the command line interface"""

import getopt
import os
from logging import DEBUG, getLogger

from ldap.filter import filter_format

import univention.admin.modules
import univention.admin.objects
import univention.admin.uldap
import univention.config_registry
import univention.logging


log = getLogger('ADMIN')


[docs] def doit(arglist): configRegistry = univention.config_registry.ConfigRegistry() configRegistry.load() structured = configRegistry.is_true('directory/manager/cmd/debug/structured-logging', False) univention.logging.basicConfig(filename='/var/log/univention/directory-manager-cmd.log', level=DEBUG, use_structured_logging=structured) out = [] opts, _args = getopt.getopt(arglist[1:], '', ['binddn=', 'pwdfile=', 'user=', 'pwd=']) binddn = None pwdfile = None user = None pwd = None for opt, val in opts: if opt == '--binddn': binddn = val elif opt == '--pwdfile': pwdfile = val elif opt == '--user': user = val elif opt == '--pwd': pwd = val baseDN = configRegistry['ldap/base'] with open(pwdfile) as fd: bindpw = fd.read().rstrip() log.warning('binddn: %s; bindpwd: *************', binddn) try: lo = univention.admin.uldap.access(host=configRegistry['ldap/master'], port=int(configRegistry.get('ldap/master/port', '7389')), base=baseDN, binddn=binddn, bindpw=bindpw) except Exception as exc: log.warning('authentication error: %s', exc) out.append('authentication error: %s' % (exc,)) return out if isinstance(user, bytes): # Python 2 user = user.decode('utf-8') if configRegistry.get('samba/charset/unix', 'utf8') in ['utf8', 'latin']: log.debug('univention-passwd: known charset given: %s', configRegistry.get('samba/charset/unix')) if not isinstance(pwd, bytes): # Python 3 pwd = pwd.encode('UTF-8') pwd = pwd.decode(configRegistry.get('samba/charset/unix', 'utf8')) else: log.debug('univention-passwd: unknown charset given, try fallback') if isinstance(pwd, bytes): # Python 2 pwd = pwd.decode('utf-8') try: dn = lo.searchDn(filter=filter_format('(&(uid=%s)(|(objectClass=posixAccount)(objectClass=sambaSamAccount)(objectClass=person)))', [user]), base=baseDN, unique=True) position = univention.admin.uldap.position(baseDN) module = univention.admin.modules._get('users/user') univention.admin.modules.init(lo, position, module) object = univention.admin.objects.get(module, None, lo, position=position, dn=dn[0]) object.open() # hack, to prevent that attributes belonging to the samba option are changed; Bug #41530 if 'samba' in object.options: object.options.remove('samba') object.old_options.remove('samba') object._ldap_object_classes = lambda ml: ml object['password'] = pwd log.debug('univention-passwd: passwd set, modify object') dn = object.modify() out.append('password changed') log.debug('univention-passwd: password changed') except univention.admin.uexceptions.pwalreadyused: out.append('passwd error: password already used') return out except Exception as exc: log.warning('passwd error: %s', exc) out.append('passwd error: %s' % (exc,)) return out try: # check for local ldap server connection if configRegistry.is_true('ldap/replication/preferredpassword') and configRegistry.get('ldap/server/type') == 'slave' and os.path.exists('/etc/ldap/rootpw.conf'): lo = univention.admin.uldap.access(lo=univention.uldap.getRootDnConnection()) dn = lo.searchDn(filter=filter_format('(&(uid=%s)(|(objectClass=posixAccount)(objectClass=sambaSamAccount)(objectClass=person)))', [user]), base=baseDN, unique=True) position = univention.admin.uldap.position(baseDN) module = univention.admin.modules._get('users/user') univention.admin.modules.init(lo, position, module) object = univention.admin.objects.get(module, None, lo, position=position, dn=dn[0]) object.open() object['password'] = pwd log.debug('univention-passwd: passwd set, modify object') object['overridePWHistory'] = '1' object['overridePWLength'] = '1' dn = object.modify() log.debug('univention-passwd: password changed') except Exception as exc: log.warning('passwd error: %s', exc) return out