NTLMSSP was returning the error “STATUS_MORE_PROCESSING_REQUIRED”

NTLMSSP is the security provider for NTLM, in case you were wondering.  I learnt about it as I was trying to write a log file to a DFS share in a different domain, and I was getting a “Path not found” error.

The client computer could see the network folder it was trying to write to, so I started up PROCMON and watched the traffic.  This was the error which occurred:
BAD NETWORK NAME

BAD NETWORK NAME

Wasn’t anything bad about that network name, so I connected up a network sniffer.  It told me that NTLMSSP was returning STATUS_MORE_PROCESSING_REQUIRED message.
STATUS_MORE_PROCESSING_REQUIRED

My friend Google, wasn’t of any help to me, so here is what I think was going wrong.

 

Background.
The LogPath was pointing to a DFS share in the CENT domain.
The TOLERDO and CONTOSO have cross-domain trusts, so their users can write to the CENT DFS share.

 

The problem.
The DFS request meant that the TOLERDO user, accessing the CENT domain, needed their credentials validated against the TOLERDO domain.

This credential validation is exceeding some sort of SMB timeout, and throws a "STATUS_MORE_PROCESSING_REQUIRED" message.

The credential validation path would look like this:
TOLERDO client –> CENT Server –> TOLERDO Domain Server –> CENT Server –> TOLERDO Client.  (a path too long I suspect).

The "STATUS_MORE_PROCESSING_REQUIRED" message then leads to a "STATUS_BAD_NETWORK_NAME" error being passed back to VBscript.
Which VBscript is interpreting as a "Path Not Found" error.

 

The solution?
In the TOLERDO domain, create a DFS Link to the CENT folder.
This causes the TOLERDO client to validate against the TOLERDO domain, and allows the log file to be written.

(the NTLMSSP message/error was one of the reasons I modified the SMS Client Health Startup script to allow for multiple domains).

For performance reasons, Windows was lying to me.

The creation date for a file I was creating, was 8 days out.  This was what I was trying to do:

IF logfile older than 7 days THEN
   1. delete the current log file
   2. create a new log file (with the same name)

When VBscript was creating the new log file, it was getting the creation date of the old file.  "So what?", you might be thinking.

As the log file was keeping the old file creation date, it was always executing the "IF logfile older than 7 days THEN" statement.

A bit of a Google search later, yielded this Microsoft article:

"When a name is removed from a directory (rename or delete), its short/long name pair and creation time are saved in a cache, keyed by the name that was removed. When a name is added to a directory (rename or create), the cache is searched to see if there is information to restore."
http://support.microsoft.com/?kbid=172190

Ah, so the operating system is caching the old file name and date in a "tunnelling cache" somewhere.  Now there are a couple of fixes available to me, such as disabling the "tunnelling cache".  But the fix I went for was, was to

IF logfile older than 7 days THEN
   1.  delete the current log file
   1a. wait 16 seconds.
   2.  create a new log file (with the same name)

Waiting 16 seconds works, as this is longer than the default tunnelling cache hold time (15 seconds).

The VBscript I was having problems with?  The SMS Client Health Startup Script.

Other blog posts on this subject:
Windows Date Created Timestamp strangeness
File tunnelling: weird creation timestamps

SMS Client Health Startup Scripts, and multiple domain maintenance.

The downside of multiple domains, is that I have to maintain multiple scripts for SMS Client Health Check.

Until today.

I used the sThisDomain variable I created for the Check_Domain function I wrote, and did this:
sThisDomain="CONTOSO"

Select Case sThisDomain
    Case "CONTOSO"
        WKS_admACCT = "CONTOSO\Workstations Admins"
        StrCCRServer = "CON23"
        strCCRSiteCode = "P20"
        GoodLogPath ="\\CENTLOG\CONTOSO\SMSHealthCheck\Good"
        BadLogPath ="\\CENTLOG\CONTOSO\SMSHealthCheck\Bad"
    Case "TOLERDO"   
        WKS_admACCT = "TOLERDO\Admin WKS"
        StrCCRServer = "TOOL11"
        strCCRSiteCode = "P76"
        GoodLogPath ="\\CENTLOG\TOLERDO\SMSHealthCheck\Good"
        BadLogPath ="\\CENTLOG\TOLERDO\SMSHealthCheck\Bad"
    Case Else
        LogGood=False
        LogBad=False
        COLLECTMSG "Unknown_Domain","ERROR","The domain '" + sThisDomain + "' is not configured for in SMS check script"
        CLIENTSTATE = CLIENTSTATE + 1
        StrERRType = StrERRType & "UNKNOWN_Domain_"
        aCleanUp(99)
End select

As you can see, just changing the value of sThisDomain, I am now able to have the one script working in another domain (such as  TOLERDO).  and the script now allows me to quickly add another domain by just adding another Case block in.

SMS Client Health Startup Script, and logging

sms2003_150x70The pilot of the SMS Client Health Startup Script has gone reasonably well.  So far the script has found about 30 broken PCs.

But the logging has been a bit hit and miss.  We write to a central log server, and we’re been getting quite a few “Path not found” errors.

Now, I think it’s either one of two things.

  1. The DNS server lying to me, and/or
  2. The section of the code which does the central log file creation.

For the lying DNS server, I’ve added a Ping of the central log server, so I’m hoping that’ll help.

Now the section of the SMS Client Health Script which checks that the log directory existed, was doing this:
...
If objFSO.FolderExists(LogPath) Then
Set objFolder = objFSO.GetFolder(LogPath)
Else
Set objFolder = objFSO.CreateFolder(LogPath)
End If

"Set objFolder = objFSO.GetFolder(LogPath)" – WTF???

The script is trying to get a folder listing of ALL the log files that the central log server has.  I don’t understand why.  The code doesn’t do anything with the information.  Unless it’s some perverted way of checking that the log directory is online.

My guess is that the GetFolder call is timing out, and causing the later log file write call to fail.

So, I replaced the offending code with:
If Not objFSO.FolderExists(LogPath) Then
COLLECTMSG "Set_LOGFOLDER","ERROR","GoodLogPath not found " & err & " " & err.description
Err.clear
End If

We’ll see how it goes over the next week.

SMS Client Health Startup Script and Cross Domain logons.

PowerShell logoI’m in the process of piloting the DudeWorks/1E/Shaun Cassells SMS SCCM Client Health script.  I’ve set it up so it runs in the user’s logon script.  But there’s a bug with that.

  • User FRED is the CONTOSO domain
  • User FRED logons onto a computer which is part of the TOLERDO domain.
  • SMS Client Health script tries to repair the TOLERDO domain computer
    (not a good thing).

The fix?
Update the script to check to see if the user is logging onto a computer in their own domain.  The scripts changes were:

  1. CONFIG Settings section
    Added sThisDomain="CONTOSO"
  2. In the START section, just after the Create Log file call
    Added
    ' Check Domain to ensure a CONTOSO user isn't logging onto a TOLERDO PC.
    Sub_Check_Domain
  3. And finally, added this subroutine:
    Sub Sub_Check_Domain
         If InStr(objSysInfo.ComputerName, LCase(sThisDomain)) = 0 Then
    COLLECTMSG "Sub_Check_Domain","","A " + sThisDomain + " user has logged onto a non " + sThisDomain + " PC"

            COLLECTMSG "Sub_Check_Domain","","objSysInfo.ComputerName is set to: " + objSysInfo.ComputerName
             CLIENTSTATE = 99
             StrERRType = StrERRType & "WRONG_Domain_"
             CleanUp(99)
        Else
             COLLECTMSG "Sub_Check_Domain","","PC is in domain:" + sThisDomain
        End If
    End Sub

Bookmark and Share

Detecting broken or not installed SMS/SCCM clients.

You take all your computer accounts in Active Directory, filter out the old records (I use a cut-off of 30 days), and then compare it to your SMS or SCCM database.
(I showed you how to export the LastLogin date from Active Directory here).

An aside:
I love Active Directory, as you can use it as an “Authoritative Source”.  If the computer is not in Active Directory then it won’t be able to use AD resources, such as the corporate intranet or email or network printing; if your sysadmin is particularly clever.

You’re going to have 3 cases where computers aren’t reporting into SMS/SCCM, but are in Active Directory.

1. SMS/SCCM client is not installed
This is the easy to detect.  You can see it in the Active Directory but it’s not in your SMS/SCCM database.  Simple fix, install the SMS/SCCM client.

2. SMS/SCCM client is installed but has never reported.
Investigate and resolve the issue.  If there are lots of clients not reporting, it might be a site boundary issue.

3. SMS/SCCM client is installed but has stopped reporting.
The client has become broken.  When I last had this problem, it was WMI based and I wrote a custom script to repair it.  With mixed results.

The way I tell if a client has stopped reporting?
I subtract the SMS last contact date from the Active Directory LastLogin date.  If the difference is greater than 14 days, it’s likely the SMS client has a problem.

You could fix these broken clients manually, but a better way would be to have something in your users logon script.  Which runs at user logon and just detects and fixes common SMS/SCCM problems.  Which someone has already done.  You can find it here:
SMS 2003 Client Health Startup Script v4.19

Notes:

  • 30 days?  Well people go on holidays for 4 weeks, and their computer may be turned off…
  • Corey Hynes suggested at TechEd 2005 that you should automate repeative tasks with scripts.  He was right you know.
  • SMS/SCCM?
    Microsoft Systems Management Server 2003
    Microsoft System Center Configuration Manager 2007

Bookmark and Share