[Samba] query account expired state

Rowland Penny rpenny at samba.org
Sat Oct 28 11:22:51 UTC 2023


On Sat, 28 Oct 2023 11:54:34 +0200
Kees van Vloten via samba <samba at lists.samba.org> wrote:

> 
> Op 28-10-2023 om 09:37 schreef Rowland Penny via samba:
> > On Fri, 27 Oct 2023 23:48:22 +0200
> > Kees van Vloten via samba <samba at lists.samba.org> wrote:
> >
> >> Hi Team,
> >>
> >> Is it possible to make a LDAP-query that returns whether an account
> >> is expired or not?
> >>
> >> I am aware that it is possible to do the maths against the
> >> "accountExpires" attribute, but that requires some scripting around
> >> the query.
> >>
> >> - Kees.
> >>
> >>
> > Would that it was so simple.
> >
> > There is a flag 'ADS_UF_PASSWORD_EXPIRED' in the userAccountControl
> > attribute, but you would have to obtain the value from that
> > attribute and check if '8388608' is set, I am not sure if Samba
> > uses this.
> >
> > Windows has replaced the above with the aptly named
> > 'ms-DS-User-Password-Expired' attribute which, as far as I can tell,
> > Samba knows nothing about.
> 
> The unfortunate situation is that Samba (4.19.2) does not implement
> the 'ADS_UF_PASSWORD_EXPIRED' flag. It does support 
> 'msDS-UserPasswordExpiry', but that returns and LDAP time value so it 
> requires computation by the querier to figure out expiry.

I am on 4.18.8 and that doesn't have 'msDS-UserPasswordExpiry' or
'ms-DS-User-Password-Expired', but if it did, then the time stored
would be, as you say, in Windows format.

> 
> Another suggestion from ldapwiki.com: "All expired user accounts: 
> '(&(objectCategory=Person)(objectClass=User)(!accountExpires=0)(!accountExpires=9223372036854775807))'" 
> does not work either. Accounts on Samba always have the value 
> '9223372036854775807'.

accountExpires != the password expiry.
An account can expiry for other reasons than the password expiring and
if the password does expire, then it can be reset and the account
hasn't expired.

> 
> Some output to show all this:
> 
> ldapsearch -x -W -ZZ -H ldap://dc.samdom.com -D 'CN=test 1
> user,OU=User Accounts,DC=samdom,DC=com' -b 'CN=test 1 user,OU=User 
> Accounts,DC=samdom,DC=com' '(objectClass=user)'
> Enter LDAP Password:
> ldap_bind: Invalid credentials (49)
>          additional info: 80090308: LdapErr: DSID-0C0903A9, comment: 
> AcceptSecurityContext error, data 532, v1db1
> # Apparently this seems to mean "expired"...

Perhaps, perhaps not, it could just be an incorrect password.

> 
> /var/log/samba/audit_auth.log:
> {
>    "timestamp":"2023-10-28T11:38:53.865118+0200",
>    "type":"Authentication",
>    "Authentication":{
>      "version":{
>        "major":1,
>        "minor":3
>      },
>      "eventId":4625,
>      "logonId":"0",
>      "logonType":8,
>      "status":"NT_STATUS_PASSWORD_EXPIRED",
>      "serviceDescription":"LDAP",
>      "authDescription":"simple bind/TLS",
>      "clientDomain":"SAMDOM",
>      "clientAccount":"CN=test 1 user,OU=User
> Accounts,DC=samdom,DC=com", "workstation":"DC1",
>      "mappedAccount":"test1",
>      "mappedDomain":"SAMDOM"
> # Shortend output, removed irrelevant key/values
>    }
> }
> 
> ldbsearch -H /var/lib/samba/private/sam.ldb -s sub -b 'CN=test 1 
> user,OU=User Accounts,DC=samdom,DC=com' '(objectClass=user)' 
> userAccountControl accountExpires accountExpires 
> msDS-UserPasswordExpiryTimeComputed 2> /dev/null
> # record 1
> dn: CN=test 1 user,OU=User Accounts,DC=samdom,DC=com
> accountExpires: 9223372036854775807
> userAccountControl: 512
> msDS-UserPasswordExpiryTimeComputed: 133364804925898560
> 
> # returned 1 records
> # 1 entries
> # 0 referrals
> 
> 'userAccountControl' and 'accountExpires' do not show a clue about
> the expiry!
> 
> > So, you are left with a couple of options:
> > Check if the 'computed' attribute
> > 'msDS-UserPasswordExpiryTimeComputed' exists and if it does, turn
> > that into a Unix date. Or calculate the expiry time from the
> > contents of the 'maxPwdAge' and the accounts 'pwdLastSet'
> > attributes.
> 
> This is not an option in applications that just allow a ldap filter 
> (which is basically all applications with the exception of scripts).
> 
> I consider this a big security omission: if  Samba is the source of 
> information but not the the authenticator of the user, that
> application cannot block expired users !

But, Samba when running as an AD DC is the source of information AND
the source of authentication. A user with an expired password will not
be allowed to logon.

> 
> How to proceed from here?
> 
> I guess the real fix to update 'userAccountControl' and/or 
> 'accountExpires' need changes in Samba's C code. In the meantime I
> would like to close this gap, so I am tempted to write a cron-script
> to check expiry and then update 'userAccountControl' every minute or
> so.
> 
> Any other thoughts?

I am not sure if Unix can use 'userAccountControl' and even if it can,
you are still going to need a script to check if it contains '8388608'.

Rowland



More information about the samba mailing list