Op 28-10-2023 om 13:22 schreef Rowland Penny via samba:> 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.
You mention 2 other attributes: 'msDS-UserPasswordExpiry' and
DS-User-Password-Expired'. I just check them, both are not supported in
4.19.2.>
>> 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.
Fair point, so this is not a good query anyway.>
>> 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.
You are right, this is preferable, but not always the case.
For example Samba does not support? MFA, an application that does this
can use Samba as its user database but has to perform the MFA
authentication with its own mechanism.
The situation I have is that you can login with MFA (from internet)
while you are blocked with normal authentication (when in the office)
when your password is expired. That is definitely not alright!
>
>> 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 can, I used it in the past to set 512 / 514 for enabled / disabled
account. Now I am using samba-tool for it because that is easier with a
bit-field (because other values than 512/ 514 can be there and you just
want to toggle bit-1 (the 2), which would make the code a bit complexer).
As an alternative the cron-script you set / reset some value in another
(used) attribute, which can then be used in queries.
> you are still going to need a script to check if it contains
'8388608'.
This is easy, there is a special LDAP function to query bit-values, the
same as for account disabled:
(!(userAccountControl:1.2.840.113556.1.4.803:=2)) # for not disabled
(!(userAccountControl:1.2.840.113556.1.4.803:=8388608)) # for not expired
- Kees.
>
> Rowland
>