AD Connector stuck after server password change

Hi all,

I want to share my experience with AD Connector regarding a specific problem: the “Server Password Change” mechanism when the UCS server is in “AD Member Mode”.

It happened that the password of the machine account in AD could not be changed (caused by improper network setup at customer’s site). This left us with a weird state:

  • the new password was recorded in /etc/machine.secret
  • the machine account in AD kept the old password

This, in turn, caused the AD connector to fail with the error message every 30 seconds:

 --- connect failed, failure was: ---
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/univention/connector/ad/", line 302, in main
  File "/usr/lib/python2.7/dist-packages/univention/connector/ad/", line 190, in connect
    baseConfig['%s/ad/listener/dir' % CONFIGBASENAME]
  File "/usr/lib/python2.7/dist-packages/univention/connector/ad/", line 842, in __init__
  File "/usr/lib/python2.7/dist-packages/univention/connector/ad/", line 1038, in open_ad
  File "/usr/lib/python2.7/dist-packages/univention/connector/ad/", line 1016, in get_kerberos_ticket
    raise kerberosAuthenticationFailed('The following command failed: "%s" (%s): %s' % (string.join(cmd_block), p1.returncode, stdout))
kerberosAuthenticationFailed: The following command failed: "kinit --no-addresses --password-file=/etc/machine.secret hostname$" (1): kinit: Password incorrect

One might think, ‘simply write the old password into /etc/machine.secret, and all will be ok’ but then we would have to re-invoke all the handlers in /usr/lib/univention-server/server_password_change.d with the right preconditions – better we avoid this: it’s too easy to confuse these scripts and leave the system with more inconsistencies than those we already have.

We wanted to solve this by reapplying only the one step that failed in the first place: setting the new (current) password into AD.

Looking at /usr/lib/univention-server/server_password_change.d/univention-samba, we see:

 89         # change password on ad in member mode
 90         if samba_role == 'memberserver' and univention.lib.admember.is_localhost_in_admember_mode(ucr=ucr):
 91                 cmd = ['/usr/bin/net', 'ads', 'password', '-P']
 92                 cmd.append('%s$' % ucr.get('hostname', '').upper())
 93                 cmd.append('%s' % machine_password)
 94                 process = subprocess.Popen(cmd)
 95                 process.wait()

Seems we could simply call net ads password -P machine$ manually. But the -P switch takes the initial password from Samba’s secrets.tdb, so this is expected to fail, since there we already have the new password which does not match with AD. Let’s set it to the right value.

  • stop all services which are using /var/lib/samba/private/secrets.tdb, in our case these were smbd and winbind. (check with fuser /var/lib/samba/private/secrets.tdb until the output is empty). Stop the ad connector service too, so it won’t try anything while we’re at it.
  • look into the secrets database: which secret is currently stored there:
tdbtool /var/lib/samba/private/secrets.tdb show SECRETS/MACHINE_PASSWORD/DOMAINNAME

We’ll see that Samba has the new password, and that’s why it can’t authenticate against AD.

  • now set the old password back into Samba’s database:
tdbtool /var/lib/samba/private/secrets.tdb store SECRETS/MACHINE_PASSWORD/DOMAINNAME TheOldPassword
  • Start all the services we had stopped.

And now, we can re-invoke the command to set the password:

net ads password -P 'MACHINE$' $(cat /etc/machine.secret)

This would change the password in AD, and additonally update Samba’s knowledge about the now-changed password. -> Problem solved.