ADPassMon

ADPassMon has moved!

The ADPassMon source code, software releases, and documentation are now hosted on GitHub. This page will remain for a short time for historical purposes, but I encourage you to visit GitHub for up-to-date information about using ADPassMon, instead. I will still post about ADPassMon updates and bugfixes on this blog.

Also note, comments on this page are closed. Please submit bug reports and feature requests to the github project directly.

Quick Summary and Features

ADPassMon is a small menu bar application that shows the number of days remaining until your Active Directory password expires. ADPassMon features:

  • support for Mac OS X 10.6 through 10.11
  • optional Growl or Notification Center alerts with adjustable warning period
  • integrated Kerberos ticket renewal
  • Change Password menu item, with optional password requirements reminder
  • offline functionality via cached expiry information
  • MCX support for ease of administration

This software is released under the MIT license.

Read enough? Download the correct version for your operating system:

Mac OS X 10.6 and 10.7

Mac OS X 10.8 or newer (tested up through OS X 10.11)

Want to know more? Read on for the full story.


The Problem

Most Active Directory sites require users to change their passwords at regular intervals – such as every 30, 60, 90, or 180 days. Unless you write your password expiration date on a calendar or set some other sort of reminder, it’s possible that your password will expire before you’ve had a chance to change it.

Mac OS X’s AD integration has come a long way in mitigating this issue. Since Mac OS 10.4, users with impending password expirations will be notified when they log in. If their password is set to expire within 24 hours, they will be forced to change their password before being allowed to log in. Administrators can adjust how long before password expiration to start showing these login screen warnings. This is not a foolproof solution, though. If you’re the kind of person who doesn’t regularly log out of your computer, you might go weeks without visiting the login screen, completely missing the warning period. If you can’t count on your operating system to keep you informed regardless of your use habits, what can you do?

The Solution

ADPassMon icon

Click to download ADPassMon (264KB)

ADPassMon, short for Active Directory Password Monitor, is a utility that solves this issue by providing up-to-date password expiration information at a glance. It places an item in the menu bar that shows the number of days remaining until the password expires, simply and unobtrusively. Here it is on the left.

title bar 1

Hovering your cursor over the icon reveals more precise information in a tooltip.

title bar 2

Clicking on the menu item reveals some additional features, which I’ll discuss further below.

title bar 3

Selecting the Preferences item reveals the program’s configuration options. Note the message area at the top of the window. It will normally display the full password expiration information, but if can also display errors or other messages affecting use of the application.

Preferences window
Auto or Manual Mode

By default, ADPassMon attempts to automatically acquire all the information it needs to calculate your password expiration information. This will not work in all environments, so the option to set the maximum password age manually is provided. If Auto mode results in an incorrect or negative password expiration value, then you should use Manual mode and provide your site’s maximum password age in days.

Growl / Notification Center Alerts

If you have Growl installed or use OS X 10.8 with Notifcation Center, ADPassMon can optionally send you  notifications of impending password expirations. Check the Enable Notifications box and enter the number of days before the password expires that you want the warnings to start appearing. Warnings will appear every 12 hours after the threshold is reached. Each warning will resemble the following:

notification

Kerberos Tickets

ADPassMon can also acquire and/or renew Kerberos tickets for you. In OS 10.6, Apple buried the graphical Kerberos ticket management tool — Ticket Viewer.app — inside the /System/Library/CoreServices folder. ADPassMon lets you request a new ticket or renew an existing ticket right from its menu. (A Kerberos ticket is required if you’re using Auto mode, so you’ll be prompted to obtain a ticket if you launch ADPassMon and don’t have a ticket.) This menu item will be disabled if the app cannot communicate with your AD domain.

KerbMinder Integration (only in v1.10.0+)

If you have KerbMinder installed, ADPassMon will show an extra menu option that lets you enable and disable it.

KerbMinder menu item

Change Password Shortcut

ADPassMon’s menu provides a shortcut to Mac OS X’s standard password change interface. When you select it, System Preferences will automatically launch and show you the standard password change window.

change password

This feature requires that ADPassMon be allowed to control the GUI in the Security & Privacy pref pane’s Accessibility settings. If it is not enabled, users with administrator access will be prompted to enable it when the program first launches.

Skip Accessibility Option Check

If you want to keep the Accessibility setup dialog box from appearing when your users first run ADPassMon, you can set the accTest preference value to 0 to disable it.

defaults write org.pmbuko.ADPassMon accTest 0

Password Policy Reminder

If you are an administrator and need an easy way to remind your users of your organization’s password complexity requirements, you can enable the password policy reminder feature by defining a pwPolicy key in ADPassMon’s plist file. You can do this either by editing the plist file directly with a plist editor (Xcode works well for this), or by setting the content of the reminder message in the terminal as follows:

defaults write org.pmbuko.ADPassMon pwPolicy "Your password requirement message goes here."

The password policy reminder dialog button’s default text is “OK”, but you can change it as follows:

defaults write org.pmbuko.ADPassMon pwPolicyButton "I understand"

When the pwPolicy value is set, a policy reminder alert like the one below will appear when you select Change Password from the ADPassMon menu. You must click the single button before you can change your password.

pwpolicy

Lockable Preferences

If you’re an administrator and wish to deploy this utility to your Macs, you can disable access to the Preferences window by adding a prefsLocked key and setting its value to true in the org.pmbuko.ADPassMon.plist. You can do this via MCX, or manually by entering this command in the terminal:

defaults write org.pmbuko.ADPassMon prefsLocked true

Users will still be able to enable or disable Growl/Notification Center alerts via the menu option.

App Reset

If you’re experiencing trouble with ADPassMon, you can clear the settings and return the application to defaults by selecting the Reset tab in the Preferences window and clicking the Revert to Defaults button.

reset

Acknowledgements

I have many people to thank for making this application possible.

  • Jonathan Nathan, of JNSoftware, for providing sample code for a menu app written in AppleScript ObjectiveC
  • Shane Stanley, for his excellent eBook, AppleScriptObjC Explored
  • Andrew Thomson, for his work on the Password Monitor app on which ADPassMon is based
  • John Welch, for recommending Shane’s book and inspiring me to start learning AppleScriptObjC

Last but not least, I give my sincere thanks to my beta testers: Joe Chilcote, Brian LaShomb, Joel Moses, Rusty Myers, Stephen Rayda, Tom Rodgers, and especially Rich Trouton. This app would have been less useful without their help.

MIT License

This software is released under the terms of the MIT license.

Copyright (C) 2015 by Peter Bukowinski

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

426 thoughts on “ADPassMon

  1. This is fantastic news, you should setup some way that I can pay you!

    One issue in our environment. The menubar is showing [-39] and shows my expiration 39 days in the past not the future. Any thought on that?

    Alan–

    • I’d recommend using Manual mode in this case. Just enter your site’s password change interval in days, hit enter, and then Apply changes.

  2. Or whack this into a plist file (modify the path as appropriate) and deploy it into /Library/LaunchAgents. Set it to root:wheel, mode 644, done.

    KeepAlive

    SuccessfulExit

    Label
    com.wordpress.yourmacguy.adpassmon
    ProgramArguments

    /path/to/ADPassMon.app/Contents/MacOS/ADPassMon

  3. Older Intel Core Duo MacBook:
    You can’t open the application “ADPassMon” because it’s not supported on this type of Mac.

    ADPassMon: Mach-O 64-bit executable x86_64

    Any chance to add 32 bit support for older Macs?

  4. I want this app, but …

    … keep on display “Working …”

    If I switch to “Manual”, app switch back to “Auto”.

        • Can you open up Console.app (in Utilities), select Console messages, then type ADPassMon in the search field? Copy the last 20 log items you see and paste them here, please.

          • OK
            ———————
            25.5.11 9:54:19 ADPassMon[1650] Starting manual process…
            25.5.11 9:54:19 ADPassMon[1650] Found expireAge in plist: 40
            25.5.11 9:54:19 ADPassMon[1650] The new pwdSetDate (-1,34774E+5)
            25.5.11 9:54:19 ADPassMon[1650] is < value in plist (0,0) so we ignore it
            25.5.11 9:54:19 ADPassMon[1650] daysUntilExp: -1,507932938657E+4
            25.5.11 9:54:19 ADPassMon[1650] daysUntilExpNice: -15079
            25.5.11 9:54:19 ADPassMon[1650] expirationDate: úterý, 10. února 1970 2:00:00
            25.5.11 9:54:19 ADPassMon[1650] Finished process
            25.5.11 9:54:19 ADPassMon[1650] Starting manual process…
            25.5.11 9:54:19 ADPassMon[1650] Found expireAge in plist: 40
            25.5.11 9:54:19 ADPassMon[1650] The new pwdSetDate (-1,34774E+5)
            25.5.11 9:54:19 ADPassMon[1650] is < value in plist (0,0) so we ignore it
            25.5.11 9:54:19 ADPassMon[1650] daysUntilExp: -1,507932938657E+4
            25.5.11 9:54:19 ADPassMon[1650] daysUntilExpNice: -15079
            25.5.11 9:54:19 ADPassMon[1650] expirationDate: úterý, 10. února 1970 2:00:00
            25.5.11 9:54:19 ADPassMon[1650] Finished process
            25.5.11 9:54:52 ADPassMon[1650] selectedMethod: 40
            25.5.11 9:54:52 ADPassMon[1650] Starting manual process…
            25.5.11 9:54:52 ADPassMon[1650] Found expireAge in plist: 40
            25.5.11 9:54:52 ADPassMon[1650] The new pwdSetDate (-1,34774E+5)
            25.5.11 9:54:52 ADPassMon[1650] is < value in plist (0,0) so we ignore it
            25.5.11 9:54:52 ADPassMon[1650] daysUntilExp: -1,507932976852E+4
            25.5.11 9:54:52 ADPassMon[1650] daysUntilExpNice: -15079
            25.5.11 9:54:52 ADPassMon[1650] expirationDate: úterý, 10. února 1970 2:00:00
            25.5.11 9:54:52 ADPassMon[1650] Finished process

            • Try running this in terminal and let me know the output.

              /usr/bin/dscl localhost read /Search/Users/$USER pwdLastSet | /usr/bin/awk '/pwdLastSet:/{print $2}'

            • It appears that your computer is not bound to Active Directory, or at least the user account you are logged in with does not exist in Active Directory.

              • Hmm …
                I tested the application on second computer (with clean install) with the same result :-(
                Both computers are bind to AD, and logged user is domain user.
                It can not be a problem on the domain controller? It runs on Windows SBS 2003.

            • Ok, the next thing to check is your Directory Service search policy:

              dscl -q localhost -read /Search

              If the output of this command does not include an Active Directory item, then you’ll need to modify or create your custom search path to include your Active Directory domain.

              • CSPSearchPath:
                /Local/Default
                /BSD/local
                /Active Directory/All Domains
                DHCPLDAPDefault: off
                LSPSearchPath: /Local/Default /BSD/local
                NSPSearchPath: /Local/Default /BSD/local
                ReadOnlyNode: ReadOnly
                SearchPath:
                /Local/Default
                /BSD/local
                /Active Directory/All Domains
                SearchPolicy: dsAttrTypeStandard:CSPSearchPath

              • Domain controller runs on Windows SBS 2003, but Domain Functional Levels is Windows 2000 Native …

              • Hmmm. Your search path is set correctly. I’m running out of ideas about what the problem could be, so it might be that you’re running in 2000 mode, but I can’t be sure. It could be a kerberos issue as well. Can you show me the output of the ‘klist’ command after a fresh login?

              • Output of the klist:

                Kerberos 5 ticket cache: ‘API:Initial default ccache’
                Default principal: testus@FIRMA.LOCAL

                Valid Starting Expires Service Principal
                06/15/11 11:48:51 06/15/11 19:48:51 krbtgt/FIRMA.LOCAL@FIRMA.LOCAL
                renew until 06/15/11 19:48:51

                06/15/11 11:49:01 06/15/11 19:48:51 cifs/server.firma.local@FIRMA.LOCAL
                renew until 06/15/11 19:48:51

              • I’m getting the same output as MaM consistently with Leopard and Snow Leopard regardless of OS version on all AD bound machines (50 some odd machines) 3 users (in the IT group) and one enterprise admin user show the correct days until expiration. They are all in an OD IT group and the rest of the users are in a employees OD group that has the AD “Domain Users” as the member. This is Magic triangle with Server 03. I’ve gone into the Manually setting expiration, hit Enter, then apply, I’m still getting an expiration date in 1970. When I take a user out of Domain Users, nothing changes, let’s say I add that same test user to the “IT” OD group, still nothing changes; expiration date in 1970. Now what if I bind a machine only to AD and not OD? Same thing, expiration in 1970 despite our domain policy specifying expiration every 90 days.

                I had the exact same problem with the older Password Monitor except it would just list a diamond (a sort of out of range error). Every time I deleted the user folder for testing. The users being local admins on the machine doesn’t help or hinder this false expiration repot. It’s a real mystery as to why this only works for 3 users in my domain.

              • Of the non-IT users, have their passwords ever been changed? I.e. Were they set initially by an admin and not reset by the users? Also, please let me know what the console log shows when you do a recheck expiration.

              • I reset the password interactively at the System Preferences level but had initially set the pass in AD. The log output is essentially the same as what MaM outputted. The initial opening of ADPass Mon produces this:
                6/29/11 1:15:28 PM ADPassMon[1410] Running on OS 10.6.x
                6/29/11 1:15:28 PM ADPassMon[1410] Testing Universal Access settings…
                6/29/11 1:15:28 PM ADPassMon[1410] Disabled
                6/29/11 1:15:28 PM ADPassMon[1410] Skipping because user not an admin
                6/29/11 1:15:28 PM ADPassMon[1410] Testing for Growl…
                6/29/11 1:15:28 PM ADPassMon[1410] Not running
                6/29/11 1:15:28 PM ADPassMon[1410] Starting auto process…
                6/29/11 1:15:28 PM ADPassMon[1410] Found expireAge in plist: 90
                6/29/11 1:15:28 PM ADPassMon[1410] The new pwdSetDate (-1.34774E+5)
                6/29/11 1:15:28 PM ADPassMon[1410] is < value in plist (0.0) so we ignore it
                6/29/11 1:15:28 PM ADPassMon[1410] daysUntilExp: -1.506471907407E+4
                6/29/11 1:15:28 PM ADPassMon[1410] daysUntilExpNice: -15064
                6/29/11 1:15:28 PM ADPassMon[1410] expirationDate: Tuesday, March 31, 1970 8:00:00 PM
                6/29/11 1:15:28 PM ADPassMon[1410] Finished process

                I then reset the password and re-ran expiration check and got this:

                6/29/11 1:16:06 PM ADPassMon[1410] Starting auto process…
                6/29/11 1:16:06 PM ADPassMon[1410] Found expireAge in plist: 90
                6/29/11 1:16:06 PM ADPassMon[1410] The new pwdSetDate (-1.34774E+5)
                6/29/11 1:16:06 PM ADPassMon[1410] is < value in plist (0.0) so we ignore it
                6/29/11 1:16:06 PM ADPassMon[1410] daysUntilExp: -1.506471951389E+4
                6/29/11 1:16:06 PM ADPassMon[1410] daysUntilExpNice: -15064
                6/29/11 1:16:06 PM ADPassMon[1410] expirationDate: Tuesday, March 31, 1970 8:00:00 PM
                6/29/11 1:16:06 PM ADPassMon[1410] Finished process

                For a successful user (enterprise admin):
                6/29/11 1:24:52 PM ADPassMon[1555] Starting auto process…
                6/29/11 1:24:52 PM ADPassMon[1555] Found expireAge in plist: 90
                6/29/11 1:24:52 PM ADPassMon[1555] The new pwdSetDate (1.509770815694E+4)
                6/29/11 1:24:52 PM ADPassMon[1555] is ≥ value in plist (1.509770800781E+4) so we use it
                6/29/11 1:24:52 PM ADPassMon[1555] daysUntilExp: 32.982555084538
                6/29/11 1:24:52 PM ADPassMon[1555] daysUntilExpNice: 32
                6/29/11 1:24:52 PM ADPassMon[1555] expirationDate: Monday, August 1, 2011 12:59:45 PM
                6/29/11 1:24:52 PM ADPassMon[1555] Finished process

                I'm finding that all of the users showing the eroneus expiration date are missing LDAP attributes when I browse LDAP using "NextStudio" I find that the majority of domain accounts are missing the following LDAP attributes:
                accountExpires
                adminCount
                pwdLastSet

                The normal value for
                accountExpires: 923372036854775807
                adminCount:1
                pwdLastSet (varies..obviously)

                I can tell you that the value has to exist somehow. How is it that the Snow Leopard and Windows login screens will tell a user that their pass is to expire in 25 days or less? I did a bit more digging and fired open good old ADSIedit.msc on my DC and found that the aforementioned attributes exist but just aren't getting "published" to LDAP. Methinks that apple's directory services (and MS Entourage) are doing more than just simple LDAP queries to find out when a user's pass will expire. I'm guessing that when you're utility looks for pwdLastSet and can't find the attribute that some default date gets returned in 1970.

              • You’ve definitely found the issue here. I’m somewhat gladdened that it’s no ADPassMon’s fault, but don’t know what can be done to fix the issue. Has your AD schema been extended or altered from MS standards? I’ve never heard of the password exiration value not being published.

              • I did some tests and the result is as follows:
                Clean install Windows 2003 Small Bussiness Server – ADPassMon is not functional
                Clean install Windows 2003 Server R2 – ADPassMon is functional
                Clean install Windows 2008 Server – ADPassMon is functional

                Probably the problem is in the AD schema in Windows 2003 SBS.

              • Hey y’all. Sorta went on vacation and didn’t want to post anything until I had something to contribute. As MaM guessed, yes we do have a Domain that was SBS and then later upgraded to Standard. As he says, a fresh install of Server 03 Standard would resolve the issue. As my issue is with my production AD, such a resolution was less than desirable. So, I opened up my ADUC, right clicked on Domain Users (this doesn’t matter) and selected Delegate Control… The next box asks you (for what group). I typed in auth and hit enter to auto-fill Authenticated Users. At the next screen I select “only the following objects..” radio button and scrolled down and selected the “User objects”. At the next screen I checked the box “Property-Specific” as we don’t want to grant write to all user objects (LDAP attributes). I scrolled down to “pwdLastSet” and checked read and write. The next dialogue box is a Finished screen. I then changed the password of a normal test user and successfully had a pwdLastSet value.

                This marks the end to a nearly 2 year long outstanding ticket. I thank the members of the forum and, of course, pmbuko, for helping me come to a resolution. And, to microsoft, much love for http://support.microsoft.com/kb/294952/en-us. No more users who say they weren’t warned that their password would be expiring!!

  5. Thanks for this, it is really cool.

    I found that on first use I was getting negative numbers as well. It would date back to when I last renewed the password for the user. I changed it from Auto mode to Manual mode and put in 365, then pressed Enter, and then clicked Apply Changes.

    It took me a while to figure out that I had to hit the Enter key and then Apply Changes. It seems strange to require the Enter key press for it to work. It might be helpful to make that more obvious or just allow the Apply Changes button to set it instead of the Enter key. I had to read through the comments to figure it out.

    • I agree that needing to press enter is not intuitive (or Mac-like). It bothered me at the time I coded it, but not enough to figure out the right was, I guess. I’ve added it as a feature request for the next version.

  6. Would it be possible to make the Method (Auto or Manual) an option in the plist? And then also put the interval in there as well? Then we can set those settings through ARD.

    FYI, I use Plistbuddy instead of the defaults command which is much nicer, especially when crafting Unix scripts for ARD.

  7. On our demo machine, everything seems to be working except the Refresh Kerberos Ticket menu item is disabled. We’re getting the correct number of days until expiration showing via the auto method, kerberos is working, and ticket viewer shows the current active ticket. What am I missing to allow the refresh ticket option to work?

    • Does it stay grayed out even if you re-check the expiration? The way I set up the Refresh Kerberos Ticket option is that it will be disabled under a certain test condition. The test compares the “password set date” that is saved in the plist against the just acquired “password set date”. If the fresh value is greater than or equal to the plist value, then I assume the computer is on the network and successfully talking to AD. If the fresh value is less, it is likely a negative value and I assume the computer is not on the network and disable the kerberos menu item.

      ADPassMon writes to the console log. Open Console.app, select Console messages, and then type ADPassMon in the search field to filter for those messages. Can you paste what you see in the log when you do a re-check expiration while on the network with a valid kerberos ticket?

      • In the console, it did show a lesser value than the plist for the new pwdSetDate. This account is less than 45 days old, and thus had not yet changed the password. Once I changed the password and re-checked the expiration, it all works. Thanks for pointing me in the right direction so quickly. My users are going to love this.

    • For multiple or single Macs, if you have Apple Remote Desktop you can do it by running the following “Send UNIX command” as each user on the computer(s) — assuming you already have ADPassMon copied into the Applications folder:
      defaults write loginwindow AutoLaunchedApplicationDictionary -array-add '{Path="/Applications/ADPassMon.app";}'

  8. I’d like to consider using this in a company, but they’re going to ask what license it’s released under. I didn’t see that anywhere, so I’ll ask – what license are you releasing this under?

  9. Hi Peter, I’m trying out ADpassmon for the first time, and i’m running into some issues- I’ve got 2 machines bound to the domain and successfully authentication my AD account. On one machine, the expiration date given by ADpassmon is 42 days, which is incorrect- it should be (today anyway) 88 days. On the other machine, it returns -15233 days. Same AD account, same AD domain.
    I tried running the command you suggested for an earlier commenter (/usr/bin/dscl localhost read /Search/Users/$USER pwdLastSet | /usr/bin/awk ‘/pwdLastSet:/{print $2}’) and got the no such key response, but my active directory is in my search path. If I look at the attributes on my AD account, pwdLastSet is there, and the value is yesterday, which is correct. Any ideas? thanks.

  10. Hi Peter,
    trying your tool with a 10.6 Client sucessfully bound to AD WinServ2008.R2 Cant get it work
    Console says:
    11.10.11 13:49:50 ADPassMon[834] Starting auto process…
    11.10.11 13:49:50 ADPassMon[834] Script Error: {“Can’t make word 1 of \”\” into type text.”} doesn’t match the parameters {theError, showErr} for errorOut_.
    any ideas? Cheers

    • Chris,
      Please try the following command in the terminal and let me know the result:

      scutil –dns | awk ‘/nameserver\[1\]/{print $3}’

  11. Hi,
    result is an invalid option. If I change command to
    scutil –dns | awk ‘/nameserver\[1\]/{print $3}’
    I get no result (empty prompt)
    thanks

  12. result is “nameserver[0] : 192.168.4.10”
    which is our AD DNS. As far as I know several machines are providing DNS functionality in the corresponding Domain forest.
    thanks

  13. Great! I was able to make it work by adding a second DNS entry in System Preferences and using manual method for obtaining maximum password age. But now with this new version it´s working straightaway ! Thanks a lot, I really appreciate your work.
    Chris

  14. I just installed ADPassMon yesterday. Yesterday, it said that my password would expire in -7 days. So I switched it to manual and specified 60 days. It then said my password would expire in 52 days. I wasn’t sure if that was right (I changed my password *around* a week ago) so left it and figured I’d just see how it turned out. Today when I logged in, it said my password would expire in 52 days. So I reverted to default settings and refreshed my Kerberos Ticket. But again it says [-7d]. Any suggestions?

      • Here’s the last entry:

        11/22/11 8:19:15.912 AM ADPassMon: Starting auto process…
        11/22/11 8:19:15.925 AM ADPassMon: myDNS: 10.5.1.68
        11/22/11 8:19:16.607 AM ADPassMon: mySearchBase: DC=liox,DC=org
        11/22/11 8:19:17.291 AM ADPassMon: Got expireAge: 0
        11/22/11 8:19:17.593 AM ADPassMon: The new pwdSetDate (1.529264898762E+4)
        11/22/11 8:19:17.594 AM ADPassMon: is < value in plist (1.529264941406E+4) so we ignore it
        11/22/11 8:19:17.601 AM ADPassMon: daysUntilExp: -7.988977141204
        11/22/11 8:19:17.601 AM ADPassMon: daysUntilExpNice: -7
        11/22/11 8:19:17.602 AM ADPassMon: expirationDate: Monday, November 14, 2011 8:35:09 AM
        11/22/11 8:19:17.603 AM ADPassMon: Finished process

      • I just clicked on “Re-check Expiration” and it now says -8 days. I checked with my Sys Adm and he said I changed my password on 11/14, so that’s about right. At this point, I’m thinking I just need to use the Manual Mode to set the expiration time. Thanks!

        • Is the DNS reported in the log (10.5.1.68) a Microsoft DNS server? If not, then this is what’s preventing auto-discovery of your max password age. Try the Revert to Defaults button in the Reset tab before going back to Manual mode.

          • I have the same problem as Kevin above, the expiration date is when the password was last reset. Here’s the log output:

            2/2/12 1:49:34.012 PM ADPassMon: Running on OS 10.7.x
            2/2/12 1:49:34.012 PM ADPassMon: Testing Universal Access settings…
            2/2/12 1:49:35.541 PM ADPassMon: Already enabled
            2/2/12 1:49:35.542 PM ADPassMon: Testing for Growl…
            2/2/12 1:49:35.546 PM ADPassMon: Not running
            2/2/12 1:49:35.570 PM ADPassMon: Testing for Kerberos ticket presence…
            2/2/12 1:49:35.622 PM ADPassMon: No ticket found
            2/2/12 1:49:44.146 PM ADPassMon: Ticket acquired
            2/2/12 1:49:46.443 PM ADPassMon: Testing for Kerberos ticket presence…
            2/2/12 1:49:46.475 PM ADPassMon: Ticket found and renewed
            2/2/12 1:49:46.477 PM ADPassMon: Starting auto process…
            2/2/12 1:49:46.487 PM ADPassMon: myDNS: 172.21.169.33
            2/2/12 1:49:46.611 PM ADPassMon: mySearchBase: DC=forest,DC=name
            2/2/12 1:49:46.651 PM ADPassMon: Got expireAge: 0
            2/2/12 1:49:46.802 PM ADPassMon: The new pwdSetDate (1.537156443377E+4)
            2/2/12 1:49:46.803 PM ADPassMon: is ≥ value in plist (0.0) so we use it
            2/2/12 1:49:46.810 PM ADPassMon: daysUntilExp: -0.928459753106
            2/2/12 1:49:46.810 PM ADPassMon: daysUntilExpNice: 0
            2/2/12 1:49:46.811 PM ADPassMon: expirationDate: Wednesday, February 1, 2012 3:32:47 PM
            2/2/12 1:49:46.814 PM ADPassMon: Finished process
            2/2/12 1:49:46.815 PM ADPassMon: in the loop

            Is there a way to get this working with automatic setting? This is a multi-domain forest. The forest is seen in the output above, so it’s like ‘forest.name’ but the actual domain the host is bound to is ‘domain.forest.name’. Could this have anything to do with this or the Kerberos problem I posted earlier?

            • Perttu, can you please try the following command in your terminal and let me know if it returns the proper search base of “dc=domain,dc=forest,dc=name”?

              ldapsearch -LLL -Q -s base -H ldap://172.21.169.33 defaultNamingContext | /usr/bin/awk ‘/defaultNamingContext/{print $2}’

              If it works, I will release a new version of ADPassMon for you that uses the ‘defaultNamingContext’ value instead of the ‘rootDomainNamingContext’ I’m using now.

  15. ADPassMon asks to renew the Kerberos ticket every time I log in and then asks for a password, is this normal? I already have a TGT so shouldn’t ADPassMon be able to get the ticket without providing a password?

    • If you already have a TGT then it should not need to ask you for your password. Are you using Lion? I probably didn’t do enough Kerberos testing with it. In any case, can you paste ADPassMon’s console log output here from the next time you log in?

  16. Yes, it’s 10.7.2, here’s console log output:

    “1/2/12 10:51:52.773 AM ADPassMon: Running on OS 10.7.x
    1/2/12 10:51:52.774 AM ADPassMon: Testing Universal Access settings…
    1/2/12 10:51:54.494 AM ADPassMon: Already enabled
    1/2/12 10:51:54.495 AM ADPassMon: Testing for Growl…
    1/2/12 10:51:54.498 AM ADPassMon: Not running
    1/2/12 10:51:54.529 AM ADPassMon: Testing for Kerberos ticket presence…
    1/2/12 10:51:54.695 AM ADPassMon: No ticket found
    1/2/12 10:59:32.053 AM ADPassMon: Ticket acquired
    1/2/12 10:59:35.502 AM ADPassMon: Testing for Kerberos ticket presence…
    1/2/12 10:59:35.539 AM ADPassMon: Ticket found and renewed
    1/2/12 10:59:35.542 AM ADPassMon: Starting auto process…
    1/2/12 10:59:35.551 AM ADPassMon: myDNS: 172.21.169.35
    1/2/12 10:59:35.842 AM ADPassMon: mySearchBase: DC=xxxx,DC=xxxx
    1/2/12 10:59:35.878 AM ADPassMon: Got expireAge: 0
    1/2/12 10:59:36.649 AM ADPassMon: The new pwdSetDate (1.531626249741E+4)
    1/2/12 10:59:36.650 AM ADPassMon: is < value in plist (1.531626269531E+4) so we ignore it
    1/2/12 10:59:36.667 AM ADPassMon: daysUntilExp: -25.112026909723
    1/2/12 10:59:36.668 AM ADPassMon: daysUntilExpNice: -25
    1/2/12 10:59:36.669 AM ADPassMon: expirationDate: Thursday, December 8, 2011 8:18:17 AM
    1/2/12 10:59:36.671 AM ADPassMon: Finished process
    1/2/12 10:59:36.672 AM ADPassMon: in the loop
    1/2/12 2:54:13.659 PM ADPassMon: Starting auto process…
    1/2/12 2:54:13.764 PM ADPassMon: Script Error: {"Can’t make word 1 of \"\" into type text."} doesn’t match the parameters {theError, showErr} for errorOut_.
    "

    I've obfuscated the search base.

    • Can you check to see if you have a “/Library/Preferences/edu.mit.Kerberos” file? If so, you should delete it as it may conflict with the new config file that should be at “/etc/krb5.conf”. Another thing to look for in the /etc/kkrb5.conf file. Do the servers listed in the [realms] section use FQDNs or just hostnames? If the latter, try editing the file so it uses FQDNs.

      Also, can you show me the (obfuscated) output of ‘klist -v’?

      • I finally got this information. There is no edu.mit.Kerberos file and krb5.conf is empty.
        Here’s ‘klist -v’ output before entering the password in ADPassMon:

        Credentials cache: API:1754061474:1
        Principal: username@FULLY.QUALIFIED.DOMAIN.NAME
        Cache version: 0

        Server: krbtgt/FULLY.QUALIFIED.DOMAIN.NAME@FULLY.QUALIFIED.DOMAIN.NAME
        Client: username@FULLY.QUALIFIED.DOMAIN.NAME
        Ticket etype: aes256-cts-hmac-sha1-96, kvno 3
        Ticket length: 1669
        Auth time: Jan 20 10:34:36 2012
        End time: Jan 20 20:34:36 2012
        Ticket flags: pre-authent, initial, forwardable
        Addresses: addressless

        And here’s after entering password in ADPassMon and getting the ldap ticket:

        Credentials cache: API:1754061474:1
        Principal: username@FULLY.QUALIFIED.DOMAIN.NAME
        Cache version: 0

        Server: krbtgt/FULLY.QUALIFIED.DOMAIN.NAME@FULLY.QUALIFIED.DOMAIN.NAME
        Client: username@FULLY.QUALIFIED.DOMAIN.NAME
        Ticket etype: aes256-cts-hmac-sha1-96, kvno 3
        Ticket length: 1688
        Auth time: Jan 20 10:37:16 2012
        Start time: Jan 20 10:37:25 2012
        End time: Jan 20 20:37:25 2012
        Renew till: Jan 20 20:39:17 2012
        Ticket flags: pre-authent, initial, renewable, forwardable
        Addresses: addressless

        Server: ldap/host.fully.qualified.domain.name@FULLY.QUALIFIED.DOMAIN.NAME
        Client: username@FULLY.QUALIFIED.DOMAIN.NAME
        Ticket etype: aes256-cts-hmac-sha1-96, kvno 36
        Ticket length: 1675
        Auth time: Jan 20 10:37:16 2012
        Start time: Jan 20 10:37:25 2012
        End time: Jan 20 20:37:25 2012
        Ticket flags: ok-as-delegate, pre-authent
        Addresses: addressless

        If you need more specific information you can contact me directly. Thanks!

  17. What is different in the way ADPassMon is checking the password expiration of a users account than in Password Expiration Checker script. ADPassMon works just fine on 10.7.2 machines, but when I try to run your script with all my server configurations entered in all I get is an error that says “The command exited with a non-zero status”.

    My goal is to be able to link your script to a status menu link to check the expiration status of a users AD password.

    • Password Expiration Checker is failing for two reasons. First, the AD plugin changed in Lion and domain information is now stored a bit differently. Consequently, the dscl command in the script needs to be updated. Second, AppleScript handles some numerical values differently, so the dscl command I mentioned needs further tweaking to handle that. I just did this update and it tested fine on my machine. Here’s a link: http://dl.dropbox.com/u/3967964/Password_Expiration_Checker%28lion%29.zip

      • That version works sorta…When the script was ran on our test user account it says the password will expire in -150123 days. The password expiration is set to expire every 90 days. Your saying that the dscl command needs tweaking is there a calculation I need to edit in the script?

        ADPassMon is still showing the correct expiration date on that test user.

        • I just found an error in the script I gave you. Line 67 reads “if expireAge is greater than 0 then”. Please change it to “if expireAge is 0 then”. That will make it use the expiration value you supplied at the top of the script instead of trying to find it from AD.

  18. In ADPassMon, what calculation was used to provide the actual time and date the password would expire, for instance, “On Tuesday April 17, 2012 4:22:34PM”. I would like to be able to add that into the applescript.

  19. I have noticed the following with our users. When they try and change password through ADPassmon they get the following error.

    “Your system administrator may not allow you to change your password or there was some other problem with your password.”

    Anybody seen this or know why it happens? Where would I look in a log file for the answer?

    • Steve,

      ADPassMon uses GUI scripting to bring up the same password change dialog that a user would see if he/she went into System Preferences > Users & Groups and clicked the Change Password button. I assume your users will get the same error if they do that. Can you verify this and let me know?

    • Which Mac OS version are you using? Regardless of version, you need to ensure that your Mac’s clocks are in-sync with the AD domain’s clocks. Also, have a user try running ‘kpasswd’ from the Terminal to change their password. It will likely fail there as well, but the errors returned should be more helpful.

    • I believe PSOs store password expiration information differently, and my app doesn’t know how to deal with them … yet? For now, try using the manual mode and enter the max password age manually. If you could, please open up Console.app and show me output from ADPassMon when you try to refresh the information.

    • I have something else for you to try that can help me get ADPassMon working with PSOs. Please run this command in the terminal (replace the w.x.y.z with the ip address of a domain controller and dc=example,dc=org with the proper domain info) and the and let me know what you get:

      ldapsearch -LLL -Q -s base -H ldap://w.x.y.z -b "dc=example,dc=org" msDS-MaximumPasswordAge | awk '/msDS-MaximumPasswordAge/'

      • Here is the console output.

        4/10/12 7:14:52.985 AM ADPassMon: Testing for Kerberos ticket presence…
        4/10/12 7:14:53.374 AM ADPassMon: Ticket found and renewed
        4/10/12 7:14:53.379 AM ADPassMon: Starting auto process…
        4/10/12 7:14:53.380 AM ADPassMon: Found expireAge in plist: 10675197
        4/10/12 7:14:53.430 AM dscl: received message with invalid client_id 3
        4/10/12 7:14:53.454 AM ADPassMon: The new pwdSetDate (1.543365144139E+4)
        4/10/12 7:14:53.455 AM ADPassMon: is ≥ value in plist (1.543365136719E+4) so we use it
        4/10/12 7:14:53.465 AM ADPassMon: daysUntilExp: 1.067519009944E+7
        4/10/12 7:14:53.465 AM ADPassMon: daysUntilExpNice: 10675190
        4/10/12 7:14:53.466 AM ADPassMon: expirationDate: Wednesday, December 14, 31239 9:38:04 AM
        4/10/12 7:14:53.469 AM ADPassMon: Finished process

        Here is the output for the ldapsearch

        Referral (10)
        Additional information: 0000202B: RefErr: DSID-031007EF, data 0, 1 access points
        ref 1: ‘local”’

        Referral: ldap://local”/“dc=scentsy,dc=local”

        If you need anything else, let me know. I would love to get this to work. Thanks

  20. I just installed ADPassMon, and if I could get it to work, I would be in heaven. I need a little help figuring out where I’ve gone wrong if you don’t mind though. I have a Mac running OS X 10.7.3 that is connected to an Active Directory, but after I enter the Kerberos password, it says that my password will expire in -15439d. The date of the password expiration that it gives in the preferences is Wednesday, December 31, 1969 8:00:00 PM. Any ideas as to what might be hanging it up?

    • I’ll need some more info to help you. Please quit ADPassMon, then open Console.app. Select “All Messages” from the left, then type “ADPassMon” in the search field. Now launch ADPassMon and copy and paste all the output that appears after it launches.

      • Sorry that it took me so long to get this back to you. Thanks for any help you can give. Here’s the output from Console.app after starting ADPassMon:

        4/12/12 10:38:38.725 AM ADPassMon: Running on OS 10.7.x
        4/12/12 10:38:38.726 AM ADPassMon: Testing Universal Access settings…
        4/12/12 10:38:38.748 AM ADPassMon: Already enabled
        4/12/12 10:38:38.754 AM ADPassMon: Testing for Growl…
        4/12/12 10:38:38.779 AM ADPassMon: Running
        4/12/12 10:38:38.915 AM ADPassMon: Testing for Kerberos ticket presence…
        4/12/12 10:38:39.009 AM ADPassMon: No ticket found
        4/12/12 10:38:46.527 AM ADPassMon: Ticket acquired
        4/12/12 10:38:48.004 AM ADPassMon: Testing for Kerberos ticket presence…
        4/12/12 10:38:48.234 AM ADPassMon: Ticket found and renewed
        4/12/12 10:38:48.239 AM ADPassMon: Starting auto process…
        4/12/12 10:38:48.261 AM ADPassMon: myDNS: 192.168.1.1
        4/12/12 10:38:48.492 AM ADPassMon: mySearchBase:
        4/12/12 10:38:48.515 AM ADPassMon: Got expireAge: 0
        4/12/12 10:38:48.630 AM ADPassMon: The new pwdSetDate (-1.34774E+5)
        4/12/12 10:38:48.632 AM ADPassMon: is < value in plist (0.0) so we ignore it
        4/12/12 10:38:48.640 AM ADPassMon: daysUntilExp: -1.544261027778E+4
        4/12/12 10:38:48.641 AM ADPassMon: daysUntilExpNice: -15442
        4/12/12 10:38:48.643 AM ADPassMon: expirationDate: Wednesday, December 31, 1969 8:00:00 PM
        4/12/12 10:38:48.645 AM ADPassMon: Finished process
        4/12/12 10:38:48.646 AM ADPassMon: in the loop
        4/12/12 10:39:03.739 AM ADPassMon: Starting auto process…
        4/12/12 10:39:03.755 AM ADPassMon: myDNS: 192.168.1.1
        4/12/12 10:39:03.793 AM ADPassMon: mySearchBase:
        4/12/12 10:39:03.817 AM ADPassMon: Got expireAge: 0
        4/12/12 10:39:03.917 AM ADPassMon: The new pwdSetDate (-1.34774E+5)
        4/12/12 10:39:03.918 AM ADPassMon: is < value in plist (0.0) so we ignore it
        4/12/12 10:39:03.926 AM ADPassMon: daysUntilExp: -1.544261045139E+4
        4/12/12 10:39:03.927 AM ADPassMon: daysUntilExpNice: -15442
        4/12/12 10:39:03.928 AM ADPassMon: expirationDate: Wednesday, December 31, 1969 8:00:00 PM
        4/12/12 10:39:03.930 AM ADPassMon: Finished process

        • Kevin, this console data shows me that mySearchBase is blank. ADPassMon gets this from your domain by contacting your primary DNS server, so it looks like 192.168.1.1 is not an AD server. If you have an AD DNS server in your list, try moving it to be the first server. Otherwise, you can use the manual mode and enter the password expiration age manually. Be sure to type Enter after putting in the number.

          • This may have something to do with the fact that I’m using a VPN. I changed the primary DNS server to the AD server, and here is the console output. Thanks again for your help!

            4/12/12 11:38:48.350 AM loginwindow: Login items – LSOpenApplication returned error -10660, url=/Users/kevin.martin/.Trash/ADPassMon.app
            4/12/12 11:38:48.350 AM loginwindow: Login items – LSOpenApplication returned error -10660, url=/Users/kevin.martin/.Trash/ADPassMon.app
            4/12/12 11:38:52.756 AM ADPassMon: Running on OS 10.7.x
            4/12/12 11:38:52.756 AM ADPassMon: Testing Universal Access settings…
            4/12/12 11:38:53.842 AM ADPassMon: Already enabled
            4/12/12 11:38:53.843 AM ADPassMon: Testing for Growl…
            4/12/12 11:38:53.929 AM ADPassMon: Running
            4/12/12 11:38:54.536 AM ADPassMon: Starting auto process…
            4/12/12 11:38:54.537 AM ADPassMon: Found expireAge in plist: 90
            4/12/12 11:38:54.822 AM ADPassMon: The new pwdSetDate (-1.34774E+5)
            4/12/12 11:38:54.824 AM ADPassMon: is < value in plist (0.0) so we ignore it
            4/12/12 11:38:54.839 AM ADPassMon: daysUntilExp: -1.535265201389E+4
            4/12/12 11:38:54.841 AM ADPassMon: daysUntilExpNice: -15352
            4/12/12 11:38:54.844 AM ADPassMon: expirationDate: Tuesday, March 31, 1970 8:00:00 PM
            4/12/12 11:38:54.848 AM ADPassMon: Finished process
            4/12/12 11:38:52.756 AM ADPassMon: Running on OS 10.7.x
            4/12/12 11:38:52.756 AM ADPassMon: Testing Universal Access settings…
            4/12/12 11:38:53.842 AM ADPassMon: Already enabled
            4/12/12 11:38:53.843 AM ADPassMon: Testing for Growl…
            4/12/12 11:38:53.929 AM ADPassMon: Running
            4/12/12 11:38:54.536 AM ADPassMon: Starting auto process…
            4/12/12 11:38:54.537 AM ADPassMon: Found expireAge in plist: 90
            4/12/12 11:38:54.822 AM ADPassMon: The new pwdSetDate (-1.34774E+5)
            4/12/12 11:38:54.824 AM ADPassMon: is < value in plist (0.0) so we ignore it
            4/12/12 11:38:54.839 AM ADPassMon: daysUntilExp: -1.535265201389E+4
            4/12/12 11:38:54.841 AM ADPassMon: daysUntilExpNice: -15352
            4/12/12 11:38:54.844 AM ADPassMon: expirationDate: Tuesday, March 31, 1970 8:00:00 PM
            4/12/12 11:38:54.848 AM ADPassMon: Finished process
            4/12/12 11:38:53.842 AM ADPassMon: Already enabled
            4/12/12 11:38:53.843 AM ADPassMon: Testing for Growl…
            4/12/12 11:38:53.929 AM ADPassMon: Running
            4/12/12 11:38:54.536 AM ADPassMon: Starting auto process…
            4/12/12 11:38:54.537 AM ADPassMon: Found expireAge in plist: 90
            4/12/12 11:38:54.822 AM ADPassMon: The new pwdSetDate (-1.34774E+5)
            4/12/12 11:38:54.824 AM ADPassMon: is < value in plist (0.0) so we ignore it
            4/12/12 11:38:54.839 AM ADPassMon: daysUntilExp: -1.535265201389E+4
            4/12/12 11:38:54.841 AM ADPassMon: daysUntilExpNice: -15352
            4/12/12 11:38:54.844 AM ADPassMon: expirationDate: Tuesday, March 31, 1970 8:00:00 PM
            4/12/12 11:38:54.848 AM ADPassMon: Finished process
            4/12/12 11:38:53.842 AM ADPassMon: Already enabled
            4/12/12 11:38:53.843 AM ADPassMon: Testing for Growl…
            4/12/12 11:38:53.929 AM ADPassMon: Running
            4/12/12 11:38:54.536 AM ADPassMon: Starting auto process…
            4/12/12 11:38:54.537 AM ADPassMon: Found expireAge in plist: 90
            4/12/12 11:38:54.822 AM ADPassMon: The new pwdSetDate (-1.34774E+5)
            4/12/12 11:38:54.824 AM ADPassMon: is < value in plist (0.0) so we ignore it
            4/12/12 11:38:54.839 AM ADPassMon: daysUntilExp: -1.535265201389E+4
            4/12/12 11:38:54.841 AM ADPassMon: daysUntilExpNice: -15352
            4/12/12 11:38:54.844 AM ADPassMon: expirationDate: Tuesday, March 31, 1970 8:00:00 PM
            4/12/12 11:38:54.848 AM ADPassMon: Finished process

            • It’s still using some old info, so you should open up the prefs and hit the “Revert to Defaults” button in on the Reset tab.

              • Okay, I did that. Here’s the output now:

                4/12/12 12:32:48.878 PM ADPassMon: Running on OS 10.7.x
                4/12/12 12:32:48.881 PM ADPassMon: Testing Universal Access settings…
                4/12/12 12:32:49.496 PM ADPassMon: Already enabled
                4/12/12 12:32:49.499 PM ADPassMon: Testing for Growl…
                4/12/12 12:32:49.519 PM ADPassMon: Running
                4/12/12 12:32:49.708 PM ADPassMon: Testing for Kerberos ticket presence…
                4/12/12 12:32:49.751 PM ADPassMon: No ticket found
                4/12/12 12:32:56.440 PM ADPassMon: Ticket acquired
                4/12/12 12:32:58.129 PM ADPassMon: Testing for Kerberos ticket presence…
                4/12/12 12:32:58.329 PM ADPassMon: Ticket found and renewed
                4/12/12 12:32:58.332 PM ADPassMon: Starting auto process…
                4/12/12 12:32:59.275 PM ADPassMon: mySearchBase: DC=sunopta,DC=net
                4/12/12 12:32:59.659 PM ADPassMon: Got expireAge: 90
                4/12/12 12:32:59.828 PM ADPassMon: The new pwdSetDate (-1.34774E+5)
                4/12/12 12:32:59.829 PM ADPassMon: is < value in plist (0.0) so we ignore it
                4/12/12 12:32:59.838 PM ADPassMon: daysUntilExp: -1.535268957176E+4
                4/12/12 12:32:59.839 PM ADPassMon: daysUntilExpNice: -15352
                4/12/12 12:32:59.841 PM ADPassMon: expirationDate: Tuesday, March 31, 1970 8:00:00 PM
                4/12/12 12:32:59.842 PM ADPassMon: Finished process
                4/12/12 12:32:59.843 PM ADPassMon: in the loop
                4/12/12 12:33:02.291 PM ADPassMon: Starting auto process…
                4/12/12 12:33:02.293 PM ADPassMon: Found expireAge in plist: 90
                4/12/12 12:33:02.420 PM ADPassMon: The new pwdSetDate (-1.34774E+5)
                4/12/12 12:33:02.422 PM ADPassMon: is < value in plist (0.0) so we ignore it
                4/12/12 12:33:02.431 PM ADPassMon: daysUntilExp: -1.535268960648E+4
                4/12/12 12:33:02.443 PM ADPassMon: daysUntilExpNice: -15352
                4/12/12 12:33:02.444 PM ADPassMon: expirationDate: Tuesday, March 31, 1970 8:00:00 PM
                4/12/12 12:33:02.446 PM ADPassMon: Finished process

                Just as an FYI, I think the date increased to March 31 because I tried doing what you said earlier and put a manual date of "90" in the preferences field. I have since done the "revert to defaults" option though.

  21. I have been trying to use manual mode but after I have a password change it will not reset the expiration back to the manual entry of 90 days until I click “Re-Check Expiration”

    Any ideas?

    • To keep chattiness to a minimum ADPassMon only communicates with AD periodically — which is twice a day or anytime the computer wakes or restarts.. Since it does not handle the password change itself, it won’t learn that the password changed until the next time it runs. This happens regardless of what mode you’re using.

      • Im now using Quest Authentication Services for domain authentication and up till now I’ve used manual mode to set the password policy but now manual mode doesn’t even work. I set it to 90 and hit enter and it gives me a -15365 days which shows the password expiring in 1970.

        • I just read through the Quest Authentication Services 4.0 Mac Admin Guide and see that it uses its own (non-Apple-native) Directory Services plugin. Currently, ADPassMon will only work if your Mac can communicate directly with your AD domain server(s) to get data on when your password was last changed. Manual mode is useful only for supplying the maximum password age if it can’t be obtained automatically. There may be a simple workaround I can implement, though.

          Can you try the following two commands and show me the results? This will operate on the currently logged-in user, but you can substitute “$USER” for any username. The first command is the one I’m currently using. The second command is an alternate form that may work better for you.

          dscl localhost read /Search/Users/$USER pwdLastSet

          dscl /Search read /Users/$USER pwdLastSet

          Also, please run ‘klist’ in the terminal and let me know if it shows an active kerberos ticket.

          • Here you go.

            temp-mac:bin jcollins$ dscl /Search read /Users/jcollins pwdLastSet
            No such key: pwdLastSet
            No such key: pwdLastSet
            temp-mac:bin jcollins$ dscl localhost read /Search/Users/jcollins pwdLastSet
            No such key: pwdLastSet
            No such key: pwdLastSet
            temp-mac:bin jcollins$ klist
            Credentials cache: API:62104299
            Principal: jcollins@SCENTSY.LOCAL

            Issued Expires Principal
            Apr 25 10:22:27 Apr 25 20:19:56 krbtgt/SCENTSY.LOCAL@SCENTSY.LOCAL
            Apr 25 10:22:28 Apr 25 20:19:56 ldap/corp-dc2.scentsy.local@SCENTSY.LOCAL
            temp-mac:bin jcollins$

              • I just checked and it is in my search policy. Hmm.

                I thought manual bypassed all authentication though. You would think it will work regardless.

              • It’s not an authentication issue, but a lookup issue. The “pwdLastSet” value lives in AD and is not cached locally. Using the native AD plugin, as long as you’re bound to AD, you can look up that value.

              • It does have an entry in the search policy called /VAS. I’m really hoping there is a workaround. We are going to quest because of the GPO control but losing ADPassMon in our environment will be a major subtraction from the benefits of quest. Thanks

  22. Oh Okay,

    I just didn’t wait long enough till after the change to have it auto update back to the 90 days I entered in manually.
    Thanks. This will have to be the solution till PSO’s are supported. Appreciate the quick response.

  23. It would be great to allow for some additional modifications. In our environment we use PGP and PGP does not do SSO on mac. It would be nice to have a plug-in that could also update the password for PGP Desktop so it could stay in sync as well.

    • Grant, I’m hesitant to add support for third-party products, but I’m downloading the trial version of PGP Desktop 10.2 to see if it’s workable.

      • Did you ever have any luck with Quest? I’m still in the dark with no working solution for ADpassmon. I tried everything I could think of with the search policy to no avail.

          • Hmm. How hard would it be to take all the authentication code out and just put a fixed 90 day timer that will count down and when you change your password or it expires it just resets to 90?

            I’m desperate for some kind of notification especially for our file vault users.

            Let me know if there is anything I can do! I appreciate it.

            • A fixed 90-day timer would not be trustworthy. If a user changed their password with anything other than ADPassMon — even the Accounts pref pane — the timer would reset. ADPassMon needs to query the directory to be sure it’s displaying correct info.

              I think in your case, you should get assistance from your site’s Windows admins to send out email alerts to users whose passwords will expire soon. There are plenty of free scripts out there that cam do this.

  24. Seems to be broken on Lion 10.7.4; reporting a -57 day password expiration. Standard Lion install bound against a 2003 domain.

    • Also reported that there wasn’t a ticket when the Ticket Viewer is showing a valid ticket.

    • I’m not seeing this problem on my end. Can you please send me some the log output when you choose “Re-check Expiration”? To do this, first open /Applications/Utilities/Console.app, select All Messages from the list on the left, then type “ADPassMon” in the search field in the upper right. Now choose Re-check Expiration from the ADPassMon menu and copy the last block of entries from the console and paste it here.

    • We also have some issues using it with 10.7.4. Every time a AD User logs in AdPassMon is asking if the user would like to create a Kerberos-Ticket – but we already got one before. Any news on this Issue? We just downloaded the last Version (1.6).

        • Hi Peter,
          i was just about to create the log for you, but then i read some other comments about how to set the manual value and then press tab or enter. after i did that also the question about the kerberos ticket never showed up again. So – this is solved – thanks!

          Now i see another issue – if i use the menubar-menu hand choose “Change Password…” i can see the Systempreferences starting in the Dock, but no window appears. If i click on Systempreferences in the dock, the Window appears and shows the user-settings where i could change the password. is that the expected behavior?

          • That’s definitely not the expected behavior. I took a look at my code and changed it so the prefs pane pops to the foreground before the password change dialog slides down. Look for this fix in version 1.7.

  25. AdPassMon can’t communicate with Growl for some reason. I’ve got Growl 1.3 installed with ADPassMon 1.7 on Mac OS X Server 10.7.4. Here are the relevant log entries:

    8/1/12 2:58:42.888 PM ADPassMon: Testing for Growl…
    8/1/12 2:58:42.906 PM ADPassMon: Running
    8/1/12 2:58:42.990 PM ADPassMon: *** -[ADPassMonAppDelegate applicationWillFinishLaunching:]: Growl got an error: Can’t continue «event register». (error -1708)
    8/1/12 3:00:22.715 PM ADPassMon: *** -[ADPassMonAppDelegate applicationWillTerminate:]: unrecognized function releaseStatusItem. (error -10000)

    Any idea what may be going on here?

    • Can you look at the Applications list in your Growl prefs pane and see if ADPassMon is listed? If it is, please remove it, then quit and restart ADPassMon and try it again. Beyond that, I’m not sure I can help. I’ve made no changes to the Growl code since version 1.4 and it has been working well for me.

  26. I’ve been using your applescript to tell when your AD account password expires on 10.7 and it works flawlessly. I recently started using 10.8, now when I check my AD account password it comes up with this error “Can’t make “8 (12A269)” into type integer.” This is the line its getting stuck on:

    set osVersion to (do shell script “system_profiler SPSoftwareDataType | awk -F. ‘/System Version/ {print $2}'”) as integer
    — get the value of ‘a’ in “Mac OS X 10.a.b”

    Suggestions?

    • I’m not using 10.8 yet, so I’ll need your assistance. Can you run ‘system_profiler SPSoftwareDataType | awk ‘/System Version/’ in the terminal and paste the output here?

      • Here is a few things I tried.

        Command:
        system_profiler SPSoftwareDataType | awk ‘/System Version:/’

        Output:
        System Version: OS X 10.8 (12A269)

        —————

        Command:

        system_profiler SPSoftwareDataType | awk /System Version/

        Output:
        awk: non-terminated regular expression System… at source line 1
        context is
        >>> <<>> <<<
        awk: bailing out at source line 1

        • Ok, I’ve have the awk modification that will fix it. Replace this line:

          set osVersion to (do shell script "system_profiler SPSoftwareDataType | awk -F. '/System Version/ {print $2}'") as integer

          with this:

          set osVersion to (do shell script "system_profiler SPSoftwareDataType | awk -F. '/System Version:/{sub(" \\(.*","");print $2}'") as integer

  27. Anyway to add a notification that will remind users to update their mobile device passwords when their AD account password is updated?

    example:
    User receives notification to update AD password on Mac.
    User forgets to update mobile devices password.
    Now user is unable to receive mail on the mobile device until password is updated.

    Anyway for ADPassMon to send a quick reminder alert to the user reminding them to update their mobile devices as well?

    • I don’t normally turn down feature requests, but a mobile device password change reminder is a bit outside the scope of my app. I’d suggest documenting an official password change procedure or your site and making sure that users are aware of it. Then you have something to point them to when some inevitably forget to update their mobile device passwords.

  28. I total understand and agree with your suggestion. A customer asked that I inquiry. Thanks again for your response.

  29. Hi pmbuko- I love ADPassmon and use it all the time, but I’ve got a problem with the launch agent I’m deploying with it. About 20% of the time when a user first logs in, OS X pops up a screen asking the user to locate System Events.app. Once the dialog has been pointed to Coreservices and the System Events application, ADPassmon pops up.
    Like I said, though, this doesn’t happen on every machine I image, only about 20%. It only happens once if at all, and if it doesn’t happen on your first login, it won’t ever happen.
    Here’s the contents of the launchagent I’m using:

    KeepAlive

    SuccessfulExit

    Label
    com.wordpress.yourmacguy.adpassmon
    ProgramArguments

    /Applications/ADPassMon.app/Contents/MacOS/ADPassMon

    Any ideas?

    • Nick, the dialog asking for the location of System Events comes up because of an issue with AppleScript, not your launch agent. I have a hunch that System Events hasn’t made it into the launch services database on the affected systems and that’s the reason AppleScript is asking you to find it.

      One thing you can try is simply launching System Events once *before* you launch ADPassMon. It should be invisible to the user and make it known to the OS so that ADPassMon doesn’t ask you to locate it.

      • I’m trying to do that by running an ‘open /System/Library/CoreServices/System\ Events.app/’ command in a login script, but I’m still getting the prompt. What would be the best way to force System Events to launch before the launchagent triggers?

        • I’m going to try rebuilding the launchservices database with this command in the login script instead:
          `sudo find /System/Library/Frameworks -name lsregister` -kill -seed

            • unfortunately, I’m still getting the ‘Where is system events’ dialog. I also tried using a 10.8 server configuration profile with a login item instead of the launch agent, got the same results . . . .

  30. Question and possible request – Can this app be repackage with a script I have. As we all know if macs are in an AD environment they are also required to rebuild / delete items in their keychain. I have a script that does a search of all keychain items from their old password and changes it to there new password / then changes their ad password / then reboots. If i give you the script can you put this in place of the Change Password item in your drop down box?

    • I won’t put it into the main version, but I could fork the project and create a version for you that includes your script. I’ll contact you via email.

      • Hi,
        I would love to get my hands on Gregs Script or to see this forked..did anything happen in this regards ?
        often the case that the old ad credentials have been saved in the keychain for non kerberised servers ie network printing, basic forms etc so users change their password, but still have to go through and update keychain passwords which the user is incapable of doing and and takes 5 minutes of support calls every password change despite guides been available

    • Actually, I now have a beta version for 10.8 that I’ve modified to use the Notification Center. The app isn’t officially signed, so it won’t run if your security settings prevent unsigned apps from launching. I’m considering getting a proper Apple Developer account to remedy this. Looks for version 1.8 of ADPassMon to be released this week.

  31. I am trying to make it so my non administrative users can not access the preferences or push the reset button. I ran the defaults write org.pmbuko.ADPassMon prefsLocked true through ARD Unix command but they are still able to push the reset button. Is this by design or am I doing it wrong?

    • Joseph,

      The prefsLocked setting already works as you want it to. When you run the ‘defaults write org.pmbuko.ADPassMon prefsLocked true’ command via ARD, make sure you run it as the current console user, not as root. Also, you will need to quit and re-launch ADPassMon for the change to take effect.

      • That was it. Thank you much. Your support has been excellent. Apple should learn a thing or two from you.

  32. Thanks for the quick response. Is that something that will be done soon? Not being impatient just wanting to know whether I should wait in deploying it.

  33. Having two issues here: Logged in as normal AD user and on launch I am getting “For best performance, ADPassMon requires that ‘Access for assistive devices’ be enabled” message. This I thought only occurs for Admins? And what is the command to turn on Assistive Devices from the cmd line?

    The other problem is this message: No Kerberos ticket was found. Do you want to renew it? When users login they mount shares from a Windows server so they have to have a ticket or the shares wouldn’t mount. Ticket Viewer shows that the user has a ticket.

    I have a LaunchAgent in /Library/LaunchAgents that starts a script in /sbin that runs:
    /Applications/ADPassMon.app/Contents/MacOS/ADPassMon

    Trying to get it so ADPassMon.app opens and doensn’t bother the user.

    Thanks,

    Dan

    • I’m about to leave for a two week vacation and can’t look into this now, but let me know what OS you’re using. Also, can you open up Console.app, filter the output of ‘All Messages’ for ‘ADPassMon’, save a copy and email it to me? (Send to my username at gmail)

  34. After I install the application this is what I run through ARD. This should help you out.

    Run as Root
    sudo touch /private/var/db/.AccessibilityAPIEnabled

    Run as Console user while user is logged in
    defaults write org.pmbuko.ADPassMon prefsLocked true
    defaults write loginwindow AutoLaunchedApplicationDictionary -array-add ‘{Path=”/Applications/ADPassMon.app”;}’

    • Thanks Joseph……I looked before on how to turn on Accessibility and couldn’t find out how to do it. Will look into that! The other commands I can’t use though for console as users have a temp home on login. Need to set the pref file in the user template and seems to be giving me problems if I set the file up with limited keys. Was only putting in growlEnabled and PrefsLocked and it was displaying a wild number and getting kerberos errors on login about not having a ticket. Here is what I have now in the org.pmbuko.ADPassMon.plist pref file and think its working, adding expireAge seems to have fixed the issue for some reason (Hopefully the following displays correctly):

      expireAge
      180
      growlEnabled

      prefsLocked

  35. Hello,

    I also had the issue with ADPassMon telling me that my password will expire in -15716d. And indeed:
    $ /usr/bin/dscl localhost read /Search/Users/$USER PwdLastSet | /usr/bin/awk ‘/LastSet:/{print $2}’
    No such key: PwdLastSet

    Looking at /Search/Users/$USER, I discovered the SMBPasswordLastSet value:

    $ /usr/bin/dscl localhost read /Search/Users/$USER SMBPasswordLastSet | /usr/bin/awk ‘/LastSet:/{print $2}’
    129991796360808927

    So I modified the source code of ADPassMon (ADPassMonAppDelegate.applescript) from:

    set my pwdSetDateUnix to (((do shell script “/usr/bin/dscl localhost read /Search/Users/$USER pwdLastSet | /usr/bin/awk ‘/LastSet:/{print $2}'”) as integer) / 10000000 – 1.16444736E+10)

    to:

    set my pwdSetDateUnix to (((do shell script “/usr/bin/dscl localhost read /Search/Users/$USER SMBPasswordLastSet | /usr/bin/awk ‘/LastSet:/{print $2}'”) as integer) / 10000000 – 1.16444736E+10)

    And now, ADPassMon is working fine.

    This is my two cents, I hope it can help…

      • In some environments, this call to dscl may return multiple values (SMBPasswordLastSet can appear under dsAttr and a few other places). This will cause this command to fail as it’ll try converting the multiple lines returned into an integer. All you really need to get is the FIRST match. This is more reliable:

        set my pwdSetDateUnix to (((do shell script “/usr/bin/dscl localhost read /Search/Users/$USER SMBPasswordLastSet | /usr/bin/grep -m 1 SMBPasswordLastSet | /usr/bin/awk ‘/LastSet:/{print $2}’”) as integer) / 10000000 – 1.16444736E+10)

        • Thanks for catching this. Instead of modifying the shell command, I inserted “first word of” right before the triple open parentheses. I’ll include this fix in the next release and credit you in the about box.

          • Right-o; old-school unix shell guy here — just spinning up on AppleScript — so I tend to default to the sed/grep/awk tricks. :)

            Glad to help out.

  36. Does Adpassmon support languages besides english? I’ve got a user in norway having some problems when his mac is set to use norwegian as the default system language . . . ADpassmon launches, but the menulet never appears.

    • Nick, ADPassMon is only available in English. I don’t have the resources to provide localization bundles for other languages. That being said, I’d like to see what the console log shows when the app is launched. Could you get that and paste it here?

  37. Hi, your App rocks!!!! Just a quick question – Would be possible to display a message for the user remind him of the password policy in place – i.e minimum of eight characters, with at least one number and uppercase letter??

    Thank you

    • Thanks for the compliment, Bruno. Different sites will have different complexity requirements, and while I could modify the app to include a custom reminder screen, I don’t think that would be the best way to remind users of password complexity requirements.

  38. Hi Peter,

    Many thanks for the quick reply. Would it be very hard / complicated to do so? My ideas was to have a settings in preferences that allows IT people to manually insert text that states the password policy in place in the “Change password box” so when user needs to change the password he /she knows the password policy.

    We do have a few users that are very “forgetful”

    Thanks in advance!

  39. Hi Peter,

    Many thanks on getting back to me so quickly. Sorry to be so persistent but can would be possible to make the ADMon Preferences text stating ” Your password will expire on ” editable so we can pass the password policy to the user information to the user by Growl?

    Example – Your password will experience on xxx day – Please ensure that when changing the password that it has 8 characters, with 1 number, one uppercase?

    Many thanks – your support has been great!

  40. Peter:

    A quick thought. To determine initial LDAP server, your code uses scutil -dns to pull the first nameserver and then attempts to connect to that to get the defaultNamingContext for the successive LDAP queries for password age. This is problematic in many cases: 1) the user is on a network where the DNS resolvers are not hosted on Windows but are replicas or hidden master, 2) the DNS resolver is actually a virtual address forwarding to a DNS pool, 3) DNS is deployed as a role on on non DC server, or 4) the nameserver address is tied to a VPN stub resolver and not an on-network resolver.

    A better way to determine initial naming context is to do the following:

    set my myLDAP to (do shell script “/usr/sbin/dsconfigad -show | /usr/bin/awk ‘/Active Directory Domain/ {print $5}'”) as text

    and then use the extracted value (the domain that the machine belongs to) as the host for ldapsearch. This will of course fall to DNS and may query outside of your AD site, but this should still work in all of those scenarios above. It actually wouldn’t be too difficult to select a particular LDAP server _in_ your AD site, but this would need another ldapsearch lookup and DNS query for the correct SRV record.

    Anyway, just my two cents. Do you accept external commits to any particular branch of your Github repository?

    • Joel, I can add you as a collaborator. I’m putting my latest changes into the mavericks branch, which I plan to release around the time that Apple releases Mac OS 10.9. Do you have a github account?

  41. I’m having trouble starting the application. I’m getting an error registering with Growl. Here’s the last few lines in Console.

    8/28/13 1:32:38.165 PM [0x0-0x58f58f].org.pmbuko.ADPassMon: objc[6856]: Object 0x10011d980 of class NSPathStore2 autoreleased with no pool in place – just leaking – break on objc_autoreleaseNoPool() to debug
    8/28/13 1:32:38.165 PM [0x0-0x58f58f].org.pmbuko.ADPassMon: objc[6856]: Object 0x10011dc10 of class NSPathStore2 autoreleased with no pool in place – just leaking – break on objc_autoreleaseNoPool() to debug
    8/28/13 1:32:38.203 PM [0x0-0x58f58f].org.pmbuko.ADPassMon: objc[6856]: Object 0x100513f00 of class __NSArrayM autoreleased with no pool in place – just leaking – break on objc_autoreleaseNoPool() to debug
    8/28/13 1:32:38.203 PM [0x0-0x58f58f].org.pmbuko.ADPassMon: objc[6856]: Object 0x100513f30 of class __NSCFString autoreleased with no pool in place – just leaking – break on objc_autoreleaseNoPool() to debug
    8/28/13 1:32:41.142 PM ADPassMon: Running on OS 10.7.x
    8/28/13 1:32:41.143 PM ADPassMon: Testing Universal Access settings…
    8/28/13 1:32:43.971 PM ADPassMon: Already enabled
    8/28/13 1:32:43.972 PM ADPassMon: Testing for Growl…
    8/28/13 1:32:43.987 PM ADPassMon: Running
    8/28/13 1:32:44.127 PM ADPassMon: *** -[ADPassMonAppDelegate applicationWillFinishLaunching:]: Growl got an error: Can’t continue register. (error -1708)

    • What version of Growl are you using? Can you save the code found at this link into a new applescript and try to run it from Script Editor?


      tell application "System Events"
      set isRunning to (count of (every process whose bundle identifier is "com.Growl.GrowlHelperApp")) > 0
      end tell
      if isRunning then
      tell application id "com.Growl.GrowlHelperApp"
      — Make a list of all notification types that this script will ever send:
      set the allNotificationsList to {"Test Notification"}
      — Make a list of the enabled notifications. Others can be enabled in Growl prefs.
      set the enabledNotificationsList to {"Test Notification"}
      — Register with Growl
      register as application "Test AppleScript" ¬
      all notifications allNotificationsList ¬
      default notifications enabledNotificationsList ¬
      icon of application "Script Editor"
      end tell
      end if

      view raw

      growl_register

      hosted with ❤ by GitHub

  42. I would love it if ADPASSMON did NOT change my boot disk icon. Is this an option? How can I fix this?
    Thank you,
    Andy

      • Sure. Thank you.
        After installing ADPassMOn, When I boot my mac and hold the Option key, I get two icons. One is my HD, one is the Recovery Partition. The HD now has the words ADPassMon written on it. Try it. It’s disconcerting.

  43. Hi. I just installed ADPassMon on a 10.8 system. It shows “?” in the menu bar and I see this in the console:

    10/29/13 4:01:56.380 PM ADPassMon[4977]: Starting manual process…
    10/29/13 4:01:56.382 PM ADPassMon[4977]: Found expireAge in plist: 90
    10/29/13 4:01:56.643 PM ADPassMon[4977]: Script Error: Can’t make “130268609830015509
    130207927662076121” into type integer.

    • Which version of ADPassMon are you using? If you’re using 1.9.1, can you try 1.9 and see if you get the same error? I haven’t tested my newest version as thoroughly as older ones.

  44. We recently made a change to our password policy so the passwords expire now, and I found ADPassMon as something that might help for our growing Mac users. Testing it out, it gives me 41d as the time but our policy is 180 days and when I try to change the password I get a message that it doesn’t meet the requirements when it should. I have refreshed the Kerberos ticket and I tried using the Apple generated password from Users & Groups, but still got the error message. Any ideas for what I should check?

    • ADPassMon doesn’t control the password complexity requirement, so I’m not sure why you’re unable to change your password. as for reporting the wrong expiration time, I would try using the Manual mode and putting in 180.

  45. Hi. Just starting testing this out last week for use in my environment but, it seems like we’ve a got AD weirdness, too. Running 1.9.1. It looks like the last password set date is being set as the expiration date and I end up with a negative number.

    Here’s the log:

    11/4/13 9:19:11.570 AM ADPassMon[48903]: Running on OS 10.9.x
    11/4/13 9:19:11.670 AM ADPassMon[48903]: Testing Universal Access settings…
    11/4/13 9:19:12.087 AM ADPassMon[48903]: Testing for Kerberos ticket presence…
    11/4/13 9:19:12.177 AM ADPassMon[48903]: Ticket found and renewed
    11/4/13 9:19:12.181 AM ADPassMon[48903]: Starting auto process…
    11/4/13 9:20:33.508 AM ADPassMon[48903]: mySearchBase:
    11/4/13 9:21:52.463 AM ADPassMon[48903]: Got expireAge: 0
    11/4/13 9:21:52.728 AM ADPassMon[48903]: The new pwdSetDate (1.598066247116E+4)
    11/4/13 9:21:52.786 AM ADPassMon[48903]: is ≥ value in plist (1.598066210938E+4) so we use it
    11/4/13 9:21:52.817 AM ADPassMon[48903]: daysUntilExp: -32.936047354384
    11/4/13 9:21:52.835 AM ADPassMon[48903]: daysUntilExpNice: -32
    11/4/13 9:21:53.093 AM ADPassMon[48903]: expirationDate: Wednesday, October 2, 2013 at 10:53:58 AM
    11/4/13 9:21:53.101 AM ADPassMon[48903]: Finished process
    11/4/13 9:21:53.121 AM ADPassMon[48903]: in the loop

    If I look for SMBPasswordLastSet through dscl, I get a timestamp of 130252028375085808 which converts into the expiration date above.

    • Looks like it can’t find your domain’s search base, which has the form ‘dc=domain,dc=com’. Does your AD domain happen to use a subdomain? In any case, setting ADPassMon to manual mode and supplying the expiration age should avoid the error.

  46. We actually have two domains in our forest, but when I tried setting it to manual last week, it wouldn’t take and kept resetting back to auto. Today, though, it decides to work.

  47. First I’d like to say thanks for a great tool! We just started testing with it on 10.8 & 10.9, and everything is great except it does not open the sys prefs > users&groups > change password pane when clicking “Change Password” in the drop down menu. I did verify that assistive devices are enabled in 10.8, while in 10.9, I do not see ADPassMon in the Accessibility pane. What am I missing? TIA!!

  48. Hey! Can you change or add a preference to have the change password menu choice to to the password change in the newest ticket rather than the user pref pane?

    • ADPassMon can’t bypass a disabled change password functionality. Are the Parental Controls enabled for these accounts? That’s where you can find restrictions on the ability for users to change their passwords.

        • Did some more looking around. I have a configuration profile installed. Even tho the profile allows the user to change the password, the option is still disabled. Removing the profile allows the user to change the profile. That being said the apple password expiration prompt still is not popping up on the login screen.

          • Just wanted to update you and others that may have this problem. There IS a bug in Mavericks that breaks login window password expiration notices when the system authenticate against active directory. See the below response from our AppleCare Enterprise Engineer.

            “Thank you for the clarification. I’ve just tested and have been able to reproduce this behavior here with Mavericks. This certainly isn’t the expected behavior, so I’ve filed a report with Product Engineering to see if we can determine why this is occurring.

            Unfortunately, I don’t have a workaround for you to force the prompt to appear; I’ll need to work with Product Engineering to see if I can develop one. In the interim, however, there is well-regarded third-party tool (under MIT license) that serves to give password expiration warnings that might suit your needs. That tools is ADPassMon, found here: https://yourmacguy.wordpress.com/adpassmon/.”

  49. We are trying to add a kill process for adpassmon before the updated installer runs. In Activity Monitor the process name is blank. Is there a way to resolve this?

  50. Hey man, looking forward to utilizing this at work! Great tool! We have a handful of macs running Mountain Lion. I wanted to use the pwPolicy feature, but whenever I assign any value and then log off/on again, it flushes all of my settings and prompts me to download a new Kerberos ticket. I have tried this on 1.9, 1.9.1, 1.9.2, all with the same results. Also, I can confirm that v1.9.2 doesn’t open up Users & Groups when selecting change password from ADPassMon (it is working in both 1.9 & 1.9.1 however)

      • A correction to my first post; my problem was that defaults wasn’t updating the plist file correctly, but once I switched over to a plist editor, things stopped breaking. I’m not running into the flushing of prefs anymore on any version of the program. Here’s what I found though…
        (All of this on Mountain Lion, 10.8.5)
        v1.9 – pwPolicy works great, brings up the window and then groups and prefs when changing password
        v1.9.1 – when a pwPolicy attribute is set, ADPassMon stops opening up users and groups and doesn’t bring up the warning window. (Without the pwPolicy set, users and groups opens up as expected
        v1.9.2 – doesn’t open up users and groups regardless of pwPolicy being set.

        Hope that helps!

        • Ah, thanks for this! I’ve already identified the cause, at least in v1.9.2 — and I suspect the fix will also fix 1.9.1. I’m now forcing ADPassMon to read the pwPolicy value as a string and the dialog appears normally. When it’s dismissed the password change dialog appears. Also, when the pwPolicy is empty, the password change dialog appears. Expect 1.9.3 shortly…

  51. Thanks for the update. When running defaults write org.pmbuko.ADPassMon prefsLocked true I can see the entry change in the plist but im still able to edit prefs. Any ideas?

    • If you’re using OS 10.9, it’s probably because all preferences are cached and it can take a while for the changes to be seen. Try doing ‘killall cfprefsd’ from the Terminal to force a reload of all preferences and see if that makes a difference.

    • Can you try deleting the plist file altogether? (Check in ~/Library/Preferences and /Library/Preferences). Then launch and set up ADPassMon again. It should create a new plist file. Then try adding the prefsLocked item (should be a boolean) with a plist editor. The comment Joe made a few above yours (https://yourmacguy.wordpress.com/adpassmon/#comment-4843) implies that the defaults method is no longer working well. I’ll have to see if it’s my fault or due to some higher up bug.

  52. I’m noticing that 10.8 and 10.9 clients are not keeping ADPassmon in the menu bar anymore. 10.7 clients are fine. Testing with 1.9.3. Tried installing on a new 10.8.5 machine and ran the regular scripts through ARD
    Console User
    defaults write org.pmbuko.ADPassMon prefsLocked true
    defaults write loginwindow AutoLaunchedApplicationDictionary -array-add ‘{Path=”/Applications/ADPassMon.app”;}’
    Root
    sudo touch /private/var/db/.AccessibilityAPIEnabled

      • I haven’t figured out applescript very well hence why I use ARD for everything thus far. Would I just be able to modify my com.apple.loginitems.plist. and push it out via copy in ARD?

        • That would probably work well, as long as you’re fine completely replacing the contents of the file. The applescript command at the link should work as a simple copy/paste job. Just replace “TextEdit” with “ADPassMon” in both places.

          • Copied this into the Unix portion of ARD
            osascript -e ‘tell application “System Events” to make new login item at end with properties {path:”/Applications/ADPassMon.app”, name:”ADPassMon”, hidden:true}’

            Received error message 121:122: syntax error: Expected expression but found unknown token. (-2741)

  53. Any chance you’d humor a feature request to change the dialog box that asks for kerberos password wording from “Kerberos” to “Domain” or something akin to that. AD/Kerberos? Or can I haxy the app to change the wording myself? I understand what kerberos is but most of the users I work with will just be confused when the app asks for their kerberos password.

  54. Peter, how are you or others handling users changing their passwords while not on the corporate LAN or VPN? We have all sorts of issues with users changing their passwords off the network and wreaking havoc when they return because passwords are no longer in sync (in addition to fudging up their FV2). We basically run an Applescript if their password is determined to be within two weeks of expiring that asks them if they are on VPN or on the corporate network, but we are having all sorts of problems with Accessibility in 10.9.

    • Graham, my site doesn’t actually use ADPassMon any more — ironic, eh? — so this is not really a concern for us. Our users have both LDAP and AD accounts, and we use a third-party tool that syncs LDAP and AD account passwords. The tool also handles the reminders. Our users are trained to only use this tool to change their passwords.

      Currently ADPassMon’s “Change Password” item is not tied to network state, but I *could* make it unavailable when the AD servers cannot be reached. This would not, of course, prevent users from changing the password via the Users & Groups pref pane.

      FV2 issues are another thing altogether. Our site does not mandate it, so most users do not use it.

      • It would certainly be useful to be able to limit when users could change their password, at least as it pertains to the ADPassMon alert. A customizable alert would also be useful in letting users know to sign into VPN or something similar.

        • This is an interesting observation, one that may explain issues we’ve seen when users reset passwords through the User + Groups System Preferences pane, but then end up in password purgatory with sync between AD and local password stores. I had assumed this was just the usual Keychain hell. Have not causatively connected off-network password changes with subsequent password failures, but it does make sense. So are you guys saying the Mac definitively must be online at the moment the password change request is made in OS X? Obviously domain password changed eventually carry down to the Mac, prompting users to update their Keychain password on login, but perhaps not the other way around?

          • Unless somehow the OS caches both credentials and holds them until it is able to communicate with an AD controller, I don’t see it happening. At least in the wild, we’ve seen any number of Macs that will allow machines to change password offline and then fudge the sheets when it starts talking to AD again. It would be great to somehow prevent that from happening.

            • I agree. I already have the “disable change password menu option when AD cannot be reached” feature added to the next release of ADPassMon, but that won’t stop users who go directly to the System Prefs to change their password.

  55. Hi from France. We are evaluating this very valuable tool and we encountered this problem : the customized change password dialog does not support special characters like “;” and it may fail with ‘ \ / ? * : ; ” | & . May you be able to fix this issue ? Best regards.

  56. Hi from France. Feature request : would it be possible to set a new key that would permit to optionnaly add a clickable URL when the password policy string is shown. The idea would be that before the password dialog is shown, the user would see a message like “Go to this corporate page to get all the details about the password change process”, page which would include the password policy string with many other details. Actually, the password policy string does not permit us to enter all the details about the work to do and to drive the user to a web page. You have already a similar process to drive the user to go to a password change web page. Best regards.

  57. Hi from France. Feature request : would it be possible that the previous / new password entered is not shown as bullets in the customized change password. It may lead to think that these informations are retained somewhere (in clear text ?), which is a bit scary. Best regards.

  58. Awesome utility – Really appreciate you writing and sharing it with the world.

    With that said, i’m having an issue a few people above have mentioned – “Password expiring on Password expires on Monday, 2 March 1970 10:00:00 am”

    This is the result of the pwdLastSet lookup.

    XXXXXXX:~ xxx$ dscl /Search read /Users/xxx pwdLastSet
    No such key: pwdLastSet
    dsAttrTypeNative:pwdLastSet: 130462242162960345
    dsAttrTypeNative:pwdLastSet: 130462242162960345

    Which is correct when translated – Any idea?

    • I believe the multiple pwdLastSet responses are throwing off my code. I can put in a fix for this in the code. Is your Mac bound to more than one AD server?

      • Hi,

        Wow thanks for the quick response – Again, really appreciate it!

        Just did some looking around, it’s because we have two search policies – If I remove one it returns only a single result and ADPassMon works beautifully.

        However, we do need two search policies because we have a ridiculously huge AD schema and we direct machines to a cut down location first and then the entire schema second.

        Don’t feel like you need to urgently make changes here, but would really appreciate it if you could add it in at some point!

  59. Hey there! We’re having an issue where it shows password expiration in -3 days. I’ve just changed my password 3 days ago, os I should have quite a white before the next expiration. We’re using Mavericks 10.9.3 and our AD is on Windows Server 2012 R2. Can you suggest a fix?

    • I just recently uploaded a very small update that may help. Can you redownload the latest version and see if that fixes the issue?

      • Thanks! So, I had v2.0.6 and I just downloaded v1.9.4 using the link above… v1.9.4 had the same -3d behavior. Lemmie see if I can find a newer 2.x version….

            • Ok, so no difference (since it’s three days later now). Hmmm. Can you open up Console.app, filter for “ADPassMon”, and tell me what you see there?

              • 6/30/14 11:23:32.629 AM com.apple.launchd.peruser.719161608[231]: ([0x0-0x2a72a7].org.pmbuko.ADPassMon[66043]) Exited: Killed: 9
                6/30/14 11:23:41.990 AM ADPassMon[66054]: Running on OS 10.9.x
                6/30/14 11:23:41.991 AM ADPassMon[66054]: Testing Universal Access settings…
                6/30/14 11:23:42.021 AM ADPassMon[66054]: Testing for Kerberos ticket presence…
                6/30/14 11:23:42.079 AM ADPassMon[66054]: Ticket found and renewed
                6/30/14 11:23:42.080 AM ADPassMon[66054]: Starting auto process…
                6/30/14 11:23:42.089 AM ADPassMon[66054]: myLDAP: 172.xxx.xxx.xxx
                6/30/14 11:23:42.404 AM ADPassMon[66054]: mySearchBase:
                6/30/14 11:23:42.427 AM ADPassMon[66054]: Got expireAge: 0
                6/30/14 11:23:42.455 AM ADPassMon[66054]: The new pwdSetDate (1.624497048297E+4)
                6/30/14 11:23:42.455 AM ADPassMon[66054]: is < value in plist (1.624497070312E+4) so we ignore it
                6/30/14 11:23:42.460 AM ADPassMon[66054]: daysUntilExp: -6.670755208334
                6/30/14 11:23:42.460 AM ADPassMon[66054]: daysUntilExpNice: -6
                6/30/14 11:23:42.462 AM ADPassMon[66054]: expirationDate: Monday, June 23, 2014 at 7:17:49 PM
                6/30/14 11:23:42.465 AM ADPassMon[66054]: Finished process
                6/30/14 11:23:42.465 AM ADPassMon[66054]: in the loop
                6/30/14 11:23:48.601 AM ADPassMon[66054]: Starting auto process…
                6/30/14 11:23:48.609 AM ADPassMon[66054]: myLDAP: 172.xxx.xxx.xxx
                6/30/14 11:23:48.632 AM ADPassMon[66054]: mySearchBase:
                6/30/14 11:23:48.653 AM ADPassMon[66054]: Got expireAge: 0
                6/30/14 11:23:48.688 AM ADPassMon[66054]: The new pwdSetDate (1.624497048297E+4)
                6/30/14 11:23:48.688 AM ADPassMon[66054]: is < value in plist (1.624497070312E+4) so we ignore it
                6/30/14 11:23:48.693 AM ADPassMon[66054]: daysUntilExp: -6.670824652778
                6/30/14 11:23:48.693 AM ADPassMon[66054]: daysUntilExpNice: -6
                6/30/14 11:23:48.694 AM ADPassMon[66054]: expirationDate: Monday, June 23, 2014 at 7:17:49 PM
                6/30/14 11:23:48.696 AM ADPassMon[66054]: Finished process
                6/30/14 11:23:54.198 AM ADPassMon[66054]: Starting auto process…
                6/30/14 11:23:54.205 AM ADPassMon[66054]: myLDAP: 172.xxx.xxx.xxx
                6/30/14 11:23:54.231 AM ADPassMon[66054]: mySearchBase:
                6/30/14 11:23:54.252 AM ADPassMon[66054]: Got expireAge: 0
                6/30/14 11:23:54.276 AM ADPassMon[66054]: The new pwdSetDate (1.624497048297E+4)
                6/30/14 11:23:54.276 AM ADPassMon[66054]: is < value in plist (1.624497070312E+4) so we ignore it
                6/30/14 11:23:54.281 AM ADPassMon[66054]: daysUntilExp: -6.670894097222
                6/30/14 11:23:54.281 AM ADPassMon[66054]: daysUntilExpNice: -6
                6/30/14 11:23:54.281 AM ADPassMon[66054]: expirationDate: Monday, June 23, 2014 at 7:17:49 PM
                6/30/14 11:23:54.283 AM ADPassMon[66054]: Finished process

                There it is in all its glory….. minus a slightly sanitized IP for the LDAP

              • Is the myLDAP value an AD domain controller? I make the assumption that your primary DNS server is an AD server. If it isn’t, and you can’t make it so, you will need to use manual mode.

              • Ok. Do you have a valid Kerberos ticket? (Check by running ‘klist’ in terminal.) If so, try running ‘ldapsearch -LLL -Q -s base -H ldap://172.x.x.x defaultNamingContext’ and let me know the output.

  60. Making a Mavericks image I now receive the following error message trying to start SSH for the automatic launch of ADPassmon. /bin/bash: line 1: /sbin/service: No such file or directory. Haven’t found much googling. What am I missing?

  61. Have you ever seen 2.0.6 revert back to 1.9.4 after a reboot? That’s what just happened to me while testing. I ran the script for defaults write org.pmbuko.ADPassMon selectedBehaviour -int 2 and also created a password policy defaults write org.pmbuko.ADPassMon pwPolicy “Your password requirement message goes here.” rebooted and it reverted.

    • Whoops. I see what happened it didn’t overwrite the application it created another one that didn’t startup at log in. So I’ll have to write a script to remove the old ADPassmon first before installing the new one.

  62. I’m seeing an odd issue and forgive me if this is a simple fix. When I upgrade 1.9.4 to 1.9.5 the options to change the password from ADPassMon are grayed out. If I reset the application in ADPassMon the menu item appears again. If I recheck the kerberos ticket in the application the option grays out again.

    • Is this unique to 1.9.5? I didn’t change any code for this part of ADPassMon between 1.9.4 and 1.9.5, but that doesn’t mean there isn’t a bug.

  63. Yes, this is the first time I’ve seen this issue. I tested another machine doing just a drag and replace and it had the same issue. Reverting back to 1.9.4 brings back expected functionality. Thanks for responding.

  64. Hi,

    Firstly thank you SO much for all of your hard work on this lifesaving little app!

    I have the following issue. Using ADPassMon it returns a result of, for example, 86 days remaining on a 90 day policy which is fine, but it does this for ever user I’m testing it with!

    However, if I run the following code in Terminal…

    #!/bin/bash
    pwPolicy=90
    user=`/usr/bin/who | /usr/bin/awk ‘/console/{ print $1 }’`
    lastpwdMS=`dscl localhost read /Local/Default/Users/$user | grep SMBPasswordLastSet | cut -d’ ‘ -f 2`
    todayUnix=`date “+%s”`
    lastpwdUnix=`expr $lastpwdMS / 10000000 – 11644473600`
    diffUnix=`expr $todayUnix – $lastpwdUnix`
    diffdays=`expr $diffUnix / 86400`
    daysremaining=`expr $pwPolicy – $diffdays`
    osascript -e ‘display notification “Go to (site for pwmanagement) to change your password” with title “Password expires in ‘$daysremaining’ days” sound name “Hero”‘

    It returns the correct expiry, usually around 22-26 days at the moment depending on the user.

    Any ideas why that would be Sir?

    Thanks.

    • How are you testing it with multiple accounts? Are they all logging in to the same computer or are you using separate computers? It should work properly in both cases, but it might help me figure out where to start looking.

      Also, could you share the relevant ADPassMon log lines from Console.app when it reports the incorrect expiration date?

      • Hi,

        Sorry I should have been clearer. Multiple Macs so different users.

        Here you go…

        13/08/2014 13:42:25.888 ADPassMon[6336]: selectedMethod: 1
        13/08/2014 13:42:25.888 ADPassMon[6336]: Starting auto process…
        13/08/2014 13:42:25.906 ADPassMon[6336]: myLDAP: 3.161.16.38
        13/08/2014 13:42:26.379 ADPassMon[6336]: mySearchBase: DC=nbcuni,DC=ge,DC=com
        13/08/2014 13:42:26.413 ADPassMon[6336]: Got expireAge: 91
        13/08/2014 13:42:26.444 ADPassMon[6336]: The new pwdSetDate (16289.58)
        13/08/2014 13:42:26.445 ADPassMon[6336]: is < value in plist (1.628958398438E+4) so we ignore it
        13/08/2014 13:42:26.450 ADPassMon[6336]: daysUntilExp: 85.05452
        13/08/2014 13:42:26.450 ADPassMon[6336]: daysUntilExpNice: 85
        13/08/2014 13:42:26.451 ADPassMon[6336]: expirationDate: Thursday, 6 November 2014 15:00:57
        13/08/2014 13:42:26.452 ADPassMon[6336]: Finished process
        13/08/2014 13:42:29.093 ADPassMon[6336]: Starting auto process…
        13/08/2014 13:42:29.094 ADPassMon[6336]: Found expireAge in plist: 91
        13/08/2014 13:42:29.130 ADPassMon[6336]: The new pwdSetDate (16289.58)
        13/08/2014 13:42:29.130 ADPassMon[6336]: is < value in plist (1.628958398438E+4) so we ignore it
        13/08/2014 13:42:29.135 ADPassMon[6336]: daysUntilExp: 85.05448
        13/08/2014 13:42:29.135 ADPassMon[6336]: daysUntilExpNice: 85
        13/08/2014 13:42:29.136 ADPassMon[6336]: expirationDate: Thursday, 6 November 2014 15:00:56
        13/08/2014 13:42:29.137 ADPassMon[6336]: Finished process

        Thanks.

        • The pwdSetDate value in the log file looks really small. I do a calculation that compares a value in the plist to the new value. If the new value is less than the one in the plist, then it gets ignored. (A larger value means a more recent password set date.)

          Do you push out a plist with this app? If so, try removing the pwdSetDate value from it. I think the issue is something else, though.
          Still thinking.

  65. Nope, no plist pushed out. Setup manually on each Mac for now whilst we are still testing. Thanks for looking into it, you rock!

    • Are you using the most recent version of ADPassMon (v1.9.6)? I changed the way the dates were handled in this version, so I think you’ve found a bug. I suspect the date that passwords at your site changed happen to fall near a date/time that result in a rounding error in my code. Please download this test version of ADPassMon and let me know if it fixes the issue. If it does, I’ll release it as v1.9.7.

      https://dl.dropboxusercontent.com/u/3967964/ADPassMon_v1.9.7beta.zip

      • Damm you’re good! I’ll have to check tomorrow morning now as I’ll be back in the office then. I’ll report back.

          • And if it helps, under Auto, it gets a maximum password days of 91 and not 90 which is the actual password expiry.

              • Sure… the myLDAP & mySearchBase are correct but for obvious reasons I can’t post them here!

                expireAgeUnix: 7862400
                expireAge: 91.00000000000000000000
                pwdSetDateRaw: 130518936969025000
                pwdSetDateUnix: 1407420096.90250000000000000000
                pwdSetDate: 16289.58445489004629629629
                todayUnix: 1408025407
                today: 16296.59035879629629629629
                daysUntilExp: 83.99409609375000000000
                daysUntilExpNice: 83

  66. Great tool for the MAC, how about LINUX?

    From what I saw it would be a perfect fit.

    Could you give us any clue if this tool is available for Linux as well? It would be great to see this working in Ubuntu/Debian environments, too.

    Many thanks

    Joe

  67. I just downloaded ADPassMon to try out on our corporate network. When I double click on the application nothing happens. Absolutely nothing. No program window, no menubar changes – nothing. Our Macs are running OSX 10.9.4 and I made sure I downloaded the version for 10.8 and 10.9. After trying it, I restarted the computer and tried again. Once again nothing at all happens. I re-downloaded the program again with the same results. I have our Macs set to allow all apps to run in the Security preference pane. Any guidance would be appreciated.

    • After being able to spend more time on this, I discovered that I just had to wait a very long time before it did anything. Somewhere between 2 and 5 minutes. We’re also getting negative days reported for the password expiration when it does finally respond. I tried setting it to Manual mode, but it spins for anywhere from 2 to 5 minutes until it reverts to Auto mode and still reports negative days. Is there anything on the Active Directory servers I can have our Windows Server guys look at to improve this behavior? MS Outlook 2011 also reports that the password has expired in the past, but no one can seem to put their finger on what’s causing the wrong information.

      • Can you share with me the contents of Console.app (filtered for ‘ADPassMon’ entries) from the time you first launch ADPassMon to the time to you get some response? It should help identity where the slowdown is occurring.

  68. Just heard about this tool and very excited to get it to work for us! I do have one question maybe someone has experienced and answered.

    We use fine grain passwords and I’ve noticed when I try to grab the maxPwdAge entry I get a consistent result across all accounts of 9.22337e+11 resulting in the tool saying there are 10675070 days to go.

    Now I was able to fix this issue before in a PowerShell script but I’m unsure of how to make that translate to Apple Script. Below is an example of how I can get MaxPasswordAge out of the fine grain password policy per user:
    $maxPasswordAge = (Get-ADUserResultantPasswordPolicy $user).MaxPasswordAge

    Is anyone else running fine grain policies and possibly have a solution?

    • Wes, as you’ve seen, ADPassMon doesn’t know how to deal with fine grained password policies. I might be able to help you with this, but it depends upon whether the proper attribute is available to the Mac via the Active Directory plug-in. From the terminal app on a Mac, try running this command: dscl /Search read /Users/$USER | grep -v ‘^\W’

      See if you can find any item that might hold the expiration value. The line may start with ‘dsAttrTypeNative’

      • Thanks for the reply! After looking through I realized I was going about this all the wrong way and all I needed was the group that is assigned to the user that assigns the password policy.

        I replaced:
        set my expireAgeUnix to (do shell script “/usr/bin/ldapsearch -LLL -Q -s base -H ldap://” & myLDAP & ” -b ” & mySearchBase & ” maxPwdAge | /usr/bin/awk -F- ‘/maxPwdAge/{print $2/10000000}'”) as integer

        With:
        set my expireAge to do shell script “if groups $USER | grep &>/dev/null ‘\\b6MonthExpiration\\b’;then echo 180;else echo 90;fi”

        and now it works great!

  69. I have download the latest version of ADPassMon, but unfortunately it shows a wrong number of day. [-16302d]. Here is my logs from Console.
    19/11/2014 2:20:52.252 pm ADPassMon[442]: *** -[ADPassMonAppDelegate applicationWillFinishLaunching:]: Can’t get character 1 of “”. (error -1728)
    19/11/2014 2:23:43.808 pm ADPassMon[442]: Testing for Kerberos ticket presence…
    19/11/2014 2:23:51.067 pm ADPassMon[442]: Ticket found and renewed
    19/11/2014 2:23:51.070 pm ADPassMon[442]: Starting auto process…
    19/11/2014 2:23:51.071 pm ADPassMon[442]: Found expireAge in plist: 91
    19/11/2014 2:23:51.149 pm ADPassMon[442]: New pwdSetDate (-134774) is
    19/11/2014 2:23:51.150 pm ADPassMon[442]: < plist value (0.0) so we ignore it
    19/11/2014 2:23:51.158 pm ADPassMon[442]: daysUntilExp: -1.630227E+4
    19/11/2014 2:23:51.159 pm ADPassMon[442]: daysUntilExpNice: -16302
    19/11/2014 2:23:51.160 pm ADPassMon[442]: expirationDate: Thursday, 2 April 1970 7:55:03 am
    19/11/2014 2:26:02.069 pm Console[594]: setPresentationOptions called with NSApplicationPresentationFullScreen when there is no visible fullscreen window; this call will be ignored.
    19/11/2014 2:26:38.807 pm helpd[289]: CFPropertyListCreateFromXMLData(): Old-style plist parser: missing semicolon in dictionary on line 1. Parsing will be abandoned. Break on _CFPropertyListMissingSemicolon to debug.
    19/11/2014 2:26:38.808 pm helpd[289]: CFPropertyListCreateFromXMLData(): Old-style plist parser: missing semicolon in dictionary on line 1. Parsing will be abandoned. Break on _CFPropertyListMissingSemicolon to debug.
    19/11/2014 2:39:43.775 pm com.apple.preference.network.remoteservice[656]: Could not find image named 'InvalidDataIcon'.
    19/11/2014 2:39:43.841 pm com.apple.preference.network.remoteservice[656]: *** WARNING: -[NSImage compositeToPoint:operation:fraction:] is deprecated in MacOSX 10.8 and later. Please use -[NSImage drawAtPoint:fromRect:operation:fraction:] instead.
    19/11/2014 2:39:43.841 pm com.apple.preference.network.remoteservice[656]: *** WARNING: -[NSImage compositeToPoint:fromRect:operation:fraction:] is deprecated in MacOSX 10.8 and later. Please use -[NSImage drawAtPoint:fromRect:operation:fraction:] instead.
    19/11/2014 2:49:37.576 pm com.apple.WebKit.Plugin.64[671]: CoreText performance note: Client called CTFontCreateWithName() using name "Arial Unicode MS" and got font with PostScript name "ArialUnicodeMS". For best performance, only use PostScript names when calling this API.
    19/11/2014 2:49:37.576 pm com.apple.WebKit.Plugin.64[671]: CoreText performance note: Set a breakpoint on CTFontLogSuboptimalRequest to debug.
    19/11/2014 2:49:38.307 pm com.apple.WebKit.Plugin.64[671]: CoreText performance note: Client called CTFontCreateWithName() using name "Times Roman" and got font with PostScript name "Times-Roman". For best performance, only use PostScript names when calling this API.
    19/11/2014 2:51:00.156 pm com.apple.WebKit.WebContent[681]: NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9843)
    19/11/2014 2:51:12.966 pm Safari[354]: *** -[IADomainCache init]: IA domains cache couldn't be read.
    19/11/2014 2:55:31.207 pm ADPassMon[726]: Running on OS 10.9.x
    19/11/2014 2:55:31.207 pm ADPassMon[726]: Testing Universal Access settings…
    19/11/2014 2:55:31.347 pm ADPassMon[726]: *** -[ADPassMonAppDelegate applicationWillFinishLaunching:]: Can’t get character 1 of "". (error -1728)
    19/11/2014 2:55:41.330 pm ADPassMon[733]: Running on OS 10.9.x
    19/11/2014 2:55:41.331 pm ADPassMon[733]: Testing Universal Access settings…
    19/11/2014 2:55:41.530 pm ADPassMon[733]: *** -[ADPassMonAppDelegate applicationWillFinishLaunching:]: Can’t get character 1 of "". (error -1728)
    19/11/2014 2:55:55.234 pm ADPassMon[733]: Starting auto process…
    19/11/2014 2:55:55.235 pm ADPassMon[733]: Found expireAge in plist: 91
    19/11/2014 2:55:55.280 pm ADPassMon[733]: New pwdSetDate (-134774) is
    19/11/2014 2:55:55.281 pm ADPassMon[733]: < plist value (0.0) so we ignore it
    19/11/2014 2:55:55.287 pm ADPassMon[733]: daysUntilExp: -1.630229E+4
    19/11/2014 2:55:55.287 pm ADPassMon[733]: daysUntilExpNice: -16302
    19/11/2014 2:55:55.288 pm ADPassMon[733]: expirationDate: Thursday, 2 April 1970 7:58:19 am

  70. myLDAP: ...
    mySearchBase: connect to my DC properly here.
    uAC:
    passExpires: yes
    expireAgeUnix: 7862400
    expireAge: 91.00000000000000000000
    pwdSetDateRaw:
    pwdSetDateUnix:
    pwdSetDate:
    todayUnix: 1416451226
    today: 16394.11141203703703703703
    daysUntilExp:
    $ echo “daysUntilExpNice: $daysUntilExpNice” <- hangs here.

    • Looks like it’s actually failing higher up, at pwdSetDateRaw. Try running just this command and let me know the output:

      dscl localhost read /Search/Users/$USER pwdLastSet | awk ‘/LastSet:/{print $2}’

  71. the outcomes of that scripts are:
    No such key: pwdLastSet
    No such key: pwdLastSet

    Btw, we are in Australia. Our dates are in DD/MM/YYYY format.

    • The date format doesn’t matter here since the system keeps track of time with seconds. I think your password set date is being stored elswwhere. Try this command:

      dscl localhost read /Search/Users/$USER SMBPasswordLastSet | awk ‘/LastSet:/{print $2}’

      If that comes back empty, then try this one:

      dscl localhost read /Search/Users/$USER | awk ‘/LastSet:/{print $2}’

      If that is also blank, then try this one and search for a line that might hold the password set date value:

      dscl localhost read /Search/Users/$USER

      • Hi Peter,

        I have run dscl localhost read /Search/Users/$USER and found out that there’s no Variable related to SMBPasswordLastSet.
        Just give you a little bit background, I work at K-12 school and we have 25 imacs for media student. We use magic triangle setup for our mac lab. After a long test and trials, we have decided to delete all keychains on user’s logout. We have made a short custom script to do this, :

        rm -rf /Users//Library/Keychains/

        and then change mode to be able to run it, and add it to logout hook. it works fine now. Thank you for your help, Peter.

  72. I have just installed ADPassMon and feel it may address a nagging issue with Kerberos ticket renewal in our environment. I was wondering if you could add an option for ADPassMon to automatically refresh the Kerberos Ticket on network state change “if” it can detect the domain controller. This would eliminate the need for end user training on ticket refresh.

    FYI, I am thinking the network state “changes” upon a Cisco AnyConnect connection. The VPN is used for users working at home, which is where most users are running into expired Kerberos Tickets due to elongated times of no domain connectivity.

    If you could make this tweak, we would be willing to pay for the utility if need be.

  73. Hi Peter, I was also getting the negative number issue and all the suggestions above were returning nothing, however when I ran dscl localhost read /Search/Users/$USER and searched on pass I found the following along side the rest of my AD details:

    PasswordPolicyOptions:

    failedLoginCount
    0
    failedLoginTimestamp
    2001-01-01T00:00:00Z
    lastLoginTimestamp
    2014-10-17T10:57:42Z
    passwordLastSetTime
    2014-10-17T10:57:42Z
    trackLastLogin
    1
    

    I’m not entirely sure how this data gets populated but It looks like the passwordLastSetTime is the data you need, is this something ADPassmon might support?

    • Those details are wrapped in xml plist tags, correct? That information doesn’t come from Active Directory but from the account that’s local to the computer. If you do dscl /Search read /Users/$USER | grep 'LastSet:' it should get you the Active Directory account expiration details if an AD domain is in your Directory Services search path.

      • Correct, that info was wrapped in the xml plist tags. No such luck though looking for LastSet: and I swear to you, i’m attached to AD! :-) I see the rest of my AD details when I look at the output from dscl /Search read /Users/$USER

  74. This was working until I updated my password. Now I’m getting the -1 day. Running OS X 10.9.5, here’s my output of the troubleshooting script.

    ldap_sasl_interactive_bind_s: Can’t contact LDAP server (-1)
    No such key: userAccountControl
    ldap_sasl_interactive_bind_s: Can’t contact LDAP server (-1)
    (standard_in) 1: parse error
    myLDAP: x.x.x.x
    mySearchBase:
    uAC:
    passExpires: yes
    expireAgeUnix:
    expireAge:
    pwdSetDateRaw: 130559535714356662
    pwdSetDateUnix: 1411479971.43566620000000000000
    pwdSetDate: 16336.57374346835879629629
    todayUnix: 1419358935
    today: 16427.76545138888888888888
    daysUntilExp: -91.19170792053009259259
    daysUntilExpNice: -91

    • Is your primary DNS server (seen in the output of scutil --dns | awk '/nameserver\[0\]/{print $3}' | head -1) also an Active Directory server? If it is not, then you will not get to correct output. In that case, you can switch to manual mode, type in ’90’ and hit Tab or Enter to set the maximum password age manually.

    • Added my ldap address manually, here is the updated output:

      No such key: userAccountControl
      myLDAP:
      mySearchBase: DC=blah,DC=blah
      uAC:
      passExpires: yes
      expireAgeUnix: 7776000
      expireAge: 90.00000000000000000000
      pwdSetDateRaw: 130559535714356662
      pwdSetDateUnix: 1411479971.43566620000000000000
      pwdSetDate: 16336.57374346835879629629
      todayUnix: 1419359858
      today: 16427.77613425925925925925
      daysUntilExp: -1.20239079090046296296
      daysUntilExpNice: -1

      • How recently have you changed your password? The pwdSetDateUnix line returned by the script corresponds to Tuesday, September 23, 2014. It looks like your domain account’s data is either being cached or has not been updated to reflect your most recent password change. Are you sure you changed the domain account password and not just your local account password?

        • I changed the password via System Preferences over VPN. Local and directory account passwords updated. I guess my local dscl attributes did not. Just updated again via the login screen and all is well. Thank you for your time and app!!!

        • I’m seeing that I know have 2 SMBPasswordLastSet in my DSCL attributes. Have you seen this before?

  75. I’m trying to deploy ADPassMon with .plist and a LaunchAgent using Casper. I created the plist and launchagent files with TextWrangler and saved them as plain old text format. I packaged them up using Casper Composer in a .dmg file. When I deploy the .dmg none of the settings of the plist and launch agent work. When I double click on the files in the Finder, I can read them just fine and everything is exactly as I set them. HOWEVER, if I use the more command in Terminal to view the files, I get a message telling me the files are binary and asks me if I want to view them anyway. I tell it Yes I do want to view and it comes up as binary gibberish. If I take the text files I created and manually copy them to the locations they need to be in, it works just fine. So obviously something is happening to the plist and launchagent files that is changing it from text to binary and ADPassMon can’t read them. Does anyone have any tips for resolving this?

    • The system will sometimes convert plists to binary format. Try using the defaults command to read the plist to verify that it contains what you expect. I’m not sure why the installer isn’t working for you, though. Do you have a postinstall script that loads the LaunchAgent using the launchctl load command?

      • I’m not doing a postinstall script to load the launchagent. I’m fine with just putting the files in place and then waiting for the users to reboot at their leisure. My suspicion is that something in Casper may be converting them to binary. I’ll post my query on the jamfnation site. I’ve read that some programs with fine with binary files and others prefer plain text. Unfortunately I don’t know enough about programming to know why there is a difference in the first place.

    • Actually yes. It’s been bugging me that ADPassMon is “dumb” about network state. I can’t tell you when it will happen, but it’s what I plan to work on next.

  76. Hi Peter,

    I am trying to get this going at my place of work but I do not see the SMBPasswordLastSet key for my user account. Looking at AD on the windows side from powershell, I see both PasswordLastSet and pwdLastSet.
    I looked through the code and saw where you were previously using pwdLastSet.
    Any idea why I would be missing SMBPasswordLastSet on 10.9?

    Thanks.

  77. Hello Peter
    I have an issue with some users, they are unable to change there password, the mac gives a messages saying they do not have permission or rights to change there password even though they are admins to their machines, happens on all versions of OS Mountain Lion, do not use adpassmon on Yosemite yet. So its very random I can have user side by side with same set up but one can and one can’t change password, any help be much appreciated Thanks Nick

  78. Hi. Can I please ask a very simple question. With regards to the pwPolicy message, how did you change it to say “I Understand”. I am very much a noob, so please forgive the simplicity of my question….Thanks..Roly.

    • Sorry for the misleading image. The current version uses “OK” for the button text and is not configurable. If you’d like, I can make the button text configurable with a defaults command — something like defaults write org.pmbuko.ADPassMon pwPolicyButton "I understand"

  79. Hi,
    Firstly, thank you for your speedy reply.
    I think it would be useful to have a configurable button. However, please only do this at your convenience. There is no rush. Thank you…Roly.

  80. i have a user with no pass expires, and menubar is showing [-385], when i tried to refresh kerberos ticket not work.
    you have a fix? thanks!!

  81. Hi, I’m on a Mac running 10.10.3 (managed mobile user) in a pretty basic AD environment. The default install shows -354 days til expiration. If I manually change the setting in ADPassMon to 180 days, that changes to -719 days. Does your application look to the individual AD account expiration date, the AD password policy of the domain, or both? thanks.

    • Hi Matt,

      ADPassMon queries AD with the following command to get the maximum password age for accounts: ldapsearch -LLL -Q -s base -H ldap://w.x.y.z -b dc=example,dc=com maxPwdAge. To calculate the remaining days for an individual user, it looks up the date that the user last changed their password with this command: dscl localhost read /Search/Users/$USER SMBPasswordLastSet

      Then it does some date math using these two pieces of info to get the number of days remaining until the password expires.

  82. Gotcha…perhaps my account (as a domain admin) isn’t the best to test with. If we are slowly rolling out a 180 day expiration to our standard AD users (as new accounts get created) it sounds like it makes sense to also deploy ADPassMon at that time – with the setting changed to 180 days.

    • Certainly, if it’s not auto-detecting the 180 day value, then pushing out a plist file with the manual value set is your best option.

  83. My office AD environment is fairly complex, and our users do password resets through a tool that then syncs with various services – including AD. As a result, we’ve had to disable password changing in Mac OS X – as changing the password there does hit the other services in place, leaving the user with multiple passwords – and users have to change their password via a website. Using your tool, we’ve been able to add a button to the dialog box that directs the user to the password change page we use, but the ‘OK’ button is still present, and regardless of whether the OK button or URL button is pressed, the Users & Groups preference pane opens, which is an unnecessary operation in our environment. So my question is two-fold. Is there a way to remove the ‘OK’ button and leave only the URL button, and is there a way to make it so System Preferences doesn’t open at the button push event? In its current state, the tool does work, and we enjoy using it, but we haven’t been able to put it into production because of what I’ve stated above. Any insight would certainly be welcome. Thank you for your time.

  84. Hi! And THANK YOU for this GREAT utility! One question… We’re noticing that our users who have a space between their AD account names get this crazy -151260 expiration date. Those who don’t are working as expected. Anyway to fix this?

  85. Hello,

    We recently updated our Windows Group Policy for password expiration time from 256 days to 320 days. Since we changed this I am still seeing AdPassMon keep the 256 and not the new. If I remove AdPassMon and re-install it then it shows 320. Is there anything I can do to get around a uninstall and reinstall?

    Thanks in advance.

    • Blake, the expiration data gets saved to ADPassMon’s plist file. Clicking the “Revert to Defaults” button in the Reset tab of the preferences window should clear out the value and force it to look it up again. If that doesn’t work, you can delete the ~/Library/Preferences/org.pmbuko.ADPassMon.plist file.

  86. @pmbuko

    Thanks for the info. I have tried to delete plist file before but it doesn’t change the value – it keeps it at the 256 timeline not the 320. I reset my password in ADmon and it changed it to 256(old gpo timeline). I uninstalled and reinstalled and it changed it to 320(which is the new correct gpo). I also tried to replace the plist with a fresh one that had never been opend with no values in it and it re-wrote to 256 some how.

    I could just do a uninstall and reinstall but this is currently used by a few hundred users and that is not the best solution or easiest solution.

    Thanks,
    Blake

    • Try running “sudo killall cfprefsd” on the computer after deleting the preferences file. Let me know if that makes a difference. I’ll also check to see what I can do in my code so that it can correctly detect password policy changes.

    • Could you push out the plist file of the Mac that has the right amount of days to others with ARD? Test with a couple machines first. If it works, deploy away.

  87. Love the tool. But have just run into a slight issue since upgrading from 10.9 to Yosemite. MCX settings used to lockdown Preferences within the app but its stopped working. Using version 1.10.0 ADPassMon. Any ideas?
    Tried refreshing mcx but no luck…

    • Have you tried quitting and restarting ADPassMon after making the change? Prefs are read then the app loads so it won’t take effect right away. I just tried defaults write org.pmbuko.ADPassMon prefsLocked true on my Mac (10.10.3) with ADPassMon 1.10.2 and it worked after I quit and restarted ADPassMon.

    • Since MCX is deprecated in Yosemite, particularly user-level MCX, I’m not sure it’s something I can fix from the ADPassMon side.

  88. I think I will have to script it or convince client to use config profiles. Having said that copying pmbuko plist from “/Library/Managed Preferences/legacy 10.9” user to “/Library/Managed Preferences/new 10.10 user” creates the desired result. I didn’t realise user-level MCX was deprecated in 10.10…

  89. Even running the latest version 1.10.3 and 1.10.3 I’m still getting -151323 day expiration date

    • A negative value means that ADPassMon wasn’t able to automatically determine the maximum password age by querying a domain controller. The command it uses to query AD is ldapsearch -LLL -Q -s base -H ldap://dc.example.com -b dc=example,dc=com maxPwdAge. If you run this on your computer (substituting in the correct values after -H and -b), what is the result? In any case, I suggest using Manual method in ADPassMon preferences and entering in the maximum password age there. Remember to press Enter after typing in the value.

      • Interesting, my macPwdAge returns a -51840000000000
        Even when I use manual mode it still shows a value of -151324

          • Hmmm. Your AD must be storing both the maxPwdAge and pwdLastSet values in a different format than what I’ve seen. There are three more significant digits than I’d expect. Let me see what I can learn about other ways AD can store time stamps.

  90. Hi Peter
    I’m very excited to get this working in our environment, thank you for all the hard work!!

    Before we deploy the application I’d like to create an extension attribute in our JSS so i can confirm that all the expiry dates are correct for each Mac.
    At the moment i’m using the script below as an attribute but i’m getting a lot of -negative values show up for the expiry date, i’ve checked SMBPasswordLastSet in AD for a few of the Macs that are reporting this negative value, i put the SMBPasswordLastSet timestamp into a converter and it does show the last password set date as being back in 2014 so i’m guessing that’s an issue with these AD records.

    Does ADPassMon use the value from SMBPasswordLastSet to calculate the days left till expiry or something else?
    If it does use something else, is it something i could use to make an extension attribute for our JSS ?

    here’s the attribute i’m tetsing at the moment.

    Thank you,
    Andy

    #!/bin/bash
    pwPolicy=60
    user=/usr/bin/who | /usr/bin/awk '/console/{ print $1 }'
    lastpwdMS=dscl localhost read /Local/Default/Users/$user | grep SMBPasswordLastSet | cut -d' ' -f 2
    todayUnix=date "+%s"
    lastpwdUnix=expr $lastpwdMS / 10000000 - 11644473600
    diffUnix=expr $todayUnix - $lastpwdUnix
    diffdays=expr $diffUnix / 86400
    daysremaining=expr $pwPolicy - $diffdays
    daysString=”in $daysremaining days”
    echo “$daysremaining”

    • Andy,
      You’re welcome! I posted a bash script here that contains shells commands similar to what ADPassMon uses internally. To specifically answer your question, look at line 18. I am using dscl to look up the SMBPasswordLastSet value stored in AD.

      If your network advertises multiple AD servers (run the command found on line 5 without the head -1 part), they can sometimes come up in different orders. If one or more of those AD servers doesn’t have a defaultNamingContext value set, then part of the lookup will fail and you’ll end up seeing negative password values. I suggest downloading my script and running it a few times in a row to see if you get inconsistent results.

  91. Brilliant ! thanks for the details, i’ll test them out shortly.

    Another quick question if you have the time,
    is there any way to disable the message “No Kerberos ticket for Active Directory was found. Do you want to renew it?” or is there a way i could reword the “Password is incorrect – Please try again” message if the Mac can’t reach our network ?
    We have a lot of external users who very rarely access the VPN and i think when they’re prompted to renew the kerberos ticket they’ll get confused when it tells them their password is incorrect.

    Thank you,
    Andy

    • When ADPassMon can’t reach Active Directory — when it runs dscl localhost read /Search/Users/$USER SMBPasswordLastSet and receives no result — then it should not prompt to renew the kerberos ticket. Is that happening?

  92. Yes, it is prompting to renew the key when the Mac is not connected to the VPN and can’t reach Active Directory.
    The result from /Search/Users/$USER SMBPasswordLastSet is No Such Key,
    (then i thought!) i am logged in as a local non AD user, would that cause this behaviour?
    When i’m back in the office i’ll login as an AD user and test it again and confirm it.
    Thanks again!

    • That might have something to do with it. If ADPassMon has never successfully contacted AD about a particular user (like your local one), then my code probably doesn’t catch that and should be fixed. :)

  93. sorry for adding to your list!
    i’ll let you know the outcome once i’ve tested it under an AD login
    Cheers

  94. Hi
    I’ve just tested it within an Active Directory users login and it does not prompt to refresh the ticket if it can’t reach AD.
    Though If manually ask it to Refresh Kerberos Ticket it does still display the password prompt, if i enter the AD password and is says it’s incorrect (if it can’t reach AD).
    We can advise users not to manually refresh the ticket when out of the office.

    Cheers,
    Andy

    • If AD can’t be reached when ADPassMon starts up or when the computer comes out of sleep, the Refresh Kerberos Ticket menu item should be disabled. Also, are you trying this with the latest version, 1.10.3?

  95. Yes it’s ADPAssMon version 1.10.3 on Yosemite 10.10.3, it’s not able to reach AD and all of the menu items are available.

    I’m not managing the preferences, the only thing i’ve added is a ~/LaunchAgent to keep it open.

    Prefs are

    enableNotifications

    expireAge
    60
    menu_title
    [28d]
    pwdSetDate
    16587.76
    tooltip
    Password expires on Friday, July 31, 2015 at 1:14:24 PM

    Does it write to a log file anywhere ?

  96. Thanks,
    Just tested V1.10.3 on a 10.9.2 Mac within an AD Managed Mobile account and all the menu items are still available when AD can’t be reached. Tried quitting and re-opening it and also resetting it but still the same.
    Console doesn’t show much when choosing to Refersh Kerberos Ticket:
    7/2/15 4:10:37.050 PM ADPassMon[2415] Testing for Kerberos ticket presence…
    7/2/15 4:10:37.073 PM ADPassMon[2415] No ticket found
    7/2/15 4:11:07.526 PM ADPassMon[2415] Incorrect password. Skipping.

    Cheers, Andy

  97. Running 10.10.4 with ADPassMon 1.10.3
    On the network local to Domain Controllers the ADPassMon drop down greys out both “Refresh Kerberos Ticket” and “Change Password…”. However refreshing ticket through ticket viewer works fine so we know the client can’t find a domain controller. Nothing out of the ordinary in console logs.

    Thoughts?

    • Can you paste what the log does show? The pwdLastSet value gets stored in the plist so ADPassMon can still show expiration info away from the network, but when it’s on the network it compares the stored value against AD. The result of that comparison should be logged.

  98. I’ve noticed that the change password option will be greyed out unless your password is lower than the notification days.

    • That’s certainly not working as intended. I’ll rework the code that controls the availability of the change password item. Again, it may take a few days since I don’t plan on working this weekend. :)

  99. Is there a way to have the app do a sanity check before asking if the user needs to enable Assistive Devices? I set this using a sqlite command and would rather not have a user presented with a dialog box. This worked up until the current version.

    • So one of the bugs I fixed was the code that sets up the accessibility portion. Turns out it was broken for quite some time. In fixing it, I exposed this bug that you discovered. (So goes software, I guess).

      I’ve now added an “accTest” preference that you can set (globally or per-user) to disable the accessibility test, e.g.

      defaults write org.pmbuko.ADPassMon accTest 0

      Download the new build here and please test it out. It it works for you, I’ll release it officially.

  100. I absolutely love ADPassMon, but i think i’ve found an issue with the latest version. I packaged ADPassMon for deployment with the previous version a while back and it was working great. I manually set the password expiration days to 180 since that is our policy. When i swapped out the ADPassMon app in the package payload everything seems to work, but it is adding a 0 to the days until password expires. For example my password expires in 91 days with the previous app, but with the new version it shows 910 days. It could be my configuration or something, but i figured i would let you know. Thanks again for such a great tool!

    • Hi Andy, have you tried using the reset button in the preferences, then quitting, restarting ADPassMon and reconfiguring it? Also, to help me troubleshoot, please open Console.app, add a search filter for ‘adpassmon’, and copy and paste what you see appear when you click ‘Test Settings’ in ADPassMon’s prefs window.

  101. Thanks for the quick reply. Below is the log you requested.

    7/21/15 10:32:35.630 AM ADPassMon[2151]: Running on OS 10.10.x
    7/21/15 10:32:35.632 AM ADPassMon[2151]: Testing Universal Access settings…
    7/21/15 10:32:35.633 AM ADPassMon[2151]: Enabled
    7/21/15 10:32:35.642 AM ADPassMon[2151]: Loading prefs…
    7/21/15 10:32:35.779 AM ADPassMon[2151]: Testing if password can expire…
    7/21/15 10:32:35.826 AM ADPassMon[2151]: Password does expire.
    7/21/15 10:32:35.860 AM ADPassMon[2151]: Starting auto process…
    7/21/15 10:32:35.861 AM ADPassMon[2151]: Found expireDateUnix in plist: 1.516129745E+9
    7/21/15 10:32:35.913 AM ADPassMon[2151]: Got expireDateUnix: 1516129745
    7/21/15 10:32:35.914 AM ADPassMon[2151]: Using msDS method
    7/21/15 10:32:35.926 AM ADPassMon[2151]: daysUntilExp: 910.150347222222
    7/21/15 10:32:35.926 AM ADPassMon[2151]: daysUntilExpNice: 910

    • Can you tell me what version of Windows your AD servers are running? The “expireDateUnix” value is calculated from a value given by the AD server. The number 1516129745 corresponds to a date of Jan 16, 2018. Here’s a script that shows what ADPassMon is doing.

  102. With the latest version, 1.11.1, I and my users are seeing the ADPassMon Preferences window show up after every login. We can dismiss it, but the next time we log in to the computer, there it is again. Any way we can stop this from showing up at login? Thanks, love the app.

  103. Hi, is there a way to set the format that the day appears in in the menubar? Right now I’m seeing “[78d]”, but I don’t need the brackets to be there (it would look a little cleaner without them). Is there a way for me to take them out?

    • Not currently, but I can remove the brackets in the next release. If people miss them, I’ll add an option to the prefs that allows you to enable/disable them.

      • You make a great FREE product with amazing support and this is what people are concerned about?

        • It was just a question, I wasn’t being critical. It’s something I see on my screen all day so it’s not that out of the ordinary to wonder if I can change its appearance.

          Thanks for offering to update it so quickly, @pmbuko.

  104. I am not sure if I am missing a setting, but the notifications appear to not be working on any of the test systems we have it on. I could be completely wrong about how to set it. Current settings are;
    1. I am on 10.10.4 on one system and 10.8.6 on another.
    2. KerbMind is not installed. (Don’t know if I need this or not. From what I read, I don’t think so.)
    3. My password will expire in 75 days. (I know this is accurate as I’m able to verify in Active Directory and also what ADPassMon is showing me.
    4. AD user doesn’t have a Mobile Account. (Could this matter?)
    5. User shows in Users & Groups and ADPassMon is set to run as a login item
    6. ADPassMon is checked in Security & Privacy/Accessibility
    7. ADPassMon is in the Notifications Center with all options checked and ‘alert style’ set to Banners.
    8. ADPassMon preferences does have the “Use Notifications” box checked.

    If I set this for 74 days, then tomorrow I should get a notification about my password getting ready to expire correct?
    This is the problem I run into, as it doesn’t do that. Everything seems to work except for the notifications part.
    Please let me know if my configuration is somehow lacking.

    Thank you for this product! You have done an amazing job and this is SO needed.

    • Kris, thanks for letting me know about your notification issues. I’ll run some tests on various OSes and see if I can replicate it and fix it.

    • Kris, I verified in 10.10.4 that notifications were not appearing when they should. I added a small tweak to my code and also added a logging entry. Please download the pre-release of the the next version here. To test, please set your warning threshold higher than the number of remaining days and then choose “Re-check Expiration” from the menu. Also have Console.app open with a search filter of “ADPassMon” so you can see what it’s doing. You should see a “Triggering Notification…” line appear.

      If you see the “Triggering Notification…” line but do not see a banner, then click the Notification Center icon in the menu bar and see if the notification is there. This happened to me a few times. I didn’t see a banner appear but the notification did make it into Notification Center. That may be an Apple bug.

      • With as quickly as you are responding, I certainly don’t mind being your beta tester. :)
        Let me make sure I did this correct as well.
        1. Exited ADPassMon
        2. Trashed app
        3. Trashed Preference file ~/Preferences/org.pmbuko.ADPassMon.plist
        4. Copied the new ADPassMon.app to /Applications
        5. Opened Console
        6. Ran ADPassMon.
        7. Gave me crap about the wrong AD password.
        8. Trashed all the tickets in ticket viewer.
        9. Trashed Preferences again.
        10. Ran it.
        11. Set threshold to 79 days (password will expire in 75 days).
        12. Clicked “Test Settings”
        13. Checked Console and got the following.
        7/31/15 9:15:30.471 AM ADPassMon[72609]: Triggering notification…
        7/31/15 9:16:51.622 AM com.apple.preference.notifications.remoteservice[72674]: Failed to connect (_okButton) outlet from (NCPrefAppDetailController) to (NSButton): missing setter or instance variable
        14. Started typing this.
        15. Per your instructions, clicked on “Re-Check Expiration”
        16. Notification popped right up with the following information
        7/31/15 9:29:31.394 AM ADPassMon[72609]: Starting auto process…
        7/31/15 9:29:31.394 AM ADPassMon[72609]: Found expireDateUnix in plist: 1444844990
        7/31/15 9:29:31.684 AM ADPassMon[72609]: Got expireDateUnix: 1444844990
        7/31/15 9:29:31.685 AM ADPassMon[72609]: Using msDS method
        7/31/15 9:29:31.724 AM ADPassMon[72609]: daysUntilExp: 75.055775462963
        7/31/15 9:29:31.724 AM ADPassMon[72609]: daysUntilExpNice: 75
        7/31/15 9:29:31.725 AM ADPassMon[72609]: Triggering notification…
        17. Tried the ADPassMon pref “Test Settings” button again, appears to just sit at “Triggering notification…”

        Did notice that when I click “Test Settings” it shows up right away in the Notification Panel, I just don’t get the pop up.

        Let me know how else I might be able to help test this.

        ~Kris

        • Kris, I’ll try to see if I can figure out why the banners don’t appear all the time, but if you’re seeing the notification appear in the Notification Center, with or without the popup, then my code is behaving properly.

  105. It appears to be working as advertised now. Thank you for getting to this so quickly. We are moving to a Citrix Identity solution to merge our AD and LDAP (yeah I know AD IS LDAP) passwords. I do not know if they offer a way to show on Mac when AD passwords will expire. If not, ADPassMon will be what I turn to.

    Thank you again!

    • You’re welcome, and good luck with your merge. I was recently tasked with merge independent LDAP directories from two sites into one, but both were OpenLDAP. We still have a separate AD, though.

  106. Hi Peter.

    Looks to be working beautifully. One tweak if I might suggest? When a password is past the notification threshold and the notification appears, could the “Show” button on the notification take you to the change password box the same way “Change Password” does from the menu icon (I am using the “Alert” notification setting)? This way the users won’t need an extra step to change their password. Maybe even change the “Show” to “Change”?

    Thanks again for all your hard work!

    • It’s an excellent suggestion and one I had explored previously, but I wasn’t able to get it working, then. I’ll add it to my to do list and have another crack at it.

  107. Thanks Peter.

    I only ask because the “Show” button at this point functions like the “Close” button.

    This just feels like the final piece to make this truly functional (aside from maybe making it run as a LaunchAgents prog) and push able via DeployStudio or ARD.

    Let me know if I can help.

  108. Peter,

    Have you ever seen this behavior in ADPassMon?

    1) User is on the network with the AD and is successful in communicating with it.
    2) The next time the user powers up the system, they are now remote to the network with the AD. The number of days until password expiration remains as it was when the system was last on the internal network. For this example, lets say this is over the weekend.
    3) User comes back in to the office where the AD network is and successfully authenticates with AD. However the number of days until password expiration still has not changed since the last time they were on the network. In my example its been at least 2 days due to the weekend so the time to expiration “should” have decreased by 2.

    This number will not change unless the user selects “Re-check Expiration” from the ADPassMon dropdown.
    I’ve left the system on for consecutive days and it seems as if its not checking. However if I turn off a system that had last been on the AD network and leave it off for multiple days and then log back into it again while connected to the AD network it WILL show the correct password expiration.

    This might be something easy but I have not been able to discover what the issue is. We are looking at the latest version of ADPassMon (1.11.4) and MacOS of 10.10.5.

    We are really hoping to use this app in our environment to help with our AD deployment but want to clear this one up as I have a lot of users who travel frequently and are off the network for periods of time.

    Thanks,

    –Darren

      • Wanted to followup and say that the behavior that I was seeing before has been fixed.

        I have not seen any other issues but there is a report of one. If it is I’ll report it in the other thread.

        Thanks again for this!

        –Darren

Comments are closed.