January
Sun Mon Tue Wed Thu Fri Sat
29        
2006
Months
Jan
BlogTools
the possibly accurate now

Sun, 29 Jan 2006

[09:18] Windows network connections and "net use"
I had a problem a few months ago which I have finally managed to sort out. In the end it was mind numbingly obvious and simple to fix but it had myself, and several others, well confused for some considerable time so I figured I'd note it down as an aid to my memory and hopefully someone else will find it useful. I've stuck in a reasonable amount of detail thus this post is rather long and, I daresay, rather boring if you're not interested in such things. Sorry.

PS: IPs, username/passwords, directories, etc are sanitised throughout, otherwise all commands are displayed as they exist.

The Background
We are using a software delivery product from CA called Unicenter Software Delivery (USD). It works in a similar fashion to the software deployment functionality seen in Microsoft's Systems Management Server. USD can be remotely installed if you have admin rights on the box using a utility called sdsweep and this is how we deploy it. Software can then be deployed by wrapping each piece in scripts and adding a procedure to a package group. These proceures are then run locally on the box by the Software Delivery service and error levels are used to determine the success/failure of the installation.

The Problem
I'm working on a rollout project and the the installation of USD is a pre-requisite, providing a means of installing the software we actually want to install. The normal installation procedure is:

  1. Install USD
  2. Install other software
The problem we had was that some installations that utilised the USD service immediately after it's installation failed, unless a reboot was inserted between the two steps. This was bad because the nature of the boxes being installed on precluded the possibilty of rebooting. Annoying. What made this a spectacularly painful problem is that the script that runs the install didn't notice that something had gone wrong (because there is a setup.exe in the C:\WINNT directory) and attempted to carry on installing. When the install process finally failed (another three procedures down the line) the mess remaining required an incredibly painful manual process to be followed to make things right again!
The failure was caused by a net use command. This is the offending command:
net use * \\x.x.x.100\BuildDir$ /user:x.x.x.100\RemoteUser RemoteUsersPassword
and when it ran this is what happened:
C:\>net use * \\x.x.x.100\BuildDir$ /user:x.x.x.100\RemoteUser RemoteUsersPassword
System error 1219 has occurred.

The credentials supplied conflict with an existing set of credentials.
For some reason this error has its own MS knowledgebase entry. It's pretty obvious what to do to fix the problem: disconnect from the share you're already connected to and try again. It was at this point that my ignorance let me down. I logged on and looked for already mapped drives:
C:>net use
New connections will be remembered.

There are no entries in the list.
Hmmm, that's odd. No connections. I went and had a look at the open sessions on the server (the .100 machine). There was a connection and it was with the "wrong" user ID. Problem solved I figured, "I'm not sure why that connection is there but if I get rid of it we're OK". So, I tried closing the session and running the install again but it failed with the same error. I checked the open sessions again and the session that I had terminated was back! I knew it was the old/original session because it had a different user ID to the one used by the install scripts. I went back to the box we were installing on and looked for connections. Definitely none showing up with net use but I ran netstat and:
C:\>netstat -an

Active Connections
  Proto  Local Address          Foreign Address        State
  TCP    x.x.x.50:2135          x.x.x.100:445          ESTABLISHED
Where the heck was that coming from!! Due to time constraints I had to leave it because it was an intermittent problem and only affected 5%-10% of the install base. When the error occured I broke out the mop and bucket and I cleaned it up. Recently however, this particular task has been handed over and I REALLY didn't want to have to a) admit to such shoddy work and b) explain the manual process because, even with my documentation, it's a pain in the ass. So, I took a little time and I re-visited the problem.

The Solution
I worked out that the extra connection was being left behind by the installation of the USD service. I still haven't figured out why, but for some reason, on some boxes, the install software doesn't clean up properly behind itself and leaves a connection back to the Software Delivery server. The primer installation connects using a different set of credentials to the generic software installation process, hence the error message. The reason the old connection kept getting renewed is because when you attempt to connect to a share that you already have a connection to (albeit a disconnected one) Windows attempts to renew this connection, even if it uses different credentials to the ones you supplied. I'm not sure why someone thought that this was a good idea. The reason I wasn't seeing the "renewed" connection is because of a subtle difference between what I thought net use did and what it actually does. Here's what the Microsoft help page referenced above has to say: Use net use to connect to and disconnect from a network resource, and to view your current connections to network resources.
The reason I couldn't see the connection is because it belongs to the user that the service is running as. In this case, the user is the built-in "Local System" account. Next question, how do I become that user? There is no "Local System" user so you can't use runas, and logging in as the local administrative user just gives you the local administrative users account. There are two ways that I now know:
  1. Use the "Task Scheduler" service to kick off a cmd process for you.
  2. Use psexec.
The "Task Scheduler" service (the actual service name is just "Schedule") runs specified things at a specified time. This service normally runs under the "Local System" account so any processes it kicks off also run as that user. To generate a "Local System" command prompt from the command line you can use the at command thus:
LOCAL C:\>time
The current time is: 14:12:17.00
Enter the new time:

LOCAL C:\>at 14:13 /interactive %COMSPEC%
Added a new job with job ID = 1

LOCAL C:\>at
Status ID   Day                     Time          Command Line
-------------------------------------------------------------------------------
        1   Today                   14:13 PM      C:\WINNT\system32\cmd.exe
Then, at 14:13 a command prompt will spring into being - ON THE CONSOLE. There are two main problems with this approach. If you're using Terminal Services to connect you will NOT see this new window, it spawna on the console, not on your virutal desktop. Secondly, a lot of the time the Schedule service is disabled and it is annoying to re-enable it, do your stuff and disable it again. This method is helpful, but only if we can get to the console. Let's have a look at option two instead:

psexec is another one of the eternally useful tools to be found on the Sysinternals Freeware website. Essentially, psexec allows you to run a command on a remote machine. The handy thing is: you can specify if you'd like to use the System account with the -s flag! So:
C:>psexec \\x.x.x.50 -u DOMAIN\USERNAME -s %COMSPEC%

PsExec v1.70 - Execute processes remotely
Copyright (C) 2001-2006 Mark Russinovich
Sysinternals - www.sysinternals.com

Password:

Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-2000 Microsoft Corp.

C:\WINNT\system32>net use
New connections will be remembered.

Status       Local     Remote                    Network
-------------------------------------------------------------------------------
Disconnected           \\x.x.x.100\BuildDir$     Microsoft Windows Network
The command completed successfully.
Ah HAH! There's that pesky durned connection. It can now be removed and the world is a safer place for innocent installations to go about their business.

The solution (for the symptoms anyway) is disgustingly simple and obvious now. I created a new procedure that was embedded in the install package that simply deletes the connection if it's there:
net use \\x.x.x.100\BuildDir$ /delete
If the connection is there, it is removed. If it isn't, no problem, the delete command just does nothing. This obviously doesn't stop the problem occuring in the first place but, as I have no test equipment (and no time to test anyway) this is the best solution I've got for now.

It was interesting looking at how services run and interact with the system and I'm thinking I should really look at doing an MCSE just so I know what is out there and available to play with, especially since all of this is about to change again with the way Windows 2003 deals with local system service accounts.


category: /life | permalink | Comments suspended due to spamwhores