Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Samba] How to get password expiration?

4,520 views
Skip to first unread message

Jeff Sadowski via samba

unread,
Jan 31, 2017, 11:10:05 AM1/31/17
to
my smb.conf looks as follows.
[global]
security = ads
realm = AD.MYDOMAIN.TLD
workgroup = AD
idmap config * : backend = tdb
idmap config * : range = 2000-7999
idmap config MIND:backend = ad
idmap config MIND:schema_mode = rfc2307
idmap config MIND:range = 8000-9999999
winbind nss info = rfc2307
winbind use default domain = yes
winbind enum users = yes
winbind enum groups = yes
restrict anonymous = 2
ldap server require strong auth = no
client ldap sasl wrapping = plain

I'm connected to an Windows 2008 based Active Directory environment

Is there a linux command users can run to get their password expiration
that they could run from their .bashrc files?

I searched the wiki and the mailing list but couldn't find what I am
looking for.
--
To unsubscribe from this list go to the following URL and read the
instructions: https://lists.samba.org/mailman/options/samba

mathias dufresne via samba

unread,
Feb 1, 2017, 11:50:04 AM2/1/17
to
Plop,

You'd like to modify .bashrc to auto-disconnect user with expired password?
I thought modern tools to use AD (SSSD, winbind, nslcd) would come with
such a mechanism inside. I do believe to remember some Linux disconnecting
me for "disabled user" or "expired password"...

Anyway, don't put that into .bashrc, they can modify it. If you really go
into that way, uses /etc/profile which is owned by root (normally).

In AD (MS and Samba) I believe expiration is calculated. You take current
date, you take pwdLastSet, you take password expiration policy and you
check if password wasn't set to far from now.

But I still believe a well written tool should manage these expirations
automagically when it comes to tools responsible to retrieve users from AD.

Jeff Sadowski via samba

unread,
Feb 1, 2017, 2:20:02 PM2/1/17
to
Or maybe better like so on login

Last login: Wed Feb 1 10:47:53
Password Expires in 28 days
[myaduser@machine ~]$



On Wed, Feb 1, 2017 at 12:10 PM, Jeff Sadowski <jeff.s...@gmail.com>
wrote:

> I want something like so on login
>
> Last login: Wed Feb 1 10:47:53
> Password Expires: Wed March 1 00:00:00
> [myaduser@machine ~]$
>
> I just want them to know when their password expires.

Jeff Sadowski via samba

unread,
Feb 1, 2017, 2:20:02 PM2/1/17
to
I want something like so on login

Last login: Wed Feb 1 10:47:53
Password Expires: Wed March 1 00:00:00
[myaduser@machine ~]$

I just want them to know when their password expires.



On Wed, Feb 1, 2017 at 9:39 AM, mathias dufresne <infra...@gmail.com>
wrote:

Jeff Sadowski via samba

unread,
Feb 1, 2017, 2:30:02 PM2/1/17
to
I was thinking of maybe putting a request update password expire time on
login and have a system user go find the expire times.
with ldap or something?

It could put a file in the users home directory with a timestamp of when
the user's password expires.

Ex:

In the bashrc or tcshrc (the global ones) add a line like so

touch /tmp/requestpwexpupdate/${USER}

and have a cronjob the searches for password expire times in ldap and
removes the request file
placing a timestamped file with the users expiration in ~${USER}/.passwdexp

but I don't know how to write the ldapsearch to do this.



On Wed, Feb 1, 2017 at 12:12 PM, Jeff Sadowski <jeff.s...@gmail.com>

Rowland Penny via samba

unread,
Feb 1, 2017, 3:20:08 PM2/1/17
to
On Wed, 1 Feb 2017 12:20:49 -0700
Jeff Sadowski via samba <sa...@lists.samba.org> wrote:

> I was thinking of maybe putting a request update password expire time
> on login and have a system user go find the expire times.
> with ldap or something?
>
> It could put a file in the users home directory with a timestamp of
> when the user's password expires.
>
> Ex:
>
> In the bashrc or tcshrc (the global ones) add a line like so
>
> touch /tmp/requestpwexpupdate/${USER}
>
> and have a cronjob the searches for password expire times in ldap and
> removes the request file
> placing a timestamped file with the users expiration in
> ~${USER}/.passwdexp
>
> but I don't know how to write the ldapsearch to do this.
>

I don't know if it will help, but I found this, maybe it will point
you in the right direction ;-)

http://stackoverflow.com/questions/34610020/how-to-get-user-password-expiration-date-from-active-directory

Rowland

Andrew Bartlett via samba

unread,
Feb 1, 2017, 3:30:03 PM2/1/17
to
On Tue, 2017-01-31 at 09:00 -0700, Jeff Sadowski via samba wrote:
> my smb.conf looks as follows.
> [global]
>    security = ads
>    realm = AD.MYDOMAIN.TLD
>    workgroup = AD
>    idmap config * : backend = tdb
>    idmap config * : range = 2000-7999
>    idmap config MIND:backend = ad
>    idmap config MIND:schema_mode = rfc2307
>    idmap config MIND:range = 8000-9999999
>    winbind nss info = rfc2307
>    winbind use default domain = yes
>    winbind enum users = yes
>    winbind enum groups = yes
>    restrict anonymous = 2
>    ldap server require strong auth = no
>    client ldap sasl wrapping = plain
>
> I'm connected to an Windows 2008 based Active Directory environment
>
> Is there a linux command users can run to get their password
> expiration
> that they could run from their .bashrc files?
>
> I searched the wiki and the mailing list but couldn't find what I am
> looking for.

When I kinit, I get this info. You might be able to get it from
pam_krb5?

Thanks,

Andrew Bartlett

Brian Candler via samba

unread,
Feb 2, 2017, 7:50:03 AM2/2/17
to
On 01/02/2017 19:12, Jeff Sadowski wrote:
> Or maybe better like so on login
>
> Last login: Wed Feb 1 10:47:53
> Password Expires in 28 days
> [myaduser@machine ~]$
Something like this?

warn_pwd_expire

Defines number of days before pam_winbind starts to warn about
passwords that are going to expire. Defaults to 14 days.

https://www.samba.org/samba/docs/man/manpages/pam_winbind.8.html

mathias dufresne via samba

unread,
Feb 2, 2017, 10:20:02 AM2/2/17
to
@Jeff: ok you just want to calculate and display.

You would need several tools to achieve that on each machine, as ldapsearch
if you don't find a way to retrieve information from DB magically. Perhaps
configuring nsswitch to get info for "shadow" line could help you. I mean
/etc/shadow is supposed (in my own foggy world) to store information about
password, expiration, etc.. I never tried that and never dug neither into
SSSD nslcd nor winbind to check is some is able to generate a shadow map.

So, back to ldapsearch -Y GSSAPI (if your users generate kerberos ticket at
connection time) to retrieve LDAP attribute PwdLastSet. It's not an UNIX
timestamp, it should be called LDAP time stamp or 18-digit LDAP
timestamp...)
Then you will have to compare this PwDLastSet to current and password max
age. Current date is quite easy to retrieve. For Password max age the AD
LDAP attribute is "maxPwdAge".
You should be able to retrieve it using dirty "ldbsearch -H $sam
maxPwdAge=* dn maxPwdAge" then you'll be able to get a nice and clean
ldapsearch...
Then calculation...

The idea of Andrew would be nice if it works...

Brian Candler via samba

unread,
Feb 2, 2017, 11:00:04 AM2/2/17
to
On 02/02/2017 15:17, mathias dufresne wrote:
> So, back to ldapsearch -Y GSSAPI (if your users generate kerberos
> ticket at connection time) to retrieve LDAP attribute PwdLastSet. It's
> not an UNIX timestamp, it should be called LDAP time stamp or 18-digit
> LDAP timestamp...

Aside: it's a Microsoft Win32 FILETIME. (The LDAP standard uses ISO times)

pwdLastSet doesn't tell you when it expires, so you'd have to combine
this with the domain password expiry policy too: i.e. do the equivalent
of "samba-tool domain passwordsettings show"

If he only wants to display the information to the user at login time, I
think the best/easiest place to do this would be in the PAM module which
enforces the password expiry, since it has all the information to hand
already.

Rowland Penny via samba

unread,
Feb 2, 2017, 11:10:04 AM2/2/17
to
On Thu, 2 Feb 2017 15:49:57 +0000
Brian Candler via samba <sa...@lists.samba.org> wrote:

> On 02/02/2017 15:17, mathias dufresne wrote:
> > So, back to ldapsearch -Y GSSAPI (if your users generate kerberos
> > ticket at connection time) to retrieve LDAP attribute PwdLastSet.
> > It's not an UNIX timestamp, it should be called LDAP time stamp or
> > 18-digit LDAP timestamp...
>
> Aside: it's a Microsoft Win32 FILETIME. (The LDAP standard uses ISO
> times)
>
> pwdLastSet doesn't tell you when it expires, so you'd have to combine
> this with the domain password expiry policy too: i.e. do the
> equivalent of "samba-tool domain passwordsettings show"
>
> If he only wants to display the information to the user at login
> time, I think the best/easiest place to do this would be in the PAM
> module which enforces the password expiry, since it has all the
> information to hand already.
>
>

The problem isn't getting the expiry date and time (you can use the
rpcclient command for this), it is getting something to pop-up on the
users desktop with the data.

Rowland

Jeff Sadowski via samba

unread,
Feb 3, 2017, 9:50:03 AM2/3/17
to
This seems to work for maxPwdAge

ldapsearch -LLL -Q -s base -h ad.mydomain.tld -b dc=ad,dc=mydomain,dc=tld
maxPwdAge

now I just need to query a users pwdLastSetq
I tried the commands above but am not getting anything. I tried looking at
the ungrepped output but I don't see how to link the pwdLastSet with any
user. I get a long list.
I think I'm looking for dn: and a matching pwdLastSet? So I tried the
command bellow but I don't see anything that looks like users.


ldapsearch -h ad.mydomain.tld -b 'dc=ad,dc=mydomain,dc=tld' -D
'*@ad.mydomain.tld' -U myusername|grep -e "^pwdLastSet:" -e "^dn:"|less
gives me as follows

dn: DC=ad,DC=mydomain,DC=tld
dn: CN=Computers,DC=ad,DC=mydomain,DC=tld
dn: CN=AD2,OU=Domain Controllers,DC=ad,DC=mydomain,DC=tld
pwdLastSet: 129912036833708410
dn: CN=DC1,OU=Domain Controllers,DC=ad,DC=mydomain,DC=tld
pwdLastSet: 131292041205350825
dn: OU=Domain Controllers,DC=ad,DC=mydomain,DC=tld
dn: CN=DC2,OU=Domain Controllers,DC=ad,DC=mydomain,DC=tld
pwdLastSet: 131300093694348218
dn: CN=OMEGA,OU=Domain Controllers,DC=ad,DC=mydomain,DC=tld
pwdLastSet: 129908837104473721
dn: CN=System,DC=ad,DC=mydomain,DC=tld
dn: CN=RID Manager$,CN=System,DC=ad,DC=mydomain,DC=tld
dn: CN=Users,DC=ad,DC=mydomain,DC=tld
dn: CN=LostAndFound,DC=ad,DC=mydomain,DC=tld
dn: CN=Infrastructure,DC=ad,DC=mydomain,DC=tld
dn: CN=ForeignSecurityPrincipals,DC=ad,DC=mydomain,DC=tld
dn: CN=Program Data,DC=ad,DC=mydomain,DC=tld
dn: CN=Microsoft,CN=Program Data,DC=ad,DC=mydomain,DC=tld
dn: CN=NTDS Quotas,DC=ad,DC=mydomain,DC=tld
dn: CN=Managed Service Accounts,DC=ad,DC=mydomain,DC=tld
dn: CN=WinsockServices,CN=System,DC=ad,DC=mydomain,DC=tld
dn: CN=RpcServices,CN=System,DC=ad,DC=mydomain,DC=tld
dn: CN=FileLinks,CN=System,DC=ad,DC=mydomain,DC=tld
dn: CN=VolumeTable,CN=FileLinks,CN=System,DC=ad,DC=mydomain,DC=tld
dn: CN=ObjectMoveTable,CN=FileLinks,CN=System,DC=ad,DC=mydomain,DC=tld
dn: CN=Default Domain Policy,CN=System,DC=ad,DC=mydomain,DC=tld
dn: CN=AppCategories,CN=Default Domain
Policy,CN=System,DC=ad,DC=mydomain,DC=tld
dn: CN=Meetings,CN=System,DC=ad,DC=mydomain,DC=tld
dn: CN=Policies,CN=System,DC=ad,DC=mydomain,DC=tld
...

mathias dufresne via samba

unread,
Feb 3, 2017, 10:40:04 AM2/3/17
to
Jeff,

you can ask ldapsearch to filter for you rather than using grep.

Just add "PwdLastSet" (no matter the case) after your ldapsearch :

ldapsearch -h ad.mydomain.tld -b 'dc=ad,dc=mydomain,dc=tld' -D
'*@ad.mydomain.tld' -U myusername PwdLastSet

This will retrieve only DN + asked attributes.

Not all user have a password set so they should have a PwdLastSet. Anyway
you don't care they are not real user touching keyboards and making
mistakes. And you only want to display that information to real user making
real mistakes : )

Rowland Penny via samba

unread,
Feb 3, 2017, 11:00:05 AM2/3/17
to
AS I said, you can use rpcclient to do this:

RPCLOOKUPID=$(rpcclient -P -c "lookupnames $USER" dc1)
USERDCID=$(echo "$RPCLOOKUPID" | grep -e '[0-9]\{4,9\} ' -o)
QUERYUSER=$(rpcclient -P -c "queryuser $USERDCID" dc1)
EXPDATE=$(echo "$QUERYUSER" | grep 'Password must change Time' | cut -d
":" -f 2,3,4,5 | sed -e 's/^[[:space:]]*//')

If I feed my name into this, I get:

Thu, 14 Sep 30828 03:48:05 BST

Which is understandable, because my password is set to never expire.
So, unless microsoft doesn't know what they are talking about, the
world will end in 30828 LOL

Rowland

Jeff Sadowski via samba

unread,
Feb 3, 2017, 12:30:02 PM2/3/17
to
Almost there

Is there a way to query by username?

On Fri, Feb 3, 2017 at 8:38 AM, mathias dufresne <infra...@gmail.com>
wrote:

Jeff Sadowski via samba

unread,
Feb 3, 2017, 12:30:03 PM2/3/17
to
Winner this worked wonderfully

Jeff Sadowski via samba

unread,
Feb 3, 2017, 12:30:04 PM2/3/17
to
I'll give rpcclient a try

On Fri, Feb 3, 2017 at 8:51 AM, Rowland Penny via samba <
sa...@lists.samba.org> wrote:

Rowland Penny via samba

unread,
Feb 3, 2017, 12:40:03 PM2/3/17
to
On Fri, 3 Feb 2017 10:25:18 -0700
Jeff Sadowski <jeff.s...@gmail.com> wrote:

> Winner this worked wonderfully
>

When you work out how to pop up a box with inotify or zenity etc when
the user logs in, please let me know, I have tried pam_exec with both
and inotify only seems to work if you are root and zenity doesn't work
at all (well, for me)

Still thinking about how to get it to work

Andrew Bartlett via samba

unread,
Feb 3, 2017, 1:10:02 PM2/3/17
to
On Fri, 2017-02-03 at 07:44 -0700, Jeff Sadowski via samba wrote:
> This seems to work for maxPwdAge
>
> ldapsearch -LLL -Q -s base -h ad.mydomain.tld -b
> dc=ad,dc=mydomain,dc=tld
> maxPwdAge
>
> now I just need to query a users pwdLastSetq

Don't bother. Let Samba do it for you, just query this operational
attribute: 

msDS-UserPasswordExpiryTimeComputed

on the user.

I hope this helps,

Andrew Bartlett
--
Andrew Bartlett http://samba.org/~abartlet/
Authentication Developer, Samba Team http://samba.org
Samba Developer, Catalyst IT http://catalyst.net.nz/services/samba

Jeff Sadowski via samba

unread,
Feb 3, 2017, 1:20:03 PM2/3/17
to
Actually is there a way to show it more like a timestamp. It is hard to
compute days left with a date format like that. I guess I could use date to
do the conversion but I was wondering if there is a cleaner way

On Fri, Feb 3, 2017 at 8:51 AM, Rowland Penny via samba <
sa...@lists.samba.org> wrote:

Jeff Sadowski via samba

unread,
Feb 3, 2017, 1:30:02 PM2/3/17
to
Sorry that was easy enough
let seconds=`date -d "${EXPDATE}" "+%s"`-`date "+%s"`
let days=$seconds/86400
echo $days > /na/homes/$1/.pwd_exp


On Fri, Feb 3, 2017 at 11:15 AM, Jeff Sadowski <jeff.s...@gmail.com>
wrote:

Jeff Sadowski via samba

unread,
Feb 3, 2017, 2:50:03 PM2/3/17
to
On my ubuntu machines I added

auth required pam_exec.so /scripts/password_expire.sh

to the beginning of /etc/pam.d/common-auth

it looks pretty similar to what I did below.
In the /etc/bash.bashrc
I added a check to wait for the file to be less than 1 second old before
looking at it.
break out after 5 seconds in case something failed or is taking longer then
it should.

now people get how many days till their password expires. Thank you all so
much :-)

On Fri, Feb 3, 2017 at 11:22 AM, Jeff Sadowski <jeff.s...@gmail.com>

Rowland Penny via samba

unread,
Feb 3, 2017, 3:00:02 PM2/3/17
to
On Fri, 3 Feb 2017 12:39:20 -0700
Jeff Sadowski via samba <sa...@lists.samba.org> wrote:

> On my ubuntu machines I added
>
> auth required pam_exec.so /scripts/password_expire.sh
>
> to the beginning of /etc/pam.d/common-auth
>

That's where I was going wrong, I added it to common-session, but this
being Unix, I have found another way ;-)

On Mate (so should work on gnome as well), create a .desktop file
in /etc/xdg/autostart to run a script in /usr/local/bin and you get the
attached screenshot.

Jeff Sadowski via samba

unread,
Feb 7, 2017, 1:40:03 PM2/7/17
to
figured out how to use ldapsearch also to get what I want.
Also found how to convert AD time to unix time
Another thing I wanted calculated was when an account expires.

ldapsearch -h ad.mydomain.tld -b dc=ad,dc=mydomain,dc=tld
"(sAMAccountName=$user)"

gives all the good information about a user.

here is how I used it to tell me all accounts expiring this next month.

h=ad.mydomain.tld
b=dc=ad,dc=mydomain,dc=tld
q=accountExpires
for user in $(wbinfo -u);do
accountExpires=$(ldapsearch -h $h -b $b "(sAMAccountName=$user)" $q
2>/dev/null | grep "^$q" | awk '{print $2}')
if [ "$(echo ${accountExpires}|wc -c)" -gt 7 ];then
#microsoft uses 100 nanosecond increments so I remove the last 7 digits to
get seconds
#microsoft's epoch is jan 1 1601 so I subtract 11644430400 seconds to make
it unit time
act_exp=$(expr ${accountExpires::-7} - 11644430400)
days=$(expr $(expr $act_exp - `date "+%s"`) / 86400)
if [ "$days" -lt 30 ] && [ "$days" -gt 0 ];then
echo $user expires in $days days
fi
fi
done

Rowland Penny via samba

unread,
Feb 7, 2017, 1:50:03 PM2/7/17
to
Hmm, accountExpires != msDS-UserPasswordExpiryTimeComputed

And from my internet investigations:

unixtimestamp=$((($WindowsTimeStamp/10000000)-11676009600))

and to turn that into number of days:

DAYS=$((($unixtimestamp - $DATE) / 3600 / 24))

Jeff Sadowski via samba

unread,
Feb 7, 2017, 6:20:03 PM2/7/17
to
On Tue, Feb 7, 2017 at 3:22 PM, Jeff Sadowski <jeff.s...@gmail.com>
wrote:
>> $WindowsTimeStamp/10000000
> is equal to
> ${WindowsTimeStamp::-7}
> I don't know what is a more expensive operation catting a string or
> division(I guessed division was a more expensive operation).
>
> 11676009600 doesn't work right. It gives me different times then what net
> use gives me that is how I got
> 11644430400 to match what net use gives me
>
> I plugged the unixtimestamp into "date -d @${unixtimestamp}" and compared
it with "net user %username% /domain" untill they where showing the same
times for accountExpire.

date

>
>
>> and to turn that into number of days:
>>
>> DAYS=$((($unixtimestamp - $DATE) / 3600 / 24))
>>
> x/3600/24 = x/86400

Jeff Sadowski via samba

unread,
Feb 8, 2017, 11:40:05 AM2/8/17
to
correction on time offset

11644473600 is what shows the same times for me.

On Tue, Feb 7, 2017 at 4:11 PM, Jeff Sadowski <jeff.s...@gmail.com>
0 new messages